diff options
author | Roger Sayle <roger@nextmovesoftware.com> | 2023-06-24 23:05:25 +0100 |
---|---|---|
committer | Roger Sayle <roger@nextmovesoftware.com> | 2023-06-24 23:05:25 +0100 |
commit | 8f6c747c8638d4c3c47ba2d4c8be86909e183132 (patch) | |
tree | db3b4dd537d8c51dc4c34ddbc7fbba719124d762 | |
parent | 3f97d10aa1ff5984d6fd657f246d3f251b254ff1 (diff) | |
download | gcc-8f6c747c8638d4c3c47ba2d4c8be86909e183132.zip gcc-8f6c747c8638d4c3c47ba2d4c8be86909e183132.tar.gz gcc-8f6c747c8638d4c3c47ba2d4c8be86909e183132.tar.bz2 |
i386: Add alternate representation for {and,or,xor}b %ah,%dh.
A patch that I'm working on to improve RTL simplifications in the
middle-end results in the regression of pr78904-1b.c, due to changes in
the canonical representation of high-byte (%ah, %bh, %ch, %dh) logic.
See also PR target/78904.
This patch avoids/prevents those failures by adding support for the
alternate representation, duplicating the existing *<code>qi_ext<mode>_2
as *<code>qi_ext<mode>_3 (the new version also replacing any_or with
any_logic to provide *andqi_ext<mode>_3 in the same pattern). Removing
the original pattern isn't trivial, as it's generated by define_split,
but this can be investigated after the other pieces are approved.
The current representation of this instruction is:
(set (zero_extract:DI (reg/v:DI 87 [ aD.2763 ])
(const_int 8 [0x8])
(const_int 8 [0x8]))
(subreg:DI (xor:QI (subreg:QI (zero_extract:DI (reg:DI 94)
(const_int 8 [0x8])
(const_int 8 [0x8])) 0)
(subreg:QI (zero_extract:DI (reg/v:DI 87 [ aD.2763 ])
(const_int 8 [0x8])
(const_int 8 [0x8])) 0)) 0))
after my proposed middle-end improvement, we attempt to recognize:
(set (zero_extract:DI (reg/v:DI 87 [ aD.2763 ])
(const_int 8 [0x8])
(const_int 8 [0x8]))
(zero_extract:DI (xor:DI (reg:DI 94)
(reg/v:DI 87 [ aD.2763 ]))
(const_int 8 [0x8])
(const_int 8 [0x8])))
2023-06-24 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
* config/i386/i386.md (*<code>qi_ext<mode>_3): New define_insn.
-rw-r--r-- | gcc/config/i386/i386.md | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 95a6653c..b50d82b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11380,6 +11380,8 @@ [(set_attr "type" "alu") (set_attr "mode" "QI")]) +;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below. + ;; Convert wide AND instructions with immediate operand to shorter QImode ;; equivalents when possible. ;; Don't do the splitting with memory operands, since it introduces risk @@ -12092,6 +12094,26 @@ [(set_attr "type" "alu") (set_attr "mode" "QI")]) +(define_insn "*<code>qi_ext<mode>_3" + [(set (zero_extract:SWI248 + (match_operand 0 "int248_register_operand" "+Q") + (const_int 8) + (const_int 8)) + (zero_extract:SWI248 + (any_logic:SWI248 + (match_operand 1 "int248_register_operand" "%0") + (match_operand 2 "int248_register_operand" "Q")) + (const_int 8) + (const_int 8))) + (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. */ + && (rtx_equal_p (operands[0], operands[1]) + || rtx_equal_p (operands[0], operands[2]))" + "<logic>{b}\t{%h2, %h0|%h0, %h2}" + [(set_attr "type" "alu") + (set_attr "mode" "QI")]) + ;; Convert wide OR instructions with immediate operand to shorter QImode ;; equivalents when possible. ;; Don't do the splitting with memory operands, since it introduces risk |