forked from OSchip/llvm-project
[InstCombine] Check for out of range shift values using APInt before calling getZExtValue
Reduced from oss-fuzz #4871 test case llvm-svn: 321748
This commit is contained in:
parent
8232e88dd5
commit
3bf2d64589
|
@ -87,8 +87,7 @@ static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl,
|
|||
// Equal shift amounts in opposite directions become bitwise 'and':
|
||||
// lshr (shl X, C), C --> and X, C'
|
||||
// shl (lshr X, C), C --> and X, C'
|
||||
unsigned InnerShAmt = InnerShiftConst->getZExtValue();
|
||||
if (InnerShAmt == OuterShAmt)
|
||||
if (*InnerShiftConst == OuterShAmt)
|
||||
return true;
|
||||
|
||||
// If the 2nd shift is bigger than the 1st, we can fold:
|
||||
|
@ -98,7 +97,8 @@ static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl,
|
|||
// Also, check that the inner shift is valid (less than the type width) or
|
||||
// we'll crash trying to produce the bit mask for the 'and'.
|
||||
unsigned TypeWidth = InnerShift->getType()->getScalarSizeInBits();
|
||||
if (InnerShAmt > OuterShAmt && InnerShAmt < TypeWidth) {
|
||||
if (InnerShiftConst->ugt(OuterShAmt) && InnerShiftConst->ult(TypeWidth)) {
|
||||
unsigned InnerShAmt = InnerShiftConst->getZExtValue();
|
||||
unsigned MaskShift =
|
||||
IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
|
||||
APInt Mask = APInt::getLowBitsSet(TypeWidth, OuterShAmt) << MaskShift;
|
||||
|
@ -135,7 +135,7 @@ static bool canEvaluateShifted(Value *V, unsigned NumBits, bool IsLeftShift,
|
|||
ConstantInt *CI = nullptr;
|
||||
if ((IsLeftShift && match(I, m_LShr(m_Value(), m_ConstantInt(CI)))) ||
|
||||
(!IsLeftShift && match(I, m_Shl(m_Value(), m_ConstantInt(CI))))) {
|
||||
if (CI->getZExtValue() == NumBits) {
|
||||
if (CI->getValue() == NumBits) {
|
||||
// TODO: Check that the input bits are already zero with MaskedValueIsZero
|
||||
#if 0
|
||||
// If this is a truncate of a logical shr, we can truncate it to a smaller
|
||||
|
|
|
@ -1592,3 +1592,24 @@ define i32 @ashr_select_xor_false(i32 %x, i1 %cond) {
|
|||
%3 = ashr i32 %2, 1
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
; OSS Fuzz #4871
|
||||
; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4871
|
||||
define i177 @lshr_out_of_range(i177 %Y, i177** %A2) {
|
||||
; CHECK-LABEL: @lshr_out_of_range(
|
||||
; CHECK-NEXT: store i177** [[A2:%.*]], i177*** undef, align 8
|
||||
; CHECK-NEXT: ret i177 0
|
||||
;
|
||||
%B5 = udiv i177 %Y, -1
|
||||
%B4 = add i177 %B5, -1
|
||||
%B2 = add i177 %B4, -1
|
||||
%B6 = mul i177 %B5, %B2
|
||||
%B3 = add i177 %B2, %B2
|
||||
%B10 = sub i177 %B5, %B3
|
||||
%B12 = lshr i177 %Y, %B6
|
||||
%C8 = icmp ugt i177 %B12, %B4
|
||||
%G18 = getelementptr i177*, i177** %A2, i1 %C8
|
||||
store i177** %G18, i177*** undef
|
||||
%B1 = udiv i177 %B10, %B6
|
||||
ret i177 %B1
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue