------- Comment #8 from law at redhat dot com 2006-02-19 00:16 ------- Subject: Re: [4.2 Regression] ICE compiling a-textio.adb at -O1 -ftree-vrp
On Sat, 2006-02-18 at 17:02 +0000, pinskia at gcc dot gnu dot org wrote: > > ------- Comment #5 from pinskia at gcc dot gnu dot org 2006-02-18 17:02 > ------- > Saw it too. Ignore my last post about an initial theory. It looks like some code, somewhere is goofing up types in a very unpleasant way. If I had to point a finger, I'd have to guess it's somewhere in the Ada front-end and an Ada person is going to have to look at this. It's highly unlikely with my total lack of knowledge about the Ada front-end that have any chance of fixing it. Our little odyssey starts with visiting this PHI node: [ The first visit is uninteresting, ignore it. I'm starting my analysis with the second visit. ] lastD.2483_148 = PHI <lastD.2483_60(28), lastD.2483_15(14)>; Only the edge from block #14 is executable, so the result of the PHI will be equivalent to the current range for last_15. The range we record is [0, 0x7fffffff]. We then proceed to the uses of last_148. One of which is: lastD.2483_86 = lastD.2483_148 + 1; Now for the first "oddity". If we look at the underlying type for last we have a type "natural___XDLU_0__2147483647". What's interesting about it is that it has a 32bit type precision, but the min/max values only specify 31 bits. ie, the min/max values are 0, 0x7fffffff. So anyway, we proceed to add the current range for last_148 [0, 0x7fffffff] to the constant 1. This results in [1, 0x80000000]. Second oddity. This is clearly outside the type's min/max values, but because the value is inside the type's precision, no overflow is signaled and no bits are zero'd out. We then encounter this statement: lastD.2483_60 = lastD.2483_86; So we copy the current range for last_86 to last_60. [1, 0x80000000] which I'll note again is outside the min/max values associated with last's type. We now return to the PHI node: lastD.2483_148 = PHI <lastD.2483_60(28), lastD.2483_15(14)>; We still only have one edge (from block #14) marked executable, so nothing interesting happens yet. We then visit the PHI node a 4th time. This time both edges are marked as executable. So we're going to have to meet the ranges for last_60 [0x1, 0x80000000] and last_15 [0x0, 0x7fffffff]. Now with the range for last_60 being outside the type's min/max values I don't think we can meaningfully merge these ranges. We've clearly gone off the reservation already, but just for fun let's see what happens. The min value is computed as 0x0, which is exactly what we would expect. Nothing fun or interesting here. What's fun is meeting the max values of 0x8000000 and 0x7fffffff. vrp_meet returns 0x80000000 as the meet value. OK, that's plausible, I don't think vrp_meet tries to clamp values at min/max for the type. We then fallinto this hunk of code: 3995 if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE) 3996 { 3997 if (!POINTER_TYPE_P (TREE_TYPE (lhs))) 3998 { 3999 int cmp_min = compare_values (lhs_vr->min, vr_result.min); 4000 int cmp_max = compare_values (lhs_vr->max, vr_result.max); 4001 4002 /* If the new minimum is smaller or larger than the previous 4003 one, go all the way to -INF. In the first case, to avoid 4004 iterating millions of times to reach -INF, and in the (gdb) 4005 other case to avoid infinite bouncing between different 4006 minimums. */ 4007 if (cmp_min > 0 || cmp_min < 0) 4008 vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min)); 4009 4010 /* Similarly, if the new maximum is smaller or larger than 4011 the previous one, go all the way to +INF. */ 4012 if (cmp_max < 0 || cmp_max > 0) 4013 vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max)); 4014 (gdb) 4015 /* If we ended up with a (-INF, +INF) range, set it to 4016 VARYING. */ 4017 if (vr_result.min == TYPE_MIN_VALUE (TREE_TYPE (vr_result.min)) 4018 && vr_result.max == TYPE_MAX_VALUE (TREE_TYPE (vr_result.max))) 4019 goto varying; lhs_vr->max is 0x7fffffff and vr_result->max is 0x80000000, so cmp_max is -1. Which indicates we should set a new maximum to be the maximum for the type. The maximum for the type is 0x7fffffff. But just as important, this ends up changing the underlying type for vr_result.max, instead of being "natural___XDLU_0__2147483647" it's a more generic integer type. Ugh! Now we go to update the range for the result using update_value_range. We determine the range is new, even though the underlying values are unchanged because we're using pointer equality for all our tests (this is bad). So we consider the PHI node's result as being new, so we re-simulate the uses of the PHI result and we end up ping-ponging back and forth betwen 0x7fffffff and 0x80000000 as its upper value due to the type inconsistencies. And and because of the pointer equality tests in update_value_range we keep thinking we've got a new range for the result of the PHI every time. Net result is an infinite loop. So what needs to be fixed. First, the inconsistency between the type's precision in its min/max values needs to be fixed. Most likely this is an Ada FE problem. Second, for a given integer type (such as natural___XDLU_0_2147483647, the type for the nodes in TYPE_MIN_VALUE and TYPE_MAX_VALUE really should be a natural___XDLU_0_2147483647. ie, the type of an integer constant should be the same as the type of its min/max values. Otherwise we're a lot more likely to ping pong because the anti-ping-pong tests use pointer equality to check and see if a range's type, min or max values have changed. When an integer type's min/max values are of a different type, we can think that a value changed when in fact it did not change at all. Again, both of these are issues an Ada maintainer is going to need to look at in depth. Jeff -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26348