https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96930
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I guess it could be either optimized using a match.pd pattern like we have for: /* Convert (outertype)((innertype0)a+(innertype1)b) into ((newtype)a+(newtype)b) where newtype is the widest mode from all of these. */ (for op (plus minus mult rdiv) (simplify (convert (op:s@0 (convert1?@3 @1) (convert2?@4 @2))) but for the *_div and trunc_mod/floor_mod the C/C++ FEs optimize using shorten_binary_op without the outer convert, but instead requiring that at least one of the operands is actually converted from narrower type and that the other one fits into the range of that narrower type and for signed div/mod the second operand is known not to be -1, or do it instead in: simplify_using_ranges::simplify_div_or_mod_using_ranges with the same rules. Any preferences?