From: Richard Sandiford Date: Mon, 17 Nov 2008 22:49:05 +0000 (+0000) Subject: mips.md (*mul_acc_si): Remove middle alternative and its associated define_split. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=839380ee609b06d30fd574b0396d66a58f58bb57;p=platform%2Fupstream%2Fgcc.git mips.md (*mul_acc_si): Remove middle alternative and its associated define_split. gcc/ * config/mips/mips.md (*mul_acc_si): Remove middle alternative and its associated define_split. Expose the all-d alternative to the register allocator, but mark it with "?". Mark the first alternative with "*?*?". (*mul_sub_si): Likewise. (*mul_acc_si_r3900): New pattern. gcc/testsuite/ * gcc.target/mips/madd-5.c: New test. * gcc.target/mips/madd-6.c: Likewise. * gcc.target/mips/madd-7.c: Likewise. * gcc.target/mips/madd-8.c: Likewise. * gcc.target/mips/msub-5.c: Likewise. * gcc.target/mips/msub-6.c: Likewise. * gcc.target/mips/msub-7.c: Likewise. * gcc.target/mips/msub-8.c: Likewise. From-SVN: r141954 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff38275..37bedc0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-11-17 Richard Sandiford + + * config/mips/mips.md (*mul_acc_si): Remove middle alternative + and its associated define_split. Expose the all-d alternative + to the register allocator, but mark it with "?". Mark the first + alternative with "*?*?". + (*mul_sub_si): Likewise. + (*mul_acc_si_r3900): New pattern. + 2008-11-17 Jakub Jelinek PR middle-end/38140 diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 222e41d..92e637c 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1474,34 +1474,50 @@ ;; Multiply-accumulate patterns -;; For processors that can copy the output to a general register: -;; -;; The all-d alternative is needed because the combiner will find this -;; pattern and then register alloc/reload will move registers around to -;; make them fit, and we don't want to trigger unnecessary loads to LO. -;; -;; The last alternative should be made slightly less desirable, but adding -;; "?" to the constraint is too strong, and causes values to be loaded into -;; LO even when that's more costly. For now, using "*d" mostly does the -;; trick. +;; This pattern is first matched by combine, which tries to use the +;; pattern wherever it can. We don't know until later whether it +;; is actually profitable to use MADD over a "MUL; ADDIU" sequence, +;; so we need to keep both options open. +;; +;; The second alternative has a "?" marker because it is generally +;; one instruction more costly than the first alternative. This "?" +;; marker is enough to convey the relative costs to the register +;; allocator. +;; +;; However, reload counts reloads of operands 4 and 5 in the same way as +;; reloads of the other operands, even though operands 4 and 5 need no +;; copy instructions. Reload therefore thinks that the second alternative +;; is two reloads more costly than the first. We add "*?*?" to the first +;; alternative as a counterweight. (define_insn "*mul_acc_si" - [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") + [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "register_operand" "d,d")) + (match_operand:SI 3 "register_operand" "0,d"))) + (clobber (match_scratch:SI 4 "=X,l")) + (clobber (match_scratch:SI 5 "=X,&d"))] + "GENERATE_MADD_MSUB && !TARGET_MIPS16" + "@ + madd\t%1,%2 + #" + [(set_attr "type" "imadd") + (set_attr "mode" "SI") + (set_attr "length" "4,8")]) + +;; The same idea applies here. The middle alternative needs one less +;; clobber than the final alternative, so we add "*?" as a counterweight. +(define_insn "*mul_acc_si_r3900" + [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") (match_operand:SI 2 "register_operand" "d,d,d")) - (match_operand:SI 3 "register_operand" "0,l,*d"))) + (match_operand:SI 3 "register_operand" "0,l,d"))) (clobber (match_scratch:SI 4 "=X,3,l")) (clobber (match_scratch:SI 5 "=X,X,&d"))] - "(TARGET_MIPS3900 - || GENERATE_MADD_MSUB) - && !TARGET_MIPS16" -{ - static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" }; - if (which_alternative == 2) - return "#"; - if (GENERATE_MADD_MSUB && which_alternative != 0) - return "#"; - return madd[which_alternative]; -} + "TARGET_MIPS3900 && !TARGET_MIPS16" + "@ + madd\t%1,%2 + madd\t%0,%1,%2 + #" [(set_attr "type" "imadd") (set_attr "mode" "SI") (set_attr "length" "4,4,8")]) @@ -1522,23 +1538,6 @@ (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))] "") -;; Split *mul_acc_si if the destination accumulator value is in a GPR -;; and the source accumulator value is in LO. -(define_split - [(set (match_operand:SI 0 "d_operand") - (plus:SI (mult:SI (match_operand:SI 1 "d_operand") - (match_operand:SI 2 "d_operand")) - (match_operand:SI 3 "lo_operand"))) - (clobber (match_dup 3)) - (clobber (scratch:SI))] - "reload_completed" - [(parallel [(set (match_dup 3) - (plus:SI (mult:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (clobber (scratch:SI)) - (clobber (scratch:SI))]) - (set (match_dup 0) (match_dup 3))]) - (define_insn "*macc" [(set (match_operand:SI 0 "register_operand" "=l,d") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") @@ -1718,21 +1717,21 @@ operands[2], operands[0]); }) +;; See the comment above *mul_add_si for details. (define_insn "*mul_sub_si" - [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") - (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") - (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") - (match_operand:SI 3 "register_operand" "d,d,d")))) - (clobber (match_scratch:SI 4 "=X,1,l")) - (clobber (match_scratch:SI 5 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") + (minus:SI (match_operand:SI 1 "register_operand" "0,d") + (mult:SI (match_operand:SI 2 "register_operand" "d,d") + (match_operand:SI 3 "register_operand" "d,d")))) + (clobber (match_scratch:SI 4 "=X,l")) + (clobber (match_scratch:SI 5 "=X,&d"))] "GENERATE_MADD_MSUB" "@ msub\t%2,%3 - # #" [(set_attr "type" "imadd") (set_attr "mode" "SI") - (set_attr "length" "4,8,8")]) + (set_attr "length" "4,8")]) ;; Split *mul_sub_si if both the source and destination accumulator ;; values are GPRs. @@ -1750,24 +1749,6 @@ (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))] "") -;; Split *mul_acc_si if the destination accumulator value is in a GPR -;; and the source accumulator value is in LO. -(define_split - [(set (match_operand:SI 0 "d_operand") - (minus:SI (match_operand:SI 1 "lo_operand") - (mult:SI (match_operand:SI 2 "d_operand") - (match_operand:SI 3 "d_operand")))) - (clobber (match_dup 1)) - (clobber (scratch:SI))] - "reload_completed" - [(parallel [(set (match_dup 1) - (minus:SI (match_dup 1) - (mult:SI (match_dup 2) (match_dup 3)))) - (clobber (scratch:SI)) - (clobber (scratch:SI))]) - (set (match_dup 0) (match_dup 1))] - "") - (define_insn "*muls" [(set (match_operand:SI 0 "register_operand" "=l,d") (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2b90e3d..1d97976 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,16 @@ 2008-11-17 Richard Sandiford + * gcc.target/mips/madd-5.c: New test. + * gcc.target/mips/madd-6.c: Likewise. + * gcc.target/mips/madd-7.c: Likewise. + * gcc.target/mips/madd-8.c: Likewise. + * gcc.target/mips/msub-5.c: Likewise. + * gcc.target/mips/msub-6.c: Likewise. + * gcc.target/mips/msub-7.c: Likewise. + * gcc.target/mips/msub-8.c: Likewise. + +2008-11-17 Richard Sandiford + * gcc.target/mips/no-smartmips-ror-1.c: Use -march=mips32 instead of -march=mips32r2. diff --git a/gcc/testsuite/gcc.target/mips/madd-5.c b/gcc/testsuite/gcc.target/mips/madd-5.c new file mode 100644 index 0000000..780194d --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/madd-5.c @@ -0,0 +1,8 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler-times "\tmadd\t" 4 } } */ +/* { dg-final { scan-assembler-not "\tmtlo\t" } } */ +/* { dg-final { scan-assembler-times "\tmflo\t" 3 } } */ + +NOMIPS16 void f1 (int *a) { a[0] = a[0] * a[1] + a[2] * a[3]; } +NOMIPS16 void f2 (int *a) { a[0] = a[0] * a[1] + a[2] * a[3] + a[4]; } +NOMIPS16 void f3 (int *a) { a[0] = a[0] * a[1] + a[2] * a[3] + a[4] * a[5]; } diff --git a/gcc/testsuite/gcc.target/mips/madd-6.c b/gcc/testsuite/gcc.target/mips/madd-6.c new file mode 100644 index 0000000..bbb6783 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/madd-6.c @@ -0,0 +1,6 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler-not "\tmadd\t" } } */ +/* { dg-final { scan-assembler "\tmul\t" } } */ +/* { dg-final { scan-assembler "\taddu\t" } } */ + +NOMIPS16 void f1 (int *a) { a[0] = a[0] * a[1] + a[2]; } diff --git a/gcc/testsuite/gcc.target/mips/madd-7.c b/gcc/testsuite/gcc.target/mips/madd-7.c new file mode 100644 index 0000000..25fd07d --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/madd-7.c @@ -0,0 +1,14 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler-not "\tmul\t" } } */ +/* { dg-final { scan-assembler "\tmadd\t" } } */ + +NOMIPS16 int +f1 (int *a, int *b, int n) +{ + int x, i; + + x = 0; + for (i = 0; i < n; i++) + x += a[i] * b[i]; + return x; +} diff --git a/gcc/testsuite/gcc.target/mips/madd-8.c b/gcc/testsuite/gcc.target/mips/madd-8.c new file mode 100644 index 0000000..0fc680e --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/madd-8.c @@ -0,0 +1,15 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler "\tmul\t" } } */ +/* { dg-final { scan-assembler-not "\tmadd\t" } } */ +/* { dg-final { scan-assembler-not "\tmtlo\t" } } */ +/* { dg-final { scan-assembler-not "\tmflo\t" } } */ + +NOMIPS16 int +f2 (int x, int y, int z) +{ + asm volatile ("" ::: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", + "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", + "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25", + "$31"); + return x * y + z; +} diff --git a/gcc/testsuite/gcc.target/mips/msub-5.c b/gcc/testsuite/gcc.target/mips/msub-5.c new file mode 100644 index 0000000..675da64 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/msub-5.c @@ -0,0 +1,8 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler-times "\tmsub\t" 4 } } */ +/* { dg-final { scan-assembler-not "\tmtlo\t" } } */ +/* { dg-final { scan-assembler-times "\tmflo\t" 3 } } */ + +NOMIPS16 void f1 (int *a) { a[0] = a[0] * a[1] - a[2] * a[3]; } +NOMIPS16 void f2 (int *a) { a[0] = a[0] * a[1] - a[2] * a[3] - a[4]; } +NOMIPS16 void f3 (int *a) { a[0] = a[0] * a[1] - a[2] * a[3] - a[4] * a[5]; } diff --git a/gcc/testsuite/gcc.target/mips/msub-6.c b/gcc/testsuite/gcc.target/mips/msub-6.c new file mode 100644 index 0000000..afe01cb --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/msub-6.c @@ -0,0 +1,6 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler-not "\tmsub\t" } } */ +/* { dg-final { scan-assembler "\tmul\t" } } */ +/* { dg-final { scan-assembler "\tsubu\t" } } */ + +NOMIPS16 void f1 (int *a) { a[0] = a[0] - a[1] * a[2]; } diff --git a/gcc/testsuite/gcc.target/mips/msub-7.c b/gcc/testsuite/gcc.target/mips/msub-7.c new file mode 100644 index 0000000..9fff31d --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/msub-7.c @@ -0,0 +1,14 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler-not "\tmul\t" } } */ +/* { dg-final { scan-assembler "\tmsub\t" } } */ + +NOMIPS16 int +f1 (int *a, int *b, int n) +{ + int x, i; + + x = 100; + for (i = 0; i < n; i++) + x -= a[i] * b[i]; + return x; +} diff --git a/gcc/testsuite/gcc.target/mips/msub-8.c b/gcc/testsuite/gcc.target/mips/msub-8.c new file mode 100644 index 0000000..7517540 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/msub-8.c @@ -0,0 +1,15 @@ +/* { dg-mips-options "-O2 -march=5kc" } */ +/* { dg-final { scan-assembler "\tmul\t" } } */ +/* { dg-final { scan-assembler-not "\tmsub\t" } } */ +/* { dg-final { scan-assembler-not "\tmtlo\t" } } */ +/* { dg-final { scan-assembler-not "\tmflo\t" } } */ + +NOMIPS16 int +f2 (int x, int y, int z) +{ + asm volatile ("" ::: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", + "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", + "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25", + "$31"); + return x - y * z; +}