Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -69,8 +69,6 @@ STATISTIC(IPNumInstRemoved, "Number of instructions removed by IPSCCP"); STATISTIC(IPNumArgsElimed ,"Number of arguments constant propagated by IPSCCP"); STATISTIC(IPNumGlobalConst, "Number of globals found to be constant by IPSCCP"); -STATISTIC(IPNumRangeInfoUsed, "Number of times constant range info was used by" - "IPSCCP"); namespace { @@ -1039,15 +1037,26 @@ // Handle ICmpInst instruction. void SCCPSolver::visitCmpInst(CmpInst &I) { - LatticeVal V1State = getValueState(I.getOperand(0)); - LatticeVal V2State = getValueState(I.getOperand(1)); - LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; - if (V1State.isConstant() && V2State.isConstant()) { - Constant *C = ConstantExpr::getCompare( - I.getPredicate(), V1State.getConstant(), V2State.getConstant()); + Value *Op1 = I.getOperand(0); + Value *Op2 = I.getOperand(1); + + // For parameters, use ParamState which includes constant range info if + // available. + auto V1Param = ParamState.find(Op1); + ValueLatticeElement V1State = (V1Param != ParamState.end()) + ? V1Param->second + : getValueState(Op1).toValueLattice(); + + auto V2Param = ParamState.find(Op2); + ValueLatticeElement V2State = V2Param != ParamState.end() + ? V2Param->second + : getValueState(Op2).toValueLattice(); + + Constant *C = V1State.getCompare(I.getPredicate(), I.getType(), V2State); + if (C) { if (isa(C)) return; return markConstant(IV, &I, C); @@ -1616,45 +1625,6 @@ return false; } -static bool tryToReplaceWithConstantRange(SCCPSolver &Solver, Value *V) { - bool Changed = false; - - // Currently we only use range information for integer values. - if (!V->getType()->isIntegerTy()) - return false; - - const ValueLatticeElement &IV = Solver.getLatticeValueFor(V); - if (!IV.isConstantRange()) - return false; - - for (auto UI = V->uses().begin(), E = V->uses().end(); UI != E;) { - const Use &U = *UI++; - auto *Icmp = dyn_cast(U.getUser()); - if (!Icmp || !Solver.isBlockExecutable(Icmp->getParent())) - continue; - - auto getIcmpLatticeValue = [&](Value *Op) { - if (auto *C = dyn_cast(Op)) - return ValueLatticeElement::get(C); - return Solver.getLatticeValueFor(Op); - }; - - ValueLatticeElement A = getIcmpLatticeValue(Icmp->getOperand(0)); - ValueLatticeElement B = getIcmpLatticeValue(Icmp->getOperand(1)); - - Constant *C = A.getCompare(Icmp->getPredicate(), Icmp->getType(), B); - if (C) { - Icmp->replaceAllUsesWith(C); - DEBUG(dbgs() << "Replacing " << *Icmp << " with " << *C - << ", because of range information " << A << " " << B - << "\n"); - Icmp->eraseFromParent(); - Changed = true; - } - } - return Changed; -} - static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) { Constant *Const = nullptr; if (V->getType()->isStructTy()) { @@ -1923,9 +1893,6 @@ ++IPNumArgsElimed; continue; } - - if (!AI->use_empty() && tryToReplaceWithConstantRange(Solver, &*AI)) - ++IPNumRangeInfoUsed; } for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { Index: test/Transforms/SCCP/ip-constant-ranges.ll =================================================================== --- test/Transforms/SCCP/ip-constant-ranges.ll +++ test/Transforms/SCCP/ip-constant-ranges.ll @@ -2,11 +2,7 @@ ; Constant range for %a is [1, 48) and for %b is [301, 1000) ; CHECK-LABEL: f1 -; CHECK-NOT: icmp -; CHECK: %a.1 = select i1 false, i32 1, i32 2 -; CHECK: %b.1 = select i1 true, i32 1, i32 2 -; CHECK: %a.2 = select i1 false, i32 1, i32 2 -; CHECK: %b.2 = select i1 true, i32 1, i32 2 +; CHECK: ret i32 undef define internal i32 @f1(i32 %a, i32 %b) { entry: %cmp.a = icmp sgt i32 %a, 300 @@ -28,10 +24,11 @@ ; CHECK-LABEL: f2 ; CHECK: %cmp = icmp sgt i32 %x, 300 ; CHECK: %res1 = select i1 %cmp, i32 1, i32 2 -; CHECK-NEXT: %res2 = select i1 true, i32 3, i32 4 -; CHECK-NEXT: %res3 = select i1 true, i32 5, i32 6 ; CHECK-NEXT: %res4 = select i1 %cmp4, i32 3, i32 4 -; CHECK-NEXT: %res5 = select i1 true, i32 5, i32 6 +; CHECK-NEXT: %res6 = add i32 %res1, 3 +; CHECK-NEXT: %res7 = add i32 5, %res4 +; CHECK-NEXT: %res = add i32 %res6, 5 +; CHECK-NEXT: ret i32 %res define internal i32 @f2(i32 %x) { entry: %cmp = icmp sgt i32 %x, 300 @@ -57,8 +54,7 @@ %call2 = tail call i32 @f1(i32 47, i32 999) %call3 = tail call i32 @f2(i32 47) %call4 = tail call i32 @f2(i32 301) - %res = add nsw i32 %call1, %call2 - %res.1 = add nsw i32 %res, %call3 + %res.1 = add nsw i32 12, %call3 %res.2 = add nsw i32 %res.1, %call4 ret i32 %res.2 } @@ -145,9 +141,9 @@ ; Constant range for %x is [47, 302) ; CHECK-LABEL: @f5 ; CHECK-NEXT: entry: -; CHECK-NEXT: %res1 = select i1 undef, i32 1, i32 2 -; CHECK-NEXT: %res2 = select i1 undef, i32 3, i32 4 -; CHECK-NEXT: %res = add i32 %res1, %res2 +; CHECK-NEXT: %cmp = icmp sgt i32 %x, undef +; CHECK-NEXT: %res1 = select i1 %cmp, i32 1, i32 2 +; CHECK-NEXT: %res = add i32 %res1, 3 ; CHECK-NEXT: ret i32 %res define internal i32 @f5(i32 %x) { entry: