[llvm] [GISel][X86] port X86PreLegalizerCombiner to npm (PR #182638)

Gergo Stomfai via llvm-commits llvm-commits at lists.llvm.org
Fri May 1 09:37:02 PDT 2026


https://github.com/stomfaig updated https://github.com/llvm/llvm-project/pull/182638

>From 956adb4a3b823d7a551246866ce2d8ab99b0dbbc Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sat, 21 Feb 2026 00:45:17 +0000
Subject: [PATCH 1/8] port X86PreLegalizerCombiner to npm

---
 .../X86/GISel/X86PreLegalizerCombiner.cpp     | 38 +++++++++++++++++++
 llvm/lib/Target/X86/X86.h                     |  8 ++++
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |  6 +++
 llvm/lib/Target/X86/X86PassRegistry.def       |  1 +
 4 files changed, 53 insertions(+)

diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 4aa58f0876466..0c70c27fd8a12 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -171,6 +171,44 @@ INITIALIZE_PASS_END(X86PreLegalizerCombiner, DEBUG_TYPE,
                     false)
 
 namespace llvm {
+
+PreservedAnalyses
+X86PreLegalizerCombinerPass::run(MachineFunction &MF,
+                                 MachineFunctionAnalysisManager &MFAM) {
+  if (MF.getProperties().hasFailedISel())
+    return PreservedAnalyses::all();
+
+  X86PreLegalizerCombinerImplRuleConfig RuleConfig;
+  if (!RuleConfig.parseCommandLineOption())
+    report_fatal_error("Invalid rule identifier");
+
+  auto &CSEInfo = MFAM.getResult<GISelCSEAnalysis>(MF);
+
+  const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
+  const LegalizerInfo *LI = ST.getLegalizerInfo();
+
+  const Function &F = MF.getFunction();
+  bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOptLevel::None;
+  GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
+  MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+  CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
+                     /*LegalizerInfo=*/LI, EnableOpt, F.hasOptSize(),
+                     F.hasMinSize());
+
+  // This is the first Combiner, so the input IR might contain dead
+  // instructions.
+  CInfo.EnableFullDCE = true;
+  X86PreLegalizerCombinerImpl Impl(MF, CInfo, nullptr, VT, CSEInfo.get(),
+                                   RuleConfig, ST, &MDT, LI);
+  Impl.combineMachineInstrs();
+
+  PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+  PA.preserve<GISelCSEAnalysis>();
+  PA.preserve<GISelValueTrackingAnalysis>();
+  PA.preserve<MachineDominatorTreeAnalysis>();
+  return PA;
+}
+
 FunctionPass *createX86PreLegalizerCombiner() {
   return new X86PreLegalizerCombiner();
 }
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 3b31dee767fae..55a2f84630db5 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -404,6 +404,14 @@ class X86PostLegalizerCombinerPass
 };
 
 FunctionPass *createX86PostLegalizerCombinerLegacy();
+
+class X86PreLegalizerCombinerPass
+    : public PassInfoMixin<X86PreLegalizerCombinerPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
 FunctionPass *createX86PreLegalizerCombiner();
 
 class X86LoadValueInjectionLoadHardeningPass
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 18901c65f1be0..ffb2c9f52df7e 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -61,6 +61,7 @@ class X86CodeGenPassBuilder
   void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
   void addAsmPrinter(PassManagerWrapper &PMW) const;
   void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+  void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const;
 };
 
 void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
@@ -255,6 +256,11 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
   }
 }
 
+void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
+    PassManagerWrapper &PMW) const {
+  addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
+}
+
 void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
   addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def
index 779d1b8eddfd5..c4aafd8dbdb6b 100644
--- a/llvm/lib/Target/X86/X86PassRegistry.def
+++ b/llvm/lib/Target/X86/X86PassRegistry.def
@@ -59,6 +59,7 @@ MACHINE_FUNCTION_PASS("x86-lvi-ret", X86LoadValueInjectionRetHardeningPass())
 MACHINE_FUNCTION_PASS("x86-optimize-leas", X86OptimizeLEAsPass())
 MACHINE_FUNCTION_PASS("x86-postlegalizer-combiner-pass", X86PostLegalizerCombinerPass())
 MACHINE_FUNCTION_PASS("x86-pre-tile-config", X86PreTileConfigPass())
+MACHINE_FUNCTION_PASS("x86-pre-legalizer-combiner-pass", X86PreLegalizerCombinerPass())
 MACHINE_FUNCTION_PASS("x86-return-thunks", X86ReturnThunksPass())
 MACHINE_FUNCTION_PASS("x86-seses", X86SpeculativeExecutionSideEffectSuppressionPass())
 MACHINE_FUNCTION_PASS("x86-slh", X86SpeculativeLoadHardeningPass())

>From 25444bee0091cfdb1c975ed866699416593473cf Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sat, 21 Feb 2026 20:07:57 +0000
Subject: [PATCH 2/8] resolve comments

---
 .../X86/GISel/X86PreLegalizerCombiner.cpp     |  15 +-
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |  12 +-
 .../prelegalizercombiner-trivial-arith.mir    | 520 ++++++++++++++++++
 3 files changed, 533 insertions(+), 14 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir

diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 0c70c27fd8a12..22e6815a1d391 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -55,8 +55,7 @@ class X86PreLegalizerCombinerImpl : public Combiner {
       MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
       GISelCSEInfo *CSEInfo,
       const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
-      const X86Subtarget &STI, MachineDominatorTree *MDT,
-      const LegalizerInfo *LI);
+      MachineDominatorTree *MDT, const LegalizerInfo *LI);
 
   static const char *getName() { return "X86PreLegalizerCombiner"; }
 
