Commit 839380ee by Richard Sandiford Committed by Richard Sandiford

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
parent 2cf1a19e
2008-11-17 Richard Sandiford <rdsandiford@googlemail.com>
* 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 <jakub@redhat.com>
PR middle-end/38140
......
......@@ -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")
......
2008-11-17 Richard Sandiford <rdsandiford@googlemail.com>
* 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 <rdsandiford@googlemail.com>
* gcc.target/mips/no-smartmips-ror-1.c: Use -march=mips32 instead
of -march=mips32r2.
......
/* { 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]; }
/* { 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]; }
/* { 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;
}
/* { 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;
}
/* { 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]; }
/* { 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]; }
/* { 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;
}
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment