diff options
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 12 | ||||
-rw-r--r-- | llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll | 32 |
2 files changed, 44 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index fefe448d239..8370968065d 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -90,6 +90,11 @@ static cl::opt<bool> SpeculateOneExpensiveInst( cl::desc("Allow exactly one expensive instruction to be speculatively " "executed")); +static cl::opt<unsigned> MaxSpeculationDepth( + "max-speculation-depth", cl::Hidden, cl::init(10), + cl::desc("Limit maximum recursion depth when calculating costs of " + "speculatively executed instructions")); + STATISTIC(NumBitMaps, "Number of switch instructions turned into bitmaps"); STATISTIC(NumLinearMaps, "Number of switch instructions turned into linear mapping"); STATISTIC(NumLookupTables, "Number of switch instructions turned into lookup tables"); @@ -269,6 +274,13 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB, unsigned &CostRemaining, const TargetTransformInfo &TTI, unsigned Depth = 0) { + // It is possible to hit a zero-cost cycle (phi/gep instructions for example), + // so limit the recursion depth. + // TODO: While this recursion limit does prevent pathological behavior, it + // would be better to track visited instructions to avoid cycles. + if (Depth == MaxSpeculationDepth) + return false; + Instruction *I = dyn_cast<Instruction>(V); if (!I) { // Non-instructions all dominate instructions, but not all constantexprs diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll index cae1a91bd43..6953cf9c8b3 100644 --- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -1302,3 +1302,35 @@ l6: ; CHECK: entry ; CHECK-NEXT: switch } + +; Speculation depth must be limited to avoid a zero-cost instruction cycle. + +; CHECK-LABEL: @PR26308( +; CHECK: cleanup4: +; CHECK-NEXT: br label %cleanup4 + +define i32 @PR26308(i1 %B, i64 %load) { +entry: + br label %while.body + +while.body: + br label %cleanup + +cleanup: + %cleanup.dest.slot.0 = phi i1 [ false, %while.body ] + br i1 %cleanup.dest.slot.0, label %for.cond, label %cleanup4 + +for.cond: + %e.0 = phi i64* [ undef, %cleanup ], [ %incdec.ptr, %for.cond2 ] + %pi = ptrtoint i64* %e.0 to i64 + %incdec.ptr = getelementptr inbounds i64, i64* %e.0, i64 1 + br label %for.cond2 + +for.cond2: + %storemerge = phi i64 [ %pi, %for.cond ], [ %load, %for.cond2 ] + br i1 %B, label %for.cond2, label %for.cond + +cleanup4: + br label %while.body +} + |