[llvm] [AArch64][GlobalISel] Fast-path simple common calls (NFC) (PR #217615)
Cullen Rhodes via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 06:20:39 PDT 2026
https://github.com/c-rhodes created https://github.com/llvm/llvm-project/pull/217615
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
>From 10b3020aca621c4d21158180efe6d798b3edd22a Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Wed, 19 Aug 2026 08:34:22 +0000
Subject: [PATCH] [AArch64][GlobalISel] Fast-path simple common calls (NFC)
Instrumentation of aarch64-O0-g CTMark shows the most common argument and
return types are pointer, i32, and i64, with Pointer the only common ArgFlagsTy
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.32%.
https://llvm-compile-time-tracker.com/compare.php?from=b025f5b75941fcf2e719535473c51b5e0617c4f9&to=a3f10f89b510f74a7cda1e621d44e81d9ac0a5ce&stat=instructions%3Au
Assisted-by: codex
---
.../AArch64/GISel/AArch64CallLowering.cpp | 64 ++++++++++++++++++-
1 file changed, 62 insertions(+), 2 deletions(-)
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)
More information about the llvm-commits
mailing list