@@ -292,3 +292,110 @@ 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+ TEST_F (RegionTest, AuxRoundTrip) {
371+ parseIR (C, R"IR(
372+ define i8 @foo(i8 %v0, i8 %v1) {
373+ %t0 = add i8 %v0, 1
374+ %t1 = add i8 %t0, %v1
375+ ret i8 %t1
376+ }
377+ )IR" );
378+ llvm::Function *LLVMF = &*M->getFunction (" foo" );
379+ sandboxir::Context Ctx (C);
380+ auto *F = Ctx.createFunction (LLVMF);
381+ auto *BB = &*F->begin ();
382+ auto It = BB->begin ();
383+ auto *T0 = cast<sandboxir::Instruction>(&*It++);
384+ auto *T1 = cast<sandboxir::Instruction>(&*It++);
385+
386+ sandboxir::Region Rgn (Ctx, *TTI);
387+ Rgn.add (T0);
388+ Rgn.add (T1);
389+ #ifndef NDEBUG
390+ EXPECT_DEATH (Rgn.setAux ({T0, T0}), " .*already.*" );
391+ #endif
392+ Rgn.setAux ({T1, T0});
393+
394+ SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
395+ sandboxir::Region::createRegionsFromMD (*F, *TTI);
396+ ASSERT_EQ (1U , Regions.size ());
397+ #ifndef NDEBUG
398+ EXPECT_EQ (Rgn, *Regions[0 ].get ());
399+ #endif
400+ EXPECT_THAT (Rgn.getAux (), testing::ElementsAre (T1, T0));
401+ }
0 commit comments