diff mbox

Fix TARGET_READ_MODIFY_WRITE peephole2s (PR target/57568)

Message ID 20130609085724.GM1493@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek June 9, 2013, 8:57 a.m. UTC
Hi!

These two peephole2s misbehave if it sees e.g.
regN = mem
regN = regN + regN
mem = regN
CC = regN != 0
because transforming it into
mem = mem + regN ; CC = mem != 0
is wrong, I forgot to verify the second operand of the
plusminuslogic_operator doesn't overlap the first operand.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk/4.8 and perhaps also 4.7 (where it is just latent)?

2013-06-09  Jakub Jelinek  <jakub@redhat.com>

	PR target/57568
	* config/i386/i386.md (TARGET_READ_MODIFY_WRITE peepholes): Ensure
	that operands[2] doesn't overlap with operands[0].

	* gcc.c-torture/execute/pr57568.c: New test.


	Jakub

Comments

Uros Bizjak June 9, 2013, 6:22 p.m. UTC | #1
On Sun, Jun 9, 2013 at 10:57 AM, Jakub Jelinek <jakub@redhat.com> wrote:

> These two peephole2s misbehave if it sees e.g.
> regN = mem
> regN = regN + regN
> mem = regN
> CC = regN != 0
> because transforming it into
> mem = mem + regN ; CC = mem != 0
> is wrong, I forgot to verify the second operand of the
> plusminuslogic_operator doesn't overlap the first operand.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk/4.8 and perhaps also 4.7 (where it is just latent)?
>
> 2013-06-09  Jakub Jelinek  <jakub@redhat.com>
>
>         PR target/57568
>         * config/i386/i386.md (TARGET_READ_MODIFY_WRITE peepholes): Ensure
>         that operands[2] doesn't overlap with operands[0].
>
>         * gcc.c-torture/execute/pr57568.c: New test.

The patch is OK everywhere.

Thanks,
Uros.
diff mbox

Patch

--- gcc/config/i386/i386.md.jj	2013-06-03 19:15:34.000000000 +0200
+++ gcc/config/i386/i386.md	2013-06-08 21:59:43.416954936 +0200
@@ -16591,6 +16591,7 @@  (define_peephole2
   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
    && peep2_reg_dead_p (4, operands[0])
    && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
    && (<MODE>mode != QImode
        || immediate_operand (operands[2], QImode)
        || q_regs_operand (operands[2], QImode))
@@ -16655,6 +16656,7 @@  (define_peephole2
        || immediate_operand (operands[2], SImode)
        || q_regs_operand (operands[2], SImode))
    && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
    && ix86_match_ccmode (peep2_next_insn (3),
 			 (GET_CODE (operands[3]) == PLUS
 			  || GET_CODE (operands[3]) == MINUS)
--- gcc/testsuite/gcc.c-torture/execute/pr57568.c.jj	2013-06-08 22:03:38.861005658 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr57568.c	2013-06-08 22:03:19.000000000 +0200
@@ -0,0 +1,12 @@ 
+/* PR target/57568 */
+
+extern void abort (void);
+int a[6][9] = { }, b = 1, *c = &a[3][5];
+
+int
+main ()
+{
+  if (b && (*c = *c + *c))
+    abort ();
+  return 0;
+}