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

Commit 896fb22

Browse files
authored
Merge pull request #96 from arielb1/unreachable-paradox
[ValueTracking] avoid crashing from bad assumptions (PR31809)
2 parents 51f104b + c5c2441 commit 896fb22

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/Analysis/ValueTracking.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,23 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
781781
APInt::getHighBitsSet(BitWidth, RHSKnownZero.countLeadingOnes());
782782
}
783783
}
784+
785+
// If assumptions conflict with each other or previous known bits, then we
786+
// have a logical fallacy. This should only happen when a program has
787+
// undefined behavior. We can't assert/crash, so clear out the known bits and
788+
// hope for the best.
789+
790+
// FIXME: Publish a warning/remark that we have encountered UB or the compiler
791+
// is broken.
792+
793+
// FIXME: Implement a stronger version of "I give up" by invalidating/clearing
794+
// the assumption cache. This should indicate that the cache is corrupted so
795+
// future callers will not waste time repopulating it with faulty assumptions.
796+
797+
if ((KnownZero & KnownOne) != 0) {
798+
KnownZero.clearAllBits();
799+
KnownOne.clearAllBits();
800+
}
784801
}
785802

786803
// Compute known bits from a shift operator, including those with a

test/Transforms/InstSimplify/assume.ll

+36
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,41 @@ define void @test1() {
1010

1111
}
1212

13+
; The alloca guarantees that the low bits of %a are zero because of alignment.
14+
; The assume says the opposite. The assume is processed last, so that's the
15+
; return value. There's no way to win (we can't undo transforms that happened
16+
; based on half-truths), so just don't crash.
17+
18+
define i64 @PR31809() {
19+
; CHECK-LABEL: @PR31809(
20+
; CHECK-NEXT: ret i64 3
21+
;
22+
%a = alloca i32
23+
%t1 = ptrtoint i32* %a to i64
24+
%cond = icmp eq i64 %t1, 3
25+
call void @llvm.assume(i1 %cond)
26+
ret i64 %t1
27+
}
28+
29+
; Similar to above: there's no way to know which assumption is truthful,
30+
; so just don't crash. The second icmp+assume gets processed later, so that
31+
; determines the return value. This can be improved by permanently invalidating
32+
; the cached assumptions for this function.
33+
34+
define i8 @conflicting_assumptions(i8 %x) {
35+
; CHECK-LABEL: @conflicting_assumptions(
36+
; CHECK-NEXT: call void @llvm.assume(i1 false)
37+
; CHECK-NEXT: [[COND2:%.*]] = icmp eq i8 %x, 4
38+
; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
39+
; CHECK-NEXT: ret i8 5
40+
;
41+
%add = add i8 %x, 1
42+
%cond1 = icmp eq i8 %x, 3
43+
call void @llvm.assume(i1 %cond1)
44+
%cond2 = icmp eq i8 %x, 4
45+
call void @llvm.assume(i1 %cond2)
46+
ret i8 %add
47+
}
48+
1349
declare void @llvm.assume(i1) nounwind
1450

0 commit comments

Comments
 (0)