mirror of
https://github.com/apple/swift.git
synced 2026-02-27 18:26:24 +01:00
edges into dead-end regions. - Only treat edges *into* dead-end regions as special; edges internal the region must use the normal rules. - Conservatively merge information along those edges rather than just picking one at random. This requires us to not walk into the region until we've processed all of the edges to it. - Make sure we prevent *any* stack allocations from being deallocated if the stack is inconsistent entering a block. Additionally, fix a bug which was incorrectly treating all blocks that don't themselves exit the function as ultimately leading to unreachable, which had inadvertently largely turned off the consistency check.
206 lines
8.1 KiB
Plaintext
206 lines
8.1 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -loop-invariant-code-motion | %FileCheck %s
|
|
// REQUIRES: PTRSIZE=64
|
|
// REQUIRES: OS=macosx
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
var x: Int
|
|
|
|
let reversedArray: ReversedCollection<[Int]>
|
|
|
|
// x
|
|
sil_global hidden @$s3tmp1xSivp : $Int
|
|
|
|
// reversedArray
|
|
sil_global hidden [let] @$s3tmp13reversedArrays18ReversedCollectionVySaySiGGvp : $ReversedCollection<Array<Int>>
|
|
|
|
// _swiftEmptyArrayStorage
|
|
sil_global @_swiftEmptyArrayStorage : $_SwiftEmptyArrayStorage
|
|
|
|
|
|
// CHECK-LABEL: sil hidden @multi_end_licm : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK: %10 = struct_element_addr %9 : $*Int, #Int._value
|
|
// CHECK: bb2:
|
|
// CHECK: load %10
|
|
// CHECK: bb3({{.*}} : $Builtin.Int64):
|
|
// CHECK: load
|
|
// CHECK-NOT: load
|
|
// CHECK-NOT: store
|
|
// CHECK: bb5:
|
|
// CHECK-NEXT: store
|
|
// CHECK-NOT: store
|
|
// CHECK: bb7:
|
|
// CHECK-NEXT: store
|
|
// CHECK-NOT: store
|
|
// CHECK: } // end sil function 'multi_end_licm'
|
|
sil hidden @multi_end_licm : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = global_addr @$s3tmp13reversedArrays18ReversedCollectionVySaySiGGvp : $*ReversedCollection<Array<Int>>
|
|
%1 = struct_element_addr %0 : $*ReversedCollection<Array<Int>>, #ReversedCollection._base
|
|
%2 = struct_element_addr %1 : $*Array<Int>, #Array._buffer
|
|
%3 = struct_element_addr %2 : $*_ArrayBuffer<Int>, #_ArrayBuffer._storage
|
|
%4 = struct_element_addr %3 : $*_BridgeStorage<__ContiguousArrayStorageBase>, #_BridgeStorage.rawValue
|
|
%5 = load %4 : $*Builtin.BridgeObject
|
|
%6 = unchecked_ref_cast %5 : $Builtin.BridgeObject to $__ContiguousArrayStorageBase
|
|
%7 = ref_element_addr %6 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity
|
|
%8 = struct_element_addr %7 : $*_ArrayBody, #_ArrayBody._storage
|
|
%9 = struct_element_addr %8 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count
|
|
%10 = struct_element_addr %9 : $*Int, #Int._value
|
|
%11 = load %10 : $*Builtin.Int64
|
|
%12 = builtin "assumeNonNegative_Int64"(%11 : $Builtin.Int64) : $Builtin.Int64
|
|
%13 = integer_literal $Builtin.Int64, 0
|
|
%14 = integer_literal $Builtin.Int1, 0
|
|
%15 = builtin "cmp_eq_Int64"(%12 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
|
|
%16 = builtin "int_expect_Int1"(%15 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
|
|
cond_br %16, bb1, bb2
|
|
|
|
bb1:
|
|
br bb12
|
|
|
|
bb2:
|
|
%19 = global_addr @$s3tmp1xSivp : $*Int
|
|
%20 = integer_literal $Builtin.Int64, 1
|
|
%21 = integer_literal $Builtin.Int1, -1
|
|
%23 = ref_tail_addr %6 : $__ContiguousArrayStorageBase, $Int
|
|
br bb4(%12 : $Builtin.Int64)
|
|
|
|
bb4(%27 : $Builtin.Int64):
|
|
%28 = builtin "ssub_with_overflow_Int64"(%27 : $Builtin.Int64, %20 : $Builtin.Int64, %21 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%29 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 0
|
|
%30 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %30 : $Builtin.Int1
|
|
%32 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
|
|
%33 = load %10 : $*Builtin.Int64
|
|
%34 = builtin "assumeNonNegative_Int64"(%33 : $Builtin.Int64) : $Builtin.Int64
|
|
%35 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %34 : $Builtin.Int64) : $Builtin.Int1
|
|
%36 = builtin "xor_Int1"(%35 : $Builtin.Int1, %21 : $Builtin.Int1) : $Builtin.Int1
|
|
%37 = builtin "or_Int1"(%32 : $Builtin.Int1, %36 : $Builtin.Int1) : $Builtin.Int1
|
|
cond_fail %37 : $Builtin.Int1
|
|
%39 = builtin "truncOrBitCast_Int64_Word"(%29 : $Builtin.Int64) : $Builtin.Word
|
|
%40 = index_addr %23 : $*Int, %39 : $Builtin.Word
|
|
%41 = struct_element_addr %40 : $*Int, #Int._value
|
|
%42 = load %41 : $*Builtin.Int64
|
|
%43 = struct $Int (%42 : $Builtin.Int64)
|
|
debug_value %43 : $Int, let, name "item"
|
|
%global = begin_access [modify] [dynamic] [no_nested_conflict] %19 : $*Int
|
|
%46 = builtin "cmp_eq_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
|
|
%47 = builtin "int_expect_Int1"(%46 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
|
|
cond_br %47, bb10, bb11
|
|
|
|
bb10:
|
|
store %43 to %global : $*Int
|
|
end_access %global : $*Int
|
|
cond_br %47, bb6, bb5
|
|
|
|
bb11:
|
|
%otherInt = struct $Int (%27 : $Builtin.Int64)
|
|
store %otherInt to %global : $*Int
|
|
end_access %global : $*Int
|
|
cond_br %47, bb6, bb5
|
|
|
|
bb5:
|
|
br bb4(%29 : $Builtin.Int64)
|
|
|
|
bb6:
|
|
br bb12
|
|
|
|
bb12:
|
|
%25 = tuple ()
|
|
return %25 : $()
|
|
} // end sil function 'multi_end_licm'
|
|
|
|
// CHECK-LABEL: sil hidden @multi_end_licm_loop_exit : $@convention(thin) () -> () {
|
|
// CHECK: bb2:
|
|
// CHECK: begin_access [modify] [dynamic] [no_nested_conflict]
|
|
// CHECK: br bb3
|
|
// CHECK: bb5:
|
|
// CHECK: end_access
|
|
// CHECK: bb6:
|
|
// CHECK: bb7:
|
|
// CHECK: end_access
|
|
// CHECK: bb8:
|
|
// CHECK: } // end sil function 'multi_end_licm_loop_exit'
|
|
sil hidden @multi_end_licm_loop_exit : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = global_addr @$s3tmp13reversedArrays18ReversedCollectionVySaySiGGvp : $*ReversedCollection<Array<Int>>
|
|
%1 = struct_element_addr %0 : $*ReversedCollection<Array<Int>>, #ReversedCollection._base
|
|
%2 = struct_element_addr %1 : $*Array<Int>, #Array._buffer
|
|
%3 = struct_element_addr %2 : $*_ArrayBuffer<Int>, #_ArrayBuffer._storage
|
|
%4 = struct_element_addr %3 : $*_BridgeStorage<__ContiguousArrayStorageBase>, #_BridgeStorage.rawValue
|
|
%5 = load %4 : $*Builtin.BridgeObject
|
|
%6 = unchecked_ref_cast %5 : $Builtin.BridgeObject to $__ContiguousArrayStorageBase
|
|
%7 = ref_element_addr %6 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity
|
|
%8 = struct_element_addr %7 : $*_ArrayBody, #_ArrayBody._storage
|
|
%9 = struct_element_addr %8 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count
|
|
%10 = struct_element_addr %9 : $*Int, #Int._value
|
|
%11 = load %10 : $*Builtin.Int64
|
|
%12 = builtin "assumeNonNegative_Int64"(%11 : $Builtin.Int64) : $Builtin.Int64
|
|
%13 = integer_literal $Builtin.Int64, 0
|
|
%14 = integer_literal $Builtin.Int1, 0
|
|
%15 = builtin "cmp_eq_Int64"(%12 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
|
|
%16 = builtin "int_expect_Int1"(%15 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
|
|
cond_br %16, bb1, bb2
|
|
|
|
bb1:
|
|
br bbRet
|
|
|
|
bb2:
|
|
%19 = global_addr @$s3tmp1xSivp : $*Int
|
|
%20 = integer_literal $Builtin.Int64, 1
|
|
%21 = integer_literal $Builtin.Int1, -1
|
|
%23 = ref_tail_addr %6 : $__ContiguousArrayStorageBase, $Int
|
|
br bb4(%12 : $Builtin.Int64)
|
|
|
|
bb4(%27 : $Builtin.Int64):
|
|
%28 = builtin "ssub_with_overflow_Int64"(%27 : $Builtin.Int64, %20 : $Builtin.Int64, %21 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%29 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 0
|
|
%30 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %30 : $Builtin.Int1
|
|
%32 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
|
|
%33 = load %10 : $*Builtin.Int64
|
|
%34 = builtin "assumeNonNegative_Int64"(%33 : $Builtin.Int64) : $Builtin.Int64
|
|
%35 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %34 : $Builtin.Int64) : $Builtin.Int1
|
|
%36 = builtin "xor_Int1"(%35 : $Builtin.Int1, %21 : $Builtin.Int1) : $Builtin.Int1
|
|
%37 = builtin "or_Int1"(%32 : $Builtin.Int1, %36 : $Builtin.Int1) : $Builtin.Int1
|
|
cond_fail %37 : $Builtin.Int1
|
|
%39 = builtin "truncOrBitCast_Int64_Word"(%29 : $Builtin.Int64) : $Builtin.Word
|
|
%40 = index_addr %23 : $*Int, %39 : $Builtin.Word
|
|
%41 = struct_element_addr %40 : $*Int, #Int._value
|
|
%42 = load %41 : $*Builtin.Int64
|
|
%43 = struct $Int (%42 : $Builtin.Int64)
|
|
debug_value %43 : $Int, let, name "item"
|
|
%global = begin_access [modify] [dynamic] [no_nested_conflict] %19 : $*Int
|
|
%46 = builtin "cmp_eq_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
|
|
%47 = builtin "int_expect_Int1"(%46 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
|
|
cond_br %47, bbend1, bbend2
|
|
|
|
bbend1:
|
|
store %43 to %global : $*Int
|
|
end_access %global : $*Int
|
|
cond_br %47, bb6, bb5
|
|
|
|
bbend2:
|
|
%otherInt = struct $Int (%27 : $Builtin.Int64)
|
|
store %otherInt to %global : $*Int
|
|
end_access %global : $*Int
|
|
cond_br %47, bbOut, bb5
|
|
|
|
bbOut:
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb4(%29 : $Builtin.Int64)
|
|
|
|
bb6:
|
|
br bbRet
|
|
|
|
bbRet:
|
|
%25 = tuple ()
|
|
return %25 : $()
|
|
} // end sil function 'multi_end_licm_loop_exit'
|