Files
swift-mirror/test/SILOptimizer/sil_combine_enum_addr.sil
John McCall ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00

253 lines
9.7 KiB
Plaintext

// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -sil-combine -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
}