mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
218 lines
5.9 KiB
Plaintext
218 lines
5.9 KiB
Plaintext
// Legacy passes are tested with the Windows PR tests. So no need to test them on macOS/Linux
|
|
// (they don't run on these platforms anyway). Thus we don't test both new Swift and legacy passes
|
|
// on the same platform at the same time.
|
|
// RUN: %target-sil-opt -enable-sil-verify-all %s -release-devirtualizer -module-name=test | %FileCheck %s
|
|
|
|
// REQUIRES: swift_in_compiler
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class B {
|
|
@_hasStorage var next: B
|
|
}
|
|
|
|
struct Str {
|
|
@_hasStorage var b: B
|
|
}
|
|
|
|
// CHECK-LABEL: sil @devirtualize_object
|
|
// CHECK: [[A:%[0-9]+]] = alloc_ref
|
|
// CHECK-NEXT: set_deallocating [[A]]
|
|
// CHECK-NOT: strong_release
|
|
// CHECK: [[D:%[0-9]+]] = function_ref @$s4test1BCfD
|
|
// CHECK-NEXT: apply [[D]]([[A]])
|
|
// CHECK-NEXT: dealloc_stack_ref [[A]]
|
|
// CHECK: } // end sil function 'devirtualize_object'
|
|
sil @devirtualize_object : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref [stack] $B
|
|
strong_release %1 : $B
|
|
dealloc_stack_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_devirtualize_heap_allocated
|
|
// CHECK: alloc_ref
|
|
// CHECK-NEXT: strong_release
|
|
// CHECK-NEXT: dealloc_ref
|
|
// CHECK: return
|
|
// CHECK: } // end sil function 'dont_devirtualize_heap_allocated'
|
|
sil @dont_devirtualize_heap_allocated : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref $B
|
|
strong_release %1 : $B
|
|
dealloc_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_devirtualize_devirtualized
|
|
// CHECK: alloc_ref
|
|
// CHECK-NEXT: strong_retain
|
|
// CHECK-NEXT: strong_release
|
|
// CHECK-NEXT: set_deallocating
|
|
// CHECK-NEXT: dealloc_ref
|
|
// CHECK-NEXT: dealloc_stack_ref
|
|
// CHECK-NEXT: tuple
|
|
// CHECK: } // end sil function 'dont_devirtualize_devirtualized'
|
|
sil @dont_devirtualize_devirtualized : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref [stack] $B
|
|
strong_retain %1 : $B
|
|
strong_release %1 : $B
|
|
set_deallocating %1 : $B
|
|
dealloc_ref %1 : $B
|
|
dealloc_stack_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_devirtualize_wrong_release
|
|
// CHECK: alloc_ref
|
|
// CHECK-NEXT: strong_release
|
|
// CHECK-NEXT: strong_release
|
|
// CHECK-NEXT: dealloc_ref
|
|
// CHECK: return
|
|
// CHECK: } // end sil function 'dont_devirtualize_wrong_release'
|
|
sil @dont_devirtualize_wrong_release : $@convention(thin) (@owned B) -> () {
|
|
bb0(%0 : $B):
|
|
%1 = alloc_ref $B
|
|
strong_release %1 : $B
|
|
strong_release %0 : $B
|
|
dealloc_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_devirtualize_unknown_release
|
|
// CHECK: alloc_ref
|
|
// CHECK-NEXT: strong_release
|
|
// CHECK: [[F:%[0-9]+]] = function_ref @unknown_func
|
|
// CHECK-NEXT: apply [[F]]()
|
|
// CHECK-NEXT: dealloc_ref
|
|
// CHECK: } // end sil function 'dont_devirtualize_unknown_release'
|
|
sil @dont_devirtualize_unknown_release : $@convention(thin) (@owned B) -> () {
|
|
bb0(%0 : $B):
|
|
%1 = alloc_ref $B
|
|
strong_release %1 : $B
|
|
%f = function_ref @unknown_func : $@convention(thin) () -> ()
|
|
%a = apply %f() : $@convention(thin) () -> ()
|
|
dealloc_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_crash_with_missing_release
|
|
// CHECK: [[A:%[0-9]+]] = alloc_ref
|
|
// CHECK-NEXT: set_deallocating [[A]]
|
|
// CHECK-NOT: strong_release
|
|
// CHECK: [[D:%[0-9]+]] = function_ref @$s4test1BCfD
|
|
// CHECK-NEXT: apply [[D]]([[A]])
|
|
// CHECK-NEXT: dealloc_stack_ref [[A]]
|
|
// CHECK: } // end sil function 'dont_crash_with_missing_release'
|
|
sil @dont_crash_with_missing_release : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref [stack] $B
|
|
strong_release %1 : $B
|
|
dealloc_stack_ref %1 : $B
|
|
%2 = alloc_ref [stack] $B
|
|
dealloc_stack_ref %2 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @long_chain_from_alloc_to_release
|
|
// CHECK: set_deallocating
|
|
// CHECK-NOT: release_value
|
|
// CHECK: } // end sil function 'long_chain_from_alloc_to_release'
|
|
sil @long_chain_from_alloc_to_release : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref [stack] $B
|
|
%2 = struct $Str(%1 : $B)
|
|
%3 = struct_extract %2 : $Str, #Str.b
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%3 : $B)
|
|
|
|
bb2:
|
|
br bb3(%3 : $B)
|
|
|
|
bb3(%a : $B):
|
|
%s = struct $Str (%a : $B)
|
|
%i = integer_literal $Builtin.Int64, 0
|
|
%t = tuple (%s : $Str, %i : $Builtin.Int64)
|
|
%o = enum $Optional<(Str, Builtin.Int64)>, #Optional.some!enumelt, %t : $(Str, Builtin.Int64)
|
|
release_value %o : $Optional<(Str, Builtin.Int64)>
|
|
dealloc_stack_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_devirtualize_double_release
|
|
// CHECK-NOT: set_deallocating
|
|
// CHECK: release_value
|
|
// CHECK: } // end sil function 'dont_devirtualize_double_release'
|
|
sil @dont_devirtualize_double_release : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref [stack] $B
|
|
%t = tuple (%1 : $B, %1 : $B)
|
|
release_value %t : $(B, B)
|
|
dealloc_stack_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_devirtualize_release_of_load
|
|
// CHECK-NOT: set_deallocating
|
|
// CHECK: strong_release
|
|
// CHECK: } // end sil function 'dont_devirtualize_release_of_load'
|
|
sil @dont_devirtualize_release_of_load : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref [stack] $B
|
|
%2 = ref_element_addr %1 : $B, #B.next
|
|
%3 = load %2 : $*B
|
|
strong_release %3 : $B
|
|
dealloc_stack_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_devirtualize_release_of_different_allocations
|
|
// CHECK-NOT: set_deallocating
|
|
// CHECK: strong_release
|
|
// CHECK: } // end sil function 'dont_devirtualize_release_of_different_allocations'
|
|
sil @dont_devirtualize_release_of_different_allocations : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = alloc_ref [stack] $B
|
|
%2 = alloc_ref [stack] $B
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%1 : $B)
|
|
|
|
bb2:
|
|
br bb3(%2 : $B)
|
|
|
|
bb3(%a : $B):
|
|
strong_release %a : $B
|
|
dealloc_stack_ref %2 : $B
|
|
dealloc_stack_ref %1 : $B
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
|
|
sil @unknown_func : $@convention(thin) () -> ()
|
|
|
|
sil @$s4test1BCfD : $@convention(method) (@owned B) -> ()
|
|
|
|
sil_vtable B {
|
|
#B.deinit!deallocator: @$s4test1BCfD
|
|
}
|
|
|