Skip to content

Commit 321de63

Browse files
committed
[VPlan] Unify casting unit testing (NFC).
Generalize and unify testing of isa/cast/dyn_cast for various recipes, making it easier to extend with additional casts.
1 parent 2be5421 commit 321de63

File tree

1 file changed

+137
-45
lines changed

1 file changed

+137
-45
lines changed

llvm/unittests/Transforms/Vectorize/VPlanTest.cpp

Lines changed: 137 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -969,16 +969,40 @@ compound=true
969969
#endif
970970

971971
using VPRecipeTest = VPlanTestBase;
972+
973+
namespace {
974+
template <typename RecipeT, typename T, typename... Rest>
975+
void checkVPRecipeCastImpl(RecipeT *R) {
976+
// Direct checks on recipe pointer
977+
EXPECT_TRUE(isa<T>(R));
978+
EXPECT_EQ(R, dyn_cast<T>(R));
979+
(void)cast<T>(R); // Verify cast succeeds (asserts on failure)
980+
981+
// Check through base pointer
982+
VPRecipeBase *BaseR = R;
983+
EXPECT_TRUE(isa<T>(BaseR));
984+
EXPECT_EQ(R, dyn_cast<T>(BaseR));
985+
(void)cast<T>(BaseR);
986+
987+
// Check through const base pointer
988+
const VPRecipeBase *ConstBaseR = R;
989+
EXPECT_TRUE(isa<T>(ConstBaseR));
990+
EXPECT_EQ(R, dyn_cast<T>(ConstBaseR));
991+
(void)cast<T>(ConstBaseR);
992+
993+
if constexpr (sizeof...(Rest) > 0)
994+
checkVPRecipeCastImpl<RecipeT, Rest...>(R);
995+
}
996+
} // namespace
997+
972998
TEST_F(VPRecipeTest, CastVPInstructionToVPUser) {
973999
IntegerType *Int32 = IntegerType::get(C, 32);
9741000
VPlan &Plan = getPlan();
9751001
VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
9761002
VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
9771003
VPInstruction Recipe(Instruction::Add, {Op1, Op2});
978-
EXPECT_TRUE(isa<VPUser>(&Recipe));
979-
VPRecipeBase *BaseR = &Recipe;
980-
EXPECT_TRUE(isa<VPUser>(BaseR));
981-
EXPECT_EQ(&Recipe, BaseR);
1004+
1005+
checkVPRecipeCastImpl<VPInstruction, VPUser>(&Recipe);
9821006
}
9831007

9841008
TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) {
@@ -992,10 +1016,8 @@ TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) {
9921016
Args.push_back(Op1);
9931017
Args.push_back(Op2);
9941018
VPWidenRecipe WidenR(*AI, make_range(Args.begin(), Args.end()));
995-
EXPECT_TRUE(isa<VPUser>(&WidenR));
996-
VPRecipeBase *WidenRBase = &WidenR;
997-
EXPECT_TRUE(isa<VPUser>(WidenRBase));
998-
EXPECT_EQ(&WidenR, WidenRBase);
1019+
1020+
checkVPRecipeCastImpl<VPWidenRecipe, VPUser>(&WidenR);
9991021
delete AI;
10001022
}
10011023

