[InstCombine] visitShl - ensure inner shifts have inrange amounts
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Thu, 29 Oct 2020 14:30:42 +0000 (14:30 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Thu, 29 Oct 2020 15:28:15 +0000 (15:28 +0000)
Noticed when fixing OSS Fuzz #26716

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/test/Transforms/InstCombine/shift.ll

index 6f1868a..4eaf1bc 100644 (file)
@@ -923,7 +923,8 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
     }
 
     const APInt *ShOp1;
-    if (match(Op0, m_Exact(m_Shr(m_Value(X), m_APInt(ShOp1))))) {
+    if (match(Op0, m_Exact(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
+        ShOp1->ult(BitWidth)) {
       unsigned ShrAmt = ShOp1->getZExtValue();
       if (ShrAmt < ShAmt) {
         // If C1 < C2: (X >>?,exact C1) << C2 --> X << (C2 - C1)
@@ -943,7 +944,8 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
       }
     }
 
-    if (match(Op0, m_OneUse(m_Shr(m_Value(X), m_APInt(ShOp1))))) {
+    if (match(Op0, m_OneUse(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
+        ShOp1->ult(BitWidth)) {
       unsigned ShrAmt = ShOp1->getZExtValue();
       if (ShrAmt < ShAmt) {
         // If C1 < C2: (X >>? C1) << C2 --> X << (C2 - C1) & (-1 << C2)
@@ -968,7 +970,7 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
       }
     }
 
-    if (match(Op0, m_Shl(m_Value(X), m_APInt(ShOp1)))) {
+    if (match(Op0, m_Shl(m_Value(X), m_APInt(ShOp1))) && ShOp1->ult(BitWidth)) {
       unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
       // Oversized shifts are simplified to zero in InstSimplify.
       if (AmtSum < BitWidth)
index a19dc34..5fff5e2 100644 (file)
@@ -1721,6 +1721,26 @@ define i177 @lshr_out_of_range(i177 %Y, i177** %A2) {
   ret i177 %B1
 }
 
+; OSS Fuzz #26716
+; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26716
+define i177 @lshr_out_of_range2(i177 %Y, i177** %A2) {
+; CHECK-LABEL: @lshr_out_of_range2(
+; CHECK-NEXT:    store i177** [[A2:%.*]], i177*** undef, align 8
+; CHECK-NEXT:    ret i177 0
+;
+  %B5 = udiv i177 %Y, -1
+  %B = sdiv i177 %B5, -1
+  %B4 = add i177 %B5, %B
+  %B2 = add i177 %B4, -1
+  %B6 = mul i177 %B5, %B2
+  %B12 = lshr i177 %Y, %B6
+  %C8 = icmp ugt i177 %B12, %B4
+  %G18 = getelementptr i177*, i177** %A2, i1 %C8
+  store i177** %G18, i177*** undef, align 8
+  %B1 = udiv i177 %B5, %B6
+  ret i177 %B1
+}
+
 ; OSS Fuzz #5032
 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5032
 define void @ashr_out_of_range(i177* %A) {