[llvm] r328312 - Revert r328307: [IPSCCP] Use constant range information for comparisons of parameters.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 23 05:49:39 PDT 2018


Author: fhahn
Date: Fri Mar 23 05:49:39 2018
New Revision: 328312

URL: http://llvm.org/viewvc/llvm-project?rev=328312&view=rev
Log:
Revert r328307: [IPSCCP] Use constant range information for comparisons of parameters.

Reverted for now, due to it causing verifier failures.

Modified:
    llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
    llvm/trunk/test/Transforms/SCCP/ip-constant-ranges.ll

Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=328312&r1=328311&r2=328312&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Fri Mar 23 05:49:39 2018
@@ -69,6 +69,8 @@ STATISTIC(NumDeadBlocks , "Number of bas
 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(Ins
 
 // 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(Functi
   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 Da
           ++IPNumArgsElimed;
           continue;
         }
+
+        if (!AI->use_empty() && tryToReplaceWithConstantRange(Solver, &*AI))
+          ++IPNumRangeInfoUsed;
       }
 
     for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {

Modified: llvm/trunk/test/Transforms/SCCP/ip-constant-ranges.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ip-constant-ranges.ll?rev=328312&r1=328311&r2=328312&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SCCP/ip-constant-ranges.ll (original)
+++ llvm/trunk/test/Transforms/SCCP/ip-constant-ranges.ll Fri Mar 23 05:49:39 2018
@@ -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, dou
 ; 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:




More information about the llvm-commits mailing list