[Committed] PR26361: Handle unsigned NEGATE_EXPR in VRP

Roger Sayle roger@eyesopen.com
Tue Feb 21 02:30:00 GMT 2006


The following patch should fix the Tru64 bootstrap failure caused
by a miscompilation of the compiler itself.  The original cause is
a bad interaction between ivopts and VRP, which revealed that VRP's
extract_range_from_unary_expr incorrectly handles NEGATE_EXPR of
unsigned types.

Currently -[0,+Inf] results in the incorrect range [0,1] as the
default case assumes the bounds as the unary operation applied
to the operand bounds.  The patch below corrects this.  The
logic is that -[x,y] is [-y,-x] for x > 0, -[0,0] is [0,0] and
-[0,y] is varying ([0,+Inf]) for y > 0.

I actually tried generating [0,+Inf] using TYPE_MIN_VALUE and
TYPE_MAX_VALUE for min and max respectively, but this triggered
an enable checking assert that didn't like ranges being set to
these specific values.

The patch below was tested on x86_64-unknown-linux-gnu with a
full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.

Committed to mainline as revision 111327.  It'll take me a while
to confirm whether this resolves the Tru64 bootstrap failure, but
the new testcase (thanks to Andrew Pinskia) is no longer miscompiled
on AMD64.



2006-02-20  Roger Sayle  <roger@eyesopen.com>

	PR tree-optimization/26361
	* tree-vrp.c (extract_range_from_unary_expr): Handle NEGATE_EXPR
	of unsigned integer types.

	* gcc.dg/tree-ssa/vrp27.c: New test case.


Index: tree-vrp.c
===================================================================
*** tree-vrp.c	(revision 111294)
--- tree-vrp.c	(working copy)
*************** extract_range_from_unary_expr (value_ran
*** 1790,1795 ****
--- 1790,1813 ----
        max = (vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)) && !flag_wrapv)
  	     ? TYPE_MAX_VALUE (TREE_TYPE (expr))
  	     : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+
+     }
+   else if (code == NEGATE_EXPR
+ 	   && TYPE_UNSIGNED (TREE_TYPE (expr)))
+     {
+       if (!range_includes_zero_p (&vr0))
+ 	{
+ 	  max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+ 	  min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
+ 	}
+       else
+ 	{
+ 	  if (range_is_null (&vr0))
+ 	    set_value_range_to_null (vr, TREE_TYPE (expr));
+ 	  else
+ 	    set_value_range_to_varying (vr);
+ 	  return;
+ 	}
      }
    else if (code == ABS_EXPR
             && !TYPE_UNSIGNED (TREE_TYPE (expr)))


/* PR middle-end/26361.  */
/* { dg-do run } */
/* { dg-options "-O2" } */

void abort(void);

__attribute__((noinline))
void gen_rtx_CONST_INT(long long x) {
    if (-x > 10)
        abort();
}
__attribute__((noinline))
int alpha_expand_prologue(long frame_size)
{
    unsigned long long a;
    int probed;
    if (frame_size <= 1)  return;
    unsigned long long b = -2;
    a = -2;
    do {
        int a1 = a;
        probed = -a1;
        gen_rtx_CONST_INT (a1);
        a -= 2;
        a1 = -a;
        probed = a1;
    } while (probed < frame_size);
}

int main(void) {
    alpha_expand_prologue(10);
    return 0;
}


Roger
--



More information about the Gcc-patches mailing list