// RUN: %target-swift-frontend -O -sil-verify-all -emit-sil -Xllvm '-sil-inline-never-functions=$sSa6append' %s | %FileCheck %s // REQUIRES: swift_stdlib_no_asserts,optimized_stdlib // This is an end-to-end test of the Array.append(contentsOf:) -> // Array.append(Element) optimization. // // To check that the optimization produces the expected // Array.append(Element) calls, the CHECK lines match those call // sites. The optimizer may subsequently inline Array.append(Element), // which is good, but to keep the test simple and specific to the // optimization, the RUN line prevents inlining Array.append(Element). // Likewise, negative tests check for the existence of // Array.append(contentsOf:), so don't inline those either. // CHECK-LABEL: sil @{{.*}}testInt // CHECK-NOT: apply // CHECK: [[F:%[0-9]+]] = function_ref @$sSa6appendyyxnFSi_Tg5 // CHECK-NOT: apply // CHECK: apply [[F]] // CHECK-NEXT: tuple // CHECK-NEXT: return public func testInt(_ a: inout [Int]) { a += [1] } // CHECK-LABEL: sil @{{.*}}testThreeInts // CHECK-DAG: [[FR:%[0-9]+]] = function_ref @${{(sSa15reserveCapacityyySiFSi_Tg5|sSa16_createNewBuffer)}} // CHECK-DAG: apply [[FR]] // CHECK-DAG: [[F:%[0-9]+]] = function_ref @$sSa6appendyyxnFSi_Tg5 // CHECK-DAG: apply [[F]] // CHECK-DAG: apply [[F]] // CHECK-DAG: apply [[F]] // CHECK: } // end sil function '{{.*}}testThreeInts{{.*}}' public func testThreeInts(_ a: inout [Int]) { a += [1, 2, 3] } // CHECK-LABEL: sil @{{.*}}testTooManyInts // CHECK-NOT: apply // CHECK: [[F:%[0-9]+]] = function_ref @$sSa6append10contentsOfyqd__n_t7ElementQyd__RszSTRd__lFSi_SaySiGTg5 // CHECK-NOT: apply // CHECK: apply [[F]] // CHECK-NOT: apply // CHECK: return public func testTooManyInts(_ a: inout [Int]) { a += [1, 2, 3, 4, 5, 6, 7] } // CHECK-LABEL: sil @{{.*}}testString // CHECK-NOT: apply // CHECK: [[F:%[0-9]+]] = function_ref @$sSa6appendyyxnFSS_Tg5 // CHECK-NOT: apply // CHECK: apply [[F]] // CHECK-NOT: apply // CHECK: tuple // CHECK-NEXT: return public func testString(_ a: inout [String], s: String) { a += [s] } // This is not supported yet. Just check that we don't crash on this.` public func dontPropagateContiguousArray(_ a: inout ContiguousArray) { a += [4] } // Check if the specialized Array.append(contentsOf:) is reasonably optimized for Array. // CHECK-LABEL: sil shared {{.*}}@$sSa6append10contentsOfyqd__n_t7ElementQyd__RszSTRd__lFSi_SaySiGTg5Tf4gn_n // There should only be a single call to _createNewBuffer or reserveCapacityForAppend/reserveCapacityImpl. // CHECK-NOT: apply // CHECK: [[F:%[0-9]+]] = function_ref @{{.*(_createNewBuffer|reserveCapacity).*}} // CHECK-NEXT: apply [[F]] // CHECK-NOT: apply // The number of basic blocks should not exceed 20 (ideally there are no more than 16 blocks in this function). // CHECK-NOT: bb20: // CHECK: } // end sil function '$sSa6append10contentsOfyqd__n_t7ElementQyd__RszSTRd__lFSi_SaySiGTg5