[PowerPC] wrong code comparing a truncated _BitInt(33) value
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Live Reproducer: [https://godbolt.org/z/GGz67hhEo]()
Compiling the following C code for `powerpc64le` with `clang -O1` and running it prints the wrong result.
```c
#include
typedef unsigned _BitInt(33) u33;
u33 i10;
volatile _BitInt(33) vx = 0x100000900;
int main(void) {
_BitInt(33) x2 = vx;
unsigned n9 = (unsigned)x2 & 5;
for (; i10 < n9; i10++)
x2 = 0;
printf("%llu\n", (unsigned long long)x2 + !((int)x2 >= 2304));
}
```
clang command:
```sh
clang --target=powerpc64le-linux-gnu -O1 repro.c && qemu-ppc64le ./a.out
```
Output (wrong):
```text
18446744069414586625
```
Expected (what -O0 prints, and what x86-64 prints):
```text
18446744069414586624
```
The printed value is `(unsigned long long)x2 + n11` with`n11 = !((int)x2 >= 2304)`. x2 = 0x100000900 has bit 32 set and bit 31 clear, so `(int)x2` is 2304 and `n11` should be 0. The generated code instead computes `n11` from x2 sign-extended from bit 32:
```asm
.LBB0_3:
sldi 3, 6, 31 # x2 sign-extended from bit 32 ...
sradi 3, 3, 31
.LBB0_4:
li 4, 2304
sub 4, 3, 4
rldicl 4, 4, 1, 63 # n11 = sign of (x2_sext33 - 2304) -> 1 (wrong)
```
Notes:
* Correct at -O0
clang version:
```text
clang version 24.0.0git (https://github.com/llvm/llvm-project 05fa66e6624e6b14346e559cd7b692aaf48f3ca7)
```
Contributor guide
Research direction
Start with the repro.c example and compile it using the provided powerpc64le clang command at -O1, then compare the generated assembly and result with -O0. Trace the PowerPC code generation for the _BitInt(33) to int comparison, especially the sign extension shown in the assembly. Done means the optimized program prints 18446744069414586624, matching -O0 and x86-64.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100