summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-08-27 22:41:44 +0000
committerSanjay Patel <spatel@rotateright.com>2018-08-27 22:41:44 +0000
commit42d31c20a84af29b991d61eefec8d65378cf56f7 (patch)
tree7dfa6f42add035b0aad24ea878f5424f32ddb9c1 /llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
parent20d78921437054d186a78fee0ac09cce4dafa363 (diff)
downloadbcm5719-llvm-42d31c20a84af29b991d61eefec8d65378cf56f7.tar.gz
bcm5719-llvm-42d31c20a84af29b991d61eefec8d65378cf56f7.zip
[InstCombine] allow shuffle+binop canonicalization with widening shuffles
This lines up with the behavior of an existing transform where if both operands of the binop are shuffled, we allow moving the binop before the shuffle regardless of whether the shuffle changes the size of the vector. llvm-svn: 340787
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 99d3d478aaf..99874b31912 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1393,7 +1393,10 @@ Instruction *InstCombiner::foldShuffledBinop(BinaryOperator &Inst) {
if (match(&Inst, m_c_BinOp(
m_OneUse(m_ShuffleVector(m_Value(V1), m_Undef(), m_Constant(Mask))),
m_Constant(C))) &&
- V1->getType() == Inst.getType()) {
+ V1->getType()->getVectorNumElements() <= VWidth) {
+ assert(Inst.getType()->getScalarType() == V1->getType()->getScalarType() &&
+ "Shuffle should not change scalar type");
+ unsigned V1Width = V1->getType()->getVectorNumElements();
// Find constant NewC that has property:
// shuffle(NewC, ShMask) = C
// If such constant does not exist (example: ShMask=<0,0> and C=<1,2>)
@@ -1402,14 +1405,21 @@ Instruction *InstCombiner::foldShuffledBinop(BinaryOperator &Inst) {
SmallVector<int, 16> ShMask;
ShuffleVectorInst::getShuffleMask(Mask, ShMask);
SmallVector<Constant *, 16>
- NewVecC(VWidth, UndefValue::get(C->getType()->getScalarType()));
+ NewVecC(V1Width, UndefValue::get(C->getType()->getScalarType()));
bool MayChange = true;
for (unsigned I = 0; I < VWidth; ++I) {
if (ShMask[I] >= 0) {
- assert(ShMask[I] < (int)VWidth);
+ assert(ShMask[I] < (int)VWidth && "Not expecting narrowing shuffle");
Constant *CElt = C->getAggregateElement(I);
Constant *NewCElt = NewVecC[ShMask[I]];
- if (!CElt || (!isa<UndefValue>(NewCElt) && NewCElt != CElt)) {
+ // Bail out if:
+ // 1. The constant vector contains a constant expression.
+ // 2. The shuffle needs an element of the constant vector that can't
+ // be mapped to a new constant vector.
+ // 3. This is a widening shuffle that copies elements of V1 into the
+ // extended elements (extending with undef is allowed).
+ if (!CElt || (!isa<UndefValue>(NewCElt) && NewCElt != CElt) ||
+ I >= V1Width) {
MayChange = false;
break;
}
OpenPOWER on IntegriCloud