[llvm-dev] Incorrect mangling of intrinsics
Krzysztof Parzyszek via llvm-dev
llvm-dev at lists.llvm.org
Tue Mar 24 10:21:37 PDT 2020
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
More information about the llvm-dev
mailing list