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

Reply via email to