mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
Split the SimplifyCFG pass into two variants.
The first variant contains all current transformations except transforming switches into lookup tables. The second variant contains all current transformations. The switch-to-lookup-table conversion results in code that is more difficult to analyze and optimize by other passes. Most importantly, it can inhibit Dead Code Elimination. As such it is often beneficial to only apply this transformation very late. A common example is inlining, which can often result in range restrictions for the switch expression. Changes in execution time according to LNT: SingleSource/Benchmarks/Misc/fp-convert +3.03% MultiSource/Benchmarks/ASC_Sequoia/CrystalMk/CrystalMk -11.20% MultiSource/Benchmarks/Olden/perimeter/perimeter -10.43% and a couple of smaller changes. For perimeter it also results 2.6% a smaller binary. Differential Revision: https://reviews.llvm.org/D30333 llvm-svn: 298799
This commit is contained in:
parent
c792ac0d08
commit
a1971791a7
@ -44,6 +44,9 @@ void LLVMAddAlignmentFromAssumptionsPass(LLVMPassManagerRef PM);
|
||||
/** See llvm::createCFGSimplificationPass function. */
|
||||
void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createLateCFGSimplificationPass function. */
|
||||
void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createDeadStoreEliminationPass function. */
|
||||
void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);
|
||||
|
||||
|
@ -86,6 +86,7 @@ void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry&);
|
||||
void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&);
|
||||
void initializeCFGPrinterLegacyPassPass(PassRegistry&);
|
||||
void initializeCFGSimplifyPassPass(PassRegistry&);
|
||||
void initializeLateCFGSimplifyPassPass(PassRegistry&);
|
||||
void initializeCFGViewerLegacyPassPass(PassRegistry&);
|
||||
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
|
||||
void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
|
||||
|
@ -75,6 +75,7 @@ namespace {
|
||||
(void) llvm::createCallGraphDOTPrinterPass();
|
||||
(void) llvm::createCallGraphViewerPass();
|
||||
(void) llvm::createCFGSimplificationPass();
|
||||
(void) llvm::createLateCFGSimplificationPass();
|
||||
(void) llvm::createCFLAndersAAWrapperPass();
|
||||
(void) llvm::createCFLSteensAAWrapperPass();
|
||||
(void) llvm::createStructurizeCFGPass();
|
||||
|
@ -260,6 +260,14 @@ FunctionPass *createJumpThreadingPass(int Threshold = -1);
|
||||
FunctionPass *createCFGSimplificationPass(
|
||||
int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LateCFGSimplification - Like CFGSimplification, but may also
|
||||
// convert switches to lookup tables.
|
||||
//
|
||||
FunctionPass *createLateCFGSimplificationPass(
|
||||
int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// FlattenCFG - flatten CFG, reduce number of conditional branches by using
|
||||
|
@ -27,13 +27,16 @@ namespace llvm {
|
||||
/// by the rest of the mid-level optimizer.
|
||||
class SimplifyCFGPass : public PassInfoMixin<SimplifyCFGPass> {
|
||||
int BonusInstThreshold;
|
||||
bool LateSimplifyCFG;
|
||||
|
||||
public:
|
||||
/// \brief Construct a pass with the default thresholds.
|
||||
/// \brief Construct a pass with the default thresholds
|
||||
/// and switch optimizations.
|
||||
SimplifyCFGPass();
|
||||
|
||||
/// \brief Construct a pass with a specific bonus threshold.
|
||||
SimplifyCFGPass(int BonusInstThreshold);
|
||||
/// \brief Construct a pass with a specific bonus threshold
|
||||
/// and optional switch optimizations.
|
||||
SimplifyCFGPass(int BonusInstThreshold, bool LateSimplifyCFG);
|
||||
|
||||
/// \brief Run the pass over the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
@ -142,7 +142,8 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
|
||||
/// eliminate.
|
||||
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||
unsigned BonusInstThreshold, AssumptionCache *AC = nullptr,
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr,
|
||||
bool LateSimplifyCFG = false);
|
||||
|
||||
/// This function is used to flatten a CFG. For example, it uses parallel-and
|
||||
/// and parallel-or mode to collapse if-conditions and merge if-regions with
|
||||
|
@ -141,6 +141,7 @@ void LTOCodeGenerator::initializeLTOPasses() {
|
||||
initializeMemCpyOptLegacyPassPass(R);
|
||||
initializeDCELegacyPassPass(R);
|
||||
initializeCFGSimplifyPassPass(R);
|
||||
initializeLateCFGSimplifyPassPass(R);
|
||||
}
|
||||
|
||||
void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
|
||||
|
@ -631,7 +631,7 @@ void PassManagerBuilder::populateModulePassManager(
|
||||
}
|
||||
|
||||
addExtensionsToPM(EP_Peephole, MPM);
|
||||
MPM.add(createCFGSimplificationPass());
|
||||
MPM.add(createLateCFGSimplificationPass()); // Switches to lookup tables
|
||||
addInstructionCombiningPass(MPM);
|
||||
|
||||
if (!DisableUnrollLoops) {
|
||||
|
@ -81,6 +81,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
|
||||
initializeIPSCCPLegacyPassPass(Registry);
|
||||
initializeSROALegacyPassPass(Registry);
|
||||
initializeCFGSimplifyPassPass(Registry);
|
||||
initializeLateCFGSimplifyPassPass(Registry);
|
||||
initializeStructurizeCFGPass(Registry);
|
||||
initializeSinkingLegacyPassPass(Registry);
|
||||
initializeTailCallElimPass(Registry);
|
||||
@ -117,6 +118,10 @@ void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM) {
|
||||
unwrap(PM)->add(createCFGSimplificationPass());
|
||||
}
|
||||
|
||||
void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM) {
|
||||
unwrap(PM)->add(createLateCFGSimplificationPass());
|
||||
}
|
||||
|
||||
void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM) {
|
||||
unwrap(PM)->add(createDeadStoreEliminationPass());
|
||||
}
|
||||
|
@ -130,7 +130,8 @@ static bool mergeEmptyReturnBlocks(Function &F) {
|
||||
/// iterating until no more changes are made.
|
||||
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
AssumptionCache *AC,
|
||||
unsigned BonusInstThreshold) {
|
||||
unsigned BonusInstThreshold,
|
||||
bool LateSimplifyCFG) {
|
||||
bool Changed = false;
|
||||
bool LocalChange = true;
|
||||
|
||||
@ -145,7 +146,7 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
|
||||
// Loop over all of the basic blocks and remove them if they are unneeded.
|
||||
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
|
||||
if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC, &LoopHeaders)) {
|
||||
if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC, &LoopHeaders, LateSimplifyCFG)) {
|
||||
LocalChange = true;
|
||||
++NumSimpl;
|
||||
}
|
||||
@ -156,10 +157,12 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
}
|
||||
|
||||
static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
AssumptionCache *AC, int BonusInstThreshold) {
|
||||
AssumptionCache *AC, int BonusInstThreshold,
|
||||
bool LateSimplifyCFG) {
|
||||
bool EverChanged = removeUnreachableBlocks(F);
|
||||
EverChanged |= mergeEmptyReturnBlocks(F);
|
||||
EverChanged |= iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold);
|
||||
EverChanged |= iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold,
|
||||
LateSimplifyCFG);
|
||||
|
||||
// If neither pass changed anything, we're done.
|
||||
if (!EverChanged) return false;
|
||||
@ -173,7 +176,8 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
return true;
|
||||
|
||||
do {
|
||||
EverChanged = iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold);
|
||||
EverChanged = iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold,
|
||||
LateSimplifyCFG);
|
||||
EverChanged |= removeUnreachableBlocks(F);
|
||||
} while (EverChanged);
|
||||
|
||||
@ -181,17 +185,19 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
}
|
||||
|
||||
SimplifyCFGPass::SimplifyCFGPass()
|
||||
: BonusInstThreshold(UserBonusInstThreshold) {}
|
||||
: BonusInstThreshold(UserBonusInstThreshold),
|
||||
LateSimplifyCFG(true) {}
|
||||
|
||||
SimplifyCFGPass::SimplifyCFGPass(int BonusInstThreshold)
|
||||
: BonusInstThreshold(BonusInstThreshold) {}
|
||||
SimplifyCFGPass::SimplifyCFGPass(int BonusInstThreshold, bool LateSimplifyCFG)
|
||||
: BonusInstThreshold(BonusInstThreshold),
|
||||
LateSimplifyCFG(LateSimplifyCFG) {}
|
||||
|
||||
PreservedAnalyses SimplifyCFGPass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
|
||||
if (!simplifyFunctionCFG(F, TTI, &AC, BonusInstThreshold))
|
||||
if (!simplifyFunctionCFG(F, TTI, &AC, BonusInstThreshold, LateSimplifyCFG))
|
||||
return PreservedAnalyses::all();
|
||||
PreservedAnalyses PA;
|
||||
PA.preserve<GlobalsAA>();
|
||||
@ -199,16 +205,17 @@ PreservedAnalyses SimplifyCFGPass::run(Function &F,
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct CFGSimplifyPass : public FunctionPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
struct BaseCFGSimplifyPass : public FunctionPass {
|
||||
unsigned BonusInstThreshold;
|
||||
std::function<bool(const Function &)> PredicateFtor;
|
||||
bool LateSimplifyCFG;
|
||||
|
||||
CFGSimplifyPass(int T = -1,
|
||||
std::function<bool(const Function &)> Ftor = nullptr)
|
||||
: FunctionPass(ID), PredicateFtor(std::move(Ftor)) {
|
||||
BaseCFGSimplifyPass(int T, bool LateSimplifyCFG,
|
||||
std::function<bool(const Function &)> Ftor,
|
||||
char &ID)
|
||||
: FunctionPass(ID), PredicateFtor(std::move(Ftor)),
|
||||
LateSimplifyCFG(LateSimplifyCFG) {
|
||||
BonusInstThreshold = (T == -1) ? UserBonusInstThreshold : unsigned(T);
|
||||
initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
|
||||
@ -218,7 +225,7 @@ struct CFGSimplifyPass : public FunctionPass {
|
||||
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
const TargetTransformInfo &TTI =
|
||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
return simplifyFunctionCFG(F, TTI, AC, BonusInstThreshold);
|
||||
return simplifyFunctionCFG(F, TTI, AC, BonusInstThreshold, LateSimplifyCFG);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
@ -227,6 +234,26 @@ struct CFGSimplifyPass : public FunctionPass {
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
}
|
||||
};
|
||||
|
||||
struct CFGSimplifyPass : public BaseCFGSimplifyPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
CFGSimplifyPass(int T = -1,
|
||||
std::function<bool(const Function &)> Ftor = nullptr)
|
||||
: BaseCFGSimplifyPass(T, false, Ftor, ID) {
|
||||
initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
};
|
||||
|
||||
struct LateCFGSimplifyPass : public BaseCFGSimplifyPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
LateCFGSimplifyPass(int T = -1,
|
||||
std::function<bool(const Function &)> Ftor = nullptr)
|
||||
: BaseCFGSimplifyPass(T, true, Ftor, ID) {
|
||||
initializeLateCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
char CFGSimplifyPass::ID = 0;
|
||||
@ -237,9 +264,24 @@ INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
|
||||
false)
|
||||
|
||||
char LateCFGSimplifyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LateCFGSimplifyPass, "latesimplifycfg",
|
||||
"Simplify the CFG more aggressively", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_END(LateCFGSimplifyPass, "latesimplifycfg",
|
||||
"Simplify the CFG more aggressively", false, false)
|
||||
|
||||
// Public interface to the CFGSimplification pass
|
||||
FunctionPass *
|
||||
llvm::createCFGSimplificationPass(int Threshold,
|
||||
std::function<bool(const Function &)> Ftor) {
|
||||
std::function<bool(const Function &)> Ftor) {
|
||||
return new CFGSimplifyPass(Threshold, std::move(Ftor));
|
||||
}
|
||||
|
||||
// Public interface to the LateCFGSimplification pass
|
||||
FunctionPass *
|
||||
llvm::createLateCFGSimplificationPass(int Threshold,
|
||||
std::function<bool(const Function &)> Ftor) {
|
||||
return new LateCFGSimplifyPass(Threshold, std::move(Ftor));
|
||||
}
|
||||
|
@ -170,6 +170,8 @@ class SimplifyCFGOpt {
|
||||
unsigned BonusInstThreshold;
|
||||
AssumptionCache *AC;
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
|
||||
// See comments in SimplifyCFGOpt::SimplifySwitch.
|
||||
bool LateSimplifyCFG;
|
||||
Value *isValueEqualityComparison(TerminatorInst *TI);
|
||||
BasicBlock *GetValueEqualityComparisonCases(
|
||||
TerminatorInst *TI, std::vector<ValueEqualityComparisonCase> &Cases);
|
||||
@ -193,9 +195,10 @@ class SimplifyCFGOpt {
|
||||
public:
|
||||
SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
|
||||
unsigned BonusInstThreshold, AssumptionCache *AC,
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders)
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders,
|
||||
bool LateSimplifyCFG)
|
||||
: TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold), AC(AC),
|
||||
LoopHeaders(LoopHeaders) {}
|
||||
LoopHeaders(LoopHeaders), LateSimplifyCFG(LateSimplifyCFG) {}
|
||||
|
||||
bool run(BasicBlock *BB);
|
||||
};
|
||||
@ -5562,7 +5565,12 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||
if (ForwardSwitchConditionToPHI(SI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
|
||||
if (SwitchToLookupTable(SI, Builder, DL, TTI))
|
||||
// The conversion from switch to lookup tables results in difficult
|
||||
// to analyze code and makes pruning branches much harder.
|
||||
// This is a problem of the switch expression itself can still be
|
||||
// restricted as a result of inlining or CVP. There only apply this
|
||||
// transformation during late steps of the optimisation chain.
|
||||
if (LateSimplifyCFG && SwitchToLookupTable(SI, Builder, DL, TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
|
||||
if (ReduceSwitchRange(SI, Builder, DL, TTI))
|
||||
@ -6021,8 +6029,9 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
|
||||
///
|
||||
bool llvm::SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||
unsigned BonusInstThreshold, AssumptionCache *AC,
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders,
|
||||
bool LateSimplifyCFG) {
|
||||
return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(),
|
||||
BonusInstThreshold, AC, LoopHeaders)
|
||||
BonusInstThreshold, AC, LoopHeaders, LateSimplifyCFG)
|
||||
.run(BB);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
||||
; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
||||
; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
||||
; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
||||
; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
||||
; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
||||
; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
||||
; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
||||
; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
||||
; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
||||
|
||||
; CHECK: @{{.*}} = private unnamed_addr constant [3 x i32] [i32 1234, i32 5678, i32 15532]
|
||||
; ENABLE: @{{.*}} = private unnamed_addr constant [3 x i32*] [i32* @c1, i32* @c2, i32* @c3]
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt -simplifycfg -S %s | FileCheck %s
|
||||
; RUN: opt -latesimplifycfg -S %s | FileCheck %s
|
||||
; rdar://15268442
|
||||
|
||||
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt -S -simplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||
; RUN: opt -S -latesimplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||
; rdar://17887153
|
||||
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-darwin12.0.0"
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt -S -simplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||
; RUN: opt -S -latesimplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||
; rdar://17735071
|
||||
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-darwin12.0.0"
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -simplifycfg -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
||||
; RUN: opt < %s -latesimplifycfg -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
@ -1178,8 +1178,9 @@ return:
|
||||
ret i32 %retval.0
|
||||
; CHECK-LABEL: @reuse_cmp2(
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
|
||||
; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %switch.tableidx, 4
|
||||
; CHECK-NEXT: %switch = icmp ult i32 %x, 4
|
||||
; CHECK-NEXT: %x. = select i1 %switch, i32 %x, i32 4
|
||||
; CHECK-NEXT: [[C:%.+]] = icmp ne i32 %x., 4
|
||||
; CHECK: [[R:%.+]] = select i1 [[C]], i32 {{.*}}, i32 100
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -simplifycfg -S | FileCheck %s
|
||||
; RUN: opt < %s -latesimplifycfg -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-n32"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user