[llvm] [NewPM] Adds a port for AArch64O0PreLegalizerCombiner (PR #189776)
Anshul Nigham via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 08:28:53 PDT 2026
https://github.com/nigham updated https://github.com/llvm/llvm-project/pull/189776
>From 841de7a02b8a0b2438cf5abf2005ba453c0b9c23 Mon Sep 17 00:00:00 2001
From: Anshul Nigham <nigham at google.com>
Date: Tue, 31 Mar 2026 17:35:06 -0700
Subject: [PATCH 1/3] [NewPM] Adds a port for AArch64O0PreLegalizerCombiner
---
llvm/lib/Target/AArch64/AArch64.h | 18 +++-
.../Target/AArch64/AArch64PassRegistry.def | 2 +
.../Target/AArch64/AArch64TargetMachine.cpp | 2 +-
.../GISel/AArch64O0PreLegalizerCombiner.cpp | 102 ++++++++++++++----
.../GlobalISel/salvage-debug-info-dead.mir | 1 +
5 files changed, 102 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h
index a4910df6957c9..70cafb77f5a10 100644
--- a/llvm/lib/Target/AArch64/AArch64.h
+++ b/llvm/lib/Target/AArch64/AArch64.h
@@ -21,6 +21,9 @@
#include "llvm/PassRegistry.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Target/TargetMachine.h"
+#include <memory>
+
+struct AArch64O0PreLegalizerCombinerImplRuleConfig;
namespace llvm {
@@ -71,6 +74,19 @@ InstructionSelector *
createAArch64InstructionSelector(const AArch64TargetMachine &,
const AArch64Subtarget &,
const AArch64RegisterBankInfo &);
+class AArch64O0PreLegalizerCombinerPass
+ : public PassInfoMixin<AArch64O0PreLegalizerCombinerPass> {
+ std::unique_ptr<AArch64O0PreLegalizerCombinerImplRuleConfig> RuleConfig;
+
+public:
+ AArch64O0PreLegalizerCombinerPass();
+ AArch64O0PreLegalizerCombinerPass(AArch64O0PreLegalizerCombinerPass &&);
+ ~AArch64O0PreLegalizerCombinerPass();
+
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
FunctionPass *createAArch64O0PreLegalizerCombiner();
FunctionPass *createAArch64PreLegalizerCombiner();
FunctionPass *createAArch64PostLegalizerCombiner(bool IsOptNone);
@@ -98,7 +114,7 @@ void initializeAArch64ExpandPseudoLegacyPass(PassRegistry &);
void initializeAArch64LoadStoreOptLegacyPass(PassRegistry &);
void initializeAArch64LowerHomogeneousPrologEpilogPass(PassRegistry &);
void initializeAArch64MIPeepholeOptLegacyPass(PassRegistry &);
-void initializeAArch64O0PreLegalizerCombinerPass(PassRegistry &);
+void initializeAArch64O0PreLegalizerCombinerLegacyPass(PassRegistry &);
void initializeAArch64PostCoalescerPass(PassRegistry &);
void initializeAArch64PostLegalizerCombinerPass(PassRegistry &);
void initializeAArch64PostLegalizerLoweringPass(PassRegistry &);
diff --git a/llvm/lib/Target/AArch64/AArch64PassRegistry.def b/llvm/lib/Target/AArch64/AArch64PassRegistry.def
index 9567d76ccf64c..9e105add3f317 100644
--- a/llvm/lib/Target/AArch64/AArch64PassRegistry.def
+++ b/llvm/lib/Target/AArch64/AArch64PassRegistry.def
@@ -37,4 +37,6 @@ MACHINE_FUNCTION_PASS("aarch64-ldst-opt", AArch64LoadStoreOptPass())
MACHINE_FUNCTION_PASS("aarch64-mi-peephole-opt", AArch64MIPeepholeOptPass())
MACHINE_FUNCTION_PASS("aarch64-ptrauth", AArch64PointerAuthPass())
MACHINE_FUNCTION_PASS("aarch64-simd-scalar", AArch64AdvSIMDScalarPass())
+MACHINE_FUNCTION_PASS("aarch64-O0-prelegalizer-combiner",
+ AArch64O0PreLegalizerCombinerPass())
#undef MACHINE_FUNCTION_PASS
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index b8c2c96301b69..e375544ddc459 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -257,7 +257,7 @@ LLVMInitializeAArch64Target() {
initializeAArch64LoadStoreOptLegacyPass(PR);
initializeAArch64MIPeepholeOptLegacyPass(PR);
initializeAArch64SIMDInstrOptPass(PR);
- initializeAArch64O0PreLegalizerCombinerPass(PR);
+ initializeAArch64O0PreLegalizerCombinerLegacyPass(PR);
initializeAArch64PreLegalizerCombinerPass(PR);
initializeAArch64PointerAuthLegacyPass(PR);
initializeAArch64PostCoalescerPass(PR);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
index 8bb3e64504b20..b8d7656d5403a 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "AArch64.h"
#include "AArch64GlobalISelUtils.h"
#include "AArch64TargetMachine.h"
#include "llvm/CodeGen/GlobalISel/Combiner.h"
@@ -20,11 +21,15 @@
#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/LibcallLoweringInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Instructions.h"
+#include <memory>
#define GET_GICOMBINER_DEPS
#include "AArch64GenO0PreLegalizeGICombiner.inc"
@@ -34,11 +39,13 @@
using namespace llvm;
using namespace MIPatternMatch;
-namespace {
+
#define GET_GICOMBINER_TYPES
#include "AArch64GenO0PreLegalizeGICombiner.inc"
#undef GET_GICOMBINER_TYPES
+namespace {
+
class AArch64O0PreLegalizerCombinerImpl : public Combiner {
protected:
const CombinerHelper Helper;
@@ -111,14 +118,34 @@ bool AArch64O0PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
return false;
}
+bool runCombiner(
+ MachineFunction &MF, GISelValueTracking *VT,
+ const LibcallLoweringInfo &Libcalls,
+ const AArch64O0PreLegalizerCombinerImplRuleConfig &RuleConfig) {
+ const Function &F = MF.getFunction();
+ const AArch64Subtarget &ST = MF.getSubtarget<AArch64Subtarget>();
+
+ CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
+ /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
+ F.hasOptSize(), F.hasMinSize());
+ // Disable fixed-point iteration in the Combiner. This improves compile-time
+ // at the cost of possibly missing optimizations. See PR#94291 for details.
+ CInfo.MaxIterations = 1;
+
+ AArch64O0PreLegalizerCombinerImpl Impl(MF, CInfo, *VT,
+ /*CSEInfo*/ nullptr, RuleConfig, ST,
+ Libcalls);
+ return Impl.combineMachineInstrs();
+}
+
// Pass boilerplate
// ================
-class AArch64O0PreLegalizerCombiner : public MachineFunctionPass {
+class AArch64O0PreLegalizerCombinerLegacy : public MachineFunctionPass {
public:
static char ID;
- AArch64O0PreLegalizerCombiner();
+ AArch64O0PreLegalizerCombinerLegacy();
StringRef getPassName() const override {
return "AArch64O0PreLegalizerCombiner";
@@ -133,7 +160,8 @@ class AArch64O0PreLegalizerCombiner : public MachineFunctionPass {
};
} // end anonymous namespace
-void AArch64O0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+void AArch64O0PreLegalizerCombinerLegacy::getAnalysisUsage(
+ AnalysisUsage &AU) const {
AU.setPreservesCFG();
getSelectionDAGFallbackAnalysisUsage(AU);
AU.addRequired<GISelValueTrackingAnalysisLegacy>();
@@ -142,13 +170,14 @@ void AArch64O0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
-AArch64O0PreLegalizerCombiner::AArch64O0PreLegalizerCombiner()
+AArch64O0PreLegalizerCombinerLegacy::AArch64O0PreLegalizerCombinerLegacy()
: MachineFunctionPass(ID) {
if (!RuleConfig.parseCommandLineOption())
report_fatal_error("Invalid rule identifier");
}
-bool AArch64O0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+bool AArch64O0PreLegalizerCombinerLegacy::runOnMachineFunction(
+ MachineFunction &MF) {
if (MF.getProperties().hasFailedISel())
return false;
@@ -161,32 +190,63 @@ bool AArch64O0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
*F.getParent(), ST);
- CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
- /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
- F.hasOptSize(), F.hasMinSize());
- // Disable fixed-point iteration in the Combiner. This improves compile-time
- // at the cost of possibly missing optimizations. See PR#94291 for details.
- CInfo.MaxIterations = 1;
-
- AArch64O0PreLegalizerCombinerImpl Impl(MF, CInfo, *VT,
- /*CSEInfo*/ nullptr, RuleConfig, ST,
- Libcalls);
- return Impl.combineMachineInstrs();
+ return runCombiner(MF, VT, Libcalls, RuleConfig);
}
-char AArch64O0PreLegalizerCombiner::ID = 0;
-INITIALIZE_PASS_BEGIN(AArch64O0PreLegalizerCombiner, DEBUG_TYPE,
+char AArch64O0PreLegalizerCombinerLegacy::ID = 0;
+INITIALIZE_PASS_BEGIN(AArch64O0PreLegalizerCombinerLegacy, DEBUG_TYPE,
"Combine AArch64 machine instrs before legalization",
false, false)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
-INITIALIZE_PASS_END(AArch64O0PreLegalizerCombiner, DEBUG_TYPE,
+INITIALIZE_PASS_END(AArch64O0PreLegalizerCombinerLegacy, DEBUG_TYPE,
"Combine AArch64 machine instrs before legalization", false,
false)
+AArch64O0PreLegalizerCombinerPass::AArch64O0PreLegalizerCombinerPass()
+ : RuleConfig(
+ std::make_unique<AArch64O0PreLegalizerCombinerImplRuleConfig>()) {
+ if (!RuleConfig->parseCommandLineOption())
+ report_fatal_error("Invalid rule identifier");
+}
+
+AArch64O0PreLegalizerCombinerPass::AArch64O0PreLegalizerCombinerPass(
+ AArch64O0PreLegalizerCombinerPass &&) = default;
+
+AArch64O0PreLegalizerCombinerPass::~AArch64O0PreLegalizerCombinerPass() =
+ default;
+
+PreservedAnalyses
+AArch64O0PreLegalizerCombinerPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ if (MF.getProperties().hasFailedISel())
+ return PreservedAnalyses::all();
+
+ GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
+
+ const AArch64Subtarget &ST = MF.getSubtarget<AArch64Subtarget>();
+ auto &MAMProxy =
+ MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF);
+ const LibcallLoweringModuleAnalysisResult *LibcallResult =
+ MAMProxy.getCachedResult<LibcallLoweringModuleAnalysis>(
+ *MF.getFunction().getParent());
+ if (!LibcallResult)
+ report_fatal_error("LibcallLoweringModuleAnalysis result not available");
+
+ const LibcallLoweringInfo &Libcalls = LibcallResult->getLibcallLowering(ST);
+
+ if (!runCombiner(MF, &VT, Libcalls, *RuleConfig))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+ PA.preserveSet<CFGAnalyses>();
+ PA.preserve<GISelValueTrackingAnalysis>();
+ return PA;
+}
+
namespace llvm {
FunctionPass *createAArch64O0PreLegalizerCombiner() {
- return new AArch64O0PreLegalizerCombiner();
+ return new AArch64O0PreLegalizerCombinerLegacy();
}
} // end namespace llvm
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/salvage-debug-info-dead.mir b/llvm/test/CodeGen/AArch64/GlobalISel/salvage-debug-info-dead.mir
index fb8a5c1e0fd3a..40e1e1e227b26 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/salvage-debug-info-dead.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/salvage-debug-info-dead.mir
@@ -1,4 +1,5 @@
# RUN: llc -global-isel=1 -O0 -run-pass=aarch64-O0-prelegalizer-combiner %s -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK
+# RUN: llc -global-isel=1 -O0 -passes='require<libcall-lowering-info>,function(machine-function(aarch64-O0-prelegalizer-combiner))' %s -o - | FileCheck %s --check-prefix=CHECK
--- |
; ModuleID = 'salvage-debug-info-dead.mir'
>From 4be43a61ff654248187ecc4f8d5a93ad7c0f1ca8 Mon Sep 17 00:00:00 2001
From: Anshul Nigham <nigham at gmail.com>
Date: Wed, 1 Apr 2026 08:28:12 -0700
Subject: [PATCH 2/3] Fix argname comments
Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
.../Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
index b8d7656d5403a..afa48d91cf475 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
@@ -125,8 +125,8 @@ bool runCombiner(
const Function &F = MF.getFunction();
const AArch64Subtarget &ST = MF.getSubtarget<AArch64Subtarget>();
- CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
- /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
+ CombinerInfo CInfo(/*AllowIllegalOps=*/ true, /*ShouldLegalizeIllegal=*/ false,
+ /*LegalizerInfo=*/ nullptr, /*EnableOpt=*/ false,
F.hasOptSize(), F.hasMinSize());
// Disable fixed-point iteration in the Combiner. This improves compile-time
// at the cost of possibly missing optimizations. See PR#94291 for details.
>From 16929dab5b422623a8d9e61cda8f23f6d95aa069 Mon Sep 17 00:00:00 2001
From: Anshul Nigham <nigham at gmail.com>
Date: Wed, 1 Apr 2026 08:28:43 -0700
Subject: [PATCH 3/3] s/report_fatal_error/reportFatalUsageError
Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
index afa48d91cf475..ef768995ea873 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp
@@ -232,7 +232,7 @@ AArch64O0PreLegalizerCombinerPass::run(MachineFunction &MF,
MAMProxy.getCachedResult<LibcallLoweringModuleAnalysis>(
*MF.getFunction().getParent());
if (!LibcallResult)
- report_fatal_error("LibcallLoweringModuleAnalysis result not available");
+ reportFatalUsageError("LibcallLoweringModuleAnalysis result not available");
const LibcallLoweringInfo &Libcalls = LibcallResult->getLibcallLowering(ST);
More information about the llvm-commits
mailing list