Index: llvm/include/llvm/Analysis/LoopUnrollAnalyzer.h =================================================================== --- llvm/include/llvm/Analysis/LoopUnrollAnalyzer.h +++ llvm/include/llvm/Analysis/LoopUnrollAnalyzer.h @@ -46,7 +46,7 @@ public: UnrolledInstAnalyzer(unsigned Iteration, - DenseMap &SimplifiedValues, + DenseMap &SimplifiedValues, ScalarEvolution &SE, const Loop *L) : SimplifiedValues(SimplifiedValues), SE(SE), L(L) { IterationNumber = SE.getConstant(APInt(64, Iteration)); @@ -68,15 +68,12 @@ /// iteration. const SCEV *IterationNumber; - /// A Value->Constant map for keeping values that we managed to - /// constant-fold on the given iteration. - /// /// While we walk the loop instructions, we build up and maintain a mapping /// of simplified values specific to this iteration. The idea is to propagate /// any special information we have about loads that can be replaced with /// constants after complete unrolling, and account for likely simplifications /// post-unrolling. - DenseMap &SimplifiedValues; + DenseMap &SimplifiedValues; ScalarEvolution &SE; const Loop *L; Index: llvm/lib/Analysis/LoopUnrollAnalyzer.cpp =================================================================== --- llvm/lib/Analysis/LoopUnrollAnalyzer.cpp +++ llvm/lib/Analysis/LoopUnrollAnalyzer.cpp @@ -74,10 +74,10 @@ bool UnrolledInstAnalyzer::visitBinaryOperator(BinaryOperator &I) { Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); if (!isa(LHS)) - if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) + if (Value *SimpleLHS = SimplifiedValues.lookup(LHS)) LHS = SimpleLHS; if (!isa(RHS)) - if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) + if (Value *SimpleRHS = SimplifiedValues.lookup(RHS)) RHS = SimpleRHS; Value *SimpleV = nullptr; @@ -88,11 +88,10 @@ else SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS, DL); - if (Constant *C = dyn_cast_or_null(SimpleV)) - SimplifiedValues[&I] = C; - - if (SimpleV) + if (SimpleV) { + SimplifiedValues[&I] = SimpleV; return true; + } return Base::visitBinaryOperator(I); } @@ -147,20 +146,17 @@ /// Try to simplify cast instruction. bool UnrolledInstAnalyzer::visitCastInst(CastInst &I) { - // Propagate constants through casts. - Constant *COp = dyn_cast(I.getOperand(0)); - if (!COp) - COp = SimplifiedValues.lookup(I.getOperand(0)); + Value *Op = I.getOperand(0); + if (Value *Simplified = SimplifiedValues.lookup(Op)) + Op = Simplified; - // If we know a simplified value for this operand and cast is valid, save the - // result to SimplifiedValues. // The cast can be invalid, because SimplifiedValues contains results of SCEV // analysis, which operates on integers (and, e.g., might convert i8* null to // i32 0). - if (COp && CastInst::castIsValid(I.getOpcode(), COp, I.getType())) { - if (Constant *C = - ConstantExpr::getCast(I.getOpcode(), COp, I.getType())) { - SimplifiedValues[&I] = C; + if (CastInst::castIsValid(I.getOpcode(), Op, I.getType())) { + const DataLayout &DL = I.getModule()->getDataLayout(); + if (Value *V = SimplifyCastInst(I.getOpcode(), Op, I.getType(), DL)) { + SimplifiedValues[&I] = V; return true; } } @@ -174,10 +170,10 @@ // First try to handle simplified comparisons. if (!isa(LHS)) - if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) + if (Value *SimpleLHS = SimplifiedValues.lookup(LHS)) LHS = SimpleLHS; if (!isa(RHS)) - if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) + if (Value *SimpleRHS = SimplifiedValues.lookup(RHS)) RHS = SimpleRHS; if (!isa(LHS) && !isa(RHS)) { @@ -206,6 +202,12 @@ } } + const DataLayout &DL = I.getModule()->getDataLayout(); + if (Value *V = SimplifyCmpInst(I.getPredicate(), LHS, RHS, DL)) { + SimplifiedValues[&I] = V; + return true; + } + return Base::visitCmpInst(I); } Index: llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -356,8 +356,8 @@ SmallSetVector BBWorklist; SmallSetVector, 4> ExitWorklist; - DenseMap SimplifiedValues; - SmallVector, 4> SimplifiedInputValues; + DenseMap SimplifiedValues; + SmallVector, 4> SimplifiedInputValues; // The estimated cost of the unrolled form of the loop. We try to estimate // this by simplifying as much as we can while computing the estimate. @@ -498,11 +498,9 @@ Value *V = PHI->getIncomingValueForBlock( Iteration == 0 ? L->getLoopPreheader() : L->getLoopLatch()); - Constant *C = dyn_cast(V); - if (Iteration != 0 && !C) - C = SimplifiedValues.lookup(V); - if (C) - SimplifiedInputValues.push_back({PHI, C}); + if (Iteration != 0 && SimplifiedValues.count(V)) + V = SimplifiedValues.lookup(V); + SimplifiedInputValues.push_back({PHI, V}); } // Now clear and re-populate the map for the next iteration. @@ -571,13 +569,18 @@ Instruction *TI = BB->getTerminator(); + auto getSimplifiedConstant = [&](Value *V) -> Constant * { + if (SimplifiedValues.count(V)) + V = SimplifiedValues.lookup(V); + return dyn_cast(V); + }; + // Add in the live successors by first checking whether we have terminator // that may be simplified based on the values simplified by this call. BasicBlock *KnownSucc = nullptr; if (BranchInst *BI = dyn_cast(TI)) { if (BI->isConditional()) { - if (Constant *SimpleCond = - SimplifiedValues.lookup(BI->getCondition())) { + if (auto *SimpleCond = getSimplifiedConstant(BI->getCondition())) { // Just take the first successor if condition is undef if (isa(SimpleCond)) KnownSucc = BI->getSuccessor(0); @@ -587,8 +590,7 @@ } } } else if (SwitchInst *SI = dyn_cast(TI)) { - if (Constant *SimpleCond = - SimplifiedValues.lookup(SI->getCondition())) { + if (auto *SimpleCond = getSimplifiedConstant(SI->getCondition())) { // Just take the first successor if condition is undef if (isa(SimpleCond)) KnownSucc = SI->getSuccessor(0); Index: llvm/test/Transforms/LoopUnroll/unroll-cost-symbolic-execute.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopUnroll/unroll-cost-symbolic-execute.ll @@ -0,0 +1,386 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -loop-unroll -S -unroll-threshold=120 < %s | FileCheck %s + +define i32 @test_both(i32 %limit) { +; CHECK-LABEL: @test_both( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[LOOP_GUARD:%.*]] = icmp sge i32 [[LIMIT:%.*]], 0 +; CHECK-NEXT: br i1 [[LOOP_GUARD]], label [[LOOP_PREHEADER:%.*]], label [[FAILURE:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[LIMIT]], [[SUM]] +; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sge i32 [[SUB]], 0 +; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[BACKEDGE]], label [[IF_FALSE:%.*]] +; CHECK: if.false: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[SUB]] +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 +; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8 +; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]] +; CHECK: done: +; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ] +; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] +; CHECK: failure: +; CHECK-NEXT: unreachable +; +entry: + %loop_guard = icmp sge i32 %limit, 0 + br i1 %loop_guard, label %loop, label %failure + +loop: ; preds = %backedge, %entry + %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ] + %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] + %sub = sub i32 %limit, %sum + %is.positive = icmp sge i32 %sub, 0 + br i1 %is.positive, label %backedge, label %if.false + +if.false: ; preds = %loop + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + br label %backedge + +backedge: ; preds = %if.false, %loop + %sum.next = add i32 %sum, %sub + %iv.next = add i32 %iv, 1 + %loop.cond = icmp ne i32 %iv, 8 + br i1 %loop.cond, label %loop, label %done + +done: ; preds = %backedge + %sum.next.lcssa = phi i32 [ %sum.next, %backedge ] + ret i32 %sum.next.lcssa + +failure: + unreachable +} + +define i32 @test_dom_condition(i32 %limit) { +; CHECK-LABEL: @test_dom_condition( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[LOOP_GUARD:%.*]] = icmp sge i32 [[LIMIT:%.*]], 0 +; CHECK-NEXT: br i1 [[LOOP_GUARD]], label [[LOOP_PREHEADER:%.*]], label [[FAILURE:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[SUM]] +; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sle i32 [[SUB]], [[LIMIT]] +; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[BACKEDGE]], label [[IF_FALSE:%.*]] +; CHECK: if.false: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[SUB]] +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 +; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 8 +; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]] +; CHECK: done: +; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ] +; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] +; CHECK: failure: +; CHECK-NEXT: unreachable +; +entry: + %loop_guard = icmp sge i32 %limit, 0 + br i1 %loop_guard, label %loop, label %failure + +loop: ; preds = %backedge, %entry + %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ] + %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] + %sub = sub i32 0, %sum + %is.positive = icmp sle i32 %sub, %limit + br i1 %is.positive, label %backedge, label %if.false + +if.false: ; preds = %loop + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + br label %backedge + +backedge: ; preds = %if.false, %loop + %sum.next = add i32 %sum, %sub + %iv.next = add i32 %iv, 1 + %loop.cond = icmp ne i32 %iv, 8 + br i1 %loop.cond, label %loop, label %done + +done: ; preds = %backedge + %sum.next.lcssa = phi i32 [ %sum.next, %backedge ] + ret i32 %sum.next.lcssa + +failure: + unreachable +} + + +define i32 @test_symbolic_only(i32 %limit) { +; CHECK-LABEL: @test_symbolic_only( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[LOOP_GUARD:%.*]] = icmp sge i32 [[LIMIT:%.*]], 0 +; CHECK-NEXT: br i1 [[LOOP_GUARD]], label [[LOOP_PREHEADER:%.*]], label [[FAILURE:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: br i1 true, label [[BACKEDGE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.false: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_1:%.*]], label [[IF_FALSE_1:%.*]] +; CHECK: failure: +; CHECK-NEXT: unreachable +; CHECK: if.false.1: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_1]] +; CHECK: backedge.1: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_2:%.*]], label [[IF_FALSE_2:%.*]] +; CHECK: if.false.2: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_2]] +; CHECK: backedge.2: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_3:%.*]], label [[IF_FALSE_3:%.*]] +; CHECK: if.false.3: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_3]] +; CHECK: backedge.3: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_4:%.*]], label [[IF_FALSE_4:%.*]] +; CHECK: if.false.4: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_4]] +; CHECK: backedge.4: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_5:%.*]], label [[IF_FALSE_5:%.*]] +; CHECK: if.false.5: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_5]] +; CHECK: backedge.5: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_6:%.*]], label [[IF_FALSE_6:%.*]] +; CHECK: if.false.6: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_6]] +; CHECK: backedge.6: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_7:%.*]], label [[IF_FALSE_7:%.*]] +; CHECK: if.false.7: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_7]] +; CHECK: backedge.7: +; CHECK-NEXT: br i1 true, label [[BACKEDGE_8:%.*]], label [[IF_FALSE_8:%.*]] +; CHECK: if.false.8: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BACKEDGE_8]] +; CHECK: backedge.8: +; CHECK-NEXT: ret i32 0 +; +entry: + %loop_guard = icmp sge i32 %limit, 0 + br i1 %loop_guard, label %loop, label %failure + +loop: ; preds = %backedge, %entry + %sum = phi i32 [ 0, %entry ], [ %sum.next, %backedge ] + %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] + %sub = sub i32 %limit, %sum + %is.positive = icmp eq i32 %sub, %limit + br i1 %is.positive, label %backedge, label %if.false + +if.false: ; preds = %loop + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + br label %backedge + +backedge: ; preds = %if.false, %loop + %hidden_zero = sub i32 %limit, %sub + %sum.next = add i32 %sum, %hidden_zero + %iv.next = add i32 %iv, 1 + %loop.cond = icmp ne i32 %iv, 8 + br i1 %loop.cond, label %loop, label %done + +done: ; preds = %backedge + %sum.next.lcssa = phi i32 [ %sum.next, %backedge ] + ret i32 %sum.next.lcssa + +failure: + unreachable +} + +declare void @foo() Index: llvm/unittests/Analysis/UnrollAnalyzerTest.cpp =================================================================== --- llvm/unittests/Analysis/UnrollAnalyzerTest.cpp +++ llvm/unittests/Analysis/UnrollAnalyzerTest.cpp @@ -19,7 +19,7 @@ namespace llvm { void initializeUnrollAnalyzerTestPass(PassRegistry &); -static SmallVector, 16> SimplifiedValuesVector; +static SmallVector, 16> SimplifiedValuesVector; static unsigned TripCount = 0; namespace { @@ -38,7 +38,7 @@ SimplifiedValuesVector.clear(); TripCount = SE->getSmallConstantTripCount(L, Exiting); for (unsigned Iteration = 0; Iteration < TripCount; Iteration++) { - DenseMap SimplifiedValues; + DenseMap SimplifiedValues; UnrolledInstAnalyzer Analyzer(Iteration, SimplifiedValues, *SE, L); for (auto *BB : L->getBlocks()) for (Instruction &I : *BB)