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