================
@@ -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

Reply via email to