[llvm] [win/arm64] Enable tail call with inreg arguments when possible (PR #134671)

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 00:04:02 PDT 2025


================
@@ -8703,13 +8703,19 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
       return false;
 
     // On Windows, "inreg" attributes signify non-aggregate indirect returns.
-    // In this case, it is necessary to save/restore X0 in the callee. Tail
-    // call opt interferes with this. So we disable tail call opt when the
-    // caller has an argument with "inreg" attribute.
-
-    // FIXME: Check whether the callee also has an "inreg" argument.
-    if (i->hasInRegAttr())
-      return false;
+    // In this case, it is necessary to save X0/X1 in the callee and return it
+    // in X0. Tail call opt may interfere with this, so we disable tail call
+    // opt when the caller has an "inreg" attribute -- except if the callee
+    // also has that attribute on the same argument, and the same value is
+    // passed.
+    if (i->hasInRegAttr()) {
+      unsigned ArgNum = i - CallerF.arg_begin();
+      if (!CLI.CB || CLI.CB->arg_size() <= ArgNum ||
+          !CLI.CB->getParamAttr(ArgNum, Attribute::InReg).isValid() ||
----------------
efriedma-quic wrote:

Efficiently performing the memory copies required for byval in the correct order is complicated, and musttail doesn't really provide any useful invariant for that.  It's maybe slightly simpler if you can assume byval arguments don't overlap, but not a lot simpler.  If we implement the copies properly, we can completely drop the check for byval here.

For sret, musttail ensures the attributes match, but it doesn't say anything about the value.  (Which is maybe a hole in the way we specify the interaction between musttail and sret, but I'm not sure what the right fix looks like.)

https://github.com/llvm/llvm-project/pull/134671


More information about the llvm-commits mailing list