Krzysztof Parzyszek via llvm-dev
2020-Mar-24 17:21 UTC
[llvm-dev] Incorrect mangling of intrinsics
Long story short, when I do "getDeclaration" for llvm.ctlz, I get "llvm.ctlz.i32.i1" instead of "llvm.ctlz.i32", and the module verifier flags this as an error. When bitcode is read from a file, the auto-remangler takes care of this, but when the intrinsic is created programmatically, it has an incorrect mangling. Should we also do the remangling in Intrinsic::getDeclaration? Here's a standalone example that shows the problem: --- #include <llvm/ADT/SmallVector.h> #include <llvm/IR/Function.h> #include <llvm/IR/Intrinsics.h> #include <llvm/IR/IRBuilder.h> #include <llvm/IR/Module.h> #include <llvm/IR/Type.h> #include <llvm/IR/Verifier.h> #include <llvm/Support/raw_ostream.h> int main() { llvm::LLVMContext Ctx; llvm::Module M("blah", Ctx); llvm::Intrinsic::ID Ctlz = llvm::Intrinsic::ctlz; llvm::Function* In = llvm::Intrinsic::getDeclaration(&M, Ctlz, {llvm::Type::getInt32Ty(Ctx), llvm::Type::getInt1Ty(Ctx)}); llvm::FunctionCallee FC M.getOrInsertFunction("fred", In->getFunctionType()); auto *F = llvm::cast<llvm::Function>(FC.getCallee()); auto *Entry = llvm::BasicBlock::Create(Ctx, "entry", F); llvm::IRBuilder<> Builder(Entry); auto *V = Builder.CreateCall(In->getFunctionType(), In, {&*F->arg_begin(), llvm::ConstantInt::getFalse(Ctx)}, "ctlz"); Builder.CreateRet(V); llvm::errs() << *In << '\n' << *F << '\n'; verifyModule(M, &llvm::errs()); return 0; } --- Output: $ ./a.out ; Function Attrs: nounwind readnone speculatable willreturn declare i32 @llvm.ctlz.i32.i1(i32, i1 immarg) #0 define i32 @fred(i32 %0, i1 %1) { entry: %ctlz = call i32 @llvm.ctlz.i32.i1(i32 %0, i1 false) ret i32 %ctlz } Intrinsic name not mangled correctly for type arguments! Should be: llvm.ctlz.i32 i32 (i32, i1)* @llvm.ctlz.i32.i1 -- Krzysztof Parzyszek kparzysz at quicinc.com AI tools development
Eli Friedman via llvm-dev
2020-Mar-24 20:33 UTC
[llvm-dev] Incorrect mangling of intrinsics
Intrinsic::getDeclaration takes a list of types used for overloading, not the parameter list of the function. -Eli> -----Original Message----- > From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Krzysztof > Parzyszek via llvm-dev > Sent: Tuesday, March 24, 2020 10:22 AM > To: llvm-dev at lists.llvm.org > Subject: [EXT] [llvm-dev] Incorrect mangling of intrinsics > > Long story short, when I do "getDeclaration" for llvm.ctlz, I get "llvm.ctlz.i32.i1" > instead of "llvm.ctlz.i32", and the module verifier flags this as an error. > > When bitcode is read from a file, the auto-remangler takes care of this, but > when the intrinsic is created programmatically, it has an incorrect mangling. > Should we also do the remangling in Intrinsic::getDeclaration? > > > Here's a standalone example that shows the problem: > > --- > #include <llvm/ADT/SmallVector.h> > #include <llvm/IR/Function.h> > #include <llvm/IR/Intrinsics.h> > #include <llvm/IR/IRBuilder.h> > #include <llvm/IR/Module.h> > #include <llvm/IR/Type.h> > #include <llvm/IR/Verifier.h> > #include <llvm/Support/raw_ostream.h> > > > int main() { > llvm::LLVMContext Ctx; > llvm::Module M("blah", Ctx); > llvm::Intrinsic::ID Ctlz = llvm::Intrinsic::ctlz; > llvm::Function* In = llvm::Intrinsic::getDeclaration(&M, Ctlz, > {llvm::Type::getInt32Ty(Ctx), llvm::Type::getInt1Ty(Ctx)}); > > llvm::FunctionCallee FC > M.getOrInsertFunction("fred", In->getFunctionType()); > auto *F = llvm::cast<llvm::Function>(FC.getCallee()); > auto *Entry = llvm::BasicBlock::Create(Ctx, "entry", F); > llvm::IRBuilder<> Builder(Entry); > auto *V = Builder.CreateCall(In->getFunctionType(), In, > {&*F->arg_begin(), llvm::ConstantInt::getFalse(Ctx)}, "ctlz"); > Builder.CreateRet(V); > > llvm::errs() << *In << '\n' << *F << '\n'; > verifyModule(M, &llvm::errs()); > return 0; > } > --- > > Output: > > $ ./a.out > ; Function Attrs: nounwind readnone speculatable willreturn > declare i32 @llvm.ctlz.i32.i1(i32, i1 immarg) #0 > > define i32 @fred(i32 %0, i1 %1) { > entry: > %ctlz = call i32 @llvm.ctlz.i32.i1(i32 %0, i1 false) > ret i32 %ctlz > } > > Intrinsic name not mangled correctly for type arguments! Should be: > llvm.ctlz.i32 > i32 (i32, i1)* @llvm.ctlz.i32.i1 > > > -- > Krzysztof Parzyszek kparzysz at quicinc.com AI tools development > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev