https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97282
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- We have the divmod discovery in tree-ssa-math-opts.c and it will handle this case if the division/modulo is by the same variable. But for constants it punts: /* Disable the transform if either is a constant, since division-by-constant may have specialized expansion. */ if (CONSTANT_CLASS_P (op1) || CONSTANT_CLASS_P (op2)) return false; So, perhaps we want to get it through if CONSTANT_CLASS_P (op2) (but not op1) and some further conditions are met, e.g. that op2 is not a power of two, and either the type's precision is > HOST_BITS_PER_WIDE_INT (then expand_divmod punts on it), as choose_multiplier etc. work on HOST_WIDE_INTs), or compute choose_multiplier for the constant divisor and if pre or post shift needs to be BITS_PER_WORD or more bits. Or optimize into DIVMOD always even for constant op2 and when trying to expand DIVMOD ifn with constant op2, see if the target can expand division by that constant using just shifts and +/- and if so, emit it as that division + subtraction, otherwise throw away the division expansion and emit a divmod.