Andrew Ruef
2012-Jul-04 23:00 UTC
[LLVMdev] Bogus assert in VMCore/Instructions.cpp CallInst::Create?
Evening, I was writing some code that tried to insert calls to the llvm.annotation intrinsic function, which has a signature of (i32, i8*, i8*, i32). The code is below. void addAnnotation( BasicBlock *block, Function *F) { string foo = "foo"; string bar = "barr"; Type *charTy = Type::getInt8Ty(block->getContext()); ArrayType *s1Ty = ArrayType::get(charTy, foo.size()+1); ArrayType *s2Ty = ArrayType::get(charTy, bar.size()+1); Constant *ar1 = ConstantArray::get(block->getContext(), foo); Constant *ar2 = ConstantArray::get(block->getContext(), bar); GlobalVariable *g1 = NULL; GlobalVariable *g2 = NULL; g1 = new GlobalVariable( *F->getParent(), s1Ty, true, GlobalValue::PrivateLinkage, 0, ""); g1->setAlignment(1); g2 = new GlobalVariable( *F->getParent(), s2Ty, true, GlobalValue::PrivateLinkage, 0, ""); g2->setAlignment(1); vector<Constant*> s1_id; vector<Constant*> s2_id; s1_id.push_back(ConstantInt::get( block->getContext(), APInt(64, StringRef("0"), 10))); s1_id.push_back(ConstantInt::get( block->getContext(), APInt(64, StringRef("0"), 10))); s2_id.push_back(ConstantInt::get( block->getContext(), APInt(64, StringRef("0"), 10))); s2_id.push_back(ConstantInt::get( block->getContext(), APInt(64, StringRef("0"), 10))); g1->setInitializer(ar1); g2->setInitializer(ar2); Type *tys = { Type::getInt32Ty(block->getContext()) }; Function *annot = Intrinsic::getDeclaration( F->getParent(), Intrinsic::annotation, tys); Value *v1 =ConstantExpr::getGetElementPtr(g1, s1_id); Value *v2 =ConstantExpr::getGetElementPtr(g2, s2_id); Value *c1 = ConstantInt::get(tys, 1); Value *c2 = ConstantInt::get(tys, 0); vector<Value*> v; v.push_back(c1); v.push_back(v1); v.push_back(v2); v.push_back(c2); Value *callAnnot = CallInst::Create(annot, v, "", block); return; } When I try and create the CallInst, an assert in VMCore/Instructions.cpp fails, saying that the type of second parameter of the function signature (i8*) does not match the type of the first argument (which is also i8*). I can, in the addAnontation function, call dump() on both the second parameter of the llvm.annotate function and the second element of the 'v' array, and they are indeed both i8*. I wasn't able to find an operator== method for Type, and it seems that the pointer values are different between the value populated / created by ConstantExpr::getGetElementPtr and Intrinsic::getDeclaration. For the moment, I commented out the check in VMCore/Instructions.cpp. Could I add an operator== to Type that compares the TypeIDs? or am I suffering from a fundamental misunderstanding? Thank you, Andrew
Nick Lewycky
2012-Jul-04 23:30 UTC
[LLVMdev] Bogus assert in VMCore/Instructions.cpp CallInst::Create?
Andrew Ruef wrote:> Evening, > > I was writing some code that tried to insert calls to the > llvm.annotation intrinsic function, which has a signature of (i32, > i8*, i8*, i32). The code is below. > > void addAnnotation( BasicBlock *block, Function *F) > { > string foo = "foo"; > string bar = "barr"; > > Type *charTy = Type::getInt8Ty(block->getContext()); > > ArrayType *s1Ty = ArrayType::get(charTy, foo.size()+1); > ArrayType *s2Ty = ArrayType::get(charTy, bar.size()+1); > > Constant *ar1 = ConstantArray::get(block->getContext(), foo); > Constant *ar2 = ConstantArray::get(block->getContext(), bar); > > GlobalVariable *g1 = NULL; > GlobalVariable *g2 = NULL; > > g1 = new GlobalVariable( *F->getParent(), > s1Ty, > true, > GlobalValue::PrivateLinkage, > 0, > ""); > g1->setAlignment(1); > > g2 = new GlobalVariable( *F->getParent(), > s2Ty, > true, > GlobalValue::PrivateLinkage, > 0, > ""); > g2->setAlignment(1); > > vector<Constant*> s1_id; > vector<Constant*> s2_id; > s1_id.push_back(ConstantInt::get( block->getContext(), > APInt(64, StringRef("0"), 10))); > s1_id.push_back(ConstantInt::get( block->getContext(), > APInt(64, StringRef("0"), 10))); > > s2_id.push_back(ConstantInt::get( block->getContext(), > APInt(64, StringRef("0"), 10))); > s2_id.push_back(ConstantInt::get( block->getContext(), > APInt(64, StringRef("0"), 10))); > > g1->setInitializer(ar1); > g2->setInitializer(ar2); > > Type *tys = { Type::getInt32Ty(block->getContext()) }; > Function *annot = Intrinsic::getDeclaration( F->getParent(), > Intrinsic::annotation, > tys); > Value *v1 =ConstantExpr::getGetElementPtr(g1, s1_id); > Value *v2 =ConstantExpr::getGetElementPtr(g2, s2_id); > Value *c1 = ConstantInt::get(tys, 1); > Value *c2 = ConstantInt::get(tys, 0); > > vector<Value*> v; > v.push_back(c1); > v.push_back(v1); > v.push_back(v2); > v.push_back(c2); > > Value *callAnnot = CallInst::Create(annot, v, "", block); > > return; > } > > When I try and create the CallInst, an assert in > VMCore/Instructions.cpp fails, saying that the type of second > parameter of the function signature (i8*) does not match the type of > the first argument (which is also i8*). > > I can, in the addAnontation function, call dump() on both the second > parameter of the llvm.annotate function and the second element of the > 'v' array, and they are indeed both i8*. I wasn't able to find an > operator== method for Type, and it seems that the pointer values are > different between the value populated / created by > ConstantExpr::getGetElementPtr and Intrinsic::getDeclaration. > > For the moment, I commented out the check in VMCore/Instructions.cpp. > Could I add an operator== to Type that compares the TypeIDs? or am I > suffering from a fundamental misunderstanding?Types are indeed pointer comparable. If you have two Type*'s which print the same type but have different addresses then they belong to different LLVMContexts. Over IRC, you mentioned that the block and function have the same context, but the module has a different one. Because the intrinsic is being created with the module's context, it won't match. Of course, functions must be created with the context of the module that owns them, the bug is there. Nick
Andrew Ruef
2012-Jul-04 23:32 UTC
[LLVMdev] Bogus assert in VMCore/Instructions.cpp CallInst::Create?
This was the problem! The module had been created under one context and due to a bug elsewhere in my program, everything else was using a different context! Once changed, the system works. Thank you very much. On Wed, Jul 4, 2012 at 7:30 PM, Nick Lewycky <nicholas at mxc.ca> wrote:> Andrew Ruef wrote: >> >> Evening, >> >> I was writing some code that tried to insert calls to the >> llvm.annotation intrinsic function, which has a signature of (i32, >> i8*, i8*, i32). The code is below. >> >> void addAnnotation( BasicBlock *block, Function *F) >> { >> string foo = "foo"; >> string bar = "barr"; >> >> Type *charTy = Type::getInt8Ty(block->getContext()); >> >> ArrayType *s1Ty = ArrayType::get(charTy, foo.size()+1); >> ArrayType *s2Ty = ArrayType::get(charTy, bar.size()+1); >> >> Constant *ar1 = ConstantArray::get(block->getContext(), foo); >> Constant *ar2 = ConstantArray::get(block->getContext(), bar); >> >> GlobalVariable *g1 = NULL; >> GlobalVariable *g2 = NULL; >> >> g1 = new GlobalVariable( *F->getParent(), >> s1Ty, >> true, >> GlobalValue::PrivateLinkage, >> 0, >> ""); >> g1->setAlignment(1); >> >> g2 = new GlobalVariable( *F->getParent(), >> s2Ty, >> true, >> GlobalValue::PrivateLinkage, >> 0, >> ""); >> g2->setAlignment(1); >> >> vector<Constant*> s1_id; >> vector<Constant*> s2_id; >> s1_id.push_back(ConstantInt::get( block->getContext(), >> APInt(64, StringRef("0"), 10))); >> s1_id.push_back(ConstantInt::get( block->getContext(), >> APInt(64, StringRef("0"), 10))); >> >> s2_id.push_back(ConstantInt::get( block->getContext(), >> APInt(64, StringRef("0"), 10))); >> s2_id.push_back(ConstantInt::get( block->getContext(), >> APInt(64, StringRef("0"), 10))); >> >> g1->setInitializer(ar1); >> g2->setInitializer(ar2); >> >> Type *tys = { Type::getInt32Ty(block->getContext()) }; >> Function *annot = Intrinsic::getDeclaration( F->getParent(), >> >> Intrinsic::annotation, >> tys); >> Value *v1 =ConstantExpr::getGetElementPtr(g1, s1_id); >> Value *v2 =ConstantExpr::getGetElementPtr(g2, s2_id); >> Value *c1 = ConstantInt::get(tys, 1); >> Value *c2 = ConstantInt::get(tys, 0); >> >> vector<Value*> v; >> v.push_back(c1); >> v.push_back(v1); >> v.push_back(v2); >> v.push_back(c2); >> >> Value *callAnnot = CallInst::Create(annot, v, "", block); >> >> return; >> } >> >> When I try and create the CallInst, an assert in >> VMCore/Instructions.cpp fails, saying that the type of second >> parameter of the function signature (i8*) does not match the type of >> the first argument (which is also i8*). >> >> I can, in the addAnontation function, call dump() on both the second >> parameter of the llvm.annotate function and the second element of the >> 'v' array, and they are indeed both i8*. I wasn't able to find an >> operator== method for Type, and it seems that the pointer values are >> different between the value populated / created by >> ConstantExpr::getGetElementPtr and Intrinsic::getDeclaration. >> >> For the moment, I commented out the check in VMCore/Instructions.cpp. >> Could I add an operator== to Type that compares the TypeIDs? or am I >> suffering from a fundamental misunderstanding? > > > Types are indeed pointer comparable. If you have two Type*'s which print the > same type but have different addresses then they belong to different > LLVMContexts. > > Over IRC, you mentioned that the block and function have the same context, > but the module has a different one. Because the intrinsic is being created > with the module's context, it won't match. Of course, functions must be > created with the context of the module that owns them, the bug is there. > > Nick