LLVM opt mem2reg has no effect

6k views Asked by At

I am currently playing around with LLVM and am trying to write a few optimizers to familiarize myself with opt and clang. I wrote a test.c file that is as follow:

int foo(int aa, int bb, int cc){
    int sum = aa + bb;
    return sum/cc;
}

I compiled the source code and generated 2 .ll files, one unoptimized and one with mem2reg optimizer pass:

clang -emit-llvm -O0 -c test.c -o test.bc
llvm-dis test.bc
opt -mem2reg -S test.ll -o test-mem2reg.ll

Both .ll files gave me the following output:

ModuleID = 'test.bc'
source_filename = "test.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: noinline nounwind optnone uwtable
define i32 @foo(i32 %aa, i32 %bb, i32 %cc) #0 {
entry:
  %aa.addr = alloca i32, align 4
  %bb.addr = alloca i32, align 4
  %cc.addr = alloca i32, align 4
  %sum = alloca i32, align 4
  store i32 %aa, i32* %aa.addr, align 4
  store i32 %bb, i32* %bb.addr, align 4
  store i32 %cc, i32* %cc.addr, align 4
  %0 = load i32, i32* %aa.addr, align 4
  %1 = load i32, i32* %bb.addr, align 4
  %add = add nsw i32 %0, %1
  store i32 %add, i32* %sum, align 4
  %2 = load i32, i32* %sum, align 4
  %3 = load i32, i32* %cc.addr, align 4
  %div = sdiv i32 %2, %3
  ret i32 %div
}

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 6.0.0 (trunk 314616)"}

So it seems that my mem2reg pass didn't work! What would be the problem?

2

There are 2 answers

1
Tiny Wings On BEST ANSWER

Recently, when compiled with -O0, clang started to add optnone attribute to each function, which prevents further optimizations afterwards including mem2reg pass. To prevent that, add -Xclang -disable-O0-optnone to clang.

0
Bruno De Fraine On

Another answer already points out that with -O0 (or without -O option), your functions are annotated with the optnone attribute. Another effect of lowering the optimization level is that no TBAA metadata seems to be generated, which also affects later optimizations.

So to prepare a file for opt, I found that it is better to keep your optimization level, and pass the option -Xclang -disable-llvm-passes (the help text for this option reads "Use together with -emit-llvm to get pristine LLVM IR from the frontend by not running any LLVM passes at all").

The complete invocation becomes:

clang -S -emit-llvm -O -Xclang -disable-llvm-passes source.c