@@ -292,3 +292,131 @@ define void @foo(i8 %v0, i8 %v1, i8 %v2) {
292292 EXPECT_EQ (SB.getBeforeCost (), GetCost (LLVMAdd2));
293293 EXPECT_EQ (SB.getAfterCost (), GetCost (LLVMAdd1));
294294}
295+
296+ TEST_F (RegionTest, Aux) {
297+ parseIR (C, R"IR(
298+ define void @foo(i8 %v) {
299+ %t0 = add i8 %v, 0, !sandboxvec !0, !sandboxaux !2
300+ %t1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !3
301+ %t2 = add i8 %v, 2, !sandboxvec !1
302+ %t3 = add i8 %v, 3, !sandboxvec !1, !sandboxaux !2
303+ %t4 = add i8 %v, 4, !sandboxvec !1, !sandboxaux !4
304+ %t5 = add i8 %v, 5, !sandboxvec !1, !sandboxaux !3
305+ ret void
306+ }
307+
308+ !0 = distinct !{!"sandboxregion"}
309+ !1 = distinct !{!"sandboxregion"}
310+
311+ !2 = !{i32 0}
312+ !3 = !{i32 1}
313+ !4 = !{i32 2}
314+ )IR" );
315+ llvm::Function *LLVMF = &*M->getFunction (" foo" );
316+ auto *LLVMBB = &*LLVMF->begin ();
317+ auto LLVMIt = LLVMBB->begin ();
318+ auto *LLVMI0 = &*LLVMIt++;
319+ auto *LLVMI1 = &*LLVMIt++;
320+ sandboxir::Context Ctx (C);
321+ auto *F = Ctx.createFunction (LLVMF);
322+ auto *BB = &*F->begin ();
323+ auto It = BB->begin ();
324+ auto *T0 = cast<sandboxir::Instruction>(&*It++);
325+ auto *T1 = cast<sandboxir::Instruction>(&*It++);
326+ auto *T2 = cast<sandboxir::Instruction>(&*It++);
327+ auto *T3 = cast<sandboxir::Instruction>(&*It++);
328+ auto *T4 = cast<sandboxir::Instruction>(&*It++);
329+ auto *T5 = cast<sandboxir::Instruction>(&*It++);
330+
331+ SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
332+ sandboxir::Region::createRegionsFromMD (*F, *TTI);
333+ // Check that the regions are correct.
334+ EXPECT_THAT (Regions[0 ]->insts (), testing::UnorderedElementsAre (T0, T1));
335+ EXPECT_THAT (Regions[1 ]->insts (),
336+ testing::UnorderedElementsAre (T2, T3, T4, T5));
337+ // Check aux.
338+ EXPECT_THAT (Regions[0 ]->getAux (), testing::ElementsAre (T0, T1));
339+ EXPECT_THAT (Regions[1 ]->getAux (), testing::ElementsAre (T3, T5, T4));
340+ // Check clearAux().
341+ EXPECT_TRUE (LLVMI0->getMetadata (" sandboxaux" ));
342+ EXPECT_TRUE (LLVMI1->getMetadata (" sandboxaux" ));
343+ Regions[0 ]->clearAux ();
344+ EXPECT_TRUE (Regions[0 ]->getAux ().empty ());
345+ EXPECT_FALSE (LLVMI0->getMetadata (" sandboxaux" ));
346+ EXPECT_FALSE (LLVMI1->getMetadata (" sandboxaux" ));
347+ }
348+
349+ // Check that Aux is well-formed.
350+ TEST_F (RegionTest, AuxVerify) {
351+ parseIR (C, R"IR(
352+ define void @foo(i8 %v) {
353+ %t0 = add i8 %v, 0, !sandboxvec !0, !sandboxaux !2
354+ %t1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !3
355+ ret void
356+ }
357+
358+ !0 = distinct !{!"sandboxregion"}
359+ !2 = !{i32 0}
360+ !3 = !{i32 2}
361+ )IR" );
362+ llvm::Function *LLVMF = &*M->getFunction (" foo" );
363+ sandboxir::Context Ctx (C);
364+ auto *F = Ctx.createFunction (LLVMF);
365+ #ifndef NDEBUG
366+ EXPECT_DEATH (sandboxir::Region::createRegionsFromMD (*F, *TTI), " .*Gap*" );
367+ #endif
368+ }
369+
370+ // Check that we get an assertion failure if we try to set the same index more
371+ // than once.
372+ TEST_F (RegionTest, AuxSameIndex) {
373+ parseIR (C, R"IR(
374+ define void @foo(i8 %v) {
375+ %t0 = add i8 %v, 0, !sandboxvec !0, !sandboxaux !2
376+ %t1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !2
377+ ret void
378+ }
379+
380+ !0 = distinct !{!"sandboxregion"}
381+ !2 = !{i32 0}
382+ )IR" );
383+ llvm::Function *LLVMF = &*M->getFunction (" foo" );
384+ sandboxir::Context Ctx (C);
385+ auto *F = Ctx.createFunction (LLVMF);
386+ #ifndef NDEBUG
387+ EXPECT_DEATH (sandboxir::Region::createRegionsFromMD (*F, *TTI), " .*already.*" );
388+ #endif // NDEBUG
389+ }
390+
391+ TEST_F (RegionTest, AuxRoundTrip) {
392+ parseIR (C, R"IR(
393+ define i8 @foo(i8 %v0, i8 %v1) {
394+ %t0 = add i8 %v0, 1
395+ %t1 = add i8 %t0, %v1
396+ ret i8 %t1
397+ }
398+ )IR" );
399+ llvm::Function *LLVMF = &*M->getFunction (" foo" );
400+ sandboxir::Context Ctx (C);
401+ auto *F = Ctx.createFunction (LLVMF);
402+ auto *BB = &*F->begin ();
403+ auto It = BB->begin ();
404+ auto *T0 = cast<sandboxir::Instruction>(&*It++);
405+ auto *T1 = cast<sandboxir::Instruction>(&*It++);
406+
407+ sandboxir::Region Rgn (Ctx, *TTI);
408+ Rgn.add (T0);
409+ Rgn.add (T1);
410+ #ifndef NDEBUG
411+ EXPECT_DEATH (Rgn.setAux ({T0, T0}), " .*already.*" );
412+ #endif
413+ Rgn.setAux ({T1, T0});
414+
415+ SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
416+ sandboxir::Region::createRegionsFromMD (*F, *TTI);
417+ ASSERT_EQ (1U , Regions.size ());
418+ #ifndef NDEBUG
419+ EXPECT_EQ (Rgn, *Regions[0 ].get ());
420+ #endif
421+ EXPECT_THAT (Rgn.getAux (), testing::ElementsAre (T1, T0));
422+ }
0 commit comments