@@ -1013,10 +1035,8 @@ TEST_F(VPRecipeTest, CastVPWidenCallRecipeToVPUserAndVPDef) {
10131035
Args.push_back(Op2);
10141036
Args.push_back(CalledFn);
10151037
VPWidenCallRecipe Recipe(Call, Fn, Args);
1016-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1017-
VPRecipeBase *BaseR = &Recipe;
1018-
EXPECT_TRUE(isa<VPUser>(BaseR));
1019-
EXPECT_EQ(&Recipe, BaseR);
1038+
1039+
checkVPRecipeCastImpl<VPWidenCallRecipe, VPUser>(&Recipe);
10201040

10211041
VPValue *VPV = &Recipe;
10221042
EXPECT_TRUE(VPV->getDefiningRecipe());
@@ -1041,13 +1061,10 @@ TEST_F(VPRecipeTest, CastVPWidenSelectRecipeToVPUserAndVPDef) {
10411061
Args.push_back(Op3);
10421062
VPWidenSelectRecipe WidenSelectR(*SelectI,
10431063
make_range(Args.begin(), Args.end()));
1044-
EXPECT_TRUE(isa<VPUser>(&WidenSelectR));
1045-
VPRecipeBase *BaseR = &WidenSelectR;
1046-
EXPECT_TRUE(isa<VPUser>(BaseR));
1047-
EXPECT_EQ(&WidenSelectR, BaseR);
1064+
1065+
checkVPRecipeCastImpl<VPWidenSelectRecipe, VPUser>(&WidenSelectR);
10481066

10491067
VPValue *VPV = &WidenSelectR;
1050-
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
10511068
EXPECT_EQ(&WidenSelectR, VPV->getDefiningRecipe());
10521069

10531070
delete SelectI;
@@ -1065,10 +1082,8 @@ TEST_F(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) {
10651082
Args.push_back(Op1);
10661083
Args.push_back(Op2);
10671084
VPWidenGEPRecipe Recipe(GEP, make_range(Args.begin(), Args.end()));
1068-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1069-
VPRecipeBase *BaseR = &Recipe;
1070-
EXPECT_TRUE(isa<VPUser>(BaseR));
1071-
EXPECT_EQ(&Recipe, BaseR);
1085+
1086+
checkVPRecipeCastImpl<VPWidenGEPRecipe, VPUser>(&Recipe);
10721087

10731088
VPValue *VPV = &Recipe;
10741089
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
@@ -1077,6 +1092,28 @@ TEST_F(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) {
10771092
delete GEP;
10781093
}
10791094

1095+
TEST_F(VPRecipeTest, CastVPWidenCastRecipeToVPUser) {
1096+
VPlan &Plan = getPlan();
1097+
IntegerType *Int32 = IntegerType::get(C, 32);
1098+
IntegerType *Int64 = IntegerType::get(C, 64);
1099+
auto *Cast = CastInst::CreateZExtOrBitCast(PoisonValue::get(Int32), Int64);
1100+
VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1101+
VPWidenCastRecipe Recipe(Instruction::ZExt, Op1, Int64, *Cast);
1102+
1103+
checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser>(&Recipe);
1104+
delete Cast;
1105+
}
1106+
1107+
TEST_F(VPRecipeTest, CastVPWidenIntrinsicRecipeToVPUser) {
1108+
VPlan &Plan = getPlan();
1109+
IntegerType *Int32 = IntegerType::get(C, 32);
1110+
VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1111+
VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
1112+
VPWidenIntrinsicRecipe Recipe(Intrinsic::smax, {Op1, Op2}, Int32);
1113+
1114+
checkVPRecipeCastImpl<VPWidenIntrinsicRecipe, VPUser>(&Recipe);
1115+
}
1116+
10801117
TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) {
10811118
VPlan &Plan = getPlan();
10821119
IntegerType *Int32 = IntegerType::get(C, 32);
@@ -1090,9 +1127,9 @@ TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) {
10901127
Args.push_back(I2);
10911128
Args.push_back(M2);
10921129
VPBlendRecipe Recipe(Phi, Args, {});
1093-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1094-
VPRecipeBase *BaseR = &Recipe;
1095-
EXPECT_TRUE(isa<VPUser>(BaseR));
1130+
1131+
checkVPRecipeCastImpl<VPBlendRecipe, VPUser>(&Recipe);
1132+
10961133
delete Phi;
10971134
}
10981135

@@ -1103,10 +1140,8 @@ TEST_F(VPRecipeTest, CastVPInterleaveRecipeToVPUser) {
11031140
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
11041141
InterleaveGroup<Instruction> IG(4, false, Align(4));
11051142
VPInterleaveRecipe Recipe(&IG, Addr, {}, Mask, false, {}, DebugLoc());
1106-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1107-
VPRecipeBase *BaseR = &Recipe;
1108-
EXPECT_TRUE(isa<VPUser>(BaseR));
1109-
EXPECT_EQ(&Recipe, BaseR);
1143+
1144+
checkVPRecipeCastImpl<VPInterleaveRecipe, VPUser>(&Recipe);
11101145
}
11111146

11121147
TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) {
@@ -1121,9 +1156,9 @@ TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) {
11211156
FunctionType *FTy = FunctionType::get(Int32, false);
11221157
auto *Call = CallInst::Create(FTy, PoisonValue::get(FTy));
11231158
VPReplicateRecipe Recipe(Call, make_range(Args.begin(), Args.end()), true);
1124-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1125-
VPRecipeBase *BaseR = &Recipe;
1126-
EXPECT_TRUE(isa<VPUser>(BaseR));
1159+
1160+
checkVPRecipeCastImpl<VPReplicateRecipe, VPUser>(&Recipe);
1161+
11271162
delete Call;
11281163
}
11291164

@@ -1132,10 +1167,8 @@ TEST_F(VPRecipeTest, CastVPBranchOnMaskRecipeToVPUser) {
11321167
IntegerType *Int32 = IntegerType::get(C, 32);
11331168
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
11341169
VPBranchOnMaskRecipe Recipe(Mask, {});
1135-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1136-
VPRecipeBase *BaseR = &Recipe;
1137-
EXPECT_TRUE(isa<VPUser>(BaseR));
1138-
EXPECT_EQ(&Recipe, BaseR);
1170+
1171+
checkVPRecipeCastImpl<VPBranchOnMaskRecipe, VPUser>(&Recipe);
11391172
}
11401173

11411174
TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) {
@@ -1147,10 +1180,8 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) {
11471180
VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
11481181
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
11491182
VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, {}, {});
1150-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1151-
VPRecipeBase *BaseR = &Recipe;
1152-
EXPECT_TRUE(isa<VPUser>(BaseR));
1153-
EXPECT_EQ(&Recipe, BaseR);
1183+
1184+
checkVPRecipeCastImpl<VPWidenLoadRecipe, VPUser>(&Recipe);
11541185

11551186
VPValue *VPV = Recipe.getVPSingleValue();
11561187
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
@@ -1159,6 +1190,71 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) {
11591190
delete Load;
11601191
}
11611192

