[PATCH] Fix PR28905, ICE in tree-vrp

Richard Guenther rguenther@suse.de
Sat Sep 2 13:48:00 GMT 2006


In compare_name_with_value we verify that all equivalences
recorded for a VR have the same comparison result with the
value.  fix_equivalence_set ensures that this will be the
case by pruning contradicting equivalences that we get from
impossible paths like

  if (i < 0)
    if (i > 0)

where we'd say that i is both <0 and >0.

Unfortunately this pruning does not work for symbolic ranges
as implemented.  Fortunately this is easy to fix by noting
that using !value_ranges_intersect_p (vr_p, equiv_vr) is better
implemented by proper compare_values that then also can handle
some symbolic range cases.

Bootstrapped and tested on x86_64-unknown-linux-gnu for all
languages including Ada.

Ok for mainline?

I didn't manage to create a testcase failing on 4.1, though
in principle this but is latent there.

Thanks,
Richard.

:ADDPATCH middle-end:

2006-09-02  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/28905
	* tree-vrp.c (fix_equivalence_set): Manually implement
	!value_ranges_intersect_p to also handle symbolic ranges.

	* gcc.c-torture/compile/pr28905.c: New testcase.

Index: tree-vrp.c
===================================================================
*** tree-vrp.c	(revision 116660)
--- tree-vrp.c	(working copy)
*************** fix_equivalence_set (value_range_t *vr_p
*** 774,787 ****
        value_range_t *equiv_vr = vr_value[i];
  
        if (equiv_vr->type == VR_VARYING
! 	  || equiv_vr->type == VR_UNDEFINED
! 	  || symbolic_range_p (equiv_vr))
  	continue;
  
!       if (equiv_vr->type == VR_RANGE
! 	  && vr_p->type == VR_RANGE
! 	  && !value_ranges_intersect_p (vr_p, equiv_vr))
! 	bitmap_set_bit (to_remove, i);
        else if ((equiv_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
  	       || (equiv_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
  	{
--- 774,791 ----
        value_range_t *equiv_vr = vr_value[i];
  
        if (equiv_vr->type == VR_VARYING
! 	  || equiv_vr->type == VR_UNDEFINED)
  	continue;
  
!       if (vr_p->type == VR_RANGE
! 	  && equiv_vr->type == VR_RANGE)
! 	{
! 	  /* Two ranges have an empty intersection if their end points
! 	     are outside of the other range.  */
! 	  if (compare_values (equiv_vr->min, vr_p->max) == 1
! 	      || compare_values (equiv_vr->max, vr_p->min) == -1)
! 	    bitmap_set_bit (to_remove, i);
! 	}
        else if ((equiv_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
  	       || (equiv_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
  	{
Index: testsuite/gcc.c-torture/compile/pr28905.c
===================================================================
*** testsuite/gcc.c-torture/compile/pr28905.c	(revision 0)
--- testsuite/gcc.c-torture/compile/pr28905.c	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ /* We used to ICE here because after VRP we ended up with
+    non-compatible ranges in a value-range equivalences set.  */
+ void code_comment (int size)
+ {
+   int i;
+   for (i = 0; i < size; i++)
+     if (i)
+       if (i < 0)
+         if (i < 0)
+           return;
+ }



More information about the Gcc-patches mailing list