From b8aa60d240c62f4a2e7eaaba707dceaaff7704e8 Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Tue, 5 Dec 2017 12:18:15 +0000 Subject: [PATCH] [InstCombine] Don't crash on out of bounds shifts Differential Revision: https://reviews.llvm.org/D40649 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319761 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ValueTracking.cpp | 30 +++++++++-------- .../InstCombine/out-of-bounds-indexes.ll | 33 +++++++++++++++++++ 2 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 test/Transforms/InstCombine/out-of-bounds-indexes.ll diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 106a4a71f93..8270f9c1072 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -548,7 +548,7 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, m_BitCast(m_Specific(V)))); CmpInst::Predicate Pred; - ConstantInt *C; + uint64_t C; // assume(v = a) if (match(Arg, m_c_ICmp(Pred, m_V, m_Value(A))) && Pred == ICmpInst::ICMP_EQ && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { @@ -650,51 +650,55 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Arg, m_c_ICmp(Pred, m_Shl(m_V, m_ConstantInt(C)), m_Value(A))) && Pred == ICmpInst::ICMP_EQ && - isValidAssumeForContext(I, Q.CxtI, Q.DT)) { + isValidAssumeForContext(I, Q.CxtI, Q.DT) && + C < BitWidth) { KnownBits RHSKnown(BitWidth); computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); // For those bits in RHS that are known, we can propagate them to known // bits in V shifted to the right by C. - RHSKnown.Zero.lshrInPlace(C->getZExtValue()); + RHSKnown.Zero.lshrInPlace(C); Known.Zero |= RHSKnown.Zero; - RHSKnown.One.lshrInPlace(C->getZExtValue()); + RHSKnown.One.lshrInPlace(C); Known.One |= RHSKnown.One; // assume(~(v << c) = a) } else if (match(Arg, m_c_ICmp(Pred, m_Not(m_Shl(m_V, m_ConstantInt(C))), m_Value(A))) && Pred == ICmpInst::ICMP_EQ && - isValidAssumeForContext(I, Q.CxtI, Q.DT)) { + isValidAssumeForContext(I, Q.CxtI, Q.DT) && + C < BitWidth) { KnownBits RHSKnown(BitWidth); computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); // For those bits in RHS that are known, we can propagate them inverted // to known bits in V shifted to the right by C. - RHSKnown.One.lshrInPlace(C->getZExtValue()); + RHSKnown.One.lshrInPlace(C); Known.Zero |= RHSKnown.One; - RHSKnown.Zero.lshrInPlace(C->getZExtValue()); + RHSKnown.Zero.lshrInPlace(C); Known.One |= RHSKnown.Zero; // assume(v >> c = a) } else if (match(Arg, m_c_ICmp(Pred, m_Shr(m_V, m_ConstantInt(C)), m_Value(A))) && Pred == ICmpInst::ICMP_EQ && - isValidAssumeForContext(I, Q.CxtI, Q.DT)) { + isValidAssumeForContext(I, Q.CxtI, Q.DT) && + C < BitWidth) { KnownBits RHSKnown(BitWidth); computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); // For those bits in RHS that are known, we can propagate them to known // bits in V shifted to the right by C. - Known.Zero |= RHSKnown.Zero << C->getZExtValue(); - Known.One |= RHSKnown.One << C->getZExtValue(); + Known.Zero |= RHSKnown.Zero << C; + Known.One |= RHSKnown.One << C; // assume(~(v >> c) = a) } else if (match(Arg, m_c_ICmp(Pred, m_Not(m_Shr(m_V, m_ConstantInt(C))), m_Value(A))) && Pred == ICmpInst::ICMP_EQ && - isValidAssumeForContext(I, Q.CxtI, Q.DT)) { + isValidAssumeForContext(I, Q.CxtI, Q.DT) && + C < BitWidth) { KnownBits RHSKnown(BitWidth); computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); // For those bits in RHS that are known, we can propagate them inverted // to known bits in V shifted to the right by C. - Known.Zero |= RHSKnown.One << C->getZExtValue(); - Known.One |= RHSKnown.Zero << C->getZExtValue(); + Known.Zero |= RHSKnown.One << C; + Known.One |= RHSKnown.Zero << C; // assume(v >=_s c) where c is non-negative } else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) && Pred == ICmpInst::ICMP_SGE && diff --git a/test/Transforms/InstCombine/out-of-bounds-indexes.ll b/test/Transforms/InstCombine/out-of-bounds-indexes.ll new file mode 100644 index 00000000000..a1887d27550 --- /dev/null +++ b/test/Transforms/InstCombine/out-of-bounds-indexes.ll @@ -0,0 +1,33 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s +; Check that we don't crash on unreasonable constant indexes + +define i32 @test_out_of_bounds(i32 %a, i1 %x, i1 %y) { +; CHECK-LABEL: @test_out_of_bounds( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], 3 +; CHECK-NEXT: tail call void @llvm.assume(i1 false) +; CHECK-NEXT: ret i32 [[AND1]] +; +entry: + %and1 = and i32 %a, 3 + %B = lshr i32 %and1, -2147483648 + %cmp = icmp eq i32 %B, 1 + tail call void @llvm.assume(i1 %cmp) + ret i32 %and1 +} + +define i128 @test_non64bit(i128 %a) { +; CHECK-LABEL: @test_non64bit( +; CHECK-NEXT: [[AND1:%.*]] = and i128 [[A:%.*]], 3 +; CHECK-NEXT: tail call void @llvm.assume(i1 false) +; CHECK-NEXT: ret i128 [[AND1]] +; + %and1 = and i128 %a, 3 + %B = lshr i128 %and1, -1 + %cmp = icmp eq i128 %B, 1 + tail call void @llvm.assume(i1 %cmp) + ret i128 %and1 +} + +declare void @llvm.assume(i1)