The following fixes PR77833.

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

Richard.

2016-10-04  Richard Biener  <rguent...@suse.de>

        PR middle-end/77833
        * explow.c (plus_constant): Verify the mode of the constant
        pool offset before calling plus_constant.

        * gcc.target/i386/pr77833.c: New testcase.

Index: gcc/explow.c
===================================================================
--- gcc/explow.c        (revision 240739)
+++ gcc/explow.c        (working copy)
@@ -114,12 +114,15 @@ plus_constant (machine_mode mode, rtx x,
              cst = gen_lowpart (mode, cst);
              gcc_assert (cst);
            }
-         tem = plus_constant (mode, cst, c);
-         tem = force_const_mem (GET_MODE (x), tem);
-         /* Targets may disallow some constants in the constant pool, thus
-            force_const_mem may return NULL_RTX.  */
-         if (tem && memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
-           return tem;
+         if (GET_MODE (cst) == VOIDmode || GET_MODE (cst) == mode)
+           {
+             tem = plus_constant (mode, cst, c);
+             tem = force_const_mem (GET_MODE (x), tem);
+             /* Targets may disallow some constants in the constant pool, thus
+                force_const_mem may return NULL_RTX.  */
+             if (tem && memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
+               return tem;
+           }
        }
       break;
 
Index: gcc/testsuite/gcc.target/i386/pr77833.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr77833.c     (revision 0)
+++ gcc/testsuite/gcc.target/i386/pr77833.c     (working copy)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mavx512f" } */
+
+typedef unsigned long V __attribute__((vector_size(64)));
+typedef unsigned __int128 W __attribute__((vector_size(64)));
+
+V
+foo(int i, V v)
+{
+  i *= ((W)(V){0, 0, 0, 0, 0, 1, v[0]})[2];
+  v[i] = 0;
+  i--;
+  return v + i;
+}

Reply via email to