llvm.org GIT mirror llvm / 72428f5
[SimplifyCFG] use pass options and remove the latesimplifycfg pass This is no-functional-change-intended. This is repackaging the functionality of D30333 (defer switch-to-lookup-tables) and D35411 (defer folding unconditional branches) with pass parameters rather than a named "latesimplifycfg" pass. Now that we have individual options to control the functionality, we could decouple when these fire (but that's an independent patch if desired). The next planned step would be to add another option bit to disable the sinking transform mentioned in D38566. This should also make it clear that the new pass manager needs to be updated to limit simplifycfg in the same way as the old pass manager. Differential Revision: https://reviews.llvm.org/D38631 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316835 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 1 year, 10 months ago
25 changed file(s) with 190 addition(s) and 140 deletion(s). Raw diff Collapse all Expand all
173173 void initializeJumpThreadingPass(PassRegistry&);
174174 void initializeLCSSAVerificationPassPass(PassRegistry&);
175175 void initializeLCSSAWrapperPassPass(PassRegistry&);
176 void initializeLateCFGSimplifyPassPass(PassRegistry&);
177176 void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&);
178177 void initializeLazyBranchProbabilityInfoPassPass(PassRegistry&);
179178 void initializeLazyMachineBlockFrequencyInfoPassPass(PassRegistry&);
7474 (void) llvm::createCallGraphDOTPrinterPass();
7575 (void) llvm::createCallGraphViewerPass();
7676 (void) llvm::createCFGSimplificationPass();
77 (void) llvm::createLateCFGSimplificationPass();
7877 (void) llvm::createCFLAndersAAWrapperPass();
7978 (void) llvm::createCFLSteensAAWrapperPass();
8079 (void) llvm::createStructurizeCFGPass();
3030 SimplifyCFGOptions Options;
3131
3232 public:
33 /// Construct a pass with default options.
34 SimplifyCFGPass();
33 /// The default constructor sets the pass options to create optimal IR,
34 /// rather than canonical IR. That is, by default we do transformations that
35 /// are likely to improve performance but make analysis more difficult.
36 /// FIXME: This is inverted from what most instantiations of the pass should
37 /// be.
38 SimplifyCFGPass()
39 : SimplifyCFGPass(SimplifyCFGOptions()
40 .forwardSwitchCondToPhi(true)
41 .convertSwitchToLookupTable(true)
42 .needCanonicalLoops(false)) {}
3543
3644 /// Construct a pass with optional optimizations.
3745 SimplifyCFGPass(const SimplifyCFGOptions &PassOptions);
254254 //===----------------------------------------------------------------------===//
255255 //
256256 // CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
257 // simplify terminator instructions, etc...
257 // simplify terminator instructions, convert switches to lookup tables, etc.
258258 //
259259 FunctionPass *createCFGSimplificationPass(
260 int Threshold = -1, std::function Ftor = nullptr);
261
262 //===----------------------------------------------------------------------===//
263 //
264 // LateCFGSimplification - Like CFGSimplification, but may also
265 // convert switches to lookup tables.
266 //
267 FunctionPass *createLateCFGSimplificationPass(
268 int Threshold = -1, std::function Ftor = nullptr);
260 unsigned Threshold = 1, bool ForwardSwitchCond = false,
261 bool ConvertSwitch = false, bool KeepLoops = true,
262 std::function Ftor = nullptr);
269263
270264 //===----------------------------------------------------------------------===//
271265 //
6464 bool NeedCanonicalLoop;
6565 AssumptionCache *AC;
6666
67 SimplifyCFGOptions(int BonusThreshold = 1, bool ForwardSwitchCond = false,
67 SimplifyCFGOptions(unsigned BonusThreshold = 1,
68 bool ForwardSwitchCond = false,
6869 bool SwitchToLookup = false, bool CanonicalLoops = true,
6970 AssumptionCache *AssumpCache = nullptr)
7071 : BonusInstThreshold(BonusThreshold),
7172 ForwardSwitchCondToPhi(ForwardSwitchCond),
7273 ConvertSwitchToLookupTable(SwitchToLookup),
7374 NeedCanonicalLoop(CanonicalLoops), AC(AssumpCache) {}
75
76 // Support 'builder' pattern to set members by name at construction time.
77 SimplifyCFGOptions &bonusInstThreshold(int I) {
78 BonusInstThreshold = I;
79 return *this;
80 }
81 SimplifyCFGOptions &forwardSwitchCondToPhi(bool B) {
82 ForwardSwitchCondToPhi = B;
83 return *this;
84 }
85 SimplifyCFGOptions &convertSwitchToLookupTable(bool B) {
86 ConvertSwitchToLookupTable = B;
87 return *this;
88 }
89 SimplifyCFGOptions &needCanonicalLoops(bool B) {
90 NeedCanonicalLoop = B;
91 return *this;
92 }
93 SimplifyCFGOptions &setAssumptionCache(AssumptionCache *Cache) {
94 AC = Cache;
95 return *this;
96 }
7497 };
7598
7699 //===----------------------------------------------------------------------===//
4242
4343 /** See llvm::createCFGSimplificationPass function. */
4444 void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM);
45
46 /** See llvm::createLateCFGSimplificationPass function. */
47 void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM);
4845
4946 /** See llvm::createDeadStoreEliminationPass function. */
5047 void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);
130130 initializeMemCpyOptLegacyPassPass(R);
131131 initializeDCELegacyPassPass(R);
132132 initializeCFGSimplifyPassPass(R);
133 initializeLateCFGSimplifyPassPass(R);
134133 }
135134
136135 void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
364364 // determine whether it succeeded. We can exploit existing control-flow in
365365 // ldrex/strex loops to simplify this, but it needs tidying up.
366366 if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
367 addPass(createLateCFGSimplificationPass());
367 addPass(createCFGSimplificationPass(1, true, true, false));
368368
369369 // Run LoopDataPrefetch
370370 //
383383 // determine whether it succeeded. We can exploit existing control-flow in
384384 // ldrex/strex loops to simplify this, but it needs tidying up.
385385 if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
386 addPass(createCFGSimplificationPass(-1, [this](const Function &F) {
387 const auto &ST = this->TM->getSubtarget(F);
388 return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
389 }));
386 addPass(createCFGSimplificationPass(
387 1, false, false, true, [this](const Function &F) {
388 const auto &ST = this->TM->getSubtarget(F);
389 return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
390 }));
390391
391392 TargetPassConfig::addIRPasses();
392393
624624 }
625625
626626 addExtensionsToPM(EP_Peephole, MPM);
627 MPM.add(createLateCFGSimplificationPass()); // Switches to lookup tables
627 // Switches to lookup tables and other transforms that may not be considered
628 // canonical by other IR passes.
629 MPM.add(createCFGSimplificationPass(1, true, true, false));
628630 addInstructionCombiningPass(MPM);
629631
630632 if (!DisableUnrollLoops) {
8484 initializeIPSCCPLegacyPassPass(Registry);
8585 initializeSROALegacyPassPass(Registry);
8686 initializeCFGSimplifyPassPass(Registry);
87 initializeLateCFGSimplifyPassPass(Registry);
8887 initializeStructurizeCFGPass(Registry);
8988 initializeSimpleLoopUnswitchLegacyPassPass(Registry);
9089 initializeSinkingLegacyPassPass(Registry);
118117 }
119118
120119 void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM) {
121 unwrap(PM)->add(createCFGSimplificationPass());
122 }
123
124 void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM) {
125 unwrap(PM)->add(createLateCFGSimplificationPass());
120 unwrap(PM)->add(createCFGSimplificationPass(1, false, false, true));
126121 }
127122
128123 void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM) {
4444
4545 #define DEBUG_TYPE "simplifycfg"
4646
47 static cl::opt
48 UserBonusInstThreshold("bonus-inst-threshold", cl::Hidden, cl::init(1),
49 cl::desc("Control the number of bonus instructions (default = 1)"));
47 static cl::opt UserBonusInstThreshold(
48 "bonus-inst-threshold", cl::Hidden, cl::init(1),
49 cl::desc("Control the number of bonus instructions (default = 1)"));
50
51 static cl::opt UserKeepLoops(
52 "keep-loops", cl::Hidden, cl::init(true),
53 cl::desc("Preserve canonical loop structure (default = true)"));
54
55 static cl::opt UserSwitchToLookup(
56 "switch-to-lookup", cl::Hidden, cl::init(false),
57 cl::desc("Convert switches to lookup tables (default = false)"));
58
59 static cl::opt UserForwardSwitchCond(
60 "forward-switch-cond", cl::Hidden, cl::init(false),
61 cl::desc("Forward switch condition to phi ops (default = false)"));
5062
5163 STATISTIC(NumSimpl, "Number of blocks simplified");
5264
178190 return true;
179191 }
180192
181 // FIXME: The new pass manager always creates a "late" simplifycfg pass using
182 // this default constructor.
183 SimplifyCFGPass::SimplifyCFGPass()
184 : Options(UserBonusInstThreshold, true, true, false) {}
185
186 SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &PassOptions)
187 : Options(PassOptions) {}
193 // Command-line settings override compile-time settings.
194 SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts) {
195 Options.BonusInstThreshold = UserBonusInstThreshold.getNumOccurrences()
196 ? UserBonusInstThreshold
197 : Opts.BonusInstThreshold;
198 Options.ForwardSwitchCondToPhi = UserForwardSwitchCond.getNumOccurrences()
199 ? UserForwardSwitchCond
200 : Opts.ForwardSwitchCondToPhi;
201 Options.ConvertSwitchToLookupTable = UserSwitchToLookup.getNumOccurrences()
202 ? UserSwitchToLookup
203 : Opts.ConvertSwitchToLookupTable;
204 Options.NeedCanonicalLoop = UserKeepLoops.getNumOccurrences()
205 ? UserKeepLoops
206 : Opts.NeedCanonicalLoop;
207 }
188208
189209 PreservedAnalyses SimplifyCFGPass::run(Function &F,
190210 FunctionAnalysisManager &AM) {
198218 }
199219
200220 namespace {
201 struct BaseCFGSimplifyPass : public FunctionPass {
221 struct CFGSimplifyPass : public FunctionPass {
222 static char ID;
223 SimplifyCFGOptions Options;
202224 std::function PredicateFtor;
203 int BonusInstThreshold;
204 bool ForwardSwitchCondToPhi;
205 bool ConvertSwitchToLookupTable;
206 bool KeepCanonicalLoops;
207
208 BaseCFGSimplifyPass(int T, bool ForwardSwitchCond, bool ConvertSwitch,
209 bool KeepLoops,
210 std::function Ftor, char &ID)
211 : FunctionPass(ID), PredicateFtor(std::move(Ftor)),
212 ForwardSwitchCondToPhi(ForwardSwitchCond),
213 ConvertSwitchToLookupTable(ConvertSwitch),
214 KeepCanonicalLoops(KeepLoops) {
215 BonusInstThreshold = (T == -1) ? UserBonusInstThreshold : T;
216 }
225
226 CFGSimplifyPass(unsigned Threshold = 1, bool ForwardSwitchCond = false,
227 bool ConvertSwitch = false, bool KeepLoops = true,
228 std::function Ftor = nullptr)
229 : FunctionPass(ID), PredicateFtor(std::move(Ftor)) {
230
231 initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
232
233 // Check for command-line overrides of options for debug/customization.
234 Options.BonusInstThreshold = UserBonusInstThreshold.getNumOccurrences()
235 ? UserBonusInstThreshold
236 : Threshold;
237
238 Options.ForwardSwitchCondToPhi = UserForwardSwitchCond.getNumOccurrences()
239 ? UserForwardSwitchCond
240 : ForwardSwitchCond;
241
242 Options.ConvertSwitchToLookupTable = UserSwitchToLookup.getNumOccurrences()
243 ? UserSwitchToLookup
244 : ConvertSwitch;
245
246 Options.NeedCanonicalLoop =
247 UserKeepLoops.getNumOccurrences() ? UserKeepLoops : KeepLoops;
248 }
249
217250 bool runOnFunction(Function &F) override {
218251 if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
219252 return false;
220253
221 AssumptionCache *AC =
222 &getAnalysis().getAssumptionCache(F);
223 const TargetTransformInfo &TTI =
224 getAnalysis().getTTI(F);
225 return simplifyFunctionCFG(F, TTI,
226 {BonusInstThreshold, ForwardSwitchCondToPhi,
227 ConvertSwitchToLookupTable, KeepCanonicalLoops,
228 AC});
229 }
230
254 Options.AC = &getAnalysis().getAssumptionCache(F);
255 auto &TTI = getAnalysis().getTTI(F);
256 return simplifyFunctionCFG(F, TTI, Options);
257 }
231258 void getAnalysisUsage(AnalysisUsage &AU) const override {
232259 AU.addRequired();
233260 AU.addRequired();
234261 AU.addPreserved();
235 }
236 };
237
238 struct CFGSimplifyPass : public BaseCFGSimplifyPass {
239 static char ID; // Pass identification, replacement for typeid
240
241 CFGSimplifyPass(int T = -1,
242 std::function Ftor = nullptr)
243 : BaseCFGSimplifyPass(T, false, false, true, Ftor, ID) {
244 initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
245 }
246 };
247
248 struct LateCFGSimplifyPass : public BaseCFGSimplifyPass {
249 static char ID; // Pass identification, replacement for typeid
250
251 LateCFGSimplifyPass(int T = -1,
252 std::function Ftor = nullptr)
253 : BaseCFGSimplifyPass(T, true, true, false, Ftor, ID) {
254 initializeLateCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
255262 }
256263 };
257264 }
264271 INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
265272 false)
266273
267 char LateCFGSimplifyPass::ID = 0;
268 INITIALIZE_PASS_BEGIN(LateCFGSimplifyPass, "latesimplifycfg",
269 "Simplify the CFG more aggressively", false, false)
270 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
271 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
272 INITIALIZE_PASS_END(LateCFGSimplifyPass, "latesimplifycfg",
273 "Simplify the CFG more aggressively", false, false)
274
275274 // Public interface to the CFGSimplification pass
276275 FunctionPass *
277 llvm::createCFGSimplificationPass(int Threshold,
278 std::function Ftor) {
279 return new CFGSimplifyPass(Threshold, std::move(Ftor));
280 }
281
282 // Public interface to the LateCFGSimplification pass
283 FunctionPass *
284 llvm::createLateCFGSimplificationPass(int Threshold,
276 llvm::createCFGSimplificationPass(unsigned Threshold, bool ForwardSwitchCond,
277 bool ConvertSwitch, bool KeepLoops,
285278 std::function Ftor) {
286 return new LateCFGSimplifyPass(Threshold, std::move(Ftor));
287 }
279 return new CFGSimplifyPass(Threshold, ForwardSwitchCond, ConvertSwitch,
280 KeepLoops, std::move(Ftor));
281 }
106106 ; CHECK: [[FAILED]]:
107107 ; CHECK-NOT: cmp {{w[0-9]+}}, {{w[0-9]+}}
108108
109 ; verify the preheader is simplified by latesimplifycfg.
109 ; verify the preheader is simplified by simplifycfg.
110110 ; CHECK: [[PH]]:
111111 ; CHECK: orr w22, wzr, #0x2
112112 ; CHECK-NOT: orr w22, wzr, #0x4
None ; RUN: opt < %s -O3 -latesimplifycfg -mcpu=core-avx2 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix AUTO_VEC %s
0 ; RUN: opt < %s -O3 -simplifycfg -keep-loops=false -mcpu=core-avx2 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix AUTO_VEC %s
11
22 ; This test checks auto-vectorization with FP induction variable.
33 ; The FP operation is not "fast" and requires "fast-math" function attribute.
0 ; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -dce -instcombine -S | FileCheck --check-prefix VEC4_INTERL1 %s
11 ; RUN: opt < %s -loop-vectorize -force-vector-interleave=2 -force-vector-width=4 -dce -instcombine -S | FileCheck --check-prefix VEC4_INTERL2 %s
22 ; RUN: opt < %s -loop-vectorize -force-vector-interleave=2 -force-vector-width=1 -dce -instcombine -S | FileCheck --check-prefix VEC1_INTERL2 %s
3 ; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -dce -simplifycfg -instcombine -latesimplifycfg -S | FileCheck --check-prefix VEC2_INTERL1_PRED_STORE %s
3 ; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -dce -simplifycfg -instcombine -simplifycfg -keep-loops=false -S | FileCheck --check-prefix VEC2_INTERL1_PRED_STORE %s
44
55 @fp_inc = common global float 0.000000e+00, align 4
66
None ; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
1 ; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
2 ; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
3 ; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
4 ; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
0 ; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
1 ; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
2 ; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
3 ; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
4 ; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
55
66 ; CHECK: @{{.*}} = private unnamed_addr constant [3 x i32] [i32 1234, i32 5678, i32 15532]
77 ; ENABLE: @{{.*}} = private unnamed_addr constant [3 x i32*] [i32* @c1, i32* @c2, i32* @c3]
None ; RUN: opt -latesimplifycfg -S %s | FileCheck %s
0 ; RUN: opt -simplifycfg -switch-to-lookup -S %s | FileCheck %s
11 ; rdar://15268442
22
33 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"
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt < %s -latesimplifycfg -S | FileCheck %s
1 ; RUN: opt < %s -simplifycfg -forward-switch-cond=false -S | FileCheck %s --check-prefix=NO_FWD
2 ; RUN: opt < %s -simplifycfg -forward-switch-cond=true -S | FileCheck %s --check-prefix=FWD
23
34 ; PR10131
45
67 target triple = "i386-pc-linux-gnu"
78
89 define i32 @t(i32 %m) nounwind readnone {
9 ; CHECK-LABEL: @t(
10 ; CHECK-NEXT: entry:
11 ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[M:%.*]], 4
12 ; CHECK-NEXT: [[M_:%.*]] = select i1 [[SWITCH]], i32 [[M]], i32 4
13 ; CHECK-NEXT: ret i32 [[M_]]
10 ; NO_FWD-LABEL: @t(
11 ; NO_FWD-NEXT: entry:
12 ; NO_FWD-NEXT: switch i32 [[M:%.*]], label [[SW_BB4:%.*]] [
13 ; NO_FWD-NEXT: i32 0, label [[RETURN:%.*]]
14 ; NO_FWD-NEXT: i32 1, label [[SW_BB1:%.*]]
15 ; NO_FWD-NEXT: i32 2, label [[SW_BB2:%.*]]
16 ; NO_FWD-NEXT: i32 3, label [[SW_BB3:%.*]]
17 ; NO_FWD-NEXT: ]
18 ; NO_FWD: sw.bb1:
19 ; NO_FWD-NEXT: br label [[RETURN]]
20 ; NO_FWD: sw.bb2:
21 ; NO_FWD-NEXT: br label [[RETURN]]
22 ; NO_FWD: sw.bb3:
23 ; NO_FWD-NEXT: br label [[RETURN]]
24 ; NO_FWD: sw.bb4:
25 ; NO_FWD-NEXT: br label [[RETURN]]
26 ; NO_FWD: return:
27 ; NO_FWD-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 4, [[SW_BB4]] ], [ 3, [[SW_BB3]] ], [ 2, [[SW_BB2]] ], [ 1, [[SW_BB1]] ], [ 0, [[ENTRY:%.*]] ]
28 ; NO_FWD-NEXT: ret i32 [[RETVAL_0]]
29 ;
30 ; FWD-LABEL: @t(
31 ; FWD-NEXT: entry:
32 ; FWD-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[M:%.*]], 4
33 ; FWD-NEXT: [[M_:%.*]] = select i1 [[SWITCH]], i32 [[M]], i32 4
34 ; FWD-NEXT: ret i32 [[M_]]
1435 ;
1536 entry:
1637 switch i32 %m, label %sw.bb4 [
4566 ; This then subsequently should allow squashing of the other trivial case blocks.
4667
4768 define i32 @PR34471(i32 %x) {
48 ; CHECK-LABEL: @PR34471(
49 ; CHECK-NEXT: entry:
50 ; CHECK-NEXT: switch i32 [[X:%.*]], label [[ELSE3:%.*]] [
51 ; CHECK-NEXT: i32 17, label [[RETURN:%.*]]
52 ; CHECK-NEXT: i32 19, label [[RETURN]]
53 ; CHECK-NEXT: i32 42, label [[RETURN]]
54 ; CHECK-NEXT: ]
55 ; CHECK: else3:
56 ; CHECK-NEXT: br label [[RETURN]]
57 ; CHECK: return:
58 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ 0, [[ELSE3]] ], [ [[X]], [[ENTRY:%.*]] ], [ [[X]], [[ENTRY]] ], [ [[X]], [[ENTRY]] ]
59 ; CHECK-NEXT: ret i32 [[R]]
69 ; NO_FWD-LABEL: @PR34471(
70 ; NO_FWD-NEXT: entry:
71 ; NO_FWD-NEXT: switch i32 [[X:%.*]], label [[ELSE3:%.*]] [
72 ; NO_FWD-NEXT: i32 17, label [[RETURN:%.*]]
73 ; NO_FWD-NEXT: i32 19, label [[IF19:%.*]]
74 ; NO_FWD-NEXT: i32 42, label [[IF42:%.*]]
75 ; NO_FWD-NEXT: ]
76 ; NO_FWD: if19:
77 ; NO_FWD-NEXT: br label [[RETURN]]
78 ; NO_FWD: if42:
79 ; NO_FWD-NEXT: br label [[RETURN]]
80 ; NO_FWD: else3:
81 ; NO_FWD-NEXT: br label [[RETURN]]
82 ; NO_FWD: return:
83 ; NO_FWD-NEXT: [[R:%.*]] = phi i32 [ [[X]], [[IF19]] ], [ [[X]], [[IF42]] ], [ 0, [[ELSE3]] ], [ 17, [[ENTRY:%.*]] ]
84 ; NO_FWD-NEXT: ret i32 [[R]]
85 ;
86 ; FWD-LABEL: @PR34471(
87 ; FWD-NEXT: entry:
88 ; FWD-NEXT: switch i32 [[X:%.*]], label [[ELSE3:%.*]] [
89 ; FWD-NEXT: i32 17, label [[RETURN:%.*]]
90 ; FWD-NEXT: i32 19, label [[RETURN]]
91 ; FWD-NEXT: i32 42, label [[RETURN]]
92 ; FWD-NEXT: ]
93 ; FWD: else3:
94 ; FWD-NEXT: br label [[RETURN]]
95 ; FWD: return:
96 ; FWD-NEXT: [[R:%.*]] = phi i32 [ 0, [[ELSE3]] ], [ [[X]], [[ENTRY:%.*]] ], [ [[X]], [[ENTRY]] ], [ [[X]], [[ENTRY]] ]
97 ; FWD-NEXT: ret i32 [[R]]
6098 ;
6199 entry:
62100 switch i32 %x, label %else3 [
None ; RUN: opt < %s -latesimplifycfg -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
1 ; In the presence of "-no-jump-tables"="true", late simplifycfg should not
2 ; convert any switch cases to lookup tables.
0 ; RUN: opt < %s -simplifycfg -switch-to-lookup -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
1
2 ; In the presence of "-no-jump-tables"="true", simplifycfg should not convert switches to lookup tables.
3
34 ; CHECK: @switch.table.bar = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1]
45 ; CHECK-LABEL: foo
56 ; CHECK-NOT: @switch.table.foo = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1]
None ; RUN: opt -S -latesimplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
0 ; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
11 ; rdar://17887153
22 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"
33 target triple = "x86_64-apple-darwin12.0.0"
None ; RUN: opt -S -latesimplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
0 ; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
11 ; rdar://17735071
22 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"
33 target triple = "x86_64-apple-darwin12.0.0"
None ; RUN: opt < %s -latesimplifycfg -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
0 ; RUN: opt < %s -simplifycfg -switch-to-lookup=true -keep-loops=false -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
11
22 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"
33 target triple = "x86_64-unknown-linux-gnu"
None ; RUN: opt -latesimplifycfg -S < %s | FileCheck %s
0 ; RUN: opt -simplifycfg -keep-loops=false -S < %s | FileCheck %s
11
22 ; It's not worthwhile to if-convert one of the phi nodes and leave
33 ; the other behind, because that still requires a branch. If
None ; RUN: opt -latesimplifycfg -S < %s | FileCheck %s
0 ; RUN: opt -simplifycfg -keep-loops=false -S < %s | FileCheck %s
11
22 define void @test1(i32 %n) #0 {
33 entry:
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt < %s -latesimplifycfg -S | FileCheck %s
1 ; RUN: opt < %s -simplifycfg -switch-to-lookup -S | FileCheck %s
22
33 target datalayout = "e-n32"
44