diff mbox

Fix PR66142

Message ID alpine.LSU.2.11.1505261553270.30088@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener May 26, 2015, 1:54 p.m. UTC
The following fixes the testcase in PR66142

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

Richard.

2015-05-26  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/66142
	* tree-ssa-sccvn.c (vn_reference_lookup_3): Manually compare
	MEM_REFs for the same base address.

	* gcc.dg/tree-ssa/ssa-fre-44.c: New testcase.

Comments

Kyrylo Tkachov May 27, 2015, 4 p.m. UTC | #1
Hi Richard,

On 26/05/15 14:54, Richard Biener wrote:
> The following fixes the testcase in PR66142
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
>
> Richard.
>
> 2015-05-26  Richard Biener  <rguenther@suse.de>
>
> 	PR tree-optimization/66142
> 	* tree-ssa-sccvn.c (vn_reference_lookup_3): Manually compare
> 	MEM_REFs for the same base address.
>
> 	* gcc.dg/tree-ssa/ssa-fre-44.c: New testcase.
>
> Index: gcc/tree-ssa-sccvn.c
> ===================================================================
> --- gcc/tree-ssa-sccvn.c	(revision 223574)
> +++ gcc/tree-ssa-sccvn.c	(working copy)
> @@ -1894,7 +1894,12 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>         size2 = lhs_ref.size;
>         maxsize2 = lhs_ref.max_size;
>         if (maxsize2 == -1
> -	  || (base != base2 && !operand_equal_p (base, base2, 0))
> +	  || (base != base2
> +	      && (TREE_CODE (base) != MEM_REF
> +		  || TREE_CODE (base2) != MEM_REF
> +		  || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
> +		  || !tree_int_cst_equal (TREE_OPERAND (base, 1),
> +					  TREE_OPERAND (base2, 1))))
>   	  || offset2 > offset
>   	  || offset2 + size2 < offset + maxsize)
>   	return (void *)-1;
> Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-44.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-44.c	(revision 0)
> +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-44.c	(working copy)
> @@ -0,0 +1,62 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-fre1" } */
> +
> +struct A { float x, y; };
> +struct B { struct A u; };
> +void bar (struct A *);
> +
> +float
> +f1 (struct B *x, int y)
> +{
> +  struct A p;
> +  p.x = 1.0f;
> +  p.y = 2.0f;
> +  struct A *q = &x[y].u;
> +  *q = p;
> +  float f = x[y].u.x + x[y].u.y;
> +  bar (&p);
> +  return f;
> +}
> +
> +float
> +f2 (struct B *x, int y)
> +{
> +  struct A p;
> +  p.x = 1.0f;
> +  p.y = 2.0f;
> +  x[y].u = p;
> +  float f = x[y].u.x + x[y].u.y;
> +  bar (&p);
> +  return f;
> +}
> +
> +float
> +f3 (struct B *x, int y)
> +{
> +  struct A p;
> +  p.x = 1.0f;
> +  p.y = 2.0f;
> +  struct A *q = &x[y].u;
> +  __builtin_memcpy (&q->x, &p.x, sizeof (float));
> +  __builtin_memcpy (&q->y, &p.y, sizeof (float));
> +  *q = p;
> +  float f = x[y].u.x + x[y].u.y;
> +  bar (&p);
> +  return f;
> +}
> +
> +float
> +f4 (struct B *x, int y)
> +{
> +  struct A p;
> +  p.x = 1.0f;
> +  p.y = 2.0f;
> +  __builtin_memcpy (&x[y].u.x, &p.x, sizeof (float));
> +  __builtin_memcpy (&x[y].u.y, &p.y, sizeof (float));
> +  float f = x[y].u.x + x[y].u.y;
> +  bar (&p);
> +  return f;
> +}

I see this test failing on arm-none-eabi. In particular, the f4 dump is the only one
that doesn't contain "return 3.0". Instead it is:
f4 (struct B * x, int y)
{
   float f;
   struct A p;
   unsigned int y.3_5;
   unsigned int _6;
   struct B * _8;
   float * _9;
   float * _14;
   float _19;
   float _23;

   <bb 2>:
   p.x = 1.0e+0;
   p.y = 2.0e+0;
   y.3_5 = (unsigned int) y_4(D);
   _6 = y.3_5 * 8;
   _8 = x_7(D) + _6;
   _9 = &_8->u.x;
   __builtin_memcpy (_9, &p.x, 4);
   _14 = &_8->u.y;
   __builtin_memcpy (_14, &p.y, 4);
   _19 = _8->u.x;
   _23 = _8->u.y;
   f_24 = _19 + _23;
   bar (&p);
   p ={v} {CLOBBER};
   return f_24;

}

Thanks,
Kyrill


> +
> +/* { dg-final { scan-tree-dump-times "return 3.0" 4 "fre1" } } */
> +/* { dg-final { cleanup-tree-dump "fre1" } } */
>
diff mbox

Patch

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 223574)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -1894,7 +1894,12 @@  vn_reference_lookup_3 (ao_ref *ref, tree
       size2 = lhs_ref.size;
       maxsize2 = lhs_ref.max_size;
       if (maxsize2 == -1
-	  || (base != base2 && !operand_equal_p (base, base2, 0))
+	  || (base != base2
+	      && (TREE_CODE (base) != MEM_REF
+		  || TREE_CODE (base2) != MEM_REF
+		  || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
+		  || !tree_int_cst_equal (TREE_OPERAND (base, 1),
+					  TREE_OPERAND (base2, 1))))
 	  || offset2 > offset
 	  || offset2 + size2 < offset + maxsize)
 	return (void *)-1;
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-44.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-44.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-44.c	(working copy)
@@ -0,0 +1,62 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+struct A { float x, y; };
+struct B { struct A u; };
+void bar (struct A *);
+
+float
+f1 (struct B *x, int y)
+{
+  struct A p;
+  p.x = 1.0f;
+  p.y = 2.0f;
+  struct A *q = &x[y].u;
+  *q = p;
+  float f = x[y].u.x + x[y].u.y;
+  bar (&p);
+  return f;
+}
+
+float
+f2 (struct B *x, int y)
+{
+  struct A p;
+  p.x = 1.0f;
+  p.y = 2.0f;
+  x[y].u = p;
+  float f = x[y].u.x + x[y].u.y;
+  bar (&p);
+  return f;
+}
+
+float
+f3 (struct B *x, int y)
+{
+  struct A p;
+  p.x = 1.0f;
+  p.y = 2.0f;
+  struct A *q = &x[y].u;
+  __builtin_memcpy (&q->x, &p.x, sizeof (float));
+  __builtin_memcpy (&q->y, &p.y, sizeof (float));
+  *q = p;
+  float f = x[y].u.x + x[y].u.y;
+  bar (&p);
+  return f;
+}
+
+float
+f4 (struct B *x, int y)
+{
+  struct A p;
+  p.x = 1.0f;
+  p.y = 2.0f;
+  __builtin_memcpy (&x[y].u.x, &p.x, sizeof (float));
+  __builtin_memcpy (&x[y].u.y, &p.y, sizeof (float));
+  float f = x[y].u.x + x[y].u.y;
+  bar (&p);
+  return f;
+}
+
+/* { dg-final { scan-tree-dump-times "return 3.0" 4 "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */