// RUN: %target-swift-frontend %s -emit-ir | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-%target-abi -check-prefix CHECK-%target-abi-%target-cpu // REQUIRES: CPU=aarch64 || CPU=arm64 || CPU=x86_64 // Android x86_64 doesn't expose Float80. // UNSUPPORTED: OS=linux-android && CPU=x86_64 // Generated from // var x : Int32 = 2 // public func f() -> Int32 { return x } // with swiftc -O -parse-as-library -emit-sil import Builtin import Swift struct S { var m : Int32 } public struct S2 { public var i, j : Int32 var s : S } // CHECK: %Ts5Int32V = type <{ i32 }> // CHECK: %T18static_initializer2S2V = type <{ %Ts5Int32V, %Ts5Int32V, %T18static_initializer1SV }> // CHECK: %T18static_initializer1SV = type <{ %Ts5Int32V }> // CHECK: %T18static_initializer16TestArrayStorageC_tailelems0c = type { [1 x i64], %T18static_initializer16TestArrayStorageC_tailelems0 } // CHECK: %T18static_initializer16TestArrayStorageC_tailelems0 = type <{ %swift.refcounted, %Ts5Int32V, [4 x i8], %Ts5Int64V, %Ts5Int64V }> // CHECK-SYSV-arm64: %T18static_initializer16TestArrayStorageC_tailelems1c = type { [1 x i64], %T18static_initializer16TestArrayStorageC_tailelems1 } // CHECK-SYSV-x86_64: %T18static_initializer16TestArrayStorageC_tailelems1c = type { [2 x i64], %T18static_initializer16TestArrayStorageC_tailelems1 } // CHECK-WIN-x86_64: %T18static_initializer16TestArrayStorageC_tailelems1c = type { [1 x i64], %T18static_initializer16TestArrayStorageC_tailelems1 } // CHECK-SYSV-arm64: %T18static_initializer16TestArrayStorageC_tailelems1 = type <{ %swift.refcounted, %Ts5Int32V, [1 x i8] }> // CHECK-SYSV-x86_64: %T18static_initializer16TestArrayStorageC_tailelems1 = type <{ %swift.refcounted, %Ts5Int32V, [12 x i8], %Ts7Float80V }> // CHECK-WIN-x86_64: %T18static_initializer16TestArrayStorageC_tailelems1 = type <{ %swift.refcounted, %Ts5Int32V, [1 x i8] }> // CHECK: %T18static_initializer16TestArrayStorageC_tailelems3 = type <{ %swift.refcounted, %Ts5Int32V, [1 x i8], [1 x i8] }> sil_global @$s2ch1xSiv : $Int32 = { %1 = integer_literal $Builtin.Int32, 2 %initval = struct $Int32 (%1 : $Builtin.Int32) } // CHECK: @"$s2ch1xSiv" = {{(dllexport )?}}{{(protected )?}}global %Ts5Int32V <{ i32 2 }>, align 4 sil_global @$s6nested1xAA2S2Vv : $S2 = { %1 = integer_literal $Builtin.Int32, 2 %2 = struct $Int32 (%1 : $Builtin.Int32) %3 = integer_literal $Builtin.Int32, 3 %4 = struct $Int32 (%3 : $Builtin.Int32) %5 = integer_literal $Builtin.Int32, 4 %6 = struct $Int32 (%5 : $Builtin.Int32) %7 = struct $S (%6 : $Int32) %initval = struct $S2 (%2 : $Int32, %4 : $Int32, %7 : $S) } // CHECK: @"$s6nested1xAA2S2Vv" = {{(dllexport )?}}{{(protected )?}}global %T18static_initializer2S2V <{ %Ts5Int32V <{ i32 2 }>, %Ts5Int32V <{ i32 3 }>, %T18static_initializer1SV <{ %Ts5Int32V <{ i32 4 }> }> }>, align 4 final class TestArrayStorage { @_hasStorage var count: Int32 init() } sil_vtable TestArrayStorage { } struct TestArray { var storage : TestArrayStorage } sil_global @static_array : $TestArrayStorage = { %0 = integer_literal $Builtin.Int32, 2 %1 = integer_literal $Builtin.Int64, 10 %2 = integer_literal $Builtin.Int64, 20 %3 = struct $Int32 (%0 : $Builtin.Int32) %4 = struct $Int64 (%1 : $Builtin.Int64) %5 = struct $Int64 (%2 : $Builtin.Int64) %initval = object $TestArrayStorage (%3 : $Int32, [tail_elems] %4 : $Int64, %5 : $Int64) } // CHECK: @static_array = {{(dllexport )?}}{{(protected )?}}global %T18static_initializer16TestArrayStorageC_tailelems0c { [1 x i64] zeroinitializer, %T18static_initializer16TestArrayStorageC_tailelems0 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }>, [4 x i8] undef, %Ts5Int64V <{ i64 10 }>, %Ts5Int64V <{ i64 20 }> }> }, align 8 sil_global @static_vector : $Int64 = { %0 = integer_literal $Builtin.Int64, 2 %1 = integer_literal $Builtin.Int64, 10 %2 = integer_literal $Builtin.Int64, 20 %3 = struct $Int64 (%0 : $Builtin.Int64) %4 = struct $Int64 (%1 : $Builtin.Int64) %5 = struct $Int64 (%2 : $Builtin.Int64) %initval = vector (%3 : $Int64, %4 : $Int64, %5 : $Int64) } // CHECK: @static_vector = {{(dllexport )?}}{{(protected )?}}global [3 x %Ts5Int64V] [%Ts5Int64V <{ i64 2 }>, %Ts5Int64V <{ i64 10 }>, %Ts5Int64V <{ i64 20 }>], align 8 sil_global @static_optional_int_vector : $Optional = { %0 = integer_literal $Builtin.Int32, 2 %1 = integer_literal $Builtin.Int32, 10 %2 = integer_literal $Builtin.Int32, 20 %3 = struct $Int32 (%0 : $Builtin.Int32) %4 = struct $Int32 (%1 : $Builtin.Int32) %5 = struct $Int32 (%2 : $Builtin.Int32) %6 = enum $Optional, #Optional.some!enumelt, %3 : $Int32 %7 = enum $Optional, #Optional.some!enumelt, %4 : $Int32 %8 = enum $Optional, #Optional.some!enumelt, %5 : $Int32 %initval = vector (%6 : $Optional, %7 : $Optional, %8 : $Optional) } // CHECK: @static_optional_int_vector = {{(dllexport )?}}{{(protected )?}}global [3 x <{ i32, i8, i8, i8, i8 }>] [<{ i32, i8, i8, i8, i8 }> <{ i32 2, i8 0, i8 undef, i8 undef, i8 undef }>, <{ i32, i8, i8, i8, i8 }> <{ i32 10, i8 0, i8 undef, i8 undef, i8 undef }>, <{ i32, i8, i8, i8, i8 }> <{ i32 20, i8 0, i8 undef, i8 undef, i8 undef }>], align 4 sil_global @static_aligned_array : $TestArrayStorage = { %0 = integer_literal $Builtin.Int32, 2 %1 = float_literal $Builtin.FPIEEE80, 0x3FFE8000000000000000 %3 = struct $Int32 (%0 : $Builtin.Int32) %4 = struct $Float80 (%1 : $Builtin.FPIEEE80) %initval = object $TestArrayStorage (%3 : $Int32, [tail_elems] %4 : $Float80) } // CHECK-SYSV-arm64: @static_aligned_array = {{(dllexport )?}}{{(protected )?}}global %T18static_initializer16TestArrayStorageC_tailelems1c { [1 x i64] zeroinitializer, %T18static_initializer16TestArrayStorageC_tailelems1 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }>, [1 x i8] undef }> }, align 8 // CHECK-SYSV-x86_64: @static_aligned_array = {{(dllexport )?}}{{(protected )?}}global %T18static_initializer16TestArrayStorageC_tailelems1c { [2 x i64] zeroinitializer, %T18static_initializer16TestArrayStorageC_tailelems1 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }>, [12 x i8] undef, %Ts7Float80V <{ x86_fp80 0xK3FFE8000000000000000 }> }> }, align 16 // CHECK-WIN-x86_64: @static_aligned_array = {{(dllexport )?}}{{(protected )?}}global %T18static_initializer16TestArrayStorageC_tailelems1c { [1 x i64] zeroinitializer, %T18static_initializer16TestArrayStorageC_tailelems1 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }>, [1 x i8] undef }> }, align 8 final class ClassWithEmptyField { @_hasStorage var x: Int32 @_hasStorage var y: () init() } sil_vtable ClassWithEmptyField { } sil_global @static_class_with_empty_field : $ClassWithEmptyField = { %0 = integer_literal $Builtin.Int32, 2 %3 = struct $Int32 (%0 : $Builtin.Int32) %5 = tuple () %initval = object $ClassWithEmptyField (%3 : $Int32, %5 : $()) } // CHECK: @static_class_with_empty_field = {{(dllexport )?}}{{(protected )?}}global %T18static_initializer19ClassWithEmptyFieldC_tailelems2c { [1 x i64] zeroinitializer, %T18static_initializer19ClassWithEmptyFieldC_tailelems2 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }> }> }, align 8 struct Empty { } sil_global @static_array_with_empty_element : $TestArrayStorage = { %0 = struct $Empty () // users: %7, %7 %1 = integer_literal $Builtin.Int32, 2 %2 = struct $Int32 (%1 : $Builtin.Int32) %initval = object $TestArrayStorage (%2 : $Int32, [tail_elems] %0 : $Empty, %0 : $Empty) } // CHECK: @static_array_with_empty_element = {{(dllexport )?}}{{(protected )?}}global %T18static_initializer16TestArrayStorageC_tailelems3c { [1 x i64] zeroinitializer, %T18static_initializer16TestArrayStorageC_tailelems3 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }>, [1 x i8] undef, [1 x i8] undef }> }, align 8 struct MyString { var buffer: Builtin.BridgeObject } sil_global [let] @string_with_offset : $MyString = { %0 = integer_literal $Builtin.Int64, -9223372036854775808 %1 = integer_literal $Builtin.Int1, 0 %2 = integer_literal $Builtin.Int64, 32 %3 = string_literal utf8 "abc123asd3sdj3basfasdf" %4 = builtin "ptrtoint_Word"(%3 : $Builtin.RawPointer) : $Builtin.Word %5 = builtin "zextOrBitCast_Word_Int64"(%4 : $Builtin.Word) : $Builtin.Int64 %6 = builtin "usub_with_overflow_Int64"(%5 : $Builtin.Int64, %2 : $Builtin.Int64, %1 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) %7 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 0 %8 = builtin "stringObjectOr_Int64"(%7 : $Builtin.Int64, %0 : $Builtin.Int64) : $Builtin.Int64 %9 = value_to_bridge_object %8 : $Builtin.Int64 %initval = struct $MyString (%9 : $Builtin.BridgeObject) } // CHECK: @string_with_offset = {{.*constant .*}} <{ ptr inttoptr (i64 add (i64 ptrtoint (ptr @.str.22.abc123asd3sdj3basfasdf to i64), i64 9223372036854775776) to ptr) }>, align 8 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @_TF2cha1xSi() {{.*}} { // CHECK-NEXT: entry: // CHECK-NEXT: ret ptr @"$s2ch1xSiv" sil [global_init] @_TF2cha1xSi : $@convention(thin) () -> Builtin.RawPointer { bb0: %0 = global_addr @$s2ch1xSiv : $*Int32 %1 = address_to_pointer %0 : $*Int32 to $Builtin.RawPointer return %1 : $Builtin.RawPointer } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @"$s2ch1fSiyF"() {{.*}} { // CHECK-NEXT: entry: // CHECK-NEXT: load i32, ptr @"$s2ch1xSiv" // CHECK-NEXT: ret sil @$s2ch1fSiyF : $@convention(thin) () -> Int32 { bb0: %0 = global_addr @$s2ch1xSiv : $*Int32 %1 = load %0 : $*Int32 return %1 : $Int32 } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @_TF6nesteda1xVS_2S2() {{.*}} { // CHECK-NEXT: entry: // CHECK-NEXT: ret ptr @"$s6nested1xAA2S2Vv" sil [global_init] @_TF6nesteda1xVS_2S2 : $@convention(thin) () -> Builtin.RawPointer { bb0: %0 = global_addr @$s6nested1xAA2S2Vv : $*S2 %1 = address_to_pointer %0 : $*S2 to $Builtin.RawPointer return %1 : $Builtin.RawPointer } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i32 } @"$s6nested1fAA2S2VyF"() {{.*}} { // CHECK-NEXT: entry: // CHECK: load i32, ptr @"$s6nested1xAA2S2Vv" // CHECK-NEXT: load i32, ptr getelementptr inbounds{{.*}} (%T18static_initializer2S2V, ptr @"$s6nested1xAA2S2Vv", i32 0, i32 1) // CHECK-NEXT: load i32, ptr getelementptr inbounds{{.*}} (%T18static_initializer2S2V, ptr @"$s6nested1xAA2S2Vv", i32 0, i32 2) sil @$s6nested1fAA2S2VyF : $@convention(thin) () -> S2 { bb0: %0 = global_addr @$s6nested1xAA2S2Vv : $*S2 %1 = load %0 : $*S2 return %1 : $S2 } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @return_static_array() {{.*}} { sil @return_static_array : $@convention(thin) () -> TestArray { bb0: // CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s18static_initializer16TestArrayStorageCMa"(i64 0) // CHECK: [[MD:%[0-9]+]] = extractvalue %swift.metadata_response [[TMP]], 0 // CHECK: [[O:%[0-9a-z]+]] = call ptr @swift_initStaticObject(ptr [[MD]], ptr getelementptr{{.*}} (%T18static_initializer16TestArrayStorageC_tailelems0c, ptr @static_array, i32 0, i32 1)) // CHECK: ret ptr [[O]] %0 = global_value @static_array : $TestArrayStorage %1 = struct $TestArray (%0 : $TestArrayStorage) return %1 : $TestArray } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @bare_static_array() {{.*}} { sil @bare_static_array : $@convention(thin) () -> Int32 { bb0: // CHECK: %0 = load i32, {{.*}}@static_array // CHECK: ret i32 %0 %0 = global_value [bare] @static_array : $TestArrayStorage %1 = ref_element_addr %0 : $TestArrayStorage, #TestArrayStorage.count %2 = load %1 : $*Int32 return %2 : $Int32 } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @phi_nodes(i1 %0, ptr %1) // CHECK: [[T0:%.*]] = call ptr @swift_initStaticObject // CHECK: br // CHECK: br // CHECK: [[T3:%.*]] = phi ptr [ %1, {{.*}} ], [ [[T0]], {{.*}} ] // CHECK: ret ptr [[T3]] sil @phi_nodes : $@convention(thin) (Builtin.Int1, TestArrayStorage) -> TestArrayStorage { bb0(%0 : $Builtin.Int1, %1 : $TestArrayStorage): cond_br %0, bb1, bb2 bb1: %2 = global_value @static_array : $TestArrayStorage br bb3(%2 : $TestArrayStorage) bb2: br bb3(%1 : $TestArrayStorage) bb3(%3 : $TestArrayStorage): return %3 : $TestArrayStorage }