C++ 为什么';t铿锵/llvm优化了这一点?

C++ 为什么';t铿锵/llvm优化了这一点?,c++,clang,llvm,compiler-optimization,C++,Clang,Llvm,Compiler Optimization,使用clang 3.9编译此代码时: constexpr bool很小(长v){ 返回v=-0x4000000000000000; } 正如所料,同样的情况也会发生 但是,当我将更改为\u small以检查这两个条件时: constexpr bool很小(长v){ 返回v=-0x4000000000000000; } clang不会优化if和return foo()部分 (以下是Godbolt上的上述片段,供大家使用:) 为什么会发生这种情况?它清楚地得出结论,各个条件总是正确的,为什么这不

使用clang 3.9编译此代码时:

constexpr bool很小(长v){
返回v<0x4000000000000000;
}
int foo();
INTF(INTA){
如果(a)很小,则返回a;
否则返回foo();
}
它生成相当于
intf(inta){returna;}
,因为它确定
很小(a)
将始终为真,因为
a
int
,它(在我的平台上)总是小于
0x4000000000000000

当我将
更改为\u small
时:

constexpr bool很小(长v){
返回v>=-0x4000000000000000;
}
正如所料,同样的情况也会发生

但是,当我将
更改为\u small
以检查这两个条件时:

constexpr bool很小(长v){
返回v<0x4000000000000000&&v>=-0x4000000000000000;
}
clang不会优化
if
return foo()
部分

(以下是Godbolt上的上述片段,供大家使用:)


为什么会发生这种情况?它清楚地得出结论,各个条件总是正确的,为什么这不扩展到两者的逻辑结合?

没有充分的理由,这是LLVM缺少的优化。归档以确保它得到修复


基本上,LLVM首先优化
is_small
,然后将其内联并优化在f()中的使用。优化
时的问题很小
它将比较
v<0x4000000000000000&&v>=-0x4000000000000000
转化为
v+0x4000000000000000>-1
。内联后,优化器无法识别这个新表单,因为它允许在f()中不断折叠代码。

@tkausl:这是逻辑or,而不是逻辑and。使用
condition1 | | condition1
它还可以对其进行优化。对。。我很笨。有很多事情是任何一个编译器都无法完美优化的。你找到了其中一个。我认为除了“因为编译器不是完美的”之外,这是不应该被问到的。啊!我不明白为什么它没有将
always\u-true&&always\u-true
减少到
always\u-true
,但显然,由于另一个优化,它甚至没有达到第一部分。感谢您解释并归档错误。