CodeGen][NewPM] Port PostRAScheduler to NPM. (#125798)

This commit is contained in:
Christudasan Devadasan 2025-02-05 12:45:59 +05:30 committed by GitHub
parent 16c721f2d1
commit 44f638f88e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 194 additions and 110 deletions

View File

@ -0,0 +1,32 @@
//===- llvm/CodeGen/PostRASchedulerList.h ------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_POSTRASCHEDULERLIST_H
#define LLVM_CODEGEN_POSTRASCHEDULERLIST_H
#include "llvm/CodeGen/MachinePassManager.h"
namespace llvm {
class PostRASchedulerPass : public PassInfoMixin<PostRASchedulerPass> {
const TargetMachine *TM;
public:
PostRASchedulerPass(const TargetMachine *TM) : TM(TM) {}
PreservedAnalyses run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM);
MachineFunctionProperties getRequiredProperties() const {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs);
}
};
} // namespace llvm
#endif // LLVM_CODEGEN_POSTRASCHEDULERLIST_H

View File

@ -241,7 +241,7 @@ void initializePostInlineEntryExitInstrumenterPass(PassRegistry &);
void initializePostMachineSchedulerLegacyPass(PassRegistry &);
void initializePostRAHazardRecognizerPass(PassRegistry &);
void initializePostRAMachineSinkingPass(PassRegistry &);
void initializePostRASchedulerPass(PassRegistry &);
void initializePostRASchedulerLegacyPass(PassRegistry &);
void initializePreISelIntrinsicLoweringLegacyPassPass(PassRegistry &);
void initializePrintFunctionPassWrapperPass(PassRegistry &);
void initializePrintModulePassWrapperPass(PassRegistry &);

View File

@ -55,6 +55,7 @@
#include "llvm/CodeGen/OptimizePHIs.h"
#include "llvm/CodeGen/PHIElimination.h"
#include "llvm/CodeGen/PeepholeOptimizer.h"
#include "llvm/CodeGen/PostRASchedulerList.h"
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
#include "llvm/CodeGen/RegAllocFast.h"
#include "llvm/CodeGen/RegUsageInfoCollector.h"
@ -960,7 +961,7 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
if (Opt.MISchedPostRA)
addPass(PostMachineSchedulerPass(&TM));
else
addPass(PostRASchedulerPass());
addPass(PostRASchedulerPass(&TM));
}
// GC

View File

@ -149,6 +149,7 @@ MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass())
MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass())
MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass())
MACHINE_FUNCTION_PASS("postmisched", PostMachineSchedulerPass(TM))
MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass(TM))
MACHINE_FUNCTION_PASS("print", PrintMIRPass())
MACHINE_FUNCTION_PASS("print<livedebugvars>", LiveDebugVariablesPrinterPass(errs()))
MACHINE_FUNCTION_PASS("print<live-intervals>", LiveIntervalsPrinterPass(errs()))
@ -247,7 +248,6 @@ DUMMY_MACHINE_FUNCTION_PASS("machine-uniformity", MachineUniformityInfoWrapperPa
DUMMY_MACHINE_FUNCTION_PASS("machineinstr-printer", MachineFunctionPrinterPass)
DUMMY_MACHINE_FUNCTION_PASS("mirfs-discriminators", MIRAddFSDiscriminatorsPass)
DUMMY_MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass)
DUMMY_MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass)
DUMMY_MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass)
DUMMY_MACHINE_FUNCTION_PASS("postrapseudos", ExpandPostRAPseudosPass)
DUMMY_MACHINE_FUNCTION_PASS("print-machine-cycles", MachineCycleInfoPrinterPass)

View File

@ -108,7 +108,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializePostMachineSchedulerLegacyPass(Registry);
initializePostRAHazardRecognizerPass(Registry);
initializePostRAMachineSinkingPass(Registry);
initializePostRASchedulerPass(Registry);
initializePostRASchedulerLegacyPass(Registry);
initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
initializeProcessImplicitDefsPass(Registry);
initializeRABasicPass(Registry);

