mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
I am doing this separately from the actual change to eliminate the option to make it easier to review.
253 lines
9.6 KiB
Plaintext
253 lines
9.6 KiB
Plaintext
// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -jumpthread-simplify-cfg | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
// CHECK-LABEL: sil @convert_inject_enum_addr_select_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> ()
|
|
// CHECK: init_existential_addr
|
|
// CHECK: inject_enum_addr
|
|
// CHECK-NOT: select_enum_addr
|
|
// CHECK-NOT: bb1
|
|
// CHECK: unchecked_take_enum_data_addr
|
|
// CHECK: return
|
|
sil @convert_inject_enum_addr_select_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () {
|
|
bb0(%0 : $*Int, %1 : $*_Stdout):
|
|
%2 = alloc_stack $CustomStringConvertible
|
|
%3 = alloc_stack $Optional<CustomStringConvertible>
|
|
%4 = init_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
%5 = alloc_stack $Int
|
|
%6 = load %0 : $*Int
|
|
store %6 to %5 : $*Int
|
|
unconditional_checked_cast_addr Int in %5 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
dealloc_stack %5 : $*Int
|
|
%11 = integer_literal $Builtin.Int1, -1
|
|
%12 = integer_literal $Builtin.Int1, 0
|
|
%13 = select_enum_addr %3 : $*Optional<CustomStringConvertible>, case #Optional.some!enumelt.1: %11, case #Optional.none!enumelt: %12 : $Builtin.Int1
|
|
cond_br %13, bb2, bb1
|
|
|
|
bb1:
|
|
%15 = tuple ()
|
|
dealloc_stack %3 : $*Optional<CustomStringConvertible>
|
|
dealloc_stack %2 : $*CustomStringConvertible
|
|
return %15 : $()
|
|
|
|
bb2:
|
|
%19 = unchecked_take_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
copy_addr [take] %19 to [initialization] %2 : $*CustomStringConvertible
|
|
br bb1
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: sil @convert_inject_enum_addr_switch_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> ()
|
|
// CHECK: init_existential_addr
|
|
// CHECK: inject_enum_addr
|
|
// CHECK-NOT: switch_enum_addr
|
|
// CHECK-NOT: bb1
|
|
// CHECK: unchecked_take_enum_data_addr
|
|
// CHECK: return
|
|
sil @convert_inject_enum_addr_switch_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () {
|
|
bb0(%0 : $*Int, %1 : $*_Stdout):
|
|
%2 = alloc_stack $CustomStringConvertible
|
|
%3 = alloc_stack $Optional<CustomStringConvertible>
|
|
%4 = init_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
%5 = alloc_stack $Int
|
|
%6 = load %0 : $*Int
|
|
store %6 to %5 : $*Int
|
|
unconditional_checked_cast_addr Int in %5 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
dealloc_stack %5 : $*Int
|
|
switch_enum_addr %3 : $*Optional<CustomStringConvertible>, case #Optional.some!enumelt.1: bb3, case #Optional.none!enumelt: bb2
|
|
|
|
bb1:
|
|
%15 = tuple ()
|
|
dealloc_stack %3 : $*Optional<CustomStringConvertible>
|
|
dealloc_stack %2 : $*CustomStringConvertible
|
|
return %15 : $()
|
|
|
|
bb2:
|
|
br bb1
|
|
|
|
bb3:
|
|
%19 = unchecked_take_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
copy_addr [take] %19 to [initialization] %2 : $*CustomStringConvertible
|
|
br bb1
|
|
}
|
|
|
|
|
|
// Check that a checked_cast_addr_br converting a known type into a protocol type
|
|
// is performed at the compile-time if protocol conformances are statically known.
|
|
//
|
|
// CHECK-LABEL: sil @convert_checked_cast_addr_br_into_unconditional_checked_cast_addr_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> ()
|
|
// CHECK: store
|
|
// CHECK-NOT: checked_cast_addr_br
|
|
// CHECK-NOT: bb1
|
|
// CHECK: inject_enum_addr %{{.*}} : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
// CHECK: dealloc_stack
|
|
// CHECK: return
|
|
sil @convert_checked_cast_addr_br_into_unconditional_checked_cast_addr_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () {
|
|
bb0(%0 : $*Int, %1 : $*_Stdout):
|
|
%2 = alloc_stack $CustomStringConvertible
|
|
%3 = alloc_stack $Optional<CustomStringConvertible>
|
|
%4 = init_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
%5 = alloc_stack $Int
|
|
%6 = load %0 : $*Int
|
|
store %6 to %5 : $*Int
|
|
checked_cast_addr_br take_always Int in %5 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22
|
|
|
|
bb1:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
br bb2
|
|
|
|
bb2:
|
|
dealloc_stack %5 : $*Int
|
|
dealloc_stack %3 : $*Optional<CustomStringConvertible>
|
|
%12 = integer_literal $Builtin.Int1, -1
|
|
%13 = integer_literal $Builtin.Int1, 0
|
|
%26 = tuple ()
|
|
dealloc_stack %2 : $*CustomStringConvertible
|
|
return %26 : $()
|
|
|
|
bb22:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.none!enumelt
|
|
br bb2
|
|
}
|
|
|
|
|
|
class A {
|
|
|
|
}
|
|
|
|
private final class B {
|
|
}
|
|
|
|
public class C {
|
|
}
|
|
|
|
// D cannot be extended elsewhere, but C can!
|
|
private class D : C {
|
|
}
|
|
|
|
// Check that a checked_cast_addr_br converting a known type into a protocol type
|
|
// is performed at the compile-time if protocol conformances are statically known.
|
|
// In a negative case, take care that check for internal types are not folded (unless
|
|
// a whole module optimization is used), because an extension implementing a conformance
|
|
// could be defined elsewhere.
|
|
//
|
|
// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_internal_type : $@convention(thin) (@in A, @inout _Stdout) -> ()
|
|
// CHECK: checked_cast_addr_br
|
|
// CHECK: inject_enum_addr %{{.*}} : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
// CHECK: dealloc_stack
|
|
// CHECK: return
|
|
// CHECK: inject_enum_addr %{{.*}} : $*Optional<CustomStringConvertible>, #Optional.none!enumelt
|
|
// CHECK: }
|
|
sil @convert_checked_cast_addr_br_with_internal_type : $@convention(thin) (@in A, @inout _Stdout) -> () {
|
|
bb0(%0 : $*A, %1 : $*_Stdout):
|
|
%2 = alloc_stack $CustomStringConvertible
|
|
%3 = alloc_stack $Optional<CustomStringConvertible>
|
|
%4 = init_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
%5 = alloc_stack $A
|
|
%6 = load %0 : $*A
|
|
store %6 to %5 : $*A
|
|
checked_cast_addr_br take_always A in %5 : $*A to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22
|
|
|
|
bb1:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
br bb2
|
|
|
|
bb2:
|
|
dealloc_stack %5 : $*A
|
|
dealloc_stack %3 : $*Optional<CustomStringConvertible>
|
|
%12 = integer_literal $Builtin.Int1, -1
|
|
%13 = integer_literal $Builtin.Int1, 0
|
|
%26 = tuple ()
|
|
dealloc_stack %2 : $*CustomStringConvertible
|
|
return %26 : $()
|
|
|
|
bb22:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.none!enumelt
|
|
br bb2
|
|
}
|
|
|
|
// Check that a checked_cast_addr_br converting a known type into a protocol type
|
|
// is performed at the compile-time if protocol conformances are statically known.
|
|
// In a negative case, if the source type is private, it is safe to fold the check,
|
|
// because a conformance for this type cannot be defined elsewhere.
|
|
//
|
|
// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_private_type : $@convention(thin) (@in B, @inout _Stdout) -> ()
|
|
// CHECK: store
|
|
// CHECK-NOT: checked_cast_addr_br
|
|
// CHECK-NOT: bb1
|
|
// CHECK: inject_enum_addr %{{.*}} : $*Optional<CustomStringConvertible>, #Optional.none!enumelt
|
|
// CHECK: dealloc_stack
|
|
// CHECK: return
|
|
sil @convert_checked_cast_addr_br_with_private_type : $@convention(thin) (@in B, @inout _Stdout) -> () {
|
|
bb0(%0 : $*B, %1 : $*_Stdout):
|
|
%2 = alloc_stack $CustomStringConvertible
|
|
%3 = alloc_stack $Optional<CustomStringConvertible>
|
|
%4 = init_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
%5 = alloc_stack $B
|
|
%6 = load %0 : $*B
|
|
store %6 to %5 : $*B
|
|
checked_cast_addr_br take_always B in %5 : $*B to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22
|
|
|
|
bb1:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
br bb2
|
|
|
|
bb2:
|
|
dealloc_stack %5 : $*B
|
|
dealloc_stack %3 : $*Optional<CustomStringConvertible>
|
|
%12 = integer_literal $Builtin.Int1, -1
|
|
%13 = integer_literal $Builtin.Int1, 0
|
|
%26 = tuple ()
|
|
dealloc_stack %2 : $*CustomStringConvertible
|
|
return %26 : $()
|
|
|
|
bb22:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.none!enumelt
|
|
br bb2
|
|
}
|
|
|
|
// Check that a checked_cast_addr_br converting a known type into a protocol type
|
|
// is performed at the compile-time if protocol conformances are statically known.
|
|
// In a negative case, take care that cast for private types are not folded if one
|
|
// of its superclasses could have a conformance extension defined elsewhere.
|
|
//
|
|
// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_non_private_superclass : $@convention(thin) (@in D, @inout _Stdout) -> ()
|
|
// CHECK: checked_cast_addr_br
|
|
// CHECK: inject_enum_addr %{{.*}} : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
// CHECK: dealloc_stack
|
|
// CHECK: return
|
|
// CHECK: inject_enum_addr %{{.*}} : $*Optional<CustomStringConvertible>, #Optional.none!enumelt
|
|
// CHECK: }
|
|
sil @convert_checked_cast_addr_br_with_non_private_superclass : $@convention(thin) (@in D, @inout _Stdout) -> () {
|
|
bb0(%0 : $*D, %1 : $*_Stdout):
|
|
%2 = alloc_stack $CustomStringConvertible
|
|
%3 = alloc_stack $Optional<CustomStringConvertible>
|
|
%4 = init_enum_data_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
%5 = alloc_stack $D
|
|
%6 = load %0 : $*D
|
|
store %6 to %5 : $*D
|
|
checked_cast_addr_br take_always D in %5 : $*D to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22
|
|
|
|
bb1:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.some!enumelt.1
|
|
br bb2
|
|
|
|
bb2:
|
|
dealloc_stack %5 : $*D
|
|
dealloc_stack %3 : $*Optional<CustomStringConvertible>
|
|
%12 = integer_literal $Builtin.Int1, -1
|
|
%13 = integer_literal $Builtin.Int1, 0
|
|
%26 = tuple ()
|
|
dealloc_stack %2 : $*CustomStringConvertible
|
|
return %26 : $()
|
|
|
|
bb22:
|
|
inject_enum_addr %3 : $*Optional<CustomStringConvertible>, #Optional.none!enumelt
|
|
br bb2
|
|
}
|