Hi, I'm having a hard time finding an answer to what I assume is a very basic idea. I'm trying to produce this llvm code using the LLVM api: %myString = alloca [13 x i8], i32 13 store [13 x i8] c"Hello world.\00", [13 x i8]* %myString %tmp1 = getelementptr [13 x i8]* %myString, i32 0, i32 0 %tmp2 = call i32 (i8*, ...)* @printf( i8* %tmp1 ) nounwind A simple Hello World example. But I can't seem to figure out what I'm supposed to pass to the GetElementPtrInst. For example, this snippet: std::vector<llvm::Value*> args; auto strValue llvm::ConstantDataArray::getString(llvm::getGlobalContext(), llvm::StringRef("Hello world.")); std::vector<llvm::Value*> index_vector; index_vector.push_back(Builder.getInt32(0)); index_vector.push_back(Builder.getInt32(0)); auto valueAsPtr = Builder.CreateGEP(strValue, index_vector, "tmp1"); args.push_back(valueAsPtr); Builder.CreateCall(TheModule->getFunction("printf"), args, "callprintf"); Note that this is summarized, I already have the IRBuilder, etc initialized. I've also tried this with a LoadInstr that loads the ConstantDataArray (I just inserted strValue into the example code to simplify things, I get the same error either way). If I run this code, LLVM asserts in the CreateGEP call with the error message "Non-pointer type for constant GetElementPtr expression" since the type I passed to CreateGEP is an Array type. Callstack:> Lexer.exe!llvm::ConstantExpr::getGetElementPtr(llvm::Constant * C, > llvm::ArrayRef<llvm::Value *> Idxs, bool InBounds, llvm::Type * > OnlyIfReducedTy) Line 2005 C++Lexer.exe!llvm::ConstantFolder::CreateGetElementPtr(llvm::Constant * C, llvm::ArrayRef<llvm::Value *> IdxList) Line 133 C++ Lexer.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1>>::CreateGEP(llvm::Value * Ptr, llvm::ArrayRef<llvm::Value *> IdxList, constllvm::Twine & Name) Line 1021 C++ Shockingly, I have been unable to find examples of anyone else doing this. Everyone else seems to create a global variable to hold the string value, and then passes that Global variable to CreateGEP. I know the llvm code I'm trying to create works correctly, I just can't seem to produce it using the tools, and I'm not sure why. Thanks, Jordan -- View this message in context: http://llvm.1065342.n5.nabble.com/Passing-ConstantDataArray-to-GetElementPtrInst-tp81889.html Sent from the LLVM - Dev mailing list archive at Nabble.com.
Nick Lewycky
2015-May-29 03:10 UTC
[LLVMdev] Passing ConstantDataArray to GetElementPtrInst
On 28 May 2015 at 16:52, jsrduck <jsrduck at gmail.com> wrote:> Hi, I'm having a hard time finding an answer to what I assume is a very > basic > idea. I'm trying to produce this llvm code using the LLVM api: > > %myString = alloca [13 x i8], i32 13 > store [13 x i8] c"Hello world.\00", [13 x i8]* %myString > %tmp1 = getelementptr [13 x i8]* %myString, i32 0, i32 0 > %tmp2 = call i32 (i8*, ...)* @printf( i8* %tmp1 ) nounwind > > A simple Hello World example. But I can't seem to figure out what I'm > supposed to pass to the GetElementPtrInst. For example, this snippet: > > std::vector<llvm::Value*> args; > auto strValue > llvm::ConstantDataArray::getString(llvm::getGlobalContext(), > llvm::StringRef("Hello world.")); >Note that this is the actual sequence of bytes, it is not a pointer to a place where that sequence of bytes is stored. %myString is a pointer to 13 bytes, and your store instruction put those 13 bytes in it. std::vector<llvm::Value*> index_vector;> index_vector.push_back(Builder.getInt32(0)); > index_vector.push_back(Builder.getInt32(0)); > auto valueAsPtr = Builder.CreateGEP(strValue, index_vector, "tmp1"); >This is trying to create something like: %tmp1 = getelementptr [13 x i8] c"Hello world.\00", i32 0, i32 0 which is not valid IR (as the error message says, c"Hello world.\00" is not a pointer). You want to create what you wrote in your snippet of IR, where the first argument is the AllocaInst you created. Nick> args.push_back(valueAsPtr); > Builder.CreateCall(TheModule->getFunction("printf"), args, > "callprintf"); > > Note that this is summarized, I already have the IRBuilder, etc > initialized. > I've also tried this with a LoadInstr that loads the ConstantDataArray (I > just inserted strValue into the example code to simplify things, I get the > same error either way). > > If I run this code, LLVM asserts in the CreateGEP call with the error > message "Non-pointer type for constant GetElementPtr expression" since the > type I passed to CreateGEP is an Array type. Callstack: > > > Lexer.exe!llvm::ConstantExpr::getGetElementPtr(llvm::Constant * C, > > llvm::ArrayRef<llvm::Value *> Idxs, bool InBounds, llvm::Type * > > OnlyIfReducedTy) Line 2005 C++ > Lexer.exe!llvm::ConstantFolder::CreateGetElementPtr(llvm::Constant * C, > llvm::ArrayRef<llvm::Value *> IdxList) Line 133 C++ > > > Lexer.exe!llvm::IRBuilder<1,llvm::ConstantFolder,llvm::IRBuilderDefaultInserter<1> > >::CreateGEP(llvm::Value * Ptr, llvm::ArrayRef<llvm::Value *> IdxList, > const > llvm::Twine & Name) Line 1021 C++ > > > Shockingly, I have been unable to find examples of anyone else doing this. > Everyone else seems to create a global variable to hold the string value, > and then passes that Global variable to CreateGEP. I know the llvm code I'm > trying to create works correctly, I just can't seem to produce it using the > tools, and I'm not sure why. > > Thanks, > Jordan > > > > -- > View this message in context: > http://llvm.1065342.n5.nabble.com/Passing-ConstantDataArray-to-GetElementPtrInst-tp81889.html > Sent from the LLVM - Dev mailing list archive at Nabble.com. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150528/3791a840/attachment.html>