This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]