Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit ad9846b

Browse files
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373857 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f913f0c commit ad9846b

File tree

2 files changed

+94
-3
lines changed

2 files changed

+94
-3
lines changed

lib/Analysis/LoopInfo.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,11 +360,17 @@ bool Loop::isAuxiliaryInductionVariable(PHINode &AuxIndVar,
360360
}
361361

362362
BranchInst *Loop::getLoopGuardBranch() const {
363-
assert(isLoopSimplifyForm() && "Only valid for loop in simplify form");
363+
if (!isLoopSimplifyForm())
364+
return nullptr;
365+
364366
BasicBlock *Preheader = getLoopPreheader();
365-
assert(Preheader && getLoopLatch() &&
367+
BasicBlock *Latch = getLoopLatch();
368+
assert(Preheader && Latch &&
366369
"Expecting a loop with valid preheader and latch");
367-
assert(isLoopExiting(getLoopLatch()) && "Only valid for rotated loop");
370+
371+
// Loop should be in rotate form.
372+
if (!isLoopExiting(Latch))
373+
return nullptr;
368374

369375
// Disallow loops with more than one unique exit block, as we do not verify
370376
// that GuardOtherSucc post dominates all exit blocks.

unittests/Analysis/LoopInfoTest.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,91 @@ TEST(LoopInfoTest, AuxiliaryIV) {
12721272
});
12731273
}
12741274

1275+
TEST(LoopInfoTest, LoopNotInSimplifyForm) {
1276+
const char *ModuleStr =
1277+
"define void @foo(i32 %n) {\n"
1278+
"entry:\n"
1279+
" %guard.cmp = icmp sgt i32 %n, 0\n"
1280+
" br i1 %guard.cmp, label %for.cond, label %for.end\n"
1281+
"for.cond:\n"
1282+
" %i.0 = phi i32 [ 0, %entry ], [ %inc, %latch.1 ], [ %inc, %latch.2 ]\n"
1283+
" %inc = add nsw i32 %i.0, 1\n"
1284+
" %cmp = icmp slt i32 %i.0, %n\n"
1285+
" br i1 %cmp, label %latch.1, label %for.end\n"
1286+
"latch.1:\n"
1287+
" br i1 undef, label %for.cond, label %latch.2\n"
1288+
"latch.2:\n"
1289+
" br label %for.cond\n"
1290+
"for.end:\n"
1291+
" ret void\n"
1292+
"}\n";
1293+
1294+
// Parse the module.
1295+
LLVMContext Context;
1296+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
1297+
1298+
runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
1299+
Function::iterator FI = F.begin();
1300+
// First basic block is entry - skip it.
1301+
BasicBlock *Header = &*(++FI);
1302+
assert(Header && "No header");
1303+
Loop *L = LI.getLoopFor(Header);
1304+
EXPECT_NE(L, nullptr);
1305+
EXPECT_FALSE(L->isLoopSimplifyForm());
1306+
// No loop guard because loop in not in simplify form.
1307+
EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
1308+
EXPECT_FALSE(L->isGuarded());
1309+
});
1310+
}
1311+
1312+
TEST(LoopInfoTest, LoopLatchNotExiting) {
1313+
const char *ModuleStr =
1314+
"define void @foo(i32* %A, i32 %ub) {\n"
1315+
"entry:\n"
1316+
" %guardcmp = icmp slt i32 0, %ub\n"
1317+
" br i1 %guardcmp, label %for.preheader, label %for.end\n"
1318+
"for.preheader:\n"
1319+
" br label %for.body\n"
1320+
"for.body:\n"
1321+
" %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
1322+
" %idxprom = sext i32 %i to i64\n"
1323+
" %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
1324+
" store i32 %i, i32* %arrayidx, align 4\n"
1325+
" %inc = add nsw i32 %i, 1\n"
1326+
" %cmp = icmp slt i32 %inc, %ub\n"
1327+
" br i1 %cmp, label %for.latch, label %for.exit\n"
1328+
"for.latch:\n"
1329+
" br label %for.body\n"
1330+
"for.exit:\n"
1331+
" br label %for.end\n"
1332+
"for.end:\n"
1333+
" ret void\n"
1334+
"}\n";
1335+
1336+
// Parse the module.
1337+
LLVMContext Context;
1338+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
1339+
1340+
runWithLoopInfoPlus(
1341+
*M, "foo",
1342+
[&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1343+
Function::iterator FI = F.begin();
1344+
// First two basic block are entry and for.preheader - skip them.
1345+
++FI;
1346+
BasicBlock *Header = &*(++FI);
1347+
BasicBlock *Latch = &*(++FI);
1348+
assert(Header && "No header");
1349+
Loop *L = LI.getLoopFor(Header);
1350+
EXPECT_NE(L, nullptr);
1351+
EXPECT_TRUE(L->isLoopSimplifyForm());
1352+
EXPECT_EQ(L->getLoopLatch(), Latch);
1353+
EXPECT_FALSE(L->isLoopExiting(Latch));
1354+
// No loop guard becuase loop is not exiting on latch.
1355+
EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
1356+
EXPECT_FALSE(L->isGuarded());
1357+
});
1358+
}
1359+
12751360
// Examine getUniqueExitBlocks/getUniqueNonLatchExitBlocks functions.
12761361
TEST(LoopInfoTest, LoopUniqueExitBlocks) {
12771362
const char *ModuleStr =

0 commit comments

Comments
 (0)