llvm / llvm/llvm-project

[PowerPC] unsigned `_BitInt(33)` return value is not zero-extended at -O0

Open
#222,502 1 comment 0 reactions 0 assignees View on GitHub
backend:PowerPC generated by fuzzer
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

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

Compiling the following C code for `powerpc64le` with `clang -O0` and running it prints the wrong result.

```c
#include
typedef unsigned _BitInt(33) u33;
static u33 f(void) { return (u33)0x1FFFFFFFFULL; }
int main(void) { printf("%llu\n", (unsigned long long)f()); }
```

clang command:

```sh
clang --target=powerpc64le-linux-gnu -O0 repro.c && qemu-ppc64le ./a.out
```

Output (wrong):

```text
18446744073709551615
```

Expected (what x86-64 prints, and what the same binary prints at -O1 and higher on powerpc64le):

```text
8589934591
```

Looking at the generated assembly, I noticed the func `f` materializes -1 instead of `0x1FFFFFFFF`

```asm
f:
li 3, -1
blr
```

Notes:

- Only -O0 is affected; -O1 and higher print the correct one.
- Constants that fit in 32 bits compile correctly. Any constant that needs bit 32 set is miscompiled.

clang version:

```text
clang version 24.0.0git (https://github.com/llvm/llvm-project 05fa66e6624e6b14346e559cd7b692aaf48f3ca7)
```

This reproduces with current LLVM trunk.

Contributor guide

Open the contributing guide

Research direction

Start with the C reproducer in the issue, compiling it with clang --target=powerpc64le-linux-gnu -O0 and comparing the generated assembly for f with -O1 and higher. Done means the -O0 powerpc64le result is 8589934591 and f no longer materializes -1 for the 33-bit constant.

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
Clearly specified
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.