Skip to content

Commit eba0f55

Browse files
alexey-bataevjrbyrnes
authored andcommitted
[SLP]Fix undef poison vector values shuffles with poisonous vectors.
If trying to find vector value in shuffling of the extractelements and one of the vector values is undef value, need to generate real mask value for such vector and either undef vector, or incoming second vector, if non-poisonous. Change-Id: I818d067377c9c187acc5fbc12a260cccdecd9281
1 parent d2c304a commit eba0f55

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
454454
cast<FixedVectorType>(EI0->getVectorOperandType())->getNumElements();
455455
Value *Vec1 = nullptr;
456456
Value *Vec2 = nullptr;
457+
bool HasNonUndefVec = any_of(VL, [](Value *V) {
458+
auto *EE = dyn_cast<ExtractElementInst>(V);
459+
if (!EE)
460+
return false;
461+
Value *Vec = EE->getVectorOperand();
462+
if (isa<UndefValue>(Vec))
463+
return false;
464+
return isGuaranteedNotToBePoison(Vec);
465+
});
457466
enum ShuffleMode { Unknown, Select, Permute };
458467
ShuffleMode CommonShuffleMode = Unknown;
459468
Mask.assign(VL.size(), PoisonMaskElem);
@@ -466,21 +475,27 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
466475
return std::nullopt;
467476
auto *Vec = EI->getVectorOperand();
468477
// We can extractelement from undef or poison vector.
469-
if (isUndefVector(Vec).all())
478+
if (isUndefVector</*isPoisonOnly=*/true>(Vec).all())
470479
continue;
471480
// All vector operands must have the same number of vector elements.
472-
if (cast<FixedVectorType>(Vec->getType())->getNumElements() != Size)
473-
return std::nullopt;
474-
if (isa<UndefValue>(EI->getIndexOperand()))
475-
continue;
476-
auto *Idx = dyn_cast<ConstantInt>(EI->getIndexOperand());
477-
if (!Idx)
478-
return std::nullopt;
479-
// Undefined behavior if Idx is negative or >= Size.
480-
if (Idx->getValue().uge(Size))
481+
if (isa<UndefValue>(Vec)) {
482+
Mask[I] = I;
483+
} else {
484+
if (cast<FixedVectorType>(Vec->getType())->getNumElements() != Size)
485+
return std::nullopt;
486+
if (isa<UndefValue>(EI->getIndexOperand()))
487+
continue;
488+
auto *Idx = dyn_cast<ConstantInt>(EI->getIndexOperand());
489+
if (!Idx)
490+
return std::nullopt;
491+
// Undefined behavior if Idx is negative or >= Size.
492+
if (Idx->getValue().uge(Size))
493+
continue;
494+
unsigned IntIdx = Idx->getValue().getZExtValue();
495+
Mask[I] = IntIdx;
496+
}
497+
if (isUndefVector(Vec).all() && HasNonUndefVec)
481498
continue;
482-
unsigned IntIdx = Idx->getValue().getZExtValue();
483-
Mask[I] = IntIdx;
484499
// For correct shuffling we have to have at most 2 different vector operands
485500
// in all extractelement instructions.
486501
if (!Vec1 || Vec1 == Vec) {
@@ -495,7 +510,7 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
495510
continue;
496511
// If the extract index is not the same as the operation number, it is a
497512
// permutation.
498-
if (IntIdx != I) {
513+
if (Mask[I] % Size != I) {
499514
CommonShuffleMode = Permute;
500515
continue;
501516
}

0 commit comments

Comments
 (0)