为什么clang / llvm不优化这个?

时间:2016-10-23 12:52:08

标签: c++ clang llvm compiler-optimization

使用clang 3.9编译此代码时:

constexpr bool is_small(long long v) {
  return v < 0x4000000000000000;
}
int foo();
int f(int a) {
  if (is_small(a)) return a;
  else return foo();
}

它会生成相当于int f(int a) { return a; }的程序集,因为它确定is_small(a)始终为真,因为aint,(在我的平台上)总是小于0x4000000000000000

当我将is_small更改为:

constexpr bool is_small(long long v) {
  return v >= -0x4000000000000000;
}

正如预期的那样,完全相同。

但是,当我更改is_small以检查两个条件时:

constexpr bool is_small(long long v) {
  return v < 0x4000000000000000 && v >= -0x4000000000000000;
}

clang不会优化ifreturn foo()部分。

(以下是关于Godbolt的上述片段,可以使用:https://godbolt.org/g/fnoE9A

为什么会这样?它清楚地得出结论,单独的条件总是正确的,为什么不延伸到两者的逻辑结合?

1 个答案:

答案 0 :(得分:1)

没有充分的理由,这是LLVM缺少的优化。提交https://llvm.org/bugs/show_bug.cgi?id=30794以确保其得到修复。

基本上LLVM首先在内联它并优化f()中的使用之前优化is_small。在优化is_small时,问题是将比较v < 0x4000000000000000 && v >= -0x4000000000000000转换为v + 0x4000000000000000 > -1。内联后,优化器无法识别这种新形式,允许在f()中不断折叠代码。