1193+
TEST_F(VPRecipeTest, CastVPInterleaveEVLRecipeToVPUser) {
1194+
VPlan &Plan = getPlan();
1195+
IntegerType *Int32 = IntegerType::get(C, 32);
1196+
VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1197+
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
1198+
VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8));
1199+
InterleaveGroup<Instruction> IG(4, false, Align(4));
1200+
VPInterleaveRecipe BaseRecipe(&IG, Addr, {}, Mask, false, {}, DebugLoc());
1201+
VPInterleaveEVLRecipe Recipe(BaseRecipe, *EVL, Mask);
1202+
1203+
checkVPRecipeCastImpl<VPInterleaveEVLRecipe, VPUser>(&Recipe);
1204+
}
1205+
1206+
TEST_F(VPRecipeTest, CastVPWidenLoadEVLRecipeToVPUser) {
1207+
VPlan &Plan = getPlan();
1208+
IntegerType *Int32 = IntegerType::get(C, 32);
1209+
PointerType *Int32Ptr = PointerType::get(C, 0);
1210+
auto *Load =
1211+
new LoadInst(Int32, PoisonValue::get(Int32Ptr), "", false, Align(1));
1212+
VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1213+
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
1214+
VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8));
1215+
VPWidenLoadRecipe BaseLoad(*Load, Addr, Mask, true, false, {}, {});
1216+
VPWidenLoadEVLRecipe Recipe(BaseLoad, Addr, *EVL, Mask);
1217+
1218+
checkVPRecipeCastImpl<VPWidenLoadEVLRecipe, VPUser>(&Recipe);
1219+
1220+
delete Load;
1221+
}
1222+
1223+
TEST_F(VPRecipeTest, CastVPWidenStoreRecipeToVPUser) {
1224+
VPlan &Plan = getPlan();
1225+
IntegerType *Int32 = IntegerType::get(C, 32);
1226+
PointerType *Int32Ptr = PointerType::get(C, 0);
1227+
auto *Store = new StoreInst(PoisonValue::get(Int32),
1228+
PoisonValue::get(Int32Ptr), false, Align(1));
1229+
VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1230+
VPValue *StoredVal = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 42));
1231+
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
1232+
VPWidenStoreRecipe Recipe(*Store, Addr, StoredVal, Mask, true, false, {}, {});
1233+
1234+
checkVPRecipeCastImpl<VPWidenStoreRecipe, VPUser>(&Recipe);
1235+
1236+
delete Store;
1237+
}
1238+
1239+
TEST_F(VPRecipeTest, CastVPWidenStoreEVLRecipeToVPUser) {
1240+
VPlan &Plan = getPlan();
1241+
IntegerType *Int32 = IntegerType::get(C, 32);
1242+
PointerType *Int32Ptr = PointerType::get(C, 0);
1243+
auto *Store = new StoreInst(PoisonValue::get(Int32),
1244+
PoisonValue::get(Int32Ptr), false, Align(1));
1245+
VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1246+
VPValue *StoredVal = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 42));
1247+
VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8));
1248+
VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
1249+
VPWidenStoreRecipe BaseStore(*Store, Addr, StoredVal, Mask, true, false, {},
1250+
{});
1251+
VPWidenStoreEVLRecipe Recipe(BaseStore, Addr, *EVL, Mask);
1252+
1253+
checkVPRecipeCastImpl<VPWidenStoreEVLRecipe, VPUser>(&Recipe);
1254+
1255+
delete Store;
1256+
}
1257+
11621258
TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) {
11631259
IntegerType *Int1 = IntegerType::get(C, 1);
11641260
IntegerType *Int32 = IntegerType::get(C, 32);
@@ -1606,9 +1702,7 @@ TEST_F(VPRecipeTest, CastVPReductionRecipeToVPUser) {
16061702
VPValue *CondOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3));
16071703
VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), Add, ChainOp,
16081704
CondOp, VecOp, false);
1609-
EXPECT_TRUE(isa<VPUser>(&Recipe));
1610-
VPRecipeBase *BaseR = &Recipe;
1611-
EXPECT_TRUE(isa<VPUser>(BaseR));
1705+
checkVPRecipeCastImpl<VPReductionRecipe, VPUser>(&Recipe);
16121706
delete Add;
16131707
}
16141708

@@ -1623,9 +1717,7 @@ TEST_F(VPRecipeTest, CastVPReductionEVLRecipeToVPUser) {
16231717
CondOp, VecOp, false);
16241718
VPValue *EVL = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 0));
16251719
VPReductionEVLRecipe EVLRecipe(Recipe, *EVL, CondOp);
1626-
EXPECT_TRUE(isa<VPUser>(&EVLRecipe));
1627-
VPRecipeBase *BaseR = &EVLRecipe;
1628-
EXPECT_TRUE(isa<VPUser>(BaseR));
1720+
checkVPRecipeCastImpl<VPReductionEVLRecipe, VPUser>(&EVLRecipe);
16291721
delete Add;
16301722
}
16311723
} // namespace

0 commit comments

Comments
 (0)