This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][ARM] Fix PR 59290
- From: Kyrill Tkachov <kyrylo dot tkachov at arm dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Date: Tue, 26 Nov 2013 14:49:59 +0000
- Subject: [PATCH][ARM] Fix PR 59290
- Authentication-results: sourceware.org; auth=none
Hi all,
In the spirit of stage3, this patch fixes a regression in
gcc.target/arm/negdi-2.c when compiling for big-endian with the new rtx costs
for the Cortex-A9. We ended up generating an extra mov because combine generates
a zero-extend operation that would later get split into two moves (versus the
old way where combine would generate two moves and reload would eliminate one of
them). The fix is three-fold:
- We fix the cost calculation for zero-extend when extending from SImode to
DImode by initialising the cost correctly.
- We add a splitter to match the negate-and-extend operation and break it down
into its constituent operations early on.
- Generalise the register pattern for which we scan in the testcase itself since
for big-endian the negated part goes into r1, not r0.
Tested arm-none-eabi on qemu.
Ok for trunk?
Thanks,
Kyrill
2013-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/59290
* config/arm/arm.md (*zextendsidi_negsi): New pattern.
* config/arm/arm.c (arm_new_rtx_costs): Initialise cost correctly
for zero_extend case.
2013-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/59290
* gcc.target/arm/negdi-2.c: Scan more general register names.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 91651b2..6caa44d 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -10261,6 +10261,8 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
if (speed_p)
*cost += 2 * extra_cost->alu.shift;
}
+ else /* GET_MODE (XEXP (x, 0)) == SImode. */
+ *cost = COSTS_N_INSNS (1);
/* Widening beyond 32-bits requires one more insn. */
if (mode == DImode)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 2998e63..6cac1d0 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4718,6 +4718,24 @@
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
+(define_insn_and_split "*zextendsidi_negsi"
+ [(set (match_operand:DI 0 "s_register_operand" "=r")
+ (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
+ "TARGET_32BIT"
+ "#"
+ ""
+ [(set (match_dup 2)
+ (neg:SI (match_dup 1)))
+ (set (match_dup 3)
+ (const_int 0))]
+ {
+ operands[2] = gen_lowpart (SImode, operands[0]);
+ operands[3] = gen_highpart (SImode, operands[0]);
+ }
+ [(set_attr "length" "8")
+ (set_attr "type" "multiple")]
+)
+
;; Negate an extended 32-bit value.
(define_insn_and_split "*negdi_extendsidi"
[(set (match_operand:DI 0 "s_register_operand" "=l,r")
diff --git a/gcc/testsuite/gcc.target/arm/negdi-2.c b/gcc/testsuite/gcc.target/arm/negdi-2.c
index 96bbcab..4444c20 100644
--- a/gcc/testsuite/gcc.target/arm/negdi-2.c
+++ b/gcc/testsuite/gcc.target/arm/negdi-2.c
@@ -11,6 +11,6 @@ Expected output:
rsb r0, r0, #0
mov r1, #0
*/
-/* { dg-final { scan-assembler-times "rsb\\tr0, r0, #0" 1 { target { arm_nothumb } } } } */
-/* { dg-final { scan-assembler-times "negs\\tr0, r0" 1 { target { ! arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "rsb\\t...?, ...?, #0" 1 { target { arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "negs\\t...?, ...?" 1 { target { ! arm_nothumb } } } } */
/* { dg-final { scan-assembler-times "mov" 1 } } */