llvm.org GIT mirror llvm / 2e66afa
[Tests] Add tests for loop predication of loops w/ne latch conditions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362244 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 3 months ago
1 changed file(s) with 172 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
15941594 %result = phi i32 [ %loop.acc.next, %loop ]
15951595 ret i32 %result
15961596 }
1597
1598 ; NE Check (as produced by LFTR) where we can prove Start < End via simple
1599 ; instruction analysis
1600 define i32 @ne_latch_zext(i32* %array, i32 %length, i16 %n16) {
1601 ; CHECK-LABEL: @ne_latch_zext(
1602 ; CHECK-NEXT: loop.preheader:
1603 ; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i32
1604 ; CHECK-NEXT: br label [[LOOP:%.*]]
1605 ; CHECK: loop:
1606 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1607 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1608 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1609 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1610 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
1611 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1612 ; CHECK: exit:
1613 ; CHECK-NEXT: ret i32 0
1614 ;
1615 loop.preheader:
1616 %n = zext i16 %n16 to i32
1617 br label %loop
1618
1619 loop:
1620 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1621 %within.bounds = icmp ult i32 %i, %length
1622 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1623
1624 %i.next = add nuw i32 %i, 1
1625 %continue = icmp ne i32 %i.next, %n
1626 br i1 %continue, label %loop, label %exit
1627
1628 exit:
1629 ret i32 0
1630 }
1631
1632 ; NE Check (as produced by LFTR) where we can prove Start < End via the
1633 ; condition guarding the loop entry.
1634 define i32 @ne_latch_dom_check(i32* %array, i32 %length, i32 %n) {
1635 ; CHECK-LABEL: @ne_latch_dom_check(
1636 ; CHECK-NEXT: entry:
1637 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1638 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1639 ; CHECK: loop.preheader:
1640 ; CHECK-NEXT: br label [[LOOP:%.*]]
1641 ; CHECK: loop:
1642 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1643 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1644 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1645 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1646 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
1647 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1648 ; CHECK: exit.loopexit:
1649 ; CHECK-NEXT: br label [[EXIT]]
1650 ; CHECK: exit:
1651 ; CHECK-NEXT: ret i32 0
1652 ;
1653 entry:
1654 %tmp5 = icmp sle i32 %n, 0
1655 br i1 %tmp5, label %exit, label %loop.preheader
1656
1657 loop.preheader:
1658 br label %loop
1659
1660 loop:
1661 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1662 %within.bounds = icmp ult i32 %i, %length
1663 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1664
1665 %i.next = add nuw i32 %i, 1
1666 %continue = icmp ne i32 %i.next, %n
1667 br i1 %continue, label %loop, label %exit
1668
1669 exit:
1670 ret i32 0
1671 }
1672
1673 ; NE latch - can't prove (end-start) mod step == 0 (i.e. might wrap
1674 ; around several times or even be infinite)
1675 define i32 @neg_ne_latch_mod_step(i32* %array, i32 %length, i16 %n16) {
1676 ; CHECK-LABEL: @neg_ne_latch_mod_step(
1677 ; CHECK-NEXT: loop.preheader:
1678 ; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i32
1679 ; CHECK-NEXT: br label [[LOOP:%.*]]
1680 ; CHECK: loop:
1681 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1682 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1683 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1684 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 3
1685 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
1686 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1687 ; CHECK: exit:
1688 ; CHECK-NEXT: ret i32 0
1689 ;
1690 loop.preheader:
1691 %n = zext i16 %n16 to i32
1692 br label %loop
1693
1694 loop:
1695 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1696 %within.bounds = icmp ult i32 %i, %length
1697 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1698
1699 %i.next = add i32 %i, 3
1700 %continue = icmp ne i32 %i.next, %n
1701 br i1 %continue, label %loop, label %exit
1702
1703 exit:
1704 ret i32 0
1705 }
1706
1707 ; NE latch - TODO: could prove (end-start) mod step == 0
1708 define i32 @ne_latch_mod_step(i32* %array, i32 %length) {
1709 ; CHECK-LABEL: @ne_latch_mod_step(
1710 ; CHECK-NEXT: loop.preheader:
1711 ; CHECK-NEXT: br label [[LOOP:%.*]]
1712 ; CHECK: loop:
1713 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1714 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1715 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1716 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 2
1717 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], 400
1718 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1719 ; CHECK: exit:
1720 ; CHECK-NEXT: ret i32 0
1721 ;
1722 loop.preheader:
1723 br label %loop
1724
1725 loop:
1726 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1727 %within.bounds = icmp ult i32 %i, %length
1728 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1729
1730 %i.next = add nuw i32 %i, 2
1731 %continue = icmp ne i32 %i.next, 400
1732 br i1 %continue, label %loop, label %exit
1733
1734 exit:
1735 ret i32 0
1736 }
1737
1738 ; NE Latch - but end > start so wraps around and not equivelent to a ult
1739 define i32 @neg_ne_latch_swapped_order(i32* %array, i32 %length) {
1740 ; CHECK-LABEL: @neg_ne_latch_swapped_order(
1741 ; CHECK-NEXT: loop.preheader:
1742 ; CHECK-NEXT: br label [[LOOP:%.*]]
1743 ; CHECK: loop:
1744 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ]
1745 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1746 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1747 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
1748 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], 0
1749 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1750 ; CHECK: exit:
1751 ; CHECK-NEXT: ret i32 0
1752 ;
1753 loop.preheader:
1754 br label %loop
1755
1756 loop:
1757 %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ]
1758 %within.bounds = icmp ult i32 %i, %length
1759 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1760
1761 %i.next = add i32 %i, 1
1762 %continue = icmp ne i32 %i.next, 0
1763 br i1 %continue, label %loop, label %exit
1764
1765 exit:
1766 ret i32 0
1767 }
1768