[InstCombine] don't try to shift an illegal amount (PR26760)
authorSanjay Patel <spatel@rotateright.com>
Mon, 11 Apr 2016 16:50:32 +0000 (16:50 +0000)
committerSanjay Patel <spatel@rotateright.com>
Mon, 11 Apr 2016 16:50:32 +0000 (16:50 +0000)
This is the straightforward fix for PR26760:
https://llvm.org/bugs/show_bug.cgi?id=26760

But we still need to make some changes to generalize this helper function
and then send the lshr case into here.

llvm-svn: 265960

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

index 0115678..6d68a55 100644 (file)
@@ -83,7 +83,9 @@ static bool canEvaluateShiftedShift(unsigned FirstShiftAmt,
   // If the 2nd shift is bigger than the 1st, we can fold:
   //   shr(c1) + shl(c2) -> shl(c3) + and(c4)
   // but it isn't profitable unless we know the and'd out bits are already zero.
-  if (SecondShiftAmt > FirstShiftAmt) {
+  // Also check that the 2nd shift is valid (less than the type width) or we'll
+  // crash trying to produce the bit mask for the 'and'.
+  if (SecondShiftAmt > FirstShiftAmt && SecondShiftAmt < TypeWidth) {
     unsigned MaskShift = TypeWidth - SecondShiftAmt;
     APInt Mask = APInt::getLowBitsSet(TypeWidth, FirstShiftAmt) << MaskShift;
     if (IC.MaskedValueIsZero(SecondShift->getOperand(0), Mask, 0, CxtI))
index 23a45e0..2968a9b 100644 (file)
@@ -1,7 +1,9 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -instcombine -S | FileCheck %s
 
-; This would crash if we didn't check for a negative shift.
+; These would crash if we didn't check for a negative shift.
+
+; https://llvm.org/bugs/show_bug.cgi?id=12967
 
 define void @pr12967() {
 ; CHECK-LABEL: @pr12967(
@@ -20,3 +22,22 @@ loop:
   br label %loop
 }
 
+; https://llvm.org/bugs/show_bug.cgi?id=26760
+
+define void @pr26760() {
+; CHECK-LABEL: @pr26760(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label %loop
+; CHECK:       loop:
+; CHECK-NEXT:    br label %loop
+;
+entry:
+  br label %loop
+
+loop:
+  %c = phi i32 [ %shl, %loop ], [ undef, %entry ]
+  %shr = lshr i32 %c, 7
+  %shl = shl i32 %shr, -2
+  br label %loop
+}
+