Message ID | 5294B517.3090601@arm.com |
---|---|
State | New |
Headers | show |
On 26/11/13 14:49, Kyrill Tkachov wrote: > 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. > OK. R.
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 } } */