Skip to content

Commit 04acd3e

Browse files
committed
Fix array bounds check optimization for ossa
While hoisting check_subscript call in ossa, isNativeTypeChecked call is also hoisted. The array value used in the isNativeTypeChecked may not be available if it's lifetime had ended before. Proactively set the array value of the isNativeTypeChecked call to the array value in the check_subscript call.
1 parent 8353a8c commit 04acd3e

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

lib/SILOptimizer/Analysis/ArraySemantic.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,10 @@ ApplyInst *swift::ArraySemanticsCall::hoistOrCopy(SILInstruction *InsertBefore,
496496
->begin());
497497
} else {
498498
NewArrayProps = IsNative.copyTo(InsertBefore, DT);
499+
ArraySemanticsCall NewIsNative(NewArrayProps);
500+
if (NewIsNative.getSelf() != HoistedSelf) {
501+
NewIsNative.getSelfOperand().set(HoistedSelf);
502+
}
499503
}
500504

501505
// Replace all uses of the check subscript call by a use of the empty

test/SILOptimizer/abcopts_ossa_guaranteed.sil

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,3 +1458,176 @@ bb3:
14581458
%r = tuple ()
14591459
return %r : $()
14601460
}
1461+
1462+
// CHECK-LABEL: sil [ossa] @isNativeUnavailable1 :
1463+
// CHECK: [[ISNATIVE:%.*]] = function_ref @arrayPropertyIsNative :
1464+
// CHECK: bb1:
1465+
// CHECK: [[CHECKBOUNDS:%.*]] = function_ref @checkbounds :
1466+
// CHECK: apply [[ISNATIVE]]
1467+
// CHECK: apply [[CHECKBOUNDS]]
1468+
// CHECK: bb2
1469+
// CHECK-LABEL: } // end sil function 'isNativeUnavailable1'
1470+
sil [ossa] @isNativeUnavailable1 : $@convention(thin) (Int32, @owned ArrayInt) -> Int32 {
1471+
bb0(%0 : $Int32, %1 : @owned $ArrayInt):
1472+
%2 = integer_literal $Builtin.Int1, -1
1473+
%3 = struct $Bool (%2)
1474+
%4 = struct_extract %0, #Int32._value
1475+
%5 = integer_literal $Builtin.Int32, 0
1476+
%6 = builtin "cmp_eq_Int32"(%5, %4) : $Builtin.Int1
1477+
%7 = begin_borrow %1
1478+
%8 = copy_value %7
1479+
%9 = function_ref @arrayPropertyIsNative : $@convention(method) (@guaranteed ArrayInt) -> Bool
1480+
%10 = apply %9(%7) : $@convention(method) (@guaranteed ArrayInt) -> Bool
1481+
end_borrow %7
1482+
cond_br %6, bb2, bb1
1483+
1484+
bb1:
1485+
br bb3(%5)
1486+
1487+
bb2:
1488+
destroy_value %8
1489+
destroy_value %1
1490+
br bb6(%5)
1491+
1492+
bb3(%17 : $Builtin.Int32):
1493+
%18 = struct $Int32 (%17)
1494+
%19 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @guaranteed ArrayInt) -> _DependenceToken
1495+
%20 = apply %19(%18, %10, %8) : $@convention(method) (Int32, Bool, @guaranteed ArrayInt) -> _DependenceToken
1496+
%21 = integer_literal $Builtin.Int32, 1
1497+
%22 = integer_literal $Builtin.Int1, -1
1498+
%23 = builtin "sadd_with_overflow_Int32"(%17, %21, %22) : $(Builtin.Int32, Builtin.Int1)
1499+
%24 = tuple_extract %23, 0
1500+
%25 = tuple_extract %23, 1
1501+
cond_fail %25, ""
1502+
%27 = builtin "cmp_eq_Int32"(%24, %4) : $Builtin.Int1
1503+
cond_br %27, bb5, bb4
1504+
1505+
bb4:
1506+
br bb3(%24)
1507+
1508+
bb5:
1509+
destroy_value %8
1510+
destroy_value %1
1511+
br bb6(%24)
1512+
1513+
bb6(%33 : $Builtin.Int32):
1514+
%34 = struct $Int32 (%33)
1515+
return %34
1516+
}
1517+
1518+
// CHECK-LABEL: sil [ossa] @isNativeUnavailable2 :
1519+
// CHECK: [[ISNATIVE:%.*]] = function_ref @arrayPropertyIsNative :
1520+
// CHECK: bb1:
1521+
// CHECK: [[CHECKBOUNDS:%.*]] = function_ref @checkbounds :
1522+
// CHECK: apply [[ISNATIVE]]
1523+
// CHECK: apply [[CHECKBOUNDS]]
1524+
// CHECK: bb2
1525+
// CHECK-LABEL: } // end sil function 'isNativeUnavailable2'
1526+
sil [ossa] @isNativeUnavailable2 : $@convention(thin) (Int32, @owned ArrayInt) -> Int32 {
1527+
bb0(%0 : $Int32, %1 : @owned $ArrayInt):
1528+
%2 = integer_literal $Builtin.Int1, -1
1529+
%3 = struct $Bool (%2)
1530+
%4 = struct_extract %0, #Int32._value
1531+
%5 = integer_literal $Builtin.Int32, 0
1532+
%6 = builtin "cmp_eq_Int32"(%5, %4) : $Builtin.Int1
1533+
%7 = copy_value %1
1534+
%8 = copy_value %7
1535+
%9 = function_ref @arrayPropertyIsNative : $@convention(method) (@guaranteed ArrayInt) -> Bool
1536+
%10 = apply %9(%7) : $@convention(method) (@guaranteed ArrayInt) -> Bool
1537+
destroy_value %7
1538+
cond_br %6, bb2, bb1
1539+
1540+
bb1:
1541+
br bb3(%5)
1542+
1543+
bb2:
1544+
destroy_value %8
1545+
destroy_value %1
1546+
br bb6(%5)
1547+
1548+
bb3(%17 : $Builtin.Int32):
1549+
%18 = struct $Int32 (%17)
1550+
%19 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @guaranteed ArrayInt) -> _DependenceToken
1551+
%20 = apply %19(%18, %10, %8) : $@convention(method) (Int32, Bool, @guaranteed ArrayInt) -> _DependenceToken
1552+
%21 = integer_literal $Builtin.Int32, 1
1553+
%22 = integer_literal $Builtin.Int1, -1
1554+
%23 = builtin "sadd_with_overflow_Int32"(%17, %21, %22) : $(Builtin.Int32, Builtin.Int1)
1555+
%24 = tuple_extract %23, 0
1556+
%25 = tuple_extract %23, 1
1557+
cond_fail %25, ""
1558+
%27 = builtin "cmp_eq_Int32"(%24, %4) : $Builtin.Int1
1559+
cond_br %27, bb5, bb4
1560+
1561+
bb4:
1562+
br bb3(%24)
1563+
1564+
bb5:
1565+
destroy_value %8
1566+
destroy_value %1
1567+
br bb6(%24)
1568+
1569+
bb6(%33 : $Builtin.Int32):
1570+
%34 = struct $Int32 (%33)
1571+
return %34
1572+
}
1573+
1574+
struct Wrapper {
1575+
let arr: ArrayInt
1576+
}
1577+
1578+
// CHECK-LABEL: sil [ossa] @isNativeUnavailable3 :
1579+
// CHECK: [[ISNATIVE:%.*]] = function_ref @arrayPropertyIsNative :
1580+
// CHECK: bb1:
1581+
// CHECK: [[CHECKBOUNDS:%.*]] = function_ref @checkbounds :
1582+
// CHECK: apply [[ISNATIVE]]
1583+
// CHECK: apply [[CHECKBOUNDS]]
1584+
// CHECK: bb2
1585+
// CHECK-LABEL: } // end sil function 'isNativeUnavailable3'
1586+
sil [ossa] @isNativeUnavailable3 : $@convention(thin) (Int32, @owned Wrapper) -> Int32 {
1587+
bb0(%0 : $Int32, %1 : @owned $Wrapper):
1588+
%2 = integer_literal $Builtin.Int1, -1
1589+
%3 = struct $Bool (%2)
1590+
%4 = struct_extract %0, #Int32._value
1591+
%5 = integer_literal $Builtin.Int32, 0
1592+
%6 = builtin "cmp_eq_Int32"(%5, %4) : $Builtin.Int1
1593+
%7 = begin_borrow %1
1594+
%7a = struct_extract %7, #Wrapper.arr
1595+
%8 = copy_value %7a
1596+
%9 = function_ref @arrayPropertyIsNative : $@convention(method) (@guaranteed ArrayInt) -> Bool
1597+
%10 = apply %9(%7a) : $@convention(method) (@guaranteed ArrayInt) -> Bool
1598+
end_borrow %7
1599+
cond_br %6, bb2, bb1
1600+
1601+
bb1:
1602+
br bb3(%5)
1603+
1604+
bb2:
1605+
destroy_value %8
1606+
destroy_value %1
1607+
br bb6(%5)
1608+
1609+
bb3(%17 : $Builtin.Int32):
1610+
%18 = struct $Int32 (%17)
1611+
%19 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @guaranteed ArrayInt) -> _DependenceToken
1612+
%20 = apply %19(%18, %10, %8) : $@convention(method) (Int32, Bool, @guaranteed ArrayInt) -> _DependenceToken
1613+
%21 = integer_literal $Builtin.Int32, 1
1614+
%22 = integer_literal $Builtin.Int1, -1
1615+
%23 = builtin "sadd_with_overflow_Int32"(%17, %21, %22) : $(Builtin.Int32, Builtin.Int1)
1616+
%24 = tuple_extract %23, 0
1617+
%25 = tuple_extract %23, 1
1618+
cond_fail %25, ""
1619+
%27 = builtin "cmp_eq_Int32"(%24, %4) : $Builtin.Int1
1620+
cond_br %27, bb5, bb4
1621+
1622+
bb4:
1623+
br bb3(%24)
1624+
1625+
bb5:
1626+
destroy_value %8
1627+
destroy_value %1
1628+
br bb6(%24)
1629+
1630+
bb6(%33 : $Builtin.Int32):
1631+
%34 = struct $Int32 (%33)
1632+
return %34
1633+
}

0 commit comments

Comments
 (0)