diff --git a/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp b/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp --- a/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp +++ b/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp @@ -43,7 +43,7 @@ TargetLibraryInfo TLI(TLII); AssumptionCache AC(*F); AAResults AA(TLI); - DataLayout DL("e-i64:64-f80:128-n8:16:32:64-S128"); + DataLayout DL(""); BasicAAResult BAA(DL, *F, TLI, AC, &DT); AA.addAAResult(BAA); LoopInfo LI(DT); @@ -998,3 +998,129 @@ isSafeToMoveBefore(*LoadA0, *LoadA1, DT, &PDT, nullptr, &AA)); }); } + +TEST(CodeMoverUtils, IsSafeToMoveTest7) { + LLVMContext C; + + std::unique_ptr M = + parseIR(C, R"(define i32 @dependence(i32* noalias %A, i32* noalias %B) { +entry: + store i32 0, i32* %A, align 4 ; storeA0 + store i32 4, i32* %A, align 4 ; storeA1 + store i32 8, i32* %B, align 4 ; storeB0 + %tmp0 = load i32, i32* %A, align 4 ; LoadA0 + br label %header + +header: + %b = phi i32 [ 0, %entry ], [ %c, %latch ] + %c = add i32 %b, 1 + %z = icmp eq i32 %c, 0 + store i32 2, i32* %A, align 4 ; StoreA2 + %tmp1 = load i32, i32* %B, align 4 ; LoadB0 + %tmp2 = icmp slt i32 %tmp1, %tmp1 + br i1 %tmp2, label %bb1, label %bb5 + +bb1: + store i32 7, i32* %B, align 4 ; StoreB1 + %tmp3 = load i32, i32* %B, align 4 ; LoadB1 + %tmp4 = load i32, i32* %A, align 4 ; LoadA1 + %tmp5 = icmp sgt i32 %tmp3, 10 + br i1 %tmp5, label %bb2, label %bb3 + +bb2: + store i32 9, i32* %B, align 4 ; StoreB2 + br label %bb3 + +bb3: + call void @function(i32 %tmp1) + %tmp6 = load i32, i32* %B, align 4 ; LoadB2 + store i32 5, i32* %A, align 4 ; StoreA3 + %tmp7 = load i32, i32* %A, align 4 ; LoadA2 + br label %latch + +latch: + store i32 8, i32* %B, align 4 ; StoreB3 + %tmp8 = load i32, i32* %B, align 4 ; LoadB3 + store i32 2, i32* %A, align 4 ; StoreA4 + %tmp9 = add nsw i32 %tmp8, 1 + br label %header + +bb5: + %tmp10 = load i32, i32* %B, align 4 ; LoadB4 + store i32 1, i32* %B, align 4 ; StoreB4 + store i32 2, i32* %A, align 4 ; StoreA5 + ret i32 0 +} +declare void @function(i32) willreturn nosync nounwind +)"); + run(*M, "dependence", + [&](Function &F, DominatorTree &DT, PostDominatorTree &PDT, + DependenceInfo &DI, AAResults &AA) { + Instruction *LoadA0 = getInstructionByName(F, "tmp0"); + Instruction *LoadB0 = getInstructionByName(F, "tmp1"); + Instruction *LoadB2 = getInstructionByName(F, "tmp6"); + Instruction *LoadA2 = getInstructionByName(F, "tmp7"); + Instruction *LoadB3 = getInstructionByName(F, "tmp8"); + Instruction *StoreB0 = LoadA0->getPrevNode(); + Instruction *StoreA2 = LoadB0->getPrevNode(); + Instruction *StoreA3 = LoadA2->getPrevNode(); + Instruction *StoreB3 = LoadB3->getPrevNode(); + Instruction *StoreA4 = LoadB3->getNextNode(); + + // sink instruction from entry to header + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB0, *StoreA2, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB0, *StoreA2, DT, &PDT, nullptr, &AA)); + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB0, *LoadB0, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB0, *LoadB0, DT, &PDT, nullptr, &AA)); + EXPECT_FALSE( + isSafeToMoveBefore(*LoadA0, *LoadB0, DT, &PDT, &DI, nullptr)); + EXPECT_FALSE( + isSafeToMoveBefore(*LoadA0, *LoadB0, DT, &PDT, nullptr, &AA)); + EXPECT_TRUE( + isSafeToMoveBefore(*LoadA0, *StoreA2, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*LoadA0, *StoreA2, DT, &PDT, nullptr, &AA)); + + // hoist instrcution from header to entry + EXPECT_TRUE( + isSafeToMoveBefore(*LoadB0, *LoadA0, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*LoadB0, *LoadA0, DT, &PDT, nullptr, &AA)); + EXPECT_FALSE( + isSafeToMoveBefore(*LoadB0, *StoreB0, DT, &PDT, &DI, nullptr)); + EXPECT_FALSE( + isSafeToMoveBefore(*LoadB0, *StoreB0, DT, &PDT, nullptr, &AA)); + + // sink instrcutions from bb3 to latch + EXPECT_TRUE( + isSafeToMoveBefore(*LoadA2, *StoreB3, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*LoadA2, *StoreB3, DT, &PDT, nullptr, &AA)); + EXPECT_TRUE( + isSafeToMoveBefore(*LoadA2, *LoadB3, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*LoadA2, *LoadB3, DT, &PDT, nullptr, &AA)); + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB3, *LoadA2, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB3, *LoadA2, DT, &PDT, nullptr, &AA)); + + // hoist instructions from latch to bb3 + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB3, *StoreA3, DT, &PDT, &DI, nullptr)); + EXPECT_TRUE( + isSafeToMoveBefore(*StoreB3, *StoreA3, DT, &PDT, nullptr, &AA)); + EXPECT_FALSE( + isSafeToMoveBefore(*StoreA4, *LoadA2, DT, &PDT, &DI, nullptr)); + EXPECT_FALSE( + isSafeToMoveBefore(*StoreA4, *LoadA2, DT, &PDT, nullptr, &AA)); + EXPECT_FALSE( + isSafeToMoveBefore(*StoreB3, *LoadB2, DT, &PDT, &DI, nullptr)); + EXPECT_FALSE( + isSafeToMoveBefore(*StoreB3, *LoadB2, DT, &PDT, nullptr, &AA)); + }); +}