if (TYPE_UNSIGNED (ctype) != TYPE_UNSIGNED (type))
break;
+ /* Punt for multiplication altogether.
+ MAX (1U + INT_MAX, 1U) * 2U is not equivalent to
+ MAX ((1U + INT_MAX) * 2U, 1U * 2U), the former is
+ 0U, the latter is 2U.
+ MAX (INT_MIN / 2, 0) * -2 is not equivalent to
+ MIN (INT_MIN / 2 * -2, 0 * -2), the former is
+ well defined 0, the latter invokes UB.
+ MAX (INT_MIN / 2, 5) * 5 is not equivalent to
+ MAX (INT_MIN / 2 * 5, 5 * 5), the former is
+ well defined 25, the latter invokes UB. */
+ if (code == MULT_EXPR)
+ break;
+ /* For division/modulo, punt on c being -1 for MAX, as
+ MAX (INT_MIN, 0) / -1 is not equivalent to
+ MIN (INT_MIN / -1, 0 / -1), the former is well defined
+ 0, the latter invokes UB (or for -fwrapv is INT_MIN).
+ MIN (INT_MIN, 0) / -1 already invokes UB, so the
+ transformation won't make it worse. */
+ else if (tcode == MAX_EXPR && integer_minus_onep (c))
+ break;
+
/* MIN (a, b) / 5 -> MIN (a / 5, b / 5) */
sub_strict_overflow_p = false;
if ((t1 = extract_muldiv (op0, c, code, wide_type,
--- /dev/null
+/* PR middle-end/111151 */
+
+int
+main ()
+{
+ unsigned a = (1U + __INT_MAX__) / 2U;
+ unsigned b = 1U;
+ unsigned c = (a * 2U > b * 2U ? a * 2U : b * 2U) * 2U;
+ if (c != 0U)
+ __builtin_abort ();
+ int d = (-__INT_MAX__ - 1) / 2;
+ int e = 10;
+ int f = (d * 2 > e * 5 ? d * 2 : e * 5) * 6;
+ if (f != 120)
+ __builtin_abort ();
+ int g = (-__INT_MAX__ - 1) / 2;
+ int h = 0;
+ int i = (g * 2 > h * 5 ? g * 2 : h * 5) / -1;
+ if (i != 0)
+ __builtin_abort ();
+}