[NPM] Make LoopStrengthReduce function pass
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index e25f5a6..05c44e3 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -724,15 +724,16 @@
 
   // Run loop strength reduction before anything else.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableLSR) {
-    // These passes do not use MSSA.
-    LoopPassManager LPM;
-    LPM.addPass(CanonicalizeFreezeInLoopsPass());
-    LPM.addPass(LoopStrengthReducePass());
+    addFunctionPass(
+        createFunctionToLoopPassAdaptor(CanonicalizeFreezeInLoopsPass(),
+                                        /*UseMemorySSA=*/false),
+        PMW);
+    addFunctionPass(LoopStrengthReducePass(), PMW);
+
     if (Opt.EnableLoopTermFold)
-      LPM.addPass(LoopTermFoldPass());
-    addFunctionPass(createFunctionToLoopPassAdaptor(std::move(LPM),
-                                                    /*UseMemorySSA=*/false),
-                    PMW);
+      addFunctionPass(createFunctionToLoopPassAdaptor(LoopTermFoldPass(),
+                                                      /*UseMemorySSA=*/false),
+                      PMW);
   }
 
   // Run GC lowering passes for builtin collectors
diff --git a/llvm/include/llvm/Transforms/Scalar/LoopStrengthReduce.h b/llvm/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
index 5cf805b..ea45a11 100644
--- a/llvm/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
+++ b/llvm/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
@@ -32,8 +32,7 @@
 /// Performs Loop Strength Reduce Pass.
 class LoopStrengthReducePass : public PassInfoMixin<LoopStrengthReducePass> {
 public:
-  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
-                        LoopStandardAnalysisResults &AR, LPMUpdater &U);
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index c92d93d..b0a4d03 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -568,6 +568,7 @@
 FUNCTION_PASS("view-post-dom", PostDomViewer())
 FUNCTION_PASS("view-post-dom-only", PostDomOnlyViewer())
 FUNCTION_PASS("wasm-eh-prepare", WasmEHPreparePass())
+FUNCTION_PASS("loop-reduce", LoopStrengthReducePass())
 #undef FUNCTION_PASS
 
 #ifndef FUNCTION_PASS_WITH_PARAMS
@@ -775,7 +776,6 @@
 LOOP_PASS("loop-idiom-vectorize", LoopIdiomVectorizePass())
 LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass())
 LOOP_PASS("loop-predication", LoopPredicationPass())
-LOOP_PASS("loop-reduce", LoopStrengthReducePass())
 LOOP_PASS("loop-term-fold", LoopTermFoldPass())
 LOOP_PASS("loop-simplifycfg", LoopSimplifyCFGPass())
 LOOP_PASS("loop-unroll-full", LoopFullUnrollPass())
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 5421cad..f84e398 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -57,6 +57,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PriorityWorklist.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallBitVector.h"
@@ -7126,16 +7127,48 @@
   return ReduceLoopStrength(L, IU, SE, DT, LI, TTI, AC, TLI, MSSA);
 }
 
