[clang] [llvm] [WIP][TargetLowering] Prefer 'r' over 'm' for "rm" inline asm constraints (PR #214061)
Bill Wendling via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 4 21:10:01 PDT 2026
================
@@ -207,6 +207,20 @@ class TargetCodeGenInfo {
return false;
}
+ /// Returns true if this target's backend can fold a register-preferred
+ /// inline asm operand back to memory under register pressure (mirrors
+ /// llvm::TargetLowering::supportsRegMemInlineAsmFolding() -- see that
+ /// declaration for why this defaults to false everywhere except the one
+ /// target that's actually implemented the fold). CGStmt.cpp's
+ /// direct-vs-indirect output lowering decision must agree with the
+ /// backend's own MayFoldRegister gate: if this target's backend won't
+ /// prefer 'r' for an exact "rm"/"+rm" constraint, emitting the IR as if
+ /// it will (skipping the historical indirect/alloca form) leaves nothing
+ /// to fall back to, and inline asm that has always compiled -- an
+ /// ordinary "=rm" or "+rm" output with no exotic pressure at all -- would
+ /// start failing outright.
----------------
isanbard wrote:
*From Claude:*
Nick's "only CISC" framing is a reasonable intuition but not quite the actual gate. "rm" constraints are legal on every target — RISC backends support memory constraints too (typically via a plain load/store). What's actually gating this is narrower: `TargetInstrInfo::getFrameIndexOperands()` — the addressing-mode hook that lets generic code (Greedy's InlineSpiller, and now RegAllocFast) splice a frame-index reference into an arbitrary instruction's operands without target-specific codegen. That's implemented for X86 today; it's not implemented anywhere else. That's an "unimplemented" gap, not an architectural one — AArch64 could implement it (register+offset addressing exists there too), nobody's written it.
Given that, Clang genuinely has to know the answer before it emits IR: Clang decides at IR-generation time whether to emit the optimistic direct/by-value form or the always-safe indirect/`alloca` form for `"=rm"/"+rm"`. That choice is baked into the IR's shape — it can't be deferred to the backend, because a direct output that turns out to need memory has no alloca to fall back to (that's the crash this whole capability gate exists to prevent). And Clang can't just ask a live backend TargetMachine at that point — Clang and the backend are architecturally decoupled (you can `clang -S -emit-llvm` and hand the `.ll` to a completely different `llc` invocation), which is exactly why `TargetCodeGenInfo` has always hand-mirrored backend ABI/target facts rather than querying them live (`adjustInlineAsmType`, right above this hook in the same file, is the same pattern).
Where I think Nick's concern has real teeth: two hooks that must independently agree (Clang's and LLVM's) can drift — that's not hypothetical, it's exactly what happened with the missing WinX86_64TargetCodeGenInfo override we found and fixed this week **[editor: again in this PR]**. The mitigation isn't "don't have two hooks" (the architecture forces that), it's making drift loud instead of silent — e.g. a test that enumerates every LLVM target implementing `getFrameIndexOperands()` and asserts Clang's hook agrees for matching triples. Worth proposing as a follow-up if one doesn't exist yet.
https://github.com/llvm/llvm-project/pull/214061
More information about the llvm-commits
mailing list