[LLVMdev] Bogus assert in VMCore/Instructions.cpp CallInst::Create?

Nick Lewycky nicholas at mxc.ca
Wed Jul 4 16:30:02 PDT 2012


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



More information about the llvm-dev mailing list