-PreservedAnalyses LoopStrengthReducePass::run(Loop &L, LoopAnalysisManager &AM,
-                                              LoopStandardAnalysisResults &AR,
-                                              LPMUpdater &) {
-  if (!ReduceLoopStrength(&L, AM.getResult<IVUsersAnalysis>(L, AR), AR.SE,
-                          AR.DT, AR.LI, AR.TTI, AR.AC, AR.TLI, AR.MSSA))
+PreservedAnalyses LoopStrengthReducePass::run(Function &F,
+                                              FunctionAnalysisManager &FAM) {
+  LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
+
+  if (LI.empty())
     return PreservedAnalyses::all();
 
-  auto PA = getLoopPassPreservedAnalyses();
-  if (AR.MSSA)
+  ScalarEvolution &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
+  DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
+  TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
+  TargetLibraryInfo &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
+  AssumptionCache &AC = FAM.getResult<AssumptionAnalysis>(F);
+  auto &AA = FAM.getResult<AAManager>(F);
+  auto *MSSA = FAM.getCachedResult<MemorySSAAnalysis>(F);
+
+  LoopStandardAnalysisResults LAR = {
+      AA, AC, DT, LI, SE, TLI, TTI, MSSA ? &MSSA->getMSSA() : nullptr};
+  LoopAnalysisManager &LAM =
+      FAM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
+
+  SmallPriorityWorklist<Loop *, 4> Worklist;
+  appendLoopsToWorklist(LI, Worklist);
+
+  bool Changed = false;
+  do {
+    Loop *L = Worklist.pop_back_val();
+    auto &IU = LAM.getResult<IVUsersAnalysis>(*L, LAR);
+    ReduceLoopStrength(L, IU, SE, DT, LI, TTI, AC, TLI,
+                       MSSA ? &MSSA->getMSSA() : nullptr);
+  } while (!Worklist.empty());
+
+  if (!Changed)
+    return PreservedAnalyses::all();
+
+  PreservedAnalyses PA;
+  PA.preserve<DominatorTreeAnalysis>();
+  PA.preserve<LoopAnalysis>();
+  PA.preserve<ScalarEvolutionAnalysis>();
+
+  if (MSSA)
     PA.preserve<MemorySSAAnalysis>();
+
   return PA;
 }
 
diff --git a/llvm/test/Analysis/MemorySSA/update-remove-dead-blocks.ll b/llvm/test/Analysis/MemorySSA/update-remove-dead-blocks.ll
index 26f1ad7..671e4b5 100644
--- a/llvm/test/Analysis/MemorySSA/update-remove-dead-blocks.ll
+++ b/llvm/test/Analysis/MemorySSA/update-remove-dead-blocks.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>,loop-reduce,loop-simplifycfg)' -verify-memoryssa -S %s | FileCheck %s
+; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),loop-reduce,loop-mssa(loop-simplifycfg)' -verify-memoryssa -S %s | FileCheck %s
 
 ; Test case for PR47557.
 
diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline-npm.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline-npm.ll
index c49b2b9..69bca2a 100644
--- a/llvm/test/CodeGen/AMDGPU/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline-npm.ll
@@ -125,8 +125,8 @@
 ; GCN-O2-NEXT: amdgpu-codegenprepare
 ; GCN-O2-NEXT: loop-mssa(licm<allowspeculation>)
 ; GCN-O2-NEXT: verify
-; GCN-O2-NEXT: loop(canon-freeze
-; GCN-O2-NEXT: loop-reduce)
+; GCN-O2-NEXT: loop(canon-freeze)
+; GCN-O2-NEXT: loop-reduce
 ; GCN-O2-NEXT: unreachableblockelim
 ; GCN-O2-NEXT: consthoist
 ; GCN-O2-NEXT: replace-with-veclib
@@ -294,8 +294,8 @@
 ; GCN-O3-NEXT: amdgpu-codegenprepare
 ; GCN-O3-NEXT: loop-mssa(licm<allowspeculation>)
 ; GCN-O3-NEXT: verify
-; GCN-O3-NEXT: loop(canon-freeze
-; GCN-O3-NEXT: loop-reduce)
+; GCN-O3-NEXT: loop(canon-freeze)
+; GCN-O3-NEXT: loop-reduce
 ; GCN-O3-NEXT: unreachableblockelim
 ; GCN-O3-NEXT: consthoist
 ; GCN-O3-NEXT: replace-with-veclib
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index e392cf7..3355425 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -86,8 +86,8 @@
 ; O2-NEXT: x86-lower-amx-intrinsics
 ; O2-NEXT: x86-lower-amx-type
 ; O2-NEXT: verify
