On Wed, 25 Jan 2017, Jeff Law wrote:
As has been discussed extensively, we're not doing a good job at simplifying
overflow tests, particularly those which collapse down to an EQ/NE test.
x + -1 > x -> x == 0
x + -1 < x -> x != 0
x + 1 < x -> x == -1U
x + 1 > x -> x != -1U
The simplifications allow us to propagate a constant for X into one ARM of
the associated IF/ELSE construct. For C++ std::vector operations those
propagations can eliminate lots of unnecessary code.
Those propagations also eliminate (by way of removing unnecessary code) false
positive warnings for memset calls that come from std::vector operations.
This patch does two things.
1. It adds special case patterns to the A+CST CMP A pattern for cases where
CST is 1 or -1 where the result turns into A EQ/NE 0 or A EQ/NE -1U. These
special patterns are applied regardless of the single_use status of the
expression.
2. It adds a call to fold_stmt in simplify_cond_using_ranges. This allows
VRP to transform the code early and the first DOM pass to often see the
simpified conditional and thus optimize better, rather than waiting for
forwprop3 to simplify the conditional and the last DOM pass to optimize the
code.
Bootstrapped and regression tested on x86_64-linux-gnu. OK for the trunk?
I assume this causes a regression for code like
unsigned f(unsigned a){
unsigned b=a+1;
if(b<a)return 42;
return b;
}
? On the other hand, the optimization is already very fragile, if I write
b<=a (which is equivalent since 1 != 0), it doesn't apply.
We currently get
addl $1, %edi
movl $42, %eax
cmovnc %edi, %eax
or almost as good with b==0
movl %edi, %eax
movl $42, %edx
addl $1, %eax
cmove %edx, %eax
while with a==-1 we have the redundant comparison
leal 1(%rdi), %eax
cmpl $-1, %edi
movl $42, %edx
cmove %edx, %eax
Simplifying x + 1 < x to x + 1 == 0 might not be enough to simplify your
examples though I guess?
--
Marc Glisse