Patchwork Fix up simplify_binary_operation_1 for vector float AND (PR target/54703)

login
register
mail settings
Submitter Jakub Jelinek
Date Sept. 26, 2012, 9:29 a.m.
Message ID <20120926092912.GP1787@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/187031/
State New
Headers show

Comments

Jakub Jelinek - Sept. 26, 2012, 9:29 a.m.
Hi!

At least i?86 and rs6000 backends use V*[SD]F AND/IOR/XOR/NOT
operations, seems most of the simplify-rtx.c code is properly guarded for
that with INTEGRAL_MODE_P (mode), but the
(x - (x & y)) -> (x & ~y)
optimization was not, eventhough it is only valid for integral modes.
Fixed thusly, bootstrapped/regtested on x86_64-linux/i686-linux, ok for
trunk/4.7?

2012-09-26  Jakub Jelinek  <jakub@redhat.com>

	PR target/54703
	* simplify-rtx.c (simplify_binary_operation_1): Perform
	(x - (x & y)) -> (x & ~y) optimization only for integral
	modes.

	* gcc.target/i386/pr54703.c: New test.


	Jakub
Richard Guenther - Sept. 26, 2012, 10:31 a.m.
On Wed, Sep 26, 2012 at 11:29 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> At least i?86 and rs6000 backends use V*[SD]F AND/IOR/XOR/NOT
> operations, seems most of the simplify-rtx.c code is properly guarded for
> that with INTEGRAL_MODE_P (mode), but the
> (x - (x & y)) -> (x & ~y)
> optimization was not, eventhough it is only valid for integral modes.
> Fixed thusly, bootstrapped/regtested on x86_64-linux/i686-linux, ok for
> trunk/4.7?

Ok.

Thanks,
Richard.

> 2012-09-26  Jakub Jelinek  <jakub@redhat.com>
>
>         PR target/54703
>         * simplify-rtx.c (simplify_binary_operation_1): Perform
>         (x - (x & y)) -> (x & ~y) optimization only for integral
>         modes.
>
>         * gcc.target/i386/pr54703.c: New test.
>
> --- gcc/simplify-rtx.c.jj       2012-09-25 11:59:44.000000000 +0200
> +++ gcc/simplify-rtx.c  2012-09-25 16:02:39.309652457 +0200
> @@ -2239,7 +2239,7 @@ simplify_binary_operation_1 (enum rtx_co
>                                     neg_const_int (mode, op1));
>
>        /* (x - (x & y)) -> (x & ~y) */
> -      if (GET_CODE (op1) == AND)
> +      if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
>         {
>           if (rtx_equal_p (op0, XEXP (op1, 0)))
>             {
> --- gcc/testsuite/gcc.target/i386/pr54703.c.jj  2012-09-25 16:19:19.017248505 +0200
> +++ gcc/testsuite/gcc.target/i386/pr54703.c     2012-09-25 16:21:10.740650488 +0200
> @@ -0,0 +1,36 @@
> +/* PR target/54703 */
> +/* { dg-do run { target sse2_runtime } } */
> +/* { dg-options "-O -msse2" } */
> +/* { dg-additional-options "-mavx -mtune=bdver1" { target avx_runtime } } */
> +
> +extern void abort (void);
> +typedef double V __attribute__((vector_size(16)));
> +
> +union {
> +  unsigned long long m[2];
> +  V v;
> +} u = { { 0xffffffffff000000ULL, 0xffffffffff000000ULL } };
> +
> +static inline V
> +foo (V x)
> +{
> +  V y = __builtin_ia32_andpd (x, u.v);
> +  V z = __builtin_ia32_subpd (x, y);
> +  return __builtin_ia32_mulpd (y, z);
> +}
> +
> +void
> +test (V *x)
> +{
> +  V a = { 2.1, 2.1 };
> +  *x = foo (foo (a));
> +}
> +
> +int
> +main ()
> +{
> +  test (&u.v);
> +  if (u.m[0] != 0x3acbf487f0a30550ULL || u.m[1] != u.m[0])
> +    abort ();
> +  return 0;
> +}
>
>         Jakub

Patch

--- gcc/simplify-rtx.c.jj	2012-09-25 11:59:44.000000000 +0200
+++ gcc/simplify-rtx.c	2012-09-25 16:02:39.309652457 +0200
@@ -2239,7 +2239,7 @@  simplify_binary_operation_1 (enum rtx_co
 				    neg_const_int (mode, op1));
 
       /* (x - (x & y)) -> (x & ~y) */
-      if (GET_CODE (op1) == AND)
+      if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
 	{
 	  if (rtx_equal_p (op0, XEXP (op1, 0)))
 	    {
--- gcc/testsuite/gcc.target/i386/pr54703.c.jj	2012-09-25 16:19:19.017248505 +0200
+++ gcc/testsuite/gcc.target/i386/pr54703.c	2012-09-25 16:21:10.740650488 +0200
@@ -0,0 +1,36 @@ 
+/* PR target/54703 */
+/* { dg-do run { target sse2_runtime } } */
+/* { dg-options "-O -msse2" } */
+/* { dg-additional-options "-mavx -mtune=bdver1" { target avx_runtime } } */
+
+extern void abort (void);
+typedef double V __attribute__((vector_size(16)));
+
+union {
+  unsigned long long m[2];
+  V v;
+} u = { { 0xffffffffff000000ULL, 0xffffffffff000000ULL } };
+
+static inline V
+foo (V x)
+{
+  V y = __builtin_ia32_andpd (x, u.v);
+  V z = __builtin_ia32_subpd (x, y);
+  return __builtin_ia32_mulpd (y, z);
+}
+
+void
+test (V *x)
+{
+  V a = { 2.1, 2.1 };
+  *x = foo (foo (a));
+}
+
+int
+main ()
+{
+  test (&u.v);
+  if (u.m[0] != 0x3acbf487f0a30550ULL || u.m[1] != u.m[0])
+    abort ();
+  return 0;
+}