[llvm] [CodeGen][NPM] Port MachinePipeliner to NPM (PR #221676)
Vikram Hegde via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 04:14:46 PDT 2026
https://github.com/vikramRH updated https://github.com/llvm/llvm-project/pull/221676
>From 01b1b433f611f83be93cccc6fc0e761f4e99b2dd Mon Sep 17 00:00:00 2001
From: vikhegde <vikram.hegde at amd.com>
Date: Mon, 7 Sep 2026 11:04:55 +0530
Subject: [PATCH] [CodeGen][NPM] Port MachinePipeliner to NPM
---
llvm/include/llvm/CodeGen/MachinePipeliner.h | 46 +++++--
llvm/include/llvm/InitializePasses.h | 2 +-
.../llvm/Passes/MachinePassRegistry.def | 1 +
llvm/lib/CodeGen/CodeGen.cpp | 2 +-
llvm/lib/CodeGen/MachinePipeliner.cpp | 126 +++++++++++++-----
llvm/lib/Passes/CodeGenPassBuilder.cpp | 1 +
llvm/lib/Passes/PassBuilder.cpp | 1 +
.../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 3 +
.../AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir | 1 +
.../swp-amdgpu-pipeline-gen-structure.mir | 1 +
.../swp-amdgpu-pipeline-loop-carried-mem.mir | 1 +
11 files changed, 142 insertions(+), 43 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MachinePipeliner.h b/llvm/include/llvm/CodeGen/MachinePipeliner.h
index 7b2d1226530d3..191c77ef9a8d0 100644
--- a/llvm/include/llvm/CodeGen/MachinePipeliner.h
+++ b/llvm/include/llvm/CodeGen/MachinePipeliner.h
@@ -57,8 +57,10 @@
namespace llvm {
class AAResults;
+class LiveIntervals;
class NodeSet;
class SMSchedule;
+class TargetMachine;
extern LLVM_ABI cl::opt<bool> SwpEnableCopyToPhi;
extern LLVM_ABI cl::opt<int> SwpForceIssueWidth;
@@ -72,15 +74,19 @@ struct MachinePipelinerPolicy {
};
/// The main class in the implementation of the target independent
-/// software pipeliner pass.
-class LLVM_ABI MachinePipeliner : public MachineFunctionPass {
+/// software pipeliner pass. This is the worker shared between the legacy and
+/// new pass manager wrappers (MachinePipelinerLegacy and MachinePipelinerPass).
+class LLVM_ABI MachinePipeliner {
public:
MachineFunction *MF = nullptr;
MachineOptimizationRemarkEmitter *ORE = nullptr;
const MachineLoopInfo *MLI = nullptr;
const InstrItineraryData *InstrItins = nullptr;
const TargetInstrInfo *TII = nullptr;
- const RegisterClassInfo *RegClassInfo = nullptr;
+ RegisterClassInfo *RegClassInfo = nullptr;
+ LiveIntervals *LIS = nullptr;
+ AAResults *AA = nullptr;
+ const TargetMachine *TM = nullptr;
bool disabledByPragma = false;
unsigned II_setByPragma = 0;
@@ -100,13 +106,15 @@ class LLVM_ABI MachinePipeliner : public MachineFunctionPass {
};
LoopInfo LI;
- static char ID;
-
- MachinePipeliner() : MachineFunctionPass(ID) {}
+ MachinePipeliner(MachineFunction &MF, const MachineLoopInfo &MLI,
+ LiveIntervals &LIS, AAResults &AA,
+ MachineOptimizationRemarkEmitter &ORE,
+ RegisterClassInfo &RegClassInfo);
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override;
+ /// Run the software pipeliner over all loops in the function. Returns true if
+ /// the function was modified. The caller is responsible for checking that the
+ /// pipeliner is enabled for this function.
+ bool run();
private:
void preprocessPhiNodes(MachineBasicBlock &B);
@@ -119,6 +127,26 @@ class LLVM_ABI MachinePipeliner : public MachineFunctionPass {
bool useWindowScheduler(bool Changed);
};
+/// Legacy pass manager wrapper for the software pipeliner.
+class LLVM_ABI MachinePipelinerLegacy : public MachineFunctionPass {
+public:
+ static char ID;
+
+ MachinePipelinerLegacy() : MachineFunctionPass(ID) {}
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
+
+/// New pass manager wrapper for the software pipeliner.
+class LLVM_ABI MachinePipelinerPass
+ : public OptionalPassInfoMixin<MachinePipelinerPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
/// Represents a dependence between two instruction.
class SwingSchedulerDDGEdge {
SUnit *Dst = nullptr;
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 1fa4565bef193..1ba2f67d27e5d 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -215,7 +215,7 @@ initializeMachineOptimizationRemarkEmitterPassPass(PassRegistry &);
LLVM_ABI void initializeMachineOutlinerPass(PassRegistry &);
LLVM_ABI void initializeStaticDataProfileInfoWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeStaticDataAnnotatorLegacyPass(PassRegistry &);
-LLVM_ABI void initializeMachinePipelinerPass(PassRegistry &);
+LLVM_ABI void initializeMachinePipelinerLegacyPass(PassRegistry &);
LLVM_ABI void initializeMachinePostDominatorTreeWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeMachineRegionInfoPassPass(PassRegistry &);
LLVM_ABI void initializeMachineRegisterClassInfoWrapperPassPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 63c0fa4a65ffe..78253532a8570 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -104,6 +104,7 @@ MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass())
MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass())
MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass())
MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass())
+MACHINE_FUNCTION_PASS("pipeliner", MachinePipelinerPass())
MACHINE_FUNCTION_PASS("post-RA-hazard-rec", PostRAHazardRecognizerPass())
MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass(TM))
MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass())
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index c9f14737c392c..efa9bdc635c5f 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -102,7 +102,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeMachineModuleInfoWrapperPassPass(Registry);
initializeMachineOptimizationRemarkEmitterPassPass(Registry);
initializeMachineOutlinerPass(Registry);
- initializeMachinePipelinerPass(Registry);
+ initializeMachinePipelinerLegacyPass(Registry);
initializeMachineSanitizerBinaryMetadataLegacyPass(Registry);
initializeModuloScheduleTestPass(Registry);
initializeMachinePostDominatorTreeWrapperPassPass(Registry);
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index 8ce8351b2af46..f64d63065236c 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -56,6 +56,7 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/ModuloSchedule.h"
#include "llvm/CodeGen/Register.h"
@@ -226,19 +227,19 @@ static cl::opt<WindowSchedulingFlag> WindowSchedulingOption(
"Use window algorithm instead of SMS algorithm.")));
unsigned SwingSchedulerDAG::Circuits::MaxPaths = 5;
-char MachinePipeliner::ID = 0;
+char MachinePipelinerLegacy::ID = 0;
#ifndef NDEBUG
int MachinePipeliner::NumTries = 0;
#endif
-char &llvm::MachinePipelinerID = MachinePipeliner::ID;
+char &llvm::MachinePipelinerID = MachinePipelinerLegacy::ID;
-INITIALIZE_PASS_BEGIN(MachinePipeliner, DEBUG_TYPE,
+INITIALIZE_PASS_BEGIN(MachinePipelinerLegacy, DEBUG_TYPE,
"Modulo Software Pipelining", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
-INITIALIZE_PASS_END(MachinePipeliner, DEBUG_TYPE,
+INITIALIZE_PASS_END(MachinePipelinerLegacy, DEBUG_TYPE,
"Modulo Software Pipelining", false, false)
namespace {
@@ -359,38 +360,103 @@ class LoopCarriedOrderDepsTracker {
} // end anonymous namespace
+MachinePipeliner::MachinePipeliner(MachineFunction &MF,
+ const MachineLoopInfo &MLI,
+ LiveIntervals &LIS, AAResults &AA,
+ MachineOptimizationRemarkEmitter &ORE,
+ RegisterClassInfo &RegClassInfo)
+ : MF(&MF), ORE(&ORE), MLI(&MLI), TII(MF.getSubtarget().getInstrInfo()),
+ RegClassInfo(&RegClassInfo), LIS(&LIS), AA(&AA), TM(&MF.getTarget()) {}
+
/// The "main" function for implementing Swing Modulo Scheduling.
-bool MachinePipeliner::runOnMachineFunction(MachineFunction &mf) {
- if (skipFunction(mf.getFunction()))
- return false;
+bool MachinePipeliner::run() {
+ bool Changed = false;
+ for (const auto &L : *MLI)
+ Changed |= scheduleLoop(*L);
+
+ return Changed;
+}
+/// Shared entry point for both pass manager wrappers. The analyses are passed
+/// in as callbacks so that they are only requested once the pipeliner is known
+/// to run on \p MF.
+static bool runMachinePipeliner(
+ MachineFunction &MF, function_ref<const MachineLoopInfo &()> GetMLI,
+ function_ref<LiveIntervals &()> GetLIS, function_ref<AAResults &()> GetAA,
+ function_ref<MachineOptimizationRemarkEmitter &()> GetORE,
+ function_ref<RegisterClassInfo &()> GetRCI) {
if (!EnableSWP)
return false;
- if (mf.getFunction().getAttributes().hasFnAttr(Attribute::OptimizeForSize) &&
+ if (MF.getFunction().getAttributes().hasFnAttr(Attribute::OptimizeForSize) &&
!EnableSWPOptSize.getPosition())
return false;
- if (!mf.getSubtarget().enableMachinePipeliner())
+ if (!MF.getSubtarget().enableMachinePipeliner())
return false;
// Cannot pipeline loops without instruction itineraries if we are using
// DFA for the pipeliner.
- if (mf.getSubtarget().useDFAforSMS() &&
- (!mf.getSubtarget().getInstrItineraryData() ||
- mf.getSubtarget().getInstrItineraryData()->isEmpty()))
+ if (MF.getSubtarget().useDFAforSMS() &&
+ (!MF.getSubtarget().getInstrItineraryData() ||
+ MF.getSubtarget().getInstrItineraryData()->isEmpty()))
return false;
- MF = &mf;
- MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
- ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
- RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
- TII = MF->getSubtarget().getInstrInfo();
+ MachinePipeliner MP(MF, GetMLI(), GetLIS(), GetAA(), GetORE(), GetRCI());
+ return MP.run();
+}
- for (const auto &L : *MLI)
- scheduleLoop(*L);
+bool MachinePipelinerLegacy::runOnMachineFunction(MachineFunction &MF) {
+ if (skipFunction(MF.getFunction()))
+ return false;
- return false;
+ return runMachinePipeliner(
+ MF,
+ [&]() -> const MachineLoopInfo & {
+ return getAnalysis<MachineLoopInfoWrapperPass>().getLI();
+ },
+ [&]() -> LiveIntervals & {
+ return getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+ },
+ [&]() -> AAResults & {
+ return getAnalysis<AAResultsWrapperPass>().getAAResults();
+ },
+ [&]() -> MachineOptimizationRemarkEmitter & {
+ return getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
+ },
+ [&]() -> RegisterClassInfo & {
+ return getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
+ });
+}
+
+PreservedAnalyses
+MachinePipelinerPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ if (!runMachinePipeliner(
+ MF,
+ [&]() -> const MachineLoopInfo & {
+ return MFAM.getResult<MachineLoopAnalysis>(MF);
+ },
+ [&]() -> LiveIntervals & {
+ return MFAM.getResult<LiveIntervalsAnalysis>(MF);
+ },
+ [&]() -> AAResults & {
+ return MFAM
+ .getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
+ .getManager()
+ .getResult<AAManager>(MF.getFunction());
+ },
+ [&]() -> MachineOptimizationRemarkEmitter & {
+ return MFAM.getResult<MachineOptimizationRemarkEmitterAnalysis>(MF);
+ },
+ [&]() -> RegisterClassInfo & {
+ return MFAM.getResult<MachineRegisterClassAnalysis>(MF);
+ }))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+ PA.preserve<MachineRegisterClassAnalysis>();
+ return PA;
}
/// Attempt to perform the SMS algorithm on the specified loop. This function is
@@ -632,8 +698,7 @@ bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
void MachinePipeliner::preprocessPhiNodes(MachineBasicBlock &B) {
MachineRegisterInfo &MRI = MF->getRegInfo();
- SlotIndexes &Slots =
- *getAnalysis<LiveIntervalsWrapperPass>().getLIS().getSlotIndexes();
+ SlotIndexes &Slots = *LIS->getSlotIndexes();
for (MachineInstr &PI : B.phis()) {
MachineOperand &DefOp = PI.getOperand(0);
@@ -668,10 +733,8 @@ void MachinePipeliner::preprocessPhiNodes(MachineBasicBlock &B) {
bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
assert(L.getBlocks().size() == 1 && "SMS works on single blocks only.");
- AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- SwingSchedulerDAG SMS(
- *this, L, getAnalysis<LiveIntervalsWrapperPass>().getLIS(), *RegClassInfo,
- II_setByPragma, LI.LoopPipelinerInfo.get(), AA);
+ SwingSchedulerDAG SMS(*this, L, *LIS, *RegClassInfo, II_setByPragma,
+ LI.LoopPipelinerInfo.get(), AA);
MachineBasicBlock *MBB = L.getHeader();
// The kernel should not include any terminator instructions. These
@@ -694,7 +757,7 @@ bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
return SMS.hasNewSchedule();
}
-void MachinePipeliner::getAnalysisUsage(AnalysisUsage &AU) const {
+void MachinePipelinerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>();
AU.addPreserved<AAResultsWrapperPass>();
AU.addRequired<MachineLoopInfoWrapperPass>();
@@ -710,11 +773,10 @@ bool MachinePipeliner::runWindowScheduler(MachineLoop &L) {
MachineSchedContext Context;
Context.MF = MF;
Context.MLI = MLI;
- Context.TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
- Context.AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- Context.LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
- Context.RegClassInfo =
- &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
+ Context.TM = TM;
+ Context.AA = AA;
+ Context.LIS = LIS;
+ Context.RegClassInfo = RegClassInfo;
WindowScheduler WS(&Context, L);
return WS.run();
}
diff --git a/llvm/lib/Passes/CodeGenPassBuilder.cpp b/llvm/lib/Passes/CodeGenPassBuilder.cpp
index 63e161965820e..0a4ec9d3033a8 100644
--- a/llvm/lib/Passes/CodeGenPassBuilder.cpp
+++ b/llvm/lib/Passes/CodeGenPassBuilder.cpp
@@ -55,6 +55,7 @@
#include "llvm/CodeGen/MachineLateInstrsCleanup.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachinePipeliner.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/MachineSink.h"
#include "llvm/CodeGen/MachineVerifier.h"
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 81420f2ab885d..725ce2d589a31 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -151,6 +151,7 @@
#include "llvm/CodeGen/MachineLICM.h"
#include "llvm/CodeGen/MachineLateInstrsCleanup.h"
#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachinePipeliner.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegionInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 24e1bb7f86603..192b09942b7b5 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -87,6 +87,7 @@
#include "llvm/CodeGen/MIRParser/MIParser.h"
#include "llvm/CodeGen/MachineCSE.h"
#include "llvm/CodeGen/MachineLICM.h"
+#include "llvm/CodeGen/MachinePipeliner.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/PHIElimination.h"
#include "llvm/CodeGen/Passes.h"
@@ -2648,6 +2649,8 @@ Error AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(PassManagerWrapper &PMW) {
void AMDGPUCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
if (getOptLevel() != CodeGenOptLevel::None)
addMachineFunctionPass(AMDGPUPrepareAGPRAllocPass(), PMW);
+ if (getOptLevel() >= CodeGenOptLevel::Default && EnableMachinePipeliner)
+ addMachineFunctionPass(MachinePipelinerPass(), PMW);
}
Expected<bool> AMDGPUCodeGenPassBuilder::addRegAssignAndRewriteOptimized(
diff --git a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir
index 1c1590eeb9822..56b37b6286da4 100644
--- a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir
+++ b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -pipeliner-force-ii=12 %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -passes=pipeliner -pipeliner-force-ii=12 %s -o - | FileCheck %s
# Two independent recurrences (a sum and a product) must be carried across the stage
# boundary without being swapped: each accumulator's kernel result has to flow through
# its own epilog PHI and drain op into its own store.
diff --git a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir
index 7bad3042e571a..f2aae2e57fcaf 100644
--- a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir
+++ b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir
@@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -pipeliner-force-ii=8 %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -passes=pipeliner -pipeliner-force-ii=8 %s -o - | FileCheck %s
# Verify the generated prolog / steady-state kernel / epilog structure of a pipelined loop.
# CHECK-LABEL: name: swp_amdgpu_pipeline_gen_structure
diff --git a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir
index 9dc50350a8d6c..bb39f0339e6d8 100644
--- a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir
+++ b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir
@@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -debug-only=pipeliner %s -filetype=null 2>&1 | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -passes=pipeliner -debug-only=pipeliner %s -filetype=null 2>&1 | FileCheck %s
# REQUIRES: asserts
# A loop that loads a[i] and stores a[i+1] must get a loop-carried memory dependence
# between the load and the store, so they are not reordered across iterations.
More information about the llvm-commits
mailing list