考虑以下C程序:
#include <stdlib.h>
int main() {
int * ptr = malloc(8);
*ptr = 14;
return 4;
}
使用clang -S -emit-llvm -O1
编译会发出以下信息:
...
; Function Attrs: norecurse nounwind readnone uwtable
define dso_local i32 @main() local_unnamed_addr #0 !dbg !7 {
call void @llvm.dbg.value(metadata i32* undef, metadata !13, metadata !DIExpression()), !dbg !15
ret i32 4, !dbg !16
}
...
对malloc
的调用消失了,因为它是clang
知道的内置函数。如果我们运行clang -S -emit-llvm -O1 -fno-builtin
,我们会得到以下结果:
...
; Function Attrs: nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #0 !dbg !14 {
%1 = call noalias i8* @malloc(i64 8) #3, !dbg !22
%2 = bitcast i8* %1 to i32*, !dbg !22
call void @llvm.dbg.value(metadata i32* %2, metadata !20, metadata !DIExpression()), !dbg !23
store i32 14, i32* %2, align 4, !dbg !24, !tbaa !25
ret i32 4, !dbg !29
}
...
clang
不知道malloc
是什么,必须将呼叫留在中
如何使用LLVM的opt
命令从第二个LLVM程序转到第一个?如何告诉opt
使用关于clang
显然具有的内置函数的知识?
在这个特定的例子中,问题是clang -fno-builtin
将生成LLVM代码,该代码显式地标记对具有nobuiltin
(即attributes #3 = { nobuiltin nounwind "no-builtins" }
(的内置函数的调用。
通常,哪些内置函数是可用的,可以通过传递-targetlibinfo
来猜测。您必须小心地在正确的参数和返回类型处声明和使用内置函数,否则LLVM将(正确地(不将它们识别为内置函数。