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

            Bug ID: 127556
           Summary: [loongarch64] wrong code at -Os for right-shift with
                    count that should be zero
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: shimizu2486 at gmail dot com
  Target Milestone: ---
            Target: loongarch64

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

A 128-bit right shift by a count that is zero returns zero at -Os.

$ cat t1.c
#include <stdio.h>
static volatile int A = 1;
static volatile int E = 0;
int main(void) {
  __int128 a = A;
  __int128 b = (__int128)(E != 0) + 4294967296;
  unsigned s = (unsigned)((unsigned __int128)b % 128);
  printf("%llu\n", (unsigned long long)(a >> s));
}

E is zero, so b is 2^32 and s is 2^32 % 128 == 0. a is 1, so a >> s must be 1.
$ loongarch64-unknown-linux-gnu-gcc -O2 -static t1.c -o t1 && qemu-loongarch64
./t1
1                                   (correct)
$ loongarch64-unknown-linux-gnu-gcc -Os -static t1.c -o t1 && qemu-loongarch64
./t1
0                                   (wrong)

x86-64 is correct at every level, and this looks loongarch64-only. Also looks
like long-standing:
  12.2.0            wrong
  13.4.0            wrong
  14.3.0            wrong
  15.2.0            wrong
  16.1.0            wrong
  trunk (a0b77a14)  wrong
-O0, -O1, -O2 and -O3 are correct on this file; only -Os is wrong.

Reply via email to