https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126771
Bug ID: 126771
Summary: sub-optimal bool pattern for comparison converted to
integer
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: rguenth at gcc dot gnu.org
CC: tnfchris at gcc dot gnu.org
Blocks: 53947
Target Milestone: ---
Target: x86_64-*-*, aarch64-*-*, riscv-*-*
int foo (double g, double *r, int n)
{
int hu = 0;
bool test0 = r[0] < g;
bool test1 = r[1] < g;
hu += test0 + test1;
return hu;
}
shows, on x86_64 with AVX512 (like -march=znver5):
vector(2) int vect_patt_12.8;
vector(2) unsigned long vect_patt_11.7;
vector(2) <signed-boolean:1> mask_test0_9.6;
...
mask_test0_9.6_18 = vect__1.5_16 < _17;
vect_patt_11.7_19 = VEC_COND_EXPR <mask_test0_9.6_18, { 1, 1 }, { 0, 0 }>;
vect_patt_12.8_20 = (vector(2) int) vect_patt_11.7_19;
rather than using a (vector(2) int) VEC_COND_EXPR directly.
This is due to how vect_recog_bool_pattern behaves for the conversion
of the bool result comparison. In particular with AVX512
integer_type_for_mask yields a 64bit integer, so we do not seem to
anticipate that we use a mask type for it and for "size agnostic masks"
always do
/* We may directly use cond with narrowed type to avoid multiple cond
exprs with following result packing and perform single cond with
packed mask instead. In case of widening we better make cond first
and then extract results. */
if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (lhs)))
type = TREE_TYPE (lhs);
ISTR on aarch64 SVE masks are still "unpacked", but RISC-V has one bit per
lane. I'm unsure how we make sure a scalar mask type is suitable for
the cond-expr here, possibly by trying to build an actual vector mask?
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53947
[Bug 53947] [meta-bug] vectorizer missed-optimizations