https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94021
--- Comment #9 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Jakub Jelinek from comment #6) > CCing Andrew and Aldy to see what the ranger does or can do, talking about > I mean, if we have: > h_1 = x_2 / 3600; > if (x_2 <= -3599 && x_2 <= 89999) > use (h_1); > figure out that h_1 is set to x_2 / 3600 and even when that > SSA_NAME_DEF_STMT is not in a guarded block, its use is in one and so from > the [-3599, 89999] range of x_2 at the point of use derive that h_1 there is > [0, 24]? > Surely if it is like: > if (x_2 <= -3599 && x_2 <= 89999) > { > h_1 = x_2 / 3600; > use (h_1); > } > I'd expect it to handle it that way. Certainly we get the latter case. The earlier case is currently... inconsistent. Something I hope to address in the next release. if we have precisely: h_1 = x_2 / 3600; if (x_2 <= -3599 && x_2 <= 89999) use (h_1); and if that is calculated in such a way that all of the conditions are evaluated in a single basic block, then the GORI engine well mark h1 and x_2 both as exports and the evaluator will calculate the desired value for h_1. Once we start to pull them further apart, the current implementation loses the ability to recalculate h_1 when we get new ranges for x_2. I have plans to segregate the def chains from the export lists in blocks, and allow for greater ability to recalculate things like this. When I look at #c4 in EVRP, I see: =========== BB 4 ============ <bb 4> : # x_10 = PHI <x_13(D)(2), x_14(3)> h_15 = x_10 / 3600; _1 = x_10 % 3600; m_16 = _1 / 60; h.0_2 = (unsigned int) h_15; _3 = h.0_2 > 23; _5 = _3; if (_5 != 0) goto <bb 6>; [INV] else goto <bb 5>; [INV] _1 : int [0, 3599] h.0_2 : unsigned int [0, 596523] x_10 : int [0, +INF] h_15 : int [0, 596523] m_16 : int [0, 59] 4->6 (T) h.0_2 : unsigned int [0, 596523] 4->6 (T) _5 : _Bool [1, 1] 4->6 (T) x_10 : int [0, +INF] 4->6 (T) h_15 : int [0, 596523] 4->5 (F) h.0_2 : unsigned int [0, 596523] 4->5 (F) _5 : _Bool [0, 0] 4->5 (F) x_10 : int [0, +INF] 4->5 (F) h_15 : int [0, 596523] and then later on: =========== BB 8 ============ x_10 int [0, +INF] <bb 8> : if (x_10 <= 89999) goto <bb 9>; [INV] else goto <bb 10>; [INV] 8->9 (T) x_10 : int [0, 89999] 8->10 (F) x_10 : int [90000, +INF] =========== BB 9 ============ <bb 9> : __builtin_snprintf (&a, 8, "%s%02i%02i", "+", h_15, m_16); The defchains already indicate that h_15 is dependant on the value of x_10, and I am hoping to enable recalculation of h_15 when a dependant range has changed.. and not just when they are exported from the same block. so in this case, when we ask for the range of h_15 in BB_9, we should be able to see that x_10 has a range of int [0, 89999] and trigger a recalculation of h_15 using "current" values. and come up with h_15 = [0,24] The pieces are all there, but they need to be assembled in a non time consuming way :-) It is on the radar for next release.