Optimizer: replace PredictableMemoryAccessOptimizations with MandatoryRedundantLoadElimination in the pass pipeline

PredictableMemoryAccessOptimizations has become unmaintainable as-is.
RedundantLoadElimination does (almost) the same thing as PredictableMemoryAccessOptimizations.
It's not as powerful but good enough because PredictableMemoryAccessOptimizations is actually only needed for promoting integer values for mandatory constant propagation.
And most importantly: RedundantLoadElimination does not insert additional copies which was a big problem in PredictableMemoryAccessOptimizations.

Fixes rdar://142814676
This commit is contained in:
Erik Eckstein
2025-02-06 15:28:53 +01:00
parent ce73deebc4
commit ba4081ee76
30 changed files with 191 additions and 406 deletions

View File

@@ -213,7 +213,7 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
// Promote loads as necessary to ensure we have enough SSA formation to emit
// SSA based diagnostics.
P.addPredictableMemoryAccessOptimizations();
P.addMandatoryRedundantLoadElimination();
// This phase performs optimizations necessary for correct interoperation of
// Swift os log APIs with C os_log ABIs.

View File

@@ -16,12 +16,10 @@ public class M {
// Verify that definite initialization doesn't create a bogus description of
// self pointing to the liveness bitvector.
// CHECK: sil @$s4main1MC4fromAcA12WithDelegate_p_tKcfc
// CHECK: bb0
// CHECK-NEXT: %2 = alloc_stack $Builtin.Int2
// CHECK-NOT: let
// CHECK-NOT: name
// CHECK: scope
// CHECK-LABEL: sil @$s4main1MC4fromAcA12WithDelegate_p_tKcfc
// CHECK: bb0
// CHECK-NOT: alloc_stack $Builtin.Int2{{.*}}let
// CHECK: } // end sil function '$s4main1MC4fromAcA12WithDelegate_p_tKcfc'
public init(from d: WithDelegate) throws {
guard let delegate = d.delegate as? DelegateB
else { throw Err.s(0) }

View File

@@ -44,17 +44,17 @@ distributed actor MyDistActor {
// CHECK: [[RELOADED_SYS1:%[0-9]+]] = load [[TP_FIELD2]] : $*FakeActorSystem
// CHECK: [[SELF_METATYPE:%[0-9]+]] = metatype $@thick MyDistActor.Type
// CHECK: [[ASSIGN_ID_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV8assignIDyAA0C7AddressVxm0B00bC0RzAF0G0RtzlF
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]], [[RELOADED_SYS1]])
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]],
// *** save identity ***
// CHECK: [[ID_FIELD:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.id
// CHECK: store [[ID]] to [[ID_FIELD]] : $*ActorAddress
// CHECK: copy_addr {{.*}} to [init] [[ID_FIELD]] : $*ActorAddress
// *** invoke actorReady ***
// CHECK: [[TP_FIELD3:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.actorSystem
// CHECK: [[RELOADED_SYS2:%[0-9]+]] = load [[TP_FIELD3]] : $*FakeActorSystem
// CHECK: [[READY_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV10actorReadyyyx0B00bC0RzAA0C7AddressV2IDRtzlF
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]], [[RELOADED_SYS2]])
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]],
// CHECK: } // end sil function '$s14default_deinit11MyDistActorC11system_syncAC015FakeDistributedE7Systems0hE6SystemV_tcfc'

View File

@@ -37,7 +37,7 @@ distributed actor MyDistActor {
// CHECK: store [[SYS_PARAM]] to [[SYS_FIELD]] : $*FakeActorSystem
// CHECK: [[ID_FIELD:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.id
// CHECK: store {{%[0-9]+}} to [[ID_FIELD]] : $*ActorAddress
// CHECK: copy_addr {{.*}} to [init] [[ID_FIELD]] : $*ActorAddress
// CHECK: [[RAW_BOOL:%[0-9]+]] = struct_extract [[COND]] : $Bool, #Bool._value
// CHECK: cond_br [[RAW_BOOL]], [[SUCCESS_BB:bb[0-9]+]], [[FAIL_BB:bb[0-9]+]]

View File

@@ -37,7 +37,7 @@ distributed actor MyDistActor {
// CHECK: [[SYS_FIELD:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.actorSystem
// CHECK: store [[SYSTEM]] to [[SYS_FIELD]] : $*FakeActorSystem
// CHECK: [[ID_FIELD:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.id
// CHECK: store {{.*}} to [[ID_FIELD]] : $*ActorAddress
// CHECK: copy_addr {{.*}} to [init] [[ID_FIELD]] : $*ActorAddress
// CHECK: [[RAW_BOOL:%[0-9]+]] = struct_extract [[COND]] : $Bool, #Bool._value
// CHECK: cond_br [[RAW_BOOL]], [[TRUE_BB:bb[0-9]+]], [[FALSE_BB:bb[0-9]+]]
@@ -51,7 +51,7 @@ distributed actor MyDistActor {
// CHECK: [[FALSE_BB]]:
// CHECK: br [[JOIN]]
// CHECK: [[JOIN]]:
// CHECK: [[JOIN]]({{.*}} : $Builtin.Int3):
// CHECK: cond_br {{%[0-9]+}}, [[PARTIAL_DEINIT:bb[0-9]+]], [[NO_DEINIT:bb[0-9]+]]
// CHECK: [[PARTIAL_DEINIT]]:

View File

@@ -42,17 +42,17 @@ distributed actor MyDistActor {
// CHECK: [[RELOADED_SYS1:%[0-9]+]] = load [[TP_FIELD2]] : $*FakeActorSystem
// CHECK: [[SELF_METATYPE:%[0-9]+]] = metatype $@thick MyDistActor.Type
// CHECK: [[ASSIGN_ID_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV8assignIDyAA0C7AddressVxm0B00bC0RzAF0G0RtzlF
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]], [[RELOADED_SYS1]])
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]],
// *** save identity ***
// CHECK: [[ID_FIELD:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.id
// CHECK: store [[ID]] to [[ID_FIELD]] : $*ActorAddress
// CHECK: copy_addr {{.*}} to [init] [[ID_FIELD]] : $*ActorAddress
// *** invoke actorReady ***
// CHECK: [[TP_FIELD3:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.actorSystem
// CHECK: [[RELOADED_SYS2:%[0-9]+]] = load [[TP_FIELD3]] : $*FakeActorSystem
// CHECK: [[READY_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV10actorReadyyyx0B00bC0RzAA0C7AddressV2IDRtzlF
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]], [[RELOADED_SYS2]])
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]],
// CHECK: return [[SELF]]
// CHECK: [[ERROR_BB]]([[ERRVAL:%[0-9]+]] : $any Error):

View File

@@ -49,10 +49,10 @@ distributed actor MyDistActor {
// CHECK: [[RELOADED_SYS1:%[0-9]+]] = load [[TP_FIELD2]] : $*FakeActorSystem
// CHECK: [[SELF_METATYPE:%[0-9]+]] = metatype $@thick MyDistActor.Type
// CHECK: [[ASSIGN_ID_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV8assignIDyAA0C7AddressVxm0B00bC0RzAF0G0RtzlF
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]], [[RELOADED_SYS1]])
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]], {{.*}}
// *** save identity ***
// CHECK: [[ID_FIELD:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.id
// CHECK: store [[ID]] to [[ID_FIELD]] : $*ActorAddress
// CHECK: copy_addr {{.*}} to [init] [[ID_FIELD]] : $*ActorAddress
// CHECK-NOT: apply
// CHECK: br [[JOIN_PT:bb[0-9]+]]
@@ -65,7 +65,7 @@ distributed actor MyDistActor {
// CHECK: [[TP_FIELD3:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.actorSystem
// CHECK: [[RELOADED_SYS2:%[0-9]+]] = load [[TP_FIELD3]] : $*FakeActorSystem
// CHECK: [[READY_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV10actorReadyyyx0B00bC0RzAA0C7AddressV2IDRtzlF
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]], [[RELOADED_SYS2]])
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]], {{.*}}
// CHECK: return [[SELF]] : $MyDistActor
// CHECK: [[SYSTEM_ERROR_BB]]{{.*}}:

View File

@@ -51,11 +51,11 @@ distributed actor MyDistActor {
// CHECK: [[SELF_METATYPE:%[0-9]+]] = metatype $@thick MyDistActor.Type
// CHECK: strong_retain [[RELOADED_SYS1]] : $FakeRoundtripActorSystem
// CHECK: [[ASSIGN_ID_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0a9RoundtripC6SystemC8assignIDyAA0C7AddressVxm0B00bC0RzlF
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]], [[RELOADED_SYS1]])
// CHECK: strong_release [[RELOADED_SYS1]] : $FakeRoundtripActorSystem
// CHECK: [[ID:%[0-9]+]] = apply [[ASSIGN_ID_FN]]<MyDistActor>([[SELF_METATYPE]], {{.*}})
// CHECK: strong_release {{.*}} : $FakeRoundtripActorSystem
// *** save identity ***
// CHECK: [[ID_FIELD:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.id
// CHECK: store [[ID]] to [[ID_FIELD]] : $*ActorAddress
// CHECK: copy_addr {{.*}} to [init] [[ID_FIELD]] : $*ActorAddress
// CHECK-NOT: apply
// CHECK: br [[JOIN_PT:bb[0-9]+]]
@@ -68,7 +68,7 @@ distributed actor MyDistActor {
// CHECK: [[TP_FIELD3:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.actorSystem
// CHECK: [[RELOADED_SYS2:%[0-9]+]] = load [[TP_FIELD3]] : $*FakeRoundtripActorSystem
// CHECK: [[READY_FN:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0a9RoundtripC6SystemC10actorReadyyyx0B00bC0RzAA0C7AddressV2IDRtzlF
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]], [[RELOADED_SYS2]])
// CHECK: = apply [[READY_FN]]<MyDistActor>([[SELF]], {{.*}})
// CHECK: return [[SELF]] : $MyDistActor
// CHECK: [[SYSTEM_ERROR_BB]]([[ERROR_ARG:%[0-9]+]] : $any Error):

View File

