[llvm] r260627 - [LVI] Improve select handling to use condition

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 11 16:09:18 PST 2016


Author: reames
Date: Thu Feb 11 18:09:18 2016
New Revision: 260627

URL: http://llvm.org/viewvc/llvm-project?rev=260627&view=rev
Log:
[LVI] Improve select handling to use condition

This patches teaches LVI to recognize clamp idioms (e.g. select(a > 5, a, 5) will always produce something greater than 5.

The tests end up being somewhat simplistic because trying to exercise the case I actually care about (a loop with a range check on a clamped secondary induction variable) ends up tripping across a couple of other imprecisions in the analysis. Ah, the joys of LVI...

Differential Revision: http://reviews.llvm.org/D16827


Modified:
    llvm/trunk/lib/Analysis/LazyValueInfo.cpp
    llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll

Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=260627&r1=260626&r2=260627&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Thu Feb 11 18:09:18 2016
@@ -911,6 +911,25 @@ bool LazyValueInfoCache::solveBlockValue
     return true;
   }
 
+  // Can we constrain the facts about the true and false values by using the
+  // condition itself?  This shows up with idioms like e.g. select(a > 5, a, 5).
+  // TODO: We could potentially refine an overdefined true value above.
+  if (auto *ICI = dyn_cast<ICmpInst>(SI->getCondition())) {
+    LVILatticeVal TrueValTaken, FalseValTaken;
+    if (!getValueFromFromCondition(SI->getTrueValue(), ICI,
+                                   TrueValTaken, true))
+      TrueValTaken.markOverdefined();
+    if (!getValueFromFromCondition(SI->getFalseValue(), ICI,
+                                   FalseValTaken, false))
+      FalseValTaken.markOverdefined();
+
+    TrueVal = intersect(TrueVal, TrueValTaken);
+    FalseVal = intersect(FalseVal, FalseValTaken);
+  }
+
+  // TODO: handle idioms like min & max where we can use a more precise merge
+  // when our inputs are constant ranges.
+  
   LVILatticeVal Result;  // Start Undefined.
   Result.mergeIn(TrueVal, DL);
   Result.mergeIn(FalseVal, DL);

Modified: llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll?rev=260627&r1=260626&r2=260627&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll (original)
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll Thu Feb 11 18:09:18 2016
@@ -167,3 +167,52 @@ exit:
 ; CHECK: ret i1 true
   ret i1 true
 }
+
+;; Using the condition to clamp the result
+;; 
+
+define i1 @test5(i32* %p, i1 %unknown) {
+; CHECK-LABEL: @test5
+  %pval = load i32, i32* %p
+  %cmp1 = icmp slt i32 %pval, 255
+  br i1 %cmp1, label %next, label %exit
+
+next:
+  %cond = icmp sgt i32 %pval, 0
+  %min = select i1 %cond, i32 %pval, i32 5
+  ;; TODO: This pointless branch shouldn't be neccessary
+  br label %next2
+next2:
+; CHECK-LABEL: next2:
+; CHECK: ret i1 false
+  %res = icmp eq i32 %min, -1
+  ret i1 %res
+
+exit:
+; CHECK-LABEL: exit:
+; CHECK: ret i1 true
+  ret i1 true
+}
+
+define i1 @test6(i32* %p, i1 %unknown) {
+; CHECK-LABEL: @test6
+  %pval = load i32, i32* %p
+  %cmp1 = icmp ult i32 %pval, 255
+  br i1 %cmp1, label %next, label %exit
+
+next:
+  %cond = icmp ne i32 %pval, 254
+  %sel = select i1 %cond, i32 %pval, i32 1
+  ;; TODO: This pointless branch shouldn't be neccessary
+  br label %next2
+next2:
+; CHECK-LABEL: next2:
+; CHECK: ret i1 true
+  %res = icmp slt i32 %sel, 254
+  ret i1 %res
+
+exit:
+; CHECK-LABEL: exit:
+; CHECK: ret i1 true
+  ret i1 true
+}




More information about the llvm-commits mailing list