new file mode 100644
@@ -0,0 +1,25 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div dominates mod. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype q = x / y; \
+ if (cond) \
+ foo (); \
+ bigtype r = x % y; \
+ return q + r; \
+}
+
+FOO(SImode, SImode, 1)
+FOO(SImode, USImode, 2)
+FOO(USImode, USImode, 3)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div dominates mod. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+typedef int DImode __attribute__((mode(DI)));
+typedef unsigned UDImode __attribute__((mode(DI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype q = x / y; \
+ if (cond) \
+ foo (); \
+ bigtype r = x % y; \
+ return q + r; \
+}
+
+FOO(SImode, DImode, 1)
+FOO(SImode, UDImode, 2)
+FOO(USImode, DImode, 3)
+FOO(USImode, UDImode, 4)
+FOO(DImode, DImode, 5)
+FOO(DImode, UDImode, 6)
+FOO(UDImode, UDImode, 7)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,25 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod dominates div. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype r = x % y; \
+ if (cond) \
+ foo (); \
+ bigtype q = x / y; \
+ return q + r; \
+}
+
+FOO(SImode, SImode, 1)
+FOO(SImode, USImode, 2)
+FOO(USImode, USImode, 3)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod dominates div. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+typedef int DImode __attribute__((mode(DI)));
+typedef unsigned UDImode __attribute__((mode(DI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype r = x % y; \
+ if (cond) \
+ foo (); \
+ bigtype q = x / y; \
+ return q + r; \
+}
+
+FOO(SImode, DImode, 1)
+FOO(SImode, UDImode, 2)
+FOO(USImode, DImode, 3)
+FOO(USImode, UDImode, 4)
+FOO(DImode, DImode, 5)
+FOO(DImode, UDImode, 6)
+FOO(UDImode, UDImode, 7)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,23 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div comes before mod in same bb. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype q = x / y; \
+ bigtype r = x % y; \
+ return q + r; \
+}
+
+FOO(SImode, SImode, 1)
+FOO(SImode, USImode, 2)
+FOO(USImode, USImode, 3)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,30 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div comes before mod in same bb. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+typedef int DImode __attribute__((mode(DI)));
+typedef unsigned UDImode __attribute__((mode(DI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype q = x / y; \
+ bigtype r = x % y; \
+ return q + r; \
+}
+
+FOO(SImode, DImode, 1)
+FOO(SImode, UDImode, 2)
+FOO(USImode, DImode, 3)
+FOO(USImode, UDImode, 4)
+FOO(DImode, DImode, 5)
+FOO(DImode, UDImode, 6)
+FOO(UDImode, UDImode, 7)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,23 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod comes before div in same bb. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype r = x % y; \
+ bigtype q = x / y; \
+ return q + r; \
+}
+
+FOO(SImode, SImode, 1)
+FOO(SImode, USImode, 2)
+FOO(USImode, USImode, 3)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,30 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod comes before div in same bb. */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+typedef int DImode __attribute__((mode(DI)));
+typedef unsigned UDImode __attribute__((mode(DI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype r = x % y; \
+ bigtype q = x / y; \
+ return q + r; \
+}
+
+FOO(SImode, DImode, 3)
+FOO(SImode, UDImode, 4)
+FOO(USImode, DImode, 6)
+FOO(USImode, UDImode, 7)
+FOO(DImode, DImode, 8)
+FOO(DImode, UDImode, 9)
+FOO(UDImode, UDImode, 10)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,19 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div and mod are not in same bb and
+ bb's containing div and mod don't dominate each other. */
+
+int f(int x, int y)
+{
+ int q = 0;
+ int r = 0;
+ extern int cond;
+
+ if (cond)
+ q = x / y;
+
+ r = x % y;
+ return q + r;
+}
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 0 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,26 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype q = x / y; \
+ bigtype r1 = 0, r2 = 0; \
+ if (cond) \
+ r1 = x % y; \
+ else \
+ r2 = x % y; \
+ return q + r1 + r2; \
+}
+
+FOO(SImode, SImode, 1)
+FOO(SImode, USImode, 2)
+FOO(USImode, USImode, 3)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,33 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+
+typedef int SImode __attribute__((mode(SI)));
+typedef unsigned USImode __attribute__((mode(SI)));
+
+typedef int DImode __attribute__((mode(DI)));
+typedef unsigned UDImode __attribute__((mode(DI)));
+
+extern int cond;
+void foo(void);
+
+#define FOO(smalltype, bigtype, no) \
+bigtype f_##no(smalltype x, bigtype y) \
+{ \
+ bigtype q = x / y; \
+ bigtype r1 = 0, r2 = 0; \
+ if (cond) \
+ r1 = x % y; \
+ else \
+ r2 = x % y; \
+ return q + r1 + r2; \
+}
+
+FOO(SImode, DImode, 3)
+FOO(SImode, UDImode, 4)
+FOO(USImode, DImode, 6)
+FOO(USImode, UDImode, 7)
+FOO(DImode, DImode, 8)
+FOO(DImode, UDImode, 9)
+FOO(UDImode, UDImode, 10)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,21 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+
+int f(int x, int y)
+{
+ int q = 0, r1 = 0, r2 = 0;
+ extern int cond;
+
+ if (cond)
+ q = x / y;
+ else
+ {
+ r1 = x % y;
+ return q + r1;
+ }
+
+ r2 = x % y;
+ return q + r2;
+}
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 1 "widening_mul" } } */