Patchwork Fix make_range (PR middle-end/45262)

login
register
mail settings
Submitter Jakub Jelinek
Date Aug. 12, 2010, 2:35 p.m.
Message ID <20100812143504.GP702@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/61614/
State New
Headers show

Comments

Jakub Jelinek - Aug. 12, 2010, 2:35 p.m.
Hi!

The range folding code in fold-const.c expects ranges to have always
low <= high (with NULL being -inf resp. +inf), and for PLUS_EXPR/MINUS_EXPR
the code normalizes, but not so for NEGATE_EXPR.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
Ok for trunk/4.5/4.4?

2010-08-12  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/45262
	* fold-const.c (make_range) <case NEGATE_EXPR>: Punt if
	-a overflows.  Normalize the range.

	* gcc.c-torture/execute/pr45262.c: New test.


	Jakub
Richard Guenther - Aug. 12, 2010, 3:16 p.m.
On Thu, Aug 12, 2010 at 4:35 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> The range folding code in fold-const.c expects ranges to have always
> low <= high (with NULL being -inf resp. +inf), and for PLUS_EXPR/MINUS_EXPR
> the code normalizes, but not so for NEGATE_EXPR.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
> Ok for trunk/4.5/4.4?

Ok.

Thanks,
Richard.

> 2010-08-12  Jakub Jelinek  <jakub@redhat.com>
>
>        PR middle-end/45262
>        * fold-const.c (make_range) <case NEGATE_EXPR>: Punt if
>        -a overflows.  Normalize the range.
>
>        * gcc.c-torture/execute/pr45262.c: New test.
>
> --- gcc/fold-const.c.jj 2010-07-09 13:44:24.000000000 +0200
> +++ gcc/fold-const.c    2010-08-12 13:44:42.000000000 +0200
> @@ -3985,9 +3985,9 @@ make_range (tree exp, int *pin_p, tree *
>          n_high = range_binop (MINUS_EXPR, exp_type,
>                                build_int_cst (exp_type, 0),
>                                0, low, 0);
> -         low = n_low, high = n_high;
> -         exp = arg0;
> -         continue;
> +         if (n_high != 0 && TREE_OVERFLOW (n_high))
> +           break;
> +         goto normalize;
>
>        case BIT_NOT_EXPR:
>          /* ~ X -> -X - 1  */
> @@ -4021,6 +4021,7 @@ make_range (tree exp, int *pin_p, tree *
>          if (TYPE_OVERFLOW_UNDEFINED (arg0_type))
>            *strict_overflow_p = true;
>
> +       normalize:
>          /* Check for an unsigned range which has wrapped around the maximum
>             value thus making n_high < n_low, and normalize it.  */
>          if (n_low && n_high && tree_int_cst_lt (n_high, n_low))
> --- gcc/testsuite/gcc.c-torture/execute/pr45262.c.jj    2010-08-12 13:51:49.000000000 +0200
> +++ gcc/testsuite/gcc.c-torture/execute/pr45262.c       2010-08-12 13:51:21.000000000 +0200
> @@ -0,0 +1,33 @@
> +/* PR middle-end/45262 */
> +
> +extern void abort (void);
> +
> +int
> +foo (unsigned int x)
> +{
> +  return ((int) x < 0) || ((int) (-x) < 0);
> +}
> +
> +int
> +bar (unsigned int x)
> +{
> +  return x >> 31 || (-x) >> 31;
> +}
> +
> +int
> +main (void)
> +{
> +  if (foo (1) != 1)
> +    abort ();
> +  if (foo (0) != 0)
> +    abort ();
> +  if (foo (-1) != 1)
> +    abort ();
> +  if (bar (1) != 1)
> +    abort ();
> +  if (bar (0) != 0)
> +    abort ();
> +  if (bar (-1) != 1)
> +    abort ();
> +  return 0;
> +}
>
>        Jakub
>

Patch

--- gcc/fold-const.c.jj	2010-07-09 13:44:24.000000000 +0200
+++ gcc/fold-const.c	2010-08-12 13:44:42.000000000 +0200
@@ -3985,9 +3985,9 @@  make_range (tree exp, int *pin_p, tree *
 	  n_high = range_binop (MINUS_EXPR, exp_type,
 				build_int_cst (exp_type, 0),
 				0, low, 0);
-	  low = n_low, high = n_high;
-	  exp = arg0;
-	  continue;
+	  if (n_high != 0 && TREE_OVERFLOW (n_high))
+	    break;
+	  goto normalize;
 
 	case BIT_NOT_EXPR:
 	  /* ~ X -> -X - 1  */
@@ -4021,6 +4021,7 @@  make_range (tree exp, int *pin_p, tree *
 	  if (TYPE_OVERFLOW_UNDEFINED (arg0_type))
 	    *strict_overflow_p = true;
 
+	normalize:
 	  /* Check for an unsigned range which has wrapped around the maximum
 	     value thus making n_high < n_low, and normalize it.  */
 	  if (n_low && n_high && tree_int_cst_lt (n_high, n_low))
--- gcc/testsuite/gcc.c-torture/execute/pr45262.c.jj	2010-08-12 13:51:49.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr45262.c	2010-08-12 13:51:21.000000000 +0200
@@ -0,0 +1,33 @@ 
+/* PR middle-end/45262 */
+
+extern void abort (void);
+
+int
+foo (unsigned int x)
+{
+  return ((int) x < 0) || ((int) (-x) < 0);
+}
+
+int
+bar (unsigned int x)
+{
+  return x >> 31 || (-x) >> 31;
+}
+
+int
+main (void)
+{
+  if (foo (1) != 1)
+    abort ();
+  if (foo (0) != 0)
+    abort ();
+  if (foo (-1) != 1)
+    abort ();
+  if (bar (1) != 1)
+    abort ();
+  if (bar (0) != 0)
+    abort ();
+  if (bar (-1) != 1)
+    abort ();
+  return 0;
+}