Introduce extract_operator predicate to handle both, zero-extract and sign-extract extract operations with expressions like:
(subreg:QI (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "0") (const_int 8) (const_int 8)) 0) As shown in the testcase, this will enable generation of QImode instructions with high registers when signed arguments are used. gcc/ChangeLog: PR target/78952 * config/i386/predicates.md (extract_operator): New predicate. * config/i386/i386.md (any_extract): Remove code iterator. (*cmpqi_ext<mode>_1_mem_rex64): Use extract_operator predicate. (*cmpqi_ext<mode>_1): Ditto. (*cmpqi_ext<mode>_2): Ditto. (*cmpqi_ext<mode>_3_mem_rex64): Ditto. (*cmpqi_ext<mode>_3): Ditto. (*cmpqi_ext<mode>_4): Ditto. (*extzvqi_mem_rex64): Ditto. (*extzvqi): Ditto. (*insvqi_2): Ditto. (*extendqi<SWI24:mode>_ext_1): Ditto. (*addqi_ext<mode>_0): Ditto. (*addqi_ext<mode>_1): Ditto. (*addqi_ext<mode>_2): Ditto. (*subqi_ext<mode>_0): Ditto. (*subqi_ext<mode>_2): Ditto. (*testqi_ext<mode>_1): Ditto. (*testqi_ext<mode>_2): Ditto. (*andqi_ext<mode>_0): Ditto. (*andqi_ext<mode>_1): Ditto. (*andqi_ext<mode>_1_cc): Ditto. (*andqi_ext<mode>_2): Ditto. (*<any_or:code>qi_ext<mode>_0): Ditto. (*<any_or:code>qi_ext<mode>_1): Ditto. (*<any_or:code>qi_ext<mode>_2): Ditto. (*xorqi_ext<mode>_1_cc): Ditto. (*negqi_ext<mode>_2): Ditto. (*ashlqi_ext<mode>_2): Ditto. (*<any_shiftrt:insn>qi_ext<mode>_2): Ditto. gcc/testsuite/ChangeLog: PR target/78952 * gcc.target/i386/pr78952-4.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to master. Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 0f95d8e8918..337702f5a9b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1005,9 +1005,6 @@ (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")]) ;; Mapping of extend operators (define_code_iterator any_extend [sign_extend zero_extend]) -;; Mapping of extract operators -(define_code_iterator any_extract [sign_extract zero_extract]) - ;; Mapping of highpart multiply operators (define_code_iterator any_mul_highpart [smul_highpart umul_highpart]) @@ -1462,10 +1459,10 @@ (define_insn "*cmpqi_ext<mode>_1_mem_rex64" (compare (match_operand:QI 0 "norex_memory_operand" "Bn") (subreg:QI - (any_extract:SWI248 - (match_operand 1 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)))] + (match_operator:SWI248 2 "extract_operator" + [(match_operand 1 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)))] "TARGET_64BIT && reload_completed && ix86_match_ccmode (insn, CCmode)" "cmp{b}\t{%h1, %0|%0, %h1}" @@ -1477,10 +1474,10 @@ (define_insn "*cmpqi_ext<mode>_1" (compare (match_operand:QI 0 "nonimmediate_operand" "QBc,m") (subreg:QI - (any_extract:SWI248 - (match_operand 1 "int248_register_operand" "Q,Q") - (const_int 8) - (const_int 8)) 0)))] + (match_operator:SWI248 2 "extract_operator" + [(match_operand 1 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)]) 0)))] "ix86_match_ccmode (insn, CCmode)" "cmp{b}\t{%h1, %0|%0, %h1}" [(set_attr "isa" "*,nox64") @@ -1494,29 +1491,29 @@ (define_peephole2 (match_operator 4 "compare_operator" [(match_dup 0) (subreg:QI - (any_extract:SWI248 - (match_operand 2 "int248_register_operand") - (const_int 8) - (const_int 8)) 0)]))] + (match_operator:SWI248 5 "extract_operator" + [(match_operand 2 "int248_register_operand") + (const_int 8) + (const_int 8)]) 0)]))] "TARGET_64BIT && peep2_reg_dead_p (2, operands[0])" [(set (match_dup 3) (match_op_dup 4 [(match_dup 1) (subreg:QI - (any_extract:SWI248 - (match_dup 2) - (const_int 8) - (const_int 8)) 0)]))]) + (match_op_dup 5 + [(match_dup 2) + (const_int 8) + (const_int 8)]) 0)]))]) (define_insn "*cmpqi_ext<mode>_2" [(set (reg FLAGS_REG) (compare (subreg:QI - (any_extract:SWI248 - (match_operand 0 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 2 "extract_operator" + [(match_operand 0 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 1 "const0_operand")))] "ix86_match_ccmode (insn, CCNOmode)" "test{b}\t%h0, %h0" @@ -1538,10 +1535,10 @@ (define_insn "*cmpqi_ext<mode>_3_mem_rex64" [(set (reg FLAGS_REG) (compare (subreg:QI - (any_extract:SWI248 - (match_operand 0 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 2 "extract_operator" + [(match_operand 0 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 1 "norex_memory_operand" "Bn")))] "TARGET_64BIT && reload_completed && ix86_match_ccmode (insn, CCmode)" @@ -1553,10 +1550,10 @@ (define_insn "*cmpqi_ext<mode>_3" [(set (reg FLAGS_REG) (compare (subreg:QI - (any_extract:SWI248 - (match_operand 0 "int248_register_operand" "Q,Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 2 "extract_operator" + [(match_operand 0 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 1 "general_operand" "QnBc,m")))] "ix86_match_ccmode (insn, CCmode)" "cmp{b}\t{%1, %h0|%h0, %1}" @@ -1570,35 +1567,35 @@ (define_peephole2 (set (match_operand 3 "flags_reg_operand") (match_operator 4 "compare_operator" [(subreg:QI - (any_extract:SWI248 - (match_operand 2 "int248_register_operand") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 5 "extract_operator" + [(match_operand 2 "int248_register_operand") + (const_int 8) + (const_int 8)]) 0) (match_dup 0)]))] "TARGET_64BIT && peep2_reg_dead_p (2, operands[0])" [(set (match_dup 3) (match_op_dup 4 [(subreg:QI - (any_extract:SWI248 - (match_dup 2) - (const_int 8) - (const_int 8)) 0) + (match_op_dup 5 + [(match_dup 2) + (const_int 8) + (const_int 8)]) 0) (match_dup 1)]))]) (define_insn "*cmpqi_ext<mode>_4" [(set (reg FLAGS_REG) (compare (subreg:QI - (any_extract:SWI248 - (match_operand 0 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 2 "extract_operator" + [(match_operand 0 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0) (subreg:QI - (any_extract:SWI248 - (match_operand 1 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)))] + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)))] "ix86_match_ccmode (insn, CCmode)" "cmp{b}\t{%h1, %h0|%h0, %h1}" [(set_attr "type" "icmp") @@ -3266,18 +3263,6 @@ (define_expand "extzv<mode>" operands[1] = copy_to_reg (operands[1]); }) -(define_insn "*extzvqi_mem_rex64" - [(set (match_operand:QI 0 "norex_memory_operand" "=Bn") - (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0))] - "TARGET_64BIT && reload_completed" - "mov{b}\t{%h1, %0|%0, %h1}" - [(set_attr "type" "imov") - (set_attr "mode" "QI")]) - (define_insn "*extzv<mode>" [(set (match_operand:SWI248 0 "register_operand" "=R") (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q") @@ -3288,13 +3273,25 @@ (define_insn "*extzv<mode>" [(set_attr "type" "imovx") (set_attr "mode" "SI")]) +(define_insn "*extzvqi_mem_rex64" + [(set (match_operand:QI 0 "norex_memory_operand" "=Bn") + (subreg:QI + (match_operator:SWI248 2 "extract_operator" + [(match_operand 1 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0))] + "TARGET_64BIT && reload_completed" + "mov{b}\t{%h1, %0|%0, %h1}" + [(set_attr "type" "imov") + (set_attr "mode" "QI")]) + (define_insn "*extzvqi" [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m") (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "Q,Q,Q") - (const_int 8) - (const_int 8)) 0))] + (match_operator:SWI248 2 "extract_operator" + [(match_operand 1 "int248_register_operand" "Q,Q,Q") + (const_int 8) + (const_int 8)]) 0))] "" { switch (get_attr_type (insn)) @@ -3320,17 +3317,19 @@ (define_insn "*extzvqi" (define_peephole2 [(set (match_operand:QI 0 "register_operand") (subreg:QI - (zero_extract:SWI248 (match_operand 1 "int248_register_operand") - (const_int 8) - (const_int 8)) 0)) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand") + (const_int 8) + (const_int 8)]) 0)) (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))] "TARGET_64BIT && peep2_reg_dead_p (2, operands[0])" [(set (match_dup 2) (subreg:QI - (zero_extract:SWI248 (match_dup 1) - (const_int 8) - (const_int 8)) 0))]) + (match_op_dup 3 + [(match_dup 1) + (const_int 8) + (const_int 8)]) 0))]) (define_expand "insv<mode>" [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand") @@ -3456,10 +3455,10 @@ (define_insn "*insvqi_2" (match_operand 0 "int248_register_operand" "+Q") (const_int 8) (const_int 8)) - (any_extract:SWI248 - (match_operand 1 "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)]))] "" "mov{b}\t{%h1, %h0|%h0, %h1}" [(set_attr "type" "imov") @@ -4857,10 +4856,10 @@ (define_insn "*extendqi<SWI24:mode>_ext_1" [(set (match_operand:SWI24 0 "register_operand" "=R") (sign_extend:SWI24 (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)))] + (match_operator:SWI248 2 "extract_operator" + [(match_operand 1 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)))] "" "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}" [(set_attr "type" "imovx") @@ -6720,10 +6719,10 @@ (define_insn "*addqi_ext<mode>_0" [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m") (plus:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q,Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0"))) (clobber (reg:CC FLAGS_REG))] "" @@ -6754,10 +6753,10 @@ (define_insn "*addqi_ext<mode>_1" (subreg:SWI248 (plus:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0,0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0,0") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ @@ -6793,15 +6792,15 @@ (define_insn "*addqi_ext<mode>_2" (subreg:SWI248 (plus:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "%0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "%0") + (const_int 8) + (const_int 8)]) 0) (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)) 0)) + (match_operator:SWI248 4 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ rtx_equal_p (operands[0], operands[1]) @@ -7361,10 +7360,10 @@ (define_insn "*subqi_ext<mode>_0" (minus:QI (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0") (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q,Q") - (const_int 8) - (const_int 8)) 0))) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)]) 0))) (clobber (reg:CC FLAGS_REG))] "" "sub{b}\t{%h2, %0|%0, %h2}" @@ -7380,15 +7379,15 @@ (define_insn "*subqi_ext<mode>_2" (subreg:SWI248 (minus:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0") + (const_int 8) + (const_int 8)]) 0) (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)) 0)) + (match_operator:SWI248 4 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ rtx_equal_p (operands[0], operands[1])" @@ -9972,10 +9971,10 @@ (define_insn "*testqi_ext<mode>_1" (compare (and:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 0 "int248_register_operand" "Q,Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 2 "extract_operator" + [(match_operand 0 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m")) (const_int 0)))] "ix86_match_ccmode (insn, CCNOmode)" @@ -9989,15 +9988,15 @@ (define_insn "*testqi_ext<mode>_2" (compare (and:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 0 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 2 "extract_operator" + [(match_operand 0 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0) (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)) (const_int 0)))] "ix86_match_ccmode (insn, CCNOmode)" "test{b}\t{%h1, %h0|%h0, %h1}" @@ -10639,10 +10638,10 @@ (define_insn "*andqi_ext<mode>_0" [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m") (and:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q,Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0"))) (clobber (reg:CC FLAGS_REG))] "" @@ -10673,10 +10672,10 @@ (define_insn "*andqi_ext<mode>_1" (subreg:SWI248 (and:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0,0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0,0") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ @@ -10693,10 +10692,10 @@ (define_insn "*andqi_ext<mode>_1_cc" (compare (and:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0,0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0,0") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) (const_int 0))) (set (zero_extract:SWI248 @@ -10706,10 +10705,10 @@ (define_insn "*andqi_ext<mode>_1_cc" (subreg:SWI248 (and:QI (subreg:QI - (zero_extract:SWI248 - (match_dup 1) - (const_int 8) - (const_int 8)) 0) + (match_op_dup 3 + [(match_dup 1) + (const_int 8) + (const_int 8)]) 0) (match_dup 2)) 0))] "ix86_match_ccmode (insn, CCNOmode) /* FIXME: without this LRA can't reload this pattern, see PR82524. */ @@ -10727,15 +10726,15 @@ (define_insn "*andqi_ext<mode>_2" (subreg:SWI248 (and:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "%0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "%0") + (const_int 8) + (const_int 8)]) 0) (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)) 0)) + (match_operator:SWI248 4 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ rtx_equal_p (operands[0], operands[1]) @@ -11396,10 +11395,10 @@ (define_insn "*<code>qi_ext<mode>_0" [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m") (any_or:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q,Q") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0"))) (clobber (reg:CC FLAGS_REG))] "" @@ -11416,10 +11415,10 @@ (define_insn "*<code>qi_ext<mode>_1" (subreg:SWI248 (any_or:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0,0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0,0") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0)) (clobber (reg:CC FLAGS_REG))] "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) @@ -11438,15 +11437,15 @@ (define_insn "*<code>qi_ext<mode>_2" (subreg:SWI248 (any_or:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "%0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "%0") + (const_int 8) + (const_int 8)]) 0) (subreg:QI - (zero_extract:SWI248 - (match_operand 2 "int248_register_operand" "Q") - (const_int 8) - (const_int 8)) 0)) 0)) + (match_operator:SWI248 4 "extract_operator" + [(match_operand 2 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)]) 0)) 0)) (clobber (reg:CC FLAGS_REG))] "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) /* FIXME: without this LRA can't reload this pattern, see PR82524. */ @@ -11544,10 +11543,10 @@ (define_insn "*xorqi_ext<mode>_1_cc" (compare (xor:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0,0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0,0") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) (const_int 0))) (set (zero_extract:SWI248 @@ -11557,10 +11556,10 @@ (define_insn "*xorqi_ext<mode>_1_cc" (subreg:SWI248 (xor:QI (subreg:QI - (zero_extract:SWI248 - (match_dup 1) - (const_int 8) - (const_int 8)) 0) + (match_op_dup 3 + [(match_dup 1) + (const_int 8) + (const_int 8)]) 0) (match_dup 2)) 0))] "ix86_match_ccmode (insn, CCNOmode) /* FIXME: without this LRA can't reload this pattern, see PR82524. */ @@ -11954,10 +11953,10 @@ (define_insn "*negqi_ext<mode>_2" (subreg:SWI248 (neg:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0") - (const_int 8) - (const_int 8)) 0)) 0)) + (match_operator:SWI248 2 "extract_operator" + [(match_operand 1 "int248_register_operand" "0") + (const_int 8) + (const_int 8)]) 0)) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ rtx_equal_p (operands[0], operands[1])" @@ -13515,10 +13514,10 @@ (define_insn "*ashlqi_ext<mode>_2" (subreg:SWI248 (ashift:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 2 "nonmemory_operand" "cI")) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ @@ -14418,10 +14417,10 @@ (define_insn "*<insn>qi_ext<mode>_2" (subreg:SWI248 (any_shiftrt:QI (subreg:QI - (zero_extract:SWI248 - (match_operand 1 "int248_register_operand" "0") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 3 "extract_operator" + [(match_operand 1 "int248_register_operand" "0") + (const_int 8) + (const_int 8)]) 0) (match_operand:QI 2 "nonmemory_operand" "cI")) 0)) (clobber (reg:CC FLAGS_REG))] "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ @@ -23272,9 +23271,10 @@ (define_peephole2 (match_operator 1 "compare_operator" [(and:QI (subreg:QI - (zero_extract:SWI248 (match_operand 2 "int248_register_operand") - (const_int 8) - (const_int 8)) 0) + (match_operator:SWI248 4 "extract_operator" + [(match_operand 2 "int248_register_operand") + (const_int 8) + (const_int 8)]) 0) (match_operand 3 "const_int_operand")) (const_int 0)]))] "! TARGET_PARTIAL_REG_STALL @@ -23286,9 +23286,9 @@ (define_peephole2 (match_op_dup 1 [(and:QI (subreg:QI - (zero_extract:SWI248 (match_dup 2) - (const_int 8) - (const_int 8)) 0) + (match_op_dup 4 [(match_dup 2) + (const_int 8) + (const_int 8)]) 0) (match_dup 3)) (const_int 0)])) (set (zero_extract:SWI248 (match_dup 2) @@ -23297,9 +23297,9 @@ (define_peephole2 (subreg:SWI248 (and:QI (subreg:QI - (zero_extract:SWI248 (match_dup 2) - (const_int 8) - (const_int 8)) 0) + (match_op_dup 4 [(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 b4d9ab40ab9..3f934277a57 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1684,6 +1684,9 @@ (define_predicate "promotable_binary_operator" (define_predicate "compare_operator" (match_code "compare")) +(define_predicate "extract_operator" + (match_code "zero_extract,sign_extract")) + ;; Return true if OP is a memory operand, aligned to ;; less than its natural alignment. (define_predicate "misaligned_operand" diff --git a/gcc/testsuite/gcc.target/i386/pr78952-4.c b/gcc/testsuite/gcc.target/i386/pr78952-4.c new file mode 100644 index 00000000000..c7bd63c9543 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr78952-4.c @@ -0,0 +1,48 @@ +/* PR target/78952 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ +/* { dg-final { scan-assembler-not "mov\[sz\]bl" } } */ +/* { dg-final { scan-assembler-not "movb" } } */ + +struct S1 +{ + signed char pad1; + signed char val; + signed short pad2; +}; + +struct S1 test_and (struct S1 a, struct S1 b) +{ + a.val &= b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]andb" } } */ + +struct S1 test_or (struct S1 a, struct S1 b) +{ + a.val |= b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]orb" } } */ + +struct S1 test_xor (struct S1 a, struct S1 b) +{ + a.val ^= b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]xorb" } } */ + +struct S1 test_add (struct S1 a, struct S1 b) +{ + a.val += b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]addb" } } */