From 3a412958e733be7e075cf5e80d0cdfc54a086c8c Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 29 Jan 2017 17:11:18 +0000 Subject: [PATCH] [InstCombine] enable (X >>?,exact C1) << C2 --> X << (C2 - C1) for vectors with splats git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293435 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineShifts.cpp | 34 +++++++++---------- test/Transforms/InstCombine/shift.ll | 8 ++--- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index 6507bb94519..f6bede8fbb2 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -373,21 +373,6 @@ foldShiftByConstOfShiftByConst(BinaryOperator &I, const APInt *COp1, if (ShiftAmt1 < ShiftAmt2) { uint32_t ShiftDiff = ShiftAmt2 - ShiftAmt1; - // (X >>?,exact C1) << C2 --> X << (C2-C1) - // 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()) { - assert(ShiftOp->getOpcode() == Instruction::LShr || - ShiftOp->getOpcode() == Instruction::AShr); - ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); - BinaryOperator *NewShl = - BinaryOperator::Create(Instruction::Shl, X, ShiftDiffCst); - NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); - NewShl->setHasNoSignedWrap(I.hasNoSignedWrap()); - return NewShl; - } - // (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2) if (I.getOpcode() == Instruction::LShr && ShiftOp->getOpcode() == Instruction::Shl) { @@ -702,6 +687,7 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) { if (match(Op1, m_APInt(ShAmtAPInt))) { unsigned ShAmt = ShAmtAPInt->getZExtValue(); unsigned BitWidth = I.getType()->getScalarSizeInBits(); + Type *Ty = I.getType(); // shl (zext X), ShAmt --> zext (shl X, ShAmt) // This is only valid if X would have zeros shifted out. @@ -710,13 +696,27 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) { unsigned SrcWidth = X->getType()->getScalarSizeInBits(); if (ShAmt < SrcWidth && MaskedValueIsZero(X, APInt::getHighBitsSet(SrcWidth, ShAmt), 0, &I)) - return new ZExtInst(Builder->CreateShl(X, ShAmt), I.getType()); + return new ZExtInst(Builder->CreateShl(X, ShAmt), Ty); } // (X >>u C) << C --> X & (-1 << C) if (match(Op0, m_LShr(m_Value(X), m_Specific(Op1)))) { APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt)); - return BinaryOperator::CreateAnd(X, ConstantInt::get(I.getType(), Mask)); + 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::Create(Instruction::Shl, X, ShiftDiffCst); + NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); + NewShl->setHasNoSignedWrap(I.hasNoSignedWrap()); + return NewShl; } // If the shifted-out value is known-zero, then this is a NUW shift. diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll index 1fd7d2e2406..ac5b27648ee 100644 --- a/test/Transforms/InstCombine/shift.ll +++ b/test/Transforms/InstCombine/shift.ll @@ -1,6 +1,4 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; This test makes sure that these instructions are properly eliminated. -; ; RUN: opt < %s -instcombine -S | FileCheck %s define i32 @test1(i32 %A) { @@ -840,8 +838,7 @@ define i32 @test48_nuw_nsw(i32 %x) { define <2 x i32> @test48_splat_vec(<2 x i32> %x) { ; CHECK-LABEL: @test48_splat_vec( -; CHECK-NEXT: [[A:%.*]] = lshr exact <2 x i32> %x, -; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[A]], +; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> %x, ; CHECK-NEXT: ret <2 x i32> [[B]] ; %A = lshr exact <2 x i32> %x, @@ -877,8 +874,7 @@ define i32 @test49_nuw_nsw(i32 %x) { define <2 x i32> @test49_splat_vec(<2 x i32> %x) { ; CHECK-LABEL: @test49_splat_vec( -; CHECK-NEXT: [[A:%.*]] = ashr exact <2 x i32> %x, -; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[A]], +; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> %x, ; CHECK-NEXT: ret <2 x i32> [[B]] ; %A = ashr exact <2 x i32> %x, -- 2.40.0