This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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.

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

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]