]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end/113576 - zero padding of vector bools when expanding compares
authorRichard Biener <rguenther@suse.de>
Fri, 9 Feb 2024 07:15:44 +0000 (08:15 +0100)
committerRichard Biener <rguenther@suse.de>
Wed, 14 Feb 2024 12:06:31 +0000 (13:06 +0100)
The following zeros paddings of vector bools when expanding compares
and the mode used for the compare is an integer mode.  In that case
targets cannot distinguish between a 4 element and 8 element vector
compare (both get to the QImode compare optab) so we have to do the
job in the middle-end.

PR middle-end/113576
* expr.cc (do_store_flag): For vector bool compares of vectors
with padding zero that.
* dojump.cc (do_compare_and_jump): Likewise.

gcc/dojump.cc
gcc/expr.cc

index e2d2b3cb111e01e2167f5e57268b3b556019401a..ac744e54cf89cf38e6b527ef84da19dc7c458e8c 100644 (file)
@@ -1266,6 +1266,7 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
   machine_mode mode;
   int unsignedp;
   enum rtx_code code;
+  unsigned HOST_WIDE_INT nunits;
 
   /* Don't crash if the comparison was erroneous.  */
   op0 = expand_normal (treeop0);
@@ -1308,6 +1309,21 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
       emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op1, op1));
       op1 = new_op1;
     }
+  /* For boolean vectors with less than mode precision
+     make sure to fill padding with consistent values.  */
+  else if (VECTOR_BOOLEAN_TYPE_P (type)
+          && SCALAR_INT_MODE_P (mode)
+          && TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits)
+          && maybe_ne (GET_MODE_PRECISION (mode), nunits))
+    {
+      gcc_assert (code == EQ || code == NE);
+      op0 = expand_binop (mode, and_optab, op0,
+                         GEN_INT ((1 << nunits) - 1), NULL_RTX,
+                         true, OPTAB_WIDEN);
+      op1 = expand_binop (mode, and_optab, op1,
+                         GEN_INT ((1 << nunits) - 1), NULL_RTX,
+                         true, OPTAB_WIDEN);
+    }
 
   do_compare_rtx_and_jump (op0, op1, code, unsignedp, treeop0, mode,
                           ((mode == BLKmode)
index 444f04e10cf7aed2805daf4ae28bd6a54dd927e4..e238811110e458289d368c2f4250395096ab0bc9 100644 (file)
@@ -13505,6 +13505,7 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
   rtx op0, op1;
   rtx subtarget = target;
   location_t loc = ops->location;
+  unsigned HOST_WIDE_INT nunits;
 
   arg0 = ops->op0;
   arg1 = ops->op1;
@@ -13697,6 +13698,22 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
 
   expand_operands (arg0, arg1, subtarget, &op0, &op1, EXPAND_NORMAL);
 
+  /* For boolean vectors with less than mode precision
+     make sure to fill padding with consistent values.  */
+  if (VECTOR_BOOLEAN_TYPE_P (type)
+      && SCALAR_INT_MODE_P (operand_mode)
+      && TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits)
+      && maybe_ne (GET_MODE_PRECISION (operand_mode), nunits))
+    {
+      gcc_assert (code == EQ || code == NE);
+      op0 = expand_binop (mode, and_optab, op0,
+                         GEN_INT ((1 << nunits) - 1), NULL_RTX,
+                         true, OPTAB_WIDEN);
+      op1 = expand_binop (mode, and_optab, op1,
+                         GEN_INT ((1 << nunits) - 1), NULL_RTX,
+                         true, OPTAB_WIDEN);
+    }
+
   if (target == 0)
     target = gen_reg_rtx (mode);