| Issue |
185359
|
| Summary |
[MC][PPC] Clang crashes when assembling PowerPC `wrteei` with register-name symbol as enable-bit immediate
|
| Labels |
clang
|
| Assignees |
|
| Reporter |
venkyqz
|
## Summary
`llvm-mc` (debug build) crashes with an assertion failure when assembling the PowerPC `wrteei` instruction using any register-class name (e.g., `f0`, `r0`, `cr0`, `t0`, `v0`) as the enable-bit operand. The release build silently emits wrong encoding.
---
## Reproduction
**Godbolt Link**
+ https://godbolt.org/z/KqKjW74Mz
**Test File (`poc.s`):**
```asm
.text
wrteei f0
```
**Commands:**
```bash
# Debug Build - Crashes with assertion
echo -e ".text\nwrteei f0" | llvm-mc - \
--arch=ppc64le --triple=powerpc64le-linux-gnu --filetype=obj -o /dev/null
# Exit 134, Assertion failed
# Release Build - Silent miscompilation
echo -e ".text\nwrteei f0" | llvm-mc - \
--arch=ppc64le --triple=powerpc64le-linux-gnu --filetype=obj -o /dev/null
# Exit 0, emits wrong encoding
```
**Debug Build Output:**
```
llvm-mc: /path/to/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp:472:
uint64_t llvm::PPCMCCodeEmitter::getMachineOpValue(...):
Assertion `MO.isImm() && "Relocation required in an instruction that we cannot encode!"' failed.
```
---
## Root Cause
The `wrteei` instruction takes a 1-bit "enable" immediate operand. In LLVM TableGen, the operand is typed as `u1imm` (an unsigned 1-bit immediate). However, `u1imm` lacks a `ParserMatchClass` that would reject non-numeric operands at parse time.
As a result, the parser accepts any symbol reference (including any register-class name) as the operand value. When the encoder calls `getMachineOpValue()`, it asserts `MO.isImm()` because it does not expect a non-immediate (_expression_/symbol) operand.
**Vulnerable Code (`PPCMCCodeEmitter.cpp:472`):**
```cpp
assert(MO.isImm() && "Relocation required in an instruction that we cannot encode!");
```
---
## Proposed Fix
Add a `ParserMatchClass` to `u1imm` operand type in `PPCInstrInfo.td` to validate that only numeric immediates (0 or 1) are accepted:
```cpp
def u1imm : Operand<i32> {
let ParserMatchClass = U1ImmOperand; // Add validation
// ...
}
```
---
## Impact
| Build Type | Behavior | Security Risk |
|------------|----------|---------------|
| Debug | Assertion failure (Exit 134) | Detectable |
| Release | Silent miscompilation (Exit 0) | **Undetectable in CI/CD** |
**Affected Instructions:**
| Instruction | Target | Debug | Release |
|-------------|--------|-------|---------|
| `wrteei f0` | ppc64le | 134 | 0 |
| `wrteei f1` | ppc64le | 134 | 0 |
| `wrteei r0` | ppc64le | 134 | 0 |
| `wrteei cr0` | ppc64le | 134 | 0 |
| `wrteei v0` | ppc64le | 134 | 0 |
| `wrteei f0` | ppc32le | 134 | 0 |
| `wrteei f0` | ppc64 | 134 | 0 |
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs