Patchwork Fix i?86 mem += reg + comparison peephole (PR target/52086)

login
register
mail settings
Submitter Jakub Jelinek
Date Feb. 2, 2012, 8:15 a.m.
Message ID <20120202081516.GX18768@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/139090/
State New
Headers show

Comments

Jakub Jelinek - Feb. 2, 2012, 8:15 a.m.
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.


	Jakub
Uros Bizjak - Feb. 2, 2012, 9:02 a.m.
On Thu, Feb 2, 2012 at 9:15 AM, Jakub Jelinek <jakub@redhat.com> wrote:

> 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.

OK, probably we also need to backport this fix to other release branches.

Thanks,
Uros.
Jakub Jelinek - Feb. 2, 2012, 9:15 a.m.
On Thu, Feb 02, 2012 at 10:02:09AM +0100, Uros Bizjak wrote:
> OK, 

Thanks.

> probably we also need to backport this fix to other release branches.

No, while I didn't remember it, svn blame revealed that these peepholes
were my fault, added for PR49095 just for 4.7+.

	Jakub

Patch

--- 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 ();
+    }
+}