How to make LLVM's `opt` command optimize builtin functions?

222 Views Asked by At

Consider the following C program:

#include <stdlib.h>

int main() {
    int * ptr = malloc(8);
    *ptr = 14;
    return 4;
}

Compiling with 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
}
...

The call to malloc is gone because it is a builtin function that clang knows about. If we run clang -S -emit-llvm -O1 -fno-builtin instead we 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, metadata !DIExpression()), !dbg !23
  store i32 14, i32* %2, align 4, !dbg !24, !tbaa !25
  ret i32 4, !dbg !29
}
...

clang can't know what malloc is and has to leave the call in.

How can I get from the second LLVM program to the first using LLVM's opt command? How do I tell opt to use the knowledge about builtin functions that clang apparently has?

1

There are 1 best solutions below

0
phischu On

In this specific example, the problem is that clang -fno-builtin will produce LLVM code that explicitly marks calls to builtin functions with nobuiltin, i.e. attributes #3 = { nobuiltin nounwind "no-builtins" }.

Generally, which builtin functions are available is guessed by pass -targetlibinfo. You have to be careful to declare and use builtin functions at exactly the correct parameter and return types or LLVM will (correctly) not recognize them as builtins.