Skip to content

Commit c95fe95

Browse files
Handle already masked Instructions.
'createFunctionType' should be able to create the correct FunctionType, regardless of whether the input Instruction was masked or not. It uses VFInfo to figure out if the input Instruction was already masked, and if so it does not append another mask Type. In checks, create two mock CallInsts, one with a mask and one without and verify that they have the same number of parameters.
1 parent 73d59dd commit c95fe95

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

llvm/lib/Analysis/VectorUtils.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,16 +1507,20 @@ VFABI::createFunctionType(const VFInfo &Info, const Instruction *I,
15071507
VecParams.push_back(U->getType());
15081508
}
15091509

1510-
// Append a mask and get its position.
1510+
// Get mask's position mask and append one if not present in the Instruction.
15111511
int MaskPos = -1;
15121512
if (Info.isMasked()) {
15131513
auto OptMaskPos = Info.getParamIndexForOptionalMask();
15141514
if (!OptMaskPos)
15151515
return std::nullopt;
15161516

15171517
MaskPos = OptMaskPos.value();
1518-
VectorType *MaskTy = VectorType::get(Type::getInt1Ty(M->getContext()), VF);
1519-
VecParams.insert(VecParams.begin() + MaskPos, MaskTy);
1518+
// append a mask only when it's missing
1519+
if (VecParams.size() == Info.Shape.Parameters.size() - 1) {
1520+
VectorType *MaskTy =
1521+
VectorType::get(Type::getInt1Ty(M->getContext()), VF);
1522+
VecParams.insert(VecParams.begin() + MaskPos, MaskTy);
1523+
}
15201524
}
15211525
FunctionType *VecFTy = FunctionType::get(I->getType(), VecParams, false);
15221526
return std::make_pair(VecFTy, MaskPos);

llvm/unittests/Analysis/VectorFunctionABITest.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,33 @@ class VFABIParserTest : public ::testing::Test {
131131
if (!OptVecFTyPos)
132132
return false;
133133

134+
// Ensure that masked Instructions are handled
135+
if (isMasked()) {
136+
// In case of a masked call, try creating another mock CallInst that is
137+
// masked. createFunctionType should be able to handle this.
138+
SmallVector<Type *, 8> CallTypesInclMask(CallTypes);
139+
SmallVector<Value *, 8> ArgsInclMask(Args);
140+
Type *MaskTy = VectorType::get(Type::getInt1Ty(M->getContext()), VF);
141+
CallTypesInclMask.push_back(MaskTy);
142+
ArgsInclMask.push_back(Constant::getNullValue(MaskTy));
143+
144+
FunctionCallee FMasked = M->getOrInsertFunction(
145+
VectorName + "_Masked",
146+
FunctionType::get(RetTy, CallTypesInclMask, false));
147+
std::unique_ptr<CallInst> CIMasked(
148+
CallInst::Create(FMasked, ArgsInclMask));
149+
auto OptVecFTyMaskedPos =
150+
VFABI::createFunctionType(Info, CIMasked.get(), M.get());
151+
if (!OptVecFTyMaskedPos)
152+
return false;
153+
154+
// Both FunctionTypes should have the same number of parameters.
155+
assert(
156+
(OptVecFTyPos->first->getNumParams() ==
157+
OptVecFTyMaskedPos->first->getNumParams()) &&
158+
"createFunctionType should accept masked or non masked Instructions");
159+
}
160+
134161
FunctionType *VecFTy = OptVecFTyPos->first;
135162
// Check that vectorized parameters' size match with VFInfo.
136163
// Both may include a mask.

0 commit comments

Comments
 (0)