re PR target/69010 (Boolean vector constant with a scalar mode is expanded incorrectly)
authorIlya Enkovich <enkovich.gnu@gmail.com>
Mon, 11 Jan 2016 10:27:17 +0000 (10:27 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Mon, 11 Jan 2016 10:27:17 +0000 (10:27 +0000)
gcc/

PR target/69010
* expr.c (expand_expr_real_1): For boolean vector constants
with a scalar mode use const_scalar_mask_from_tree.
(const_scalar_mask_from_tree): New.
* optabs.c (expand_vec_cond_mask_expr): Use mask mode
assigned to a mask type to handle constants.

gcc/testsuite/

PR target/69010
* gcc.target/i386/pr69010.c: New test.

From-SVN: r232216

gcc/ChangeLog
gcc/expr.c
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr69010.c [new file with mode: 0644]

index f28cf448312aff96692af03a95900e748c80123f..bfdefb91ce50d1f5fc83070c75368d96b184be6a 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-11  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       PR target/69010
+       * expr.c (expand_expr_real_1): For boolean vector constants
+       with a scalar mode use const_scalar_mask_from_tree.
+       (const_scalar_mask_from_tree): New.
+       * optabs.c (expand_vec_cond_mask_expr): Use mask mode
+       assigned to a mask type to handle constants.
+
 2016-01-11  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/69044
index 0c5dff8be97a67d7724616d615e1aa9b34d4922a..0a1c4259bb54dda2f2dffa77806fcb3acda17125 100644 (file)
@@ -137,6 +137,7 @@ static void emit_single_push_insn (machine_mode, rtx, tree);
 #endif
 static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx, int);
 static rtx const_vector_from_tree (tree);
+static rtx const_scalar_mask_from_tree (tree);
 static tree tree_expr_size (const_tree);
 static HOST_WIDE_INT int_expr_size (tree);
 
@@ -9742,9 +9743,15 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
          return const_vector_from_tree (exp);
        if (GET_MODE_CLASS (mode) == MODE_INT)
          {
-           tree type_for_mode = lang_hooks.types.type_for_mode (mode, 1);
-           if (type_for_mode)
-             tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, type_for_mode, exp);
+           if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
+             return const_scalar_mask_from_tree (exp);
+           else
+             {
+               tree type_for_mode = lang_hooks.types.type_for_mode (mode, 1);
+               if (type_for_mode)
+                 tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
+                                       type_for_mode, exp);
+             }
          }
        if (!tmp)
          {
@@ -11455,6 +11462,29 @@ const_vector_mask_from_tree (tree exp)
   return gen_rtx_CONST_VECTOR (mode, v);
 }
 
+/* Return a CONST_INT rtx representing vector mask for
+   a VECTOR_CST of booleans.  */
+static rtx
+const_scalar_mask_from_tree (tree exp)
+{
+  machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
+  wide_int res = wi::zero (GET_MODE_PRECISION (mode));
+  tree elt;
+  unsigned i;
+
+  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+    {
+      elt = VECTOR_CST_ELT (exp, i);
+      gcc_assert (TREE_CODE (elt) == INTEGER_CST);
+      if (integer_all_onesp (elt))
+       res = wi::set_bit (res, i);
+      else
+       gcc_assert (integer_zerop (elt));
+    }
+
+  return immed_wide_int_const (res, mode);
+}
+
 /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
 static rtx
 const_vector_from_tree (tree exp)
index d9c118369bb5e4a89e4bc1c3f87efa5ef5c5444c..e1ba61504732e4cf8be0149ca6d2991e23a717e3 100644 (file)
@@ -5547,7 +5547,7 @@ expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
   rtx_op1 = expand_normal (op1);
   rtx_op2 = expand_normal (op2);
 
-  mask = force_reg (GET_MODE (mask), mask);
+  mask = force_reg (mask_mode, mask);
   rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
 
   create_output_operand (&ops[0], target, mode);
index 69f589f281c584e4f9c482feef9d8b3c2c069607..cabef26023e88cb897c3eb36f5351676204c86e8 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-11  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       PR target/69010
+       * gcc.target/i386/pr69010.c: New test.
+
 2016-01-11  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/69044
diff --git a/gcc/testsuite/gcc.target/i386/pr69010.c b/gcc/testsuite/gcc.target/i386/pr69010.c
new file mode 100644 (file)
index 0000000..29f66f4
--- /dev/null
@@ -0,0 +1,49 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -mavx512bw" } */
+/* { dg-require-effective-target avx512bw } */
+
+#define AVX512BW
+#include "avx512f-helper.h"
+
+extern void abort (void);
+
+void __attribute__((noinline,noclone))
+test1 (int *a, int *b, int *c)
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    {
+      if ((i == 0) || (i == 3))
+       a[i] = b[i];
+      else
+       a[i] = c[i];
+    }
+}
+
+void
+TEST ()
+{
+  int a[16], b[16], c[16], i;
+
+  for (i = 0; i < 16; i++)
+    {
+      a[i] = i;
+      b[i] = -i;
+    }
+
+  test1 (a, b, c);
+
+  for (i = 0; i < 16; i++)
+    {
+      if ((i == 0) || (i == 3))
+       {
+         if (a[i] != b[i])
+           abort ();
+       }
+      else
+       {
+         if (a[i] != c[i])
+           abort ();
+       }
+    }
+}