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.
This commit is contained in:
Richard Biener 2024-02-09 08:15:44 +01:00
parent bbb30f12a7
commit 5352ede924
2 changed files with 33 additions and 0 deletions

View 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)

View 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);