Files
swift-mirror/test/SILOptimizer/simplify_load.sil
Erik Eckstein 736d8d5e9c SimplifyLoad: fix removal of load operand instructions
Also consider that the (transitive) operand of a load can be a multi-value instruction, like begin_cow_mutation

rdar://140778782
2024-12-02 19:38:53 +01:00

546 lines
21 KiB
Plaintext

// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -onone-simplification -simplify-instruction=load | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ONONE
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -simplification -simplify-instruction=load | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-O
// REQUIRES: swift_in_compiler
import Swift
import Builtin
struct Str {
@_hasStorage let x: Int64
@_hasStorage let y: (Int64, Int64)
}
sil_global [let] @gstr : $Str = {
%0 = integer_literal $Builtin.Int64, 10
%1 = struct $Int64 (%0 : $Builtin.Int64)
%2 = integer_literal $Builtin.Int64, 27
%3 = struct $Int64 (%2 : $Builtin.Int64)
%4 = tuple (%1 : $Int64, %3 : $Int64)
%initval = struct $Str (%1 : $Int64, %4 : $(Int64, Int64))
}
class B { }
class E : B { }
class C {
@_hasStorage var c: Builtin.Int64
}
class D : C {
@_hasStorage var d: Builtin.Int64
}
sil_global hidden [let] @gb : $B
sil_global hidden [let] @gb2 : $(B, Int64)
sil_global private @gb_obj : $B = {
%initval = object $B ()
}
sil_global [let] @gc : $D = {
%0 = integer_literal $Builtin.Int64, 0
%1 = integer_literal $Builtin.Int64, 1
%2 = integer_literal $Builtin.Int64, 2
%3 = integer_literal $Builtin.Int64, 3
%initval = object $D (%0, %1, [tail_elems] %2, %3)
}
sil_global @gc_var : $D = {
%0 = integer_literal $Builtin.Int64, 0
%1 = integer_literal $Builtin.Int64, 1
%2 = integer_literal $Builtin.Int64, 2
%3 = integer_literal $Builtin.Int64, 3
%initval = object $D (%0, %1, [tail_elems] %2, %3)
}
sil [global_init_once_fn] @init_gb : $@convention(c) () -> () {
bb0:
alloc_global @gb
%1 = global_addr @gb : $*B
%2 = global_value @gb_obj : $B
store %2 to %1 : $*B
%6 = tuple ()
return %6 : $()
}
sil [global_init_once_fn] @init_gb2 : $@convention(c) () -> () {
bb0:
alloc_global @gb2
%1 = global_addr @gb2 : $*(B, Int64)
%2 = global_value @gb_obj : $B
%3 = integer_literal $Builtin.Int64, 10
%4 = struct $Int64 (%3 : $Builtin.Int64)
%5 = tuple (%2 : $B, %4 : $Int64)
store %5 to %1 : $*(B, Int64)
%6 = tuple ()
return %6 : $()
}
sil [global_init] @gstr_addressor : $@convention(thin) () -> Builtin.RawPointer {
bb0:
%0 = global_addr @gstr : $*Str
%1 = address_to_pointer %0 : $*Str to $Builtin.RawPointer
return %1 : $Builtin.RawPointer
}
sil_global private @global_char : $Int8
sil_global private [let] @global_pointer : $UnsafeRawPointer
// CHECK-LABEL: sil @load_global_simple
// CHECK-DAG: [[L27:%.*]] = integer_literal $Builtin.Int64, 27
// CHECK-DAG: [[I27:%.*]] = struct $Int64 ([[L27]] : $Builtin.Int64)
// CHECK-DAG: [[L10:%.*]] = integer_literal $Builtin.Int64, 10
// CHECK-DAG: [[I10:%.*]] = struct $Int64 ([[L10]] : $Builtin.Int64)
// CHECK-DAG: [[T:%.*]] = tuple ([[I10]] : $Int64, [[I27]] : $Int64)
// CHECK: [[STR:%.*]] = struct $Str ([[I10]] : $Int64, [[T]] : $(Int64, Int64))
// CHECK: return [[STR]]
// CHECK: } // end sil function 'load_global_simple'
sil @load_global_simple : $@convention(thin) () -> Str {
bb0:
%0 = global_addr @gstr : $*Str
%1 = begin_access [read] [static] %0 : $*Str
%2 = load %1 : $*Str
end_access %1 : $*Str
return %2 : $Str
}
// CHECK-LABEL: sil @load_global_via_addressor
// CHECK-NOT: apply
// CHECK-DAG: [[L27:%.*]] = integer_literal $Builtin.Int64, 27
// CHECK-DAG: [[I27:%.*]] = struct $Int64 ([[L27]] : $Builtin.Int64)
// CHECK-DAG: [[L10:%.*]] = integer_literal $Builtin.Int64, 10
// CHECK-DAG: [[I10:%.*]] = struct $Int64 ([[L10]] : $Builtin.Int64)
// CHECK-DAG: [[T:%.*]] = tuple ([[I10]] : $Int64, [[I27]] : $Int64)
// CHECK: [[STR:%.*]] = struct $Str ([[I10]] : $Int64, [[T]] : $(Int64, Int64))
// CHECK: return [[STR]]
// CHECK: } // end sil function 'load_global_via_addressor'
sil @load_global_via_addressor : $@convention(thin) () -> Str {
bb0:
%0 = function_ref @gstr_addressor : $@convention(thin) () -> Builtin.RawPointer
%1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
%2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Str
%3 = load %2 : $*Str
return %3 : $Str
}
// CHECK-LABEL: sil @load_global_struct_element
// CHECK-NOT: global_addr
// CHECK-DAG: [[L10:%.*]] = integer_literal $Builtin.Int64, 10
// CHECK-DAG: [[I10:%.*]] = struct $Int64 ([[L10]] : $Builtin.Int64)
// CHECK: return [[I10]]
// CHECK: } // end sil function 'load_global_struct_element'
sil @load_global_struct_element : $@convention(thin) () -> Int64 {
bb0:
%0 = global_addr @gstr : $*Str
%1 = struct_element_addr %0 : $*Str, #Str.x
%2 = load %1 : $*Int64
return %2 : $Int64
}
// CHECK-LABEL: sil @load_global_struct_tuple
// CHECK-NOT: global_addr
// CHECK-DAG: [[L27:%.*]] = integer_literal $Builtin.Int64, 27
// CHECK-DAG: [[I27:%.*]] = struct $Int64 ([[L27]] : $Builtin.Int64)
// CHECK: return [[I27]]
// CHECK: } // end sil function 'load_global_struct_tuple'
sil @load_global_struct_tuple : $@convention(thin) () -> Int64 {
bb0:
%0 = global_addr @gstr : $*Str
%1 = struct_element_addr %0 : $*Str, #Str.y
%2 = tuple_element_addr %1 : $*(Int64, Int64), 1
%3 = load %2 : $*Int64
return %3 : $Int64
}
// CHECK-LABEL: sil @load_global_object :
// CHECK: %1 = global_value @gb_obj
// CHECK-NEXT: return %1
// CHECK: } // end sil function 'load_global_object'
sil @load_global_object : $@convention(thin) (Builtin.RawPointer) -> @owned B {
bb0(%0 : $Builtin.RawPointer):
%1 = function_ref @init_gb : $@convention(c) () -> ()
%2 = builtin "once"(%0 : $Builtin.RawPointer, %1 : $@convention(c) () -> ()) : $Builtin.SILToken
%3 = global_addr @gb : $*B depends_on %2
%4 = load %3 : $*B
return %4 : $B
}
// CHECK-LABEL: sil @load_global_object_keep_once :
// CHECK: %2 = builtin "once"
// CHECK: %3 = global_value @gb_obj
// CHECK: fix_lifetime
// CHECK: return %3
// CHECK: } // end sil function 'load_global_object_keep_once'
sil @load_global_object_keep_once : $@convention(thin) (Builtin.RawPointer) -> @owned B {
bb0(%0 : $Builtin.RawPointer):
%1 = function_ref @init_gb : $@convention(c) () -> ()
%2 = builtin "once"(%0 : $Builtin.RawPointer, %1 : $@convention(c) () -> ()) : $Builtin.SILToken
%3 = global_addr @gb : $*B depends_on %2
%4 = load %3 : $*B
%5 = global_addr @gb : $*B depends_on %2
fix_lifetime %5 : $*B
return %4 : $B
}
// CHECK-LABEL: sil @load_global_object_from_tuple :
// CHECK: %1 = global_value @gb_obj
// CHECK-NEXT: return %1
// CHECK: } // end sil function 'load_global_object_from_tuple'
sil @load_global_object_from_tuple : $@convention(thin) (Builtin.RawPointer) -> @owned B {
bb0(%0 : $Builtin.RawPointer):
%1 = function_ref @init_gb2 : $@convention(c) () -> ()
%2 = builtin "once"(%0 : $Builtin.RawPointer, %1 : $@convention(c) () -> ()) : $Builtin.SILToken
%3 = global_addr @gb2 : $*(B, Int64) depends_on %2
%4 = tuple_element_addr %3 : $*(B, Int64), 0
%5 = load %4 : $*B
return %5 : $B
}
// CHECK-LABEL: sil @load_global_tuple :
// CHECK: %1 = global_value @gb_obj
// CHECK: [[T:%.*]] = tuple (%1 : $B, {{%.*}} : $Int64)
// CHECK-NEXT: return [[T]]
// CHECK: } // end sil function 'load_global_tuple'
sil @load_global_tuple : $@convention(thin) (Builtin.RawPointer) -> @owned (B, Int64) {
bb0(%0 : $Builtin.RawPointer):
%1 = function_ref @init_gb2 : $@convention(c) () -> ()
%2 = builtin "once"(%0 : $Builtin.RawPointer, %1 : $@convention(c) () -> ()) : $Builtin.SILToken
%3 = global_addr @gb2 : $*(B, Int64) depends_on %2
%4 = load %3 : $*(B, Int64)
return %4 : $(B, Int64)
}
sil private [global_init_once_fn] @init_global_pointer : $@convention(c) (Builtin.RawPointer) -> () {
bb0(%0 : $Builtin.RawPointer):
alloc_global @global_pointer
%2 = global_addr @global_pointer : $*UnsafeRawPointer
%3 = global_addr @global_char : $*Int8
%4 = begin_access [modify] [dynamic] %3 : $*Int8
%5 = address_to_pointer %4 : $*Int8 to $Builtin.RawPointer
%6 = struct $UnsafeRawPointer (%5 : $Builtin.RawPointer)
end_access %4 : $*Int8
store %6 to %2 : $*UnsafeRawPointer
%9 = tuple ()
return %9 : $()
}
// CHECK-LABEL: sil @load_global_pointer :
// CHECK: %1 = global_addr @global_char
// CHECK-NEXT: %2 = address_to_pointer %1 : $*Int8 to $Builtin.RawPointer
// CHECK-NEXT: %3 = struct $UnsafeRawPointer (%2 : $Builtin.RawPointer)
// CHECK-NEXT: return %3
// CHECK: } // end sil function 'load_global_pointer'
sil @load_global_pointer : $@convention(thin) (Builtin.RawPointer) -> UnsafeRawPointer {
bb0(%0 : $Builtin.RawPointer):
%2 = function_ref @init_global_pointer : $@convention(c) (Builtin.RawPointer) -> ()
%3 = builtin "once"(%0 : $Builtin.RawPointer, %2 : $@convention(c) (Builtin.RawPointer) -> ()) : $Builtin.SILToken
%4 = global_addr @global_pointer : $*UnsafeRawPointer depends_on %3
%5 = load %4 : $*UnsafeRawPointer
return %5 : $UnsafeRawPointer
}
// CHECK-LABEL: sil @load_first_char_from_string_literal
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int8, 97
// CHECK-NEXT: return %0
// CHECK: } // end sil function 'load_first_char_from_string_literal'
sil @load_first_char_from_string_literal : $@convention(thin) () -> Builtin.Int8 {
bb0:
%0 = string_literal utf8 "abc123a"
%1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*UInt8
%2 = struct_element_addr %1 : $*UInt8, #UInt8._value
%3 = load %2 : $*Builtin.Int8
return %3 : $Builtin.Int8
}
// CHECK-LABEL: sil @load_from_string_literal
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int8, 49
// CHECK-NEXT: return %0
// CHECK: } // end sil function 'load_from_string_literal'
sil @load_from_string_literal : $@convention(thin) () -> Builtin.Int8 {
bb0:
%0 = string_literal utf8 "abc123a"
%1 = integer_literal $Builtin.Word, 3
%2 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*UInt8
%3 = index_addr %2 : $*UInt8, %1 : $Builtin.Word
%4 = struct_element_addr %3 : $*UInt8, #UInt8._value
%5 = load %4 : $*Builtin.Int8
return %5 : $Builtin.Int8
}
// CHECK-LABEL: sil @load_addrcast_to_upcast :
// CHECK: bb0(%0 : $*E):
// CHECK-NEXT: %1 = load %0
// CHECK-NEXT: %2 = upcast %1 : $E to $B
// CHECK-NEXT: return %2
// CHECK: } // end sil function 'load_addrcast_to_upcast'
sil @load_addrcast_to_upcast : $@convention(thin) (@inout E) -> B {
bb0(%0 : $*E):
%1 = unchecked_addr_cast %0 : $*E to $*B
%2 = load %1 : $*B
return %2 : $B
}
struct _SwiftEmptyArrayStorage {
}
class __EmptyArrayStorage {
}
class __ContiguousArrayStorageBase : __EmptyArrayStorage {
@_hasStorage let countAndCapacity: _ArrayBody
}
struct _ArrayBody {
@_hasStorage let _storage: _SwiftArrayBodyStorage
}
struct _SwiftArrayBodyStorage {
@_hasStorage let count: Int64
@_hasStorage let _capacityAndFlags: Int64
}
struct _SwiftEmptySetSingleton {
}
class __EmptySetSingleton {
}
class __RawSetStorage : __EmptySetSingleton {
@_hasStorage let _count: Int64
@_hasStorage let _capacity: Int64
}
struct _SwiftEmptyDictionarySingleton {
}
class __EmptyDictionarySingleton {
}
class __RawDictionaryStorage : __EmptyDictionarySingleton {
@_hasStorage let _count: Int64
@_hasStorage let _capacity: Int64
}
sil_global @_swiftEmptyArrayStorage : $_SwiftEmptyArrayStorage
sil_global @_swiftEmptySetSingleton : $_SwiftEmptySetSingleton
sil_global @_swiftEmptyDictionarySingleton : $_SwiftEmptyDictionarySingleton
// CHECK-LABEL: sil @load_count_from_empty_array :
// CHECK: %0 = integer_literal $Builtin.Int64, 0
// CHECK-NEXT: %1 = struct $Int64 (%0 : $Builtin.Int64)
// CHECK-NEXT: return %1
// CHECK: } // end sil function 'load_count_from_empty_array'
sil @load_count_from_empty_array : $@convention(thin) () -> Int64 {
bb0:
%3 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage
%4 = address_to_pointer [stack_protection] %3 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer
%5 = raw_pointer_to_ref %4 : $Builtin.RawPointer to $__EmptyArrayStorage
%6 = unchecked_ref_cast %5 : $__EmptyArrayStorage to $__ContiguousArrayStorageBase
%8 = ref_element_addr [immutable] %6 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity
%9 = struct_element_addr %8 : $*_ArrayBody, #_ArrayBody._storage
%10 = struct_element_addr %9 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count
%11 = struct_element_addr %10 : $*Int64, #Int64._value
%12 = load %11 : $*Builtin.Int64
%15 = struct $Int64 (%12 : $Builtin.Int64)
return %15 : $Int64
}
// CHECK-LABEL: sil @load_capacity_from_empty_array :
// CHECK: %0 = integer_literal $Builtin.Int64, 0
// CHECK-NEXT: %1 = integer_literal $Builtin.Int64, 1
// CHECK-NEXT: %2 = builtin "lshr_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64)
// CHECK-NEXT: %3 = struct $Int64 (%2 : $Builtin.Int64)
// CHECK-NEXT: return %3
// CHECK: } // end sil function 'load_capacity_from_empty_array'
sil @load_capacity_from_empty_array : $@convention(thin) () -> Int64 {
bb0:
%3 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage
%4 = address_to_pointer [stack_protection] %3 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer
%5 = raw_pointer_to_ref %4 : $Builtin.RawPointer to $__EmptyArrayStorage
%6 = unchecked_ref_cast %5 : $__EmptyArrayStorage to $__ContiguousArrayStorageBase
%8 = ref_element_addr [immutable] %6 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity
%9 = struct_element_addr %8 : $*_ArrayBody, #_ArrayBody._storage
%10 = struct_element_addr %9 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage._capacityAndFlags
%11 = struct_element_addr %10 : $*Int64, #Int64._value
%12 = load %11 : $*Builtin.Int64
%13 = integer_literal $Builtin.Int64, 1
%14 = builtin "lshr_Int64"(%12 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int64
%15 = struct $Int64 (%14 : $Builtin.Int64)
return %15 : $Int64
}
// CHECK-LABEL: sil @dont_load_capacity_and_flags_from_empty_array :
// CHECK: [[X:%.*]] = load
// CHECK: [[I:%.*]] = struct $Int64 ([[X]]
// CHECK: return [[I]]
// CHECK: } // end sil function 'dont_load_capacity_and_flags_from_empty_array'
sil @dont_load_capacity_and_flags_from_empty_array : $@convention(thin) () -> Int64 {
bb0:
%3 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage
%4 = address_to_pointer [stack_protection] %3 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer
%5 = raw_pointer_to_ref %4 : $Builtin.RawPointer to $__EmptyArrayStorage
%6 = unchecked_ref_cast %5 : $__EmptyArrayStorage to $__ContiguousArrayStorageBase
%8 = ref_element_addr [immutable] %6 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity
%9 = struct_element_addr %8 : $*_ArrayBody, #_ArrayBody._storage
%10 = struct_element_addr %9 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage._capacityAndFlags
%11 = struct_element_addr %10 : $*Int64, #Int64._value
%12 = load %11 : $*Builtin.Int64
%15 = struct $Int64 (%12 : $Builtin.Int64)
return %15 : $Int64
}
// CHECK-LABEL: sil @load_count_from_empty_set :
// CHECK: %0 = integer_literal $Builtin.Int64, 0
// CHECK-NEXT: %1 = struct $Int64 (%0 : $Builtin.Int64)
// CHECK-NEXT: return %1
// CHECK: } // end sil function 'load_count_from_empty_set'
sil @load_count_from_empty_set : $@convention(thin) () -> Int64 {
bb0:
%0 = global_addr @_swiftEmptySetSingleton : $*_SwiftEmptySetSingleton
%1 = address_to_pointer [stack_protection] %0 : $*_SwiftEmptySetSingleton to $Builtin.RawPointer
%2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $__EmptySetSingleton
%3 = unchecked_ref_cast %2 : $__EmptySetSingleton to $__RawSetStorage
%5 = ref_element_addr %3 : $__RawSetStorage, #__RawSetStorage._count
%6 = struct_element_addr %5 : $*Int64, #Int64._value
%7 = load %6 : $*Builtin.Int64
%9 = struct $Int64 (%7 : $Builtin.Int64)
return %9 : $Int64
}
// CHECK-LABEL: sil @load_capacity_from_empty_set :
// CHECK: %0 = integer_literal $Builtin.Int64, 0
// CHECK-NEXT: %1 = struct $Int64 (%0 : $Builtin.Int64)
// CHECK-NEXT: return %1
// CHECK: } // end sil function 'load_capacity_from_empty_set'
sil @load_capacity_from_empty_set : $@convention(thin) () -> Int64 {
bb0:
%0 = global_addr @_swiftEmptySetSingleton : $*_SwiftEmptySetSingleton
%1 = address_to_pointer [stack_protection] %0 : $*_SwiftEmptySetSingleton to $Builtin.RawPointer
%2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $__EmptySetSingleton
%3 = unchecked_ref_cast %2 : $__EmptySetSingleton to $__RawSetStorage
%5 = ref_element_addr %3 : $__RawSetStorage, #__RawSetStorage._capacity
%6 = struct_element_addr %5 : $*Int64, #Int64._value
%7 = load %6 : $*Builtin.Int64
%9 = struct $Int64 (%7 : $Builtin.Int64)
return %9 : $Int64
}
// CHECK-LABEL: sil @load_count_from_empty_dictionary :
// CHECK: %0 = integer_literal $Builtin.Int64, 0
// CHECK-NEXT: %1 = struct $Int64 (%0 : $Builtin.Int64)
// CHECK-NEXT: return %1
// CHECK: } // end sil function 'load_count_from_empty_dictionary'
sil @load_count_from_empty_dictionary : $@convention(thin) () -> Int64 {
bb0:
%0 = global_addr @_swiftEmptyDictionarySingleton : $*_SwiftEmptyDictionarySingleton
%1 = address_to_pointer [stack_protection] %0 : $*_SwiftEmptyDictionarySingleton to $Builtin.RawPointer
%2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $__EmptyDictionarySingleton
%3 = unchecked_ref_cast %2 : $__EmptyDictionarySingleton to $Builtin.BridgeObject
%4 = unchecked_ref_cast %3 : $Builtin.BridgeObject to $__RawDictionaryStorage
%5 = ref_element_addr %4 : $__RawDictionaryStorage, #__RawDictionaryStorage._count
%6 = struct_element_addr %5 : $*Int64, #Int64._value
%7 = load %6 : $*Builtin.Int64
%9 = struct $Int64 (%7 : $Builtin.Int64)
return %9 : $Int64
}
// CHECK-LABEL: sil @load_capacity_from_empty_dictionary :
// CHECK: %0 = integer_literal $Builtin.Int64, 0
// CHECK-NEXT: %1 = struct $Int64 (%0 : $Builtin.Int64)
// CHECK-NEXT: return %1
// CHECK: } // end sil function 'load_capacity_from_empty_dictionary'
sil @load_capacity_from_empty_dictionary : $@convention(thin) () -> Int64 {
bb0:
%0 = global_addr @_swiftEmptyDictionarySingleton : $*_SwiftEmptyDictionarySingleton
%1 = address_to_pointer [stack_protection] %0 : $*_SwiftEmptyDictionarySingleton to $Builtin.RawPointer
%2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $__EmptyDictionarySingleton
%3 = unchecked_ref_cast %2 : $__EmptyDictionarySingleton to $Builtin.BridgeObject
%4 = unchecked_ref_cast %3 : $Builtin.BridgeObject to $__RawDictionaryStorage
%5 = ref_element_addr %4 : $__RawDictionaryStorage, #__RawDictionaryStorage._capacity
%6 = struct_element_addr %5 : $*Int64, #Int64._value
%7 = load %6 : $*Builtin.Int64
%9 = struct $Int64 (%7 : $Builtin.Int64)
return %9 : $Int64
}
// CHECK-LABEL: sil [ossa] @remove_dead_load :
// CHECK-NOT: load
// CHECK-NOT: destroy_value
// CHECK: } // end sil function 'remove_dead_load'
sil [ossa] @remove_dead_load : $@convention(thin) (@in_guaranteed B) -> () {
bb0(%0 : $*B):
%1 = load [copy] %0 : $*B
destroy_value %1 : $B
%3 = tuple ()
return %3 : $()
}
// CHECK-LABEL: sil [ossa] @remove_dead_load_with_debug_value :
// CHECK-ONONE: load
// CHECK-ONONE: destroy_value
// CHECK-O-NOT: load
// CHECK-O-NOT: destroy_value
// CHECK: } // end sil function 'remove_dead_load_with_debug_value'
sil [ossa] @remove_dead_load_with_debug_value : $@convention(thin) (@in_guaranteed B) -> () {
bb0(%0 : $*B):
%1 = load [copy] %0 : $*B
debug_value %1 : $B, let, name "x"
destroy_value %1 : $B
%3 = tuple ()
return %3 : $()
}
// CHECK-LABEL: sil [ossa] @load_from_global_object :
// CHECK-DAG: [[I0:%.*]] = integer_literal $Builtin.Int64, 0
// CHECK-DAG: [[I1:%.*]] = integer_literal $Builtin.Int64, 1
// CHECK-DAG: [[I2:%.*]] = integer_literal $Builtin.Int64, 2
// CHECK-DAG: [[I3:%.*]] = integer_literal $Builtin.Int64, 3
// CHECK: [[T:%.*]] = tuple ([[I0]] : $Builtin.Int64, [[I1]] : $Builtin.Int64, [[I2]] : $Builtin.Int64, [[I3]] : $Builtin.Int64)
// CHECK: return [[T]]
// CHECK: } // end sil function 'load_from_global_object'
sil [ossa] @load_from_global_object : $@convention(thin) () -> (Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64) {
bb0:
%0 = global_value @gc : $D
%1 = upcast %0 to $C
%2 = ref_element_addr %1, #C.c
%3 = ref_element_addr %0, #D.d
%4 = ref_tail_addr %1, $Builtin.Int64
%5 = integer_literal $Builtin.Word, 1
%6 = index_addr %4, %5
%7 = load [trivial] %2
%8 = load [trivial] %3
%9 = load [trivial] %4
%10 = load [trivial] %6
%11 = tuple (%7, %8, %9, %10)
return %11
}
// CHECK-LABEL: sil [ossa] @dont_load_from_global_var_object :
// CHECK: [[L:%.*]] = load
// CHECK: return [[L]]
// CHECK: } // end sil function 'dont_load_from_global_var_object'
sil [ossa] @dont_load_from_global_var_object : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = global_value @gc_var : $D
%1 = ref_element_addr %0, #D.d
%2 = load [trivial] %1
return %2
}
// CHECK-LABEL: sil @load_from_begin_cow_mutation :
// CHECK: [[I:%.*]] = integer_literal $Builtin.Int64, 1
// CHECK: return [[I]]
// CHECK: } // end sil function 'load_from_begin_cow_mutation'
sil @load_from_begin_cow_mutation : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = global_value @gc : $D
(%1, %2) = begin_cow_mutation %0
%3 = ref_element_addr %2, #D.d
%4 = load %3
return %4
}