From ca7a21e00060cb4ba883d421924de91cc67d1ab2 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 8 Feb 2018 14:52:40 +0000 Subject: [PATCH] [ValueTracking] don't crash when assumptions conflict (PR36270) The last assume in the test says that %B12 is 0. The first assume says that %and1 is less than %B12. Therefore, %and1 is unsigned less than 0...does not compute. That means this line: Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros() + 1); ...tries to set more bits than exist. Differential Revision: https://reviews.llvm.org/D43052 llvm-svn: 324610 --- lib/Analysis/ValueTracking.cpp | 8 ++++++++ test/Transforms/InstSimplify/assume.ll | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 5a8bd4bb7a1..ada31e09cbd 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -816,6 +816,14 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, KnownBits RHSKnown(BitWidth); computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + // If the RHS is known zero, then this assumption must be wrong (nothing + // is unsigned less than zero). Signal a conflict and get out of here. + if (RHSKnown.isZero()) { + Known.Zero.setAllBits(); + Known.One.setAllBits(); + break; + } + // Whatever high bits in c are zero are known to be zero (if c is a power // of 2, then one more). if (isKnownToBeAPowerOfTwo(A, false, Depth + 1, Query(Q, I))) diff --git a/test/Transforms/InstSimplify/assume.ll b/test/Transforms/InstSimplify/assume.ll index 66f2120f292..06613a4ce37 100644 --- a/test/Transforms/InstSimplify/assume.ll +++ b/test/Transforms/InstSimplify/assume.ll @@ -5,6 +5,7 @@ ; CHECK: remark: /tmp/s.c:1:13: Detected conflicting code assumptions. ; CHECK: remark: /tmp/s.c:4:10: Detected conflicting code assumptions. +; CHECK: remark: /tmp/s.c:5:50: Detected conflicting code assumptions. define void @test1() { ; CHECK-LABEL: @test1( @@ -50,6 +51,24 @@ define i8 @conflicting_assumptions(i8 %x) !dbg !10 { ret i8 %add } +; Another case of conflicting assumptions. This would crash because we'd +; try to set more known bits than existed in the known bits struct. + +define void @PR36270(i32 %b) !dbg !13 { +; CHECK-LABEL: @PR36270( +; CHECK-NEXT: tail call void @llvm.assume(i1 false) +; CHECK-NEXT: unreachable +; + %B7 = xor i32 -1, 2147483647 + %and1 = and i32 %b, 3 + %B12 = lshr i32 %B7, %and1, !dbg !14 + %C1 = icmp ult i32 %and1, %B12 + tail call void @llvm.assume(i1 %C1) + %cmp2 = icmp eq i32 0, %B12 + tail call void @llvm.assume(i1 %cmp2) + unreachable +} + declare void @llvm.assume(i1) nounwind !llvm.dbg.cu = !{!0} @@ -69,4 +88,6 @@ declare void @llvm.assume(i1) nounwind !10 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, variables: !2) !11 = !DILocation(line: 4, column: 10, scope: !10) !12 = !DILocation(line: 4, column: 3, scope: !10) +!13 = distinct !DISubprogram(name: "PR36270", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, variables: !2) +!14 = !DILocation(line: 5, column: 50, scope: !13)