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

            Bug ID: 127367
           Summary: [17 Regression] RISC-V: wrong code for unsigned
                    _BitInt(96) %
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: shimizu2486 at gmail dot com
  Target Milestone: ---
            Target: riscv64-unknown-linux-gnu

Live Reproducer: https://godbolt.org/z/n9dKerYYE

An unsigned _BitInt(96) modulo gives the wrong value from -O2 up.

$ cat t1.c
#include <stdio.h>

_BitInt(5) g;
_BitInt(65) prod;

int main(void) {
  _BitInt(6) t = ~g;
  _BitInt(96) m = t % (unsigned _BitInt(96))362;
  _BitInt(5) r = __builtin_mul_overflow(t, m, &prod) ?: prod;
  printf("m=%lld r=%d prod=%lld\n", (long long)m, (int)r, (long long)prod);
}

g is zero, so t is -1, (unsigned _BitInt(96))t is 2^96-1, and m must be
(2^96-1) % 362 == 297.

$ riscv64-unknown-linux-gnu-gcc -O0 -static t1.c -o t1 && qemu-riscv64 ./t1
m=297 r=-9 prod=-297                (correct)
$ riscv64-unknown-linux-gnu-gcc -O2 -static t1.c -o t1 && qemu-riscv64 ./t1
m=125 r=3 prod=-125                 (wrong)

125 is (2^128-1) % 362, so I assume the 96-bit value is compiled into a 128-bit
one.

  16.1.0                correct
  trunk (83c53762)      wrong

-O0 and -O1 are correct; -O2, -O3 and -Os are wrong.

Reply via email to