middle-end/97521 - always use single-bit bools in mask vector types
authorRichard Biener <rguenther@suse.de>
Fri, 23 Oct 2020 06:40:15 +0000 (08:40 +0200)
committerRichard Biener <rguenther@suse.de>
Mon, 26 Oct 2020 11:28:30 +0000 (12:28 +0100)
This makes us always use a single-bit boolean type component type
for integer mode mask VECTOR_BOOLEAN_TYPE_P to match the RTL and target
representation.  This aovids the need for magic translation and
the inconsistencies from the translation requirement now that
we expose temporaries of those types on the GIMPLE level.

2020-10-23  Richard Biener  <rguenther@suse.de>

PR middle-end/97521
* expr.c (const_scalar_mask_from_tree): Remove.
(expand_expr_real_1): Always VIEW_CONVERT integer mode
vector constants to an integer type.
* tree.c (build_truth_vector_type_for_mode): Use a single-bit
boolean component type for non-vector-mode mask_mode.

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

gcc/expr.c
gcc/testsuite/gcc.target/i386/pr97521.c [new file with mode: 0644]
gcc/tree.c

index 9d951e82522f58308c786ba49ef73ebf810511a6..ae16f07775870792729e3805436d7f2debafb6ca 100644 (file)
@@ -96,7 +96,6 @@ static void emit_single_push_insn (machine_mode, rtx, tree);
 static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx,
                          profile_probability);
 static rtx const_vector_from_tree (tree);
-static rtx const_scalar_mask_from_tree (scalar_int_mode, tree);
 static tree tree_expr_size (const_tree);
 static HOST_WIDE_INT int_expr_size (tree);
 static void convert_mode_scalar (rtx, rtx, int);
@@ -10356,16 +10355,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
        scalar_int_mode int_mode;
        if (is_int_mode (mode, &int_mode))
          {
-           if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
-             return const_scalar_mask_from_tree (int_mode, exp);
-           else
-             {
-               tree type_for_mode
-                 = lang_hooks.types.type_for_mode (int_mode, 1);
-               if (type_for_mode)
-                 tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
-                                       type_for_mode, exp);
-             }
+           tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1);
+           if (type_for_mode)
+             tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
+                                   type_for_mode, exp);
          }
        if (!tmp)
          {
@@ -12739,30 +12732,6 @@ const_vector_mask_from_tree (tree exp)
   return builder.build ();
 }
 
-/* EXP is a VECTOR_CST in which each element is either all-zeros or all-ones.
-   Return a constant scalar rtx of mode MODE in which bit X is set if element
-   X of EXP is nonzero.  */
-static rtx
-const_scalar_mask_from_tree (scalar_int_mode mode, tree exp)
-{
-  wide_int res = wi::zero (GET_MODE_PRECISION (mode));
-  tree elt;
-
-  /* The result has a fixed number of bits so the input must too.  */
-  unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
-  for (unsigned int i = 0; i < nunits; ++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/testsuite/gcc.target/i386/pr97521.c b/gcc/testsuite/gcc.target/i386/pr97521.c
new file mode 100644 (file)
index 0000000..804ffd6
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-O -mno-sse2" } */
+
+typedef unsigned char __attribute__ ((__vector_size__ (8))) V;
+typedef unsigned long long __attribute__ ((__vector_size__ (16))) W;
+
+V c;
+W d, e;
+
+V
+foo (W f)
+{
+  W g = (W) { 0, 209 } <7 <= (0 < f);
+  W h = e + g + d;
+  V j = (V) (h[0]) + (V) c;
+  return j;
+}
+
+int
+main (void)
+{
+  V x = foo ((W) { 3 });
+  for (unsigned i = 0; i < sizeof (x); i++)
+    if (x[i] != 0xff)
+      __builtin_abort ();
+  return 0;
+}
index fa03d963eedea8d500c778bd6c041d00c78a6c63..6759ac8179a339753601f7e535c46f9e8f324404 100644 (file)
@@ -10926,8 +10926,15 @@ build_truth_vector_type_for_mode (poly_uint64 nunits, machine_mode mask_mode)
 {
   gcc_assert (mask_mode != BLKmode);
 
-  poly_uint64 vsize = GET_MODE_BITSIZE (mask_mode);
-  unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits);
+  unsigned HOST_WIDE_INT esize;
+  if (VECTOR_MODE_P (mask_mode))
+    {
+      poly_uint64 vsize = GET_MODE_BITSIZE (mask_mode);
+      esize = vector_element_size (vsize, nunits);
+    }
+  else
+    esize = 1;
+
   tree bool_type = build_nonstandard_boolean_type (esize);
 
   return make_vector_type (bool_type, nunits, mask_mode);