This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix ARM neon vashr<mode>3 and vlshr<mode>3 expanders (PR target/52375)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Ramana Radhakrishnan <ramana dot radhakrishnan at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 27 Feb 2012 16:12:01 +0100
- Subject: [PATCH] Fix ARM neon vashr<mode>3 and vlshr<mode>3 expanders (PR target/52375)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
We ICE shortly after expansion on this testcase, because
vlshrv4si3 expander is called with a SUBREG as operands[2],
but we were testing just for REG_P, and in the other branch
we assume that it is an immediate. But there is no right shift
with register shift count.
Fixed thusly, additionally moved the neg initialization down into
the scope in which it is used to avoid creating a pseudo needlessly.
Ok for trunk?
2012-02-27 Jakub Jelinek <jakub@redhat.com>
PR target/52375
* config/arm/neon.md (vashr<mode>3, vlshr<mode>3): Use
s_register_operand in the test instead of REG_P. Don't call
gen_reg_rtx if it won't be used.
* gcc.target/arm/pr52375.c: New test.
* gcc.c-torture/compile/pr52375.c: New test.
--- gcc/config/arm/neon.md.jj 2012-01-20 12:35:15.000000000 +0100
+++ gcc/config/arm/neon.md 2012-02-27 13:03:42.981798700 +0100
@@ -1064,9 +1064,9 @@ (define_expand "vashr<mode>3"
(match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
"TARGET_NEON"
{
- rtx neg = gen_reg_rtx (<MODE>mode);
- if (REG_P (operands[2]))
+ if (s_register_operand (operands[2], <MODE>mode))
{
+ rtx neg = gen_reg_rtx (<MODE>mode);
emit_insn (gen_neg<mode>2 (neg, operands[2]));
emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
}
@@ -1081,9 +1081,9 @@ (define_expand "vlshr<mode>3"
(match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
"TARGET_NEON"
{
- rtx neg = gen_reg_rtx (<MODE>mode);
- if (REG_P (operands[2]))
+ if (s_register_operand (operands[2], <MODE>mode))
{
+ rtx neg = gen_reg_rtx (<MODE>mode);
emit_insn (gen_neg<mode>2 (neg, operands[2]));
emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
}
--- gcc/testsuite/gcc.target/arm/pr52375.c.jj 2012-02-27 13:16:27.679449171 +0100
+++ gcc/testsuite/gcc.target/arm/pr52375.c 2012-02-27 13:01:04.000000000 +0100
@@ -0,0 +1,15 @@
+/* PR target/52375 */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-march=armv7-a -mfloat-abi=hard -mfpu=neon -O -ftree-vectorize" } */
+
+struct C { int c, d; };
+
+unsigned
+foo (struct C *p)
+{
+ unsigned int b = 0, i;
+ for (i = 0; i < 64; i++)
+ b |= 0x80000000U >> p[i].c;
+ return b;
+}
--- gcc/testsuite/gcc.c-torture/compile/pr52375.c.jj 2012-02-27 13:16:46.263345654 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr52375.c 2012-02-27 13:16:50.221320554 +0100
@@ -0,0 +1,12 @@
+/* PR target/52375 */
+
+struct C { int c, d; };
+
+unsigned
+foo (struct C *p)
+{
+ unsigned int b = 0, i;
+ for (i = 0; i < 64; i++)
+ b |= 0x80000000U >> p[i].c;
+ return b;
+}
Jakub