From e8d6f34445856fcdf9224095441a04457b626f83 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 15 May 2018 21:23:58 +0000 Subject: [PATCH] [InstCombine] clean up code for binop-shuffle transforms; NFCI git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332399 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstructionCombining.cpp | 73 ++++++++++------------ 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index c913988d164..7f97b78986a 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1351,17 +1351,6 @@ Value *InstCombiner::Descale(Value *Val, APInt Scale, bool &NoSignedWrap) { } while (true); } -/// Creates node of binary operation with the same attributes as the -/// specified one but with other operands. -static Value *CreateBinOpAsGiven(BinaryOperator &Inst, Value *LHS, Value *RHS, - InstCombiner::BuilderTy &B) { - Value *BO = B.CreateBinOp(Inst.getOpcode(), LHS, RHS); - // If LHS and RHS are constant, BO won't be a binary operator. - if (BinaryOperator *NewBO = dyn_cast(BO)) - NewBO->copyIRFlags(&Inst); - return BO; -} - /// Makes transformation of binary operation specific for vector types. /// \param Inst Binary operator to transform. /// \return Pointer to node that must replace the original binary operator, or @@ -1380,6 +1369,13 @@ Value *InstCombiner::SimplifyVectorOp(BinaryOperator &Inst) { assert(cast(LHS->getType())->getNumElements() == VWidth); assert(cast(RHS->getType())->getNumElements() == VWidth); + auto createBinOpShuffle = [&](Value *X, Value *Y, Constant *M) { + Value *XY = Builder.CreateBinOp(Inst.getOpcode(), X, Y); + if (auto *BO = dyn_cast(XY)) + BO->copyIRFlags(&Inst); + return Builder.CreateShuffleVector(XY, UndefValue::get(XY->getType()), M); + }; + // If both arguments of the binary operation are shuffles that use the same // mask and shuffle within a single vector, move the shuffle after the binop. Value *V1, *V2; @@ -1389,47 +1385,46 @@ Value *InstCombiner::SimplifyVectorOp(BinaryOperator &Inst) { V1->getType() == V2->getType() && (LHS->hasOneUse() || RHS->hasOneUse() || LHS == RHS)) { // Op(shuffle(V1, Mask), shuffle(V2, Mask)) -> shuffle(Op(V1, V2), Mask) - Value *B = CreateBinOpAsGiven(Inst, V1, V2, Builder); - return Builder.CreateShuffleVector(B, UndefValue::get(V1->getType()), Mask); + return createBinOpShuffle(V1, V2, Mask); } - // If one argument is a shuffle within one vector, the other is a constant, - // try moving the shuffle after the binary operation. - ShuffleVectorInst *Shuffle = nullptr; - Constant *C1 = nullptr; - if (isa(LHS)) Shuffle = cast(LHS); - if (isa(RHS)) Shuffle = cast(RHS); - if (isa(LHS)) C1 = cast(LHS); - if (isa(RHS)) C1 = cast(RHS); - if (Shuffle && C1 && - (isa(C1) || isa(C1)) && - isa(Shuffle->getOperand(1)) && - Shuffle->getType() == Shuffle->getOperand(0)->getType()) { - SmallVector ShMask = Shuffle->getShuffleMask(); - // Find constant C2 that has property: - // shuffle(C2, ShMask) = C1 - // If such constant does not exist (example: ShMask=<0,0> and C1=<1,2>) + // If one argument is a shuffle within one vector and the other is a constant, + // try moving the shuffle after the binary operation. This canonicalization + // intends to move shuffles closer to other shuffles and binops closer to + // other binops, so they can be folded. It may also enable demanded elements + // transforms. + Constant *C; + if (match(&Inst, m_c_BinOp( + m_ShuffleVector(m_Value(V1), m_Undef(), m_Constant(Mask)), + m_Constant(C))) && + V1->getType() == Inst.getType()) { + // Find constant NewC that has property: + // shuffle(NewC, ShMask) = C + // If such constant does not exist (example: ShMask=<0,0> and C=<1,2>) // reorder is not possible. - SmallVector C2M(VWidth, - UndefValue::get(C1->getType()->getScalarType())); + SmallVector ShMask; + ShuffleVectorInst::getShuffleMask(Mask, ShMask); + SmallVector + NewVecC(VWidth, UndefValue::get(C->getType()->getScalarType())); bool MayChange = true; for (unsigned I = 0; I < VWidth; ++I) { if (ShMask[I] >= 0) { assert(ShMask[I] < (int)VWidth); - if (!isa(C2M[ShMask[I]])) { + Constant *CElt = C->getAggregateElement(I); + if (!CElt || !isa(NewVecC[ShMask[I]])) { MayChange = false; break; } - C2M[ShMask[I]] = C1->getAggregateElement(I); + NewVecC[ShMask[I]] = CElt; } } if (MayChange) { - Constant *C2 = ConstantVector::get(C2M); - Value *NewLHS = isa(LHS) ? C2 : Shuffle->getOperand(0); - Value *NewRHS = isa(LHS) ? Shuffle->getOperand(0) : C2; - Value *NewBO = CreateBinOpAsGiven(Inst, NewLHS, NewRHS, Builder); - return Builder.CreateShuffleVector(NewBO, - UndefValue::get(Inst.getType()), Shuffle->getMask()); + // Op(shuffle(V1, Mask), C) -> shuffle(Op(V1, NewC), Mask) + // Op(C, shuffle(V1, Mask)) -> shuffle(Op(NewC, V1), Mask) + Constant *NewC = ConstantVector::get(NewVecC); + Value *NewLHS = isa(LHS) ? NewC : V1; + Value *NewRHS = isa(LHS) ? V1 : NewC; + return createBinOpShuffle(NewLHS, NewRHS, Mask); } } -- 2.11.0