最適化抑制属性(optnone)
会社の技術情報共有ということでLLVMを紹介しようと思ってコードを書きながら試していたら昔(LLVM3.4世代)と違ったところがあり、ちょっとハマったのでメモしておく。
$ clang -v clang version 8.0.1 (tags/RELEASE_801/final) Target: x86_64-apple-darwin18.7.0 Thread model: posix InstalledDir: /usr/local/opt/llvm/bin
やりたかったこと
ある関数のLLVM-IRを出力して、PASSで最適化する。
実際にやったこと
- ある関数(func_add.c)
int func_add(int a, int b) { int c; c = a + b; return c; }
- LLVM-IRを出力する
$ clang -S -emit-llvm func_add.c
これで、func_add.ll
が生成される。
- PASS(-mem2reg)で最適化する。
$ opt -S -mem2reg func_add.ll -o func_add_opt.ll
問題
PASSが効いていない!
func_add_opt.ll
の抜粋(func_add.llと同じ結果に...)
; Function Attrs: noinline nounwind optnone ssp uwtable define i32 @func_add(i32, i32) #0 { %3 = alloca i32, align 4 %4 = alloca i32, align 4 %5 = alloca i32, align 4 store i32 %0, i32* %3, align 4 store i32 %1, i32* %4, align 4 %6 = load i32, i32* %3, align 4 %7 = load i32, i32* %4, align 4 %8 = add nsw i32 %6, %7 store i32 %8, i32* %5, align 4 %9 = load i32, i32* %5, align 4 ret i32 %9 } attributes #0 = { noinline nounwind optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
原因
最適化抑制属性:optnone が追加されていたもよう。
対応
LLVM-IR生成時に-Xclang -disable-O0-optnone
を追加する。
- LLVM-IRを出力する
$ clang -S -emit-llvm -Xclang -disable-O0-optnone func_add.c
結果
- func_add.llの比較
optnone
属性が削除されている。
--- func_add.ll 2019-08-16 16:05:48.000000000 +0900 +++ func_add_O0.ll 2019-08-16 16:38:32.000000000 +0900 @@ -3,7 +3,7 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.14.0" -; Function Attrs: noinline nounwind optnone ssp uwtable +; Function Attrs: noinline nounwind ssp uwtable define i32 @func_add(i32, i32) #0 { %3 = alloca i32, align 4 %4 = alloca i32, align 4 @@ -18,7 +18,7 @@ ret i32 %9 } -attributes #0 = { noinline nounwind optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #0 = { noinline nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2}
- PASS(-mem2reg)適用後の結果抜粋
; Function Attrs: noinline nounwind ssp uwtable define i32 @func_add(i32, i32) #0 { %3 = add nsw i32 %0, %1 ret i32 %3 }
できた!
全然watchできてないからこんな事に。。。