mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[LOOPGUARD] Remove asserts in getLoopGuardBranch
Summary: The assertion in getLoopGuardBranch can be a 'return nullptr' under if condition. Authored By: DTharun Reviewer: Whitney, fhahn Reviewed By: Whitney, fhahn Subscribers: fhahn, llvm-commits Tag: LLVM Differential Revision: https://reviews.llvm.org/D66084 llvm-svn: 373857
This commit is contained in:
parent
8f532fcce0
commit
a6f46eec3d
@ -360,11 +360,17 @@ bool Loop::isAuxiliaryInductionVariable(PHINode &AuxIndVar,
|
||||
}
|
||||
|
||||
BranchInst *Loop::getLoopGuardBranch() const {
|
||||
assert(isLoopSimplifyForm() && "Only valid for loop in simplify form");
|
||||
if (!isLoopSimplifyForm())
|
||||
return nullptr;
|
||||
|
||||
BasicBlock *Preheader = getLoopPreheader();
|
||||
assert(Preheader && getLoopLatch() &&
|
||||
BasicBlock *Latch = getLoopLatch();
|
||||
assert(Preheader && Latch &&
|
||||
"Expecting a loop with valid preheader and latch");
|
||||
assert(isLoopExiting(getLoopLatch()) && "Only valid for rotated loop");
|
||||
|
||||
// Loop should be in rotate form.
|
||||
if (!isLoopExiting(Latch))
|
||||
return nullptr;
|
||||
|
||||
// Disallow loops with more than one unique exit block, as we do not verify
|
||||
// that GuardOtherSucc post dominates all exit blocks.
|
||||
|
@ -1272,6 +1272,91 @@ TEST(LoopInfoTest, AuxiliaryIV) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LoopInfoTest, LoopNotInSimplifyForm) {
|
||||
const char *ModuleStr =
|
||||
"define void @foo(i32 %n) {\n"
|
||||
"entry:\n"
|
||||
" %guard.cmp = icmp sgt i32 %n, 0\n"
|
||||
" br i1 %guard.cmp, label %for.cond, label %for.end\n"
|
||||
"for.cond:\n"
|
||||
" %i.0 = phi i32 [ 0, %entry ], [ %inc, %latch.1 ], [ %inc, %latch.2 ]\n"
|
||||
" %inc = add nsw i32 %i.0, 1\n"
|
||||
" %cmp = icmp slt i32 %i.0, %n\n"
|
||||
" br i1 %cmp, label %latch.1, label %for.end\n"
|
||||
"latch.1:\n"
|
||||
" br i1 undef, label %for.cond, label %latch.2\n"
|
||||
"latch.2:\n"
|
||||
" br label %for.cond\n"
|
||||
"for.end:\n"
|
||||
" ret void\n"
|
||||
"}\n";
|
||||
|
||||
// Parse the module.
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
|
||||
|
||||
runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
|
||||
Function::iterator FI = F.begin();
|
||||
// First basic block is entry - skip it.
|
||||
BasicBlock *Header = &*(++FI);
|
||||
assert(Header && "No header");
|
||||
Loop *L = LI.getLoopFor(Header);
|
||||
EXPECT_NE(L, nullptr);
|
||||
EXPECT_FALSE(L->isLoopSimplifyForm());
|
||||
// No loop guard because loop in not in simplify form.
|
||||
EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
|
||||
EXPECT_FALSE(L->isGuarded());
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LoopInfoTest, LoopLatchNotExiting) {
|
||||
const char *ModuleStr =
|
||||
"define void @foo(i32* %A, i32 %ub) {\n"
|
||||
"entry:\n"
|
||||
" %guardcmp = icmp slt i32 0, %ub\n"
|
||||
" br i1 %guardcmp, label %for.preheader, label %for.end\n"
|
||||
"for.preheader:\n"
|
||||
" br label %for.body\n"
|
||||
"for.body:\n"
|
||||
" %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
|
||||
" %idxprom = sext i32 %i to i64\n"
|
||||
" %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
|
||||
" store i32 %i, i32* %arrayidx, align 4\n"
|
||||
" %inc = add nsw i32 %i, 1\n"
|
||||
" %cmp = icmp slt i32 %inc, %ub\n"
|
||||
" br i1 %cmp, label %for.latch, label %for.exit\n"
|
||||
"for.latch:\n"
|
||||
" br label %for.body\n"
|
||||
"for.exit:\n"
|
||||
" br label %for.end\n"
|
||||
"for.end:\n"
|
||||
" ret void\n"
|
||||
"}\n";
|
||||
|
||||
// Parse the module.
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
|
||||
|
||||
runWithLoopInfoPlus(
|
||||
*M, "foo",
|
||||
[&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
|
||||
Function::iterator FI = F.begin();
|
||||
// First two basic block are entry and for.preheader - skip them.
|
||||
++FI;
|
||||
BasicBlock *Header = &*(++FI);
|
||||
BasicBlock *Latch = &*(++FI);
|
||||
assert(Header && "No header");
|
||||
Loop *L = LI.getLoopFor(Header);
|
||||
EXPECT_NE(L, nullptr);
|
||||
EXPECT_TRUE(L->isLoopSimplifyForm());
|
||||
EXPECT_EQ(L->getLoopLatch(), Latch);
|
||||
EXPECT_FALSE(L->isLoopExiting(Latch));
|
||||
// No loop guard becuase loop is not exiting on latch.
|
||||
EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
|
||||
EXPECT_FALSE(L->isGuarded());
|
||||
});
|
||||
}
|
||||
|
||||
// Examine getUniqueExitBlocks/getUniqueNonLatchExitBlocks functions.
|
||||
TEST(LoopInfoTest, LoopUniqueExitBlocks) {
|
||||
const char *ModuleStr =
|
||||
|
Loading…
Reference in New Issue
Block a user