EDIT:我目前正在编写一个 LLVM 通行证,它基本上是在做你在这个问题中尝试做的事情。您的代码的问题如下:
std::vector<Type *> types(2, Type::getInt32Ty(getGlobalContext()));
Function *mwait = Intrinsic::getDeclaration(m, Intrinsic::x86_sse3_mwait, types);
您正在尝试获取名为 llvm.x86.sse3.mwait.i32.i32 的内部函数的减速度,但该内部函数不存在。但是,llvm.x86.sse3.mwait 存在,因此您必须编写以下内容:
Function *mwait = Intrinsic::getDeclaration(m, Intrinsic::x86_sse3_mwait);
请注意调用中缺少的类型参数。这是因为 llvm.x86.sse3.mwait 没有重载。
我希望你同时想通了。
好吧,因为我想能够暂时回答你,这是一个疯狂的猜测答案。
问题在于您通过优化器传递添加内在函数的方式。看起来您只是创建一个与内在函数同名的函数,而不是内在函数本身。
下面是一些 C++ 代码,它仅使用内置的 clang 来获取 IR 内部的内部函数(我使用 clang 3.5,但这应该不会产生任何影响)。
int main ()
{
__builtin_ia32_mwait(4,2);
}
编译它clang -emit-llvm -S
I get:
; ModuleID = 'intrin.cpp'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
call void @llvm.x86.sse3.mwait(i32 4, i32 2)
ret i32 0
}
; Function Attrs: nounwind
declare void @llvm.x86.sse3.mwait(i32, i32) #1
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.5.0 "}
请注意,SSE3 内在函数没有像您的版本中那样的类型重载。
在生成的文件上使用 llc 为我提供了:
.Ltmp2:
.cfi_def_cfa_register %rbp
movl $4, %ecx
movl $2, %eax
mwait
xorl %eax, %eax
popq %rbp
retq
创建了正确的装配体。
所以我假设您在 opt 传递中将内在函数引入函数的方式是错误的。
Get the intrinsic function and call it:
vector<Type*> types;
types.push_back(IntegerType::get(/*LLVM context*/, 32));
types.push_back(IntegerType::get(/*LLVM context*/, 32));
Function* func = Intrinsic::getDeclaration(/* module */, Intrinsic::x86_sse3_mwait, types);
CallInst* call = CallInst::Create(func, /* arguments */);