This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, PR target/69010] Fix expand for constant boolean vectors with a scalar mode


Hi,

Currently boolean vector constant is expanded incorrectly when
it has a scalar mode.  Generated constant is incorrect and also
its mode (which is VOIDmode) is used for roce_reg which causes
ICE.  This patch fixes both problems.  Bootstrapped and tested
on x86_64-pc-linux-gnu.  OK for trunk?

Thanks,
Ilya
--
gcc/

2015-12-23  Ilya Enkovich  <enkovich.gnu@gmail.com>

	* 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/

2015-12-23  Ilya Enkovich  <enkovich.gnu@gmail.com>

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


diff --git a/gcc/expr.c b/gcc/expr.c
index bd43dc4..2183ef2 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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);
 
@@ -9745,9 +9746,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)
 	  {
@@ -11458,6 +11465,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)
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 8cc4802..ae675fb 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -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);
diff --git a/gcc/testsuite/gcc.target/i386/pr69010.c b/gcc/testsuite/gcc.target/i386/pr69010.c
new file mode 100644
index 0000000..29f66f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr69010.c
@@ -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 ();
+	}
+    }
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]