From: Sanjay Patel Date: Thu, 20 Apr 2017 22:33:54 +0000 (+0000) Subject: [InstCombine] allow shl+shr demanded bits folds with splat constants X-Git-Tag: android-x86-7.1-r4~17402 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=e29c6aab81d4aae580786d9421424acb3ddda8e2;p=android-x86%2Fexternal-llvm.git [InstCombine] allow shl+shr demanded bits folds with splat constants git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300911 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineInternal.h b/lib/Transforms/InstCombine/InstCombineInternal.h index 71000063ab3..978c8a3c671 100644 --- a/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/lib/Transforms/InstCombine/InstCombineInternal.h @@ -551,9 +551,10 @@ private: unsigned Depth, Instruction *CxtI); /// Helper routine of SimplifyDemandedUseBits. It tries to simplify demanded /// bit for "r1 = shr x, c1; r2 = shl r1, c2" instruction sequence. - Value *SimplifyShrShlDemandedBits(Instruction *Lsr, Instruction *Sftl, - const APInt &DemandedMask, APInt &KnownZero, - APInt &KnownOne); + Value *SimplifyShrShlDemandedBits( + Instruction *Shr, const APInt &ShrOp1, Instruction *Shl, + const APInt &ShlOp1, const APInt &DemandedMask, APInt &KnownZero, + APInt &KnownOne); /// \brief Tries to simplify operands to an integer instruction based on its /// demanded bits. diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 3d14e59ea0d..899b5dfc575 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -472,15 +472,12 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, case Instruction::Shl: { const APInt *SA; if (match(I->getOperand(1), m_APInt(SA))) { - { - Value *VarX; ConstantInt *C1; - if (match(I->getOperand(0), m_Shr(m_Value(VarX), m_ConstantInt(C1)))) { - Instruction *Shr = cast(I->getOperand(0)); - Value *R = SimplifyShrShlDemandedBits(Shr, I, DemandedMask, - KnownZero, KnownOne); - if (R) - return R; - } + const APInt *ShrAmt; + if (match(I->getOperand(0), m_Shr(m_Value(), m_APInt(ShrAmt)))) { + Instruction *Shr = cast(I->getOperand(0)); + if (Value *R = SimplifyShrShlDemandedBits( + Shr, *ShrAmt, I, *SA, DemandedMask, KnownZero, KnownOne)) + return R; } uint64_t ShiftAmt = SA->getLimitedValue(BitWidth-1); @@ -876,20 +873,17 @@ Value *InstCombiner::SimplifyMultipleUseDemandedBits(Instruction *I, /// /// As with SimplifyDemandedUseBits, it returns NULL if the simplification was /// not successful. -Value *InstCombiner::SimplifyShrShlDemandedBits(Instruction *Shr, - Instruction *Shl, - const APInt &DemandedMask, - APInt &KnownZero, - APInt &KnownOne) { - - const APInt &ShlOp1 = cast(Shl->getOperand(1))->getValue(); - const APInt &ShrOp1 = cast(Shr->getOperand(1))->getValue(); +Value * +InstCombiner::SimplifyShrShlDemandedBits(Instruction *Shr, const APInt &ShrOp1, + Instruction *Shl, const APInt &ShlOp1, + const APInt &DemandedMask, + APInt &KnownZero, APInt &KnownOne) { if (!ShlOp1 || !ShrOp1) - return nullptr; // Noop. + return nullptr; // No-op. Value *VarX = Shr->getOperand(0); Type *Ty = VarX->getType(); - unsigned BitWidth = Ty->getIntegerBitWidth(); + unsigned BitWidth = Ty->getScalarSizeInBits(); if (ShlOp1.uge(BitWidth) || ShrOp1.uge(BitWidth)) return nullptr; // Undef. diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll index 6a6c1880c5e..ce8e2fcd38b 100644 --- a/test/Transforms/InstCombine/shift.ll +++ b/test/Transforms/InstCombine/shift.ll @@ -1075,9 +1075,8 @@ define i32 @test54(i32 %x) { define <2 x i32> @test54_splat_vec(<2 x i32> %x) { ; CHECK-LABEL: @test54_splat_vec( -; CHECK-NEXT: [[SHR2:%.*]] = lshr <2 x i32> %x, -; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[SHR2]], -; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[SHL]], +; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> %x, +; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[AND]] ; %shr2 = lshr <2 x i32> %x, @@ -1138,9 +1137,8 @@ define i32 @test58(i32 %x) { define <2 x i32> @test58_splat_vec(<2 x i32> %x) { ; CHECK-LABEL: @test58_splat_vec( -; CHECK-NEXT: [[SHR:%.*]] = ashr <2 x i32> %x, -; CHECK-NEXT: [[SHL:%.*]] = shl nsw <2 x i32> [[SHR]], -; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHL]], +; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> %x, +; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[OR]] ; %shr = ashr <2 x i32> %x,