Skip to content
This repository has been archived by the owner on Feb 5, 2019. It is now read-only.

Commit

Permalink
Merge pull request #96 from arielb1/unreachable-paradox
Browse files Browse the repository at this point in the history
[ValueTracking] avoid crashing from bad assumptions (PR31809)
  • Loading branch information
alexcrichton authored Nov 9, 2017
2 parents 51f104b + c5c2441 commit 896fb22
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,23 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
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
Expand Down
36 changes: 36 additions & 0 deletions test/Transforms/InstSimplify/assume.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,41 @@ define void @test1() {

}

; 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

0 comments on commit 896fb22

Please sign in to comment.