https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96930

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The optimization is there, but just has different conditions:
            /* Although it would be tempting to shorten always here, that
               loses on some targets, since the modulo instruction is
               undefined if the quotient can't be represented in the
               computation mode.  We shorten only if unsigned or if
               dividing by something we know != -1.  */
            shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0))
                       || (TREE_CODE (op1) == INTEGER_CST
                           && !integer_all_onesp (op1)));
in C, and
              /* When dividing two signed integers, we have to promote to int.
                 unless we divide by a constant != -1.  Note that default
                 conversion will have been performed on the operands at this
                 point, so we have to dig out the original type to find out if
                 it was unsigned.  */
              tree stripped_op1 = tree_strip_any_location_wrapper (op1);
              shorten = ((TREE_CODE (op0) == NOP_EXPR
                          && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
                         || (TREE_CODE (stripped_op1) == INTEGER_CST
                             && ! integer_all_onesp (stripped_op1)));
So, in C++ we only try to shorten divisions (and modulo) if the first operand
has been extended, rather than the second one.
Anyway, if we optimize this in the middle-end, it won't be needed to change the
FE.

Reply via email to