问题描述
考虑以下C程序:
#include <stdlib.h>
int main() {
int * ptr = malloc(8);
*ptr = 14;
return 4;
}
使用clang -S -emit-llvm -O1
emits the following进行编译:
...
; 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
,则我们get the following:
...
; 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,!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将(正确)将其识别为内置函数。