https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111151
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |pinskia at gcc dot gnu.org,
| |rguenth at gcc dot gnu.org
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
instrumenting extract_muldiv shows
...
Applying pattern match.pd:5113, generic-match-4.cc:2339
Applying fold-const.c:6892
Applying fold-const.c:7101
Applying fold-const.c:6892
Applying fold-const.c:6985
Applying pattern match.pd:4392, generic-match-8.cc:3091
and commenting
case MIN_EXPR: case MAX_EXPR:
/* If widening the type changes the signedness, then we can't perform
this optimization as that changes the result. */
if (TYPE_UNSIGNED (ctype) != TYPE_UNSIGNED (type))
break;
/* MIN (a, b) / 5 -> MIN (a / 5, b / 5) */
sub_strict_overflow_p = false;
if ((t1 = extract_muldiv (op0, c, code, wide_type,
&sub_strict_overflow_p)) != 0
&& (t2 = extract_muldiv (op1, c, code, wide_type,
&sub_strict_overflow_p)) != 0)
{
if (tree_int_cst_sgn (c) < 0)
tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);
if (sub_strict_overflow_p)
*strict_overflow_p = true;
return DUMP_FOLD (fold_build2 (tcode, ctype, fold_convert (ctype,
t1),
fold_convert (ctype, t2)));
}
break;
fixes the testcase. We turn
MAX ((long long unsigned int) t + 4503599, 32739) * 18446744073709551606
to
MIN ((long long unsigned int) t * 18446744073709551606 +
18446744073664515626,
18446744073709224226)
I think when overflow wraps we cannot do this transform at all, independent
on the "sign" of 'c'.
Maybe
@@ -6970,8 +6972,11 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code,
tree wide_type,
/* MIN (a, b) / 5 -> MIN (a / 5, b / 5) */
sub_strict_overflow_p = false;
- if ((t1 = extract_muldiv (op0, c, code, wide_type,
- &sub_strict_overflow_p)) != 0
+ if ((wide_type
+ ? TYPE_OVERFLOW_UNDEFINED (wide_type)
+ : TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
+ && (t1 = extract_muldiv (op0, c, code, wide_type,
+ &sub_strict_overflow_p)) != 0
&& (t2 = extract_muldiv (op1, c, code, wide_type,
&sub_strict_overflow_p)) != 0)
{