EDIT: I am currently writing an LLVM pass that basically does what you tried to do in this question. The problem with your code is as follows:
std::vector<Type *> types(2, Type::getInt32Ty(getGlobalContext())); Function *mwait = Intrinsic::getDeclaration(m, Intrinsic::x86_sse3_mwait, types);
You are trying to get braking for an Intrinsic function named llvm.x86.sse3.mwait.i32.i32, and this Intrinsic does not exist. However, llvm.x86.sse3.mwait exists, and so you need to write this:
Function *mwait = Intrinsic::getDeclaration(m, Intrinsic::x86_sse3_mwait);
Note the missing type argument to invoke. This is because llvm.x86.sse3.mwait does not have overloads.
I hope you figured this out.
Well, since I want to be able to answer you for a while, this is the answer to the question.
The problem is how you add inside information through your optimizer pass. It looks like you are just creating a function with the same name as the internal one, not the internal one.
Here is a little C ++ code that just uses the built-in clang to get the inside IR (I use clang 3.5, but this should not have any effect).
int main () { __builtin_ia32_mwait(4,2); }
Compiling it with clang -emit-llvm -S
, I get:
; ModuleID = 'intrin.cpp' target datalayout = "em: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
Please, not that the built-in SSE3 does not have overload types like in your version.
Using llc in the generated file provides me with:
.Ltmp2: .cfi_def_cfa_register %rbp movl $4, %ecx movl $2, %eax mwait xorl %eax, %eax popq %rbp retq
The corresponding assembly has been created.
So, I assume that the way you enter the internal value into the function is incorrect in your optional pass.
Get the internal function and call it:
vector<Type*> types; types.push_back(IntegerType::get(, 32)); types.push_back(IntegerType::get(, 32)); Function* func = Intrinsic::getDeclaration(, Intrinsic::x86_sse3_mwait, types); CallInst* call = CallInst::Create(func, );