[llvm] r292151 - [InstCombine] use m_APInt to allow shift-shift folds for vectors with splat constants

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 16 11:35:45 PST 2017


Author: spatel
Date: Mon Jan 16 13:35:45 2017
New Revision: 292151

URL: http://llvm.org/viewvc/llvm-project?rev=292151&view=rev
Log:
[InstCombine] use m_APInt to allow shift-shift folds for vectors with splat constants

Some existing 'FIXME' tests are still not folded because of splat holes in value tracking.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
    llvm/trunk/test/Transforms/InstCombine/apint-shift.ll
    llvm/trunk/test/Transforms/InstCombine/shift.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp?rev=292151&r1=292150&r2=292151&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Mon Jan 16 13:35:45 2017
@@ -72,9 +72,9 @@ static bool canEvaluateShiftedShift(unsi
                                     Instruction *CxtI) {
   assert(SecondShift->isLogicalShift() && "Unexpected instruction type");
 
-  // We need constant shifts.
-  auto *SecondShiftConst = dyn_cast<ConstantInt>(SecondShift->getOperand(1));
-  if (!SecondShiftConst)
+  // We need constant scalar or constant splat shifts.
+  const APInt *SecondShiftConst;
+  if (!match(SecondShift->getOperand(1), m_APInt(SecondShiftConst)))
     return false;
 
   unsigned SecondShiftAmt = SecondShiftConst->getZExtValue();
@@ -200,7 +200,8 @@ static Value *foldShiftedShift(BinaryOpe
   unsigned TypeWidth = ShType->getScalarSizeInBits();
 
   // We only accept shifts-by-a-constant in canEvaluateShifted().
-  ConstantInt *C1 = cast<ConstantInt>(InnerShift->getOperand(1));
+  const APInt *C1;
+  match(InnerShift->getOperand(1), m_APInt(C1));
   unsigned InnerShAmt = C1->getZExtValue();
 
   // Change the shift amount and clear the appropriate IR flags.

Modified: llvm/trunk/test/Transforms/InstCombine/apint-shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/apint-shift.ll?rev=292151&r1=292150&r2=292151&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/apint-shift.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/apint-shift.ll Mon Jan 16 13:35:45 2017
@@ -113,71 +113,66 @@ define i19 @test10(i19 %X) {
   ret i19 %sh2
 }
 
-; FIXME: Two right shifts in the same direction:
+; Two right shifts in the same direction:
 ; lshr (lshr X, C1), C2 --> lshr X, C1 + C2
 
 define <2 x i19> @lshr_lshr_splat_vec(<2 x i19> %X) {
 ; CHECK-LABEL: @lshr_lshr_splat_vec(
-; CHECK-NEXT:    [[SH1:%.*]] = lshr <2 x i19> %X, <i19 3, i19 3>
-; CHECK-NEXT:    [[SH2:%.*]] = lshr <2 x i19> [[SH1]], <i19 2, i19 2>
-; CHECK-NEXT:    ret <2 x i19> [[SH2]]
+; CHECK-NEXT:    [[SH1:%.*]] = lshr <2 x i19> %X, <i19 5, i19 5>
+; CHECK-NEXT:    ret <2 x i19> [[SH1]]
 ;
   %sh1 = lshr <2 x i19> %X, <i19 3, i19 3>
   %sh2 = lshr <2 x i19> %sh1, <i19 2, i19 2>
   ret <2 x i19> %sh2
 }
 
-; FIXME: Two left shifts in the same direction:
+; Two left shifts in the same direction:
 ; shl (shl X, C1), C2 -->  shl X, C1 + C2
 
 define <2 x i19> @shl_shl_splat_vec(<2 x i19> %X) {
 ; CHECK-LABEL: @shl_shl_splat_vec(
-; CHECK-NEXT:    [[SH1:%.*]] = shl <2 x i19> %X, <i19 3, i19 3>
-; CHECK-NEXT:    [[SH2:%.*]] = shl <2 x i19> [[SH1]], <i19 2, i19 2>
-; CHECK-NEXT:    ret <2 x i19> [[SH2]]
+; CHECK-NEXT:    [[SH1:%.*]] = shl <2 x i19> %X, <i19 5, i19 5>
+; CHECK-NEXT:    ret <2 x i19> [[SH1]]
 ;
   %sh1 = shl <2 x i19> %X, <i19 3, i19 3>
   %sh2 = shl <2 x i19> %sh1, <i19 2, i19 2>
   ret <2 x i19> %sh2
 }
 
-; FIXME: Equal shift amounts in opposite directions become bitwise 'and':
+; Equal shift amounts in opposite directions become bitwise 'and':
 ; lshr (shl X, C), C --> and X, C'
 
 define <2 x i19> @eq_shl_lshr_splat_vec(<2 x i19> %X) {
 ; CHECK-LABEL: @eq_shl_lshr_splat_vec(
-; CHECK-NEXT:    [[SH1:%.*]] = shl <2 x i19> %X, <i19 3, i19 3>
-; CHECK-NEXT:    [[SH2:%.*]] = lshr exact <2 x i19> [[SH1]], <i19 3, i19 3>
-; CHECK-NEXT:    ret <2 x i19> [[SH2]]
+; CHECK-NEXT:    [[SH1:%.*]] = and <2 x i19> %X, <i19 65535, i19 65535>
+; CHECK-NEXT:    ret <2 x i19> [[SH1]]
 ;
   %sh1 = shl <2 x i19> %X, <i19 3, i19 3>
   %sh2 = lshr <2 x i19> %sh1, <i19 3, i19 3>
   ret <2 x i19> %sh2
 }
 
-; FIXME: Equal shift amounts in opposite directions become bitwise 'and':
+; Equal shift amounts in opposite directions become bitwise 'and':
 ; shl (lshr X, C), C --> and X, C'
 
 define <2 x i19> @eq_lshr_shl_splat_vec(<2 x i19> %X) {
 ; CHECK-LABEL: @eq_lshr_shl_splat_vec(
-; CHECK-NEXT:    [[SH1:%.*]] = lshr <2 x i19> %X, <i19 3, i19 3>
-; CHECK-NEXT:    [[SH2:%.*]] = shl nuw <2 x i19> [[SH1]], <i19 3, i19 3>
-; CHECK-NEXT:    ret <2 x i19> [[SH2]]
+; CHECK-NEXT:    [[SH1:%.*]] = and <2 x i19> %X, <i19 -8, i19 -8>
+; CHECK-NEXT:    ret <2 x i19> [[SH1]]
 ;
   %sh1 = lshr <2 x i19> %X, <i19 3, i19 3>
   %sh2 = shl <2 x i19> %sh1, <i19 3, i19 3>
   ret <2 x i19> %sh2
 }
 
-; FIXME: In general, we would need an 'and' for this transform, but the masked-off bits are known zero.
+; In general, we would need an 'and' for this transform, but the masked-off bits are known zero.
 ; shl (lshr X, C1), C2 --> lshr X, C1 - C2
 
 define <2 x i7> @lshr_shl_splat_vec(<2 x i7> %X) {
 ; CHECK-LABEL: @lshr_shl_splat_vec(
 ; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i7> %X, <i7 -8, i7 -8>
-; CHECK-NEXT:    [[SH1:%.*]] = lshr exact <2 x i7> [[MUL]], <i7 3, i7 3>
-; CHECK-NEXT:    [[SH2:%.*]] = shl nuw nsw <2 x i7> [[SH1]], <i7 2, i7 2>
-; CHECK-NEXT:    ret <2 x i7> [[SH2]]
+; CHECK-NEXT:    [[SH1:%.*]] = lshr exact <2 x i7> [[MUL]], <i7 1, i7 1>
+; CHECK-NEXT:    ret <2 x i7> [[SH1]]
 ;
   %mul = mul <2 x i7> %X, <i7 -8, i7 -8>
   %sh1 = lshr exact <2 x i7> %mul, <i7 3, i7 3>
@@ -185,15 +180,14 @@ define <2 x i7> @lshr_shl_splat_vec(<2 x
   ret <2 x i7> %sh2
 }
 
-; FIXME: In general, we would need an 'and' for this transform, but the masked-off bits are known zero.
+; In general, we would need an 'and' for this transform, but the masked-off bits are known zero.
 ; lshr (shl X, C1), C2 -->  shl X, C1 - C2
 
 define <2 x i7> @shl_lshr_splat_vec(<2 x i7> %X) {
 ; CHECK-LABEL: @shl_lshr_splat_vec(
 ; CHECK-NEXT:    [[DIV:%.*]] = udiv <2 x i7> %X, <i7 9, i7 9>
-; CHECK-NEXT:    [[SH1:%.*]] = shl nuw <2 x i7> [[DIV]], <i7 3, i7 3>
-; CHECK-NEXT:    [[SH2:%.*]] = lshr exact <2 x i7> [[SH1]], <i7 2, i7 2>
-; CHECK-NEXT:    ret <2 x i7> [[SH2]]
+; CHECK-NEXT:    [[SH1:%.*]] = shl nuw nsw <2 x i7> [[DIV]], <i7 1, i7 1>
+; CHECK-NEXT:    ret <2 x i7> [[SH1]]
 ;
   %div = udiv <2 x i7> %X, <i7 9, i7 9>
   %sh1 = shl nuw <2 x i7> %div, <i7 3, i7 3>

Modified: llvm/trunk/test/Transforms/InstCombine/shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/shift.ll?rev=292151&r1=292150&r2=292151&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/shift.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/shift.ll Mon Jan 16 13:35:45 2017
@@ -453,9 +453,8 @@ define i32 @test25(i32 %tmp.2, i32 %AA)
 
 define <2 x i32> @test25_vector(<2 x i32> %tmp.2, <2 x i32> %AA) {
 ; CHECK-LABEL: @test25_vector(
-; CHECK-NEXT:    [[TMP_3:%.*]] = lshr <2 x i32> %tmp.2, <i32 17, i32 17>
-; CHECK-NEXT:    [[TMP_51:%.*]] = shl nuw <2 x i32> [[TMP_3]], <i32 17, i32 17>
-; CHECK-NEXT:    [[X2:%.*]] = add <2 x i32> [[TMP_51]], %AA
+; CHECK-NEXT:    [[TMP_3:%.*]] = and <2 x i32> %tmp.2, <i32 -131072, i32 -131072>
+; CHECK-NEXT:    [[X2:%.*]] = add <2 x i32> [[TMP_3]], %AA
 ; CHECK-NEXT:    [[TMP_6:%.*]] = and <2 x i32> [[X2]], <i32 -131072, i32 -131072>
 ; CHECK-NEXT:    ret <2 x i32> [[TMP_6]]
 ;




More information about the llvm-commits mailing list