diff mbox

Fix i?86/x86_64 shift + plus peephole2 (PR target/47800)

Message ID 20110218205837.GO30899@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 18, 2011, 8:58 p.m. UTC
Hi!

This testcase ICEs (on !TARGET_PARTIAL_REG_STALL targets) because
this peephole2 creates the first insn with mistmatching modes
(destination uses SImode, src has QImode).
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk?

2011-02-18  Jakub Jelinek  <jakub@redhat.com>

	PR target/47800
	* config/i386/i386.md (peephole2 for shift and plus): Use
	operands[1] original mode in the first insn.

	* gcc.target/i386/pr47800.c: New test.


	Jakub

Comments

Uros Bizjak Feb. 19, 2011, 10:38 a.m. UTC | #1
On Fri, Feb 18, 2011 at 9:58 PM, Jakub Jelinek <jakub@redhat.com> wrote:

> This testcase ICEs (on !TARGET_PARTIAL_REG_STALL targets) because
> this peephole2 creates the first insn with mistmatching modes
> (destination uses SImode, src has QImode).
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
> ok for trunk?
>
> 2011-02-18  Jakub Jelinek  <jakub@redhat.com>
>
>        PR target/47800
>        * config/i386/i386.md (peephole2 for shift and plus): Use
>        operands[1] original mode in the first insn.
>
>        * gcc.target/i386/pr47800.c: New test.

Please change INTVAL ... line to

IN_RANGE (INTVAL (operands[2]), 1, 3)

OK with that change.

Thanks,
Uros.
diff mbox

Patch

--- gcc/config/i386/i386.md.jj	2011-01-18 12:20:15.000000000 +0100
+++ gcc/config/i386/i386.md	2011-02-18 15:45:55.000000000 +0100
@@ -17461,7 +17461,7 @@  (define_peephole2
 		   (plus (match_dup 0)
 			 (match_operand 4 "x86_64_general_operand" "")))
 		   (clobber (reg:CC FLAGS_REG))])]
-  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
+  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3
    /* Validate MODE for lea.  */
    && ((!TARGET_PARTIAL_REG_STALL
 	&& (GET_MODE (operands[0]) == QImode
@@ -17475,7 +17475,8 @@  (define_peephole2
   [(set (match_dup 5) (match_dup 4))
    (set (match_dup 0) (match_dup 1))]
 {
-  enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
+  enum machine_mode op1mode = GET_MODE (operands[1]);
+  enum machine_mode mode = op1mode == DImode ? DImode : SImode;
   int scale = 1 << INTVAL (operands[2]);
   rtx index = gen_lowpart (Pmode, operands[1]);
   rtx base = gen_lowpart (Pmode, operands[5]);
@@ -17485,10 +17486,9 @@  (define_peephole2
   			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
   operands[5] = base;
   if (mode != Pmode)
-    {
-      operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
-      operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
-    }
+    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
+  if (op1mode != Pmode)
+    operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
   operands[0] = dest;
 })
 
--- gcc/testsuite/gcc.target/i386/pr47800.c.jj	2011-02-18 15:32:47.000000000 +0100
+++ gcc/testsuite/gcc.target/i386/pr47800.c	2011-02-18 15:31:59.000000000 +0100
@@ -0,0 +1,15 @@ 
+/* PR target/47800 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=nocona" } */
+
+int
+foo (unsigned char *x, unsigned char *y)
+{
+  unsigned char a;
+  for (a = 0; x < y; x++)
+    if (a & 0x80)
+      a = (unsigned char) (a << 1) + 1 + *x;
+    else
+      a = (unsigned char) (a << 1) + *x;
+  return a;
+}