diff options
| author | Florian Hahn <flo@fhahn.com> | 2025-11-06 18:58:17 +0000 |
|---|---|---|
| committer | Florian Hahn <flo@fhahn.com> | 2025-11-06 18:58:43 +0000 |
| commit | 321de63633be1867d5c93d59ab2c49794cd5041a (patch) | |
| tree | 0380375cf556e0956356089a9def2930792b7026 | |
| parent | 2be5421da9aa3eda909b4b8bb86983927b4bba86 (diff) | |
| download | llvm-321de63633be1867d5c93d59ab2c49794cd5041a.zip llvm-321de63633be1867d5c93d59ab2c49794cd5041a.tar.gz llvm-321de63633be1867d5c93d59ab2c49794cd5041a.tar.bz2 | |
[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.
| -rw-r--r-- | llvm/unittests/Transforms/Vectorize/VPlanTest.cpp | 182 |
1 files changed, 137 insertions, 45 deletions
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp index c256eae..82ecc16 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -969,16 +969,40 @@ compound=true #endif using VPRecipeTest = VPlanTestBase; + +namespace { +template <typename RecipeT, typename T, typename... Rest> +void checkVPRecipeCastImpl(RecipeT *R) { + // Direct checks on recipe pointer + EXPECT_TRUE(isa<T>(R)); + EXPECT_EQ(R, dyn_cast<T>(R)); + (void)cast<T>(R); // Verify cast succeeds (asserts on failure) + + // Check through base pointer + VPRecipeBase *BaseR = R; + EXPECT_TRUE(isa<T>(BaseR)); + EXPECT_EQ(R, dyn_cast<T>(BaseR)); + (void)cast<T>(BaseR); + + // Check through const base pointer + const VPRecipeBase *ConstBaseR = R; + EXPECT_TRUE(isa<T>(ConstBaseR)); + EXPECT_EQ(R, dyn_cast<T>(ConstBaseR)); + (void)cast<T>(ConstBaseR); + + if constexpr (sizeof...(Rest) > 0) + checkVPRecipeCastImpl<RecipeT, Rest...>(R); +} +} // namespace + TEST_F(VPRecipeTest, CastVPInstructionToVPUser) { IntegerType *Int32 = IntegerType::get(C, 32); VPlan &Plan = getPlan(); VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPInstruction Recipe(Instruction::Add, {Op1, Op2}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPInstruction, VPUser>(&Recipe); } TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) { @@ -992,10 +1016,8 @@ TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) { Args.push_back(Op1); Args.push_back(Op2); VPWidenRecipe WidenR(*AI, make_range(Args.begin(), Args.end())); - EXPECT_TRUE(isa<VPUser>(&WidenR)); - VPRecipeBase *WidenRBase = &WidenR; - EXPECT_TRUE(isa<VPUser>(WidenRBase)); - EXPECT_EQ(&WidenR, WidenRBase); + + checkVPRecipeCastImpl<VPWidenRecipe, VPUser>(&WidenR); delete AI; } @@ -1013,10 +1035,8 @@ TEST_F(VPRecipeTest, CastVPWidenCallRecipeToVPUserAndVPDef) { Args.push_back(Op2); Args.push_back(CalledFn); VPWidenCallRecipe Recipe(Call, Fn, Args); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPWidenCallRecipe, VPUser>(&Recipe); VPValue *VPV = &Recipe; EXPECT_TRUE(VPV->getDefiningRecipe()); @@ -1041,13 +1061,10 @@ TEST_F(VPRecipeTest, CastVPWidenSelectRecipeToVPUserAndVPDef) { Args.push_back(Op3); VPWidenSelectRecipe WidenSelectR(*SelectI, make_range(Args.begin(), Args.end())); - EXPECT_TRUE(isa<VPUser>(&WidenSelectR)); - VPRecipeBase *BaseR = &WidenSelectR; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&WidenSelectR, BaseR); + + checkVPRecipeCastImpl<VPWidenSelectRecipe, VPUser>(&WidenSelectR); VPValue *VPV = &WidenSelectR; - EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe())); EXPECT_EQ(&WidenSelectR, VPV->getDefiningRecipe()); delete SelectI; @@ -1065,10 +1082,8 @@ TEST_F(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) { Args.push_back(Op1); Args.push_back(Op2); VPWidenGEPRecipe Recipe(GEP, make_range(Args.begin(), Args.end())); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPWidenGEPRecipe, VPUser>(&Recipe); VPValue *VPV = &Recipe; EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe())); @@ -1077,6 +1092,28 @@ TEST_F(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) { delete GEP; } +TEST_F(VPRecipeTest, CastVPWidenCastRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + IntegerType *Int64 = IntegerType::get(C, 64); + auto *Cast = CastInst::CreateZExtOrBitCast(PoisonValue::get(Int32), Int64); + VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPWidenCastRecipe Recipe(Instruction::ZExt, Op1, Int64, *Cast); + + checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser>(&Recipe); + delete Cast; +} + +TEST_F(VPRecipeTest, CastVPWidenIntrinsicRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPWidenIntrinsicRecipe Recipe(Intrinsic::smax, {Op1, Op2}, Int32); + + checkVPRecipeCastImpl<VPWidenIntrinsicRecipe, VPUser>(&Recipe); +} + TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) { VPlan &Plan = getPlan(); IntegerType *Int32 = IntegerType::get(C, 32); @@ -1090,9 +1127,9 @@ TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) { Args.push_back(I2); Args.push_back(M2); VPBlendRecipe Recipe(Phi, Args, {}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); + + checkVPRecipeCastImpl<VPBlendRecipe, VPUser>(&Recipe); + delete Phi; } @@ -1103,10 +1140,8 @@ TEST_F(VPRecipeTest, CastVPInterleaveRecipeToVPUser) { VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); InterleaveGroup<Instruction> IG(4, false, Align(4)); VPInterleaveRecipe Recipe(&IG, Addr, {}, Mask, false, {}, DebugLoc()); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPInterleaveRecipe, VPUser>(&Recipe); } TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) { @@ -1121,9 +1156,9 @@ TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) { FunctionType *FTy = FunctionType::get(Int32, false); auto *Call = CallInst::Create(FTy, PoisonValue::get(FTy)); VPReplicateRecipe Recipe(Call, make_range(Args.begin(), Args.end()), true); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); + + checkVPRecipeCastImpl<VPReplicateRecipe, VPUser>(&Recipe); + delete Call; } @@ -1132,10 +1167,8 @@ TEST_F(VPRecipeTest, CastVPBranchOnMaskRecipeToVPUser) { IntegerType *Int32 = IntegerType::get(C, 32); VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPBranchOnMaskRecipe Recipe(Mask, {}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPBranchOnMaskRecipe, VPUser>(&Recipe); } TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) { @@ -1147,10 +1180,8 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) { VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, {}, {}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPWidenLoadRecipe, VPUser>(&Recipe); VPValue *VPV = Recipe.getVPSingleValue(); EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe())); @@ -1159,6 +1190,71 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) { delete Load; } +TEST_F(VPRecipeTest, CastVPInterleaveEVLRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8)); + InterleaveGroup<Instruction> IG(4, false, Align(4)); + VPInterleaveRecipe BaseRecipe(&IG, Addr, {}, Mask, false, {}, DebugLoc()); + VPInterleaveEVLRecipe Recipe(BaseRecipe, *EVL, Mask); + + checkVPRecipeCastImpl<VPInterleaveEVLRecipe, VPUser>(&Recipe); +} + +TEST_F(VPRecipeTest, CastVPWidenLoadEVLRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + PointerType *Int32Ptr = PointerType::get(C, 0); + auto *Load = + new LoadInst(Int32, PoisonValue::get(Int32Ptr), "", false, Align(1)); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8)); + VPWidenLoadRecipe BaseLoad(*Load, Addr, Mask, true, false, {}, {}); + VPWidenLoadEVLRecipe Recipe(BaseLoad, Addr, *EVL, Mask); + + checkVPRecipeCastImpl<VPWidenLoadEVLRecipe, VPUser>(&Recipe); + + delete Load; +} + +TEST_F(VPRecipeTest, CastVPWidenStoreRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + PointerType *Int32Ptr = PointerType::get(C, 0); + auto *Store = new StoreInst(PoisonValue::get(Int32), + PoisonValue::get(Int32Ptr), false, Align(1)); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *StoredVal = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 42)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPWidenStoreRecipe Recipe(*Store, Addr, StoredVal, Mask, true, false, {}, {}); + + checkVPRecipeCastImpl<VPWidenStoreRecipe, VPUser>(&Recipe); + + delete Store; +} + +TEST_F(VPRecipeTest, CastVPWidenStoreEVLRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + PointerType *Int32Ptr = PointerType::get(C, 0); + auto *Store = new StoreInst(PoisonValue::get(Int32), + PoisonValue::get(Int32Ptr), false, Align(1)); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *StoredVal = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 42)); + VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPWidenStoreRecipe BaseStore(*Store, Addr, StoredVal, Mask, true, false, {}, + {}); + VPWidenStoreEVLRecipe Recipe(BaseStore, Addr, *EVL, Mask); + + checkVPRecipeCastImpl<VPWidenStoreEVLRecipe, VPUser>(&Recipe); + + delete Store; +} + TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { IntegerType *Int1 = IntegerType::get(C, 1); IntegerType *Int32 = IntegerType::get(C, 32); @@ -1606,9 +1702,7 @@ TEST_F(VPRecipeTest, CastVPReductionRecipeToVPUser) { VPValue *CondOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3)); VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), Add, ChainOp, CondOp, VecOp, false); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); + checkVPRecipeCastImpl<VPReductionRecipe, VPUser>(&Recipe); delete Add; } @@ -1623,9 +1717,7 @@ TEST_F(VPRecipeTest, CastVPReductionEVLRecipeToVPUser) { CondOp, VecOp, false); VPValue *EVL = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 0)); VPReductionEVLRecipe EVLRecipe(Recipe, *EVL, CondOp); - EXPECT_TRUE(isa<VPUser>(&EVLRecipe)); - VPRecipeBase *BaseR = &EVLRecipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); + checkVPRecipeCastImpl<VPReductionEVLRecipe, VPUser>(&EVLRecipe); delete Add; } } // namespace |
