[PATCH] D29395: [ValueTracking] avoid crashing from bad assumptions (PR31809)

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 07:33:36 PST 2017


spatel created this revision.
Herald added a subscriber: mcrosier.

A program may contain llvm.assume info that disagrees with other analysis. This may be caused by UB in the program, so we must not crash because of that.

As noted in the code comments and PR31809:
https://llvm.org/bugs/show_bug.cgi?id=31809
...we can do better, but this at least avoids the assert/crash in the bug report.


https://reviews.llvm.org/D29395

Files:
  lib/Analysis/ValueTracking.cpp
  test/Transforms/InstSimplify/assume.ll


Index: test/Transforms/InstSimplify/assume.ll
===================================================================
--- test/Transforms/InstSimplify/assume.ll
+++ test/Transforms/InstSimplify/assume.ll
@@ -10,5 +10,41 @@
 
 }
 
+; The alloca guarantees that the low bits of %a are zero because of alignment.
+; The assume says the opposite. The assume is processed last, so that's the 
+; return value. There's no way to win (we can't undo transforms that happened
+; based on half-truths), so just don't crash.
+
+define i64 @PR31809() {
+; CHECK-LABEL: @PR31809(
+; CHECK-NEXT:    ret i64 3
+;
+  %a = alloca i32
+  %t1 = ptrtoint i32* %a to i64
+  %cond = icmp eq i64 %t1, 3
+  call void @llvm.assume(i1 %cond)
+  ret i64 %t1
+}
+
+; Similar to above: there's no way to know which assumption is truthful,
+; so just don't crash. The second icmp+assume gets processed later, so that
+; determines the return value. This can be improved by permanently invalidating
+; the cached assumptions for this function. 
+
+define i8 @conflicting_assumptions(i8 %x) {
+; CHECK-LABEL: @conflicting_assumptions(
+; CHECK-NEXT:    call void @llvm.assume(i1 false)
+; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i8 %x, 4
+; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])
+; CHECK-NEXT:    ret i8 5
+;
+  %add = add i8 %x, 1
+  %cond1 = icmp eq i8 %x, 3
+  call void @llvm.assume(i1 %cond1)
+  %cond2 = icmp eq i8 %x, 4
+  call void @llvm.assume(i1 %cond2)
+  ret i8 %add
+}
+
 declare void @llvm.assume(i1) nounwind
 
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -788,6 +788,23 @@
           APInt::getHighBitsSet(BitWidth, RHSKnownZero.countLeadingOnes());
     }
   }
+
+  // If assumptions conflict with each other or previous known bits, then we
+  // have a logical fallacy. This should only happen when a program has
+  // undefined behavior. We can't assert/crash, so clear out the known bits and
+  // hope for the best.
+
+  // FIXME: Publish a warning/remark that we have encountered UB or the compiler
+  // is broken.
+
+  // FIXME: Implement a stronger version of "I give up" by invalidating/clearing
+  // the assumption cache. This should indicate that the cache is corrupted so
+  // future callers will not waste time repopulating it with faulty assumptions.
+
+  if ((KnownZero & KnownOne) != 0) {
+    KnownZero.clearAllBits();
+    KnownOne.clearAllBits();
+  }
 }
 
 // Compute known bits from a shift operator, including those with a


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29395.86633.patch
Type: text/x-patch
Size: 2575 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170201/8867a0da/attachment.bin>


More information about the llvm-commits mailing list