View File

@ -17,6 +17,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/PostRASchedulerList.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/AntiDepBreaker.h"
@ -39,6 +40,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
#define DEBUG_TYPE "post-RA-sched"
@ -73,124 +75,134 @@ DebugMod("postra-sched-debugmod",
AntiDepBreaker::~AntiDepBreaker() = default;
namespace {
class PostRAScheduler : public MachineFunctionPass {
const TargetInstrInfo *TII = nullptr;
RegisterClassInfo RegClassInfo;
class PostRAScheduler {
const TargetInstrInfo *TII = nullptr;
MachineLoopInfo *MLI = nullptr;
AliasAnalysis *AA = nullptr;
const TargetMachine *TM = nullptr;
RegisterClassInfo RegClassInfo;
public:
static char ID;
PostRAScheduler() : MachineFunctionPass(ID) {}
public:
PostRAScheduler(MachineFunction &MF, MachineLoopInfo *MLI, AliasAnalysis *AA,
const TargetMachine *TM)
: TII(MF.getSubtarget().getInstrInfo()), MLI(MLI), AA(AA), TM(TM) {}
bool run(MachineFunction &MF);
};
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachineLoopInfoWrapperPass>();
AU.addPreserved<MachineLoopInfoWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
class PostRASchedulerLegacy : public MachineFunctionPass {
public:
static char ID;
PostRASchedulerLegacy() : MachineFunctionPass(ID) {}
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachineLoopInfoWrapperPass>();
AU.addPreserved<MachineLoopInfoWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &Fn) override;
};
char PostRAScheduler::ID = 0;
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs);
}
class SchedulePostRATDList : public ScheduleDAGInstrs {
/// AvailableQueue - The priority queue to use for the available SUnits.
///
LatencyPriorityQueue AvailableQueue;
bool runOnMachineFunction(MachineFunction &Fn) override;
};
char PostRASchedulerLegacy::ID = 0;
/// PendingQueue - This contains all of the instructions whose operands have
/// been issued, but their results are not ready yet (due to the latency of
/// the operation). Once the operands becomes available, the instruction is
/// added to the AvailableQueue.
std::vector<SUnit*> PendingQueue;
class SchedulePostRATDList : public ScheduleDAGInstrs {
/// AvailableQueue - The priority queue to use for the available SUnits.
///
LatencyPriorityQueue AvailableQueue;
/// HazardRec - The hazard recognizer to use.
ScheduleHazardRecognizer *HazardRec;
/// PendingQueue - This contains all of the instructions whose operands have
/// been issued, but their results are not ready yet (due to the latency of
/// the operation). Once the operands becomes available, the instruction is
/// added to the AvailableQueue.
std::vector<SUnit *> PendingQueue;
/// AntiDepBreak - Anti-dependence breaking object, or NULL if none
AntiDepBreaker *AntiDepBreak;
/// HazardRec - The hazard recognizer to use.
ScheduleHazardRecognizer *HazardRec;
/// AA - AliasAnalysis for making memory reference queries.
AliasAnalysis *AA;
/// AntiDepBreak - Anti-dependence breaking object, or NULL if none
AntiDepBreaker *AntiDepBreak;
/// The schedule. Null SUnit*'s represent noop instructions.
std::vector<SUnit*> Sequence;
/// AA - AliasAnalysis for making memory reference queries.
AliasAnalysis *AA;
/// Ordered list of DAG postprocessing steps.
std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
/// The schedule. Null SUnit*'s represent noop instructions.
std::vector<SUnit *> Sequence;
/// The index in BB of RegionEnd.
///
/// This is the instruction number from the top of the current block, not
/// the SlotIndex. It is only used by the AntiDepBreaker.
unsigned EndIndex = 0;
/// Ordered list of DAG postprocessing steps.
std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
public:
SchedulePostRATDList(
MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA,
const RegisterClassInfo &,
TargetSubtargetInfo::AntiDepBreakMode AntiDepMode,
SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs);
/// The index in BB of RegionEnd.
///
/// This is the instruction number from the top of the current block, not
/// the SlotIndex. It is only used by the AntiDepBreaker.
unsigned EndIndex = 0;
~SchedulePostRATDList() override;
public:
SchedulePostRATDList(
MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA,
const RegisterClassInfo &,
TargetSubtargetInfo::AntiDepBreakMode AntiDepMode,
SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs);
/// startBlock - Initialize register live-range state for scheduling in
/// this block.
///
void startBlock(MachineBasicBlock *BB) override;
~SchedulePostRATDList() override;
// Set the index of RegionEnd within the current BB.
void setEndIndex(unsigned EndIdx) { EndIndex = EndIdx; }
/// startBlock - Initialize register live-range state for scheduling in
/// this block.
///
void startBlock(MachineBasicBlock *BB) override;
/// Initialize the scheduler state for the next scheduling region.
void enterRegion(MachineBasicBlock *bb,
MachineBasicBlock::iterator begin,
MachineBasicBlock::iterator end,
unsigned regioninstrs) override;
// Set the index of RegionEnd within the current BB.
void setEndIndex(unsigned EndIdx) { EndIndex = EndIdx; }
/// Notify that the scheduler has finished scheduling the current region.
void exitRegion() override;
/// Initialize the scheduler state for the next scheduling region.
void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin,
MachineBasicBlock::iterator end,
unsigned regioninstrs) override;
/// Schedule - Schedule the instruction range using list scheduling.
///
void schedule() override;
/// Notify that the scheduler has finished scheduling the current region.
void exitRegion() override;
void EmitSchedule();
/// Schedule - Schedule the instruction range using list scheduling.
///
void schedule() override;
/// Observe - Update liveness information to account for the current
/// instruction, which will not be scheduled.
///
void Observe(MachineInstr &MI, unsigned Count);
void EmitSchedule();
/// finishBlock - Clean up register live-range state.
///
void finishBlock() override;
/// Observe - Update liveness information to account for the current
/// instruction, which will not be scheduled.
///
void Observe(MachineInstr &MI, unsigned Count);
private:
/// Apply each ScheduleDAGMutation step in order.
void postProcessDAG();
/// finishBlock - Clean up register live-range state.
///
void finishBlock() override;
void ReleaseSucc(SUnit *SU, SDep *SuccEdge);
void ReleaseSuccessors(SUnit *SU);
void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
void ListScheduleTopDown();
private:
/// Apply each ScheduleDAGMutation step in order.
void postProcessDAG();
void dumpSchedule() const;
void emitNoop(unsigned CurCycle);
};
}
void ReleaseSucc(SUnit *SU, SDep *SuccEdge);
void ReleaseSuccessors(SUnit *SU);
void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
void ListScheduleTopDown();
char &llvm::PostRASchedulerID = PostRAScheduler::ID;
void dumpSchedule() const;
void emitNoop(unsigned CurCycle);
};
} // namespace
INITIALIZE_PASS(PostRAScheduler, DEBUG_TYPE,
char &llvm::PostRASchedulerID = PostRASchedulerLegacy::ID;
INITIALIZE_PASS(PostRASchedulerLegacy, DEBUG_TYPE,
"Post RA top-down list latency scheduler", false, false)
SchedulePostRATDList::SchedulePostRATDList(
@ -263,19 +275,12 @@ static bool enablePostRAScheduler(const TargetSubtargetInfo &ST,
OptLevel >= ST.getOptLevelToEnablePostRAScheduler();
}
bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
if (skipFunction(Fn.getFunction()))
return false;
const auto &Subtarget = Fn.getSubtarget();
TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>();
bool PostRAScheduler::run(MachineFunction &MF) {
const auto &Subtarget = MF.getSubtarget();
// Check that post-RA scheduling is enabled for this target.
if (!enablePostRAScheduler(Subtarget, PassConfig->getOptLevel()))
if (!enablePostRAScheduler(Subtarget, TM->getOptLevel()))
return false;
TII = Subtarget.getInstrInfo();
MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
TargetSubtargetInfo::AntiDepBreakMode AntiDepMode =
Subtarget.getAntiDepBreakMode();
if (EnableAntiDepBreaking.getPosition() > 0) {
@ -287,22 +292,22 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
}
SmallVector<const TargetRegisterClass *, 4> CriticalPathRCs;
Subtarget.getCriticalPathRCs(CriticalPathRCs);
RegClassInfo.runOnMachineFunction(Fn);
RegClassInfo.runOnMachineFunction(MF);
LLVM_DEBUG(dbgs() << "PostRAScheduler\n");
SchedulePostRATDList Scheduler(Fn, MLI, AA, RegClassInfo, AntiDepMode,
SchedulePostRATDList Scheduler(MF, *MLI, AA, RegClassInfo, AntiDepMode,
CriticalPathRCs);
// Loop over all of the basic blocks
for (auto &MBB : Fn) {
for (auto &MBB : MF) {
#ifndef NDEBUG
// If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod
if (DebugDiv > 0) {
static int bbcnt = 0;
if (bbcnt++ % DebugDiv != DebugMod)
continue;
dbgs() << "*** DEBUG scheduling " << Fn.getName() << ":"
dbgs() << "*** DEBUG scheduling " << MF.getName() << ":"
<< printMBBReference(MBB) << " ***\n";
}
#endif
@ -320,7 +325,7 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
// Calls are not scheduling boundaries before register allocation, but
// post-ra we don't gain anything by scheduling across calls since we
// don't need to worry about register pressure.
if (MI.isCall() || TII->isSchedulingBoundary(MI, &MBB, Fn)) {
if (MI.isCall() || TII->isSchedulingBoundary(MI, &MBB, MF)) {
Scheduler.enterRegion(&MBB, I, Current, CurrentCount - Count);
Scheduler.setEndIndex(CurrentCount);
Scheduler.schedule();
@ -353,6 +358,39 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
return true;
}
bool PostRASchedulerLegacy::runOnMachineFunction(MachineFunction &MF) {
if (skipFunction(MF.getFunction()))
return false;
MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
const TargetMachine *TM =
&getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
PostRAScheduler Impl(MF, MLI, AA, TM);
return Impl.run(MF);
}
PreservedAnalyses
PostRASchedulerPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
MFPropsModifier _(*this, MF);
MachineLoopInfo *MLI = &MFAM.getResult<MachineLoopAnalysis>(MF);
auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
.getManager();
AliasAnalysis *AA = &FAM.getResult<AAManager>(MF.getFunction());
PostRAScheduler Impl(MF, MLI, AA, TM);
bool Changed = Impl.run(MF);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
PA.preserveSet<CFGAnalyses>();
PA.preserve<MachineDominatorTreeAnalysis>();
PA.preserve<MachineLoopAnalysis>();
return PA;
}
/// StartBlock - Initialize register live-range state for scheduling in
/// this block.
///

View File

@ -125,6 +125,7 @@
#include "llvm/CodeGen/OptimizePHIs.h"
#include "llvm/CodeGen/PHIElimination.h"
#include "llvm/CodeGen/PeepholeOptimizer.h"
#include "llvm/CodeGen/PostRASchedulerList.h"
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
#include "llvm/CodeGen/RegAllocFast.h"
#include "llvm/CodeGen/RegUsageInfoCollector.h"

View File

@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -run-pass=post-RA-sched %s -o - | FileCheck -check-prefix=GCN %s
# RUN: llc -mtriple=amdgcn -mcpu=gfx900 -passes=post-RA-sched %s -o - | FileCheck -check-prefix=GCN %s
# Check that we move consumer further from producer, even if one of them is in a bundle.

View File

@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgcn -mcpu=tonga -mattr=-xnack -run-pass post-RA-sched -verify-machineinstrs -o - %s | FileCheck -check-prefix=GCN %s
# RUN: llc -mtriple=amdgcn -mcpu=tonga -mattr=-xnack -passes=post-RA-sched -o - %s | FileCheck -check-prefix=GCN %s
# GCN: FLAT_LOAD_DWORD
# GCN-NEXT: FLAT_LOAD_DWORD

View File

@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -run-pass post-RA-sched %s -o - | FileCheck -check-prefix=GFX90 %s
# RUN: llc -mtriple=amdgcn -mcpu=gfx900 -passes=post-RA-sched %s -o - | FileCheck -check-prefix=GFX90 %s
# This tests that a KILL isn't considered as a valid instruction for a hazard
# slot (e.g. m0 def followed by V_INTERP for gfx9)

View File

@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -verify-machineinstrs -run-pass=post-RA-sched -o - %s | FileCheck %s
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -passes=post-RA-sched -o - %s | FileCheck %s
# Make sure ScheduleDAGInstrs::fixupKills does not produce invalid kill flags.
---
name: func0

View File

@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgcn -verify-machineinstrs -run-pass post-RA-sched %s -o - | FileCheck %s
# RUN: llc -mtriple=amdgcn -passes=post-RA-sched %s -o - | FileCheck %s
# This tests a situation where a sub-register of a killed super-register operand
# of V_MOVRELS happens to have an undef use later on. This leads to the post RA

View File

@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -run-pass=post-RA-sched -verify-machineinstrs -o - %s | FileCheck %s
# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -passes=post-RA-sched -o - %s | FileCheck %s
# The scheduler was not inspecting the first instruction in the bundle
# when adding kill flags, so it would incorrectly mark the first use

View File

@ -1,4 +1,5 @@
# RUN: llc -run-pass=post-RA-sched %s -o - | FileCheck %s
# RUN: llc -passes=post-RA-sched %s -o - | FileCheck %s
# CHECK: VLDMDIA
--- |
target triple = "thumbv7-w64-windows-gnu"

View File

@ -1,4 +1,5 @@
# RUN: llc -mtriple=hexagon -run-pass post-RA-sched %s -o - | FileCheck %s
# RUN: llc -mtriple=hexagon -passes=post-RA-sched %s -o - | FileCheck %s
# The two loads from %a ($r0) can cause a bank conflict. Check that they
# are not scheduled next to each other.

View File

@ -1,4 +1,5 @@
# RUN: llc -mtriple=hexagon -run-pass post-RA-sched %s -o - | FileCheck %s
# RUN: llc -mtriple=hexagon -passes=post-RA-sched %s -o - | FileCheck %s
# Test that the Post RA scheduler does not schedule back-to-back loads
# when there is another instruction to schedule. The scheduler avoids

View File

@ -1,5 +1,7 @@
# RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=btver2 -run-pass=post-RA-sched -o - %s | FileCheck %s
# RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=btver2 -passes=post-RA-sched -o - %s | FileCheck %s
# RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=btver2 -run-pass=post-RA-sched -o - %s -experimental-debug-variable-locations| FileCheck %s
# RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=btver2 -passes=post-RA-sched -o - %s -experimental-debug-variable-locations| FileCheck %s
# Test that multiple DBG_VALUE's and DBG_PHIs following an instruction whose
# register needs # to be changed during the post-RA scheduler pass are updated

View File

@ -1,4 +1,5 @@
# RUN: llc -mtriple=i386-unknown-linux-gnu -mcpu=slm -run-pass post-RA-sched -o - %s | FileCheck %s
# RUN: llc -mtriple=i386-unknown-linux-gnu -mcpu=slm -passes=post-RA-sched -o - %s | FileCheck %s
#
# Verify that the critical antidependence breaker does not consider
# a high byte register as available as a replacement register