https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102800
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Last reconfirmed| |2021-10-17 Status|UNCONFIRMED |NEW Keywords| |missed-optimization --- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- end_10 = begin_9(D) + _3; if (begin_9(D) != end_10) goto <bb 3>; [INV] else goto <bb 5>; [INV] ;; succ: 3 (TRUE_VALUE,EXECUTABLE) ;; 5 (FALSE_VALUE,EXECUTABLE) ;; basic block 3, loop depth 0, maybe hot ;; prev block 2, next block 4, flags: (NEW, VISITED) ;; pred: 2 (TRUE_VALUE,EXECUTABLE) # RANGE [0, 7] NONZERO 7 _15 = (signed long) _3; ;; basic block 4, loop depth 1, maybe hot ;; prev block 3, next block 5, flags: (NEW, VISITED) ;; pred: 3 (FALLTHRU,EXECUTABLE) ;; 4 (TRUE_VALUE,EXECUTABLE) # RANGE [-9223372036854775808, 7] # x_6 = PHI <_15(3), x_14(4)> # .MEM_7 = PHI <.MEM_11(D)(3), .MEM_13(4)> _4 = (charD.7) x_6; # RANGE [-128, 127] _5 = (intD.6) _4; # .MEM_13 = VDEF <.MEM_7> # USE = nonlocal escaped # CLB = nonlocal escaped barD.1978 (_5); # RANGE [-9223372036854775808, 6] x_14 = x_6 + -1; if (x_14 != 0) goto <bb 4>; [INV] else goto <bb 5>; [INV] ;; succ: 4 (TRUE_VALUE,EXECUTABLE) ;; 5 (FALSE_VALUE,EXECUTABLE) this is from evrp. Oh We miss that _15 cannot be 1. even though later on we can detect it. SO simple testcase: void bar(char x); void link_error(void); void foo(char * begin) { // end = ALIGN(begin, 8); __SIZE_TYPE__ t = 7 - ((((unsigned long)begin) - 1) % 8); char * end = begin + t; if (begin != end) { if (!t) link_error(); long long x = end - begin; do bar(x); while(--x != 0); } } The call to should really be removed in evrp. So forwprop1 does not change the first begin!=end to t!=0 but changes end-begin. to (long long)t. And then forwprop2 changes begin!=end to t!=0 and vrp1 can then figure out the range of x inside the loop is [1,7].