new file mode 100644
@@ -0,0 +1,22 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div dominates mod. */
+
+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(int, int, 1)
+FOO(int, unsigned, 2)
+FOO(unsigned, unsigned, 5)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,26 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div dominates mod. */
+
+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(int, long long, 3)
+FOO(int, unsigned long long, 4)
+FOO(unsigned, long long, 6)
+FOO(unsigned, unsigned long long, 7)
+FOO(long long, long long, 8)
+FOO(long long, unsigned long long, 9)
+FOO(unsigned long long, unsigned long long, 10)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,22 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod dominates div. */
+
+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(int, int, 1)
+FOO(int, unsigned, 2)
+FOO(unsigned, unsigned, 5)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,26 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod dominates div. */
+
+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(int, long long, 3)
+FOO(int, unsigned long long, 4)
+FOO(unsigned, long long, 6)
+FOO(unsigned, unsigned long long, 7)
+FOO(long long, long long, 8)
+FOO(long long, unsigned long long, 9)
+FOO(unsigned long long, unsigned long long, 10)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,20 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div comes before mod in same bb. */
+
+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(int, int, 1)
+FOO(int, unsigned, 2)
+FOO(unsigned, unsigned, 5)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* div comes before mod in same bb. */
+
+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(int, long long, 3)
+FOO(int, unsigned long long, 4)
+FOO(unsigned, long long, 6)
+FOO(unsigned, unsigned long long, 7)
+FOO(long long, long long, 8)
+FOO(long long, unsigned long long, 9)
+FOO(unsigned long long, unsigned long long, 10)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 7 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,20 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod comes before div in same bb. */
+
+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(int, int, 1)
+FOO(int, unsigned, 2)
+FOO(unsigned, unsigned, 5)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+/* mod comes before div in same bb. */
+
+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(int, long long, 3)
+FOO(int, unsigned long long, 4)
+FOO(unsigned, long long, 6)
+FOO(unsigned, unsigned long long, 7)
+FOO(long long, long long, 8)
+FOO(long long, unsigned long long, 9)
+FOO(unsigned long long, unsigned long long, 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,24 @@
+/* { dg-require-effective-target divmod_simode } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+
+
+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(int, int, 1)
+FOO(int, unsigned, 2)
+FOO(unsigned, unsigned, 5)
+
+/* { dg-final { scan-tree-dump-times "DIVMOD" 3 "widening_mul" } } */
new file mode 100644
@@ -0,0 +1,27 @@
+/* { dg-require-effective-target divmod } */
+/* { dg-options "-O2 -fdump-tree-widening_mul-details" } */
+
+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(int, long long, 3)
+FOO(int, unsigned long long, 4)
+FOO(unsigned, long long, 6)
+FOO(unsigned, unsigned long long, 7)
+FOO(long long, long long, 8)
+FOO(long long, unsigned long long, 9)
+FOO(unsigned long long, unsigned long long, 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" } } */