From: Uros Bizjak Date: Thu, 20 Apr 2023 14:51:56 +0000 (+0200) Subject: i386: Handle sign-extract for QImode operations with high registers [PR78952] X-Git-Tag: basepoints/gcc-15~10022 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=272484dae6b5264baa0f41eba80a9521e9b7ecf5;p=thirdparty%2Fgcc.git i386: Handle sign-extract for QImode operations with high registers [PR78952] 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_1_mem_rex64): Use extract_operator predicate. (*cmpqi_ext_1): Ditto. (*cmpqi_ext_2): Ditto. (*cmpqi_ext_3_mem_rex64): Ditto. (*cmpqi_ext_3): Ditto. (*cmpqi_ext_4): Ditto. (*extzvqi_mem_rex64): Ditto. (*extzvqi): Ditto. (*insvqi_2): Ditto. (*extendqi_ext_1): Ditto. (*addqi_ext_0): Ditto. (*addqi_ext_1): Ditto. (*addqi_ext_2): Ditto. (*subqi_ext_0): Ditto. (*subqi_ext_2): Ditto. (*testqi_ext_1): Ditto. (*testqi_ext_2): Ditto. (*andqi_ext_0): Ditto. (*andqi_ext_1): Ditto. (*andqi_ext_1_cc): Ditto. (*andqi_ext_2): Ditto. (*qi_ext_0): Ditto. (*qi_ext_1): Ditto. (*qi_ext_2): Ditto. (*xorqi_ext_1_cc): Ditto. (*negqi_ext_2): Ditto. (*ashlqi_ext_2): Ditto. (*qi_ext_2): Ditto. gcc/testsuite/ChangeLog: PR target/78952 * gcc.target/i386/pr78952-4.c: New test. --- diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index f8698ea903e0..d49f1cdc3fed 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1008,9 +1008,6 @@ ;; 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]) @@ -1465,10 +1462,10 @@ (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}" @@ -1480,10 +1477,10 @@ (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") @@ -1497,29 +1494,29 @@ (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_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" @@ -1541,10 +1538,10 @@ [(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)" @@ -1556,10 +1553,10 @@ [(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}" @@ -1573,35 +1570,35 @@ (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_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") @@ -3269,18 +3266,6 @@ 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" [(set (match_operand:SWI248 0 "register_operand" "=R") (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q") @@ -3291,13 +3276,25 @@ [(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)) @@ -3323,17 +3320,19 @@ (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" [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand") @@ -3459,10 +3458,10 @@ (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") @@ -4860,10 +4859,10 @@ [(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|x}\t{%h1, %0|%0, %h1}" [(set_attr "type" "imovx") @@ -6723,10 +6722,10 @@ [(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))] "" @@ -6757,10 +6756,10 @@ (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. */ @@ -6796,15 +6795,15 @@ (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]) @@ -7364,10 +7363,10 @@ (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}" @@ -7383,15 +7382,15 @@ (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])" @@ -9975,10 +9974,10 @@ (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)" @@ -9992,15 +9991,15 @@ (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}" @@ -10642,10 +10641,10 @@ [(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))] "" @@ -10676,10 +10675,10 @@ (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. */ @@ -10696,10 +10695,10 @@ (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 @@ -10709,10 +10708,10 @@ (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. */ @@ -10730,15 +10729,15 @@ (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]) @@ -11399,10 +11398,10 @@ [(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))] "" @@ -11419,10 +11418,10 @@ (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)) @@ -11441,15 +11440,15 @@ (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. */ @@ -11547,10 +11546,10 @@ (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 @@ -11560,10 +11559,10 @@ (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. */ @@ -11957,10 +11956,10 @@ (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])" @@ -13518,10 +13517,10 @@ (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. */ @@ -14421,10 +14420,10 @@ (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. */ @@ -23291,9 +23290,10 @@ (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 @@ -23305,9 +23305,9 @@ (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) @@ -23316,9 +23316,9 @@ (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 b4d9ab40ab93..3f934277a571 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1684,6 +1684,9 @@ (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 000000000000..c7bd63c95438 --- /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" } } */