================
@@ -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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits