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.