This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][m68k] PR target/36134 Prefer LEA over ADD.L
- From: Andrew Stubbs <ams at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 13 Nov 2008 14:05:59 +0000
- Subject: [PATCH][m68k] PR target/36134 Prefer LEA over ADD.L
The attached patch attempts to resolve pr36134 by preferring the 4-byte
LEA instruction over the longer 6-byte ADD.L instruction, where appropriate.
This patch differs somewhat from the original patch posted by Gunnar von
Boehm in that it only prefers LEA when it would not use an extra
register. It also takes the split condition and scheduling attributes
into account, and adds a test-case.
I've run a full test with no regressions.
OK?
Andrew Stubbs
2008-11-13 Maxim Kuvyrkov <maxim@codesourcery.com>
Andrew Stubbs <ams@codesourcery.com>
Gunnar Von Boehn <gunnar@genesi-usa.com>
gcc/
PR target/36134
* config/m68k/m68k.md (addsi3_5200): Add a new alternative preferring
the shorter LEA insn over ADD.L where possible.
gcc/testsuite/
PR target/36134
* gcc.target/m68k/pr36134.c: New test.
---
src/gcc-4.3/gcc/config/m68k/m68k.md | 25 ++++++++++----------
src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36134.c | 23 ++++++++++++++++++
2 files changed, 36 insertions(+), 12 deletions(-)
Index: issue3283/src/gcc-4.3/gcc/config/m68k/m68k.md
===================================================================
--- issue3283.orig/src/gcc-4.3/gcc/config/m68k/m68k.md 2008-11-12 15:07:27.000000000 +0000
+++ issue3283/src/gcc-4.3/gcc/config/m68k/m68k.md 2008-11-13 12:42:12.000000000 +0000
@@ -2368,9 +2368,9 @@
"* return output_addsi3 (operands);")
(define_insn_and_split "*addsi3_5200"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,m,r, ?a,?a,?a,?a")
- (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0,0, a, a, r, a")
- (match_operand:SI 2 "general_src_operand" " I, L, d,mrKi,Cj,r, a, J")))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a,m,r, ?a, ?a,?a,?a")
+ (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0,0,0, a, a, r, a")
+ (match_operand:SI 2 "general_src_operand" " I, L, J,d,mrKi,Cj, r, a, J")))]
"TARGET_COLDFIRE"
{
switch (which_alternative)
@@ -2382,21 +2382,22 @@
operands[2] = GEN_INT (- INTVAL (operands[2]));
return "subq%.l %2,%0";
- case 2:
case 3:
+ case 4:
return "add%.l %2,%0";
- case 4:
+ case 5:
/* move%.l %2,%0\n\tadd%.l %1,%0 */
return "#";
- case 5:
+ case 6:
return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
- case 6:
+ case 7:
return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0";
- case 7:
+ case 2:
+ case 8:
return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
default:
@@ -2404,16 +2405,16 @@
return "";
}
}
- "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 4) && !operands_match_p (operands[0], operands[1])"
+ "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])"
[(set (match_dup 0)
(match_dup 2))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_dup 1)))]
""
- [(set_attr "type" "aluq_l,aluq_l,alu_l,alu_l,*,lea,lea,lea")
- (set_attr "opy" "2,2,2,2,*,*,*,*")
- (set_attr "opy_type" "*,*,*,*,*,mem6,mem6,mem5")])
+ [(set_attr "type" "aluq_l,aluq_l,lea,alu_l,alu_l,*,lea,lea,lea")
+ (set_attr "opy" "2,2,*,2,2,*,*,*,*")
+ (set_attr "opy_type" "*,*,mem5,*,*,*,mem6,mem6,mem5")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=a")
Index: issue3283/src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36134.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ issue3283/src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36134.c 2008-11-12 15:10:47.000000000 +0000
@@ -0,0 +1,23 @@
+/* pr36134.c
+
+ This test ensures that the shorter LEA instruction is used in preference
+ to the longer ADD instruction. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "lea" } } */
+/* { dg-final { scan-assembler-not "add" } } */
+
+int *a, *b;
+
+void
+f ()
+{
+ while (a > b)
+ {
+ *a++ = *b++;
+ *a++ = *b++;
+ *a++ = *b++;
+ *a++ = *b++;
+ }
+}