[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