Skip to content

Commit 75a73c9

Browse files
committed
Revert "[ScalarEvolution] Infer loop max trip count from array accesses"
This reverts commit 57e0931.
1 parent 47a4331 commit 75a73c9

File tree

3 files changed

+0
-335
lines changed

3 files changed

+0
-335
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -831,13 +831,6 @@ class ScalarEvolution {
831831
/// Returns 0 if the trip count is unknown or not constant.
832832
unsigned getSmallConstantMaxTripCount(const Loop *L);
833833

834-
/// Returns the upper bound of the loop trip count infered from array size.
835-
/// Can not access bytes starting outside the statically allocated size
836-
/// without being immediate UB.
837-
/// Returns SCEVCouldNotCompute if the trip count could not inferred
838-
/// from array accesses.
839-
const SCEV *getConstantMaxTripCountFromArray(const Loop *L);
840-
841834
/// Returns the largest constant divisor of the trip count as a normal
842835
/// unsigned value, if possible. This means that the actual trip count is
843836
/// always a multiple of the returned value. Returns 1 if the trip count is

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 0 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -8107,126 +8107,6 @@ unsigned ScalarEvolution::getSmallConstantMaxTripCount(const Loop *L) {
81078107
return getConstantTripCount(MaxExitCount);
81088108
}
81098109

8110-
const SCEV *ScalarEvolution::getConstantMaxTripCountFromArray(const Loop *L) {
8111-
// We can't infer from Array in Irregular Loop.
8112-
// FIXME: It's hard to infer loop bound from array operated in Nested Loop.
8113-
if (!L->isLoopSimplifyForm() || !L->isInnermost())
8114-
return getCouldNotCompute();
8115-
8116-
// FIXME: To make the scene more typical, we only analysis loops that have
8117-
// one exiting block and that block must be the latch. To make it easier to
8118-
// capture loops that have memory access and memory access will be executed
8119-
// in each iteration.
8120-
const BasicBlock *LoopLatch = L->getLoopLatch();
8121-
assert(LoopLatch && "See defination of simplify form loop.");
8122-
if (L->getExitingBlock() != LoopLatch)
8123-
return getCouldNotCompute();
8124-
8125-
const DataLayout &DL = getDataLayout();
8126-
SmallVector<const SCEV *> InferCountColl;
8127-
for (auto *BB : L->getBlocks()) {
8128-
// Go here, we can know that Loop is a single exiting and simplified form
8129-
// loop. Make sure that infer from Memory Operation in those BBs must be
8130-
// executed in loop. First step, we can make sure that max execution time
8131-
// of MemAccessBB in loop represents latch max excution time.
8132-
// If MemAccessBB does not dom Latch, skip.
8133-
// Entry
8134-
// │
8135-
// ┌─────▼─────┐
8136-
// │Loop Header◄─────┐
8137-
// └──┬──────┬─┘ │
8138-
// │ │ │
8139-
// ┌────────▼──┐ ┌─▼─────┐ │
8140-
// │MemAccessBB│ │OtherBB│ │
8141-
// └────────┬──┘ └─┬─────┘ │
8142-
// │ │ │
8143-
// ┌─▼──────▼─┐ │
8144-
// │Loop Latch├─────┘
8145-
// └────┬─────┘
8146-
// ▼
8147-
// Exit
8148-
if (!DT.dominates(BB, LoopLatch))
8149-
continue;
8150-
8151-
for (Instruction &Inst : *BB) {
8152-
// Find Memory Operation Instruction.
8153-
auto *GEP = getLoadStorePointerOperand(&Inst);
8154-
if (!GEP)
8155-
continue;
8156-
8157-
auto *ElemSize = dyn_cast<SCEVConstant>(getElementSize(&Inst));
8158-
// Do not infer from scalar type, eg."ElemSize = sizeof()".
8159-
if (!ElemSize)
8160-
continue;
8161-
8162-
// Use a existing polynomial recurrence on the trip count.
8163-
auto *AddRec = dyn_cast<SCEVAddRecExpr>(getSCEV(GEP));
8164-
if (!AddRec)
8165-
continue;
8166-
auto *ArrBase = dyn_cast<SCEVUnknown>(getPointerBase(AddRec));
8167-
auto *Step = dyn_cast<SCEVConstant>(AddRec->getStepRecurrence(*this));
8168-
if (!ArrBase || !Step)
8169-
continue;
8170-
assert(isLoopInvariant(ArrBase, L) && "See addrec definition");
8171-
8172-
// Only handle { %array + step },
8173-
// FIXME: {(SCEVAddRecExpr) + step } could not be analysed here.
8174-
if (AddRec->getStart() != ArrBase)
8175-
continue;
8176-
8177-
// Memory operation pattern which have gaps.
8178-
// Or repeat memory opreation.
8179-
// And index of GEP wraps arround.
8180-
if (Step->getAPInt().getActiveBits() > 32 ||
8181-
Step->getAPInt().getZExtValue() !=
8182-
ElemSize->getAPInt().getZExtValue() ||
8183-
Step->isZero() || Step->getAPInt().isNegative())
8184-
continue;
8185-
8186-
// Only infer from stack array which has certain size.
8187-
// Make sure alloca instruction is not excuted in loop.
8188-
AllocaInst *AllocateInst = dyn_cast<AllocaInst>(ArrBase->getValue());
8189-
if (!AllocateInst || L->contains(AllocateInst->getParent()))
8190-
continue;
8191-
8192-
// Make sure only handle normal array.
8193-
auto *Ty = dyn_cast<ArrayType>(AllocateInst->getAllocatedType());
8194-
auto *ArrSize = dyn_cast<ConstantInt>(AllocateInst->getArraySize());
8195-
if (!Ty || !ArrSize || !ArrSize->isOne())
8196-
continue;
8197-
8198-
// FIXME: Since gep indices are silently zext to the indexing type,
8199-
// we will have a narrow gep index which wraps around rather than
8200-
// increasing strictly, we shoule ensure that step is increasing
8201-
// strictly by the loop iteration.
8202-
// Now we can infer a max execution time by MemLength/StepLength.
8203-
const SCEV *MemSize =
8204-
getConstant(Step->getType(), DL.getTypeAllocSize(Ty));
8205-
auto *MaxExeCount =
8206-
dyn_cast<SCEVConstant>(getUDivCeilSCEV(MemSize, Step));
8207-
if (!MaxExeCount || MaxExeCount->getAPInt().getActiveBits() > 32)
8208-
continue;
8209-
8210-
// If the loop reaches the maximum number of executions, we can not
8211-
// access bytes starting outside the statically allocated size without
8212-
// being immediate UB. But it is allowed to enter loop header one more
8213-
// time.
8214-
auto *InferCount = dyn_cast<SCEVConstant>(
8215-
getAddExpr(MaxExeCount, getOne(MaxExeCount->getType())));
8216-
// Discard the maximum number of execution times under 32bits.
8217-
if (!InferCount || InferCount->getAPInt().getActiveBits() > 32)
8218-
continue;
8219-
8220-
InferCountColl.push_back(InferCount);
8221-
}
8222-
}
8223-
8224-
if (InferCountColl.size() == 0)
8225-
return getCouldNotCompute();
8226-
8227-
return getUMinFromMismatchedTypes(InferCountColl);
8228-
}
8229-
82308110
unsigned ScalarEvolution::getSmallConstantTripMultiple(const Loop *L) {
82318111
SmallVector<BasicBlock *, 8> ExitingBlocks;
82328112
L->getExitingBlocks(ExitingBlocks);

llvm/unittests/Analysis/ScalarEvolutionTest.cpp

Lines changed: 0 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,214 +1536,6 @@ TEST_F(ScalarEvolutionsTest, SCEVUDivFloorCeiling) {
15361536
});
15371537
}
15381538

1539-
TEST_F(ScalarEvolutionsTest, ComputeMaxTripCountFromArrayNormal) {
1540-
LLVMContext C;
1541-
SMDiagnostic Err;
1542-
std::unique_ptr<Module> M = parseAssemblyString(
1543-
"define void @foo(i32 signext %len) { "
1544-
"entry: "
1545-
" %a = alloca [7 x i32], align 4 "
1546-
" %cmp4 = icmp sgt i32 %len, 0 "
1547-
" br i1 %cmp4, label %for.body.preheader, label %for.cond.cleanup "
1548-
"for.body.preheader: "
1549-
" br label %for.body "
1550-
"for.cond.cleanup.loopexit: "
1551-
" br label %for.cond.cleanup "
1552-
"for.cond.cleanup: "
1553-
" ret void "
1554-
"for.body: "
1555-
" %iv = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] "
1556-
" %idxprom = zext i32 %iv to i64 "
1557-
" %arrayidx = getelementptr inbounds [7 x i32], [7 x i32]* %a, i64 0, \
1558-
i64 %idxprom "
1559-
" store i32 0, i32* %arrayidx, align 4 "
1560-
" %inc = add nuw nsw i32 %iv, 1 "
1561-
" %cmp = icmp slt i32 %inc, %len "
1562-
" br i1 %cmp, label %for.body, label %for.cond.cleanup.loopexit "
1563-
"} ",
1564-
Err, C);
1565-
1566-
ASSERT_TRUE(M && "Could not parse module?");
1567-
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
1568-
1569-
runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1570-
auto *ScevIV = SE.getSCEV(getInstructionByName(F, "iv"));
1571-
const Loop *L = cast<SCEVAddRecExpr>(ScevIV)->getLoop();
1572-
1573-
const SCEV *ITC = SE.getConstantMaxTripCountFromArray(L);
1574-
EXPECT_FALSE(isa<SCEVCouldNotCompute>(ITC));
1575-
EXPECT_TRUE(isa<SCEVConstant>(ITC));
1576-
EXPECT_EQ(cast<SCEVConstant>(ITC)->getAPInt().getSExtValue(), 8);
1577-
});
1578-
}
1579-
1580-
TEST_F(ScalarEvolutionsTest, ComputeMaxTripCountFromZeroArray) {
1581-
LLVMContext C;
1582-
SMDiagnostic Err;
1583-
std::unique_ptr<Module> M = parseAssemblyString(
1584-
"define void @foo(i32 signext %len) { "
1585-
"entry: "
1586-
" %a = alloca [0 x i32], align 4 "
1587-
" %cmp4 = icmp sgt i32 %len, 0 "
1588-
" br i1 %cmp4, label %for.body.preheader, label %for.cond.cleanup "
1589-
"for.body.preheader: "
1590-
" br label %for.body "
1591-
"for.cond.cleanup.loopexit: "
1592-
" br label %for.cond.cleanup "
1593-
"for.cond.cleanup: "
1594-
" ret void "
1595-
"for.body: "
1596-
" %iv = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] "
1597-
" %idxprom = zext i32 %iv to i64 "
1598-
" %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* %a, i64 0, \
1599-
i64 %idxprom "
1600-
" store i32 0, i32* %arrayidx, align 4 "
1601-
" %inc = add nuw nsw i32 %iv, 1 "
1602-
" %cmp = icmp slt i32 %inc, %len "
1603-
" br i1 %cmp, label %for.body, label %for.cond.cleanup.loopexit "
1604-
"} ",
1605-
Err, C);
1606-
1607-
ASSERT_TRUE(M && "Could not parse module?");
1608-
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
1609-
1610-
runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1611-
auto *ScevIV = SE.getSCEV(getInstructionByName(F, "iv"));
1612-
const Loop *L = cast<SCEVAddRecExpr>(ScevIV)->getLoop();
1613-
1614-
const SCEV *ITC = SE.getConstantMaxTripCountFromArray(L);
1615-
EXPECT_FALSE(isa<SCEVCouldNotCompute>(ITC));
1616-
EXPECT_TRUE(isa<SCEVConstant>(ITC));
1617-
EXPECT_EQ(cast<SCEVConstant>(ITC)->getAPInt().getSExtValue(), 1);
1618-
});
1619-
}
1620-
1621-
TEST_F(ScalarEvolutionsTest, ComputeMaxTripCountFromExtremArray) {
1622-
LLVMContext C;
1623-
SMDiagnostic Err;
1624-
std::unique_ptr<Module> M = parseAssemblyString(
1625-
"define void @foo(i32 signext %len) { "
1626-
"entry: "
1627-
" %a = alloca [4294967295 x i1], align 4 "
1628-
" %cmp4 = icmp sgt i32 %len, 0 "
1629-
" br i1 %cmp4, label %for.body.preheader, label %for.cond.cleanup "
1630-
"for.body.preheader: "
1631-
" br label %for.body "
1632-
"for.cond.cleanup.loopexit: "
1633-
" br label %for.cond.cleanup "
1634-
"for.cond.cleanup: "
1635-
" ret void "
1636-
"for.body: "
1637-
" %iv = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] "
1638-
" %idxprom = zext i32 %iv to i64 "
1639-
" %arrayidx = getelementptr inbounds [4294967295 x i1], \
1640-
[4294967295 x i1]* %a, i64 0, i64 %idxprom "
1641-
" store i1 0, i1* %arrayidx, align 4 "
1642-
" %inc = add nuw nsw i32 %iv, 1 "
1643-
" %cmp = icmp slt i32 %inc, %len "
1644-
" br i1 %cmp, label %for.body, label %for.cond.cleanup.loopexit "
1645-
"} ",
1646-
Err, C);
1647-
1648-
ASSERT_TRUE(M && "Could not parse module?");
1649-
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
1650-
1651-
runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1652-
auto *ScevIV = SE.getSCEV(getInstructionByName(F, "iv"));
1653-
const Loop *L = cast<SCEVAddRecExpr>(ScevIV)->getLoop();
1654-
1655-
const SCEV *ITC = SE.getConstantMaxTripCountFromArray(L);
1656-
EXPECT_TRUE(isa<SCEVCouldNotCompute>(ITC));
1657-
});
1658-
}
1659-
1660-
TEST_F(ScalarEvolutionsTest, ComputeMaxTripCountFromArrayInBranch) {
1661-
LLVMContext C;
1662-
SMDiagnostic Err;
1663-
std::unique_ptr<Module> M = parseAssemblyString(
1664-
"define void @foo(i32 signext %len) { "
1665-
"entry: "
1666-
" %a = alloca [8 x i32], align 4 "
1667-
" br label %for.cond "
1668-
"for.cond: "
1669-
" %iv = phi i32 [ %inc, %for.inc ], [ 0, %entry ] "
1670-
" %cmp = icmp slt i32 %iv, %len "
1671-
" br i1 %cmp, label %for.body, label %for.cond.cleanup "
1672-
"for.cond.cleanup: "
1673-
" br label %for.end "
1674-
"for.body: "
1675-
" %cmp1 = icmp slt i32 %iv, 8 "
1676-
" br i1 %cmp1, label %if.then, label %if.end "
1677-
"if.then: "
1678-
" %idxprom = sext i32 %iv to i64 "
1679-
" %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %a, i64 0, \
1680-
i64 %idxprom "
1681-
" store i32 0, i32* %arrayidx, align 4 "
1682-
" br label %if.end "
1683-
"if.end: "
1684-
" br label %for.inc "
1685-
"for.inc: "
1686-
" %inc = add nsw i32 %iv, 1 "
1687-
" br label %for.cond "
1688-
"for.end: "
1689-
" ret void "
1690-
"} ",
1691-
Err, C);
1692-
1693-
ASSERT_TRUE(M && "Could not parse module?");
1694-
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
1695-
1696-
runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1697-
auto *ScevIV = SE.getSCEV(getInstructionByName(F, "iv"));
1698-
const Loop *L = cast<SCEVAddRecExpr>(ScevIV)->getLoop();
1699-
1700-
const SCEV *ITC = SE.getConstantMaxTripCountFromArray(L);
1701-
EXPECT_TRUE(isa<SCEVCouldNotCompute>(ITC));
1702-
});
1703-
}
1704-
1705-
TEST_F(ScalarEvolutionsTest, ComputeMaxTripCountFromMultiDemArray) {
1706-
LLVMContext C;
1707-
SMDiagnostic Err;
1708-
std::unique_ptr<Module> M = parseAssemblyString(
1709-
"define void @foo(i32 signext %len) { "
1710-
"entry: "
1711-
" %a = alloca [3 x [5 x i32]], align 4 "
1712-
" br label %for.cond "
1713-
"for.cond: "
1714-
" %iv = phi i32 [ %inc, %for.inc ], [ 0, %entry ] "
1715-
" %cmp = icmp slt i32 %iv, %len "
1716-
" br i1 %cmp, label %for.body, label %for.cond.cleanup "
1717-
"for.cond.cleanup: "
1718-
" br label %for.end "
1719-
"for.body: "
1720-
" %arrayidx = getelementptr inbounds [3 x [5 x i32]], \
1721-
[3 x [5 x i32]]* %a, i64 0, i64 3 "
1722-
" %idxprom = sext i32 %iv to i64 "
1723-
" %arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %arrayidx, \
1724-
i64 0, i64 %idxprom "
1725-
" store i32 0, i32* %arrayidx1, align 4"
1726-
" br label %for.inc "
1727-
"for.inc: "
1728-
" %inc = add nsw i32 %iv, 1 "
1729-
" br label %for.cond "
1730-
"for.end: "
1731-
" ret void "
1732-
"} ",
1733-
Err, C);
1734-
1735-
ASSERT_TRUE(M && "Could not parse module?");
1736-
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
1737-
1738-
runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
1739-
auto *ScevIV = SE.getSCEV(getInstructionByName(F, "iv"));
1740-
const Loop *L = cast<SCEVAddRecExpr>(ScevIV)->getLoop();
1741-
1742-
const SCEV *ITC = SE.getConstantMaxTripCountFromArray(L);
1743-
EXPECT_TRUE(isa<SCEVCouldNotCompute>(ITC));
1744-
});
1745-
}
1746-
17471539
TEST_F(ScalarEvolutionsTest, CheckGetPowerOfTwo) {
17481540
Module M("CheckGetPowerOfTwo", Context);
17491541
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), {}, false);

0 commit comments

Comments
 (0)