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

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> ---
Seems like a bogus fold-const.c transformation has been moved into match.pd and
so now it hits even more often.  Another testcase:
__attribute__((noinline, noclone)) int
f1 (int x, int y)
{
  return x % y;
}

__attribute__((noinline, noclone)) int
f2 (int x, int y)
{
  return x % -y;
}

__attribute__((noinline, noclone)) int
f3 (int x, int y)
{
  int z = -y;
  return x % z;
}

int
main ()
{
  if (f1 (-__INT_MAX__ - 1, 1) != 0
      || f2 (-__INT_MAX__ - 1, -1) != 0
      || f3 (-__INT_MAX__ - 1, -1) != 0)
    __builtin_abort ();
  return 0;
}

The bad optimization has been introduced with
https://gcc.gnu.org/ml/gcc-patches/2004-07/msg00358.html in 2004.
For constant last operand we already do the right thing:
/* X % -C is the same as X % C.  */
(simplify
 (trunc_mod @0 INTEGER_CST@1)
  (if (TYPE_SIGN (type) == SIGNED
       && !TREE_OVERFLOW (@1)
       && wi::neg_p (@1)
       && !TYPE_OVERFLOW_TRAPS (type)
       /* Avoid this transformation if C is INT_MIN, i.e. C == -C.  */
       && !sign_bit_p (@1, @1))
   (trunc_mod @0 (negate @1))))
because we only do the transformation for negative constants.  But for variable
last operand:
/* X % -Y is the same as X % Y.  */
(simplify
 (trunc_mod @0 (convert? (negate @1)))
 (if (!TYPE_UNSIGNED (type)
      && !TYPE_OVERFLOW_TRAPS (type)
      && tree_nop_conversion_p (type, TREE_TYPE (@1)))
  (trunc_mod @0 (convert @1))))
we can turn a valid INT_MIN % -(-1) which yields 0 into invalid INT_MIN % -1
which raises division by zero.
So, if we really want to perform this X % -Y transformation to X % Y, we can do
that only if VRP info tells us that the first operand can't be the signed
minimum, or the operand of the negation can't be -1.

Reply via email to