[llvm-dev] Incorrect mangling of intrinsics

Eli Friedman via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 24 13:33:51 PDT 2020


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


More information about the llvm-dev mailing list