Patchwork Fix PR51730

login
register
mail settings
Submitter Richard Guenther
Date Jan. 2, 2012, 2:44 p.m.
Message ID <alpine.LNX.2.00.1201021544020.4999@zhemvz.fhfr.qr>
Download mbox | patch
Permalink /patch/133852/
State New
Headers show

Comments

Richard Guenther - Jan. 2, 2012, 2:44 p.m.
I am testing the following patch to fix PR51730.

Richard.

2012-01-02  Richard Guenther  <rguenther@suse.de>

	PR middle-end/51730
	* fold-const.c (fold_comparison): Properly canonicalize
	tree offset and HOST_WIDE_INT bit position.

	* gcc.dg/fold-compare-6.c: New testcase.
Richard Guenther - Jan. 3, 2012, 8:57 a.m.
On Mon, 2 Jan 2012, Richard Guenther wrote:

> 
> I am testing the following patch to fix PR51730.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

> Richard.
> 
> 2012-01-02  Richard Guenther  <rguenther@suse.de>
> 
> 	PR middle-end/51730
> 	* fold-const.c (fold_comparison): Properly canonicalize
> 	tree offset and HOST_WIDE_INT bit position.
> 
> 	* gcc.dg/fold-compare-6.c: New testcase.
> 
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c	(revision 182784)
> +++ gcc/fold-const.c	(working copy)
> @@ -8886,6 +8886,14 @@ fold_comparison (location_t loc, enum tr
>  	      indirect_base0 = true;
>  	    }
>  	  offset0 = TREE_OPERAND (arg0, 1);
> +	  if (host_integerp (offset0, 0)
> +	      && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT)
> +		  / BITS_PER_UNIT
> +		  == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset0)))
> +	    {
> +	      bitpos0 = TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT;
> +	      offset0 = NULL_TREE;
> +	    }
>  	}
>  
>        base1 = arg1;
> @@ -8909,6 +8917,14 @@ fold_comparison (location_t loc, enum tr
>  	      indirect_base1 = true;
>  	    }
>  	  offset1 = TREE_OPERAND (arg1, 1);
> +	  if (host_integerp (offset1, 0)
> +	      && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT)
> +		  / BITS_PER_UNIT
> +		  == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset1)))
> +	    {
> +	      bitpos1 = TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT;
> +	      offset1 = NULL_TREE;
> +	    }
>  	}
>  
>        /* A local variable can never be pointed to by
> Index: gcc/testsuite/gcc.dg/fold-compare-6.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/fold-compare-6.c	(revision 0)
> +++ gcc/testsuite/gcc.dg/fold-compare-6.c	(revision 0)
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fdump-tree-original" } */
> +
> +char digs[] = "0123456789";
> +int foo (void)
> +{
> +  int xlcbug = 1 / (&(digs + 5)[-2 + (_Bool) 1] == &digs[4] ? 1 : -1);
> +  return xlcbug;
> +}
> +
> +/* { dg-final { scan-tree-dump "xlcbug = 1;" "original" } } */
> +/* { dg-final { cleanup-tree-dump "original" } } */
>

Patch

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 182784)
+++ gcc/fold-const.c	(working copy)
@@ -8886,6 +8886,14 @@  fold_comparison (location_t loc, enum tr
 	      indirect_base0 = true;
 	    }
 	  offset0 = TREE_OPERAND (arg0, 1);
+	  if (host_integerp (offset0, 0)
+	      && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT)
+		  / BITS_PER_UNIT
+		  == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset0)))
+	    {
+	      bitpos0 = TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT;
+	      offset0 = NULL_TREE;
+	    }
 	}
 
       base1 = arg1;
@@ -8909,6 +8917,14 @@  fold_comparison (location_t loc, enum tr
 	      indirect_base1 = true;
 	    }
 	  offset1 = TREE_OPERAND (arg1, 1);
+	  if (host_integerp (offset1, 0)
+	      && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT)
+		  / BITS_PER_UNIT
+		  == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset1)))
+	    {
+	      bitpos1 = TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT;
+	      offset1 = NULL_TREE;
+	    }
 	}
 
       /* A local variable can never be pointed to by
Index: gcc/testsuite/gcc.dg/fold-compare-6.c
===================================================================
--- gcc/testsuite/gcc.dg/fold-compare-6.c	(revision 0)
+++ gcc/testsuite/gcc.dg/fold-compare-6.c	(revision 0)
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-original" } */
+
+char digs[] = "0123456789";
+int foo (void)
+{
+  int xlcbug = 1 / (&(digs + 5)[-2 + (_Bool) 1] == &digs[4] ? 1 : -1);
+  return xlcbug;
+}
+
+/* { dg-final { scan-tree-dump "xlcbug = 1;" "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */