summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-24 05:51:57 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-24 05:51:57 +0000
commit7e564f7304a4050ea56fed5b6d3158e48b6d0389 (patch)
tree414ebf4e011654eddd3531c3e652690d778992c9
parent32201e9aeb52a4eef9ba61c156399f0090a98023 (diff)
downloadppe42-gcc-7e564f7304a4050ea56fed5b6d3158e48b6d0389.tar.gz
ppe42-gcc-7e564f7304a4050ea56fed5b6d3158e48b6d0389.zip
gcc/
2007-xx-xx Chao-ying Fu <fu@mips.com> Richard Sandiford <richard@nildram.co.uk> * doc/md.texi (madd@var{m}@var{n}4, umadd@var{m}@var{n}4): Document. * optabs.h (OTI_smadd_widen, OTI_umadd_widen): New optab_indexes. (smadd_widen_optab, umadd_widen_optab): Define. * optabs.c (init_optabs): Initialize smadd_widen_optab and umadd_widen_optab. * genopinit.c (optabs): Fill in smadd_widen_optab and umadd_widen_optab. * expr.c (expand_expr_real_1): Try to use smadd_widen_optab and umadd_widen_optab to implement multiply-add sequences. * config/mips/mips.md (*<su>mul_acc_di): Rename to... (<u>maddsidi4): ...this. Extend condition to include GENERATE_MADD_MSUB and TARGET_DSPR2. Change the constraint of operand 0 to "ka" and use the three-operand form of madd<u> for TARGET_DSPR2. * config/mips/mips-dspr2.md (mips_madd, mips_maddu): Convert to define_expands. * config/mips/constraints.md (ka): New register constraint. gcc/testsuite/ 2007-xx-xx Richard Sandiford <richard@nildram.co.uk> * gcc.target/mips/madd-1.c, gcc.target/mips/madd-2.c, * gcc.target/mips/madd-3.c, gcc.target/mips/madd-4.c, * gcc.target/mips/maddu-1.c, gcc.target/mips/maddu-2.c, * gcc.target/mips/maddu-3.c, gcc.target/mips/maddu-4.c: New tests. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124095 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/mips/constraints.md5
-rw-r--r--gcc/config/mips/mips-dspr2.md31
-rw-r--r--gcc/config/mips/mips.md10
-rw-r--r--gcc/doc/md.texi18
-rw-r--r--gcc/expr.c43
-rw-r--r--gcc/genopinit.c2
-rw-r--r--gcc/optabs.c2
-rw-r--r--gcc/optabs.h8
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-1.c25
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-2.c25
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-3.c25
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-4.c25
-rw-r--r--gcc/testsuite/gcc.target/mips/maddu-1.c28
-rw-r--r--gcc/testsuite/gcc.target/mips/maddu-2.c28
-rw-r--r--gcc/testsuite/gcc.target/mips/maddu-3.c28
-rw-r--r--gcc/testsuite/gcc.target/mips/maddu-4.c28
18 files changed, 329 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5825eccde03..3983b427938 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2007-04-24 Chao-ying Fu <fu@mips.com>
+ Richard Sandiford <richard@nildram.co.uk>
+
+ * doc/md.texi (madd@var{m}@var{n}4, umadd@var{m}@var{n}4): Document.
+ * optabs.h (OTI_smadd_widen, OTI_umadd_widen): New optab_indexes.
+ (smadd_widen_optab, umadd_widen_optab): Define.
+ * optabs.c (init_optabs): Initialize smadd_widen_optab and
+ umadd_widen_optab.
+ * genopinit.c (optabs): Fill in smadd_widen_optab and
+ umadd_widen_optab.
+ * expr.c (expand_expr_real_1): Try to use smadd_widen_optab
+ and umadd_widen_optab to implement multiply-add sequences.
+ * config/mips/mips.md (*<su>mul_acc_di): Rename to...
+ (<u>maddsidi4): ...this. Extend condition to include
+ GENERATE_MADD_MSUB and TARGET_DSPR2. Change the constraint
+ of operand 0 to "ka" and use the three-operand form of madd<u>
+ for TARGET_DSPR2.
+ * config/mips/mips-dspr2.md (mips_madd, mips_maddu): Convert
+ to define_expands.
+ * config/mips/constraints.md (ka): New register constraint.
+
2007-04-24 Jan Hubicka <j@suse.cz>
Revert:
diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md
index a01777dc926..1388fc2cca1 100644
--- a/gcc/config/mips/constraints.md
+++ b/gcc/config/mips/constraints.md
@@ -78,6 +78,11 @@
(define_register_constraint "D" "COP3_REGS"
"@internal")
+;; Registers that can be used as the target of multiply-accumulate
+;; instructions. The core MIPS32 ISA provides a hi/lo madd,
+;; but the DSPr2 version allows any accumulator target.
+(define_register_constraint "ka" "TARGET_DSPR2 ? ACC_REGS : MD_REGS")
+
;; Integer constraints
(define_constraint "I"
diff --git a/gcc/config/mips/mips-dspr2.md b/gcc/config/mips/mips-dspr2.md
index 948c693c7d8..dd0aab553a1 100644
--- a/gcc/config/mips/mips-dspr2.md
+++ b/gcc/config/mips/mips-dspr2.md
@@ -154,31 +154,13 @@
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
-(define_insn "mips_madd"
- [(set (match_operand:DI 0 "register_operand" "=a")
+(define_expand "mips_madd<u>"
+ [(set (match_operand:DI 0 "register_operand")
(plus:DI
- (mult:DI (sign_extend:DI
- (match_operand:SI 2 "register_operand" "d"))
- (sign_extend:DI
- (match_operand:SI 3 "register_operand" "d")))
- (match_operand:DI 1 "register_operand" "0")))]
- "TARGET_DSPR2 && !TARGET_64BIT"
- "madd\t%q0,%2,%3"
- [(set_attr "type" "imadd")
- (set_attr "mode" "SI")])
-
-(define_insn "mips_maddu"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (plus:DI
- (mult:DI (zero_extend:DI
- (match_operand:SI 2 "register_operand" "d"))
- (zero_extend:DI
- (match_operand:SI 3 "register_operand" "d")))
- (match_operand:DI 1 "register_operand" "0")))]
- "TARGET_DSPR2 && !TARGET_64BIT"
- "maddu\t%q0,%2,%3"
- [(set_attr "type" "imadd")
- (set_attr "mode" "SI")])
+ (mult:DI (any_extend:DI (match_operand:SI 2 "register_operand"))
+ (any_extend:DI (match_operand:SI 3 "register_operand")))
+ (match_operand:DI 1 "register_operand")))]
+ "TARGET_DSPR2 && !TARGET_64BIT")
(define_insn "mips_msub"
[(set (match_operand:DI 0 "register_operand" "=a")
@@ -623,4 +605,3 @@
"dpsqx_sa.w.ph\t%q0,%z2,%z3"
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
-
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 12415e42f99..e44b919ccb9 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1767,18 +1767,20 @@
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
-(define_insn "*<su>mul_acc_di"
- [(set (match_operand:DI 0 "register_operand" "=x")
+(define_insn "<u>maddsidi4"
+ [(set (match_operand:DI 0 "register_operand" "=ka")
(plus:DI
(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
(any_extend:DI (match_operand:SI 2 "register_operand" "d")))
(match_operand:DI 3 "register_operand" "0")))]
- "(TARGET_MAD || ISA_HAS_MACC)
+ "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || TARGET_DSPR2)
&& !TARGET_64BIT"
{
if (TARGET_MAD)
return "mad<u>\t%1,%2";
- else if (TARGET_MIPS5500)
+ else if (TARGET_DSPR2)
+ return "madd<u>\t%q0,%1,%2";
+ else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
return "madd<u>\t%1,%2";
else
/* See comment in *macc. */
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 01705ad282d..56cc60f2e1e 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3669,6 +3669,24 @@ The least significant half of the product is discarded.
@item @samp{umul@var{m}3_highpart}
Similar, but the multiplication is unsigned.
+@cindex @code{madd@var{m}@var{n}4} instruction pattern
+@item @samp{madd@var{m}@var{n}4}
+Multiply operands 1 and 2, sign-extend them to mode @var{n}, add
+operand 3, and store the result in operand 0. Operands 1 and 2
+have mode @var{m} and operands 0 and 3 have mode @var{n}.
+Both modes must be integer modes and @var{n} must be twice
+the size of @var{m}.
+
+In other words, @code{madd@var{m}@var{n}4} is like
+@code{mul@var{m}@var{n}3} except that it also adds operand 3.
+
+These instructions are not allowed to @code{FAIL}.
+
+@cindex @code{umadd@var{m}@var{n}4} instruction pattern
+@item @samp{umadd@var{m}@var{n}4}
+Like @code{madd@var{m}@var{n}4}, but zero-extend the multiplication
+operands instead of sign-extending them.
+
@cindex @code{divmod@var{m}4} instruction pattern
@item @samp{divmod@var{m}4}
Signed division that produces both a quotient and a remainder.
diff --git a/gcc/expr.c b/gcc/expr.c
index e239f4c69b5..34cc0aa6553 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6824,7 +6824,7 @@ static rtx
expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl)
{
- rtx op0, op1, temp, decl_rtl;
+ rtx op0, op1, op2, temp, decl_rtl;
tree type;
int unsignedp;
enum machine_mode mode;
@@ -7977,6 +7977,47 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return op0;
case PLUS_EXPR:
+ /* Check if this is a case for multiplication and addition. */
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TREE_CODE (TREE_OPERAND (exp, 0)) == MULT_EXPR)
+ {
+ tree subsubexp0, subsubexp1;
+ enum tree_code code0, code1;
+
+ subexp0 = TREE_OPERAND (exp, 0);
+ subsubexp0 = TREE_OPERAND (subexp0, 0);
+ subsubexp1 = TREE_OPERAND (subexp0, 1);
+ code0 = TREE_CODE (subsubexp0);
+ code1 = TREE_CODE (subsubexp1);
+ if (code0 == NOP_EXPR && code1 == NOP_EXPR
+ && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0)))
+ < TYPE_PRECISION (TREE_TYPE (subsubexp0)))
+ && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0)))
+ == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp1, 0))))
+ && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp0, 0)))
+ == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp1, 0)))))
+ {
+ tree op0type = TREE_TYPE (TREE_OPERAND (subsubexp0, 0));
+ enum machine_mode innermode = TYPE_MODE (op0type);
+ bool zextend_p = TYPE_UNSIGNED (op0type);
+ this_optab = zextend_p ? umadd_widen_optab : smadd_widen_optab;
+ if (mode == GET_MODE_2XWIDER_MODE (innermode)
+ && (this_optab->handlers[(int) mode].insn_code
+ != CODE_FOR_nothing))
+ {
+ expand_operands (TREE_OPERAND (subsubexp0, 0),
+ TREE_OPERAND (subsubexp1, 0),
+ NULL_RTX, &op0, &op1, EXPAND_NORMAL);
+ op2 = expand_expr (TREE_OPERAND (exp, 1), subtarget,
+ VOIDmode, 0);
+ temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
+ target, unsignedp);
+ gcc_assert (temp);
+ return REDUCE_BIT_FIELD (temp);
+ }
+ }
+ }
+
/* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
something else, make sure we add the register to the constant and
then to the other thing. This case can occur during strength
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 0e6d419bcbe..992981aa8c0 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -85,6 +85,8 @@ static const char * const optabs[] =
"smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
"umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
"usmul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(usmul$a$b3$)$N",
+ "smadd_widen_optab->handlers[$B].insn_code = CODE_FOR_$(madd$a$b4$)$N",
+ "umadd_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umadd$a$b4$)$N",
"sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
"sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
"udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
diff --git a/gcc/optabs.c b/gcc/optabs.c
index b45a9b3abad..49e01217414 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5439,6 +5439,8 @@ init_optabs (void)
smul_widen_optab = init_optab (UNKNOWN);
umul_widen_optab = init_optab (UNKNOWN);
usmul_widen_optab = init_optab (UNKNOWN);
+ smadd_widen_optab = init_optab (UNKNOWN);
+ umadd_widen_optab = init_optab (UNKNOWN);
sdiv_optab = init_optab (DIV);
sdivv_optab = init_optabv (DIV);
sdivmod_optab = init_optab (UNKNOWN);
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 62a69c742fb..e5bbef89e4c 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -86,6 +86,12 @@ enum optab_index
OTI_umul_widen,
/* Widening multiply of one unsigned and one signed operand. */
OTI_usmul_widen,
+ /* Signed multiply and add with the result and addend one machine mode
+ wider than the multiplicand and multiplier. */
+ OTI_smadd_widen,
+ /* Unigned multiply and add with the result and addend one machine mode
+ wider than the multiplicand and multiplier. */
+ OTI_umadd_widen,
/* Signed divide */
OTI_sdiv,
@@ -309,6 +315,8 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define smul_widen_optab (optab_table[OTI_smul_widen])
#define umul_widen_optab (optab_table[OTI_umul_widen])
#define usmul_widen_optab (optab_table[OTI_usmul_widen])
+#define smadd_widen_optab (optab_table[OTI_smadd_widen])
+#define umadd_widen_optab (optab_table[OTI_umadd_widen])
#define sdiv_optab (optab_table[OTI_sdiv])
#define smulv_optab (optab_table[OTI_smulv])
#define sdivv_optab (optab_table[OTI_sdivv])
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5c9223922bb..d94dc90c33d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2007-04-24 Richard Sandiford <richard@nildram.co.uk>
+
+ * gcc.target/mips/madd-1.c, gcc.target/mips/madd-2.c,
+ * gcc.target/mips/madd-3.c, gcc.target/mips/madd-4.c,
+ * gcc.target/mips/maddu-1.c, gcc.target/mips/maddu-2.c,
+ * gcc.target/mips/maddu-3.c, gcc.target/mips/maddu-4.c: New tests.
+
2007-04-23 Simon Baldwin <simonb@google.com>
* g++.dg/other/error15.C: New.
diff --git a/gcc/testsuite/gcc.target/mips/madd-1.c b/gcc/testsuite/gcc.target/mips/madd-1.c
new file mode 100644
index 00000000000..e5223396e8d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-1.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=vr4130 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmacc\t\\\$1," 3 } } */
+
+long long
+f1 (int x, int y, long long z)
+{
+ return (long long) x * y + z;
+}
+
+long long
+f2 (int x, int y, long long z)
+{
+ return z + (long long) y * x;
+}
+
+long long
+f3 (int x, int y, long long z)
+{
+ long long t = (long long) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/madd-2.c b/gcc/testsuite/gcc.target/mips/madd-2.c
new file mode 100644
index 00000000000..4c761ed6ca4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-2.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=vr5500 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmadd\t" 3 } } */
+
+long long
+f1 (int x, int y, long long z)
+{
+ return (long long) x * y + z;
+}
+
+long long
+f2 (int x, int y, long long z)
+{
+ return z + (long long) y * x;
+}
+
+long long
+f3 (int x, int y, long long z)
+{
+ long long t = (long long) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/madd-3.c b/gcc/testsuite/gcc.target/mips/madd-3.c
new file mode 100644
index 00000000000..6fc30e57a6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-3.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -mips32 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmadd\t" 3 } } */
+
+long long
+f1 (int x, int y, long long z)
+{
+ return (long long) x * y + z;
+}
+
+long long
+f2 (int x, int y, long long z)
+{
+ return z + (long long) y * x;
+}
+
+long long
+f3 (int x, int y, long long z)
+{
+ long long t = (long long) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/madd-4.c b/gcc/testsuite/gcc.target/mips/madd-4.c
new file mode 100644
index 00000000000..28b5534b6f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-4.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -mips32r2 -mdspr2 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmadd\t\\\$ac" 3 } } */
+
+long long
+f1 (int x, int y, long long z)
+{
+ return (long long) x * y + z;
+}
+
+long long
+f2 (int x, int y, long long z)
+{
+ return z + (long long) y * x;
+}
+
+long long
+f3 (int x, int y, long long z)
+{
+ long long t = (long long) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/maddu-1.c b/gcc/testsuite/gcc.target/mips/maddu-1.c
new file mode 100644
index 00000000000..961e49bcb3c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/maddu-1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=vr4130 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmaccu\t\\\$1," 3 } } */
+
+typedef unsigned int ui;
+typedef unsigned long long ull;
+
+ull
+f1 (ui x, ui y, ull z)
+{
+ return (ull) x * y + z;
+}
+
+ull
+f2 (ui x, ui y, ull z)
+{
+ return z + (ull) y * x;
+}
+
+ull
+f3 (ui x, ui y, ull z)
+{
+ ull t = (ull) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/maddu-2.c b/gcc/testsuite/gcc.target/mips/maddu-2.c
new file mode 100644
index 00000000000..2add97410ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/maddu-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=vr5500 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmaddu\t" 3 } } */
+
+typedef unsigned int ui;
+typedef unsigned long long ull;
+
+ull
+f1 (ui x, ui y, ull z)
+{
+ return (ull) x * y + z;
+}
+
+ull
+f2 (ui x, ui y, ull z)
+{
+ return z + (ull) y * x;
+}
+
+ull
+f3 (ui x, ui y, ull z)
+{
+ ull t = (ull) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/maddu-3.c b/gcc/testsuite/gcc.target/mips/maddu-3.c
new file mode 100644
index 00000000000..d89c450bb68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/maddu-3.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -mips32 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmaddu\t" 3 } } */
+
+typedef unsigned int ui;
+typedef unsigned long long ull;
+
+ull
+f1 (ui x, ui y, ull z)
+{
+ return (ull) x * y + z;
+}
+
+ull
+f2 (ui x, ui y, ull z)
+{
+ return z + (ull) y * x;
+}
+
+ull
+f3 (ui x, ui y, ull z)
+{
+ ull t = (ull) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/maddu-4.c b/gcc/testsuite/gcc.target/mips/maddu-4.c
new file mode 100644
index 00000000000..f208713ef8a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/maddu-4.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -mips32r2 -mdspr2 -mgp32" } */
+/* { dg-final { scan-assembler-times "\tmaddu\t\\\$ac" 3 } } */
+
+typedef unsigned int ui;
+typedef unsigned long long ull;
+
+ull
+f1 (ui x, ui y, ull z)
+{
+ return (ull) x * y + z;
+}
+
+ull
+f2 (ui x, ui y, ull z)
+{
+ return z + (ull) y * x;
+}
+
+ull
+f3 (ui x, ui y, ull z)
+{
+ ull t = (ull) x * y;
+ int temp = 5;
+ if (temp == 5)
+ z += t;
+ return z;
+}
OpenPOWER on IntegriCloud