// 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 } struct AO { let a: AnyObject } 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 } // CHECK-LABEL: sil [ossa] @load_of_addr_cast : // CHECK: %1 = load [copy] %0 // CHECK: %2 = unchecked_ref_cast %1 : $B to $AnyObject // CHECK: fix_lifetime %2 // CHECK: destroy_value %2 // CHECK: } // end sil function 'load_of_addr_cast' sil [ossa] @load_of_addr_cast : $@convention(thin) (@inout B) -> () { bb0(%0 : $*B): %1 = unchecked_addr_cast %0 to $*AnyObject %2 = load [copy] %1 fix_lifetime %2 destroy_value %2 %6 = tuple () return %6 } // CHECK-LABEL: sil [ossa] @dont_remove_non_class_addr_cast1 : // CHECK: %1 = unchecked_addr_cast %0 // CHECK: } // end sil function 'dont_remove_non_class_addr_cast1' sil [ossa] @dont_remove_non_class_addr_cast1 : $@convention(thin) (@inout AO) -> () { bb0(%0 : $*AO): %1 = unchecked_addr_cast %0 to $*AnyObject %2 = load [copy] %1 fix_lifetime %2 destroy_value %2 %6 = tuple () return %6 } // CHECK-LABEL: sil [ossa] @dont_remove_non_class_addr_cast2 : // CHECK: %1 = unchecked_addr_cast %0 // CHECK: } // end sil function 'dont_remove_non_class_addr_cast2' sil [ossa] @dont_remove_non_class_addr_cast2 : $@convention(thin) (@inout AnyObject) -> () { bb0(%0 : $*AnyObject): %1 = unchecked_addr_cast %0 to $*AO %2 = load [copy] %1 fix_lifetime %2 destroy_value %2 %6 = tuple () return %6 }