https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85598
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |aldyh at gcc dot gnu.org, | |jakub at gcc dot gnu.org, | |law at gcc dot gnu.org, | |rguenth at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, during evrp we have: <bb 2> : goto <bb 4>; [INV] <bb 3> : __builtin_snprintf (&temp, 4, "%%%02X", x_1); # RANGE [1, 256] NONZERO 511 x_6 = x_1 + 1; <bb 4> : # RANGE [0, 256] NONZERO 511 # x_1 = PHI <0(2), x_6(3)> if (x_1 != 256) goto <bb 3>; [INV] else goto <bb 5>; [INV] and that is correct and maximum of what we can achieve, x_1 indeed has [0, 256] range and only perhaps on-demand vrp analysis improvements can help there for the use in bb 3. During vrp1 it is still like that but we have additional assert_expr <bb 3> [local count: 1063004407]: x_7 = ASSERT_EXPR <x_1, x_1 != 256>; __builtin_snprintf (&temp, 4, "%%%02X", x_7); x_5 = x_7 + 1; <bb 4> [local count: 1073741824]: if (x_1 != 256) goto <bb 3>; [99.00%] else goto <bb 5>; [1.00%] and determine: x_1: unsigned int [0, 256] x_5: unsigned int [1, 256] x_7: unsigned int [0, 255] EQUIVALENCES: { x_1 } (1 elements) But the ASSERT_EXPR is removed and there was nothing to stick the [0, 255] range on, so before jump threading in vrp1 we have: <bb 2> [local count: 10737418]: goto <bb 4>; [100.00%] <bb 3> [local count: 1063004407]: __builtin_snprintf (&temp, 4, "%%%02X", x_1); # RANGE [1, 256] NONZERO 511 x_5 = x_1 + 1; <bb 4> [local count: 1073741824]: # RANGE [0, 256] NONZERO 511 # x_1 = PHI <0(2), x_5(3)> if (x_1 != 256) goto <bb 3>; [99.00%] else goto <bb 5>; [1.00%] Then the jump threading transforms this into: <bb 2> [local count: 10737418]: goto <bb 6>; [100.00%] <bb 3> [local count: 1063004407]: # RANGE [0, 256] NONZERO 511 # x_10 = PHI <x_1(4), x_8(6)> __builtin_snprintf (&temp, 4, "%%%02X", x_10); # RANGE [1, 256] NONZERO 511 x_5 = x_10 + 1; <bb 4> [local count: 1063004406]: # RANGE [0, 256] NONZERO 511 # x_1 = PHI <x_5(3)> if (x_1 != 256) goto <bb 3>; [98.99%] else goto <bb 5>; [1.01%] <bb 6> [local count: 10737418]: # RANGE [0, 256] NONZERO 511 # x_8 = PHI <0(2)> goto <bb 3>; [100.00%] And that is already the case where the range info is only conservatively correct, but we could perhaps do better, though it would mean jump threading has to think about the value ranges of the SSA_NAMEs it creates. In particular, x_8 could have range: # RANGE [0, 0] NONZERO 0 because the phi arg is constant 0, and x_10 could have: # RANGE [0, 255] NONZERO 255 because x_8 has [0, 0] range and while x_1 has [0, 256] range, the condition on the 4 -> 3 edge is x_1 != 256. Is that doable in the jump threading code at least for the simple cases? Or should some other pass figure this out? Right now it is only vrp2 that adjusts the range, too late for the printf-return-value2 pass that queries this info.