[llvm] [AArch64][GlobalISel] Fast-path simple common calls (NFC) (PR #217615)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 06:21:25 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Cullen Rhodes (c-rhodes)

<details>
<summary>Changes</summary>

Instrumentation of aarch64-O0-g CTMark shows the most common argument and return types are pointer, i32, and i64, with Pointer the only common flag.

Fast-path these values when they map directly to w0-w7/x0-x7 or w0/x0. Fall back to the generic assignment machinery for all other cases.

Improves aarch64-O0-g CTMark geomean by -0.31%.

https://llvm-compile-time-tracker.com/compare.php?from=a49d90627bd44d2e76c20b9d4e0cafb339fb806f&to=10b3020aca621c4d21158180efe6d798b3edd22a&stat=instructions%3Au

Assisted-by: codex

---
Full diff: https://github.com/llvm/llvm-project/pull/217615.diff


1 Files Affected:

- (modified) llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp (+62-2) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
index b0a409d153fd2..12a291595de0d 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -20,6 +20,7 @@
 #include "AArch64SMEAttributes.h"
 #include "AArch64Subtarget.h"
 #include "AArch64TargetMachine.h"
+#include "Utils/AArch64BaseInfo.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/ObjCARCUtil.h"
@@ -58,6 +59,58 @@ using namespace AArch64GISelUtils;
 
 extern cl::opt<bool> EnableSVEGISel;
 
+static bool isSimpleGPRCallValue(const CallLowering::ArgInfo &Arg) {
+  if (Arg.Regs.size() != 1 || any_of(Arg.Flags, [](ISD::ArgFlagsTy Flags) {
+        auto FlagVals = Flags.getFlags();
+        return FlagVals != ISD::ArgFlagsTy::NoFlags &&
+               FlagVals != ISD::ArgFlagsTy::Pointer;
+      }))
+    return false;
+
+  Type *Ty = Arg.Ty;
+  return Ty->isPointerTy() || Ty->isIntegerTy(32) || Ty->isIntegerTy(64);
+}
+
+// Avoid the generic assignment machinery when every argument maps directly to
+// w0-w7/x0-x7. Fast path for compile-time.
+static bool tryAssignSimpleGPRCallArgs(MachineIRBuilder &MIRBuilder,
+                                       MachineInstrBuilder MIB,
+                                       ArrayRef<CallLowering::ArgInfo> Args) {
+  if (Args.size() > 8)
+    return false;
+
+  for (const CallLowering::ArgInfo &Arg : Args)
+    if (!isSimpleGPRCallValue(Arg))
+      return false;
+
+  for (unsigned I = 0, E = Args.size(); I != E; ++I) {
+    const CallLowering::ArgInfo &Arg = Args[I];
+    MCRegister XReg = AArch64::getGPRArgRegs()[I];
+    Register PhysReg = Arg.Ty->isIntegerTy(32) ? getWRegFromXReg(XReg) : XReg;
+    MIB.addUse(PhysReg, RegState::Implicit);
+    MIRBuilder.buildCopy(PhysReg, Arg.Regs[0]);
+  }
+  return true;
+}
+
+// Avoid the generic assignment machinery when the return value maps directly
+// to w0/x0. Fast path for compile-time.
+static bool tryAssignSimpleGPRCallReturn(MachineIRBuilder &MIRBuilder,
+                                         MachineInstrBuilder MIB,
+                                         ArrayRef<CallLowering::ArgInfo> Rets) {
+  if (Rets.size() != 1)
+    return false;
+
+  const CallLowering::ArgInfo &Ret = Rets[0];
+  if (!isSimpleGPRCallValue(Ret))
+    return false;
+
+  Register PhysReg = Ret.Ty->isIntegerTy(32) ? AArch64::W0 : AArch64::X0;
+  MIB.addDef(PhysReg, RegState::Implicit);
+  MIRBuilder.buildCopy(Ret.Regs[0], PhysReg);
+  return true;
+}
+
 AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
   : CallLowering(&TLI) {}
 
@@ -1444,7 +1497,10 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
                                         Subtarget, /*IsReturn*/ false);
   // Do the actual argument marshalling.
   OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, /*IsReturn*/ false);
-  if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
+  bool AssignedCallArgs = Info.CallConv == CallingConv::C &&
+                          tryAssignSimpleGPRCallArgs(MIRBuilder, MIB, OutArgs);
+  if (!AssignedCallArgs &&
+      !determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
                                      Info.CallConv, Info.IsVarArg))
     return false;
 
@@ -1513,7 +1569,11 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
     AArch64OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn, Subtarget,
                                           /*IsReturn*/ false);
     ReturnedArgCallReturnHandler ReturnedArgHandler(MIRBuilder, MRI, MIB);
-    if (!determineAndHandleAssignments(
+    bool AssignedCallReturn =
+        Info.CallConv == CallingConv::C && !UsingReturnedArg &&
+        tryAssignSimpleGPRCallReturn(MIRBuilder, MIB, InArgs);
+    if (!AssignedCallReturn &&
+        !determineAndHandleAssignments(
             UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs,
             MIRBuilder, Info.CallConv, Info.IsVarArg,
             UsingReturnedArg ? ArrayRef(OutArgs[0].Regs)

``````````

</details>


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


More information about the llvm-commits mailing list