> -----Original Message-----
> From: Richard Biener <[email protected]>
> Sent: Tuesday, July 21, 2026 9:52 PM
> To: [email protected]
> Cc: Liu, Hongtao <[email protected]>; [email protected]
> Subject: [PATCH] target/126328 - [x86] insn_cost of
> *sse3_h{add,sub}v2df3[_low]
>
> I run into issues with gcc.target/i386/pr54400.c when SLP vectorizing a
> horizontal reduction of a V2DF vector. The following plugs the remaining hole
> in costing which prevents combine from doing its work to recover the single
> hadd instruction for { p[0] + p[1], q[0] + q[1] }
>
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
>
> OK for trunk if testing succeeds?
>
> To have an effect it depends on the prerequesite [v2] Simplify
> (vec_select:<scalar> (vec_concat ..)) and unless Support two-lane vector BB
> reductions without target support is installed gcc.target/i386/pr54400.c is
> passing anyway.
>
> PR target/126328
> * config/i386/i386.cc (ix86_insn_cost): Match
> *sse3_h{add,sub}v2df3[_low] and cost it like an add.
> ---
> gcc/config/i386/i386.cc | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index
> 56a90333cfc..ab04290bf7c 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -22714,6 +22714,27 @@ ix86_insn_cost (rtx_insn *insn, bool speed)
> : COSTS_N_INSNS (3) + 1;
> }
> }
> + if (rtx set = single_set (insn))
> + {
> + rtx src = SET_SRC (set);
> + /* ix86_rtx_cost makes VEC_CONCAT artificially cheap by not recursing
> + into operands. That makes *sse3_haddv2df3 win over
> + *sse3_haddv2df3_low, preventing combine from doing its work for
> + gcc.target/i386/pr54400.c. Cost both the same explicitly. */
> + if ((GET_MODE (src) == V2DFmode
> + && GET_CODE (src) == VEC_CONCAT
> + && (GET_CODE (XEXP (src, 0)) == PLUS
> + || GET_CODE (XEXP (src, 0)) == MINUS)
> + && GET_CODE (XEXP (XEXP (src, 0), 0)) == VEC_SELECT)
> + || (GET_MODE (src) == DFmode
> + && (GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
> + && GET_CODE (XEXP (src, 0)) == VEC_SELECT
> + && GET_CODE (XEXP (src, 1)) == VEC_SELECT))
> + /* Assume this is only recognized as *sse3_h{add,sub}v2df3[_low].
> */
> + return insn_cost + ix86_vec_cost (GET_MODE (pat),
> + (speed ? ix86_tune_cost
> + : &ix86_size_cost)->addss);
GET_MODE (pat) returns VOIDmode since pat is a SET - you likely intended to use
V2DFmode here. Alternatively, we could simply drop ix86_vec_cost since it is
only used in the vectorization cost model and not in rtx_cost.
In that case, we could just return:
insn_cost + (speed ? ix86_tune_cost : &ix86_size_cost)->addss;
Also, regarding the fix you proposed for combine [1] - with that fix in place,
would it be possible to use insn_attr instead of structural pattern matching in
this patch?
[1] https://gcc.gnu.org/pipermail/gcc-patches/2026-July/724837.html
> + }
>
> return insn_cost + pattern_cost (pat, speed); }
> --
> 2.51.0