|
6 | 6 | //
|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
9 |
| -#include "llvm/AsmParser/Parser.h" |
10 | 9 | #include "llvm/IR/Instructions.h"
|
| 10 | +#include "llvm/ADT/CombinationGenerator.h" |
11 | 11 | #include "llvm/ADT/STLExtras.h"
|
12 | 12 | #include "llvm/Analysis/ValueTracking.h"
|
| 13 | +#include "llvm/Analysis/VectorUtils.h" |
| 14 | +#include "llvm/AsmParser/Parser.h" |
13 | 15 | #include "llvm/IR/BasicBlock.h"
|
14 | 16 | #include "llvm/IR/Constants.h"
|
15 | 17 | #include "llvm/IR/DataLayout.h"
|
@@ -1115,6 +1117,92 @@ TEST(InstructionsTest, ShuffleMaskQueries) {
|
1115 | 1117 | delete Id15;
|
1116 | 1118 | }
|
1117 | 1119 |
|
| 1120 | +TEST(InstructionsTest, ShuffleMaskIsReplicationMask) { |
| 1121 | + for (int ReplicationFactor : seq_inclusive(1, 8)) { |
| 1122 | + for (int VF : seq_inclusive(1, 8)) { |
| 1123 | + const auto ReplicatedMask = createReplicatedMask(ReplicationFactor, VF); |
| 1124 | + int GuessedReplicationFactor = -1, GuessedVF = -1; |
| 1125 | + EXPECT_TRUE(ShuffleVectorInst::isReplicationMask( |
| 1126 | + ReplicatedMask, GuessedReplicationFactor, GuessedVF)); |
| 1127 | + EXPECT_EQ(GuessedReplicationFactor, ReplicationFactor); |
| 1128 | + EXPECT_EQ(GuessedVF, VF); |
| 1129 | + } |
| 1130 | + } |
| 1131 | +} |
| 1132 | + |
| 1133 | +TEST(InstructionsTest, ShuffleMaskIsReplicationMask_undef) { |
| 1134 | + for (int ReplicationFactor : seq_inclusive(1, 6)) { |
| 1135 | + for (int VF : seq_inclusive(1, 4)) { |
| 1136 | + const auto ReplicatedMask = createReplicatedMask(ReplicationFactor, VF); |
| 1137 | + int GuessedReplicationFactor = -1, GuessedVF = -1; |
| 1138 | + |
| 1139 | + // If we change some mask elements to undef, we should still match. |
| 1140 | + |
| 1141 | + SmallVector<SmallVector<bool>> ElementChoices(ReplicatedMask.size(), |
| 1142 | + {false, true}); |
| 1143 | + |
| 1144 | + CombinationGenerator<bool, decltype(ElementChoices)::value_type, |
| 1145 | + /*variable_smallsize=*/4> |
| 1146 | + G(ElementChoices); |
| 1147 | + |
| 1148 | + G.generate([&](ArrayRef<bool> UndefOverrides) -> bool { |
| 1149 | + SmallVector<int> AdjustedMask; |
| 1150 | + AdjustedMask.reserve(ReplicatedMask.size()); |
| 1151 | + for (auto I : zip(ReplicatedMask, UndefOverrides)) |
| 1152 | + AdjustedMask.emplace_back(std::get<1>(I) ? -1 : std::get<0>(I)); |
| 1153 | + assert(AdjustedMask.size() == ReplicatedMask.size() && |
| 1154 | + "Size misprediction"); |
| 1155 | + |
| 1156 | + EXPECT_TRUE(ShuffleVectorInst::isReplicationMask( |
| 1157 | + AdjustedMask, GuessedReplicationFactor, GuessedVF)); |
| 1158 | + // Do not check GuessedReplicationFactor and GuessedVF, |
| 1159 | + // with enough undef's we may deduce a different tuple. |
| 1160 | + |
| 1161 | + return /*Abort=*/false; |
| 1162 | + }); |
| 1163 | + } |
| 1164 | + } |
| 1165 | +} |
| 1166 | + |
| 1167 | +TEST(InstructionsTest, ShuffleMaskIsReplicationMask_Exhaustive_Correctness) { |
| 1168 | + for (int ShufMaskNumElts : seq_inclusive(1, 8)) { |
| 1169 | + SmallVector<int> PossibleShufMaskElts; |
| 1170 | + PossibleShufMaskElts.reserve(ShufMaskNumElts + 2); |
| 1171 | + for (int PossibleShufMaskElt : seq_inclusive(-1, ShufMaskNumElts)) |
| 1172 | + PossibleShufMaskElts.emplace_back(PossibleShufMaskElt); |
| 1173 | + assert(PossibleShufMaskElts.size() == ShufMaskNumElts + 2U && |
| 1174 | + "Size misprediction"); |
| 1175 | + |
| 1176 | + SmallVector<SmallVector<int>> ElementChoices(ShufMaskNumElts, |
| 1177 | + PossibleShufMaskElts); |
| 1178 | + |
| 1179 | + CombinationGenerator<int, decltype(ElementChoices)::value_type, |
| 1180 | + /*variable_smallsize=*/4> |
| 1181 | + G(ElementChoices); |
| 1182 | + |
| 1183 | + G.generate([&](ArrayRef<int> Mask) -> bool { |
| 1184 | + int GuessedReplicationFactor = -1, GuessedVF = -1; |
| 1185 | + bool Match = ShuffleVectorInst::isReplicationMask( |
| 1186 | + Mask, GuessedReplicationFactor, GuessedVF); |
| 1187 | + if (!Match) |
| 1188 | + return /*Abort=*/false; |
| 1189 | + |
| 1190 | + const auto ActualMask = |
| 1191 | + createReplicatedMask(GuessedReplicationFactor, GuessedVF); |
| 1192 | + EXPECT_EQ(Mask.size(), ActualMask.size()); |
| 1193 | + for (auto I : zip(Mask, ActualMask)) { |
| 1194 | + int Elt = std::get<0>(I); |
| 1195 | + int ActualElt = std::get<0>(I); |
| 1196 | + |
| 1197 | + if (Elt != -1) |
| 1198 | + EXPECT_EQ(Elt, ActualElt); |
| 1199 | + } |
| 1200 | + |
| 1201 | + return /*Abort=*/false; |
| 1202 | + }); |
| 1203 | + } |
| 1204 | +} |
| 1205 | + |
1118 | 1206 | TEST(InstructionsTest, GetSplat) {
|
1119 | 1207 | // Create the elements for various constant vectors.
|
1120 | 1208 | LLVMContext Ctx;
|
|
0 commit comments