88
99#include " llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h"
1010#include " llvm/Analysis/AssumptionCache.h"
11+ #include " llvm/Analysis/BasicAliasAnalysis.h"
1112#include " llvm/Analysis/LoopInfo.h"
1213#include " llvm/Analysis/ScalarEvolution.h"
1314#include " llvm/Analysis/TargetLibraryInfo.h"
@@ -30,15 +31,20 @@ struct LegalityTest : public testing::Test {
3031 std::unique_ptr<AssumptionCache> AC;
3132 std::unique_ptr<LoopInfo> LI;
3233 std::unique_ptr<ScalarEvolution> SE;
34+ std::unique_ptr<BasicAAResult> BAA;
35+ std::unique_ptr<AAResults> AA;
3336
34- ScalarEvolution & getSE (llvm::Function &LLVMF) {
37+ void getAnalyses (llvm::Function &LLVMF) {
3538 DT = std::make_unique<DominatorTree>(LLVMF);
3639 TLII = std::make_unique<TargetLibraryInfoImpl>();
3740 TLI = std::make_unique<TargetLibraryInfo>(*TLII);
3841 AC = std::make_unique<AssumptionCache>(LLVMF);
3942 LI = std::make_unique<LoopInfo>(*DT);
4043 SE = std::make_unique<ScalarEvolution>(LLVMF, *TLI, *AC, *DT, *LI);
41- return *SE;
44+ BAA = std::make_unique<BasicAAResult>(LLVMF.getParent ()->getDataLayout (),
45+ LLVMF, *TLI, *AC, DT.get ());
46+ AA = std::make_unique<AAResults>(*TLI);
47+ AA->addAAResult (*BAA);
4248 }
4349
4450 void parseIR (LLVMContext &C, const char *IR) {
@@ -49,7 +55,7 @@ struct LegalityTest : public testing::Test {
4955 }
5056};
5157
52- TEST_F (LegalityTest, Legality ) {
58+ TEST_F (LegalityTest, LegalitySkipSchedule ) {
5359 parseIR (C, R"IR(
5460define void @foo(ptr %ptr, <2 x float> %vec2, <3 x float> %vec3, i8 %arg, float %farg0, float %farg1, i64 %v0, i64 %v1, i32 %v2) {
5561 %gep0 = getelementptr float, ptr %ptr, i32 0
@@ -76,7 +82,7 @@ define void @foo(ptr %ptr, <2 x float> %vec2, <3 x float> %vec3, i8 %arg, float
7682}
7783)IR" );
7884 llvm::Function *LLVMF = &*M->getFunction (" foo" );
79- auto &SE = getSE (*LLVMF);
85+ getAnalyses (*LLVMF);
8086 const auto &DL = M->getDataLayout ();
8187
8288 sandboxir::Context Ctx (C);
@@ -104,83 +110,139 @@ define void @foo(ptr %ptr, <2 x float> %vec2, <3 x float> %vec3, i8 %arg, float
104110 auto *CmpSLT = cast<sandboxir::CmpInst>(&*It++);
105111 auto *CmpSGT = cast<sandboxir::CmpInst>(&*It++);
106112
107- sandboxir::LegalityAnalysis Legality (SE, DL);
108- const auto &Result = Legality.canVectorize ({St0, St1});
113+ sandboxir::LegalityAnalysis Legality (*AA, *SE, DL);
114+ const auto &Result =
115+ Legality.canVectorize ({St0, St1}, /* SkipScheduling=*/ true );
109116 EXPECT_TRUE (isa<sandboxir::Widen>(Result));
110117
111118 {
112119 // Check NotInstructions
113- auto &Result = Legality.canVectorize ({F, St0});
120+ auto &Result = Legality.canVectorize ({F, St0}, /* SkipScheduling= */ true );
114121 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
115122 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
116123 sandboxir::ResultReason::NotInstructions);
117124 }
118125 {
119126 // Check DiffOpcodes
120- const auto &Result = Legality.canVectorize ({St0, Ld0});
127+ const auto &Result =
128+ Legality.canVectorize ({St0, Ld0}, /* SkipScheduling=*/ true );
121129 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
122130 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
123131 sandboxir::ResultReason::DiffOpcodes);
124132 }
125133 {
126134 // Check DiffTypes
127- EXPECT_TRUE (isa<sandboxir::Widen>(Legality.canVectorize ({St0, StVec2})));
128- EXPECT_TRUE (isa<sandboxir::Widen>(Legality.canVectorize ({StVec2, StVec3})));
135+ EXPECT_TRUE (isa<sandboxir::Widen>(
136+ Legality.canVectorize ({St0, StVec2}, /* SkipScheduling=*/ true )));
137+ EXPECT_TRUE (isa<sandboxir::Widen>(
138+ Legality.canVectorize ({StVec2, StVec3}, /* SkipScheduling=*/ true )));
129139
130- const auto &Result = Legality.canVectorize ({St0, StI8});
140+ const auto &Result =
141+ Legality.canVectorize ({St0, StI8}, /* SkipScheduling=*/ true );
131142 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
132143 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
133144 sandboxir::ResultReason::DiffTypes);
134145 }
135146 {
136147 // Check DiffMathFlags
137- const auto &Result = Legality.canVectorize ({FAdd0, FAdd1});
148+ const auto &Result =
149+ Legality.canVectorize ({FAdd0, FAdd1}, /* SkipScheduling=*/ true );
138150 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
139151 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
140152 sandboxir::ResultReason::DiffMathFlags);
141153 }
142154 {
143155 // Check DiffWrapFlags
144- const auto &Result = Legality.canVectorize ({Trunc0, Trunc1});
156+ const auto &Result =
157+ Legality.canVectorize ({Trunc0, Trunc1}, /* SkipScheduling=*/ true );
145158 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
146159 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
147160 sandboxir::ResultReason::DiffWrapFlags);
148161 }
149162 {
150163 // Check DiffTypes for unary operands that have a different type.
151- const auto &Result = Legality.canVectorize ({Trunc64to8, Trunc32to8});
164+ const auto &Result = Legality.canVectorize ({Trunc64to8, Trunc32to8},
165+ /* SkipScheduling=*/ true );
152166 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
153167 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
154168 sandboxir::ResultReason::DiffTypes);
155169 }
156170 {
157171 // Check DiffOpcodes for CMPs with different predicates.
158- const auto &Result = Legality.canVectorize ({CmpSLT, CmpSGT});
172+ const auto &Result =
173+ Legality.canVectorize ({CmpSLT, CmpSGT}, /* SkipScheduling=*/ true );
159174 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
160175 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
161176 sandboxir::ResultReason::DiffOpcodes);
162177 }
163178 {
164179 // Check NotConsecutive Ld0,Ld0b
165- const auto &Result = Legality.canVectorize ({Ld0, Ld0b});
180+ const auto &Result =
181+ Legality.canVectorize ({Ld0, Ld0b}, /* SkipScheduling=*/ true );
166182 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
167183 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
168184 sandboxir::ResultReason::NotConsecutive);
169185 }
170186 {
171187 // Check NotConsecutive Ld0,Ld3
172- const auto &Result = Legality.canVectorize ({Ld0, Ld3});
188+ const auto &Result =
189+ Legality.canVectorize ({Ld0, Ld3}, /* SkipScheduling=*/ true );
173190 EXPECT_TRUE (isa<sandboxir::Pack>(Result));
174191 EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
175192 sandboxir::ResultReason::NotConsecutive);
176193 }
177194 {
178195 // Check Widen Ld0,Ld1
179- const auto &Result = Legality.canVectorize ({Ld0, Ld1});
196+ const auto &Result =
197+ Legality.canVectorize ({Ld0, Ld1}, /* SkipScheduling=*/ true );
180198 EXPECT_TRUE (isa<sandboxir::Widen>(Result));
181199 }
182200}
183201
202+ TEST_F (LegalityTest, LegalitySchedule) {
203+ parseIR (C, R"IR(
204+ define void @foo(ptr %ptr) {
205+ %gep0 = getelementptr float, ptr %ptr, i32 0
206+ %gep1 = getelementptr float, ptr %ptr, i32 1
207+ %ld0 = load float, ptr %gep0
208+ store float %ld0, ptr %gep1
209+ %ld1 = load float, ptr %gep1
210+ store float %ld0, ptr %gep0
211+ store float %ld1, ptr %gep1
212+ ret void
213+ }
214+ )IR" );
215+ llvm::Function *LLVMF = &*M->getFunction (" foo" );
216+ getAnalyses (*LLVMF);
217+ const auto &DL = M->getDataLayout ();
218+
219+ sandboxir::Context Ctx (C);
220+ auto *F = Ctx.createFunction (LLVMF);
221+ auto *BB = &*F->begin ();
222+ auto It = BB->begin ();
223+ [[maybe_unused]] auto *Gep0 = cast<sandboxir::GetElementPtrInst>(&*It++);
224+ [[maybe_unused]] auto *Gep1 = cast<sandboxir::GetElementPtrInst>(&*It++);
225+ auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
226+ [[maybe_unused]] auto *ConflictingSt = cast<sandboxir::StoreInst>(&*It++);
227+ auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
228+ auto *St0 = cast<sandboxir::StoreInst>(&*It++);
229+ auto *St1 = cast<sandboxir::StoreInst>(&*It++);
230+
231+ sandboxir::LegalityAnalysis Legality (*AA, *SE, DL);
232+ {
233+ // Can vectorize St0,St1.
234+ const auto &Result = Legality.canVectorize ({St0, St1});
235+ EXPECT_TRUE (isa<sandboxir::Widen>(Result));
236+ }
237+ {
238+ // Can't vectorize Ld0,Ld1 because of conflicting store.
239+ auto &Result = Legality.canVectorize ({Ld0, Ld1});
240+ EXPECT_TRUE (isa<sandboxir::Pack>(Result));
241+ EXPECT_EQ (cast<sandboxir::Pack>(Result).getReason (),
242+ sandboxir::ResultReason::CantSchedule);
243+ }
244+ }
245+
184246#ifndef NDEBUG
185247TEST_F (LegalityTest, LegalityResultDump) {
186248 parseIR (C, R"IR(
@@ -189,7 +251,7 @@ define void @foo() {
189251}
190252)IR" );
191253 llvm::Function *LLVMF = &*M->getFunction (" foo" );
192- auto &SE = getSE (*LLVMF);
254+ getAnalyses (*LLVMF);
193255 const auto &DL = M->getDataLayout ();
194256
195257 auto Matches = [](const sandboxir::LegalityResult &Result,
@@ -200,7 +262,7 @@ define void @foo() {
200262 return Buff == ExpectedStr;
201263 };
202264
203- sandboxir::LegalityAnalysis Legality (SE, DL);
265+ sandboxir::LegalityAnalysis Legality (*AA, * SE, DL);
204266 EXPECT_TRUE (
205267 Matches (Legality.createLegalityResult <sandboxir::Widen>(), " Widen" ));
206268 EXPECT_TRUE (Matches (Legality.createLegalityResult <sandboxir::Pack>(
0 commit comments