aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386
diff options
context:
space:
mode:
authorRoger Sayle <roger@nextmovesoftware.com>2021-12-13 18:48:22 +0000
committerRoger Sayle <roger@nextmovesoftware.com>2021-12-13 18:51:00 +0000
commit149739c39475f3691e67aa0aee4f205f4e83392f (patch)
treeafea33c9c0f340e9220ed3c834c2c44393c81144 /gcc/config/i386
parentfc4a93eb41243babe3f2ef3a3c6171b48e503138 (diff)
downloadgcc-149739c39475f3691e67aa0aee4f205f4e83392f.zip
gcc-149739c39475f3691e67aa0aee4f205f4e83392f.tar.gz
gcc-149739c39475f3691e67aa0aee4f205f4e83392f.tar.bz2
x86: Avoid generating orb $0, %ah
I'll post my proposed fix for PR target/103611 shortly, but this patch fixes another missed optimization opportunity revealed by that PR. Occasionally, reload materializes integer constants during register allocation sometimes resulting in unnecessary instructions such as: (insn 23 31 24 2 (parallel [ (set (reg:SI 0 ax [99]) (ior:SI (reg:SI 0 ax [99]) (const_int 0 [0]))) (clobber (reg:CC 17 flags)) ]) "pr103611.c":18:73 550 {*iorsi_1} (nil)) These then get "optimized" during the split2 pass, which realizes that no bits outside of 0xff00 are set, so this operation can be implemented by operating on just the highpart of a QIreg_operand, i.e. %ah, %bh, %ch etc., which leads to the useless "orb $0, %ah" seen in the reported PR. This fix catches the case of const0_rtx in relevant splitter, either eliminating the instruction or turning it into a simple move. 2021-12-13 Roger Sayle <roger@nextmovesoftware.com> gcc/ChangeLog * config/i386/i386.md (define_split any_or:SWI248 -> orb %?h): Optimize the case where the integer constant operand is zero. gcc/testsuite/ChangeLog * gcc.target/i386/pr103611-1.c: New test case.
Diffstat (limited to 'gcc/config/i386')
-rw-r--r--gcc/config/i386/i386.md9
1 files changed, 9 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 9d7d116..f6d9c4b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10542,6 +10542,15 @@
(match_dup 2)) 0))
(clobber (reg:CC FLAGS_REG))])]
{
+ /* Handle the case where INTVAL (operands[2]) == 0. */
+ if (operands[2] == const0_rtx)
+ {
+ if (!rtx_equal_p (operands[0], operands[1]))
+ emit_move_insn (operands[0], operands[1]);
+ else
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+ }
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);