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

Commit c5c2441

Browse files
rotaterightarielb1
authored andcommitted
[ValueTracking] avoid crashing from bad assumptions (PR31809)
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: 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. Differential Revision: https://reviews.llvm.org/D29395 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293773 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 83b72ce commit c5c2441

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/Analysis/ValueTracking.cpp

Lines changed: 17 additions & 0 deletions
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

Lines changed: 36 additions & 0 deletions
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)