最適化抑制属性(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できてないからこんな事に。。。