[llvm] r332399 - [InstCombine] clean up code for binop-shuffle transforms; NFCI
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue May 15 14:23:58 PDT 2018
Author: spatel
Date: Tue May 15 14:23:58 2018
New Revision: 332399
URL: http://llvm.org/viewvc/llvm-project?rev=332399&view=rev
Log:
[InstCombine] clean up code for binop-shuffle transforms; NFCI
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=332399&r1=332398&r2=332399&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Tue May 15 14:23:58 2018
@@ -1351,17 +1351,6 @@ Value *InstCombiner::Descale(Value *Val,
} 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<BinaryOperator>(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(Bi
assert(cast<VectorType>(LHS->getType())->getNumElements() == VWidth);
assert(cast<VectorType>(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<BinaryOperator>(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(Bi
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<ShuffleVectorInst>(LHS)) Shuffle = cast<ShuffleVectorInst>(LHS);
- if (isa<ShuffleVectorInst>(RHS)) Shuffle = cast<ShuffleVectorInst>(RHS);
- if (isa<Constant>(LHS)) C1 = cast<Constant>(LHS);
- if (isa<Constant>(RHS)) C1 = cast<Constant>(RHS);
- if (Shuffle && C1 &&
- (isa<ConstantVector>(C1) || isa<ConstantDataVector>(C1)) &&
- isa<UndefValue>(Shuffle->getOperand(1)) &&
- Shuffle->getType() == Shuffle->getOperand(0)->getType()) {
- SmallVector<int, 16> 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<Constant*, 16> C2M(VWidth,
- UndefValue::get(C1->getType()->getScalarType()));
+ SmallVector<int, 16> ShMask;
+ ShuffleVectorInst::getShuffleMask(Mask, ShMask);
+ SmallVector<Constant *, 16>
+ 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<UndefValue>(C2M[ShMask[I]])) {
+ Constant *CElt = C->getAggregateElement(I);
+ if (!CElt || !isa<UndefValue>(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<Constant>(LHS) ? C2 : Shuffle->getOperand(0);
- Value *NewRHS = isa<Constant>(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<Constant>(LHS) ? NewC : V1;
+ Value *NewRHS = isa<Constant>(LHS) ? V1 : NewC;
+ return createBinOpShuffle(NewLHS, NewRHS, Mask);
}
}
More information about the llvm-commits
mailing list