https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111151
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Richard Biener from comment #3) > 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) > { but even when overflow is undefined we don't know whether we introduce additional overflow then. Consider MAX (INT_MIN, 0) * -1 where we compute 0 * -1 (fine) but after the transform we'd do MIN (INT_MIN * -1, 0) which isn't valid. And when overflow wraps consider MAX (UINT_MAX, 1) * 2 which will compute UINT_MAX * 2 == 0 while MAX (UINT_MAX * 2, 1 * 2) will compute 2. Unless I'm missing something. What we'd need to know is whether the inner operations are known to not overflow/wrap (or whether they change sign consistently). But without range info we can't know this unless op0 and op1 are constants. So - scrap that whole sub-rule?