mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-30 15:10:30 +00:00
[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
This commit is contained in:
parent
f071b970e4
commit
b8aa60d240
@ -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 &&
|
||||
|
33
test/Transforms/InstCombine/out-of-bounds-indexes.ll
Normal file
33
test/Transforms/InstCombine/out-of-bounds-indexes.ll
Normal file
@ -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)
|
Loading…
Reference in New Issue
Block a user