Skip to content

Commit 1440f02

Browse files
Icohedronjayfoad
andauthored
[Scalarizer] Ensure valid VectorSplits for each struct element in visitExtractValueInst (#128538)
Fixes #127739 The `visitExtractValueInst` is missing a check that was present in `splitCall` / `visitCallInst`. This check ensures that each struct element has a VectorSplit, and that each VectorSplit contains the same number of elements packed per fragment. --------- Co-authored-by: Jay Foad <[email protected]>
1 parent d6301b2 commit 1440f02

File tree

2 files changed

+248
-7
lines changed

2 files changed

+248
-7
lines changed

llvm/lib/Transforms/Scalar/Scalarizer.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -719,13 +719,12 @@ bool ScalarizerVisitor::splitCall(CallInst &CI) {
719719
for (unsigned I = 1; I < CallType->getNumContainedTypes(); I++) {
720720
std::optional<VectorSplit> CurrVS =
721721
getVectorSplit(cast<FixedVectorType>(CallType->getContainedType(I)));
722-
// This case does not seem to happen, but it is possible for
723-
// VectorSplit.NumPacked >= NumElems. If that happens a VectorSplit
724-
// is not returned and we will bailout of handling this call.
725-
// The secondary bailout case is if NumPacked does not match.
726-
// This can happen if ScalarizeMinBits is not set to the default.
727-
// This means with certain ScalarizeMinBits intrinsics like frexp
728-
// will only scalarize when the struct elements have the same bitness.
722+
// It is possible for VectorSplit.NumPacked >= NumElems. If that happens a
723+
// VectorSplit is not returned and we will bailout of handling this call.
724+
// The secondary bailout case is if NumPacked does not match. This can
725+
// happen if ScalarizeMinBits is not set to the default. This means with
726+
// certain ScalarizeMinBits intrinsics like frexp will only scalarize when
727+
// the struct elements have the same bitness.
729728
if (!CurrVS || CurrVS->NumPacked != VS->NumPacked)
730729
return false;
731730
if (isVectorIntrinsicWithStructReturnOverloadAtField(ID, I, TTI))
@@ -1083,6 +1082,18 @@ bool ScalarizerVisitor::visitExtractValueInst(ExtractValueInst &EVI) {
10831082
std::optional<VectorSplit> VS = getVectorSplit(VecType);
10841083
if (!VS)
10851084
return false;
1085+
for (unsigned I = 1; I < OpTy->getNumContainedTypes(); I++) {
1086+
std::optional<VectorSplit> CurrVS =
1087+
getVectorSplit(cast<FixedVectorType>(OpTy->getContainedType(I)));
1088+
// It is possible for VectorSplit.NumPacked >= NumElems. If that happens a
1089+
// VectorSplit is not returned and we will bailout of handling this call.
1090+
// The secondary bailout case is if NumPacked does not match. This can
1091+
// happen if ScalarizeMinBits is not set to the default. This means with
1092+
// certain ScalarizeMinBits intrinsics like frexp will only scalarize when
1093+
// the struct elements have the same bitness.
1094+
if (!CurrVS || CurrVS->NumPacked != VS->NumPacked)
1095+
return false;
1096+
}
10861097
IRBuilder<> Builder(&EVI);
10871098
Scatterer Op0 = scatter(&EVI, Op, *VS);
10881099
assert(!EVI.getIndices().empty() && "Make sure an index exists");

0 commit comments

Comments
 (0)