[PATCH] D19559: [LVI] Exploit trivial range information from unknown RHS of icmp

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 26 14:42:59 PDT 2016


reames created this revision.
reames added reviewers: sanjoy, nicholas, hfinkel, regehr.
reames added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.

The primary motivation is in proving overflow facts.  Particularly, overflow facts for loop induction variables.  SCEV gets many of these cases today, but there's no reason LVI shouldn't get them to and having LVI able to catch the simple cases makes our pass order less fragile.

Note that this patch is only the analysis changes.  A separate change will build on top of this to actually make "add" instructions as nsw/nuw.  

http://reviews.llvm.org/D19559

Files:
  lib/Analysis/LazyValueInfo.cpp
  test/Transforms/CorrelatedValuePropagation/overflow.ll

Index: test/Transforms/CorrelatedValuePropagation/overflow.ll
===================================================================
--- test/Transforms/CorrelatedValuePropagation/overflow.ll
+++ test/Transforms/CorrelatedValuePropagation/overflow.ll
@@ -0,0 +1,44 @@
+; RUN: opt < %s -correlated-propagation -S | FileCheck %s
+
+; Just showing arbitrary constants work, not really a clamp
+define i1 @slt(i8 %a, i8 %b) {
+; CHECK-LABEL: @slt(
+; CHECK: ret i1 true
+entry:
+  %cmp = icmp slt i8 %a, %b
+  call void @llvm.assume(i1 %cmp)
+  %res = icmp slt i8 %a, 127
+  ret i1 %res
+}
+
+define i1 @sgt(i8 %a, i8 %b) {
+; CHECK-LABEL: @sgt(
+; CHECK: ret i1 true
+entry:
+  %cmp = icmp sgt i8 %a, %b
+  call void @llvm.assume(i1 %cmp)
+  %res = icmp sgt i8 %a, -128
+  ret i1 %res
+}
+
+define i1 @ult(i8 %a, i8 %b) {
+; CHECK-LABEL: @ult(
+; CHECK: ret i1 true
+entry:
+  %cmp = icmp ult i8 %a, %b
+  call void @llvm.assume(i1 %cmp)
+  %res = icmp ult i8 %a, 255
+  ret i1 %res
+}
+
+define i1 @ugt(i8 %a, i8 %b) {
+; CHECK-LABEL: @ugt(
+; CHECK: ret i1 true
+entry:
+  %cmp = icmp ugt i8 %a, %b
+  call void @llvm.assume(i1 %cmp)
+  %res = icmp ugt i8 %a, 0
+  ret i1 %res
+}
+
+declare void @llvm.assume(i1)
Index: lib/Analysis/LazyValueInfo.cpp
===================================================================
--- lib/Analysis/LazyValueInfo.cpp
+++ lib/Analysis/LazyValueInfo.cpp
@@ -1153,6 +1153,36 @@
     }
   }
 
+  if (isTrueDest && ICI->getOperand(0) == Val) {
+    // TODO: generalize this for when Val is operand(1)
+    unsigned BitWidth = Val->getType()->getPrimitiveSizeInBits();
+
+    // A <s B for any A and B implies A <s INT_MAX on success path
+    // A <u B for any A and B implies A <u UINT_MAX on success path
+    if ((ICI->getPredicate() == ICmpInst::ICMP_SLT ||
+         ICI->getPredicate() == ICmpInst::ICMP_ULT)) {
+      ConstantRange Max = ICI->isSigned() ?
+        ConstantRange(APInt::getSignedMaxValue(BitWidth)) :
+        ConstantRange(APInt::getMaxValue(BitWidth));
+      ConstantRange TrueValues =
+        ConstantRange::makeAllowedICmpRegion(ICI->getPredicate(), Max);
+      Result = LVILatticeVal::getRange(std::move(TrueValues));
+      return true;
+    }
+    // A >s B for any A and B implies A >s INT_MIN on success path
+    // A >u B for any A and B implies A >u UINT_MIN on success path
+    if ((ICI->getPredicate() == ICmpInst::ICMP_SGT ||
+         ICI->getPredicate() == ICmpInst::ICMP_UGT)) {
+      ConstantRange Min = ICI->isSigned() ?
+        ConstantRange(APInt::getSignedMinValue(BitWidth)) :
+        ConstantRange(APInt::getMinValue(BitWidth));
+      ConstantRange TrueValues =
+        ConstantRange::makeAllowedICmpRegion(ICI->getPredicate(), Min);
+      Result = LVILatticeVal::getRange(std::move(TrueValues));
+      return true;
+    }
+  }
+
   return false;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19559.55096.patch
Type: text/x-patch
Size: 2839 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160426/71bb069c/attachment.bin>


More information about the llvm-commits mailing list