Skip to content

Commit f48414f

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 f48414f

File tree

2 files changed

+180
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)