Skip to content

Commit 3c6041d

Browse files
authored
[SandboxVec][Interval] Implement getUnionInterval() and getSingleDiff() (#111455)
1 parent c563fe5 commit 3c6041d

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,27 @@ template <typename T> class Interval {
176176
Result.emplace_back(Intersection.To->getNextNode(), To);
177177
return Result;
178178
}
179+
/// \Returns the interval difference `this - Other`. This will crash in Debug
180+
/// if the result is not a single interval.
181+
Interval getSingleDiff(const Interval &Other) {
182+
auto Diff = *this - Other;
183+
assert(Diff.size() == 1 && "Expected a single interval!");
184+
return Diff[0];
185+
}
186+
/// \Returns a single interval that spans across both this and \p Other.
187+
// For example:
188+
// |---| this
189+
// |---| Other
190+
// |----------| this->getUnionInterval(Other)
191+
Interval getUnionInterval(const Interval &Other) {
192+
if (empty())
193+
return Other;
194+
if (Other.empty())
195+
return *this;
196+
auto *NewFrom = From->comesBefore(Other.From) ? From : Other.From;
197+
auto *NewTo = To->comesBefore(Other.To) ? Other.To : To;
198+
return {NewFrom, NewTo};
199+
}
179200
};
180201

181202
} // namespace llvm::sandboxir

llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ define void @foo(i8 %v0) {
162162
EXPECT_EQ(Diffs.size(), 1u);
163163
const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0];
164164
EXPECT_THAT(getPtrVec(Diff), testing::ElementsAre(I0, I1, I2, Ret));
165+
166+
// Check getSingleDiff().
167+
EXPECT_EQ(I0Ret.getSingleDiff(Empty), Diff);
165168
}
166169
{
167170
// Check [] - [I0,Ret]
@@ -171,6 +174,9 @@ define void @foo(i8 %v0) {
171174
EXPECT_EQ(Diffs.size(), 1u);
172175
const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0];
173176
EXPECT_TRUE(Diff.empty());
177+
178+
// Check getSingleDiff().
179+
EXPECT_EQ(Empty.getSingleDiff(I0Ret), Diff);
174180
}
175181
{
176182
// Check [I0,Ret] - [I0].
@@ -180,6 +186,9 @@ define void @foo(i8 %v0) {
180186
EXPECT_EQ(Diffs.size(), 1u);
181187
const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0];
182188
EXPECT_THAT(getPtrVec(Diff), testing::ElementsAre(I1, I2, Ret));
189+
190+
// Check getSingleDiff().
191+
EXPECT_EQ(I0Ret.getSingleDiff(I0I0), Diff);
183192
}
184193
{
185194
// Check [I0,Ret] - [I1].
@@ -191,6 +200,11 @@ define void @foo(i8 %v0) {
191200
EXPECT_THAT(getPtrVec(Diff0), testing::ElementsAre(I0));
192201
const sandboxir::Interval<sandboxir::Instruction> &Diff1 = Diffs[1];
193202
EXPECT_THAT(getPtrVec(Diff1), testing::ElementsAre(I2, Ret));
203+
204+
#ifndef NDEBUG
205+
// Check getSingleDiff().
206+
EXPECT_DEATH(I0Ret.getSingleDiff(I1I1), ".*single.*");
207+
#endif // NDEBUG
194208
}
195209
}
196210

@@ -249,3 +263,52 @@ define void @foo(i8 %v0) {
249263
EXPECT_THAT(getPtrVec(Intersection), testing::ElementsAre(I1));
250264
}
251265
}
266+
267+
TEST_F(IntervalTest, UnionInterval) {
268+
parseIR(C, R"IR(
269+
define void @foo(i8 %v0) {
270+
%I0 = add i8 %v0, %v0
271+
%I1 = add i8 %v0, %v0
272+
%I2 = add i8 %v0, %v0
273+
ret void
274+
}
275+
)IR");
276+
Function &LLVMF = *M->getFunction("foo");
277+
sandboxir::Context Ctx(C);
278+
auto &F = *Ctx.createFunction(&LLVMF);
279+
auto *BB = &*F.begin();
280+
auto It = BB->begin();
281+
auto *I0 = &*It++;
282+
auto *I1 = &*It++;
283+
[[maybe_unused]] auto *I2 = &*It++;
284+
auto *Ret = &*It++;
285+
286+
{
287+
// Check [I0] unionInterval [I2].
288+
sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
289+
sandboxir::Interval<sandboxir::Instruction> I2I2(I2, I2);
290+
auto SingleUnion = I0I0.getUnionInterval(I2I2);
291+
EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1, I2));
292+
}
293+
{
294+
// Check [I0] unionInterval Empty.
295+
sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
296+
sandboxir::Interval<sandboxir::Instruction> Empty;
297+
auto SingleUnion = I0I0.getUnionInterval(Empty);
298+
EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0));
299+
}
300+
{
301+
// Check [I0,I1] unionInterval [I1].
302+
sandboxir::Interval<sandboxir::Instruction> I0I1(I0, I1);
303+
sandboxir::Interval<sandboxir::Instruction> I1I1(I1, I1);
304+
auto SingleUnion = I0I1.getUnionInterval(I1I1);
305+
EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1));
306+
}
307+
{
308+
// Check [I2,Ret] unionInterval [I0].
309+
sandboxir::Interval<sandboxir::Instruction> I2Ret(I2, Ret);
310+
sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
311+
auto SingleUnion = I2Ret.getUnionInterval(I0I0);
312+
EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1, I2, Ret));
313+
}
314+
}

0 commit comments

Comments
 (0)