This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix i?86 mem += reg + comparison peephole (PR target/52086)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Uros Bizjak <ubizjak at gmail dot com>, Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 2 Feb 2012 09:15:17 +0100
- Subject: [PATCH] Fix i?86 mem += reg + comparison peephole (PR target/52086)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This peephole, as shown on the testcase, happily transforms a QImode
memory load into a register, followed by SImode addition of that reg and
%ebp, followed by QImode store of that back into the same memory and
QImode comparison of that with zero into a QImode addition of the register
to the memory with setting flags instead of clobbering them. The problem
with that is that for -m32 %ebp can't be used in QImode instructions.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk?
2012-02-02 Jakub Jelinek <jakub@redhat.com>
PR target/52086
* config/i386/i386.md (*addqi_2 peephole with SImode addition): Check
that operands[2] is either immediate, or q_regs_operand.
* gcc.dg/pr52086.c: New test.
--- gcc/config/i386/i386.md.jj 2012-01-13 21:47:34.000000000 +0100
+++ gcc/config/i386/i386.md 2012-02-01 22:42:57.805296347 +0100
@@ -17232,6 +17232,9 @@ (define_peephole2
&& REG_P (operands[0]) && REG_P (operands[4])
&& REGNO (operands[0]) == REGNO (operands[4])
&& peep2_reg_dead_p (4, operands[0])
+ && (<MODE>mode != QImode
+ || immediate_operand (operands[2], SImode)
+ || q_regs_operand (operands[2], SImode))
&& !reg_overlap_mentioned_p (operands[0], operands[1])
&& ix86_match_ccmode (peep2_next_insn (3),
(GET_CODE (operands[3]) == PLUS
--- gcc/testsuite/gcc.dg/pr52086.c.jj 2012-02-01 22:56:54.520519545 +0100
+++ gcc/testsuite/gcc.dg/pr52086.c 2012-02-01 22:56:35.000000000 +0100
@@ -0,0 +1,21 @@
+/* PR target/52086 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-fpic" { target fpic } } */
+
+struct S { char a; char b[100]; };
+int bar (void);
+int baz (int);
+
+void
+foo (struct S *x)
+{
+ if (bar () & 1)
+ {
+ char c = bar ();
+ baz (4);
+ x->a += c;
+ while (x->a)
+ x->b[c] = bar ();
+ }
+}
Jakub