@@ -690,3 +690,118 @@ bb_unwind:
690690 unwind
691691
692692}
693+
694+ sil [ossa] [transparent] @simplest_in_guaranteed : $@yield_once @convention(thin) () -> @yields @in_guaranteed () {
695+ entry:
696+ %tuple = tuple ()
697+ %addr = alloc_stack $()
698+ store %tuple to [trivial] %addr : $*()
699+ yield %addr : $*(), resume resume_block, unwind unwind_block
700+
701+ resume_block:
702+ dealloc_stack %addr : $*()
703+ %retval = tuple ()
704+ return %retval : $()
705+
706+ unwind_block:
707+ dealloc_stack %addr : $*()
708+ unwind
709+ }
710+
711+ // CHECK-LABEL: sil [ossa] @ends_1 : {{.*}} {
712+ // CHECK: [[VOID:%[^,]+]] = tuple ()
713+ // CHECK: [[ADDR:%[^,]+]] = alloc_stack $()
714+ // CHECK: store [[VOID]] to [trivial] [[ADDR]]
715+ // CHECK: cond_br undef, [[GOOD:bb[0-9]+]], [[BAD:bb[0-9]+]]
716+ // CHECK: [[GOOD]]:
717+ // CHECK: dealloc_stack [[ADDR]]
718+ // CHECK: br [[EXIT:bb[0-9]+]]
719+ // CHECK: [[BAD]]:
720+ // CHECK: cond_br undef, [[NORMAL_BAD:bb[0-9]+]], [[REALLY_BAD:bb[0-9]+]]
721+ // CHECK: [[NORMAL_BAD]]:
722+ // CHECK: dealloc_stack [[ADDR]]
723+ // CHECK: br [[EXIT]]
724+ // CHECK: [[REALLY_BAD]]:
725+ // CHECK: unreachable
726+ // CHECK: [[EXIT]]:
727+ // CHECK-LABEL: } // end sil function 'ends_1'
728+ sil [ossa] @ends_1 : $@convention(thin) () -> () {
729+ entry:
730+ %simplest = function_ref @simplest_in_guaranteed : $@yield_once @convention(thin) () -> @yields @in_guaranteed ()
731+ (%_, %token) = begin_apply %simplest() : $@yield_once @convention(thin) () -> @yields @in_guaranteed ()
732+ cond_br undef, good, bad
733+
734+ good:
735+ end_apply %token as $()
736+ br exit
737+
738+ bad:
739+ cond_br undef, normal_bad, really_bad
740+
741+ normal_bad:
742+ abort_apply %token
743+ br exit
744+
745+ really_bad:
746+ end_borrow %token : $Builtin.SILToken
747+ unreachable
748+
749+ exit:
750+ %retval = tuple ()
751+ return %retval : $()
752+ }
753+
754+ // Test handling for multiple end_borrows of a token.
755+ // CHECK-LABEL: sil [ossa] @ends_2 : {{.*}} {
756+ // CHECK: [[VOID:%[^,]+]] = tuple ()
757+ // CHECK: [[ADDR:%[^,]+]] = alloc_stack $()
758+ // CHECK: store [[VOID]] to [trivial] [[ADDR]] : $*()
759+ // CHECK: cond_br undef, [[GOOD:bb[0-9]+]], [[BAD:bb[0-9]+]]
760+ // CHECK: [[GOOD]]:
761+ // CHECK: dealloc_stack [[ADDR]]
762+ // CHECK: br [[EXIT:bb[0-9]+]]
763+ // CHECK: [[BAD]]:
764+ // CHECK: cond_br undef, [[NORMAL_BAD:bb[0-9]+]], [[REALLY_BAD:bb[0-9]+]]
765+ // CHECK: [[NORMAL_BAD]]:
766+ // CHECK: dealloc_stack [[ADDR]]
767+ // CHECK: br [[EXIT]]
768+ // CHECK: [[REALLY_BAD]]:
769+ // CHECK: cond_br undef, [[BAD_NEWS_BUNNIES:bb[0-9]+]], [[BAD_NEWS_BEARS:bb[0-9]+]]
770+ // CHECK: [[BAD_NEWS_BUNNIES]]:
771+ // CHECK: unreachable
772+ // CHECK: [[BAD_NEWS_BEARS]]:
773+ // CHECK: unreachable
774+ // CHECK: [[EXIT]]:
775+ // CHECK-LABEL: } // end sil function 'ends_2'
776+ sil [ossa] @ends_2 : $@convention(thin) () -> () {
777+ entry:
778+ %simplest = function_ref @simplest_in_guaranteed : $@yield_once @convention(thin) () -> @yields @in_guaranteed ()
779+ (%_, %token) = begin_apply %simplest() : $@yield_once @convention(thin) () -> @yields @in_guaranteed ()
780+ cond_br undef, good, bad
781+
782+ good:
783+ end_apply %token as $()
784+ br exit
785+
786+ bad:
787+ cond_br undef, normal_bad, really_bad
788+
789+ normal_bad:
790+ abort_apply %token
791+ br exit
792+
793+ really_bad:
794+ cond_br undef, bad_news_bunnies, bad_news_bears
795+
796+ bad_news_bunnies:
797+ end_borrow %token : $Builtin.SILToken
798+ unreachable
799+
800+ bad_news_bears:
801+ end_borrow %token : $Builtin.SILToken
802+ unreachable
803+
804+ exit:
805+ %retval = tuple ()
806+ return %retval : $()
807+ }
0 commit comments