@@ -1604,24 +1604,141 @@ func.func @func_execute_region_inline_multi_yield() {
16041604
16051605// -----
16061606
1607- // CHECK-LABEL: func.func private @canonicalize_execute_region_yeilding_external_value(
1608- // CHECK-SAME: %[[VAL_0:.*]]: tensor<1x120xui8>) -> tensor<1x60xui8> {
1609- // CHECK: %[[VAL_1:.*]] = memref.alloc() {alignment = 64 : i64} : memref<1x60xui8>
1607+ // Test case with single scf.yield op inside execute_region and its operand is defined outside the execute_region op.
1608+ // Make scf.execute_region not to return anything.
1609+
16101610// CHECK: scf.execute_region no_inline {
16111611// CHECK: scf.yield
16121612// CHECK: }
1613- // CHECK: %[[VAL_2:.*]] = bufferization.to_tensor %[[VAL_1]] : memref<1x60xui8> to tensor<1x60xui8>
1614- // CHECK: return %[[VAL_2]] : tensor<1x60xui8>
1615- // CHECK: }
16161613
1617- func.func private @canonicalize_execute_region_yeilding_external_value (%arg0: tensor <1 x120 xui8 >) -> tensor <1 x60 xui8 > {
1618- %alloc = memref.alloc () {alignment = 64 : i64 } : memref <1 x60 xui8 >
1619- %0 = bufferization.to_tensor %alloc : memref <1 x60 xui8 > to tensor <1 x60 xui8 >
1620- %1 = scf.execute_region -> memref <1 x60 xui8 > no_inline {
1621- scf.yield %alloc : memref <1 x60 xui8 >
1614+ module {
1615+ func.func private @foo ()->()
1616+ func.func private @execute_region_yeilding_external_value () -> memref <1 x60 xui8 > {
1617+ %alloc = memref.alloc () {alignment = 64 : i64 } : memref <1 x60 xui8 >
1618+ %1 = scf.execute_region -> memref <1 x60 xui8 > no_inline {
1619+ func.call @foo ():()->()
1620+ scf.yield %alloc: memref <1 x60 xui8 >
1621+ }
1622+ return %1 : memref <1 x60 xui8 >
1623+ }
1624+ }
1625+
1626+ // -----
1627+
1628+ // Test case with scf.yield op inside execute_region with multiple operands.
1629+ // One of operands is defined outside the execute_region op.
1630+ // In this case scf.execute_region doesn't change.
1631+
1632+ // CHECK: %[[VAL_1:.*]]:2 = scf.execute_region -> (memref<1x60xui8>, memref<1x120xui8>) no_inline {
1633+ // CHECK: scf.yield %{{.*}}, %{{.*}} : memref<1x60xui8>, memref<1x120xui8>
1634+
1635+ module {
1636+ func.func private @foo ()->()
1637+ func.func private @execute_region_yeilding_external_and_local_values () -> (memref <1 x60 xui8 >, memref <1 x120 xui8 >) {
1638+ %alloc = memref.alloc () {alignment = 64 : i64 } : memref <1 x60 xui8 >
1639+ %1 , %2 = scf.execute_region -> (memref <1 x60 xui8 >, memref <1 x120 xui8 >) no_inline {
1640+ %alloc_1 = memref.alloc () {alignment = 64 : i64 } : memref <1 x120 xui8 >
1641+ func.call @foo ():()->()
1642+ scf.yield %alloc , %alloc_1: memref <1 x60 xui8 >, memref <1 x120 xui8 >
1643+ }
1644+ return %1 , %2 : memref <1 x60 xui8 >, memref <1 x120 xui8 >
1645+ }
1646+ }
1647+
1648+ // -----
1649+
1650+ // Test case with multiple scf.yield ops inside execute_region with same operands and those operands are defined outside the execute_region op..
1651+ // Make scf.execute_region not to return anything.
1652+ // scf.yield must remain, cause scf.execute_region can't be empty.
1653+
1654+ // CHECK: scf.execute_region no_inline {
1655+ // CHECK: %[[VAL_3:.*]] = "test.cmp"() : () -> i1
1656+ // CHECK: cf.cond_br %[[VAL_3]], ^bb1, ^bb2
1657+ // CHECK: ^bb1:
1658+ // CHECK: scf.yield
1659+ // CHECK: ^bb2:
1660+ // CHECK: scf.yield
1661+ // CHECK: }
1662+
1663+ module {
1664+ func.func private @foo ()->()
1665+ func.func private @execute_region_multiple_yields_same_operands () -> (memref <1 x60 xui8 >, memref <1 x120 xui8 >) {
1666+ %alloc = memref.alloc () {alignment = 64 : i64 } : memref <1 x60 xui8 >
1667+ %alloc_1 = memref.alloc () {alignment = 64 : i64 } : memref <1 x120 xui8 >
1668+ %1 , %2 = scf.execute_region -> (memref <1 x60 xui8 >, memref <1 x120 xui8 >) no_inline {
1669+ %c = " test.cmp" () : () -> i1
1670+ cf.cond_br %c , ^bb2 , ^bb3
1671+ ^bb2 :
1672+ func.call @foo ():()->()
1673+ scf.yield %alloc , %alloc_1 : memref <1 x60 xui8 >, memref <1 x120 xui8 >
1674+ ^bb3 :
1675+ func.call @foo ():()->()
1676+ scf.yield %alloc , %alloc_1 : memref <1 x60 xui8 >, memref <1 x120 xui8 >
1677+ }
1678+ return %1 , %2 : memref <1 x60 xui8 >, memref <1 x120 xui8 >
16221679 }
1623- %2 = bufferization.to_tensor %1 : memref <1 x60 xui8 > to tensor <1 x60 xui8 >
1624- return %2 : tensor <1 x60 xui8 >
1680+ }
1681+
1682+ // -----
1683+
1684+ // Test case with multiple scf.yield ops with at least one different operand, then no change.
1685+
1686+ // CHECK: %[[VAL_3:.*]]:2 = scf.execute_region -> (memref<1x60xui8>, memref<1x120xui8>) no_inline {
1687+ // CHECK: ^bb1:
1688+ // CHECK: scf.yield %{{.*}}, %{{.*}} : memref<1x60xui8>, memref<1x120xui8>
1689+ // CHECK: ^bb2:
1690+ // CHECK: scf.yield %{{.*}}, %{{.*}} : memref<1x60xui8>, memref<1x120xui8>
1691+ // CHECK: }
1692+
1693+ module {
1694+ func.func private @foo ()->()
1695+ func.func private @execute_region_multiple_yields_different_operands () -> (memref <1 x60 xui8 >, memref <1 x120 xui8 >) {
1696+ %alloc = memref.alloc () {alignment = 64 : i64 } : memref <1 x60 xui8 >
1697+ %alloc_1 = memref.alloc () {alignment = 64 : i64 } : memref <1 x120 xui8 >
1698+ %alloc_2 = memref.alloc () {alignment = 64 : i64 } : memref <1 x120 xui8 >
1699+ %1 , %2 = scf.execute_region -> (memref <1 x60 xui8 >, memref <1 x120 xui8 >) no_inline {
1700+ %c = " test.cmp" () : () -> i1
1701+ cf.cond_br %c , ^bb2 , ^bb3
1702+ ^bb2 :
1703+ func.call @foo ():()->()
1704+ scf.yield %alloc , %alloc_1 : memref <1 x60 xui8 >, memref <1 x120 xui8 >
1705+ ^bb3 :
1706+ func.call @foo ():()->()
1707+ scf.yield %alloc , %alloc_2 : memref <1 x60 xui8 >, memref <1 x120 xui8 >
1708+ }
1709+ return %1 , %2 : memref <1 x60 xui8 >, memref <1 x120 xui8 >
1710+ }
1711+ }
1712+
1713+ // -----
1714+
1715+ // Test case with multiple scf.yield ops each has different operand.
1716+ // In this case scf.execute_region isn't changed.
1717+
1718+ // CHECK: %[[VAL_2:.*]] = scf.execute_region -> memref<1x60xui8> no_inline {
1719+ // CHECK: ^bb1:
1720+ // CHECK: scf.yield %{{.*}} : memref<1x60xui8>
1721+ // CHECK: ^bb2:
1722+ // CHECK: scf.yield %{{.*}} : memref<1x60xui8>
1723+ // CHECK: }
1724+
1725+ module {
1726+ func.func private @foo ()->()
1727+ func.func private @execute_region_multiple_yields_different_operands () -> (memref <1 x60 xui8 >) {
1728+ %alloc = memref.alloc () {alignment = 64 : i64 } : memref <1 x60 xui8 >
1729+ %alloc_1 = memref.alloc () {alignment = 64 : i64 } : memref <1 x60 xui8 >
1730+ %1 = scf.execute_region -> (memref <1 x60 xui8 >) no_inline {
1731+ %c = " test.cmp" () : () -> i1
1732+ cf.cond_br %c , ^bb2 , ^bb3
1733+ ^bb2 :
1734+ func.call @foo ():()->()
1735+ scf.yield %alloc : memref <1 x60 xui8 >
1736+ ^bb3 :
1737+ func.call @foo ():()->()
1738+ scf.yield %alloc_1 : memref <1 x60 xui8 >
1739+ }
1740+ return %1 : memref <1 x60 xui8 >
1741+ }
16251742}
16261743
16271744// -----
0 commit comments