C++ 为什么';t铿锵/llvm优化了这一点?
使用clang 3.9编译此代码时: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上的上述片段,供大家使用:) 为什么会发生这种情况?它清楚地得出结论,各个条件总是正确的,为什么这不
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
,但显然,由于另一个优化,它甚至没有达到第一部分。感谢您解释并归档错误。