+++ This bug was initially created as a clone of Bug #107131 +++ __attribute__((noipa)) unsigned long long foo (unsigned char o) { unsigned long long t1 = -(long long) (o == 0); unsigned long long t2 = -(long long) (t1 > 10439075533421201520ULL); unsigned long long t3 = -(long long) (t1 <= t2); return t3; } from comment 8 of that PR could be optimized into return -1ULL. t1 has range [0,0][-1ULL,-1ULL], t2 is set to 0 if t1 is 0 and to -1ULL if t1 is -1ULL and thus t2 could be optimized to t2 = t1. And t1 <= t2 can then trivially fold to t1 <= t1 aka true.
Confirmed.
I think the simple missed optimization here is: ``` int f2(int a) { if(a != -1 && a != 0) __builtin_unreachable(); unsigned c = a; if(c > 121212) return 1; return 0; } ``` This should be optimized to just: ``` int f2_(int a) { return a != 0; } ``` That is if we have: ``` # RANGE [irange] unsigned int [0, 0][+INF, +INF] a.0_1 = (unsigned int) a_4(D); if (a.0_1 > 121212) ``` Since we have two values for a.0_1 we can just compare to one or the other in the above case. Then that will optimize the original testcase as we can optimize away the nop_convert and then negative and then we get: t1 <= t1 and that is folded trivially to true.
I have seen other bug reports having a similar issue too.
Also: ``` int f(int a, int b) { int c = a == b; c = -c; return c <= -1; } ``` At `-O2 -fwrapv` is not optimized at the gimple level but is at the RTL level even.
I am going to change/fix va-values.cc:test_for_singularity to implement this. The comment before this function even says: ``` /* We are comparing trees OP0 and OP1 using COND_CODE. OP0 has a known value range VR. If there is one and only one value which will satisfy the conditional, then return that value. Else return NULL. ``` Which does make it sound like it should have done that too.
I have a patch to fix the testcase in comment #2. After that patch we have: ``` _1 = o_10(D) == 0; _2 = (long long int) _1; _3 = -_2; t1_11 = (long long unsigned int) _3; _4 = t1_11 == 18446744073709551615; _5 = (long long int) _4; _6 = -_5; t2_12 = (long long unsigned int) _6; _7 = t1_11 <= t2_12; _8 = (long long int) _7; _9 = -_8; t3_13 = (long long unsigned int) _9; ``` Forwprop will not change _4 to _1 though. because t1_11 is used twice.
(In reply to Andrew Pinski from comment #6) > Forwprop will not change _4 to _1 though. because t1_11 is used twice. But combined with PR 107137, we are able to optimize it just fine.