================
@@ -6234,6 +6234,42 @@ unsigned
TargetLowering::AsmOperandInfo::getMatchedOperand() const {
return atoi(ConstraintCode.c_str());
}
+/// Return true if \p OpInfo is an "rm" operand that should prefer a register,
+/// leaving the register allocator to fold it to a stack slot if it runs out of
+/// registers (see AsmOperandInfo::MayFoldRegister).
+static bool
+shouldPreferFoldableRegister(const TargetLowering &TLI,
+ const TargetRegisterInfo *TRI,
+ const TargetLowering::AsmOperandInfo &OpInfo) {
+ // Codes stays empty for a constraint with alternatives ("r|m") until one is
+ // selected, so this only ever matches a plain "rm".
+ if (OpInfo.Codes.size() != 2 || !is_contained(OpInfo.Codes, "r") ||
+ !is_contained(OpInfo.Codes, "m"))
----------------
isanbard wrote:
Good catch, thanks. The exact `{r, m}` check left `"g"` (`"imr"`) out, so it
still went through memory.
I've updated it so an operand qualifies if its codes include `r` and `m` and
every other code is an immediate (`C_Immediate`/`C_Other`). For such an
operand, `getConstraintPreferences()` returns the immediate codes first, in the
same order as before, then `r`, then `m`. So:
- A constant `g` operand still becomes an immediate (`imm, 42`).
- A non-constant `g` operand gets a foldable register, which the allocator
folds to a stack slot under register pressure.
- Any other code, e.g. another register class like `"qmr"`, keeps the old
choice of memory.
The existing checks (direct operand, fits in one `r` register, above -O0,
target opt-in) are unchanged.
New tests:
- `asm-constraints-rm-isel.ll`: `g` input, constant, `"mri"` ordering, i128,
indirect, `=g` output, tied `g`, and `"qmr"`.
- `asm-constraints-rm-pressure.ll`: `@test_g_pressure`, under both greedy and
fast RA.
https://github.com/llvm/llvm-project/pull/229632
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits