From 2f325d93ca44b12df40f37d75e10fe0818357ea1 Mon Sep 17 00:00:00 2001 From: Emanuel Zephir Date: Thu, 31 Dec 2015 14:27:42 -0800 Subject: [PATCH] [SILOptimizer] Refactor ObjC dependencies in sil_combine tests Move functionality that requires ObjC interop into a new file and remove the XFAIL on Linux. Partially resolves SR-216. --- test/SILOptimizer/sil_combine.sil | 138 ----------------------- test/SILOptimizer/sil_combine_objc.sil | 150 +++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 138 deletions(-) create mode 100644 test/SILOptimizer/sil_combine_objc.sil diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil index 628d796e6f484..4774731ea71e5 100644 --- a/test/SILOptimizer/sil_combine.sil +++ b/test/SILOptimizer/sil_combine.sil @@ -1,7 +1,5 @@ // RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -verify-skip-unreachable-must-be-last | FileCheck %s -// XFAIL: linux - sil_stage canonical import Builtin @@ -694,48 +692,6 @@ bb0(%0 : $*X): return %19 : $() } -sil @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> -sil @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - -// CHECK-LABEL: sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () -// CHECK: bb0 -// CHECK-NEXT: release_value -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () { -bb0(%0 : $_StringCore): - %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %3 = function_ref @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - %5 = tuple() - return %5 : $() -} - -// CHECK-LABEL: sil @dead_closure_elimination2 -// CHECK: bb0 -// CHECK-NEXT: br bb1 -// CHECK: bb1 -// CHECK-NEXT: release_value -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @dead_closure_elimination2 : $@convention(thin) (@owned _StringCore) -> () { -bb0(%0 : $_StringCore): - %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %3 = function_ref @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - br bb1 - -bb1: - strong_retain %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - %5 = tuple() - return %5 : $() -} - sil @unbalanced_closure : $@convention(thin) (@guaranteed B) -> () // CHECK-LABEL: sil @partial_apply_unbalanced_retain_release @@ -1855,32 +1811,6 @@ bb3(%a : $ZZZ): return %a : $ZZZ } - -// FIXME: Add dead array elimination to DeadObjectElimination -// CHECK-LABEL: test_dead_array -// CHECK: bb0(%0 : $ZZZ): -// DISABLED-CHECK-NEXT: strong_release %0 -// DISABLED-CHECK-NEXT: tuple -// DISABLED-CHECK-NEXT: return -sil @test_dead_array : $@convention(thin) (@owned ZZZ) -> () { -bb0(%0 : $ZZZ): - %1 = integer_literal $Builtin.Word, 1 - %2 = function_ref @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) - %3 = apply %2(%1) : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) - %4 = tuple_extract %3 : $(Array, Builtin.RawPointer), 0 - %5 = tuple_extract %3 : $(Array, Builtin.RawPointer), 1 - %6 = pointer_to_address %5 : $Builtin.RawPointer to $*ZZZ - store %0 to %6 : $*ZZZ - %8 = struct_extract %4 : $Array, #Array._buffer - %9 = struct_extract %8 : $_ArrayBuffer, #_ArrayBuffer._storage - %10 = struct_extract %9 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue - strong_release %10 : $Builtin.BridgeObject - %12 = tuple () - return %12 : $() -} - -sil [_semantics "array.uninitialized"] @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) - struct FakeInt16 { var val : Builtin.Int16 } @@ -2602,55 +2532,6 @@ bb0(%0 : $Builtin.Int1): return %2 : $Builtin.Int1 } -// dead_array test helpers -sil [thunk] @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () { -bb0(%0 : $@callee_owned () -> Bool): - %1 = apply %0() : $@callee_owned () -> Bool - %2 = tuple () - return %2 : $() -} - -sil @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool { -bb0(%0 : $*_HeapBuffer): - %1 = struct_element_addr %0 : $*_HeapBuffer, #_HeapBuffer._storage // user: %2 - %2 = is_unique %1 : $*Optional // user: %3 - %3 = struct $Bool (%2 : $Builtin.Int1) // user: %4 - return %3 : $Bool // id: %4 -} - -// Mimicks Swift._allocateUninitializedArray -sil [_semantics "array.uninitialized"] @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) - -// HeapBuffer.swift test case spuriously reports a "unique" buffer -// CHECK-LABEL: sil @dead_array -// CHECK-NOT: release -// CHECK: retain_value %{{[0-9]+}} : $Optional -// CHECK: apply -// CHECK: strong_release %{{[0-9]+}} : $Builtin.BridgeObject -sil @dead_array : $@convention(thin) (@inout _HeapBuffer) -> () { -bb0(%0 : $*_HeapBuffer): - %1 = integer_literal $Builtin.Word, 1 // user: %3 - %2 = function_ref @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) - %3 = apply %2<_HeapBuffer>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) - %4 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 0 // user: %15 - %5 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 1 // user: %6 - %6 = pointer_to_address %5 : $Builtin.RawPointer to $*_HeapBuffer // user: %9 - %7 = load %0 : $*_HeapBuffer // users: %8, %9 - %8 = struct_extract %7 : $_HeapBuffer, #_HeapBuffer._storage // user: %13 - store %7 to %6 : $*_HeapBuffer // id: %9 - %10 = function_ref @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () // user: %14 - %11 = function_ref @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %12 - %12 = partial_apply %11(%0) : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %14 - retain_value %8 : $Optional // id: %13 - %14 = apply %10(%12) : $@convention(thin) (@owned @callee_owned () -> Bool) -> () - %15 = struct_extract %4 : $Array<_HeapBuffer>, #Array._buffer // user: %16 - %16 = struct_extract %15 : $_ArrayBuffer<_HeapBuffer>, #_ArrayBuffer._storage // user: %17 - %17 = struct_extract %16 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue // user: %18 - strong_release %17 : $Builtin.BridgeObject // id: %18 - %19 = tuple () // user: %20 - return %19 : $() // id: %20 -} - struct NStruct { var a:Int var b:Int @@ -2792,25 +2673,6 @@ bb0: return %2 : $Builtin.Int1 } -// Check that it does not crash the compiler. -// Int is ObjC-bridgeable in this case, but its conformance is not know, -// because Foundation is not imported yet. -// Therefore the cast may succeed from the compiler point of view. -// CHECK-LABEL: sil @cast_of_class_to_int -// CHECK: unconditional_checked_cast_addr -// CHECK: return -sil @cast_of_class_to_int : $@convention(thin) (C) -> Int { -bb0(%0 : $C): - %1 = alloc_stack $Int - %2 = alloc_stack $C - store %0 to %2#1 : $*C - unconditional_checked_cast_addr take_always C in %2#1 : $*C to Int in %1#1 : $*Int - %4 = load %1#1 : $*Int - dealloc_stack %2#0 : $*@local_storage C - dealloc_stack %1#0 : $*@local_storage Int - return %4 : $Int -} - class CC1 { deinit init() diff --git a/test/SILOptimizer/sil_combine_objc.sil b/test/SILOptimizer/sil_combine_objc.sil new file mode 100644 index 0000000000000..dd441c7c131b5 --- /dev/null +++ b/test/SILOptimizer/sil_combine_objc.sil @@ -0,0 +1,150 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -verify-skip-unreachable-must-be-last | FileCheck %s +// REQUIRES: objc_interop + +sil_stage canonical + +import Builtin +import Swift + +class ZZZ { + @objc deinit + init() +} + +class C {} + +sil @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> +sil @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + +// CHECK-LABEL: sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () +// CHECK: bb0 +// CHECK-NEXT: release_value +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () { +bb0(%0 : $_StringCore): + %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %3 = function_ref @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + %5 = tuple() + return %5 : $() +} + +// CHECK-LABEL: sil @dead_closure_elimination2 +// CHECK: bb0 +// CHECK-NEXT: br bb1 +// CHECK: bb1 +// CHECK-NEXT: release_value +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @dead_closure_elimination2 : $@convention(thin) (@owned _StringCore) -> () { +bb0(%0 : $_StringCore): + %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %3 = function_ref @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + br bb1 + +bb1: + strong_retain %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + %5 = tuple() + return %5 : $() +} + +// FIXME: Add dead array elimination to DeadObjectElimination +// CHECK-LABEL: test_dead_array +// CHECK: bb0(%0 : $ZZZ): +// DISABLED-CHECK-NEXT: strong_release %0 +// DISABLED-CHECK-NEXT: tuple +// DISABLED-CHECK-NEXT: return +sil @test_dead_array : $@convention(thin) (@owned ZZZ) -> () { +bb0(%0 : $ZZZ): + %1 = integer_literal $Builtin.Word, 1 + %2 = function_ref @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) + %3 = apply %2(%1) : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) + %4 = tuple_extract %3 : $(Array, Builtin.RawPointer), 0 + %5 = tuple_extract %3 : $(Array, Builtin.RawPointer), 1 + %6 = pointer_to_address %5 : $Builtin.RawPointer to $*ZZZ + store %0 to %6 : $*ZZZ + %8 = struct_extract %4 : $Array, #Array._buffer + %9 = struct_extract %8 : $_ArrayBuffer, #_ArrayBuffer._storage + %10 = struct_extract %9 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue + strong_release %10 : $Builtin.BridgeObject + %12 = tuple () + return %12 : $() +} + +sil [_semantics "array.uninitialized"] @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) + +// dead_array test helpers +sil [thunk] @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () { +bb0(%0 : $@callee_owned () -> Bool): + %1 = apply %0() : $@callee_owned () -> Bool + %2 = tuple () + return %2 : $() +} + +sil @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool { +bb0(%0 : $*_HeapBuffer): + %1 = struct_element_addr %0 : $*_HeapBuffer, #_HeapBuffer._storage // user: %2 + %2 = is_unique %1 : $*Optional // user: %3 + %3 = struct $Bool (%2 : $Builtin.Int1) // user: %4 + return %3 : $Bool // id: %4 +} + +// Mimicks Swift._allocateUninitializedArray +sil [_semantics "array.uninitialized"] @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) + +// HeapBuffer.swift test case spuriously reports a "unique" buffer +// CHECK-LABEL: sil @dead_array +// CHECK-NOT: release +// CHECK: retain_value %{{[0-9]+}} : $Optional +// CHECK: apply +// CHECK: strong_release %{{[0-9]+}} : $Builtin.BridgeObject +sil @dead_array : $@convention(thin) (@inout _HeapBuffer) -> () { +bb0(%0 : $*_HeapBuffer): + %1 = integer_literal $Builtin.Word, 1 // user: %3 + %2 = function_ref @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) + %3 = apply %2<_HeapBuffer>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) + %4 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 0 // user: %15 + %5 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 1 // user: %6 + %6 = pointer_to_address %5 : $Builtin.RawPointer to $*_HeapBuffer // user: %9 + %7 = load %0 : $*_HeapBuffer // users: %8, %9 + %8 = struct_extract %7 : $_HeapBuffer, #_HeapBuffer._storage // user: %13 + store %7 to %6 : $*_HeapBuffer // id: %9 + %10 = function_ref @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () // user: %14 + %11 = function_ref @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %12 + %12 = partial_apply %11(%0) : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %14 + retain_value %8 : $Optional // id: %13 + %14 = apply %10(%12) : $@convention(thin) (@owned @callee_owned () -> Bool) -> () + %15 = struct_extract %4 : $Array<_HeapBuffer>, #Array._buffer // user: %16 + %16 = struct_extract %15 : $_ArrayBuffer<_HeapBuffer>, #_ArrayBuffer._storage // user: %17 + %17 = struct_extract %16 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue // user: %18 + strong_release %17 : $Builtin.BridgeObject // id: %18 + %19 = tuple () // user: %20 + return %19 : $() // id: %20 +} + +// Check that it does not crash the compiler. +// Int is ObjC-bridgeable in this case, but its conformance is not know, +// because Foundation is not imported yet. +// Therefore the cast may succeed from the compiler point of view. +// CHECK-LABEL: sil @cast_of_class_to_int +// CHECK: unconditional_checked_cast_addr +// CHECK: return +sil @cast_of_class_to_int : $@convention(thin) (C) -> Int { +bb0(%0 : $C): + %1 = alloc_stack $Int + %2 = alloc_stack $C + store %0 to %2#1 : $*C + unconditional_checked_cast_addr take_always C in %2#1 : $*C to Int in %1#1 : $*Int + %4 = load %1#1 : $*Int + dealloc_stack %2#0 : $*@local_storage C + dealloc_stack %1#0 : $*@local_storage Int + return %4 : $Int +} +