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 >