aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests')
-rw-r--r--llvm/unittests/Frontend/OpenMPDecompositionTest.cpp1
-rw-r--r--llvm/unittests/IR/PatternMatch.cpp27
-rw-r--r--llvm/unittests/Option/OptionSubCommandsTest.cpp13
-rw-r--r--llvm/unittests/Support/ThreadPool.cpp14
-rw-r--r--llvm/unittests/Transforms/Vectorize/VPlanTest.cpp196
5 files changed, 206 insertions, 45 deletions
diff --git a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp
index a8706ce..e0c6b39 100644
--- a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp
@@ -88,6 +88,7 @@ using DistSchedule = tomp::clause::DistScheduleT<TypeTy, IdTy, ExprTy>;
using Doacross = tomp::clause::DoacrossT<TypeTy, IdTy, ExprTy>;
using DynamicAllocators =
tomp::clause::DynamicAllocatorsT<TypeTy, IdTy, ExprTy>;
+using DynGroupprivate = tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy>;
using Enter = tomp::clause::EnterT<TypeTy, IdTy, ExprTy>;
using Exclusive = tomp::clause::ExclusiveT<TypeTy, IdTy, ExprTy>;
using Fail = tomp::clause::FailT<TypeTy, IdTy, ExprTy>;
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 972dac8..1142c55 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -2657,4 +2657,31 @@ TEST_F(PatternMatchTest, ShiftOrSelf) {
EXPECT_EQ(ShAmtC, 0U);
}
+TEST_F(PatternMatchTest, CommutativeDeferredIntrinsicMatch) {
+ Value *X = ConstantFP::get(IRB.getDoubleTy(), 1.0);
+ Value *Y = ConstantFP::get(IRB.getDoubleTy(), 2.0);
+
+ auto CheckMatch = [X, Y](Value *Pattern) {
+ Value *tX = nullptr, *tY = nullptr;
+ EXPECT_TRUE(
+ match(Pattern, m_c_Intrinsic<Intrinsic::minimum>(
+ m_Value(tX), m_c_Intrinsic<Intrinsic::minimum>(
+ m_Deferred(tX), m_Value(tY)))));
+ EXPECT_EQ(tX, X);
+ EXPECT_EQ(tY, Y);
+ };
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, X,
+ IRB.CreateBinaryIntrinsic(Intrinsic::minimum, X, Y)));
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, X,
+ IRB.CreateBinaryIntrinsic(Intrinsic::minimum, Y, X)));
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, IRB.CreateBinaryIntrinsic(Intrinsic::minimum, X, Y),
+ X));
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, IRB.CreateBinaryIntrinsic(Intrinsic::minimum, Y, X),
+ X));
+}
+
} // anonymous namespace.
diff --git a/llvm/unittests/Option/OptionSubCommandsTest.cpp b/llvm/unittests/Option/OptionSubCommandsTest.cpp
index e31a326..d4744c9 100644
--- a/llvm/unittests/Option/OptionSubCommandsTest.cpp
+++ b/llvm/unittests/Option/OptionSubCommandsTest.cpp
@@ -192,6 +192,19 @@ TYPED_TEST(OptSubCommandTableTest, SubCommandParsing) {
std::string::npos,
ErrMsg.find("Option [lowercase] is not valid for SubCommand [bar]"));
}
+
+ {
+ // Test case 7: Check valid use of a valid subcommand following more
+ // positional arguments.
+ const char *Args[] = {"bar", "input"};
+ InputArgList AL = T.ParseArgs(Args, MAI, MAC);
+ StringRef SC = AL.getSubCommand(
+ T.getSubCommands(), HandleMultipleSubcommands, HandleOtherPositionals);
+ EXPECT_EQ(SC, "bar"); // valid subcommand
+ EXPECT_NE(std::string::npos,
+ ErrMsg.find("Unregistered positionals passed"));
+ EXPECT_NE(std::string::npos, ErrMsg.find("input"));
+ }
}
TYPED_TEST(OptSubCommandTableTest, SubCommandHelp) {
diff --git a/llvm/unittests/Support/ThreadPool.cpp b/llvm/unittests/Support/ThreadPool.cpp
index aa7f874..b5268c8 100644
--- a/llvm/unittests/Support/ThreadPool.cpp
+++ b/llvm/unittests/Support/ThreadPool.cpp
@@ -183,6 +183,20 @@ TYPED_TEST(ThreadPoolTest, Async) {
ASSERT_EQ(2, i.load());
}
+TYPED_TEST(ThreadPoolTest, AsyncMoveOnly) {
+ CHECK_UNSUPPORTED();
+ DefaultThreadPool Pool;
+ std::promise<int> p;
+ std::future<int> f = p.get_future();
+ Pool.async([this, p = std::move(p)]() mutable {
+ this->waitForMainThread();
+ p.set_value(42);
+ });
+ this->setMainThreadReady();
+ Pool.wait();
+ ASSERT_EQ(42, f.get());
+}
+
TYPED_TEST(ThreadPoolTest, GetFuture) {
CHECK_UNSUPPORTED();
DefaultThreadPool Pool(hardware_concurrency(2));
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index c1791dfa..82ecc16 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -704,6 +704,20 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) {
}
}
+TEST_F(VPBasicBlockTest, splitAtEnd) {
+ VPlan &Plan = getPlan();
+ VPInstruction *VPI = new VPInstruction(0, {});
+ VPBasicBlock *VPBB = Plan.createVPBasicBlock("VPBB1", VPI);
+ VPBlockUtils::connectBlocks(Plan.getEntry(), VPBB);
+ VPBlockUtils::connectBlocks(VPBB, Plan.getScalarHeader());
+ VPBB->splitAt(VPBB->end());
+ EXPECT_EQ(VPBB->size(), 1u);
+ EXPECT_EQ(&VPBB->front(), VPI);
+ auto *Split = cast<VPBasicBlock>(VPBB->getSingleSuccessor());
+ EXPECT_TRUE(Split->empty());
+ EXPECT_EQ(Split->getSingleSuccessor(), Plan.getScalarHeader());
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
TEST_F(VPBasicBlockTest, print) {
VPInstruction *TC = new VPInstruction(Instruction::PHI, {});
@@ -955,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) {
@@ -978,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;
}
@@ -999,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());
@@ -1027,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;
@@ -1051,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()));
@@ -1063,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);
@@ -1076,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;
}
@@ -1089,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) {
@@ -1107,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;
}
@@ -1118,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) {
@@ -1133,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()));
@@ -1145,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);
@@ -1592,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;
}
@@ -1609,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