diff options
author | Florian Hahn <florian.hahn@arm.com> | 2018-03-23 12:49:39 +0000 |
---|---|---|
committer | Florian Hahn <florian.hahn@arm.com> | 2018-03-23 12:49:39 +0000 |
commit | f73c3ece7f1004dd5c1b8351a90172258018dd12 (patch) | |
tree | 19e273371f02825a384efe9b1cad5b2918576634 /llvm | |
parent | f54235594222ed8925429e050d0b7611b2c249a4 (diff) | |
download | bcm5719-llvm-f73c3ece7f1004dd5c1b8351a90172258018dd12.tar.gz bcm5719-llvm-f73c3ece7f1004dd5c1b8351a90172258018dd12.zip |
Revert r328307: [IPSCCP] Use constant range information for comparisons of parameters.
Reverted for now, due to it causing verifier failures.
llvm-svn: 328312
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Transforms/Scalar/SCCP.cpp | 67 | ||||
-rw-r--r-- | llvm/test/Transforms/SCCP/ip-constant-ranges.ll | 22 |
2 files changed, 63 insertions, 26 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index d6fbbce23a3..5a6697fd9fe 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -69,6 +69,8 @@ STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable"); 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 { @@ -1037,26 +1039,15 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) { // 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; - 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 (V1State.isConstant() && V2State.isConstant()) { + Constant *C = ConstantExpr::getCompare( + I.getPredicate(), V1State.getConstant(), V2State.getConstant()); if (isa<UndefValue>(C)) return; return markConstant(IV, &I, C); @@ -1625,6 +1616,45 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { 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<ICmpInst>(U.getUser()); + if (!Icmp || !Solver.isBlockExecutable(Icmp->getParent())) + continue; + + auto getIcmpLatticeValue = [&](Value *Op) { + if (auto *C = dyn_cast<Constant>(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()) { @@ -1893,6 +1923,9 @@ bool llvm::runIPSCCP(Module &M, const DataLayout &DL, ++IPNumArgsElimed; continue; } + + if (!AI->use_empty() && tryToReplaceWithConstantRange(Solver, &*AI)) + ++IPNumRangeInfoUsed; } for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { diff --git a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll index d5a3e208adf..22a239d1208 100644 --- a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll +++ b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll @@ -2,7 +2,11 @@ ; Constant range for %a is [1, 48) and for %b is [301, 1000) ; CHECK-LABEL: f1 -; CHECK: ret i32 undef +; 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 define internal i32 @f1(i32 %a, i32 %b) { entry: %cmp.a = icmp sgt i32 %a, 300 @@ -24,11 +28,10 @@ entry: ; 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: %res6 = add i32 %res1, 3 -; CHECK-NEXT: %res7 = add i32 5, %res4 -; CHECK-NEXT: %res = add i32 %res6, 5 -; CHECK-NEXT: ret i32 %res +; CHECK-NEXT: %res5 = select i1 true, i32 5, i32 6 define internal i32 @f2(i32 %x) { entry: %cmp = icmp sgt i32 %x, 300 @@ -54,7 +57,8 @@ entry: %call2 = tail call i32 @f1(i32 47, i32 999) %call3 = tail call i32 @f2(i32 47) %call4 = tail call i32 @f2(i32 301) - %res.1 = add nsw i32 12, %call3 + %res = add nsw i32 %call1, %call2 + %res.1 = add nsw i32 %res, %call3 %res.2 = add nsw i32 %res.1, %call4 ret i32 %res.2 } @@ -141,9 +145,9 @@ define double @test_struct({ double, double } %test) { ; Constant range for %x is [47, 302) ; CHECK-LABEL: @f5 ; CHECK-NEXT: entry: -; 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: %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: ret i32 %res define internal i32 @f5(i32 %x) { entry: |