Skip to content

Commit 554c47c

Browse files
committed
[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.
1 parent 562c479 commit 554c47c

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,15 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
502502
cast<FixedVectorType>(EI0->getVectorOperandType())->getNumElements();
503503
Value *Vec1 = nullptr;
504504
Value *Vec2 = nullptr;
505+
bool HasNonUndefVec = any_of(VL, [](Value *V) {
506+
auto *EE = dyn_cast<ExtractElementInst>(V);
507+
if (!EE)
508+
return false;
509+
Value *Vec = EE->getVectorOperand();
510+
if (isa<UndefValue>(Vec))
511+
return false;
512+
return isGuaranteedNotToBePoison(Vec);
513+
});
505514
enum ShuffleMode { Unknown, Select, Permute };
506515
ShuffleMode CommonShuffleMode = Unknown;
507516
Mask.assign(VL.size(), PoisonMaskElem);
@@ -514,21 +523,27 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
514523
return std::nullopt;
515524
auto *Vec = EI->getVectorOperand();
516525
// We can extractelement from undef or poison vector.
517-
if (isUndefVector(Vec).all())
526+
if (isUndefVector</*isPoisonOnly=*/true>(Vec).all())
518527
continue;
519528
// All vector operands must have the same number of vector elements.
520-
if (cast<FixedVectorType>(Vec->getType())->getNumElements() != Size)
521-
return std::nullopt;
522-
if (isa<UndefValue>(EI->getIndexOperand()))
523-
continue;
524-
auto *Idx = dyn_cast<ConstantInt>(EI->getIndexOperand());
525-
if (!Idx)
526-
return std::nullopt;
527-
// Undefined behavior if Idx is negative or >= Size.
528-
if (Idx->getValue().uge(Size))
529+
if (isa<UndefValue>(Vec)) {
530+
Mask[I] = I;
531+
} else {
532+
if (cast<FixedVectorType>(Vec->getType())->getNumElements() != Size)
533+
return std::nullopt;
534+
if (isa<UndefValue>(EI->getIndexOperand()))
535+
continue;
536+
auto *Idx = dyn_cast<ConstantInt>(EI->getIndexOperand());
537+
if (!Idx)
538+
return std::nullopt;
539+
// Undefined behavior if Idx is negative or >= Size.
540+
if (Idx->getValue().uge(Size))
541+
continue;
542+
unsigned IntIdx = Idx->getValue().getZExtValue();
543+
Mask[I] = IntIdx;
544+
}
545+
if (isUndefVector(Vec).all() && HasNonUndefVec)
529546
continue;
530-
unsigned IntIdx = Idx->getValue().getZExtValue();
531-
Mask[I] = IntIdx;
532547
// For correct shuffling we have to have at most 2 different vector operands
533548
// in all extractelement instructions.
534549
if (!Vec1 || Vec1 == Vec) {
@@ -543,7 +558,7 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
543558
continue;
544559
// If the extract index is not the same as the operation number, it is a
545560
// permutation.
546-
if (IntIdx != I) {
561+
if (Mask[I] % Size != I) {
547562
CommonShuffleMode = Permute;
548563
continue;
549564
}

llvm/test/Transforms/SLPVectorizer/AMDGPU/crash_extract_subvector_cost.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
define <2 x i16> @uadd_sat_v9i16_combine_vi16(<9 x i16> %arg0, <9 x i16> %arg1) {
55
; CHECK-LABEL: @uadd_sat_v9i16_combine_vi16(
66
; CHECK-NEXT: bb:
7-
; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <9 x i16> [[ARG0:%.*]], <9 x i16> poison, <2 x i32> <i32 poison, i32 8>
7+
; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <9 x i16> undef, <9 x i16> [[ARG0:%.*]], <2 x i32> <i32 0, i32 17>
88
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <9 x i16> [[ARG1:%.*]], <9 x i16> poison, <2 x i32> <i32 7, i32 8>
99
; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> [[TMP0]], <2 x i16> [[TMP1]])
1010
; CHECK-NEXT: ret <2 x i16> [[TMP2]]

llvm/test/Transforms/SLPVectorizer/X86/blending-shuffle.ll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ define <4 x i8> @h(<4 x i8> %x, <4 x i8> %y) {
3939

4040
define <4 x i8> @h_undef(<4 x i8> %x, <4 x i8> %y) {
4141
; CHECK-LABEL: @h_undef(
42-
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 poison, i32 3, i32 5, i32 6>
43-
; CHECK-NEXT: [[TMP2:%.*]] = mul <4 x i8> [[TMP1]], [[TMP1]]
44-
; CHECK-NEXT: ret <4 x i8> [[TMP2]]
42+
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> <i8 undef, i8 poison, i8 poison, i8 poison>, <4 x i32> <i32 4, i32 3, i32 poison, i32 poison>
43+
; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 5, i32 6>
44+
; CHECK-NEXT: [[TMP3:%.*]] = mul <4 x i8> [[TMP2]], [[TMP2]]
45+
; CHECK-NEXT: ret <4 x i8> [[TMP3]]
4546
;
4647
%x0 = extractelement <4 x i8> undef, i32 0
4748
%x3 = extractelement <4 x i8> %x, i32 3

0 commit comments

Comments
 (0)