From ce2b63cf709f6cd335508142fca4850b472f47e3 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 11 Apr 2019 16:39:31 +0000 Subject: [PATCH] [ConstantFold] ExtractConstantBytes - handle shifts on large integer types Use APInt instead of getZExtValue from the ConstantInt until we can confirm that the shift amount is in range. Reduced from OSS-Fuzz #14169 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14169 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358192 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/ConstantFold.cpp | 30 ++++++++-------- .../InstCombine/constant-fold-shifts.ll | 36 +++++++++++++++++++ 2 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 test/Transforms/InstCombine/constant-fold-shifts.ll diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 3784405ecb0..3c01a482a44 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -268,19 +268,20 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, ConstantInt *Amt = dyn_cast(CE->getOperand(1)); if (!Amt) return nullptr; - unsigned ShAmt = Amt->getZExtValue(); + APInt ShAmt = Amt->getValue(); // Cannot analyze non-byte shifts. if ((ShAmt & 7) != 0) return nullptr; - ShAmt >>= 3; + ShAmt.lshrInPlace(3); // If the extract is known to be all zeros, return zero. - if (ByteStart >= CSize-ShAmt) - return Constant::getNullValue(IntegerType::get(CE->getContext(), - ByteSize*8)); + if (ShAmt.uge(CSize - ByteStart)) + return Constant::getNullValue( + IntegerType::get(CE->getContext(), ByteSize * 8)); // If the extract is known to be fully in the input, extract it. - if (ByteStart+ByteSize+ShAmt <= CSize) - return ExtractConstantBytes(CE->getOperand(0), ByteStart+ShAmt, ByteSize); + if (ShAmt.ule(CSize - (ByteStart + ByteSize))) + return ExtractConstantBytes(CE->getOperand(0), + ByteStart + ShAmt.getZExtValue(), ByteSize); // TODO: Handle the 'partially zero' case. return nullptr; @@ -290,19 +291,20 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, ConstantInt *Amt = dyn_cast(CE->getOperand(1)); if (!Amt) return nullptr; - unsigned ShAmt = Amt->getZExtValue(); + APInt ShAmt = Amt->getValue(); // Cannot analyze non-byte shifts. if ((ShAmt & 7) != 0) return nullptr; - ShAmt >>= 3; + ShAmt.lshrInPlace(3); // If the extract is known to be all zeros, return zero. - if (ByteStart+ByteSize <= ShAmt) - return Constant::getNullValue(IntegerType::get(CE->getContext(), - ByteSize*8)); + if (ShAmt.uge(ByteStart + ByteSize)) + return Constant::getNullValue( + IntegerType::get(CE->getContext(), ByteSize * 8)); // If the extract is known to be fully in the input, extract it. - if (ByteStart >= ShAmt) - return ExtractConstantBytes(CE->getOperand(0), ByteStart-ShAmt, ByteSize); + if (ShAmt.ule(ByteStart)) + return ExtractConstantBytes(CE->getOperand(0), + ByteStart - ShAmt.getZExtValue(), ByteSize); // TODO: Handle the 'partially zero' case. return nullptr; diff --git a/test/Transforms/InstCombine/constant-fold-shifts.ll b/test/Transforms/InstCombine/constant-fold-shifts.ll new file mode 100644 index 00000000000..1a5e0c35f51 --- /dev/null +++ b/test/Transforms/InstCombine/constant-fold-shifts.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -instcombine < %s | FileCheck %s + +@A = external constant i32 + +; OSS-Fuzz #14169 +; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14169 +define void @ossfuzz_14169_test1(i32* %a0) { +; CHECK-LABEL: @ossfuzz_14169_test1( +; CHECK-NEXT: bb: +; CHECK-NEXT: ret void +; +bb: + %B = ptrtoint i32* @A to i64 + %C = icmp sge i64 %B, 0 + %X = select i1 %C, i712 0, i712 1 + %B9 = lshr i712 %X, 146783911423364576743092537299333564210980159306769991919205685720763064069663027716481187399048043939495936 + %G5 = getelementptr i64, i64* undef, i712 %B9 + store i64* %G5, i64** undef + ret void +} + +define void @ossfuzz_14169_test2(i32* %a0) { +; CHECK-LABEL: @ossfuzz_14169_test2( +; CHECK-NEXT: bb: +; CHECK-NEXT: ret void +; +bb: + %B = ptrtoint i32* @A to i64 + %C = icmp sge i64 %B, 0 + %X = select i1 %C, i712 0, i712 1 + %B9 = shl i712 %X, 146783911423364576743092537299333564210980159306769991919205685720763064069663027716481187399048043939495936 + %G5 = getelementptr i64, i64* undef, i712 %B9 + store i64* %G5, i64** undef + ret void +} -- 2.40.0