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