1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// RUN: %target-sil-opt -let-properties-opt -enable-sil-verify-all %s | %FileCheck %s
sil_stage canonical
import Builtin
import Swift
// Test initialization of a constant aggregate "let".
// rdar://problem/45691574
// https://github.com/apple/swift/issues/51642
// IBAnimatable - 'SILCloner' crash in 'LetPropertiesOpt'
struct Point {
var x: Int64
var y: Int64
}
class HasCenter {
let centerPoint: Point = Point(x: 0, y: 0)
public func getCenter() -> Int64
}
sil hidden [ossa] @$s19let_properties_opts5PointV1x1yACSi_SitcfC : $@convention(method) (Int64, Int64, @thin Point.Type) -> Point {
bb0(%0 : $Int64, %1 : $Int64, %2 : $@thin Point.Type):
%3 = struct $Point (%0 : $Int64, %1 : $Int64)
return %3 : $Point
}
// variable initialization expression of HasCenter.centerPoint
sil hidden [transparent] [ossa] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvpfi : $@convention(thin) () -> Point {
bb0:
%0 = integer_literal $Builtin.Int64, 0
%1 = struct $Int64 (%0 : $Builtin.Int64)
%2 = struct $Point (%1 : $Int64, %1 : $Int64)
return %2 : $Point
}
// HasCenter.centerPoint.getter
// CHECK-LABEL: sil hidden [transparent] [ossa] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg : $@convention(method) (@guaranteed HasCenter) -> Point {
// CHECK: bb0(%0 : @guaranteed $HasCenter):
// CHECK: [[LIT:%.*]] = integer_literal $Builtin.Int64, 0
// CHECK: [[INT:%.*]] = struct $Int64 ([[LIT]] : $Builtin.Int64)
// CHECK: [[PNT:%.*]] = struct $Point ([[INT]] : $Int64, [[INT]] : $Int64)
// CHECK: return [[PNT]] : $Point
// CHECK-LABEL: } // end sil function '$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg'
sil hidden [transparent] [ossa] @$s19let_properties_opts9HasCenterC11centerPointAA0E0Vvg : $@convention(method) (@guaranteed HasCenter) -> Point {
bb0(%0 : @guaranteed $HasCenter):
%1 = ref_element_addr %0 : $HasCenter, #HasCenter.centerPoint
%2 = load [trivial] %1 : $*Point
return %2 : $Point
}
// HasCenter.getCenter()
// CHECK-LABEL: sil hidden [ossa] @$s19let_properties_opts9HasCenterC9getCenterSiyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
// CHECK: [[LIT:%.*]] = integer_literal $Builtin.Int64, 0
// CHECK: [[INT:%.*]] = struct $Int64 ([[LIT]] : $Builtin.Int64)
// CHECK: [[PNT:%.*]] = struct $Point ([[INT]] : $Int64, [[INT]] : $Int64)
// CHECK: [[X:%.*]] = struct_extract [[PNT]] : $Point, #Point.x
// CHECK: return [[X]] : $Int64
// CHECK-LABEL: } // end sil function '$s19let_properties_opts9HasCenterC9getCenterSiyF'
sil hidden [ossa] @$s19let_properties_opts9HasCenterC9getCenterSiyF : $@convention(method) (@guaranteed HasCenter) -> Int64 {
bb0(%0 : @guaranteed $HasCenter):
%1 = ref_element_addr %0 : $HasCenter, #HasCenter.centerPoint
%2 = struct_element_addr %1 : $*Point, #Point.x
%3 = load [trivial] %2 : $*Int64
return %3 : $Int64
}
// HasCenter.init()
sil hidden [ossa] @$s19let_properties_opts9HasCenterCACycfc : $@convention(method) (@owned HasCenter) -> @owned HasCenter {
bb0(%0 : @owned $HasCenter):
%1 = integer_literal $Builtin.Int64, 0
%3 = struct $Int64 (%1 : $Builtin.Int64)
%4 = struct $Point (%3 : $Int64, %3 : $Int64)
%5 = begin_borrow %0 : $HasCenter
%6 = ref_element_addr %5 : $HasCenter, #HasCenter.centerPoint
store %4 to [trivial] %6 : $*Point
end_borrow %5 : $HasCenter
%9 = copy_value %0 : $HasCenter
destroy_value %0 : $HasCenter
return %9 : $HasCenter
}
// -----------------------------------------------------------------------------
// Test that struct 'let's are not replaced with constants. A struct
// 'let' is part of a larger mutable value.
private struct Inner {
@_hasStorage let val: Int32 { get }
init(val: Int32)
}
private struct Outer {
@_hasStorage @_hasInitialValue var inner: Inner { get set }
init(inner: Inner)
}
sil [transparent] @initInnerLet : $@convention(thin) () -> Inner {
bb0:
%0 = integer_literal $Builtin.Int32, 1
%1 = struct $Int32 (%0 : $Builtin.Int32)
%2 = struct $Inner (%1 : $Int32)
return %2 : $Inner
}
// Check that the returned value is reloaded from inner.val after the memcpy.
//
// CHECK-LABEL: sil hidden @testStructLet : $@convention(thin) (@inout Outer) -> Int32 {
// CHECK: bb0(%0 : $*Outer):
// CHECK: [[OUTADR:%.*]] = address_to_pointer %0 : $*Outer to $Builtin.RawPointer
// CHECK: builtin "int_memcpy_RawPointer_RawPointer_Int64"([[OUTADR]] : $Builtin.RawPointer, %{{.*}} : $Builtin.RawPointer, %{{.*}} : $Builtin.Int64, %{{.*}} : $Builtin.Int1) : $()
// CHECK: [[INADR:%.*]] = struct_element_addr %0 : $*Outer, #Outer.inner
// CHECK: [[VALADR:%.*]] = struct_element_addr [[INADR]] : $*Inner, #Inner.val
// CHECK: [[VAL:%.*]] = load %22 : $*Int32
// CHECK: return [[VAL]] : $Int32
// CHECK-LABEL: } // end sil function 'testStructLet'
sil hidden @testStructLet : $@convention(thin) (@inout Outer) -> Int32 {
bb0(%0 : $*Outer):
%1 = address_to_pointer %0 : $*Outer to $Builtin.RawPointer
%2 = metatype $@thick Outer.Type
%3 = builtin "sizeof"<Outer>(%2 : $@thick Outer.Type) : $Builtin.Word
%4 = builtin "sextOrBitCast_Word_Int64"(%3 : $Builtin.Word) : $Builtin.Int64
%5 = integer_literal $Builtin.Int64, 0
%6 = builtin "cmp_slt_Int64"(%4 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
cond_fail %6 : $Builtin.Int1, "UnsafeMutableRawBufferPointer with negative count"
%8 = integer_literal $Builtin.Int32, 0
%9 = struct $Int32 (%8 : $Builtin.Int32)
%10 = integer_literal $Builtin.Int1, 0
%11 = alloc_stack $Int32
store %9 to %11 : $*Int32
%13 = address_to_pointer %11 : $*Int32 to $Builtin.RawPointer
%14 = metatype $@thick Int32.Type
%15 = builtin "sizeof"<Int32>(%14 : $@thick Int32.Type) : $Builtin.Word
%16 = builtin "sextOrBitCast_Word_Int64"(%15 : $Builtin.Word) : $Builtin.Int64
%17 = builtin "cmp_slt_Int64"(%16 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
cond_fail %17 : $Builtin.Int1, "Negative value is not representable"
%19 = builtin "int_memcpy_RawPointer_RawPointer_Int64"(%1 : $Builtin.RawPointer, %13 : $Builtin.RawPointer, %16 : $Builtin.Int64, %10 : $Builtin.Int1) : $()
dealloc_stack %11 : $*Int32
%21 = struct_element_addr %0 : $*Outer, #Outer.inner
%22 = struct_element_addr %21 : $*Inner, #Inner.val
%23 = load %22 : $*Int32
return %23 : $Int32
}
|