This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix ICE in Tree-VRP
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 5 May 2006 21:15:21 +0200
- Subject: [PATCH] Fix ICE in Tree-VRP
Hi,
The compiler ICEs at -O2 on the attached testcase, a regression from 3.x:
eric@linux:~/build/gcc/native32> gcc/xgcc -Bgcc -S -O2 tti0.adb -Igcc/ada/rts
+===========================GNAT BUG DETECTED==============================+
| 4.2.0 20060503 (experimental) (i586-suse-linux-gnu) GCC error: |
| in set_value_range, at tree-vrp.c:157 |
| Error detected at tti0.adb:39:4 |
The relevant statement is:
if Least_Significant < Most_Significant then
Least_Significant := Most_Significant;
end if;
Both Least_Significant and Most_Significant are Boolean and VRP computes that
Least_Significant is equal to True (1). When the pass is extracting the
range from the associated ASSERT expression, it builds a range of the form
[MIN+1, MAX] but here we have MIN == MAX so set_value_range aborts.
The proposed fix is to set the range to VARYING in this case. I don't think
something more sophisticated would be worthwhile as all should be optimized
away in the branch.
Tested on x86_64-suse-linux. OK for mainline and 4.1 branch?
2006-05-05 Eric Botcazou <ebotcazou@adacore.com>
* tree-vrp.c (extract_range_from_assert): Set the range to VARYING
for LT and GT if the computed range is effectively empty.
--
Eric Botcazou
Index: tree-vrp.c
===================================================================
--- tree-vrp.c (revision 113493)
+++ tree-vrp.c (working copy)
@@ -923,14 +923,22 @@ extract_range_from_assert (value_range_t
max = limit_vr->max;
}
- /* For LT_EXPR, we create the range [MIN, MAX - 1]. */
- if (cond_code == LT_EXPR)
+ /* If the maximum value forces us to be out of bounds, simply punt.
+ It would be pointless to try and do anything more since this
+ all should be optimized away above us. */
+ if (cond_code == LT_EXPR && compare_values (max, min) == 0)
+ set_value_range_to_varying (vr_p);
+ else
{
- tree one = build_int_cst (type, 1);
- max = fold_build2 (MINUS_EXPR, type, max, one);
- }
+ /* For LT_EXPR, we create the range [MIN, MAX - 1]. */
+ if (cond_code == LT_EXPR)
+ {
+ tree one = build_int_cst (type, 1);
+ max = fold_build2 (MINUS_EXPR, type, max, one);
+ }
- set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+ set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+ }
}
else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
{
@@ -946,14 +954,22 @@ extract_range_from_assert (value_range_t
min = limit_vr->min;
}
- /* For GT_EXPR, we create the range [MIN + 1, MAX]. */
- if (cond_code == GT_EXPR)
+ /* If the minimum value forces us to be out of bounds, simply punt.
+ It would be pointless to try and do anything more since this
+ all should be optimized away above us. */
+ if (cond_code == GT_EXPR && compare_values (min, max) == 0)
+ set_value_range_to_varying (vr_p);
+ else
{
- tree one = build_int_cst (type, 1);
- min = fold_build2 (PLUS_EXPR, type, min, one);
- }
+ /* For GT_EXPR, we create the range [MIN + 1, MAX]. */
+ if (cond_code == GT_EXPR)
+ {
+ tree one = build_int_cst (type, 1);
+ min = fold_build2 (PLUS_EXPR, type, min, one);
+ }
- set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+ set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+ }
}
else
gcc_unreachable ();
procedure TTI0 is
subtype Component_T is Boolean;
function Condition return Boolean is
begin
return True;
end;
V : Integer := 0;
function Component_Value return Integer is
begin
V := V + 1;
return V;
end;
Most_Significant : Component_T := False;
Least_Significant : Component_T := True;
begin
if Condition then
Most_Significant := True;
end if;
if Condition then
Least_Significant := Component_T'Val (Component_Value);
end if;
if Least_Significant < Most_Significant then
Least_Significant := Most_Significant;
end if;
if Least_Significant /= True then
raise Program_Error;
end if;
end;