[clang] [llvm] [CodeGen] Fix inline asm clobber-list registers incorrectly marked Ea… (PR #206222)
Jessica Clarke via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 27 19:32:14 PDT 2026
jrtc27 wrote:
> …rlyClobber
>
> Clobber-list registers specified via `~{reg}` in inline asm constraints are modified _during_ the asm body, not before inputs are read. As such they must NOT carry the EarlyClobber flag — inputs are permitted to use them, matching GCC's behaviour.
>
> Before this fix, `InlineAsm::Kind::Clobber` fell through into the `InlineAsm::Kind::RegDefEarlyClobber` case in `InstrEmitter::EmitSpecialNode`, causing every clobbered register to receive `RegState::EarlyClobber` in the generated INLINEASM MachineInstr. This prevented the register allocator from ever assigning a clobbered register to any input operand.
>
> With a heavy clobber list (e.g. rax, rbx, rcx, rdx, r8-r11, r13-r15 — 11 registers), `-fno-omit-frame-pointer` (rbp reserved), and a gcov counter increment between two inlined asm calls (adding register pressure), the allocator ran out of registers and emitted: "inline assembly requires more registers than available"
>
> The bug was first observed in the Linux kernel's Curve25519 field arithmetic: `fsqr()`/`fsqr2()` in `arch/x86/crypto/curve25519-x86_64.c` use this exact pattern — 11-register clobber lists with `+&r` early-clobber outputs — and fail to compile with clang under CONFIG_GCOV_KERNEL + frame pointer builds. The bug is reproducible with clang 17 through 22 but not with clang 10 or GCC.
>
> Fix: give `Kind::Clobber` its own case that emits `RegState::Define` only, without `RegState::EarlyClobber`.
Given the style of this commit message is of a certain nature, was an LLM used in the creation of this PR? Please see https://llvm.org/docs/AIToolPolicy.html if so.
https://github.com/llvm/llvm-project/pull/206222
More information about the llvm-commits
mailing list