diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-01-03 18:28:20 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-01-03 18:28:20 +0000 |
| commit | 3bf2d645890f91398e1a28586188fad3c831933a (patch) | |
| tree | ac1ea9dc1b2a1bb22cde39ac6d82b40d99f529f1 | |
| parent | 8232e88dd56a94b5d883479d2d6ae96c11b8d6f1 (diff) | |
| download | bcm5719-llvm-3bf2d645890f91398e1a28586188fad3c831933a.tar.gz bcm5719-llvm-3bf2d645890f91398e1a28586188fad3c831933a.zip | |
[InstCombine] Check for out of range shift values using APInt before calling getZExtValue
Reduced from oss-fuzz #4871 test case
llvm-svn: 321748
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/shift.ll | 21 |
2 files changed, 25 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 44bbb84686a..3d379ad68b6 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -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 diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll index ba52023e0db..38fd5462611 100644 --- a/llvm/test/Transforms/InstCombine/shift.ll +++ b/llvm/test/Transforms/InstCombine/shift.ll @@ -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 +} |