@@ -78,10 +77,10 @@ X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
     MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
     GISelCSEInfo *CSEInfo,
     const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
-    const X86Subtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
+    MachineDominatorTree *MDT, const LegalizerInfo *LI)
     : Combiner(MF, CInfo, &VT, CSEInfo),
       Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT, LI),
-      RuleConfig(RuleConfig), STI(STI),
+      RuleConfig(RuleConfig), STI(MF.getSubtarget<X86Subtarget>()),
 #define GET_GICOMBINER_CONSTRUCTOR_INITS
 #include "X86GenPreLegalizeGICombiner.inc"
 #undef GET_GICOMBINER_CONSTRUCTOR_INITS
@@ -154,7 +153,7 @@ bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
   // This is the first Combiner, so the input IR might contain dead
   // instructions.
   CInfo.EnableFullDCE = true;
-  X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST, MDT,
+  X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT,
                                    LI);
   return Impl.combineMachineInstrs();
 }
@@ -198,14 +197,14 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
   // This is the first Combiner, so the input IR might contain dead
   // instructions.
   CInfo.EnableFullDCE = true;
-  X86PreLegalizerCombinerImpl Impl(MF, CInfo, nullptr, VT, CSEInfo.get(),
-                                   RuleConfig, ST, &MDT, LI);
+  X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
+                                   RuleConfig, &MDT, LI);
   Impl.combineMachineInstrs();
 
   PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+  PA.preserveSet<CFGAnalyses>();
   PA.preserve<GISelCSEAnalysis>();
   PA.preserve<GISelValueTrackingAnalysis>();
-  PA.preserve<MachineDominatorTreeAnalysis>();
   return PA;
 }
 
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index ffb2c9f52df7e..6e3846f7d40f9 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -46,6 +46,7 @@ class X86CodeGenPassBuilder
   void addIRPasses(PassManagerWrapper &PMW) const;
   void addPreISel(PassManagerWrapper &PMW) const;
   Error addInstSelector(PassManagerWrapper &PMW) const;
+  void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const;
   void addILPOpts(PassManagerWrapper &PMW) const;
   void addPreRegBankSelect(PassManagerWrapper &PMW) const;
   void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
@@ -61,7 +62,6 @@ class X86CodeGenPassBuilder
   void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
   void addAsmPrinter(PassManagerWrapper &PMW) const;
   void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
-  void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const;
 };
 
 void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
@@ -118,6 +118,11 @@ Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
   return Error::success();
 }
 
+void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
+    PassManagerWrapper &PMW) const {
+  addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
+}
+
 void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
   addMachineFunctionPass(EarlyIfConverterPass(), PMW);
   if (X86EnableMachineCombinerPass) {
@@ -256,11 +261,6 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
   }
 }
 
-void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
-}
-
 void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
   addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
new file mode 100644
index 0000000000000..c85421a434208
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
@@ -0,0 +1,520 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+
+---
+name:            right_ident_sub
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $eax
+    ; Fold (x - 0) -> x
+    ; CHECK-LABEL: name: right_ident_sub
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %x(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_SUB %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+
+...
+---
+name:            right_ident_add
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x + 0) -> x
+    ; CHECK-LABEL: name: right_ident_add
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %x(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_ADD %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            mul_0
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x * 0) -> 0
+    ; CHECK-LABEL: name: mul_0
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+    ; CHECK-NEXT: $eax = COPY %cst(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_MUL %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            mul_0_cant_replace
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x * 0) -> 0
+    ; CHECK-LABEL: name: mul_0_cant_replace
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+    ; CHECK-NEXT: %op:gpr(s32) = G_MUL %x, %cst
+    ; CHECK-NEXT: $eax = COPY %op(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:gpr(s32) = G_MUL %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            sdiv_0
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (0 / x) -> 0
+    ; CHECK-LABEL: name: sdiv_0
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+    ; CHECK-NEXT: $eax = COPY %cst(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_SDIV %cst, %x
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            udiv_0
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (0 / x) -> 0
+    ; CHECK-LABEL: name: udiv_0
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+    ; CHECK-NEXT: $eax = COPY %cst(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_UDIV %cst, %x
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            srem_0
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (0 % x) -> 0
+    ; CHECK-LABEL: name: srem_0
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+    ; CHECK-NEXT: $eax = COPY %cst(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_SREM %cst, %x
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+
+---
+name:            urem_0
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (0 % x) -> 0
+    ; CHECK-LABEL: name: urem_0
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+    ; CHECK-NEXT: $eax = COPY %cst(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_UREM %cst, %x
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            right_ident_or
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x || 0) -> x
+    ; CHECK-LABEL: name: right_ident_or
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %x(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_OR %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+
+---
+name:            right_ident_xor
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x | 0) -> x
+    ; CHECK-LABEL: name: right_ident_xor
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %x(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_XOR %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            right_ident_shl
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x << 0) -> x
+    ; CHECK-LABEL: name: right_ident_shl
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %x(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_SHL %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            right_ident_ashr
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x ashr 0) -> x
+    ; CHECK-LABEL: name: right_ident_ashr
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %x(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_ASHR %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            right_ident_lshr
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Fold (x lshr 0) -> x
+    ; CHECK-LABEL: name: right_ident_lshr
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %x(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 0
+    %op:_(s32) = G_LSHR %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            dont_fold_sub
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; Not an identity, no folding.
+    ; CHECK-LABEL: name: dont_fold_sub
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
+    ; CHECK-NEXT: $eax = COPY %op(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 1
+    %op:_(s32) = G_SUB %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            look_through_zext
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $rax
+    ; CHECK-LABEL: name: look_through_zext
+    ; CHECK: liveins: $rax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %zero:_(s8) = G_CONSTANT i8 0
+    ; CHECK-NEXT: %zext_zero:_(s64) = G_ZEXT %zero(s8)
+    ; CHECK-NEXT: $rax = COPY %zext_zero(s64)
+    ; CHECK-NEXT: RET implicit $rax
+    %zero:_(s8) = G_CONSTANT i8 0
+    %zext_zero:_(s64) = G_ZEXT %zero(s8)
+    %c:_(s64) = G_CONSTANT i64 72340172838076673
+    %mul:_(s64) = G_MUL %c, %zext_zero
+    $rax = COPY %mul(s64)
+    RET implicit $rax
+...
+---
+name:            right_ident_ptr_add
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $rax
+    ; Fold (x + 0) -> x
+    ; CHECK-LABEL: name: right_ident_ptr_add
+    ; CHECK: liveins: $rax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(p0) = COPY $rax
+    ; CHECK-NEXT: $rax = COPY %x(p0)
+    ; CHECK-NEXT: RET implicit $rax
+    %x:_(p0) = COPY $rax
+    %cst:_(s64) = G_CONSTANT i64 0
+    %op:_(p0) = G_PTR_ADD %x(p0), %cst
+    $rax = COPY %op(p0)
+    RET implicit $rax
+...
+---
+name:            right_identity_rotl
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $eax, $ebx
+    ; CHECK-LABEL: name: right_identity_rotl
+    ; CHECK: liveins: $eax, $ebx
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %copy:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %copy(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %copy:_(s32) = COPY $eax
+    %zero:_(s32) = G_CONSTANT i32 0
+    %rot:_(s32) = G_ROTL %copy(s32), %zero(s32)
+    $eax = COPY %rot(s32)
+    RET implicit $eax
+...
+---
+name:            right_identity_rotr
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $eax, $ebx
+    ; CHECK-LABEL: name: right_identity_rotr
+    ; CHECK: liveins: $eax, $ebx
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %copy:_(s32) = COPY $eax
+    ; CHECK-NEXT: $eax = COPY %copy(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %copy:_(s32) = COPY $eax
+    %zero:_(s32) = G_CONSTANT i32 0
+    %rot:_(s32) = G_ROTR %copy(s32), %zero(s32)
+    $eax = COPY %rot(s32)
+    RET implicit $eax
+...
+---
+name: lshr_of_vec_zero
+body:             |
+  bb.1:
+  liveins: $xmm0
+    ; CHECK-LABEL: name: lshr_of_vec_zero
+    ; CHECK: liveins: $xmm0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $xmm0
+    ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<8 x s16>)
+    ; CHECK-NEXT: RET implicit $xmm0
+    %0:_(<8 x s16>) = COPY $xmm0
+    %5:_(s16) = G_CONSTANT i16 0
+    %zero_vec:_(<8 x s16>) = G_BUILD_VECTOR %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16)
+    %shift:_(<8 x s16>) = G_LSHR %0, %zero_vec(<8 x s16>)
+    $xmm0 = COPY %shift(<8 x s16>)
+    RET implicit $xmm0
+...
+---
+name: ptradd_of_vec_zero
+body:             |
+  bb.1:
+  liveins: $xmm0
+    ; CHECK-LABEL: name: ptradd_of_vec_zero
+    ; CHECK: liveins: $xmm0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x p0>) = COPY $xmm0
+    ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<2 x p0>)
+    ; CHECK-NEXT: RET implicit $xmm0
+    %0:_(<2 x p0>) = COPY $xmm0
+    %5:_(s64) = G_CONSTANT i64 0
+    %zero_vec:_(<2 x s64>) = G_BUILD_VECTOR %5(s64), %5(s64)
+    %ptr:_(<2 x p0>) = G_PTR_ADD %0, %zero_vec(<2 x s64>)
+    $xmm0 = COPY %ptr(<2 x p0>)
+    RET implicit $xmm0
+...
+---
+name:            i128_or_cst
+liveins:
+  - { reg: '$rax' }
+body:             |
+  bb.1:
+    liveins: $rax
+
+    ; CHECK-LABEL: name: i128_or_cst
+    ; CHECK: liveins: $rax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $rax
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128))
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 9223372036854775808
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s128) = G_OR [[LOAD]], [[C]]
+    ; CHECK-NEXT: G_STORE [[OR]](s128), [[COPY]](p0) :: (store (s128), align 4)
+    ; CHECK-NEXT: RET 0
+    %0:_(p0) = COPY $rax
+    %2:_(s128) = G_LOAD %0(p0) :: (load (s128))
+    %4:_(s128) = G_CONSTANT i128 9223372036854775808
+    %5:_(s128) = G_OR %2, %4
+    G_STORE %5(s128), %0(p0) :: (store (s128), align 4)
+    RET 0
+...
+---
+name:            mul_1_shift_of_shift
+liveins:
+  - { reg: '$rax' }
+body:             |
+  bb.1:
+    liveins: $rax
+
+    ; CHECK-LABEL: name: mul_1_shift_of_shift
+    ; CHECK: liveins: $rax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $rax
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+    ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[SHL]], [[C]]
+    ; CHECK-NEXT: $rax = COPY [[OR]](s64)
+    ; CHECK-NEXT: RET implicit $rax
+    %0:_(s64) = COPY $rax
+    %1:_(s64) = G_CONSTANT i64 1
+    %2:_(s64) = G_SHL %0, %1(s64)
+    %3:_(s64) = G_OR %2, %1
+    %4:_(s64) = G_MUL %3, %1
+    $rax = COPY %4(s64)
+    RET implicit $rax
+...
+---
+name:            sub_to_add
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; CHECK-LABEL: name: sub_to_add
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
+    ; CHECK-NEXT: $eax = COPY %op(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 1
+    %op:_(s32) = G_SUB %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:            sub_to_add_nuw
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $eax
+    ; CHECK-LABEL: name: sub_to_add_nuw
+    ; CHECK: liveins: $eax
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(s32) = COPY $eax
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
+    ; CHECK-NEXT: $eax = COPY %op(s32)
+    ; CHECK-NEXT: RET implicit $eax
+    %x:_(s32) = COPY $eax
+    %cst:_(s32) = G_CONSTANT i32 1
+    %op:_(s32) = nuw G_SUB %x(s32), %cst
+    $eax = COPY %op(s32)
+    RET implicit $eax
+...
+---
+name:   sub_to_add_nsw_128
+body:             |
+  bb.0:
+    liveins: $eax, $ebx
+
+    ; CHECK-LABEL: name: sub_to_add_nsw_128
+    ; CHECK: liveins: $eax, $ebx
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s32) = COPY $eax
+    ; CHECK-NEXT: %b:_(s8) = G_TRUNC %a(s32)
+    ; CHECK-NEXT: %c:_(s8) = G_CONSTANT i8 -128
+    ; CHECK-NEXT: %add:_(s8) = G_ADD %b, %c
+    ; CHECK-NEXT: %d:_(s32) = G_ZEXT %add(s8)
+    ; CHECK-NEXT: $eax = COPY %d(s32)
+    ; CHECK-NEXT: RET implicit $rax
+    %a:_(s32) = COPY $eax
+    %b:_(s8) = G_TRUNC %a
+    %c:_(s8) = G_CONSTANT i8 -128
+    %add:_(s8) = nsw nuw G_SUB %b, %c
+    %d:_(s32) = G_ZEXT %add
+    $eax = COPY %d
+    RET implicit $rax
+...
+---
+name:   sub_to_add_nsw_intmin
+body:             |
+  bb.0:
+    liveins: $eax, $ebx
+
+    ; CHECK-LABEL: name: sub_to_add_nsw_intmin
+    ; CHECK: liveins: $eax, $ebx
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s32) = COPY $eax
+    ; CHECK-NEXT: %c:_(s32) = G_CONSTANT i32 -2147483648
+    ; CHECK-NEXT: %add:_(s32) = G_ADD %a, %c
+    ; CHECK-NEXT: $eax = COPY %add(s32)
+    ; CHECK-NEXT: RET implicit $rax
+    %a:_(s32) = COPY $eax
+    %c:_(s32) = G_CONSTANT i32 -2147483648
+    %add:_(s32) = nsw nuw G_SUB %a, %c
+    $eax = COPY %add
+    RET implicit $rax
+...

