gnu/gcc/48c2ea1750efe48723dbb04a77d0deb3e242f35f PR target/123238: VCOND_MASK regression on x86_64.
This patch is my revised fix for (the regression aspects of) PR123238,
a code quality regression on x86_64 triggered by the generation of
VCOND_MASK. The regression is actually just bad luck. From gimple,
VCOND_MASK(a==b,c,d) is equivalent to VCOND_MASK(a!=b,d,c), and which
form gets generated was previously arbitrary. This is reasonable for
many (most?) targets, but on x86_64 there's an asymmetry, equality
can be performed in 1 instruction, but inequality requires three.
Teaching the middle-end's expand pass which form is preferred could
in theory be done with a new (very specific) target hook, that would
require documentation, but a more generic solution is for expand's
expand_vec_cond_mask_optab_fn to make use of rtx_costs, and reverse
the sense of VCOND_MASK if that would be an improvement. This has
the convenient property that the default rtx_costs of all comparison
operators is the same, resulting in no change unless explicitly
specified by the backend.
This revision incorporates the feedback from both Andrew Pinksi and
Richard Biener, using get_gimple_for_ssa_name instead of
SSA_NAME_DEF_STMT, and Andrew's suggestion to log expand's
decision to the dump file, which now contains lines such as:
;; swapping operands of .VCOND_MASK
;; cost of original ne: 8
;; cost of replacement eq: 4
or (for failure)
;; not swapping operands of .VCOND_MASK
;; cost of original eq: 4
;; cost of replacement ne: 8
Thanks to Richard and Hongtao for approvals.
2026-04-01 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR target/123238
* expr.cc (convert_tree_comp_to_rtx): Make global.
* expr.h (convert_tree_comp_to_rtx): Prototype here.
* internal-fn.cc (expand_vec_cond_mask_optab_fn): Use rtx_costs
to determine whether swapping operands would result in better
code.
* config/i386/i386-expand.cc (ix86_expand_int_vec_cmp): On
AVX512 targets use a ternlog instead of a comparison to negate
the mask (requires one instruction instead of two).
* config/i386/i386.cc (ix86_rtx_costs): Refactor code for UNSPEC.
Provide costs for UNSPEC_BLENDV and UNSPEC_MOVMSK. Provide
costs for comparison operators of integer vector modes.
gcc/testsuite/ChangeLog
PR target/123238
* gcc.target/i386/pr123238.c: Likewise.
6 files changed