Files
swift-mirror/test/SILOptimizer/sil_combine_enum_addr.sil
Erik Eckstein 7cceaff5f3 SIL: don't print operand types in textual SIL
Type annotations for instruction operands are omitted, e.g.

```
  %3 = struct $S(%1, %2)
```

Operand types are redundant anyway and were only used for sanity checking in the SIL parser.

But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:

* if the block with the definition appears after the block where the operand's instruction is located

* if a block or instruction is printed in isolation, e.g. in a debugger

The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
2024-11-21 18:49:52 +01:00

720 lines
24 KiB
Plaintext

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -enable-library-evolution \
// RUN: -emit-module-path=%t/resilient_struct.swiftmodule \
// RUN: -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
// RUN: %target-sil-opt -sil-print-types -sdk %clang-importer-sdk-path -enable-sil-verify-all %s -sil-combine -jumpthread-simplify-cfg -I %t | %FileCheck %s
sil_stage canonical
import Builtin
import Swift
import resilient_struct
import ctypes
// CHECK-LABEL: sil @convert_inject_enum_addr_select_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> ()
// CHECK-NOT: init_existential_addr
// CHECK-NOT: inject_enum_addr
// CHECK-NOT: select_enum_addr
// CHECK-NOT: bb1
// CHECK-NOT: 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
%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
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: %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
copy_addr [take] %19 to [init] %2 : $*CustomStringConvertible
br bb1
}
// CHECK-LABEL: sil @convert_inject_enum_addr_switch_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> ()
// CHECK-NOT: init_existential_addr
// CHECK-NOT: inject_enum_addr
// CHECK-NOT: switch_enum_addr
// CHECK-NOT: bb1
// CHECK-NOT: 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
%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
dealloc_stack %5 : $*Int
switch_enum_addr %3 : $*Optional<CustomStringConvertible>, case #Optional.some!enumelt: 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
copy_addr [take] %19 to [init] %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<any CustomStringConvertible>, #Optional.some!enumelt
// 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
%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
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<any CustomStringConvertible>, #Optional.some!enumelt
// CHECK: dealloc_stack
// CHECK: return
// CHECK: inject_enum_addr %{{.*}} : $*Optional<any 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
%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
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<any 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
%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
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<any CustomStringConvertible>, #Optional.some!enumelt
// CHECK: dealloc_stack
// CHECK: return
// CHECK: inject_enum_addr %{{.*}} : $*Optional<any 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
%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
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
}
sil @no_init : $@convention(thin) () -> (@out ())
// CHECK-LABEL: sil @test_empty_tuple_uninintialized : $@convention(thin) () -> () {
// CHECK-NOT: inject_enum_addr
// CHECK-LABEL: } // end sil function 'test_empty_tuple_uninintialized'
sil @test_empty_tuple_uninintialized : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $Optional<()>
%1 = init_enum_data_addr %0 : $*Optional<()>, #Optional.some!enumelt
%f = function_ref @no_init : $@convention(thin) () -> (@out ())
apply %f(%1) : $@convention(thin) () -> (@out ())
inject_enum_addr %0 : $*Optional<()>, #Optional.some!enumelt
%2 = load %0 : $*Optional<()>
switch_enum %2 : $Optional<()>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
bb1(%4 : $()):
br bb3
bb2:
br bb3
bb3:
dealloc_stack %0 : $*Optional<()>
%8 = tuple ()
return %8 : $()
}
sil @no_init_nested_tuple : $@convention(thin) () -> (@out ((), ()))
// CHECK-LABEL: sil @test_empty_nested_tuple_uninintialized : $@convention(thin) () -> () {
// CHECK-NOT: inject_enum_addr
// CHECK-LABEL: } // end sil function 'test_empty_nested_tuple_uninintialized'
sil @test_empty_nested_tuple_uninintialized : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $Optional<((), ())>
%1 = init_enum_data_addr %0 : $*Optional<((), ())>, #Optional.some!enumelt
%f = function_ref @no_init_nested_tuple : $@convention(thin) () -> (@out ((), ()))
apply %f(%1) : $@convention(thin) () -> (@out ((), ()))
inject_enum_addr %0 : $*Optional<((), ())>, #Optional.some!enumelt
%2 = load %0 : $*Optional<((), ())>
switch_enum %2 : $Optional<((), ())>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
bb1(%4 : $((), ())):
br bb3
bb2:
br bb3
bb3:
dealloc_stack %0 : $*Optional<((), ())>
%8 = tuple ()
return %8 : $()
}
sil @no_init_struct : $@convention(thin) () -> (@out ResilientEmptyStruct)
// CHECK-LABEL: sil @test_empty_struct_uninitialized : $@convention(thin) () -> () {
// CHECK-NOT: switch_enum_addr
// CHECK-LABEL: } // end sil function 'test_empty_struct_uninitialized'
sil @test_empty_struct_uninitialized : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $Optional<ResilientEmptyStruct>
%1 = init_enum_data_addr %0 : $*Optional<ResilientEmptyStruct>, #Optional.some!enumelt
%f = function_ref @no_init_struct : $@convention(thin) () -> (@out ResilientEmptyStruct)
apply %f(%1) : $@convention(thin) () -> (@out ResilientEmptyStruct)
inject_enum_addr %0 : $*Optional<ResilientEmptyStruct>, #Optional.some!enumelt
switch_enum_addr %0 : $*Optional<ResilientEmptyStruct>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
bb1:
br bb3
bb2:
br bb3
bb3:
dealloc_stack %0 : $*Optional<ResilientEmptyStruct>
%8 = tuple ()
return %8 : $()
}
sil @no_init_c_union : $@convention(thin) () -> (@out EmptyCUnion)
// CHECK-LABEL: sil @test_empty_c_union : $@convention(thin) () -> () {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'test_empty_c_union'
sil @test_empty_c_union : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $Optional<EmptyCUnion>
%1 = init_enum_data_addr %0 : $*Optional<EmptyCUnion>, #Optional.some!enumelt
%f = function_ref @no_init_c_union : $@convention(thin) () -> (@out EmptyCUnion)
apply %f(%1) : $@convention(thin) () -> (@out EmptyCUnion)
inject_enum_addr %0 : $*Optional<EmptyCUnion>, #Optional.some!enumelt
switch_enum_addr %0 : $*Optional<EmptyCUnion>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
bb1:
br bb3
bb2:
br bb3
bb3:
dealloc_stack %0 : $*Optional<EmptyCUnion>
%8 = tuple ()
return %8 : $()
}
struct NestedUnreferenceableStorage {
let e: EmptyCUnion
}
sil @no_init_nested_c_union : $@convention(thin) () -> (@out NestedUnreferenceableStorage)
// CHECK-LABEL: sil @test_empty_nested_c_union : $@convention(thin) () -> () {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'test_empty_nested_c_union'
sil @test_empty_nested_c_union : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $Optional<NestedUnreferenceableStorage>
%1 = init_enum_data_addr %0 : $*Optional<NestedUnreferenceableStorage>, #Optional.some!enumelt
%f = function_ref @no_init_nested_c_union : $@convention(thin) () -> (@out NestedUnreferenceableStorage)
apply %f(%1) : $@convention(thin) () -> (@out NestedUnreferenceableStorage)
inject_enum_addr %0 : $*Optional<NestedUnreferenceableStorage>, #Optional.some!enumelt
switch_enum_addr %0 : $*Optional<NestedUnreferenceableStorage>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
bb1:
br bb3
bb2:
br bb3
bb3:
dealloc_stack %0 : $*Optional<NestedUnreferenceableStorage>
%8 = tuple ()
return %8 : $()
}
sil @getVoidOut : $@convention(thin) () -> @out ()
sil @getIntOut : $@convention(thin) () -> @out Int
// CHECK-LABEL: sil @empty_nondominating_apply : {{.*}} {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'empty_nondominating_apply'
sil @empty_nondominating_apply : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<()>
%some_addr = init_enum_data_addr %addr : $*Optional<()>, #Optional.some!enumelt
cond_br %cond, left, right
left:
br middle
right:
%get = function_ref @getVoidOut : $@convention(thin) () -> @out ()
apply %get(%some_addr) : $@convention(thin) () -> @out ()
br middle
middle:
inject_enum_addr %addr : $*Optional<()>, #Optional.some!enumelt
%o = load %addr : $*Optional<()>
switch_enum %o : $Optional<()>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $()):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<()>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @check_dominating_apply_unreachable : {{.*}} {
// CHECK-NOT: inject_enum_addr
// CHECK-LABEL: } // end sil function 'check_dominating_apply_unreachable'
sil @check_dominating_apply_unreachable : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<()>
%some_addr = init_enum_data_addr %addr : $*Optional<()>, #Optional.some!enumelt
cond_br %cond, left, right
left:
%get = function_ref @getVoidOut : $@convention(thin) () -> @out ()
apply %get(%some_addr) : $@convention(thin) () -> @out ()
br middle
right:
unreachable
middle:
inject_enum_addr %addr : $*Optional<()>, #Optional.some!enumelt
%o = load %addr : $*Optional<()>
switch_enum %o : $Optional<()>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $()):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<()>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @check_dominating_apply_unreachable_nonempty : {{.*}} {
// CHECK-NOT: inject_enum_addr
// CHECK-LABEL: } // end sil function 'check_dominating_apply_unreachable_nonempty'
sil @check_dominating_apply_unreachable_nonempty : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<Int>
%some_addr = init_enum_data_addr %addr : $*Optional<Int>, #Optional.some!enumelt
cond_br %cond, left, right
left:
%get = function_ref @getIntOut : $@convention(thin) () -> @out Int
apply %get(%some_addr) : $@convention(thin) () -> @out Int
br middle
right:
unreachable
middle:
inject_enum_addr %addr : $*Optional<Int>, #Optional.some!enumelt
%o = load %addr : $*Optional<Int>
switch_enum %o : $Optional<Int>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $Int):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<Int>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @empty_nondominating_store : {{.*}} {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'empty_nondominating_store'
sil @empty_nondominating_store : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<()>
%some_addr = init_enum_data_addr %addr : $*Optional<()>, #Optional.some!enumelt
cond_br %cond, left, right
left:
br middle
right:
%void = tuple ()
store %void to %some_addr : $*()
br middle
middle:
inject_enum_addr %addr : $*Optional<()>, #Optional.some!enumelt
%o = load %addr : $*Optional<()>
switch_enum %o : $Optional<()>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $()):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<()>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @empty_nondominating_tuple_store_neither : {{.*}} {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'empty_nondominating_tuple_store_neither'
sil @empty_nondominating_tuple_store_neither : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<((), ())>
%some_addr = init_enum_data_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%left_addr = tuple_element_addr %some_addr : $*((), ()), 0
%right_addr = tuple_element_addr %some_addr : $*((), ()), 1
cond_br %cond, left, right
left:
br middle
right:
%void = tuple ()
store %void to %left_addr : $*()
store %void to %right_addr : $*()
br middle
middle:
inject_enum_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%o = load %addr : $*Optional<((), ())>
switch_enum %o : $Optional<((), ())>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $((), ())):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<((), ())>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @empty_nondominating_tuple_store_left : {{.*}} {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'empty_nondominating_tuple_store_left'
sil @empty_nondominating_tuple_store_left : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<((), ())>
%some_addr = init_enum_data_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%left_addr = tuple_element_addr %some_addr : $*((), ()), 0
%right_addr = tuple_element_addr %some_addr : $*((), ()), 1
%void = tuple ()
cond_br %cond, left, right
left:
br middle
right:
store %void to %left_addr : $*()
br middle
middle:
store %void to %right_addr : $*()
inject_enum_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%o = load %addr : $*Optional<((), ())>
switch_enum %o : $Optional<((), ())>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $((), ())):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<((), ())>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @empty_nondominating_tuple_store_right : {{.*}} {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'empty_nondominating_tuple_store_right'
sil @empty_nondominating_tuple_store_right : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<((), ())>
%some_addr = init_enum_data_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%left_addr = tuple_element_addr %some_addr : $*((), ()), 0
%right_addr = tuple_element_addr %some_addr : $*((), ()), 1
%void = tuple ()
cond_br %cond, left, right
left:
br middle
right:
store %void to %right_addr : $*()
br middle
middle:
store %void to %left_addr : $*()
inject_enum_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%o = load %addr : $*Optional<((), ())>
switch_enum %o : $Optional<((), ())>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $((), ())):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<((), ())>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @check_partially_dominating_tuple_stores : {{.*}} {
// CHECK: inject_enum_addr
// CHECK-LABEL: } // end sil function 'check_partially_dominating_tuple_stores'
sil @check_partially_dominating_tuple_stores : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<(Builtin.Int1, ())>
%some_addr = init_enum_data_addr %addr : $*Optional<(Builtin.Int1, ())>, #Optional.some!enumelt
%left_addr = tuple_element_addr %some_addr : $*(Builtin.Int1, ()), 0
%false = integer_literal $Builtin.Int1, 0
store %false to %left_addr : $*Builtin.Int1
%right_addr = tuple_element_addr %some_addr : $*(Builtin.Int1, ()), 1
cond_br %cond, left, right
left:
br middle
right:
%void = tuple ()
store %void to %right_addr : $*()
br middle
middle:
inject_enum_addr %addr : $*Optional<(Builtin.Int1, ())>, #Optional.some!enumelt
%o = load %addr : $*Optional<(Builtin.Int1, ())>
switch_enum %o : $Optional<(Builtin.Int1, ())>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $(Builtin.Int1, ())):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<(Builtin.Int1, ())>
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: sil @empty_dominating_tuple_stores : {{.*}} {
// CHECK-NOT: inject_enum_addr
// CHECK-LABEL: } // end sil function 'empty_dominating_tuple_stores'
sil @empty_dominating_tuple_stores : $@convention(thin) (Builtin.Int1) -> () {
entry(%cond : $Builtin.Int1):
%addr = alloc_stack $Optional<((), ())>
%some_addr = init_enum_data_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%left_addr = tuple_element_addr %some_addr : $*((), ()), 0
%right_addr = tuple_element_addr %some_addr : $*((), ()), 1
%void = tuple ()
cond_br %cond, left, right
left:
br middle
right:
br middle
middle:
store %void to %right_addr : $*()
store %void to %left_addr : $*()
inject_enum_addr %addr : $*Optional<((), ())>, #Optional.some!enumelt
%o = load %addr : $*Optional<((), ())>
switch_enum %o : $Optional<((), ())>, case #Optional.some!enumelt: some_block, case #Optional.none!enumelt: none_block
some_block(%avoid : $((), ())):
br exit
none_block:
br exit
exit:
dealloc_stack %addr : $*Optional<((), ())>
%retval = tuple ()
return %retval : $()
}