[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 Richard Biener changed: What|Removed |Added Target Milestone|15.3|16.0
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 Hongtao Liu changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #28 from Hongtao Liu --- Fixed in GCC16.
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 --- Comment #27 from GCC Commits --- The master branch has been updated by hongtao Liu : https://gcc.gnu.org/g:106e001b4bb5313a8d59b858e80d5633f90fcec0 commit r16-5846-g106e001b4bb5313a8d59b858e80d5633f90fcec0 Author: liuhongt Date: Mon Dec 1 00:51:26 2025 -0800 Transform std::max(t, float(0)) into vmaxps w/o fast-math. The pattern is simplied to below since there's const0_operand (set (reg:V8SF 124) (and:V8SF (not:V8SF (lt:V8SF (reg:V8SF 123 [ MEM [(const float *)input_12(D) + ivtmp.30_4 * 1] ]) (const_vector:V8SF [ (const_double:SF 0.0 [0x0.0p+0]) repeated x8 ]))) (reg:V8SF 123 [ MEM [(const float *)input_12(D) + ivtmp.30_4 * 1] ])) Add new combine pattern to match it. Also extend related avx512 pattern to accept immediate_operand, so that the optimization is also available under AVX512. The codegen is now better than before, however, vpxor is not hoisted outside of the loop after it's created in split1. gcc/ChangeLog: PR target/71921 * config/i386/predicates.md (ieee_maxmin_comparison_operator): New predicator. * config/i386/sse.md (*minmax3_3): New define_insn_and_split. (*minmax3_4): Ditto. (*minmax3_1): Extend operands[2]/operands[4] to handle immediate_operand. gcc/testsuite/ChangeLog: * g++.target/i386/avx512-pr71921.C: New test. * g++.target/i386/pr71921.C: New test.
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 --- Comment #26 from Hongtao Liu --- > which should have same semantics as x86 min/max, and the backend need to > support those variants for it. w/ more combine pattern, now it generates .L4: vxorps %xmm0, %xmm0, %xmm0 vmaxps (%rsi,%rax), %ymm0, %ymm0 vmovups %ymm0, (%rdi,%rax) addq$32, %rax cmpq%rax, %r8 jne .L4 Looks like after split1, there's no loop inviriant motion and failed to hoist vxorps outside. Similar for the testcase in #c16 .L4: vxorps %xmm0, %xmm0, %xmm0 vmaxps (%rsi,%rax), %ymm0, %ymm0 vmovups %ymm0, (%rdi,%rax) addq$32, %rax cmpq%rax, %r8 jne .L4 But it should still better than before since vxorps is cheap.
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921
Hongtao Liu changed:
What|Removed |Added
CC||liuhongt at gcc dot gnu.org
--- Comment #25 from Hongtao Liu ---
(In reply to Richard Biener from comment #24)
> The testcase in the description works with GCC 15, the testcase in comment
> 16 does not. Neither works with GCC 16 for me.
>
> The x86 backend has ix86_expand_fp_movcc for scalar operations to detect
> min/max, for vector it relies on combine IIRC.
>
> We are not exposing the mask generation upon RTL expansion,
> expand_vec_cond_mask_optab_fn does not try to TER here and
> ix86_expand_sse_movcc
> does
>
> else if (op_false == CONST0_RTX (mode))
> {
> x = expand_simple_binop (mode, AND, cmp, op_true,
>dest, 1, OPTAB_DIRECT);
> if (x != dest)
> emit_move_insn (dest, x);
>
> hereby confusing the existing combiner patterns (in general if this does not
> match to min/max that's of course a good optimization).
I saw the pattern is simplified to
(set (reg:V8SF 124)
(and:V8SF (not:V8SF (lt:V8SF (reg:V8SF 123 [ MEM
[(const float *)input_12(D) + ivtmp.30_4 * 1] ])
(const_vector:V8SF [
(const_double:SF 0.0 [0x0.0p+0]) repeated x8
])))
(reg:V8SF 123 [ MEM [(const float *)input_12(D)
+ ivtmp.30_4 * 1] ])))
which should have same semantics as x86 min/max, and the backend need to
support those variants for it.
BTW the testcase in the description works for GCC trunk with
-march=sapphirerapids/znver5 -O3, but not for -march=x86-64-v3.
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921
Richard Biener changed:
What|Removed |Added
CC||crazylht at gmail dot com
--- Comment #24 from Richard Biener ---
The testcase in the description works with GCC 15, the testcase in comment 16
does not. Neither works with GCC 16 for me.
The x86 backend has ix86_expand_fp_movcc for scalar operations to detect
min/max, for vector it relies on combine IIRC.
We are not exposing the mask generation upon RTL expansion,
expand_vec_cond_mask_optab_fn does not try to TER here and
ix86_expand_sse_movcc
does
else if (op_false == CONST0_RTX (mode))
{
x = expand_simple_binop (mode, AND, cmp, op_true,
dest, 1, OPTAB_DIRECT);
if (x != dest)
emit_move_insn (dest, x);
hereby confusing the existing combiner patterns (in general if this does not
match to min/max that's of course a good optimization).
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 Richard Biener changed: What|Removed |Added Priority|P3 |P2
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 Richard Biener changed: What|Removed |Added Target Milestone|15.2|15.3 --- Comment #23 from Richard Biener --- GCC 15.2 is being released, retargeting bugs to 15.3.
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 --- Comment #22 from Andrew Pinski --- (In reply to Andrew Pinski from comment #21) > Trying 22 -> 27: >22: r118:V4SF=r113:V4SF REG_EQUAL r113:V4SF27: r121:V4SF=~r118:V4SF&r113:V4SF > REG_DEAD r118:V4SF > REG_DEAD r113:V4SF > Failed to match this instruction: > (set (reg:V4SF 121) > (and:V4SF (not:V4SF (lt:V4SF (reg:V4SF 113 [ MEM > [(const float *)input_12(D) + ivtmp.21_83 * 1] ]) > (const_vector:V4SF [ > (const_double:SF 0.0 [0x0.0p+0]) repeated x4 > ]))) > (reg:V4SF 113 [ MEM [(const float > *)input_12(D) + ivtmp.21_83 * 1] ]))) > > > Since we know the vector is 0, this should be changed to: > (if_then_else (lt r113 0) 0 r113) > > Which then can be recongized ... Or the backend could recognize the and not form ...
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 --- Comment #21 from Andrew Pinski --- Trying 22 -> 27: 22: r118:V4SF=r113:V4SF [(const float *)input_12(D) + ivtmp.21_83 * 1] ]) (const_vector:V4SF [ (const_double:SF 0.0 [0x0.0p+0]) repeated x4 ]))) (reg:V4SF 113 [ MEM [(const float *)input_12(D) + ivtmp.21_83 * 1] ]))) Since we know the vector is 0, this should be changed to: (if_then_else (lt r113 0) 0 r113) Which then can be recongized ...
[Bug target/71921] [15/16 Regression] missed vectorization optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71921 Andrew Pinski changed: What|Removed |Added Target Milestone|--- |15.2