>From e2af25d4197f38ddbaeeb27bafc851d0e06d4881 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sat, 21 Feb 2026 20:35:04 +0000
Subject: [PATCH 3/8] remove LI duplicated dependence

---
 .../lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 22e6815a1d391..abe20a74b273c 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -55,7 +55,7 @@ class X86PreLegalizerCombinerImpl : public Combiner {
       MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
       GISelCSEInfo *CSEInfo,
       const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
-      MachineDominatorTree *MDT, const LegalizerInfo *LI);
+      MachineDominatorTree *MDT);
 
   static const char *getName() { return "X86PreLegalizerCombiner"; }
 
@@ -77,9 +77,10 @@ X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
     MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
     GISelCSEInfo *CSEInfo,
     const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
-    MachineDominatorTree *MDT, const LegalizerInfo *LI)
+    MachineDominatorTree *MDT)
     : Combiner(MF, CInfo, &VT, CSEInfo),
-      Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT, LI),
+      Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT,
+             MF.getSubtarget<X86Subtarget>().getLegalizerInfo()),
       RuleConfig(RuleConfig), STI(MF.getSubtarget<X86Subtarget>()),
 #define GET_GICOMBINER_CONSTRUCTOR_INITS
 #include "X86GenPreLegalizeGICombiner.inc"
@@ -153,8 +154,7 @@ bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
   // This is the first Combiner, so the input IR might contain dead
   // instructions.
   CInfo.EnableFullDCE = true;
-  X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT,
-                                   LI);
+  X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT);
   return Impl.combineMachineInstrs();
 }
 
@@ -198,7 +198,7 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
   // instructions.
   CInfo.EnableFullDCE = true;
   X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
-                                   RuleConfig, &MDT, LI);
+                                   RuleConfig, &MDT);
   Impl.combineMachineInstrs();
 
   PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();

>From b156578848de85a0ff03ef3333d7b0ad00b2536f Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sun, 22 Feb 2026 09:27:05 +0000
Subject: [PATCH 4/8] include npm tests

---
 llvm/lib/Target/X86/X86PassRegistry.def                         | 2 +-
 .../X86/GlobalISel/prelegalizercombiner-trivial-arith.mir       | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def
index c4aafd8dbdb6b..45e7d0ebdbf7b 100644
--- a/llvm/lib/Target/X86/X86PassRegistry.def
+++ b/llvm/lib/Target/X86/X86PassRegistry.def
@@ -59,7 +59,7 @@ MACHINE_FUNCTION_PASS("x86-lvi-ret", X86LoadValueInjectionRetHardeningPass())
 MACHINE_FUNCTION_PASS("x86-optimize-leas", X86OptimizeLEAsPass())
 MACHINE_FUNCTION_PASS("x86-postlegalizer-combiner-pass", X86PostLegalizerCombinerPass())
 MACHINE_FUNCTION_PASS("x86-pre-tile-config", X86PreTileConfigPass())
