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][ARM] Fix PR 59290


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 } } */

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