https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125308

--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-16 branch has been updated by Jakub Jelinek
<[email protected]>:

https://gcc.gnu.org/g:d10ef83766fc886bb76c1aadae2e5dd760e155f0

commit r16-8917-gd10ef83766fc886bb76c1aadae2e5dd760e155f0
Author: Jakub Jelinek <[email protected]>
Date:   Fri May 15 09:55:40 2026 +0200

    i386: Fix up *minmax<mode>3_4 [PR125308]

    IEEE min/max are not commutative and in the pattern
    (define_insn "ieee_<ieee_maxmin><mode>3<mask_name><round_saeonly_name>"
      [(set (match_operand:VFH 0 "register_operand" "=x,v")
            (unspec:VFH
              [(match_operand:VFH 1 "register_operand" "0,v")
               (match_operand:VFH 2 "<round_saeonly_nimm_predicate>"
"xBm,<round_saeonly_constraint>")]
              IEEE_MAXMIN))]
    the first operand is a register and only the second one is register/memory.
    Now, the *minmax<mode>3_3 define_insn_and_split does
       rtx tmp = force_reg (<MODE>mode, operands[3]);
       rtvec v = gen_rtvec (2, tmp, operands[2]);
       operands[5] = gen_rtx_UNSPEC (<MODE>mode, v, u);
    where operands[3] is the const0_operand, so operands[2] can there be
    a memory, but in the *minmax<mode>3_4 case
       rtx tmp = force_reg (<MODE>mode, operands[3]);
       rtvec v = gen_rtvec (2, operands[2], tmp);
       operands[5] = gen_rtx_UNSPEC (<MODE>mode, v, u);
    operands[2] goes into the operand which must be a REG, so it
    is incorrect to split it into something that won't work.
    Now, I've tried both disabling the define_insn_and_split and
    the following patch, the former to the latter results in
            movaps  a, %xmm0
            pxor    %xmm1, %xmm1
    -       cmpltps %xmm0, %xmm1
    -       andps   %xmm1, %xmm0
    +       maxps   %xmm1, %xmm0
            movaps  %xmm0, a
            ret
    on the testcase, so I think it is better to match it and force_reg
    (it is a pre-reload splitter) than change "nonimmediate_operand"
    to "register_operand" because it won't match in that case.

    2026-05-15  Jakub Jelinek  <[email protected]>

            PR target/125308
            * config/i386/sse.md (*minmax<mode>3_4): Force also
            operands[2] into a REG.

            * gcc.target/i386/pr125308.c: New test.

    (cherry picked from commit c96589414eeb0e46d9fe9cc1d562e048230b5f67)

Reply via email to