This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix i?86/x86_64 shift + plus peephole2 (PR target/47800)
- 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: Fri, 18 Feb 2011 21:58:37 +0100
- Subject: [PATCH] Fix i?86/x86_64 shift + plus peephole2 (PR target/47800)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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