@@ -2994,7 +2994,7 @@ func callImplAsync_i5(_ impl: ImplAsync, _ b: Bool) async -> (Int, Int, Int, Int
// CHECK: [[SUCCESS]]:
// CHECK: ret { float, float, i64 } { float 1.000000e+00, float 2.000000e+00, i64 undef }
// CHECK: [[FAIL]]:
// CHECK: [[ERROR_RES0:%.*]] = load i64, ptr %.x1._value, align 8
// CHECK: [[ERROR_RES0:%.*]] = call swiftcc i64 @"$s16typed_throws_abi7OneWordVACycfC"()
// CHECK: store ptr inttoptr (i64 1 to ptr), ptr %2, align 8
// CHECK: [[ERROR_RES:%.*]] = insertvalue { float, float, i64 } undef, i64 [[ERROR_RES0]], 2
// CHECK: ret { float, float, i64 } [[ERROR_RES]]
@@ -3049,7 +3049,7 @@ func callNonMatching_f0(_ b: Bool) -> (Int, Float, Float) {
// CHECK: [[SUCCESS]]:
// CHECK: ret { float, i64, float } { float 1.000000e+00, i64 1, float 2.000000e+00 }
// CHECK: [[FAIL]]:
// CHECK: [[ERROR_RES0:%.*]] = load i64, ptr %.x1._value, align 8
// CHECK: [[ERROR_RES0:%.*]] = call swiftcc i64 @"$s16typed_throws_abi7OneWordVACycfC"()
// CHECK: store ptr inttoptr (i64 1 to ptr), ptr %2, align 8
// CHECK: [[ERROR_RES:%.*]] = insertvalue { float, i64, float } undef, i64 [[ERROR_RES0]], 1
// CHECK: ret { float, i64, float } [[ERROR_RES]]
@@ -3108,7 +3108,7 @@ func callNonMatching_f1(_ b: Bool) -> (Int, Float, Bool, Float) {
// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi20nonMatching_f0_asyncySf_SftSbYaAA7OneWordVYKF{{.*}}", ptr {{%.*}}, ptr {{%.*}}, float 1.000000e+00, float 2.000000e+00, i64 undef, ptr null)
// CHECK: unreachable
// CHECK: 18:
// CHECK: [[ERROR_X:%.*]] = load i64, ptr %.x1._value, align 8
// CHECK: [[ERROR_X:%.*]] = call swiftcc i64 @"$s16typed_throws_abi7OneWordVACycfC"()
// CHECK: [[ERROR_RET:%.*]] = insertvalue { float, float, i64 } undef, i64 [[ERROR_X]], 2
// CHECK: [[ERROR_RET0:%.*]] = extractvalue { float, float, i64 } [[ERROR_RET]], 0
// CHECK: [[ERROR_RET1:%.*]] = extractvalue { float, float, i64 } [[ERROR_RET]], 1
@@ -3168,7 +3168,7 @@ func callNonMatching_f0_async(_ b: Bool) async -> (Int, Float, Float) {
// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @"$s16typed_throws_abi20nonMatching_f1_asyncySf_SbSftSbYaAA7OneWordVYKF{{.*}}", ptr {{%.*}}, ptr {{%.*}}, float 1.000000e+00, i64 1, float 2.000000e+00, ptr null)
// CHECK: unreachable
// CHECK: [[ERROR]]:
// CHECK: [[ERROR_X:%.*]] = load i64, ptr %.x1._value, align 8
// CHECK: [[ERROR_X:%.*]] = call swiftcc i64 @"$s16typed_throws_abi7OneWordVACycfC"()
// CHECK: [[ERROR_RET:%.*]] = insertvalue { float, i64, float } undef, i64 [[ERROR_X]], 1
// CHECK: [[ERROR_RET0:%.*]] = extractvalue { float, i64, float } [[ERROR_RET]], 0
// CHECK: [[ERROR_RET1:%.*]] = extractvalue { float, i64, float } [[ERROR_RET]], 1

View File

@@ -16,7 +16,7 @@ public func blackHole<T>(_ _: T) { }
ReferenceCountedTestSuite.test("Local") {
var x = createLocalCount()
#if NO_OPTIMIZATIONS
expectEqual(x.value, 6) // This is 6 because of "var x" "x.value" * 2 and "(x, x, x)".
expectEqual(x.value, 2)
#endif
let t = (x, x, x)

View File

@@ -20,7 +20,7 @@ public func blackHole<T>(_ _: T) { }
func localTest() {
var x = NS.LocalCount.create()
#if NO_OPTIMIZATIONS
expectEqual(x.value, 8) // This is 8 because of "var x" "x.value" * 2, two method calls on x, and "(x, x, x)".
expectEqual(x.value, 2)
#endif
expectEqual(x.returns42(), 42)

View File

@@ -137,8 +137,8 @@ int main() {
}
// CHECK: create NonTrivialTemplate
// CHECK-NEXT: copy NonTrivialTemplate
// CHECK-NEXT: x and y: 1, 2
// CHECK-NEXT: ~NonTrivialTemplate
// CHECK-NEXT: x and y: 1, 2
// CHECK-NEXT: DoneCall
// CHECK-NEXT: ~NonTrivialTemplate
{

View File

@@ -35,10 +35,10 @@ func doSomething() {}
// SIL: [[BOX:%.*]] = alloc_stack [var_decl] $Int, var, name "x"
// SIL: [[INOUT_BOX:%.*]] = alloc_stack [var_decl] $Int, var, name "x2"
// SIL: [[ACCESS:%.*]] = begin_access [modify] [static] [[BOX]]
// SIL: store {{%.*}} to [[INOUT_BOX]]
// SIL: copy_addr [take] [[ACCESS]] to [init] [[INOUT_BOX]]
// SIL: [[FUNC:%.*]] = function_ref @$s18reference_bindings11doSomethingyyF : $@convention(thin) () -> ()
// SIL: apply [[FUNC]]()
// SIL: store {{%.*}} to [[ACCESS]]
// SIL: copy_addr [take] [[INOUT_BOX]] to [init] [[ACCESS]]
// SIL: end_access [[ACCESS]]
// SIL: } // end sil function '$s18reference_bindings13testBindToVaryyF'
func testBindToVar() {
@@ -64,11 +64,9 @@ func testBindToVar() {
// SIL: bb0([[ARG:%.*]] : $*String):
// SIL: [[STACK:%.*]] = alloc_stack [var_decl] $String
// SIL: [[ACCESS:%.*]] = begin_access [modify] [static] [[ARG]]
// SIL: [[VAL:%.*]] = load [[ACCESS]]
// SIL: store [[VAL]] to [[STACK]]
// SIL: copy_addr [take] [[ACCESS]] to [init] [[STACK]]
// SIL: apply {{%.*}}
// SIL: [[VAL:%.*]] = load [[STACK]]
// SIL: store [[VAL]] to [[ACCESS]]
// SIL: copy_addr [take] [[STACK]] to [init] [[ACCESS]]
// SIL: end_access [[ACCESS]]
// SIL: dealloc_stack [[STACK]]
// SIL: } // end sil function '$s18reference_bindings15testBindToInOutyySSzF'

View File

@@ -17,9 +17,8 @@ public struct S {
// CHECK: [[WRITE:%.*]] = begin_access [modify] [static] [[STK]] : $*S
// CHECK: store %{{.*}} to [[WRITE]] : $*S
// CHECK: end_access [[WRITE]]
// CHECK: bb3:
// CHECK: bb3([[RET:%.*]] : $S):
// CHECK: [[READ:%.*]] = begin_access [read] [static] [[STK]] : $*S
// CHECK: [[RET:%.*]] = load [[READ]] : $*S
// CHECK: end_access [[READ]]
// CHECK: destroy_addr [[STK]]
// CHECK: dealloc_stack [[STK]]

View File

@@ -14,7 +14,7 @@
// especially performance inlining as it inlines functions such as String.+=
// that the evaluator has special knowledge about.
//
// RUN: not %target-sil-opt -sil-print-types -opt-mode=speed -silgen-cleanup -diagnose-invalid-escaping-captures -diagnose-static-exclusivity -capture-promotion -access-enforcement-selection -allocbox-to-stack -noreturn-folding -definite-init -raw-sil-inst-lowering -closure-lifetime-fixup -semantic-arc-opts -mandatory-inlining -predictable-memaccess-opts -os-log-optimization -diagnostic-constant-propagation -predictable-deadalloc-elim -mandatory-arc-opts -diagnose-unreachable -diagnose-infinite-recursion -yield-once-check -dataflow-diagnostics -split-non-cond_br-critical-edges -constexpr-limit 3000 -test-constant-evaluable-subset %t/constant_evaluable_subset_test_silgen.sil > /dev/null 2> %t/error-output-mandatory
// RUN: not %target-sil-opt -sil-print-types -opt-mode=speed -silgen-cleanup -diagnose-invalid-escaping-captures -diagnose-static-exclusivity -capture-promotion -access-enforcement-selection -allocbox-to-stack -noreturn-folding -definite-init -raw-sil-inst-lowering -closure-lifetime-fixup -semantic-arc-opts -mandatory-inlining -mandatory-redundant-load-elimination -os-log-optimization -diagnostic-constant-propagation -predictable-deadalloc-elim -mandatory-arc-opts -diagnose-unreachable -diagnose-infinite-recursion -yield-once-check -dataflow-diagnostics -split-non-cond_br-critical-edges -constexpr-limit 3000 -test-constant-evaluable-subset %t/constant_evaluable_subset_test_silgen.sil > /dev/null 2> %t/error-output-mandatory
//
// RUN: %FileCheck %S/Inputs/constant_evaluable.swift < %t/error-output-mandatory

View File

@@ -16,7 +16,7 @@
// especially performance inlining as it inlines functions such as String.+=
// that the evaluator has special knowledge about.
//
// RUN: not %target-sil-opt -silgen-cleanup -diagnose-invalid-escaping-captures -diagnose-static-exclusivity -capture-promotion -access-enforcement-selection -allocbox-to-stack -noreturn-folding -definite-init -raw-sil-inst-lowering -closure-lifetime-fixup -semantic-arc-opts -ownership-model-eliminator -mandatory-inlining -predictable-memaccess-opts -os-log-optimization -diagnostic-constant-propagation -predictable-deadalloc-elim -mandatory-arc-opts -diagnose-unreachable -diagnose-infinite-recursion -yield-once-check -dataflow-diagnostics -split-non-cond_br-critical-edges -constexpr-limit 3000 -test-constant-evaluable-subset %t/constant_evaluable_subset_test_arch64_silgen.sil > /dev/null 2> %t/error-output-mandatory
// RUN: not %target-sil-opt -silgen-cleanup -diagnose-invalid-escaping-captures -diagnose-static-exclusivity -capture-promotion -access-enforcement-selection -allocbox-to-stack -noreturn-folding -definite-init -raw-sil-inst-lowering -closure-lifetime-fixup -semantic-arc-opts -ownership-model-eliminator -mandatory-inlining -mandatory-redundant-load-elimination -os-log-optimization -diagnostic-constant-propagation -predictable-deadalloc-elim -mandatory-arc-opts -diagnose-unreachable -diagnose-infinite-recursion -yield-once-check -dataflow-diagnostics -split-non-cond_br-critical-edges -constexpr-limit 3000 -test-constant-evaluable-subset %t/constant_evaluable_subset_test_arch64_silgen.sil > /dev/null 2> %t/error-output-mandatory
//
// RUN: %FileCheck %s < %t/error-output-mandatory

View File

@@ -188,9 +188,9 @@ actor BoringActor {
// CHECK: store [[INIT2]] to [[SELF_ALLOC]] : $*SingleVarActor
// CHECK-NEXT: hop_to_executor [[INIT2]] : $SingleVarActor
// CHECK: bb3([[T0:%.*]] : $SingleVarActor):
// CHECK: [[ARBITRARY_FN:%.*]] = function_ref @$s4test14arbitraryAsyncyyYaF
// CHECK-NEXT: apply [[ARBITRARY_FN]]()
// CHECK-NEXT: [[T0:%.*]] = load [[SELF_ALLOC]] :
// CHECK-NEXT: strong_retain [[T0]]
// CHECK-NEXT: [[T1:%.*]] = init_existential_ref [[T0]] :
// CHECK-NEXT: [[T2:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[T1]] :

View File

@@ -404,15 +404,16 @@ struct ThrowStruct {
// CHECK: [[SELF_BOX:%.*]] = alloc_stack [var_decl] $ThrowStruct
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers11ThrowStructV6noFailACyt_tcfC
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
// CHECK-NEXT: retain_value [[NEW_SELF]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
// CHECK-NEXT: // function_ref
// CHECK-NEXT: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb1([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: retain_value [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: return [[NEW_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb2([[ERROR:%.*]] : $any Error):
// CHECK: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
@@ -424,32 +425,27 @@ struct ThrowStruct {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers11ThrowStructV27failDuringOrAfterDelegationACSi_tKcfC
// CHECK: bb0(%0 : $Int, %1 : $@thin ThrowStruct.Type):
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowStruct
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers11ThrowStructV4failACyt_tKcfC
// CHECK-NEXT: try_apply [[INIT_FN]](%1)
// CHECK: bb1([[NEW_SELF:.*]] : $ThrowStruct):
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
// CHECK-NEXT: retain_value [[NEW_SELF]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
// CHECK-NEXT: // function_ref
// CHECK-NEXT: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb2([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: retain_value [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[NEW_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb3([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[ZERO]] : $Builtin.Int1)
// CHECK: bb4([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: release_value [[NEW_SELF]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK: bb5([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[BIT]] : $Builtin.Int1)
// CHECK: bb5([[ERROR:%.*]] : $any Error, [[COND:%.*]] : $Builtin.Int1):
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
// CHECK: bb6:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
@@ -458,7 +454,6 @@ struct ThrowStruct {
// CHECK-NEXT: br bb8
// CHECK: bb8:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR]]
init(failDuringOrAfterDelegation: Int) throws {
try self.init(fail: ())
@@ -467,34 +462,29 @@ struct ThrowStruct {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers11ThrowStructV27failBeforeOrAfterDelegationACSi_tKcfC
// CHECK: bb0(%0 : $Int, %1 : $@thin ThrowStruct.Type):
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowStruct
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb1([[RESULT:%.*]] : $Int):
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers11ThrowStructV6noFailACyt_tcfC
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
// CHECK-NEXT: retain_value [[NEW_SELF]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
// CHECK-NEXT: // function_ref
// CHECK-NEXT: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb2([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: retain_value [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[NEW_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb3([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[ZERO]] : $Builtin.Int1)
// CHECK: bb4([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: release_value [[NEW_SELF]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK: bb5([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[BIT]] : $Builtin.Int1)
// CHECK: bb5([[ERROR:%.*]] : $any Error, [[COND:%.*]] : $Builtin.Int1):
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
// CHECK: bb6:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
@@ -503,7 +493,6 @@ struct ThrowStruct {
// CHECK-NEXT: br bb8
// CHECK: bb8:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR]]
init(failBeforeOrAfterDelegation: Int) throws {
try unwrap(failBeforeOrAfterDelegation)
@@ -598,17 +587,17 @@ struct ThrowStruct {
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers11ThrowStructV6noFailACyt_tcfC
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [static] [[SELF_BOX]] : $*ThrowStruct
// CHECK-NEXT: retain_value [[NEW_SELF]]
// CHECK-NEXT: store [[NEW_SELF]] to [[WRITE]]
// CHECK-NEXT: end_access [[WRITE]] : $*ThrowStruct
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb1([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: retain_value [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: return [[NEW_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb2([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: release_value [[NEW_SELF]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: throw [[ERROR]]
@@ -848,13 +837,13 @@ class FailableDerivedClass : FailableBaseClass {
// CHECK: bb0([[SELF:%.*]] : $FailableDerivedClass):
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [var_decl] $FailableDerivedClass
// CHECK: store [[SELF]] to [[SELF_BOX]]
// CHECK: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK: [[CANARY_FUN:%.*]] = function_ref @$s35definite_init_failable_initializers6CanaryCACycfC :
// CHECK: [[CANARY:%.*]] = apply [[CANARY_FUN]](
// CHECK-NEXT: [[MEMBER_ADDR:%.*]] = ref_element_addr [[SELF]]
// CHECK-NEXT: [[MEMBER_ADDR:%.*]] = ref_element_addr [[LD]]
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [init] [static] [[MEMBER_ADDR]] : $*Canary
// CHECK-NEXT: store [[CANARY]] to [[WRITE]]
// CHECK-NEXT: end_access [[WRITE]] : $*Canary
// CHECK-NEXT: strong_release [[SELF]]
// CHECK-NEXT: [[RELOAD_SELF:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: [[BASE_SELF:%.*]] = upcast [[RELOAD_SELF]]
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers17FailableBaseClassC28failBeforeFullInitializationACSgyt_tcfc
@@ -977,10 +966,8 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17ThrowDerivedClassC28failBeforeFullInitialization0h6DuringjK0ACSi_SitKcfc
// CHECK: bb0(%0 : $Int, %1 : $Int, %2 : $ThrowDerivedClass):
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowDerivedClass
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: store %2 to [[SELF_BOX]] : $*ThrowDerivedClass
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
@@ -989,7 +976,6 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: [[BASE_SELF:%.*]] = upcast [[RELOAD_SELF]]
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers14ThrowBaseClassCACyKcfc
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
// CHECK: try_apply [[INIT_FN]]([[BASE_SELF]])
// CHECK: bb2([[NEW_SELF:%.*]] : $ThrowBaseClass):
// CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]]
@@ -997,14 +983,12 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[DERIVED_SELF]]
// CHECK: bb3([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[ZERO]] : $Builtin.Int1)
// CHECK: bb4([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK: bb5([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[BIT]] : $Builtin.Int1)
// CHECK: bb5([[ERROR:%.*]] : $any Error, [[COND:%.*]] : $Builtin.Int1):
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
// CHECK: bb6:
// CHECK-NEXT: br bb8
@@ -1015,7 +999,6 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: br bb8
// CHECK: bb8:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR]]
init(failBeforeFullInitialization: Int, failDuringFullInitialization: Int) throws {
try unwrap(failBeforeFullInitialization)
@@ -1031,16 +1014,16 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers14ThrowBaseClassC6noFailACyt_tcfc
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]]([[BASE_SELF]])
// CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]]
// CHECK-NEXT: strong_retain [[DERIVED_SELF]]
// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb1([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: strong_retain [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: return [[DERIVED_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb2([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: strong_release [[DERIVED_SELF]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: throw [[ERROR]]
@@ -1051,37 +1034,32 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17ThrowDerivedClassC27failAfterFullInitialization0h6DuringjK0ACSi_SitKcfc
// CHECK: bb0(%0 : $Int, %1 : $Int, %2 : $ThrowDerivedClass):
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowDerivedClass
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: store %2 to [[SELF_BOX]]
// CHECK-NEXT: [[RELOAD_SELF:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: [[DERIVED_SELF:%.*]] = upcast [[RELOAD_SELF]]
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers14ThrowBaseClassCACyKcfc
// CHECK: [[BIT1:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK: try_apply [[INIT_FN]]([[DERIVED_SELF]])
// CHECK: bb1([[NEW_SELF:%.*]] : $ThrowBaseClass):
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
// CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]]
// CHECK-NEXT: strong_retain [[DERIVED_SELF]]
// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb2([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: strong_retain [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[DERIVED_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb3([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[BIT1]] : $Builtin.Int2)
// CHECK: bb4([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: strong_release [[DERIVED_SELF]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK: bb5([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[BIT]] : $Builtin.Int2)
// CHECK: bb5([[ERROR:%.*]] : $any Error, [[COND:%.*]] : $Builtin.Int2):
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2)
// CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[COND]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2)
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2)
// CHECK-NEXT: cond_br [[COND]], bb6, bb7
// CHECK: bb6:
@@ -1091,7 +1069,6 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: br bb8
// CHECK: bb8:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR]]
init(failAfterFullInitialization: Int, failDuringFullInitialization: Int) throws {
try super.init()
@@ -1100,43 +1077,35 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17ThrowDerivedClassC28failBeforeFullInitialization0h5AfterjK0ACSi_SitKcfc
// CHECK: bb0(%0 : $Int, %1 : $Int, %2 : $ThrowDerivedClass):
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowDerivedClass
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: store %2 to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb1([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[TWO:%.*]] = integer_literal $Builtin.Int2, -2
// CHECK-NEXT: store [[TWO]] to [[BITMAP_BOX]]
// CHECK-NEXT: [[RELOAD_SELF:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: [[BASE_SELF:%.*]] = upcast [[RELOAD_SELF]]
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers14ThrowBaseClassC6noFailACyt_tcfc
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, -1
// CHECK-NEXT: store [[ONE]] to [[BITMAP_BOX]]
// CHECK: [[NEW_SELF:%.*]] = apply [[INIT_FN]]([[BASE_SELF]])
// CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]]
// CHECK-NEXT: strong_retain [[DERIVED_SELF]]
// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%1)
// CHECK: bb2([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: strong_retain [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[DERIVED_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb3([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[ZERO]] : $Builtin.Int2)
// CHECK: bb4([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: strong_release [[DERIVED_SELF]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK: bb5([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[ONE]] : $Builtin.Int2)
// CHECK: bb5([[ERROR:%.*]] : $any Error, [[BITMAP:%.*]] : $Builtin.Int2):
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP]] : $Builtin.Int2) : $Builtin.Int1
// CHECK-NEXT: cond_br [[COND]], bb6, bb10
// CHECK: bb6:
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK-NEXT: [[SHIFTED:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) : $Builtin.Int2
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[SHIFTED]] : $Builtin.Int2) : $Builtin.Int1
@@ -1155,7 +1124,6 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: br bb11
// CHECK: bb11:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR]] : $any Error
init(failBeforeFullInitialization: Int, failAfterFullInitialization: Int) throws {
try unwrap(failBeforeFullInitialization)
@@ -1165,10 +1133,8 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17ThrowDerivedClassC28failBeforeFullInitialization0h6DuringjK00h5AfterjK0ACSi_S2itKcfc
// CHECK: bb0(%0 : $Int, %1 : $Int, %2 : $Int, %3 : $ThrowDerivedClass):
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowDerivedClass
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: store %3 to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
@@ -1177,34 +1143,29 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: [[BASE_SELF:%.*]] = upcast [[RELOAD_SELF]]
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers14ThrowBaseClassCACyKcfc
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK-NEXT: store [[ONE]] to [[BITMAP_BOX]]
// CHECK: try_apply [[INIT_FN]]([[BASE_SELF]])
// CHECK: bb2([[NEW_SELF:%.*]] : $ThrowBaseClass):
// CHECK-NEXT: [[NEG_ONE:%.*]] = integer_literal $Builtin.Int2, -1
// CHECK-NEXT: store [[NEG_ONE]] to [[BITMAP_BOX]]
// CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]]
// CHECK-NEXT: strong_retain [[DERIVED_SELF]]
// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%2)
// CHECK: bb3([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: strong_retain [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[DERIVED_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb4([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb7([[ERROR]] : $any Error)
// CHECK-NEXT: br bb7([[ERROR]] : $any Error, [[ZERO]] : $Builtin.Int2)
// CHECK: bb5([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb7([[ERROR]] : $any Error)
// CHECK-NEXT: br bb7([[ERROR]] : $any Error, [[ONE]] : $Builtin.Int2)
// CHECK: bb6([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: strong_release [[DERIVED_SELF]]
// CHECK-NEXT: br bb7([[ERROR]] : $any Error)
// CHECK: bb7([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: br bb7([[ERROR]] : $any Error, [[NEG_ONE]] : $Builtin.Int2)
// CHECK: bb7([[ERROR:%.*]] : $any Error, [[BITMAP:%.*]] : $Builtin.Int2):
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP]] : $Builtin.Int2)
// CHECK-NEXT: cond_br [[COND]], bb8, bb12
// CHECK: bb8:
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2)
// CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2)
@@ -1223,7 +1184,6 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: br bb13
// CHECK: bb13:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR]]
init(failBeforeFullInitialization: Int, failDuringFullInitialization: Int, failAfterFullInitialization: Int) throws {
try unwrap(failBeforeFullInitialization)
@@ -1330,16 +1290,16 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [var_decl] $ThrowDerivedClass
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
// CHECK-NEXT: strong_retain [[NEW_SELF]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb1([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: strong_retain [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: return [[NEW_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb2([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: strong_release [[NEW_SELF]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: throw [[ERROR]]
@@ -1350,32 +1310,27 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17ThrowDerivedClassC27failDuringOrAfterDelegationACSi_tKcfC
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
// CHECK: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
// CHECK: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowDerivedClass
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers17ThrowDerivedClassCACyKcfC
// CHECK-NEXT: try_apply [[INIT_FN]](%1)
// CHECK: bb1([[NEW_SELF:%.*]] : $ThrowDerivedClass):
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
// CHECK-NEXT: strong_retain [[NEW_SELF]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb2([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: strong_retain [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[NEW_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb3([[ERROR1:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR1]] : $any Error)
// CHECK-NEXT: br bb5([[ERROR1]] : $any Error, [[ZERO]] : $Builtin.Int1)
// CHECK: bb4([[ERROR2:%.*]] : $any Error):
// CHECK-NEXT: strong_release [[NEW_SELF]]
// CHECK-NEXT: br bb5([[ERROR2]] : $any Error)
// CHECK: bb5([[ERROR3:%.*]] : $any Error):
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
// CHECK: cond_br {{.*}}, bb6, bb7
// CHECK-NEXT: br bb5([[ERROR2]] : $any Error, [[BIT]] : $Builtin.Int1)
// CHECK: bb5([[ERROR3:%.*]] : $any Error, [[COND:%.*]] : $Builtin.Int1):
// CHECK: cond_br [[COND]], bb6, bb7
// CHECK: bb6:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: br bb8
@@ -1383,7 +1338,6 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: br bb8
// CHECK: bb8:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR3]]
convenience init(failDuringOrAfterDelegation: Int) throws {
try self.init()
@@ -1392,34 +1346,29 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17ThrowDerivedClassC27failBeforeOrAfterDelegationACSi_tKcfC
// CHECK: bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
// CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ThrowDerivedClass
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb1([[RESULT:%.*]] : $Int):
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]
// CHECK-NEXT: strong_retain [[NEW_SELF]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
// CHECK: [[UNWRAP_FN:%.*]] = function_ref @$s35definite_init_failable_initializers6unwrapyS2iKF
// CHECK-NEXT: try_apply [[UNWRAP_FN]](%0)
// CHECK: bb2([[RESULT:%.*]] : $Int):
// CHECK-NEXT: [[LD:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: strong_retain [[LD]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: return [[NEW_SELF]]
// CHECK-NEXT: return [[LD]]
// CHECK: bb3([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[ZERO]] : $Builtin.Int1)
// CHECK: bb4([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: strong_release [[NEW_SELF]]
// CHECK-NEXT: br bb5([[ERROR]] : $any Error)
// CHECK: bb5([[ERROR:%.*]] : $any Error):
// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]
// CHECK: cond_br {{.*}}, bb6, bb7
// CHECK-NEXT: br bb5([[ERROR]] : $any Error, [[BIT]] : $Builtin.Int1)
// CHECK: bb5([[ERROR:%.*]] : $any Error, [[COND:%.*]] : $Builtin.Int1):
// CHECK: cond_br [[COND]], bb6, bb7
// CHECK: bb6:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: br bb8
@@ -1427,7 +1376,6 @@ class ThrowDerivedClass : ThrowBaseClass {
// CHECK-NEXT: br bb8
// CHECK: bb8:
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]
// CHECK-NEXT: throw [[ERROR]]
convenience init(failBeforeOrAfterDelegation: Int) throws {
try unwrap(failBeforeOrAfterDelegation)

View File

@@ -46,18 +46,17 @@ class Cat : FakeNSObject {
// CHECK: bb0([[ARG0:%.*]] : $Int, [[ARG1:%.*]] : $Bool, [[ARG2:%.*]] : $Cat):
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [var_decl] $Cat
// CHECK: store [[ARG2]] to [[SELF_BOX]] : $*Cat
// CHECK: [[FIELD_ADDR:%.*]] = ref_element_addr [[ARG2]] : $Cat, #Cat.x
// CHECK: [[FIELD_ADDR:%.*]] = ref_element_addr {{.*}} : $Cat, #Cat.x
// CHECK-NEXT: store {{%.*}} to [[FIELD_ADDR]] : $*LifetimeTracked
// CHECK-NEXT: strong_release [[ARG2]]
// CHECK-NEXT: [[COND:%.*]] = struct_extract %1 : $Bool, #Bool._value
// CHECK-NEXT: cond_br [[COND]], bb1, bb2
// CHECK: bb1:
// CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr [[ARG2]] : $Cat, #Cat.x
// CHECK-NEXT: [[LD:%.*]] = load {{.*}} : $*Cat
// CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr [[LD]] : $Cat, #Cat.x
// CHECK-NEXT: [[FIELD_ADDR_ACCESS:%.*]] = begin_access [deinit] [static] [[FIELD_ADDR]]
// CHECK-NEXT: destroy_addr [[FIELD_ADDR_ACCESS]] : $*LifetimeTracked
// CHECK-NEXT: end_access [[FIELD_ADDR_ACCESS]]
// CHECK-NEXT: strong_release [[ARG2]]
// CHECK-NEXT: [[RELOAD_FROM_BOX:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick Cat.Type
// CHECK-NEXT: dealloc_partial_ref [[RELOAD_FROM_BOX]] : $Cat, [[METATYPE]] : $@thick Cat.Type
@@ -66,7 +65,6 @@ class Cat : FakeNSObject {
// CHECK-NEXT: br bb3([[RESULT]] : $Optional<Cat>)
// CHECK: bb2:
// CHECK-NEXT: strong_release [[ARG2]]
// CHECK-NEXT: [[RELOAD_ARG2:%.*]] = load [[SELF_BOX]]
// CHECK-NEXT: [[SUPER:%.*]] = upcast [[RELOAD_ARG2]] : $Cat to $FakeNSObject
// CHECK-NEXT: [[SUB:%.*]] = unchecked_ref_cast [[RELOAD_ARG2]] : $Cat to $Cat
@@ -102,7 +100,6 @@ class Cat : FakeNSObject {
// CHECK-LABEL: sil hidden @$s40definite_init_failable_initializers_objc3CatC4fail5afterACSgSb_Sbtcfc : $@convention(method) (Bool, Bool, @owned Cat) -> @owned Optional<Cat>
// CHECK: bb0([[ARG0:%.*]] : $Bool, [[ARG1:%.*]] : $Bool, [[ARG2:%.*]] : $Cat):
// CHECK-NEXT: [[HAS_RUN_INIT_BOX:%.+]] = alloc_stack $Builtin.Int1
// CHECK-NEXT: [[SELF_BOX:%.+]] = alloc_stack [dynamic_lifetime] [var_decl] $Cat
// CHECK: store [[ARG2]] to [[SELF_BOX]] : $*Cat
// CHECK-NEXT: [[COND:%.+]] = struct_extract [[ARG0]] : $Bool, #Bool._value
@@ -132,8 +129,7 @@ class Cat : FakeNSObject {
// CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
// CHECK-NEXT: br [[RESULT_BRANCH:bb[0-9]+]]([[RESULT]] : $Optional<Cat>)
// CHECK: [[ERROR_BRANCH]]:
// CHECK-NEXT: [[COND:%.+]] = load [[HAS_RUN_INIT_BOX]] : $*Builtin.Int1
// CHECK: [[ERROR_BRANCH]]([[COND:%.*]] : $Builtin.Int1):
// CHECK-NEXT: cond_br [[COND]], [[ERROR_WITHOUT_DESTROY_BRANCH:bb[0-9]+]], [[ERROR_WITH_DESTROY_BRANCH:bb[0-9]+]]
// CHECK: [[ERROR_WITHOUT_DESTROY_BRANCH]]:
@@ -151,7 +147,6 @@ class Cat : FakeNSObject {
// CHECK-NEXT: br [[RESULT_BRANCH]]([[NIL_RESULT]] : $Optional<Cat>)
// CHECK: [[RESULT_BRANCH]]([[RESULT:%.+]] : $Optional<Cat>):
// CHECK-NEXT: dealloc_stack [[HAS_RUN_INIT_BOX]] : $*Builtin.Int1
// CHECK-NEXT: return [[RESULT]] : $Optional<Cat>
// CHECK: end sil function '$s40definite_init_failable_initializers_objc3CatC4fail5afterACSgSb_Sbtcfc'

View File

@@ -31,4 +31,6 @@ extension Person {
// Verify that the DI instructions share the scope of the adjacent instructions.
// CHECK: sil {{.*}}$s28definite_init_nsmanagedvalue6PersonCyACSiKcfc
// CHECK: integer_literal $Builtin.Int2, {{.*}}, scope [[SCOPE:[0-9]+]]
// CHECK-NEXT: debug_value
// CHECK-NEXT: debug_value
// CHECK-NEXT: store {{.*}}, scope [[SCOPE]]

View File

@@ -13,10 +13,8 @@ class FirstClass {
// CHECK-LABEL: sil hidden @$s24definite_init_root_class10FirstClassC1nACSgs5Int32V_tcfc : $@convention(method) (Int32, @owned FirstClass) -> @owned Optional<FirstClass>
init?(n: Int32) {
// CHECK: [[CONTROL:%.*]] = alloc_stack $Builtin.Int1
// CHECK: [[EI:%.*]] = end_init_let_ref %1
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK: store [[ZERO]] to [[CONTROL]] : $*Builtin.Int1
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
// CHECK: [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
@@ -36,7 +34,6 @@ class FirstClass {
// CHECK: [[X_ADDR:%.*]] = ref_element_addr [[EI]] : $FirstClass, #FirstClass.x
// CHECK: [[X_ACCESS:%.*]] = begin_access [init] [static] [[X_ADDR]] : $*OtherClass
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK: store [[ONE]] to [[CONTROL]] : $*Builtin.Int1
// CHECK: store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
// CHECK: end_access [[X_ACCESS]] : $*OtherClass
x = OtherClass()
@@ -56,8 +53,7 @@ class FirstClass {
// CHECK: [[RESULT:%.*]] = enum $Optional<FirstClass>, #Optional.some!enumelt, [[EI]] : $FirstClass
// CHECK: br bb12([[RESULT]] : $Optional<FirstClass>)
// CHECK: bb5:
// CHECK: [[BIT:%.*]] = load [[CONTROL]] : $*Builtin.Int1
// CHECK: bb5([[BIT:%.*]] : $Builtin.Int1):
// CHECK: cond_br [[BIT]], bb6, bb7
// CHECK: bb6:
@@ -65,7 +61,6 @@ class FirstClass {
// CHECK: br bb11
// CHECK: bb7:
// CHECK: [[BIT:%.*]] = load [[CONTROL]] : $*Builtin.Int1
// CHECK: cond_br [[BIT]], bb8, bb9
// CHECK: bb8:
@@ -87,7 +82,6 @@ class FirstClass {
// CHECK: br bb12([[NIL]] : $Optional<FirstClass>)
// CHECK: bb12([[RESULT:%.*]] : $Optional<FirstClass>):
// CHECK: dealloc_stack [[CONTROL]] : $*Builtin.Int1
// CHECK: return [[RESULT]] : $Optional<FirstClass>
}
}
@@ -98,10 +92,8 @@ class SecondClass {
// CHECK-LABEL: sil hidden @$s24definite_init_root_class11SecondClassC1nACSgs5Int32V_tcfc : $@convention(method) (Int32, @owned SecondClass) -> @owned Optional<SecondClass> {
init?(n: Int32) {
// CHECK: [[CONTROL:%.*]] = alloc_stack $Builtin.Int2
// CHECK: [[EI:%.*]] = end_init_let_ref %1
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
// CHECK: store [[ZERO]] to [[CONTROL]] : $*Builtin.Int2
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
// CHECK: [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
@@ -121,7 +113,6 @@ class SecondClass {
// CHECK: [[X_ADDR:%.*]] = ref_element_addr [[EI]] : $SecondClass, #SecondClass.x
// CHECK: [[X_ACCESS:%.*]] = begin_access [init] [static] [[X_ADDR]] : $*OtherClass
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK: store [[ONE]] to [[CONTROL]] : $*Builtin.Int2
// CHECK: store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
// CHECK: end_access [[X_ACCESS]] : $*OtherClass
x = OtherClass()
@@ -144,7 +135,6 @@ class SecondClass {
// CHECK: [[Y_ADDR:%.*]] = ref_element_addr [[EI]] : $SecondClass, #SecondClass.y
// CHECK: [[Y_ACCESS:%.*]] = begin_access [init] [static] [[Y_ADDR]] : $*OtherClass
// CHECK: [[THREE:%.*]] = integer_literal $Builtin.Int2, -1
// CHECK: store [[THREE]] to [[CONTROL]] : $*Builtin.Int2
// CHECK: store [[OTHER]] to [[Y_ACCESS]] : $*OtherClass
// CHECK: end_access [[Y_ACCESS]] : $*OtherClass
y = OtherClass()
@@ -164,8 +154,7 @@ class SecondClass {
// CHECK: [[RESULT:%.*]] = enum $Optional<SecondClass>, #Optional.some!enumelt, [[EI]] : $SecondClass
// CHECK: br bb17([[RESULT]] : $Optional<SecondClass>)
// CHECK: bb7:
// CHECK: [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
// CHECK: bb7([[BITS:%.*]] : $Builtin.Int2):
// CHECK: [[THREE:%.*]] = integer_literal $Builtin.Int2, -1
// CHECK: [[BIT:%.*]] = builtin "cmp_eq_Int2"([[BITS]] : $Builtin.Int2, [[THREE]] : $Builtin.Int2) : $Builtin.Int1
// CHECK: cond_br [[BIT]], bb8, bb9
@@ -175,7 +164,6 @@ class SecondClass {
// CHECK: br bb16
// CHECK: bb9:
// CHECK: [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
// CHECK: [[BIT:%.*]] = builtin "trunc_Int2_Int1"([[BITS]] : $Builtin.Int2) : $Builtin.Int1
// CHECK: cond_br [[BIT]], bb10, bb11
@@ -190,7 +178,6 @@ class SecondClass {
// CHECK: br bb12
// CHECK: bb12:
// CHECK: [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK: [[TMP:%.*]] = builtin "lshr_Int2"([[BITS]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) : $Builtin.Int2
// CHECK: [[BIT:%.*]] = builtin "trunc_Int2_Int1"([[TMP]] : $Builtin.Int2) : $Builtin.Int1
@@ -216,7 +203,6 @@ class SecondClass {
// CHECK: br bb17([[NIL]] : $Optional<SecondClass>)
// CHECK: bb17([[RESULT:%.*]] : $Optional<SecondClass>):
// CHECK: dealloc_stack [[CONTROL]] : $*Builtin.Int2
// CHECK: return [[RESULT]] : $Optional<SecondClass>
}
}

View File

@@ -30,26 +30,22 @@ enum ValueEnum {
// CHECK-LABEL: sil hidden @$s25definite_init_value_types9ValueEnumO1xACSb_tcfC : $@convention(method) (Bool, @thin ValueEnum.Type) -> @owned ValueEnum
// CHECK: bb0(%0 : $Bool, %1 : $@thin ValueEnum.Type):
// CHECK-NEXT: [[STATE:%.*]] = alloc_stack $Builtin.Int1
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack [dynamic_lifetime] [var_decl] $ValueEnum
// CHECK-NEXT: [[INIT_STATE:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: store [[INIT_STATE]] to [[STATE]]
// CHECK: [[BOOL:%.*]] = struct_extract %0 : $Bool, #Bool._value
// CHECK-NEXT: cond_br [[BOOL]], bb1, bb2
// CHECK: bb1:
// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.b!enumelt
// CHECK-NEXT: [[SELF_ACCESS:%.*]] = begin_access [modify] [static] [[SELF_BOX]]
// CHECK-NEXT: [[NEW_STATE:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: store [[NEW_STATE]] to [[STATE]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_ACCESS]]
// CHECK-NEXT: end_access [[SELF_ACCESS]]
// CHECK-NEXT: br bb3
// CHECK: bb2:
// CHECK-NEXT: br bb3
// CHECK: bb3:
// CHECK: bb3([[STATE_VALUE:%.*]] : $Builtin.Int1):
// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $ValueEnum, #ValueEnum.c!enumelt
// CHECK-NEXT: [[SELF_ACCESS:%.*]] = begin_access [modify] [static] [[SELF_BOX]]
// CHECK-NEXT: [[STATE_VALUE:%.*]] = load [[STATE]]
// CHECK-NEXT: cond_br [[STATE_VALUE]], bb4, bb5
// CHECK: bb4:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
@@ -57,13 +53,10 @@ enum ValueEnum {
// CHECK: bb5:
// CHECK-NEXT: br bb6
// CHECK: bb6:
// CHECK-NEXT: [[NEW_STATE:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: store [[NEW_STATE]] to [[STATE]]
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_ACCESS]]
// CHECK-NEXT: end_access [[SELF_ACCESS]]
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[STATE]]
// CHECK-NEXT: return [[NEW_SELF]]
init(x: Bool) {
if x {

View File

@@ -67,7 +67,7 @@ class C {
// CHECK: [[A:%.*]] = ref_element_addr %1 : $C, #C.a
// CHECK: store {{.*}} to [[A]] : $*Int
// CHECK: [[EI:%.*]] = end_init_let_ref %1
// CHECK: bb1:
// CHECK: bb1({{.*}} : $Builtin.Int2):
// CHECK: ref_element_addr [[EI]] : $C, #C.b
// CHECK: return [[EI]]
// CHECK: } // end sil function '$s4test1CC1cACSb_tcfc'
@@ -173,7 +173,7 @@ class D : C {
// CHECK-LABEL: sil hidden @$s4test1DCACycfc :
// CHECK-NOT: end_init_let_ref
// CHECK: ref_element_addr %0 : $D, #D.c
// CHECK: ref_element_addr %{{[0-9]+}} : $D, #D.c
// CHECK-NOT: end_init_let_ref
// CHECK: } // end sil function '$s4test1DCACycfc'
override init() {

View File

@@ -44,9 +44,8 @@ public struct Concrete : Thrower {
// CHECK-LABEL: sil @$s4test6calleryyAA8ConcreteVKF : $@convention(thin) (Concrete) -> @error any Error
public func caller(_ c: Concrete) throws {
// CHECK: [[ARG:%.*]] = struct $Concrete ()
// CHECK: [[FN:%.*]] = function_ref @$s4test8ConcreteV4failyyKF : $@convention(method) (Concrete) -> @error any Error
// CHECK: try_apply [[FN]]([[ARG]]) : $@convention(method) (Concrete) -> @error any Error
// CHECK: try_apply [[FN]](%0) : $@convention(method) (Concrete) -> @error any Error
try callee(c)
}

View File

@@ -45,7 +45,7 @@ package struct PkgStruct {
// CHECK: store {{.*}} to [trivial] [[FIELD1_IVAR]] : $*Int
// CHECK: [[FIELD2_IVAR:%.*]] = struct_element_addr [[PKG_INIT]] : $*PkgStruct, #PkgStruct.field2
// CHECK: store {{.*}} to [trivial] [[FIELD2_IVAR]] : $*Int
// CHECK: [[PKG_STR:%.*]] = struct $PkgStruct
// CHECK: [[PKG_STR:%.*]] = load [trivial] [[PKG_INIT]]
// CHECK: store [[PKG_STR]] to [trivial] [[PKG_ALLOC]] : $*PkgStruct
// CHECK: [[FIELD1:%.*]] = struct_element_addr [[PKG_ALLOC]] : $*PkgStruct, #PkgStruct.field1
// CHECK: load [trivial] [[FIELD1]] : $*Int

View File

@@ -1,8 +1,7 @@
// RUN: %target-swift-frontend -module-name pointer_conversion -Xllvm -sil-print-types -emit-sil -O %s | %FileCheck %s
// REQUIRES: optimized_stdlib
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
// REQUIRES: objc_interop
// REQUIRES: swift_stdlib_asserts
// Opaque, unoptimizable functions to call.
@_silgen_name("takesConstRawPointer")
@@ -29,12 +28,6 @@ public func testOptionalArray() {
// CHECK: switch_enum {{.*}}, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
// CHECK: [[SOME_BB]](
// CHECK: cond_br {{%.*}}, {{bb[0-9]+}}, [[CHECK_BB:bb[0-9]+]]
// CHECK: [[CHECK_BB]]:
// CHECK: cond_br {{%.*}}, [[CHECK_BB_2:bb[0-9]+]], {{bb[0-9]+}}
// CHECK: [[CHECK_BB_2]]:
// CHECK: [[ORIGINAL_OWNER:%.*]] = unchecked_ref_cast {{%.*}} : $Builtin.BridgeObject to $__ContiguousArrayStorageBase
// CHECK: [[ORIGINAL_OWNER_EXISTENTIAL:%.*]] = init_existential_ref [[ORIGINAL_OWNER]]
// CHECK: [[OWNER:%.+]] = enum $Optional<AnyObject>, #Optional.some!enumelt, [[ORIGINAL_OWNER_EXISTENTIAL]]

View File

@@ -94,11 +94,11 @@ func test_topLevelEvaluation(topLevelArgument: Int) {
var topLevelVar = 1 // expected-warning {{never mutated}}
#assert(topLevelVar == 1)
// expected-note @+1 {{cannot evaluate top-level value as constant here}}
var topLevelVarConditionallyMutated = 1
if topLevelVarConditionallyMutated < 0 {
if topLevelArgument < 0 {
topLevelVarConditionallyMutated += 1
}
// expected-note @+2 {{cannot evaluate expression as constant here}}
// expected-error @+1 {{#assert condition not constant}}
#assert(topLevelVarConditionallyMutated == 1)

View File

@@ -1,4 +1,4 @@
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -update-borrowed-from -predictable-memaccess-opts -predictable-deadalloc-elim | %FileCheck %s
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -update-borrowed-from -mandatory-redundant-load-elimination -predictable-deadalloc-elim | %FileCheck %s
sil_stage raw
@@ -21,11 +21,6 @@ struct SomeClassPair {
// Eliminate the load [copy]
// Update the mark_dependence base to the available value.
//
// FIXME: This creates an extra copy in order to promote a load to a copy_value.
// Fix predictable memopts so it never introduces new copies.
// A copy_value should only be introduced if the corresponding store can be
// eliminated.
//
// TODO: box promotion is unsupported:
// - Eliminate the allocation and store
// - Update the mark_dependence base to the available value
@@ -33,8 +28,7 @@ struct SomeClassPair {
// CHECK-LABEL: sil [ossa] @markdep_base_promote_box : $@convention(thin) (@owned SomeClass, UnsafeMutablePointer<Int>) -> @owned SomeClass {
// CHECK: [[ST:%.*]] = copy_value %0 : $SomeClass
// CHECK: store %0 to [init]
// CHECK: [[LD:%.*]] = copy_value [[ST]] : $SomeClass
// CHECK: return [[LD]]
// CHECK: return [[ST]]
// CHECK-LABEL: } // end sil function 'markdep_base_promote_box'
sil [ossa] @markdep_base_promote_box : $@convention(thin) (@owned SomeClass, UnsafeMutablePointer<Int>) -> @owned SomeClass {
bb0(%0 : @owned $SomeClass, %1 : $UnsafeMutablePointer<Int>):
@@ -60,10 +54,8 @@ bb0(%0 : @owned $SomeClass, %1 : $UnsafeMutablePointer<Int>):
// CHECK-LABEL: sil [ossa] @markdep_base_promote_stack : $@convention(thin) (@owned SomeClass, UnsafeMutablePointer<Int>) -> @owned SomeClass {
// CHECK: [[ST:%.*]] = copy_value %0 : $SomeClass
// CHECK: [[MD:%.*]] = mark_dependence %1 : $UnsafeMutablePointer<Int> on %0 : $SomeClass
// CHECK: [[LD:%.*]] = copy_value [[ST]] : $SomeClass
// CHECK: destroy_value [[ST]] : $SomeClass
// CHECK: struct_extract [[MD]] : $UnsafeMutablePointer<Int>, #UnsafeMutablePointer._rawValue
// CHECK: return [[LD]] : $SomeClass
// CHECK: return [[ST]] : $SomeClass
// CHECK-LABEL: } // end sil function 'markdep_base_promote_stack'
sil [ossa] @markdep_base_promote_stack : $@convention(thin) (@owned SomeClass, UnsafeMutablePointer<Int>) -> @owned SomeClass {
bb0(%0 : @owned $SomeClass, %1 : $UnsafeMutablePointer<Int>):
@@ -118,10 +110,8 @@ bb0(%0 : $Int, %1 : $UnsafeMutablePointer<Int>):
// CHECK: [[CP1:%.*]] = copy_value %0 : $SomeClass
// CHECK: store %0 to [init]
// CHECK: [[MD:%.*]] = mark_dependence [[CP1]] : $SomeClass on %1 : $SomeClass
// CHECK: [[CP2:%.*]] = copy_value [[MD]] : $SomeClass
// CHECK: destroy_value [[MD]] : $SomeClass
// CHECK: destroy_value %{{.*}} : $<τ_0_0> { var τ_0_0 } <SomeClass>
// CHECK: return [[CP2]] : $SomeClass
// CHECK: return [[MD]] : $SomeClass
// CHECK-LABEL: } // end sil function 'markdep_source_promote_box'
sil [ossa] @markdep_source_promote_box : $@convention(thin) (@owned SomeClass, @guaranteed SomeClass) -> @owned SomeClass {
bb0(%0 : @owned $SomeClass, %1 : @guaranteed $SomeClass):
@@ -141,11 +131,10 @@ bb0(%0 : @owned $SomeClass, %1 : @guaranteed $SomeClass):
//
// CHECK-LABEL: sil [ossa] @markdep_source_promote_stack : $@convention(thin) (@owned SomeClass, @guaranteed SomeClass) -> @owned SomeClass {
// CHECK: [[CP1:%.*]] = copy_value %0 : $SomeClass
// CHECK: [[MD_OLD:%.*]] = mark_dependence %0 : $SomeClass on %1 : $SomeClass
// CHECK: [[MD:%.*]] = mark_dependence [[CP1]] : $SomeClass on %1 : $SomeClass
// CHECK: [[CP2:%.*]] = copy_value [[MD]] : $SomeClass
// CHECK: destroy_value [[MD]] : $SomeClass
// CHECK: destroy_value %0 : $SomeClass
// CHECK: return [[CP2]] : $SomeClass
// CHECK: destroy_value [[MD_OLD]] : $SomeClass
// CHECK: return [[MD]] : $SomeClass
// CHECK-LABEL: } // end sil function 'markdep_source_promote_stack'
sil [ossa] @markdep_source_promote_stack: $@convention(thin) (@owned SomeClass, @guaranteed SomeClass) -> @owned SomeClass {
bb0(%0 : @owned $SomeClass, %1 : @guaranteed $SomeClass):
@@ -246,10 +235,8 @@ bb0(%0 : @owned $SomeClass, %1 : $UnsafeMutablePointer<Int>):
// CHECK: [[CP1:%.*]] = copy_value %0 : $SomeClass
// CHECK: store %0 to [init]
// CHECK: [[MD:%.*]] = mark_dependence [[CP1]] : $SomeClass on %1 : $SomeClass
// CHECK: [[CP2:%.*]] = copy_value [[MD]] : $SomeClass
// CHECK: destroy_value [[MD]] : $SomeClass
// CHECK: destroy_value %{{.*}} : $<τ_0_0> { var τ_0_0 } <SomeClass>
// CHECK: destroy_value [[CP2]] : $SomeClass
// CHECK: destroy_value [[MD]] : $SomeClass
// CHECK-LABEL: } // end sil function 'markdep_source_dead_box'
sil [ossa] @markdep_source_dead_box : $@convention(thin) (@owned SomeClass, @guaranteed SomeClass) -> () {
bb0(%0 : @owned $SomeClass, %1 : @guaranteed $SomeClass):
@@ -271,11 +258,10 @@ bb0(%0 : @owned $SomeClass, %1 : @guaranteed $SomeClass):
// CHECK-LABEL: sil [ossa] @markdep_source_dead_stack : $@convention(thin) (@owned SomeClass, @guaranteed SomeClass) -> () {
// CHECK: bb0(%0 : @owned $SomeClass, %1 : @guaranteed $SomeClass):
// CHECK-NEXT: [[CP1:%.*]] = copy_value %0 : $SomeClass
// CHECK-NEXT: [[MD_OLD:%.*]] = mark_dependence %0 : $SomeClass on %1 : $SomeClass
// CHECK-NEXT: [[MD:%.*]] = mark_dependence [[CP1]] : $SomeClass on %1 : $SomeClass
// CHECK-NEXT: [[CP2:%.*]] = copy_value [[MD]] : $SomeClass
// CHECK-NEXT: destroy_value [[MD_OLD]] : $SomeClass
// CHECK-NEXT: destroy_value [[MD]] : $SomeClass
// CHECK-NEXT: destroy_value %0 : $SomeClass
// CHECK-NEXT: destroy_value [[CP2]] : $SomeClass
// CHECK-LABEL: } // end sil function 'markdep_source_dead_stack'
sil [ossa] @markdep_source_dead_stack: $@convention(thin) (@owned SomeClass, @guaranteed SomeClass) -> () {
bb0(%0 : @owned $SomeClass, %1 : @guaranteed $SomeClass):
@@ -362,16 +348,20 @@ bb0(%0 : @owned $SomeClass, %1 : @owned $SomeClass, %2 : @guaranteed $SomeClass)
// Test mark_dependence source: load from dependent phi value.
//
// TODO: Phis are not handled by load promotion.
//
// CHECK-LABEL: sil [ossa] @markdep_source_load_phi : $@convention(thin) (@guaranteed SomeClass) -> () {
// CHECK: bb0(%0 : @guaranteed $SomeClass):
// CHECK: [[ALLOC:%.*]] = alloc_stack $SomeClass
// CHECK: [[MD:%.*]] = mark_dependence [[ALLOC]] : $*SomeClass on %0 : $SomeClass
// CHECK: [[LD:%.*]] = load [copy] [[MD]] : $*SomeClass
// CHECK: destroy_addr %1 : $*SomeClass
// CHECK-LABEL: sil [ossa] @markdep_source_load_phi :
// CHECK: bb0(%0 : @guaranteed $SomeClass):
// CHECK-NEXT: [[CP0:%.*]] = copy_value %0 : $SomeClass
// CHECK: bb1:
// CHECK-NEXT: [[CP1:%.*]] = copy_value [[CP0]]
// CHECK-NEXT: br bb3([[CP1]] : $SomeClass)
// CHECK: bb2:
// CHECK-NEXT: [[CP2:%.*]] = copy_value [[CP0]]
// CHECK-NEXT: br bb3([[CP2]] : $SomeClass)
// CHECK: bb3([[PHI:%.*]] : @owned $SomeClass):
// CHECK: [[MD:%.*]] = mark_dependence [[PHI]] : $SomeClass on %0 : $SomeClass
// CHECK: return [[MD]]
// CHECK-LABEL: } // end sil function 'markdep_source_load_phi'
sil [ossa] @markdep_source_load_phi : $@convention(thin) (@guaranteed SomeClass) -> () {
sil [ossa] @markdep_source_load_phi : $@convention(thin) (@guaranteed SomeClass) -> @owned SomeClass {
bb0(%0 : @guaranteed $SomeClass):
%1 = alloc_stack $SomeClass
%copy = copy_value %0 : $SomeClass
@@ -388,11 +378,9 @@ bb2:
bb3:
%md = mark_dependence %1 : $*SomeClass on %0 : $SomeClass
%ld = load [copy] %md : $*SomeClass
destroy_value %ld : $SomeClass
destroy_addr %1 : $*SomeClass
dealloc_stack %1 : $*SomeClass
%9999 = tuple()
return %9999 : $()
return %ld : $SomeClass
}
// Test mark_dependence source: dead dependent phi.

View File

@@ -14,8 +14,6 @@ public func main() {
// CHECK-SAME: loc {{.*}}:11:10, scope [[S:[0-9]+]]
// CHECK-NEXT: %[[I:.*]] = struct_extract %[[A]]
// CHECK-SAME: loc {{.*}}:11:10, scope [[S]]
// CHECK-NEXT: struct_extract %[[I]]
// CHECK-SAME: loc {{.*}}:11:10, scope [[S]]
// CHECK: store %[[A]] to %0 : $*MyStruct,
// CHECK-SAME: loc {{.*}}:11:10, scope [[S]]
use(a.a)

View File

@@ -1,4 +1,4 @@
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -update-borrowed-from -predictable-memaccess-opts -predictable-deadalloc-elim | %FileCheck %s
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -update-borrowed-from -mandatory-redundant-load-elimination -predictable-deadalloc-elim | %FileCheck %s
sil_stage raw
@@ -146,8 +146,8 @@ bb0(%1 : $Int):
store %1 to [trivial] %0a : $*Int // CHECK: store
// In an escape region, we should not promote loads.
%r = load [trivial] %0a : $*Int // CHECK: load
%r = load [trivial] %0a : $*Int
// CHECK: return %0
return %r : $Int
}
@@ -216,12 +216,8 @@ bb0(%0 : @owned $ContainsNativeObject):
// CHECK: [[f3:%.*]] = struct_extract [[BORROWED_ARG]] : $ComplexStruct, #ComplexStruct.f1
// CHECK: [[f3_copy:%.*]] = copy_value [[f3]]
// CHECK: end_borrow [[BORROWED_ARG]]
// CHECK: [[f3_copy_1:%.*]] = copy_value [[f3_copy]]
// CHECK: [[f3_copy_2:%.*]] = copy_value [[f3_copy_1]]
// CHECK: [[f2_x_copy_1:%.*]] = copy_value [[f2_x_copy]]
// CHECK: [[f2_x_copy_2:%.*]] = copy_value [[f2_x_copy_1]]
// CHECK: destroy_value [[ARG]]
// CHECK: [[RESULT:%.*]] = tuple ([[f3_copy_2]] : $Builtin.NativeObject, [[f2_x_copy_2]] : $Builtin.NativeObject, [[f1]] : $Builtin.Int32)
// CHECK: [[RESULT:%.*]] = tuple ([[f3_copy]] : $Builtin.NativeObject, [[f2_x_copy]] : $Builtin.NativeObject, [[f1]] : $Builtin.Int32)
// CHECK: return [[RESULT]]
// CHECK: } // end sil function 'multiple_level_extract_2'
sil [ossa] @multiple_level_extract_2 : $@convention(thin) (@owned ComplexStruct) -> (@owned Builtin.NativeObject, @owned Builtin.NativeObject, Builtin.Int32) {
@@ -248,21 +244,24 @@ bb0(%0 : @owned $ComplexStruct):
var int_global : Int
// CHECK-LABEL: sil [ossa] @promote_alloc_stack
// CHECK: [[IL:%.*]] = integer_literal
// CHECK: [[I:%.*]] = struct $Int32 ([[IL]] : $Builtin.Int32)
// CHECK-NOT: alloc_stack
// CHECK: [[E:%.*]] = struct_extract [[I]]
// CHECK: return [[E]]
// CHECK: } // end sil function 'promote_alloc_stack'
sil [ossa] @promote_alloc_stack : $@convention(thin) (Int32) -> Builtin.Int32 {
bb0(%0 : $Int32):
%5 = integer_literal $Builtin.Int32, 1
// CHECK: [[IL:%[0-9]+]] = integer_literal
%18 = struct $Int32 (%5 : $Builtin.Int32)
%22 = alloc_stack $Int32
// CHECK-NOT: alloc_stack
store %18 to [trivial] %22 : $*Int32
%24 = struct_element_addr %22 : $*Int32, #Int32._value
%25 = load [trivial] %24 : $*Builtin.Int32
dealloc_stack %22 : $*Int32
// CHECK-NEXT: return [[IL]]
return %25 : $Builtin.Int32
}
@@ -430,39 +429,35 @@ bb0:
}
// <rdar://problem/17755462> Predictable memory opts removes refcount operation
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @dead_allocation_1
sil [ossa] @dead_allocation_1 : $@convention(thin) (@owned Optional<AnyObject>) -> () {
bb0(%0 : @owned $Optional<AnyObject>):
// CHECK-NOT: alloc_stack
%1 = alloc_stack $Optional<AnyObject>
%2 = alloc_stack $Optional<AnyObject>
store %0 to [init] %2 : $*Optional<AnyObject>
// CHECK-NOT: copy_addr
copy_addr %2 to [init] %1 : $*Optional<AnyObject>
destroy_addr %2 : $*Optional<AnyObject>
dealloc_stack %2 : $*Optional<AnyObject>
destroy_addr %1 : $*Optional<AnyObject>
dealloc_stack %1 : $*Optional<AnyObject>
// CHECK: destroy_value %0
%3 = tuple ()
return %3 : $()
}
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @dead_allocation_2
sil [ossa] @dead_allocation_2 : $@convention(thin) (@owned Optional<AnyObject>) -> () {
bb0(%0 : @owned $Optional<AnyObject>):
// CHECK-NOT: alloc_stack
%1 = alloc_stack $Optional<AnyObject>
%2 = alloc_stack $Optional<AnyObject>
store %0 to [init] %1 : $*Optional<AnyObject>
// CHECK-NOT: copy_addr
copy_addr %1 to [init] %2 : $*Optional<AnyObject>
destroy_addr %2 : $*Optional<AnyObject>
dealloc_stack %2 : $*Optional<AnyObject>
destroy_addr %1 : $*Optional<AnyObject>
dealloc_stack %1 : $*Optional<AnyObject>
%3 = tuple ()
// CHECK: destroy_value %0
return %3 : $()
}
@@ -557,32 +552,13 @@ bb3:
// This test makes sure that we insert the tuple_extracts that we need before
// the store in bb0, not at the load block.
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @diamond_test_2 : $@convention(thin) (@owned NativeObjectPair) -> @owned Builtin.NativeObject {
// CHECK: bb0([[ARG:%.*]] : @owned $NativeObjectPair):
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK: [[LHS1:%.*]] = struct_extract [[BORROWED_ARG]] : $NativeObjectPair, #NativeObjectPair.x
// CHECK: [[LHS1_COPY:%.*]] = copy_value [[LHS1]]
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK: [[LHS2:%.*]] = struct_extract [[BORROWED_ARG]] : $NativeObjectPair, #NativeObjectPair.x
// CHECK: [[LHS2_COPY:%.*]] = copy_value [[LHS2]]
// CHECK: cond_br undef, bb1, bb2
//
// CHECK: bb1:
// CHECK: destroy_value [[LHS1_COPY]]
// CHECK: [[LHS2_COPY_1:%.*]] = copy_value [[LHS2_COPY]]
// CHECK: [[LHS2_COPY_2:%.*]] = copy_value [[LHS2_COPY_1]]
// CHECK: br bb3([[LHS2_COPY_2]] :
//
// CHECK: bb2:
// CHECK: destroy_value [[LHS2_COPY]] : $Builtin.NativeObject
// CHECK: [[LHS1_COPY_1:%.*]] = copy_value [[LHS1_COPY]]
// CHECK: [[LHS1_COPY_2:%.*]] = copy_value [[LHS1_COPY_1]]
// CHECK: br bb3([[LHS1_COPY_2]] :
//
// CHECK: bb3([[PHI:%.*]] :
// CHECK: destroy_value [[ARG]]
// CHECK: return [[PHI]]
// CHECK: } // end sil function 'diamond_test_2'
// CHECK: bb1:
// CHECK: load [copy]
// CHECK: bb2:
// CHECK: load [copy]
// CHECK: } // end sil function 'diamond_test_2'
sil [ossa] @diamond_test_2 : $@convention(thin) (@owned NativeObjectPair) -> @owned Builtin.NativeObject {
bb0(%0 : @owned $NativeObjectPair):
%1 = alloc_stack $NativeObjectPair
@@ -606,12 +582,14 @@ bb3(%6 : @owned $Builtin.NativeObject):
}
// We should be able to promote all memory operations here.
// TODO: this is currently not optimized
//
// CHECK-LABEL: sil [ossa] @diamond_test_3 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
// CHECK-NOT: alloc_stack
// CHECK-NOT: load
// CHECK-NOT: store
// CHECK: } // end sil function 'diamond_test_3'
// CHECK: bb1:
// CHECK: load [copy]
// CHECK: bb2:
// CHECK: load [copy]
// CHECK: } // end sil function 'diamond_test_3'
sil [ossa] @diamond_test_3 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
%2 = alloc_stack $NativeObjectPair
@@ -663,11 +641,9 @@ struct NativeObjectTriple {
// CHECK-NEXT: br bb3([[PAIR_LHS_COPY]] :
//
// CHECK: bb3([[PHI:%.*]] : @owned $Builtin.NativeObject):
// CHECK: [[PHI_COPY_1:%.*]] = copy_value [[PHI]]
// CHECK: [[PHI_COPY_2:%.*]] = copy_value [[PHI_COPY_1]]
// CHECK: [[REFORMED:%.*]] = struct $NativeObjectTriple ([[ARG0]] : {{.*}}, [[ARG1]] : {{.*}})
// CHECK: destroy_value [[REFORMED]]
// CHECK: return [[PHI_COPY_2]]
// CHECK: return [[PHI]]
// CHECK: } // end sil function 'diamond_test_4'
sil [ossa] @diamond_test_4 : $@convention(thin) (@owned Builtin.NativeObject, @owned NativeObjectPair) -> @owned Builtin.NativeObject {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $NativeObjectPair):
@@ -699,42 +675,12 @@ bb3:
// Make sure that we do the right thing if our definite init value is partially
// overridden along one path
// TODO: this is currently not optimized
//
// CHECK-LABEL: sil [ossa] @diamond_test_5 : $@convention(thin) (@owned Builtin.NativeObject, @owned NativeObjectPair, @owned Builtin.NativeObject) -> @owned NativeObjectPair {
// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $NativeObjectPair, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
// CHECK: [[BOX:%.*]] = alloc_stack $NativeObjectTriple
// CHECK: br bb1
//
// CHECK: bb1:
// CHECK: [[TRIPLE_LHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f1
// CHECK: [[TRIPLE_RHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f2
// CHECK: store [[ARG0]] to [init] [[TRIPLE_LHS]]
// CHECK: [[BORROWED_ARG1:%.*]] = begin_borrow [[ARG1]]
// CHECK: [[BORROWED_TRIPLE_RHS_RHS_VAL:%.*]] = struct_extract [[BORROWED_ARG1]] : $NativeObjectPair, #NativeObjectPair.y
// CHECK: [[TRIPLE_RHS_RHS_VAL:%.*]] = copy_value [[BORROWED_TRIPLE_RHS_RHS_VAL]]
// CHECK: store [[ARG1]] to [init] [[TRIPLE_RHS]]
// CHECK: cond_br undef, bb2, bb3
//
// CHECK: bb2:
// CHECK: [[TRIPLE_RHS_LHS:%.*]] = struct_element_addr [[TRIPLE_RHS]]
// CHECK: store [[ARG2]] to [assign] [[TRIPLE_RHS_LHS]]
// CHECK: br bb4
//
// CHECK: bb3:
// CHECK: br bb4
//
// CHECK: bb4:
// CHECK: [[TRIPLE_RHS_LHS:%.*]] = struct_element_addr [[TRIPLE_RHS]] : $*NativeObjectPair, #NativeObjectPair.x
// CHECK: [[TRIPLE_RHS_LHS_VAL:%.*]] = load [copy] [[TRIPLE_RHS_LHS]] : $*Builtin.NativeObject
// CHECK: [[TRIPLE_RHS_RHS_VAL_COPY:%.*]] = copy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK: [[TRIPLE_RHS_LHS_VAL_BORROW:%.*]] = begin_borrow [[TRIPLE_RHS_LHS_VAL]]
// CHECK: [[TRIPLE_RHS_RHS_VAL_COPY_BORROW:%.*]] = begin_borrow [[TRIPLE_RHS_RHS_VAL_COPY]]
// CHECK: [[STRUCT:%.*]] = struct $NativeObjectPair ([[TRIPLE_RHS_LHS_VAL_BORROW]] : {{.*}}, [[TRIPLE_RHS_RHS_VAL_COPY_BORROW]] : {{.*}})
// CHECK: [[STRUCT_COPY:%.*]] = copy_value [[STRUCT]]
// CHECK: [[STRUCT_COPY_2:%.*]] = copy_value [[STRUCT_COPY]]
// CHECK: destroy_addr [[BOX]]
// CHECK: return [[STRUCT_COPY_2]]
// CHECK: } // end sil function 'diamond_test_5'
// CHECK: bb4:
// CHECK: load [copy]
// CHECK: } // end sil function 'diamond_test_5'
sil [ossa] @diamond_test_5 : $@convention(thin) (@owned Builtin.NativeObject, @owned NativeObjectPair, @owned Builtin.NativeObject) -> @owned NativeObjectPair {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $NativeObjectPair, %arg2 : @owned $Builtin.NativeObject):
%2 = alloc_stack $NativeObjectTriple
@@ -763,74 +709,11 @@ bb4:
return %13 : $NativeObjectPair
}
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @diamond_test_6 : $@convention(thin) (@owned Builtin.NativeObject, @owned NativeObjectPair, @owned Builtin.NativeObject) -> @owned NativeObjectPair {
// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $NativeObjectPair, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
// CHECK: [[BOX:%.*]] = alloc_stack $NativeObjectTriple
// CHECK: cond_br undef, [[TRUE_BB:bb[0-9]+]], [[FALSE_BB:bb[0-9]+]]
//
// CHECK: [[TRUE_BB]]:
// CHECK: [[TRIPLE_LHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f1
// CHECK: [[TRIPLE_RHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f2
// CHECK: store [[ARG0]] to [init] [[TRIPLE_LHS]]
// CHECK: [[BORROWED_ARG1:%.*]] = begin_borrow [[ARG1]]
// CHECK: [[BORROWED_TRIPLE_RHS_RHS_VAL:%.*]] = struct_extract [[BORROWED_ARG1]] : $NativeObjectPair, #NativeObjectPair.y
// CHECK: [[TRIPLE_RHS_RHS_VAL:%.*]] = copy_value [[BORROWED_TRIPLE_RHS_RHS_VAL]]
// CHECK: store [[ARG1]] to [init] [[TRIPLE_RHS]]
// CHECK: cond_br undef, [[CRITEDGE_BREAK_BB_1:bb[0-9]+]], [[CRITEDGE_BREAK_BB_2:bb[0-9]+]]
//
// CHECK: [[CRITEDGE_BREAK_BB_1]]:
// CHECK-NEXT: [[TRIPLE_RHS_RHS_VAL_COPY:%.*]] = copy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: destroy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: br [[SUCC_2:bb[0-9]+]]([[TRIPLE_RHS_RHS_VAL_COPY]] :
//
// CHECK: [[CRITEDGE_BREAK_BB_2]]:
// CHECK-NEXT: [[TRIPLE_RHS_RHS_VAL_COPY:%.*]] = copy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: destroy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: br [[SUCC_1:bb[0-9]+]]([[TRIPLE_RHS_RHS_VAL_COPY]] :
//
// CHECK: [[FALSE_BB]]:
// CHECK: [[TRIPLE_LHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f1
// CHECK: [[TRIPLE_RHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f2
// CHECK: store [[ARG0]] to [init] [[TRIPLE_LHS]]
// CHECK: [[BORROWED_ARG1:%.*]] = begin_borrow [[ARG1]]
// CHECK: [[BORROWED_TRIPLE_RHS_RHS_VAL:%.*]] = struct_extract [[BORROWED_ARG1]] : $NativeObjectPair, #NativeObjectPair.y
// CHECK: [[TRIPLE_RHS_RHS_VAL:%.*]] = copy_value [[BORROWED_TRIPLE_RHS_RHS_VAL]]
// CHECK: store [[ARG1]] to [init] [[TRIPLE_RHS]]
// CHECK: cond_br undef, [[CRITEDGE_BREAK_BB_1:bb[0-9]+]], [[CRITEDGE_BREAK_BB_2:bb[0-9]+]]
//
// CHECK: [[CRITEDGE_BREAK_BB_1]]:
// CHECK-NEXT: [[TRIPLE_RHS_RHS_VAL_COPY:%.*]] = copy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: destroy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: br [[SUCC_2]]([[TRIPLE_RHS_RHS_VAL_COPY]] :
//
// CHECK: [[CRITEDGE_BREAK_BB_2]]:
// CHECK-NEXT: [[TRIPLE_RHS_RHS_VAL_COPY:%.*]] = copy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: destroy_value [[TRIPLE_RHS_RHS_VAL]]
// CHECK-NEXT: br [[SUCC_1]]([[TRIPLE_RHS_RHS_VAL_COPY]] :
//
// CHECK: [[SUCC_2]]([[PHI1:%.*]] : @owned $Builtin.NativeObject):
// CHECK: [[TRIPLE_RHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f2
// CHECK: [[TRIPLE_RHS_LHS:%.*]] = struct_element_addr [[TRIPLE_RHS]]
// CHECK: store [[ARG2]] to [assign] [[TRIPLE_RHS_LHS]]
// CHECK: br [[EXIT_BB:bb[0-9]+]]([[PHI1:%.*]] : $Builtin.NativeObject)
//
// CHECK: [[SUCC_1]]([[PHI:%.*]] : @owned $Builtin.NativeObject):
// CHECK: [[PHI_COPY:%.*]] = copy_value [[PHI]]
// CHECK: br [[EXIT_BB]]([[PHI_COPY]] : {{.*}})
//
// CHECK: [[EXIT_BB]]([[PHI:%.*]] : @owned $Builtin.NativeObject):
// CHECK: [[TRIPLE_RHS:%.*]] = struct_element_addr [[BOX]] : $*NativeObjectTriple, #NativeObjectTriple.f2
// CHECK: [[TRIPLE_RHS_LHS:%.*]] = struct_element_addr [[TRIPLE_RHS]] : $*NativeObjectPair, #NativeObjectPair.x
// CHECK: [[TRIPLE_RHS_LHS_VAL:%.*]] = load [copy] [[TRIPLE_RHS_LHS]] : $*Builtin.NativeObject
// CHECK: [[PHI_COPY:%.*]] = copy_value [[PHI]]
// CHECK: [[TRIPLE_RHS_LHS_VAL_BORROW:%.*]] = begin_borrow [[TRIPLE_RHS_LHS_VAL]]
// CHECK: [[PHI_COPY_BORROW:%.*]] = begin_borrow [[PHI_COPY]]
// CHECK: [[STRUCT:%.*]] = struct $NativeObjectPair ([[TRIPLE_RHS_LHS_VAL_BORROW]] : {{.*}}, [[PHI_COPY_BORROW]] : {{.*}})
// CHECK: [[STRUCT_COPY_1:%.*]] = copy_value [[STRUCT]]
// CHECK: [[STRUCT_COPY_2:%.*]] = copy_value [[STRUCT_COPY_1]]
// CHECK: destroy_addr [[BOX]]
// CHECK: return [[STRUCT_COPY_2]]
// CHECK: } // end sil function 'diamond_test_6'
// CHECK: bb9:
// CHECK: load [copy]
// CHECK: } // end sil function 'diamond_test_6'
sil [ossa] @diamond_test_6 : $@convention(thin) (@owned Builtin.NativeObject, @owned NativeObjectPair, @owned Builtin.NativeObject) -> @owned NativeObjectPair {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $NativeObjectPair, %arg2 : @owned $Builtin.NativeObject):
%2 = alloc_stack $NativeObjectTriple
@@ -1027,9 +910,10 @@ bb0(%0 : @owned $NativeObjectPair, %1 : @owned $Builtin.NativeObject):
}
// Loop case.
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @promote_with_loop_1 : $@convention(thin) (@owned NativeObjectPair) -> () {
// CHECK-NOT: load [copy]
// CHECK: } // end sil function 'promote_with_loop_1'
// CHECK: load [copy]
// CHECK: } // end sil function 'promote_with_loop_1'
sil [ossa] @promote_with_loop_1 : $@convention(thin) (@owned NativeObjectPair) -> () {
bb0(%0 : @owned $NativeObjectPair):
%1 = alloc_stack $NativeObjectPair
@@ -1045,9 +929,10 @@ bb2:
br bb2
}
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @promote_with_loop_2 : $@convention(thin) (@owned NativeObjectPair) -> () {
// CHECK-NOT: load [copy]
// CHECK: } // end sil function 'promote_with_loop_2'
// CHECK: load [copy]
// CHECK: } // end sil function 'promote_with_loop_2'
sil [ossa] @promote_with_loop_2 : $@convention(thin) (@owned NativeObjectPair) -> () {
bb0(%0 : @owned $NativeObjectPair):
%1 = alloc_stack $NativeObjectPair
@@ -1072,9 +957,13 @@ bb4:
return %9999 : $()
}
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @two_backedge_loop : $@convention(thin) (@owned Builtin.NativeObject) -> () {
// CHECK-NOT: load [copy]
// CHECK: } // end sil function 'two_backedge_loop'
// CHECK: bb3:
// CHECK: load [copy]
// CHECK: bb4:
// CHECK: load [copy]
// CHECK: } // end sil function 'two_backedge_loop'
sil [ossa] @two_backedge_loop : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = alloc_stack $Builtin.NativeObject
@@ -1116,14 +1005,13 @@ bb9:
return %9999 : $()
}
// Make sure that we can eliminate the allocation and all loads. The key here is
// that we are verifying that we first eliminate load [copy] and treat the load
// [take] as part of the destroy_addr optimization.
//
// TODO: this is currently not optimized
// CHECK-LABEL: sil [ossa] @two_backedge_loop_with_take : $@convention(thin) (@owned Builtin.NativeObject) -> () {
// CHECK-NOT: alloc_stack
// CHECK-NOT: load
// CHECK: } // end sil function 'two_backedge_loop_with_take'
// CHECK: bb3:
// CHECK: load [copy]
// CHECK: bb4:
// CHECK: load [copy]
// CHECK: } // end sil function 'two_backedge_loop_with_take'
sil [ossa] @two_backedge_loop_with_take : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = alloc_stack $Builtin.NativeObject