-; O2-NEXT: loop(canon-freeze
-; O2-NEXT: loop-reduce)
+; O2-NEXT: loop(canon-freeze)
+; O2-NEXT: loop-reduce
 ; O2-NEXT: gc-lowering)
 ; O2-NEXT: shadow-stack-gc-lowering
 ; O2-NEXT: function(unreachableblockelim
@@ -272,8 +272,8 @@
 ; O3-WINDOWS-NEXT: x86-lower-amx-intrinsics
 ; O3-WINDOWS-NEXT: x86-lower-amx-type
 ; O3-WINDOWS-NEXT: verify
-; O3-WINDOWS-NEXT: loop(canon-freeze
-; O3-WINDOWS-NEXT: loop-reduce)
+; O3-WINDOWS-NEXT: loop(canon-freeze)
+; O3-WINDOWS-NEXT: loop-reduce
 ; O3-WINDOWS-NEXT: gc-lowering)
 ; O3-WINDOWS-NEXT: shadow-stack-gc-lowering
 ; O3-WINDOWS-NEXT: function(unreachableblockelim
diff --git a/llvm/test/Feature/optnone-opt.ll b/llvm/test/Feature/optnone-opt.ll
index 83ff946..d8223df 100644
--- a/llvm/test/Feature/optnone-opt.ll
+++ b/llvm/test/Feature/optnone-opt.ll
@@ -3,7 +3,7 @@
 ; RUN: opt -passes='default<O2>' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3
 ; RUN: opt -passes='default<O3>' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3
 ; RUN: opt -passes='dce,gvn-hoist,lower-atomic' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-MORE
-; RUN: opt -passes='loop(indvars,licm,loop-deletion,loop-idiom,loop-instsimplify,loop-reduce,simple-loop-unswitch),loop-unroll' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-LOOP
+; RUN: opt -passes='loop(indvars,licm,loop-deletion,loop-idiom,loop-instsimplify,simple-loop-unswitch),loop-reduce,loop-unroll' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-LOOP
 ; RUN: opt -passes='instsimplify,verify' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-REQUIRED
 
 ; This test verifies that we don't run target independent IR-level
diff --git a/llvm/test/Transforms/LoopRotate/preserve-scev.ll b/llvm/test/Transforms/LoopRotate/preserve-scev.ll
index 2164f46..baaf429 100644
--- a/llvm/test/Transforms/LoopRotate/preserve-scev.ll
+++ b/llvm/test/Transforms/LoopRotate/preserve-scev.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -passes=loop-rotate,loop-reduce -verify-memoryssa -verify-dom-info -verify-loop-info -disable-output
+; RUN: opt < %s -passes=loop(loop-rotate),loop-reduce -verify-memoryssa -verify-dom-info -verify-loop-info -disable-output
 
 define fastcc void @foo(ptr %A, i64 %i) nounwind {
 BB:
diff --git a/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll b/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll
index e7afc96..7a17c30 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -loop-reduce %s -o - -S | FileCheck %s --check-prefix=LEGACYPM
-; RUN: opt -passes='loop(loop-reduce)' %s -o - -S | FileCheck %s --check-prefix=NEWPM
+; RUN: opt -passes='lcssa,loop-reduce' %s -o - -S | FileCheck %s --check-prefix=NEWPM
 
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 
diff --git a/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting2.ll b/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting2.ll
index 3b6f519..32e7360 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting2.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting2.ll
@@ -1,4 +1,4 @@
-; RUN: opt -passes='loop(loop-reduce)' %s -o - -S | FileCheck %s
+; RUN: opt -passes='loop-reduce' %s -o - -S | FileCheck %s
 
 ; Required metadata to trigger previously failing assertion.
 target datalayout = "e-m:e-i64:64-n32:64"
diff --git a/llvm/test/Transforms/LoopStrengthReduce/depth-limit-overrun.ll b/llvm/test/Transforms/LoopStrengthReduce/depth-limit-overrun.ll
index 9c3698a..25693a3 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/depth-limit-overrun.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/depth-limit-overrun.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes 'loop-reduce' -scalar-evolution-max-arith-depth=2 -S < %s | FileCheck --check-prefixes=DEFAULT %s
+; RUN: opt -passes 'loop-simplify,loop-reduce' -scalar-evolution-max-arith-depth=2 -S < %s | FileCheck --check-prefixes=DEFAULT %s
 ; RUN: opt -loop-reduce -scalar-evolution-max-arith-depth=2 -S < %s | FileCheck --check-prefixes=LIMIT %s
 
 ; This test should just compile cleanly without assertions.
diff --git a/llvm/test/Transforms/LoopStrengthReduce/ivchain.ll b/llvm/test/Transforms/LoopStrengthReduce/ivchain.ll
index f1c9938..87d1b2f 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/ivchain.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/ivchain.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
 ; RUN: opt < %s -loop-reduce -S | FileCheck %s
-; RUN: opt -passes='require<scalar-evolution>,require<target-ir>,loop(loop-reduce)' < %s -S | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<target-ir>,loop-reduce' < %s -S | FileCheck %s
 ;
 ; PR11782: bad cast to AddRecExpr.
 ; A sign extend feeds an IVUser and cannot be hoisted into the AddRec.
diff --git a/llvm/test/Transforms/LoopStrengthReduce/lsr-rewrite-to-add-one.ll b/llvm/test/Transforms/LoopStrengthReduce/lsr-rewrite-to-add-one.ll
index 74d861c..14dd063 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/lsr-rewrite-to-add-one.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/lsr-rewrite-to-add-one.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes=loop-reduce -S %s | FileCheck %s
+; RUN: opt -passes=lcssa,loop-reduce -S %s | FileCheck %s
 
 target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
 
diff --git a/llvm/test/Transforms/LoopStrengthReduce/lsr-term-fold-negative-testcase.ll b/llvm/test/Transforms/LoopStrengthReduce/lsr-term-fold-negative-testcase.ll
index 89ddba3..f040e73 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/lsr-term-fold-negative-testcase.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/lsr-term-fold-negative-testcase.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
 ; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-reduce,loop-term-fold -S -debug 2>&1 | FileCheck %s
+; RUN: opt < %s -passes=loop-simplify,loop-reduce,loop-term-fold -S -debug 2>&1 | FileCheck %s
 
 target datalayout = "e-p:64:64:64-n64"
 
diff --git a/llvm/test/Transforms/LoopStrengthReduce/pr84709.ll b/llvm/test/Transforms/LoopStrengthReduce/pr84709.ll
index 99794d0..71891c7 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/pr84709.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/pr84709.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
-; RUN: opt -S -passes=loop-reduce < %s | FileCheck %s
+; RUN: opt -S -passes=lcssa,loop-reduce < %s | FileCheck %s
 
 ; Make sure it does not assert.
 define i64 @test() {
diff --git a/llvm/test/Transforms/LoopStrengthReduce/preserve-lcssa.ll b/llvm/test/Transforms/LoopStrengthReduce/preserve-lcssa.ll
index 0add19e..fcd94eb 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/preserve-lcssa.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/preserve-lcssa.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
 ; RUN: opt -S -loop-reduce %s | FileCheck --check-prefixes=LEGACYPM %s
-; RUN: opt -S -passes=loop-reduce %s | FileCheck --check-prefixes=NEWPM %s
+; RUN: opt -S -passes=loop-simplify,loop-reduce %s | FileCheck --check-prefixes=NEWPM %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/Transforms/LoopStrengthReduce/scev-after-loopinstsimplify.ll b/llvm/test/Transforms/LoopStrengthReduce/scev-after-loopinstsimplify.ll
index 044f76a..7de39269 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/scev-after-loopinstsimplify.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/scev-after-loopinstsimplify.ll
@@ -1,4 +1,4 @@
-; RUN: opt %s -passes=indvars,loop-instsimplify,loop-reduce
+; RUN: opt %s -passes=loop(indvars,loop-instsimplify),loop-reduce
 ; We are only checking that there is no crash!
 
 ; https://bugs.llvm.org/show_bug.cgi?id=37936