inserting a print statement into IR

Hi Everyone,
I am trying to construct the print statement : printf(“value:%d\n”, value);
This is my llvm code. It is seg faulting at builder.CreateGlobalStringPtr(str,"").
Thanks.

George

vector<const Type *> params;
params.push_back(Type::getInt8PtrTy(M.getContext()));
FunctionType *fType = FunctionType::get(Type::getInt32Ty(M.getContext()), params, true);
Constant *temp = M.getOrInsertFunction(“printf”,fType);
if(!temp){
errs() << “printf function not in symbol table\n”;
exit(1);
}
Function *f = cast(temp);
f->setCallingConv(CallingConv::C);

const char *str = “value: %d\n”;
Value *intparam = …

Value *strPtr = builder.CreateGlobalStringPtr(str,"");

builder.CreateCall2(PrintF, strPtr, intparam,“tmp6”);

Hi Everyone,
I am trying to construct the print statement : printf(“value:%d\n”, value);
This is my llvm code. It is seg faulting at builder.CreateGlobalStringPtr(str,"").

This might be easier to debug with a stack trace. Use a debugger to see the call stack when the segfault occurs. Also try to isolate which pointer value is bad.

As a guess, did you give the builder object all the information it needs to insert IR (e.g., which LLVM Module * it is modifying, which BasicBlock or Instruction it is to use when inserting instructions, etc)?

– John T.

This is the seg fault I am getting.

dyld: lazy symbol binding failed: Symbol not found: __ZN4llvm13IRBuilderBase18CreateGlobalStringEPKcRKNS_5TwineE
Referenced from: /Users/georgebaah/llvm_dir/llvm-2.8/Debug+Asserts/lib/LLVMArrayBoundsCheck.dylib
Expected in: flat namespace

dyld: Symbol not found: __ZN4llvm13IRBuilderBase18CreateGlobalStringEPKcRKNS_5TwineE
Referenced from: /Users/georgebaah/llvm_dir/llvm-2.8/Debug+Asserts/lib/LLVMArrayBoundsCheck.dylib
Expected in: flat namespace

0 opt 0x0045e01c llvm::SearchForAddressOfSpecialSymbol(char const*) + 284
1 opt 0x0045e61e llvm::sys::RunInterruptHandlers() + 354
2 libSystem.B.dylib 0x93bcb2bb _sigtramp + 43
3 libSystem.B.dylib 0xffffffff _sigtramp + 1816350063
4 libSystem.B.dylib 0x8fe18c2f _sigtramp + 18446744073644857759
5 LLVMArrayBoundsCheck.dylib 0x0102c9df
6 LLVMArrayBoundsCheck.dylib 0x0102ca95
7 LLVMArrayBoundsCheck.dylib 0x0102ce2c
8 LLVMArrayBoundsCheck.dylib 0x0102ceec
9 opt 0x003d265b llvm::FPPassManager::doInitialization(llvm::Module&) + 63
10 opt 0x003d6062 llvm::FPPassManager::runOnModule(llvm::Module&) + 24
11 opt 0x003d5b4d llvm::MPPassManager::runOnModule(llvm::Module&) + 375
12 opt 0x003d5d9c llvm::PassManagerImpl::run(llvm::Module&) + 112
13 opt 0x003d5df5 llvm::PassManager::run(llvm::Module&) + 27
14 opt 0x0000d68e main + 4026
15 opt 0x00002146 start + 54
16 opt 0x00000005 start + 18446744073709543157
Stack dump:
0. Program arguments: opt -mem2reg -load …/llvm-2.8/Debug+Asserts/lib/LLVMArrayBoundsCheck.dylib -paa

  1. Running pass ‘Function Pass Manager’ on module ‘’.
    Segmentation fault

Hi George,

   I am trying to construct the print statement : printf("value:%d\n", value);
This is my llvm code. It is seg faulting at builder.CreateGlobalStringPtr(str,"").

please build LLVM with assertions enabled (configure with --enable-assertions) and try again. When assertions are enabled failures are usually much less
obscure.

Ciao, Duncan.

Hi George,

This is the seg fault I am getting.

dyld: lazy symbol binding failed: Symbol not found:
__ZN4llvm13IRBuilderBase18CreateGlobalStringEPKcRKNS_5TwineE
   Referenced from:
/Users/georgebaah/llvm_dir/llvm-2.8/Debug+Asserts/lib/LLVMArrayBoundsCheck.dylib
   Expected in: flat namespace

dyld: Symbol not found: __ZN4llvm13IRBuilderBase18CreateGlobalStringEPKcRKNS_5TwineE
   Referenced from:
/Users/georgebaah/llvm_dir/llvm-2.8/Debug+Asserts/lib/LLVMArrayBoundsCheck.dylib
   Expected in: flat namespace

this is quite a different kind failure to what I was imagining when you
mentioned getting a segfault! Indeed calling a function will clearly fail
if that function doesn't exist. I suggest you work out where in LLVM these
symbols are defined (or determine that they are not defined anywhere) and
then try to work out why your library wasn't linked with them. Probably
you forgot to link with the right LLVM library.

Ciao, Duncan.

Duncan,

I have this same issue using the 2.8 release in Linux. The function CreateGlobalString is declared on line 150 of llvm/Support/IRBuilder.h in the IRBuilderBase class but without implementation:

Value *CreateGlobalString(const char *Str = “”, const Twine &Name = “”);

CreateGlobalStringPtr is implemented in terms of CreateGlobalString starting on line 818 of llvm/Support/IRBuilder.h in the IRBuilder class::

/// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer
/// with “i8*” type instead of a pointer to array of i8.
Value *CreateGlobalStringPtr(const char *Str = “”, const Twine &Name = “”) {
Value *gv = CreateGlobalString(Str, Name);
Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
Value *Args[] = { zero, zero };
return CreateInBoundsGEP(gv, Args, Args+2, Name);
}

The implementation of CreateGlobalString starts on line 25 of lib/VMCore/IRBuilder.cpp. That file implements just one other function, getCurrentFunctionReturnType. Attempting to call getCurrentFunctionReturnType has the same issue, it compiles but fails with opt due to the symbol being undefined.

However, there are stock transforms that successfully call these functions, for example lib/Transforms/InstCombine. InstCombine is being built as a static library (using BUILD_ARCHIVE), whereas our transform is a loadable module. Does that offer any clue as to the problem? Perhaps we need to specify something for LIBS or USEDLIBS in our Makefile?

Thanks.

-Jake