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

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Serge noticed LLVM miscompilation and bisected to my change and then with
instrumented GCC found two possible compilation units, and I've eyeballed the
differences on one of those and spotted the bug in the .MUL_OVERFLOW arguments
in the widening_mul dump.
The original LLVM code is like:
  // Check each interesting stride.
  for (int64_t Factor : Factors) {
    // Check that the multiplication doesn't overflow.
    if (Base.BaseOffset == std::numeric_limits<int64_t>::min() && Factor == -1)
      continue;
    int64_t NewBaseOffset = (uint64_t)Base.BaseOffset * Factor;
    if (NewBaseOffset / Factor != Base.BaseOffset)
      continue;

(and another very similar a few lines below).

Note, as I said in the PR for which the change has been made, the case where
one of the arguments is signed min and the other -1 can cause UB in the
division, so one needs to either do what LLVM does or conditionalize the
divisor and != other arg on what operand is -1 (choose the other one).
GCC isn't able to figure out such comparisons are part of the overflow check...

Reply via email to