Why doesn't clang/llvm optimize this?

When compiling this code with 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();
}

it produces assembly equivalent to int f(int a) { return a; } int f(int a) { return a; } , since it determined that is_small(a) will always be true, since a is an int , which (on my platform) is always smaller than 0x4000000000000000 .

When I change is_small to:

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

the exact same happens, as expected.

However, when I change is_small to check both conditions:

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

clang doesn't optimize the if and the return foo() part away.

(Here's the above snippets on Godbolt, to play around with: https://godbolt.org/g/fnoE9A)

Why does this happen? It clearly concluded that the conditions individually are always true, why doesn't this extend to the logical conjunction of both?


There is no good reason, it is a missing optimization from LLVM. Filed https://llvm.org/bugs/show_bug.cgi?id=30794 to make sure it gets fixed.

Basically LLVM is first optimizing is_small before inlining it and optimizing the use in f(). The issue that when optimizing is_small it is turning the comparison v < 0x4000000000000000 && v >= -0x4000000000000000 into v + 0x4000000000000000 > -1 . After inlining, this new form is not recognize by the optimizer in a way that allows to constant fold the code in f().

链接地址: http://www.djcxy.com/p/85638.html

上一篇: 我如何比较C ++中log()和fp的性能?

下一篇: 为什么不clang / llvm优化呢?