On Tue, Aug 5, 2025 at 12:19 PM Richard Sandiford
<richard.sandif...@arm.com> wrote:
>
> The i386 high-register patterns used things like:
>
>     (match_operator:SWI248 2 "extract_operator"
>       [(match_operand 0 "int248_register_operand" "Q")
>        (const_int 8)
>        (const_int 8)])
>
> to match an extraction of a high register such as AH from AX/EAX/RAX.
>
> This construct is used in contexts where only the low 8 bits of the
> value matter.  This is either done explicitly using a (subreg:QI ... 0)
> or implicitly by assigning to an 8-bit zero_extract destination.
>
> extract_operator therefore matches both sign_extract and zero_extract,
> since the signedness of the extension beyond 8 bits is irrelevant.
>
> But the fact that only the low 8 bits of the value are significant
> means that a shift right by 8 is as good as an extraction.  Shifts
> right would already be used for things like:
>
>   struct s {
>     long a:8;
>     long b:8;
>     long c:48;
>   };
>
>   struct s f(struct s x, long y, long z) {
>     x.b = (y & z) >> 8;
>     return x;
>   }
>
> but are used more after g:965564eafb721f8000013a3112f1bba8d8fae32b.
>
> This patch therefore replaces extract_operator with a new predicate
> called extract_high_operator that matches both extractions and shifts.
> The predicate checks the extraction field and shift amount itself,
> so that patterns only need to match the first operand.
>
> Splitters used match_op_dup to preserve the choice of extraction.
> But the fact that the extractions (and now shifts) are equivalent
> means that we can just as easily canonicalise on one of them.
> (In theory, canonicalisation would also promote CSE, although
> that's unlikely in practice.)  The patch goes for zero_extract,
> for consistency with destinations.
>
> I think this should go in before:
>
>   https://gcc.gnu.org/pipermail/gcc-patches/2025-August/691581.html
>
> and follow-ups, since on its own the patches there will regress
> other gcc.target/i386 tests.
>
> Bootstrapped & regression-tested on x86_64-linux-gnu (with {,-m32}).
> OK to install?
>
> Richard
>
>
> gcc/
>         PR target/121306
>         * config/i386/predicates.md (extract_operator): Replace with...
>         (extract_high_operator): ...this new predicate.
>         * config/i386/i386.md (*cmpqi_ext<mode>_1, *cmpqi_ext<mode>_2)
>         (*cmpqi_ext<mode>_3, *cmpqi_ext<mode>_4, *movstrictqi_ext<mode>_1)
>         (*extzv<mode>, *insvqi_2, *extendqi<SWI24:mode>_ext_1)
>         (*addqi_ext<mode>_1_slp, *addqi_ext<mode>_1_slp, *addqi_ext<mode>_0)
>         (*addqi_ext2<mode>_0, *addqi_ext<mode>_1, *<insn>qi_ext<mode>_2)
>         (*subqi_ext<mode>_1_slp, *subqi_ext<mode>_2_slp, *subqi_ext<mode>_0)
>         (*subqi_ext2<mode>_0, *subqi_ext<mode>_1, *testqi_ext<mode>_1)
>         (*testqi_ext<mode>_2, *<code>qi_ext<mode>_1_slp)
>         (*<code>qi_ext<mode>_2_slp. *<code>qi_ext<mode>_0)
>         (*<code>qi_ext2<mode>_0, *<code>qi_ext<mode>_1)
>         (*<code>qi_ext<mode>_1_cc, *<code>qi_ext<mode>_1_cc)
>         (*<code>qi_ext<mode>_2, *<code>qi_ext<mode>_3, *negqi_ext<mode>_1)
>         (*one_cmplqi_ext<mode>_1, *ashlqi_ext<mode>_1, *<insn>qi_ext<mode>_1)
>         (define_peephole2): Replace uses of extract_operator with
>         extract_high_operator, matching only the first operand.
>         Use zero_extract rather than match_op_dup when splitting.

OK.

Thanks,
Uros.

> ---
>  gcc/config/i386/i386.md       | 400 +++++++++++++---------------------
>  gcc/config/i386/predicates.md |   8 +-
>  2 files changed, 162 insertions(+), 246 deletions(-)
>
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index a50475bdaf4..fa82ace0e10 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -1618,10 +1618,8 @@ (define_insn "*cmpqi_ext<mode>_1"
>         (compare
>           (match_operand:QI 0 "nonimmediate_operand" "QBn")
>           (subreg:QI
> -           (match_operator:SWI248 2 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))]
> +           (match_operator:SWI248 2 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)))]
>    "ix86_match_ccmode (insn, CCmode)"
>    "cmp{b}\t{%h1, %0|%0, %h1}"
>    [(set_attr "addr" "gpr8")
> @@ -1632,10 +1630,8 @@ (define_insn "*cmpqi_ext<mode>_2"
>    [(set (reg FLAGS_REG)
>         (compare
>           (subreg:QI
> -           (match_operator:SWI248 2 "extract_operator"
> -             [(match_operand 0 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 2 "extract_high_operator"
> +             [(match_operand 0 "int248_register_operand" "Q")]) 0)
>           (match_operand:QI 1 "const0_operand")))]
>    "ix86_match_ccmode (insn, CCNOmode)"
>    "test{b}\t%h0, %h0"
> @@ -1657,10 +1653,8 @@ (define_insn "*cmpqi_ext<mode>_3"
>    [(set (reg FLAGS_REG)
>         (compare
>           (subreg:QI
> -           (match_operator:SWI248 2 "extract_operator"
> -             [(match_operand 0 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 2 "extract_high_operator"
> +             [(match_operand 0 "int248_register_operand" "Q")]) 0)
>           (match_operand:QI 1 "general_operand" "QnBn")))]
>    "ix86_match_ccmode (insn, CCmode)"
>    "cmp{b}\t{%1, %h0|%h0, %1}"
> @@ -1672,15 +1666,11 @@ (define_insn "*cmpqi_ext<mode>_4"
>    [(set (reg FLAGS_REG)
>         (compare
>           (subreg:QI
> -           (match_operator:SWI248 2 "extract_operator"
> -             [(match_operand 0 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 2 "extract_high_operator"
> +             [(match_operand 0 "int248_register_operand" "Q")]) 0)
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))]
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)))]
>    "ix86_match_ccmode (insn, CCmode)"
>    "cmp{b}\t{%h1, %h0|%h0, %h1}"
>    [(set_attr "type" "icmp")
> @@ -3480,10 +3470,8 @@ (define_insn "*movstrictqi_ext<mode>_1"
>    [(set (strict_low_part
>           (match_operand:QI 0 "register_operand" "+Q"))
>           (subreg:QI
> -           (match_operator:SWI248 2 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0))]
> +           (match_operator:SWI248 2 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0))]
>    "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
>    "mov{b}\t{%h1, %0|%0, %h1}"
>    [(set_attr "type" "imov")
> @@ -3566,10 +3554,8 @@ (define_insn "*extzv<mode>"
>  (define_insn "*extzvqi"
>    [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
>         (subreg:QI
> -         (match_operator:SWI248 2 "extract_operator"
> -           [(match_operand 1 "int248_register_operand" "Q,Q")
> -            (const_int 8)
> -            (const_int 8)]) 0))]
> +         (match_operator:SWI248 2 "extract_high_operator"
> +           [(match_operand 1 "int248_register_operand" "Q,Q")]) 0))]
>    ""
>  {
>    switch (get_attr_type (insn))
> @@ -3690,10 +3676,8 @@ (define_insn "*insvqi_2"
>           (match_operand 0 "int248_register_operand" "+Q")
>           (const_int 8)
>           (const_int 8))
> -       (match_operator:SWI248 2 "extract_operator"
> -         [(match_operand 1 "int248_register_operand" "Q")
> -          (const_int 8)
> -          (const_int 8)]))]
> +       (match_operator:SWI248 2 "extract_high_operator"
> +         [(match_operand 1 "int248_register_operand" "Q")]))]
>    ""
>    "mov{b}\t{%h1, %h0|%h0, %h1}"
>    [(set_attr "type" "imov")
> @@ -5260,10 +5244,8 @@ (define_insn "*extendqi<SWI24:mode>_ext_1"
>    [(set (match_operand:SWI24 0 "register_operand" "=R")
>         (sign_extend:SWI24
>           (subreg:QI
> -           (match_operator:SWI248 2 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))]
> +           (match_operator:SWI248 2 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)))]
>    ""
>    "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
>     [(set_attr "type" "imovx")
> @@ -7009,10 +6991,8 @@ (define_insn_and_split "*addqi_ext<mode>_1_slp"
>    [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
>         (plus:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q,Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)
>           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
>     (clobber (reg:CC FLAGS_REG))]
>    "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
> @@ -7026,8 +7006,8 @@ (define_insn_and_split "*addqi_ext<mode>_1_slp"
>       [(set (strict_low_part (match_dup 0))
>            (plus:QI
>              (subreg:QI
> -              (match_op_dup 3
> -                [(match_dup 2) (const_int 8) (const_int 8)]) 0)
> +              (zero_extract:SWI248
> +                (match_dup 2) (const_int 8) (const_int 8)) 0)
>              (match_dup 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -7038,29 +7018,25 @@ (define_insn_and_split "*addqi_ext<mode>_2_slp"
>    [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
>         (plus:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)
>           (subreg:QI
> -           (match_operator:SWI248 4 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 4 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
>    "#"
>    "&& reload_completed"
>    [(set (strict_low_part (match_dup 0))
>         (subreg:QI
> -         (match_op_dup 4
> -           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
> +         (zero_extract:SWI248
> +           (match_dup 2) (const_int 8) (const_int 8)) 0))
>     (parallel
>       [(set (strict_low_part (match_dup 0))
>            (plus:QI
>              (subreg:QI
> -              (match_op_dup 3
> -                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
> +              (zero_extract:SWI248
> +                (match_dup 1) (const_int 8) (const_int 8)) 0)
>              (match_dup 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -7475,10 +7451,8 @@ (define_insn "*addqi_ext<mode>_0"
>    [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
>         (plus:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)
>           (match_operand:QI 1 "nonimmediate_operand" "0")))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
> @@ -7491,29 +7465,25 @@ (define_insn_and_split "*addqi_ext2<mode>_0"
>    [(set (match_operand:QI 0 "register_operand" "=&Q")
>         (plus:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)
>           (subreg:QI
> -           (match_operator:SWI248 4 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 4 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
>    "#"
>    "&& reload_completed"
>    [(set (match_dup 0)
>         (subreg:QI
> -         (match_op_dup 4
> -           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
> +         (zero_extract:SWI248
> +           (match_dup 2) (const_int 8) (const_int 8)) 0))
>     (parallel
>       [(set (match_dup 0)
>            (plus:QI
>              (subreg:QI
> -              (match_op_dup 3
> -                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
> +              (zero_extract:SWI248
> +                (match_dup 1) (const_int 8) (const_int 8)) 0)
>            (match_dup 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -7543,10 +7513,8 @@ (define_insn_and_split "*addqi_ext<mode>_1"
>         (subreg:SWI248
>           (plus:QI
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
>             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
> @@ -7581,8 +7549,8 @@ (define_insn_and_split "*addqi_ext<mode>_1"
>            (subreg:SWI248
>              (plus:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)
>                (match_dup 2)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -7602,15 +7570,11 @@ (define_insn_and_split "*<insn>qi_ext<mode>_2"
>         (subreg:SWI248
>           (plusminus:QI
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "<comm>0,!Q")]) 0)
>             (subreg:QI
> -             (match_operator:SWI248 4 "extract_operator"
> -               [(match_operand 2 "int248_register_operand" "Q,Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)) 0))
> +             (match_operator:SWI248 4 "extract_high_operator"
> +               [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
>    "@
> @@ -7629,11 +7593,11 @@ (define_insn_and_split "*<insn>qi_ext<mode>_2"
>            (subreg:SWI248
>              (plusminus:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)
>                (subreg:QI
> -                (match_op_dup 4
> -                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
> +                (zero_extract:SWI248
> +                  (match_dup 2) (const_int 8) (const_int 8)) 0)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
>    [(set_attr "type" "alu")
> @@ -8230,10 +8194,8 @@ (define_insn_and_split "*subqi_ext<mode>_1_slp"
>         (minus:QI
>           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q,Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
>    "@
> @@ -8247,8 +8209,8 @@ (define_insn_and_split "*subqi_ext<mode>_1_slp"
>            (minus:QI
>              (match_dup 0)
>              (subreg:QI
> -              (match_op_dup 3
> -                [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
> +              (zero_extract:SWI248
> +                (match_dup 2) (const_int 8) (const_int 8)) 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
>    [(set_attr "type" "alu")
> @@ -8258,30 +8220,26 @@ (define_insn_and_split "*subqi_ext<mode>_2_slp"
>    [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
>         (minus:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)
>           (subreg:QI
> -           (match_operator:SWI248 4 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 4 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
>    "#"
>    "&& reload_completed"
>    [(set (strict_low_part (match_dup 0))
>         (subreg:QI
> -         (match_op_dup 3
> -           [(match_dup 1) (const_int 8) (const_int 8)]) 0))
> +         (zero_extract:SWI248
> +           (match_dup 1) (const_int 8) (const_int 8)) 0))
>     (parallel
>       [(set (strict_low_part (match_dup 0))
>            (minus:QI
>            (match_dup 0)
>              (subreg:QI
> -              (match_op_dup 4
> -                [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
> +              (zero_extract:SWI248
> +                (match_dup 2) (const_int 8) (const_int 8)) 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
>    [(set_attr "type" "alu")
> @@ -8332,10 +8290,8 @@ (define_insn "*subqi_ext<mode>_0"
>         (minus:QI
>           (match_operand:QI 1 "nonimmediate_operand" "0")
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
>    "sub{b}\t{%h2, %0|%0, %h2}"
> @@ -8347,30 +8303,26 @@ (define_insn_and_split "*subqi_ext2<mode>_0"
>    [(set (match_operand:QI 0 "register_operand" "=&Q")
>         (minus:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)
>           (subreg:QI
> -           (match_operator:SWI248 4 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 4 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
>    "#"
>    "&& reload_completed"
>    [(set (match_dup 0)
>         (subreg:QI
> -         (match_op_dup 3
> -           [(match_dup 1) (const_int 8) (const_int 8)]) 0))
> +         (zero_extract:SWI248
> +           (match_dup 1) (const_int 8) (const_int 8)) 0))
>     (parallel
>       [(set (match_dup 0)
>            (minus:QI
>              (match_dup 0)
>              (subreg:QI
> -              (match_op_dup 4
> -                [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
> +              (zero_extract:SWI248
> +                (match_dup 2) (const_int 8) (const_int 8)) 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
>    [(set_attr "type" "alu")
> @@ -8385,10 +8337,8 @@ (define_insn_and_split "*subqi_ext<mode>_1"
>         (subreg:SWI248
>           (minus:QI
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
>             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
> @@ -8407,8 +8357,8 @@ (define_insn_and_split "*subqi_ext<mode>_1"
>            (subreg:SWI248
>              (minus:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)
>                (match_dup 2)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -12356,10 +12306,8 @@ (define_insn "*testqi_ext<mode>_1"
>         (compare
>           (and:QI
>             (subreg:QI
> -             (match_operator:SWI248 2 "extract_operator"
> -               [(match_operand 0 "int248_register_operand" "Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 2 "extract_high_operator"
> +               [(match_operand 0 "int248_register_operand" "Q")]) 0)
>             (match_operand:QI 1 "general_operand" "QnBn"))
>           (const_int 0)))]
>    "ix86_match_ccmode (insn, CCNOmode)"
> @@ -12373,15 +12321,11 @@ (define_insn "*testqi_ext<mode>_2"
>         (compare
>           (and:QI
>             (subreg:QI
> -             (match_operator:SWI248 2 "extract_operator"
> -               [(match_operand 0 "int248_register_operand" "Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 2 "extract_high_operator"
> +               [(match_operand 0 "int248_register_operand" "Q")]) 0)
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "Q")
> -                (const_int 8)
> -                (const_int 8)]) 0))
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "Q")]) 0))
>           (const_int 0)))]
>    "ix86_match_ccmode (insn, CCNOmode)"
>    "test{b}\t{%h1, %h0|%h0, %h1}"
> @@ -12970,10 +12914,8 @@ (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
>    [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
>         (any_logic:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q,Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)
>           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
>     (clobber (reg:CC FLAGS_REG))]
>    "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
> @@ -12987,8 +12929,8 @@ (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
>       [(set (strict_low_part (match_dup 0))
>            (any_logic:QI
>              (subreg:QI
> -              (match_op_dup 3
> -                [(match_dup 2) (const_int 8) (const_int 8)]) 0)
> +              (zero_extract:SWI248
> +                (match_dup 2) (const_int 8) (const_int 8)) 0)
>              (match_dup 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -12999,29 +12941,25 @@ (define_insn_and_split "*<code>qi_ext<mode>_2_slp"
>    [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
>         (any_logic:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)
>           (subreg:QI
> -           (match_operator:SWI248 4 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 4 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
>    "#"
>    "&& reload_completed"
>    [(set (strict_low_part (match_dup 0))
>         (subreg:QI
> -         (match_op_dup 4
> -           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
> +         (zero_extract:SWI248
> +           (match_dup 2) (const_int 8) (const_int 8)) 0))
>     (parallel
>       [(set (strict_low_part (match_dup 0))
>            (any_logic:QI
>              (subreg:QI
> -              (match_op_dup 3
> -                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
> +              (zero_extract:SWI248
> +                (match_dup 1) (const_int 8) (const_int 8)) 0)
>              (match_dup 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -13224,10 +13162,8 @@ (define_insn "*<code>qi_ext<mode>_0"
>    [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
>         (any_logic:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)
>           (match_operand:QI 1 "nonimmediate_operand" "0")))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
> @@ -13240,29 +13176,25 @@ (define_insn_and_split "*<code>qi_ext2<mode>_0"
>    [(set (match_operand:QI 0 "register_operand" "=&Q")
>         (any_logic:QI
>           (subreg:QI
> -           (match_operator:SWI248 3 "extract_operator"
> -             [(match_operand 1 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)
> +           (match_operator:SWI248 3 "extract_high_operator"
> +             [(match_operand 1 "int248_register_operand" "Q")]) 0)
>           (subreg:QI
> -           (match_operator:SWI248 4 "extract_operator"
> -             [(match_operand 2 "int248_register_operand" "Q")
> -              (const_int 8)
> -              (const_int 8)]) 0)))
> +           (match_operator:SWI248 4 "extract_high_operator"
> +             [(match_operand 2 "int248_register_operand" "Q")]) 0)))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
>    "#"
>    "&& reload_completed"
>    [(set (match_dup 0)
>         (subreg:QI
> -         (match_op_dup 4
> -           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
> +         (zero_extract:SWI248
> +           (match_dup 2) (const_int 8) (const_int 8)) 0))
>     (parallel
>       [(set (match_dup 0)
>            (any_logic:QI
>              (subreg:QI
> -              (match_op_dup 3
> -                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
> +              (zero_extract:SWI248
> +                (match_dup 1) (const_int 8) (const_int 8)) 0)
>            (match_dup 0)))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -13292,10 +13224,8 @@ (define_insn_and_split "*<code>qi_ext<mode>_1"
>         (subreg:SWI248
>           (any_logic:QI
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
>             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
> @@ -13314,8 +13244,8 @@ (define_insn_and_split "*<code>qi_ext<mode>_1"
>            (subreg:SWI248
>              (any_logic:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)
>                (match_dup 2)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -13329,10 +13259,8 @@ (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
>         (match_operator 5 "compare_operator"
>           [(any_logic:QI
>              (subreg:QI
> -              (match_operator:SWI248 3 "extract_operator"
> -                [(match_operand 1 "int248_register_operand" "0,!Q")
> -                 (const_int 8)
> -                 (const_int 8)]) 0)
> +              (match_operator:SWI248 3 "extract_high_operator"
> +                [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
>              (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
>           (const_int 0)]))
>     (set (zero_extract:SWI248
> @@ -13342,8 +13270,8 @@ (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
>         (subreg:SWI248
>           (any_logic:QI
>             (subreg:QI
> -             (match_op_dup 3
> -               [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +             (zero_extract:SWI248
> +               (match_dup 0) (const_int 8) (const_int 8)) 0)
>             (match_dup 2)) 0))]
>    "ix86_match_ccmode (insn, CCNOmode)"
>    "@
> @@ -13359,9 +13287,9 @@ (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
>       [(set (match_dup 4)
>            (match_op_dup 5
>              [(any_logic:QI
> -               (subreg:QI
> -                 (match_op_dup 3
> -                   [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +               (subreg:QI
> +                 (zero_extract:SWI248
> +                   (match_dup 0) (const_int 8) (const_int 8)) 0)
>                 (match_dup 2))
>               (const_int 0)]))
>        (set (zero_extract:SWI248
> @@ -13369,8 +13297,8 @@ (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
>            (subreg:SWI248
>              (any_logic:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 1) (const_int 8) (const_int 8)) 0)
>                (match_dup 2)) 0))])]
>    ""
>    [(set_attr "addr" "gpr8")
> @@ -13386,15 +13314,11 @@ (define_insn_and_split "*<code>qi_ext<mode>_2"
>         (subreg:SWI248
>           (any_logic:QI
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "%0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "%0,!Q")]) 0)
>             (subreg:QI
> -             (match_operator:SWI248 4 "extract_operator"
> -               [(match_operand 2 "int248_register_operand" "Q,Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)) 0))
> +             (match_operator:SWI248 4 "extract_high_operator"
> +               [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
>    "@
> @@ -13413,11 +13337,11 @@ (define_insn_and_split "*<code>qi_ext<mode>_2"
>            (subreg:SWI248
>              (any_logic:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)
>                (subreg:QI
> -                (match_op_dup 4
> -                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
> +                (zero_extract:SWI248
> +                  (match_dup 2) (const_int 8) (const_int 8)) 0)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
>    [(set_attr "type" "alu")
> @@ -13429,12 +13353,10 @@ (define_insn_and_split "*<code>qi_ext<mode>_3"
>           (match_operand 0 "int248_register_operand" "+Q,&Q")
>           (const_int 8)
>           (const_int 8))
> -       (match_operator:SWI248 3 "extract_operator"
> +       (match_operator:SWI248 3 "extract_high_operator"
>           [(any_logic
>              (match_operand 1 "int248_register_operand" "%0,!Q")
> -            (match_operand 2 "int248_register_operand" "Q,Q"))
> -          (const_int 8)
> -          (const_int 8)]))
> +            (match_operand 2 "int248_register_operand" "Q,Q"))]))
>     (clobber (reg:CC FLAGS_REG))]
>    "GET_MODE (operands[1]) == GET_MODE (operands[2])"
>    "@
> @@ -13450,9 +13372,9 @@ (define_insn_and_split "*<code>qi_ext<mode>_3"
>     (parallel
>       [(set (zero_extract:SWI248
>              (match_dup 0) (const_int 8) (const_int 8))
> -          (match_op_dup 3
> -            [(any_logic (match_dup 4) (match_dup 2))
> -             (const_int 8) (const_int 8)]))
> +          (zero_extract:SWI248
> +            (any_logic (match_dup 4) (match_dup 2))
> +            (const_int 8) (const_int 8)))
>        (clobber (reg:CC FLAGS_REG))])]
>    "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
>    [(set_attr "type" "alu")
> @@ -14697,10 +14619,8 @@ (define_insn_and_split "*negqi_ext<mode>_1"
>         (subreg:SWI248
>           (neg:QI
>             (subreg:QI
> -             (match_operator:SWI248 2 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)) 0))
> +             (match_operator:SWI248 2 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
>    "@
> @@ -14718,8 +14638,8 @@ (define_insn_and_split "*negqi_ext<mode>_1"
>            (subreg:SWI248
>              (neg:QI
>                (subreg:QI
> -                (match_op_dup 2
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
>    [(set_attr "type" "negnot")
> @@ -15354,10 +15274,8 @@ (define_insn_and_split "*one_cmplqi_ext<mode>_1"
>         (subreg:SWI248
>           (not:QI
>             (subreg:QI
> -             (match_operator:SWI248 2 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)) 0))]
> +             (match_operator:SWI248 2 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)) 0))]
>    ""
>    "@
>     not{b}\t%h0
> @@ -15373,8 +15291,8 @@ (define_insn_and_split "*one_cmplqi_ext<mode>_1"
>         (subreg:SWI248
>           (not:QI
>             (subreg:QI
> -             (match_op_dup 2
> -               [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
> +             (zero_extract:SWI248
> +               (match_dup 0) (const_int 8) (const_int 8)) 0)) 0))]
>    ""
>    [(set_attr "type" "negnot")
>     (set_attr "mode" "QI")])
> @@ -16721,10 +16639,8 @@ (define_insn_and_split "*ashlqi_ext<mode>_1"
>         (subreg:SWI248
>           (ashift:QI
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
>             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
> @@ -16758,8 +16674,8 @@ (define_insn_and_split "*ashlqi_ext<mode>_1"
>            (subreg:SWI248
>              (ashift:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)
>                (match_dup 2)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -18005,10 +17921,8 @@ (define_insn_and_split "*<insn>qi_ext<mode>_1"
>         (subreg:SWI248
>           (any_shiftrt:QI
>             (subreg:QI
> -             (match_operator:SWI248 3 "extract_operator"
> -               [(match_operand 1 "int248_register_operand" "0,!Q")
> -                (const_int 8)
> -                (const_int 8)]) 0)
> +             (match_operator:SWI248 3 "extract_high_operator"
> +               [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
>             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
>     (clobber (reg:CC FLAGS_REG))]
>    ""
> @@ -18034,8 +17948,8 @@ (define_insn_and_split "*<insn>qi_ext<mode>_1"
>            (subreg:SWI248
>              (any_shiftrt:QI
>                (subreg:QI
> -                (match_op_dup 3
> -                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
> +                (zero_extract:SWI248
> +                  (match_dup 0) (const_int 8) (const_int 8)) 0)
>                (match_dup 2)) 0))
>        (clobber (reg:CC FLAGS_REG))])]
>    ""
> @@ -28252,10 +28166,8 @@ (define_peephole2
>         (match_operator 1 "compare_operator"
>           [(and:QI
>              (subreg:QI
> -              (match_operator:SWI248 4 "extract_operator"
> -                [(match_operand 2 "int248_register_operand")
> -                 (const_int 8)
> -                 (const_int 8)]) 0)
> +              (match_operator:SWI248 4 "extract_high_operator"
> +                [(match_operand 2 "int248_register_operand")]) 0)
>              (match_operand 3 "const_int_operand"))
>            (const_int 0)]))]
>    "! TARGET_PARTIAL_REG_STALL
> @@ -28267,9 +28179,9 @@ (define_peephole2
>            (match_op_dup 1
>              [(and:QI
>                 (subreg:QI
> -                 (match_op_dup 4 [(match_dup 2)
> -                                  (const_int 8)
> -                                  (const_int 8)]) 0)
> +                 (zero_extract:SWI248 (match_dup 2)
> +                                      (const_int 8)
> +                                      (const_int 8)) 0)
>                 (match_dup 3))
>               (const_int 0)]))
>        (set (zero_extract:SWI248 (match_dup 2)
> @@ -28278,9 +28190,9 @@ (define_peephole2
>            (subreg:SWI248
>              (and:QI
>                (subreg:QI
> -                (match_op_dup 4 [(match_dup 2)
> -                                 (const_int 8)
> -                                 (const_int 8)]) 0)
> +                (zero_extract:SWI248 (match_dup 2)
> +                                     (const_int 8)
> +                                     (const_int 8)) 0)
>                (match_dup 3)) 0))])])
>
>  ;; Don't do logical operations with memory inputs.
> diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
> index b2d2eecc64f..0f310902e7b 100644
> --- a/gcc/config/i386/predicates.md
> +++ b/gcc/config/i386/predicates.md
> @@ -1740,8 +1740,12 @@ (define_predicate "promotable_binary_operator"
>  (define_predicate "compare_operator"
>    (match_code "compare"))
>
> -(define_predicate "extract_operator"
> -  (match_code "zero_extract,sign_extract"))
> +(define_predicate "extract_high_operator"
> +  (match_code "zero_extract,sign_extract,ashiftrt,lshiftrt")
> +{
> +  return (const8_operand (XEXP (op, 1), VOIDmode)
> +         && (BINARY_P (op) || const8_operand (XEXP (op, 2), VOIDmode)));
> +})
>
>  ;; Return true if OP is a memory operand, aligned to
>  ;; less than its natural alignment.
> --
> 2.43.0
>

Reply via email to