aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-02-09 08:15:44 +0100
committerRichard Biener <rguenther@suse.de>2024-02-14 13:06:31 +0100
commit5352ede92483b949e811cbdcdfaec5378f3e06d6 (patch)
treee2bb6631b7c03abf140a8130c9e83ad90dac63a3 /gcc
parentbbb30f12a7e5ce008f59ec26c9e4cc65ee79fe56 (diff)
downloadgcc-5352ede92483b949e811cbdcdfaec5378f3e06d6.zip
gcc-5352ede92483b949e811cbdcdfaec5378f3e06d6.tar.gz
gcc-5352ede92483b949e811cbdcdfaec5378f3e06d6.tar.bz2
middle-end/113576 - zero padding of vector bools when expanding compares
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/dojump.cc16
-rw-r--r--gcc/expr.cc17
2 files changed, 33 insertions, 0 deletions
diff --git a/gcc/dojump.cc b/gcc/dojump.cc
index e2d2b3c..ac744e5 100644
--- a/gcc/dojump.cc
+++ b/gcc/dojump.cc
@@ -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)
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 444f04e..e238811 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -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);