-MACHINE_FUNCTION_PASS("x86-pre-legalizer-combiner-pass", X86PreLegalizerCombinerPass())
+MACHINE_FUNCTION_PASS("x86-prelegalizer-combiner-pass", X86PreLegalizerCombinerPass())
 MACHINE_FUNCTION_PASS("x86-return-thunks", X86ReturnThunksPass())
 MACHINE_FUNCTION_PASS("x86-seses", X86SpeculativeExecutionSideEffectSuppressionPass())
 MACHINE_FUNCTION_PASS("x86-slh", X86SpeculativeLoadHardeningPass())
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
index c85421a434208..cce4f248aa199 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name:            right_ident_sub

>From ac93919ba507dcafae22c1e9d5d094be155f5c54 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Tue, 24 Feb 2026 17:37:57 +0000
Subject: [PATCH 5/8] add Legacy to lpm pass

---
 .../X86/GISel/X86PreLegalizerCombiner.cpp     | 25 +++++++++++--------
 llvm/lib/Target/X86/X86.h                     |  4 +--
 llvm/lib/Target/X86/X86TargetMachine.cpp      |  4 +--
 3 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index abe20a74b273c..43f0b87d9329b 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -92,13 +92,15 @@ bool X86PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
   return tryCombineAllImpl(MI);
 }
 
-class X86PreLegalizerCombiner : public MachineFunctionPass {
+class X86PreLegalizerCombinerLegacy : public MachineFunctionPass {
 public:
   static char ID;
 
-  X86PreLegalizerCombiner();
+  X86PreLegalizerCombinerLegacy();
 
-  StringRef getPassName() const override { return "X86PreLegalizerCombiner"; }
+  StringRef getPassName() const override {
+    return "X86PreLegalizerCombinerLegacy";
+  }
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
@@ -109,7 +111,7 @@ class X86PreLegalizerCombiner : public MachineFunctionPass {
 };
 } // end anonymous namespace
 
-void X86PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+void X86PreLegalizerCombinerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<TargetPassConfig>();
   AU.setPreservesCFG();
   getSelectionDAGFallbackAnalysisUsage(AU);
@@ -122,12 +124,13 @@ void X86PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
-X86PreLegalizerCombiner::X86PreLegalizerCombiner() : MachineFunctionPass(ID) {
+X86PreLegalizerCombinerLegacy::X86PreLegalizerCombinerLegacy()
+    : MachineFunctionPass(ID) {
   if (!RuleConfig.parseCommandLineOption())
     report_fatal_error("Invalid rule identifier");
 }
 
-bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
   if (MF.getProperties().hasFailedISel())
     return false;
   auto &TPC = getAnalysis<TargetPassConfig>();
@@ -158,14 +161,14 @@ bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
   return Impl.combineMachineInstrs();
 }
 
-char X86PreLegalizerCombiner::ID = 0;
-INITIALIZE_PASS_BEGIN(X86PreLegalizerCombiner, DEBUG_TYPE,
+char X86PreLegalizerCombinerLegacy::ID = 0;
+INITIALIZE_PASS_BEGIN(X86PreLegalizerCombinerLegacy, DEBUG_TYPE,
                       "Combine X86 machine instrs before legalization", false,
                       false)
 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
 INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
 INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
-INITIALIZE_PASS_END(X86PreLegalizerCombiner, DEBUG_TYPE,
+INITIALIZE_PASS_END(X86PreLegalizerCombinerLegacy, DEBUG_TYPE,
                     "Combine X86 machine instrs before legalization", false,
                     false)
 
@@ -208,7 +211,7 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
   return PA;
 }
 
-FunctionPass *createX86PreLegalizerCombiner() {
-  return new X86PreLegalizerCombiner();
+FunctionPass *createX86PreLegalizerCombinerLegacy() {
+  return new X86PreLegalizerCombinerLegacy();
 }
 } // end namespace llvm
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 55a2f84630db5..a934abb78e956 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -412,7 +412,7 @@ class X86PreLegalizerCombinerPass
                         MachineFunctionAnalysisManager &MFAM);
 };
 
