]> granicus.if.org Git - llvm/commitdiff
[InstCombine] enable (X >>?exact C1) << C2 --> X >>?exact (C1-C2) for vectors with...
authorSanjay Patel <spatel@rotateright.com>
Mon, 30 Jan 2017 18:40:23 +0000 (18:40 +0000)
committerSanjay Patel <spatel@rotateright.com>
Mon, 30 Jan 2017 18:40:23 +0000 (18:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293524 91177308-0d34-0410-b5e6-96231b3b80d8

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

index fb90814b6ecc451dc29054d2a52f3b30eb1afb0c..edd51baf2a8981ad024f70397387cc874ab37d65 100644 (file)
@@ -373,18 +373,6 @@ foldShiftByConstOfShiftByConst(BinaryOperator &I, const APInt *COp1,
   if (ShiftAmt2 < ShiftAmt1) {
     uint32_t ShiftDiff = ShiftAmt1 - ShiftAmt2;
 
-    // (X >>?exact C1) << C2 --> X >>?exact (C1-C2)
-    // The inexact version is deferred to DAGCombine so we don't hide shl
-    // behind a bit mask.
-    if (I.getOpcode() == Instruction::Shl &&
-        ShiftOp->getOpcode() != Instruction::Shl && ShiftOp->isExact()) {
-      ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff);
-      BinaryOperator *NewShr =
-          BinaryOperator::Create(ShiftOp->getOpcode(), X, ShiftDiffCst);
-      NewShr->setIsExact(true);
-      return NewShr;
-    }
-
     // (X << C1) >>u C2  --> X << (C1-C2) & (-1 >> C2)
     if (I.getOpcode() == Instruction::LShr &&
         ShiftOp->getOpcode() == Instruction::Shl) {
@@ -670,18 +658,28 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) {
       return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, Mask));
     }
 
-    const APInt *ShrAmt;
-    if (match(Op0, m_CombineOr(m_Exact(m_LShr(m_Value(X), m_APInt(ShrAmt))),
-                               m_Exact(m_AShr(m_Value(X), m_APInt(ShrAmt))))) &&
-        ShrAmt->ult(*ShAmtAPInt)) {
-      // If C1 < C2: (X >>?,exact C1) << C2 --> X << (C2 - C1)
-      // The inexact version is deferred to DAGCombine, so we don't hide shl
-      // behind a bit mask.
-      Constant *ShiftDiffCst = ConstantInt::get(Ty, *ShAmtAPInt - *ShrAmt);
-      auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiffCst);
-      NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
-      NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
-      return NewShl;
+    // The inexact versions are deferred to DAGCombine, so we don't hide shl
+    // behind a bit mask.
+    const APInt *ShrOp1;
+    if (match(Op0, m_CombineOr(m_Exact(m_LShr(m_Value(X), m_APInt(ShrOp1))),
+                               m_Exact(m_AShr(m_Value(X), m_APInt(ShrOp1)))))) {
+      unsigned ShrAmt = ShrOp1->getZExtValue();
+      if (ShrAmt < ShAmt) {
+        // If C1 < C2: (X >>?,exact C1) << C2 --> X << (C2 - C1)
+        Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShrAmt);
+        auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
+        NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
+        NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
+        return NewShl;
+      }
+      if (ShrAmt > ShAmt) {
+        // If C1 > C2: (X >>?exact C1) << C2 --> X >>?exact (C1 - C2)
+        Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmt);
+        auto *NewShr = BinaryOperator::Create(
+            cast<BinaryOperator>(Op0)->getOpcode(), X, ShiftDiff);
+        NewShr->setIsExact(true);
+        return NewShr;
+      }
     }
 
     // If the shifted-out value is known-zero, then this is a NUW shift.
index 0c6655c800debc4565c32903370522b06b066f82..ea4936e373747c656f2ea86eefa7a3c94f69348b 100644 (file)
@@ -806,8 +806,7 @@ define i32 @test46(i32 %a) {
 
 define <2 x i32> @test46_splat_vec(<2 x i32> %a) {
 ; CHECK-LABEL: @test46_splat_vec(
-; CHECK-NEXT:    [[Y:%.*]] = ashr exact <2 x i32> %a, <i32 3, i32 3>
-; CHECK-NEXT:    [[Z:%.*]] = shl nsw <2 x i32> [[Y]], <i32 1, i32 1>
+; CHECK-NEXT:    [[Z:%.*]] = ashr exact <2 x i32> %a, <i32 2, i32 2>
 ; CHECK-NEXT:    ret <2 x i32> [[Z]]
 ;
   %y = ashr exact <2 x i32> %a, <i32 3, i32 3>
@@ -831,8 +830,7 @@ define i8 @test47(i8 %a) {
 
 define <2 x i8> @test47_splat_vec(<2 x i8> %a) {
 ; CHECK-LABEL: @test47_splat_vec(
-; CHECK-NEXT:    [[Y:%.*]] = lshr exact <2 x i8> %a, <i8 3, i8 3>
-; CHECK-NEXT:    [[Z:%.*]] = shl nuw nsw <2 x i8> [[Y]], <i8 1, i8 1>
+; CHECK-NEXT:    [[Z:%.*]] = lshr exact <2 x i8> %a, <i8 2, i8 2>
 ; CHECK-NEXT:    ret <2 x i8> [[Z]]
 ;
   %y = lshr exact <2 x i8> %a, <i8 3, i8 3>