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.
---
 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