-FunctionPass *createX86PreLegalizerCombiner();
+FunctionPass *createX86PreLegalizerCombinerLegacy();
 
 class X86LoadValueInjectionLoadHardeningPass
     : public PassInfoMixin<X86LoadValueInjectionLoadHardeningPass> {
@@ -497,7 +497,7 @@ void initializeX86SpeculativeLoadHardeningLegacyPass(PassRegistry &);
 void initializeX86SuppressAPXForRelocationLegacyPass(PassRegistry &);
 void initializeX86TileConfigLegacyPass(PassRegistry &);
 void initializeX86WinEHUnwindV2LegacyPass(PassRegistry &);
-void initializeX86PreLegalizerCombinerPass(PassRegistry &);
+void initializeX86PreLegalizerCombinerLegacyPass(PassRegistry &);
 void initializeX86PostLegalizerCombinerLegacyPass(PassRegistry &);
 
 namespace X86AS {
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 6de566b39d045..5c8a508f37917 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -107,7 +107,7 @@ extern "C" LLVM_C_ABI void LLVMInitializeX86Target() {
   initializeX86DynAllocaExpanderLegacyPass(PR);
   initializeX86SuppressAPXForRelocationLegacyPass(PR);
   initializeX86WinEHUnwindV2LegacyPass(PR);
-  initializeX86PreLegalizerCombinerPass(PR);
+  initializeX86PreLegalizerCombinerLegacyPass(PR);
   initializeX86PostLegalizerCombinerLegacyPass(PR);
 }
 
@@ -495,7 +495,7 @@ bool X86PassConfig::addGlobalInstructionSelect() {
 
 void X86PassConfig::addPreLegalizeMachineIR() {
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addPass(createX86PreLegalizerCombiner());
+    addPass(createX86PreLegalizerCombinerLegacy());
   }
 }
 

>From 8be6041bda9e2ef87537e012080c1942f2fe2379 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Tue, 24 Feb 2026 20:02:34 +0000
Subject: [PATCH 6/8] create CombinerInfo factory fn

---
 .../X86/GISel/X86PreLegalizerCombiner.cpp     | 35 +++++++------------
 1 file changed, 13 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 43f0b87d9329b..99ed6de00183a 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -27,6 +27,7 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/IR/Instructions.h"
 
 #define GET_GICOMBINER_DEPS
@@ -40,6 +41,16 @@ using namespace MIPatternMatch;
 
 namespace {
 
+CombinerInfo createCombinerInfo(bool EnableOpt, const Function &F) {
+  CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
+                     nullptr, EnableOpt, F.hasOptSize(), F.hasMinSize());
+
+  // This is the first Combiner, so the input IR might contain dead
+  // instructions.
+  CInfo.EnableFullDCE = true;
+  return CInfo;
+}
+
 #define GET_GICOMBINER_TYPES
 #include "X86GenPreLegalizeGICombiner.inc"
 #undef GET_GICOMBINER_TYPES
@@ -139,10 +150,6 @@ bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
   GISelCSEAnalysisWrapper &Wrapper =
       getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
   auto *CSEInfo = &Wrapper.get(TPC.getCSEConfig());
-
-  const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
-  const LegalizerInfo *LI = ST.getLegalizerInfo();
-
   const Function &F = MF.getFunction();
   bool EnableOpt =
       MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
@@ -150,13 +157,7 @@ bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
       &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
   MachineDominatorTree *MDT =
       &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-  CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
-                     /*LegalizerInfo=*/LI, EnableOpt, F.hasOptSize(),
-                     F.hasMinSize());
-
-  // This is the first Combiner, so the input IR might contain dead
-  // instructions.
-  CInfo.EnableFullDCE = true;
+  CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
   X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT);
   return Impl.combineMachineInstrs();
 }
@@ -185,21 +186,11 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
     report_fatal_error("Invalid rule identifier");
 
   auto &CSEInfo = MFAM.getResult<GISelCSEAnalysis>(MF);
-
-  const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
-  const LegalizerInfo *LI = ST.getLegalizerInfo();
-
   const Function &F = MF.getFunction();
   bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOptLevel::None;
   GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
   MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
-  CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
-                     /*LegalizerInfo=*/LI, EnableOpt, F.hasOptSize(),
-                     F.hasMinSize());
-
-  // This is the first Combiner, so the input IR might contain dead
-  // instructions.
-  CInfo.EnableFullDCE = true;
+  CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
   X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
                                    RuleConfig, &MDT);
   Impl.combineMachineInstrs();

>From bdfe5e2fcc7dc293f85566a25273601c07257aae Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Fri, 1 May 2026 16:00:38 +0100
Subject: [PATCH 7/8] hook up tests

---
 .../X86/GISel/X86PreLegalizerCombiner.cpp     |   1 -
 .../GlobalISel/prelegalizer-combiner-div.mir  |   1 +
 .../prelegalizer-combiner-identity.mir        |   1 +
 .../GlobalISel/prelegalizer-combiner-lshr.mir |   1 +
 .../GlobalISel/prelegalizer-combiner-mul.mir  |   1 +
 .../GlobalISel/prelegalizer-combiner-or.mir   |   1 +
 .../prelegalizer-combiner-ptr-add.mir         |   1 +
 .../GlobalISel/prelegalizer-combiner-rem.mir  |   1 +
 .../GlobalISel/prelegalizer-combiner-sub.mir  |   1 +
 .../prelegalizercombiner-trivial-arith.mir    | 521 ------------------
 10 files changed, 8 insertions(+), 522 deletions(-)
 delete mode 100644 llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir

diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 99ed6de00183a..18333944ce52b 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -27,7 +27,6 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/IR/Instructions.h"
 
 #define GET_GICOMBINER_DEPS
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir
index 717f0daaddcd6..dc9c458cf2b02 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name:            sdiv_0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir
index ebc9d92301c57..d41198950fc10 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir
@@ -1,4 +1,5 @@
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name:            right_ident_sub
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir
index 4db7750258801..2ded48ba58d01 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name: lshr_of_vec_zero
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir
index fce8b011a31eb..ed13149ea086a 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name:            mul_0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir
index 9b34333dd3c22..29433a21cbff3 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name:            i128_or_cst
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir
index 4c3c5d2e1e7fd..2a8612ce3ee5b 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name: ptradd_of_vec_zero
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir
index 500223080f899..2b98c5792e07b 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name:            srem_0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir
index 05215130a30f2..26965e3ecad73 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
 
 ---
 name:            dont_fold_sub
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
deleted file mode 100644
index cce4f248aa199..0000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
+++ /dev/null
@@ -1,521 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
-# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
-
----
-name:            right_ident_sub
-tracksRegLiveness: true
-body:             |
-  bb.0.entry:
-    liveins: $eax
-    ; Fold (x - 0) -> x
-    ; CHECK-LABEL: name: right_ident_sub
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %x(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_SUB %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-
-...
----
-name:            right_ident_add
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x + 0) -> x
-    ; CHECK-LABEL: name: right_ident_add
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %x(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_ADD %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            mul_0
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x * 0) -> 0
-    ; CHECK-LABEL: name: mul_0
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
-    ; CHECK-NEXT: $eax = COPY %cst(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_MUL %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            mul_0_cant_replace
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x * 0) -> 0
-    ; CHECK-LABEL: name: mul_0_cant_replace
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
-    ; CHECK-NEXT: %op:gpr(s32) = G_MUL %x, %cst
-    ; CHECK-NEXT: $eax = COPY %op(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:gpr(s32) = G_MUL %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            sdiv_0
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (0 / x) -> 0
-    ; CHECK-LABEL: name: sdiv_0
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
-    ; CHECK-NEXT: $eax = COPY %cst(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_SDIV %cst, %x
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            udiv_0
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (0 / x) -> 0
-    ; CHECK-LABEL: name: udiv_0
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
-    ; CHECK-NEXT: $eax = COPY %cst(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_UDIV %cst, %x
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            srem_0
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (0 % x) -> 0
-    ; CHECK-LABEL: name: srem_0
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
-    ; CHECK-NEXT: $eax = COPY %cst(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_SREM %cst, %x
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
-
----
-name:            urem_0
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (0 % x) -> 0
-    ; CHECK-LABEL: name: urem_0
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
-    ; CHECK-NEXT: $eax = COPY %cst(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_UREM %cst, %x
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            right_ident_or
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x || 0) -> x
-    ; CHECK-LABEL: name: right_ident_or
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %x(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_OR %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
-
----
-name:            right_ident_xor
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x | 0) -> x
-    ; CHECK-LABEL: name: right_ident_xor
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %x(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_XOR %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            right_ident_shl
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x << 0) -> x
-    ; CHECK-LABEL: name: right_ident_shl
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %x(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_SHL %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            right_ident_ashr
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x ashr 0) -> x
-    ; CHECK-LABEL: name: right_ident_ashr
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %x(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_ASHR %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            right_ident_lshr
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Fold (x lshr 0) -> x
-    ; CHECK-LABEL: name: right_ident_lshr
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %x(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 0
-    %op:_(s32) = G_LSHR %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            dont_fold_sub
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; Not an identity, no folding.
-    ; CHECK-LABEL: name: dont_fold_sub
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
-    ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
-    ; CHECK-NEXT: $eax = COPY %op(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 1
-    %op:_(s32) = G_SUB %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            look_through_zext
-tracksRegLiveness: true
-body:             |
-  bb.0:
-    liveins: $rax
-    ; CHECK-LABEL: name: look_through_zext
-    ; CHECK: liveins: $rax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %zero:_(s8) = G_CONSTANT i8 0
-    ; CHECK-NEXT: %zext_zero:_(s64) = G_ZEXT %zero(s8)
-    ; CHECK-NEXT: $rax = COPY %zext_zero(s64)
-    ; CHECK-NEXT: RET implicit $rax
-    %zero:_(s8) = G_CONSTANT i8 0
-    %zext_zero:_(s64) = G_ZEXT %zero(s8)
-    %c:_(s64) = G_CONSTANT i64 72340172838076673
-    %mul:_(s64) = G_MUL %c, %zext_zero
-    $rax = COPY %mul(s64)
-    RET implicit $rax
-...
----
-name:            right_ident_ptr_add
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $rax
-    ; Fold (x + 0) -> x
-    ; CHECK-LABEL: name: right_ident_ptr_add
-    ; CHECK: liveins: $rax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(p0) = COPY $rax
-    ; CHECK-NEXT: $rax = COPY %x(p0)
-    ; CHECK-NEXT: RET implicit $rax
-    %x:_(p0) = COPY $rax
-    %cst:_(s64) = G_CONSTANT i64 0
-    %op:_(p0) = G_PTR_ADD %x(p0), %cst
-    $rax = COPY %op(p0)
-    RET implicit $rax
-...
----
-name:            right_identity_rotl
-tracksRegLiveness: true
-body:             |
-  bb.0:
-    liveins: $eax, $ebx
-    ; CHECK-LABEL: name: right_identity_rotl
-    ; CHECK: liveins: $eax, $ebx
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %copy:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %copy(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %copy:_(s32) = COPY $eax
-    %zero:_(s32) = G_CONSTANT i32 0
-    %rot:_(s32) = G_ROTL %copy(s32), %zero(s32)
-    $eax = COPY %rot(s32)
-    RET implicit $eax
-...
----
-name:            right_identity_rotr
-tracksRegLiveness: true
-body:             |
-  bb.0:
-    liveins: $eax, $ebx
-    ; CHECK-LABEL: name: right_identity_rotr
-    ; CHECK: liveins: $eax, $ebx
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %copy:_(s32) = COPY $eax
-    ; CHECK-NEXT: $eax = COPY %copy(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %copy:_(s32) = COPY $eax
-    %zero:_(s32) = G_CONSTANT i32 0
-    %rot:_(s32) = G_ROTR %copy(s32), %zero(s32)
-    $eax = COPY %rot(s32)
-    RET implicit $eax
-...
----
-name: lshr_of_vec_zero
-body:             |
-  bb.1:
-  liveins: $xmm0
-    ; CHECK-LABEL: name: lshr_of_vec_zero
-    ; CHECK: liveins: $xmm0
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $xmm0
-    ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<8 x s16>)
-    ; CHECK-NEXT: RET implicit $xmm0
-    %0:_(<8 x s16>) = COPY $xmm0
-    %5:_(s16) = G_CONSTANT i16 0
-    %zero_vec:_(<8 x s16>) = G_BUILD_VECTOR %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16)
-    %shift:_(<8 x s16>) = G_LSHR %0, %zero_vec(<8 x s16>)
-    $xmm0 = COPY %shift(<8 x s16>)
-    RET implicit $xmm0
-...
----
-name: ptradd_of_vec_zero
-body:             |
-  bb.1:
-  liveins: $xmm0
-    ; CHECK-LABEL: name: ptradd_of_vec_zero
-    ; CHECK: liveins: $xmm0
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x p0>) = COPY $xmm0
-    ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<2 x p0>)
-    ; CHECK-NEXT: RET implicit $xmm0
-    %0:_(<2 x p0>) = COPY $xmm0
-    %5:_(s64) = G_CONSTANT i64 0
-    %zero_vec:_(<2 x s64>) = G_BUILD_VECTOR %5(s64), %5(s64)
-    %ptr:_(<2 x p0>) = G_PTR_ADD %0, %zero_vec(<2 x s64>)
-    $xmm0 = COPY %ptr(<2 x p0>)
-    RET implicit $xmm0
-...
----
-name:            i128_or_cst
-liveins:
-  - { reg: '$rax' }
-body:             |
-  bb.1:
-    liveins: $rax
-
-    ; CHECK-LABEL: name: i128_or_cst
-    ; CHECK: liveins: $rax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $rax
-    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128))
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 9223372036854775808
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s128) = G_OR [[LOAD]], [[C]]
-    ; CHECK-NEXT: G_STORE [[OR]](s128), [[COPY]](p0) :: (store (s128), align 4)
-    ; CHECK-NEXT: RET 0
-    %0:_(p0) = COPY $rax
-    %2:_(s128) = G_LOAD %0(p0) :: (load (s128))
-    %4:_(s128) = G_CONSTANT i128 9223372036854775808
-    %5:_(s128) = G_OR %2, %4
-    G_STORE %5(s128), %0(p0) :: (store (s128), align 4)
-    RET 0
-...
----
-name:            mul_1_shift_of_shift
-liveins:
-  - { reg: '$rax' }
-body:             |
-  bb.1:
-    liveins: $rax
-
-    ; CHECK-LABEL: name: mul_1_shift_of_shift
-    ; CHECK: liveins: $rax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $rax
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
-    ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[SHL]], [[C]]
-    ; CHECK-NEXT: $rax = COPY [[OR]](s64)
-    ; CHECK-NEXT: RET implicit $rax
-    %0:_(s64) = COPY $rax
-    %1:_(s64) = G_CONSTANT i64 1
-    %2:_(s64) = G_SHL %0, %1(s64)
-    %3:_(s64) = G_OR %2, %1
-    %4:_(s64) = G_MUL %3, %1
-    $rax = COPY %4(s64)
-    RET implicit $rax
-...
----
-name:            sub_to_add
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; CHECK-LABEL: name: sub_to_add
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
-    ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
-    ; CHECK-NEXT: $eax = COPY %op(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 1
-    %op:_(s32) = G_SUB %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:            sub_to_add_nuw
-tracksRegLiveness: true
-body:             |
-  bb.1.entry:
-    liveins: $eax
-    ; CHECK-LABEL: name: sub_to_add_nuw
-    ; CHECK: liveins: $eax
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x:_(s32) = COPY $eax
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
-    ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
-    ; CHECK-NEXT: $eax = COPY %op(s32)
-    ; CHECK-NEXT: RET implicit $eax
-    %x:_(s32) = COPY $eax
-    %cst:_(s32) = G_CONSTANT i32 1
-    %op:_(s32) = nuw G_SUB %x(s32), %cst
-    $eax = COPY %op(s32)
-    RET implicit $eax
-...
----
-name:   sub_to_add_nsw_128
-body:             |
-  bb.0:
-    liveins: $eax, $ebx
-
-    ; CHECK-LABEL: name: sub_to_add_nsw_128
-    ; CHECK: liveins: $eax, $ebx
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s32) = COPY $eax
-    ; CHECK-NEXT: %b:_(s8) = G_TRUNC %a(s32)
-    ; CHECK-NEXT: %c:_(s8) = G_CONSTANT i8 -128
-    ; CHECK-NEXT: %add:_(s8) = G_ADD %b, %c
-    ; CHECK-NEXT: %d:_(s32) = G_ZEXT %add(s8)
-    ; CHECK-NEXT: $eax = COPY %d(s32)
-    ; CHECK-NEXT: RET implicit $rax
-    %a:_(s32) = COPY $eax
-    %b:_(s8) = G_TRUNC %a
-    %c:_(s8) = G_CONSTANT i8 -128
-    %add:_(s8) = nsw nuw G_SUB %b, %c
-    %d:_(s32) = G_ZEXT %add
-    $eax = COPY %d
-    RET implicit $rax
-...
----
-name:   sub_to_add_nsw_intmin
-body:             |
-  bb.0:
-    liveins: $eax, $ebx
-
-    ; CHECK-LABEL: name: sub_to_add_nsw_intmin
-    ; CHECK: liveins: $eax, $ebx
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s32) = COPY $eax
-    ; CHECK-NEXT: %c:_(s32) = G_CONSTANT i32 -2147483648
-    ; CHECK-NEXT: %add:_(s32) = G_ADD %a, %c
-    ; CHECK-NEXT: $eax = COPY %add(s32)
-    ; CHECK-NEXT: RET implicit $rax
-    %a:_(s32) = COPY $eax
-    %c:_(s32) = G_CONSTANT i32 -2147483648
-    %add:_(s32) = nsw nuw G_SUB %a, %c
-    $eax = COPY %add
-    RET implicit $rax
-...

>From 39495c2875e2140d9f82ff300d7425c6da0a1987 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Fri, 1 May 2026 17:36:44 +0100
Subject: [PATCH 8/8] format

---
 llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 18333944ce52b..d52bc3e19932a 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -190,8 +190,8 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
   GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
   MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
   CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
-  X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
-                                   RuleConfig, &MDT);
+  X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(), RuleConfig,
+                                   &MDT);
   Impl.combineMachineInstrs();
 
   PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();



More information about the llvm-commits mailing list