Skip to content

Commit 017a2c7

Browse files
committed
CheckedCastBrJumpThreading test cases.
1 parent 04aa16f commit 017a2c7

File tree

1 file changed

+242
-28
lines changed

1 file changed

+242
-28
lines changed

test/SILOptimizer/simplify_cfg_checkcast.sil

Lines changed: 242 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// RUN: %target-sil-opt -enable-sil-verify-all %s -jumpthread-simplify-cfg -enable-ossa-simplify-cfg -enable-ossa-rewriteterminator | %FileCheck %s
22
// RUN: %target-sil-opt -enable-sil-verify-all %s -jumpthread-simplify-cfg -enable-ossa-simplify-cfg -enable-ossa-rewriteterminator -debug-only=sil-simplify-cfg 2>&1 | %FileCheck %s --check-prefix=CHECK-TRACE
3-
//
4-
// REQUIRES: EnableOSSASimplifyCFG
53

64
// FIXME: When OSSA optimization is complete, convert XCHECK to CHECK lines
75

86
// FIXME: which of these tests actually require -jumpthread-simplify-cfg instead of -simplify-cfg?
97

8+
// FIXME_rauw: revisit these fixme's after the OwnershipRAUW utility is rewritten in terms of OwnershipLiveness.
9+
1010
sil_stage canonical
1111

1212
import Builtin
@@ -46,6 +46,8 @@ class Final : Derived {
4646
sil [ossa] @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
4747
sil [ossa] @_TFC3ccb4Base6middlefS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
4848

49+
sil @get_base : $@convention(thin) () -> @owned Base
50+
4951
// CHECK-LABEL: sil [ossa] @redundant_checked_cast_br
5052
sil [ossa] @redundant_checked_cast_br : $@convention(method) (@guaranteed Base) -> () {
5153
bb0(%0 : @guaranteed $Base):
@@ -62,7 +64,7 @@ bb1:
6264
bb2(%5 : @guaranteed $Base):
6365
// CHECK: [[SUCCESS]]
6466
%7 = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
65-
// XCHECK-NOT: checked_cast_br
67+
// CHECK-NOT: checked_cast_br
6668
checked_cast_br [exact] %0 : $Base to Base, bb3, bb5
6769
// CHECK: [[INNER:%.*]] = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
6870
// CHECK: apply [[INNER]]
@@ -109,9 +111,10 @@ bb1:
109111
return %3 : $()
110112

111113
// CHECK: [[SUCCESS]]([[SUCCESSARG:%.*]] : @owned $Base)
112-
// XCHECK-NOT: checked_cast_br
113-
// XCHECK: [[INNER:%.*]] = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
114-
// XCHECK: apply [[INNER]]([[SUCCESSARG]])
114+
// CHECK-NOT: checked_cast_br
115+
// CHECK: [[SUCCESSCOPY:%.*]] = copy_value [[SUCCESSARG]] : $Base
116+
// CHECK: [[INNER:%.*]] = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
117+
// CHECK: apply [[INNER]]([[SUCCESSCOPY]])
115118
// CHECK: br bb1
116119
bb2(%5 : @owned $Base):
117120
%7 = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
@@ -206,8 +209,8 @@ bb2(%5 : @guaranteed $Base):
206209
// CHECK: [[SUCCESS]]([[SUCCESSARG:%.*]] : @guaranteed $Base)
207210
// CHECK: [[METHOD2:%.*]] = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
208211
%7 = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
209-
// XCHECK-NOT: checked_cast_br [exact] %0 : $Base to Derived
210-
// XCHECK: apply [[METHOD2]]([[SUCCESSARG]])
212+
// CHECK-NOT: checked_cast_br [exact] %0 : $Base to Derived
213+
// CHECK: apply [[METHOD2]]([[SUCCESSARG]])
211214
// Check that checked_cast_br [exact] was replaced by a branch to the failure BB of the checked_cast_br.
212215
// This is because bb2 is reached via the success branch of the checked_cast_br [exact] from bb0.
213216
// It means that the exact dynamic type of %0 is $Base. Thus it cannot be $Derived.
@@ -252,8 +255,8 @@ bb1:
252255

253256
// CHECK: [[SUCCESS]]([[SUCCESSARG:%.*]] : @owned $Base)
254257
// CHECK: [[METHOD2:%.*]] = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
255-
// XCHECK-NOT: checked_cast_br [exact] %0 : $Base to Derived
256-
// XCHECK: apply [[METHOD2]]([[SUCCESSARG]])
258+
// CHECK-NOT: checked_cast_br [exact] %0 : $Base to Derived
259+
// CHECK: apply [[METHOD2]]([[SUCCESSARG]])
257260
// Check that checked_cast_br [exact] was replaced by a branch to the failure BB of the checked_cast_br.
258261
// This is because bb2 is reached via the success branch of the checked_cast_br [exact] from bb0.
259262
// It means that the exact dynamic type of %0 is $Base. Thus it cannot be $Derived.
@@ -324,16 +327,16 @@ bb5(%2a : @guaranteed $Base):
324327
br bb6
325328

326329
bb6:
330+
dealloc_ref %a : $Base
327331
dealloc_stack_ref %a : $Base
328332
%r = tuple()
329333
return %r : $()
330334
}
331335

332336
// Test a redundant checked_cast_br that has success, failure paths, and unknown paths.
333337
//
334-
// TODO: this is currently a bailout.
335-
//
336-
//!!! CHECKME
338+
// TODO: this is currently a bailout because the CFG transform can't handle it:
339+
// (!SuccessPreds.empty() && !FailurePreds.empty() && numUnknownPreds > 0)
337340
sil [ossa] @redundant_checked_cast_br_joined_success_fail_unknown : $@convention(method) (@guaranteed Base) -> () {
338341
bb0(%0 : @guaranteed $Base):
339342
%middle = class_method %0 : $Base, #Base.middle : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
@@ -344,26 +347,22 @@ bb1(%successBB0 : @guaranteed $Base):
344347

345348
bb2:
346349
%successBB0call2 = apply %middle(%successBB0) : $@convention(method) (@guaranteed Base) -> ()
347-
%successBB0borrow2 = begin_borrow %successBB0 : $Base
348-
br bb8(%successBB0borrow2 : $Base)
350+
br bb8(%successBB0 : $Base)
349351

350352
bb3:
351353
%successBB0call3 = apply %middle(%successBB0) : $@convention(method) (@guaranteed Base) -> ()
352-
%successBB0borrow3 = begin_borrow %successBB0 : $Base
353-
br bb7(%successBB0borrow3 : $Base)
354+
br bb7(%successBB0 : $Base)
354355

355356
bb4(%failBB0 : @guaranteed $Base):
356357
cond_br undef, bb5, bb6
357358

358359
bb5:
359360
%failBB0call5 = apply %middle(%failBB0) : $@convention(method) (@guaranteed Base) -> ()
360-
%failBB0borrow5 = begin_borrow %failBB0 : $Base
361-
br bb7(%failBB0borrow5 : $Base)
361+
br bb7(%failBB0 : $Base)
362362

363363
bb6:
364364
%failBB0call6 = apply %middle(%failBB0) : $@convention(method) (@guaranteed Base) -> ()
365-
%failBB0borrow6 = begin_borrow %failBB0 : $Base
366-
br bb8(%failBB0borrow6 : $Base)
365+
br bb8(%failBB0 : $Base)
367366

368367
bb7(%unknown : @guaranteed $Base):
369368
%unknownCall = apply %middle(%unknown) : $@convention(method) (@guaranteed Base) -> ()
@@ -391,9 +390,11 @@ bb11:
391390
// Verify that checked-cast jump-threading kicks in and generates verifiable SIL.
392391
//
393392
// CHECK-TRACE-LABEL: ### Run SimplifyCFG on $testCheckCastJumpThread
394-
// XCHECK-TRACE: Condition is the same if reached over {{.*}} parent @$testCheckCastJumpThread : $@convention(thin) (@guaranteed Klass) -> @owned OtherKlass }
395-
// XCHECK-TRACE-NEXT: bb3(%{{.*}} : $OtherKlass):
396-
// XCHECK-TRACE-NEXT: br bb5(%{{.*}} : $Klass)
393+
// CHECK-TRACE: Condition is the same if reached over {{.*}} parent @$testCheckCastJumpThread : $@convention(thin) (@guaranteed Klass) -> @owned any OtherKlass }
394+
// CHECK-TRACE-NEXT: // %{{.*}} user:
395+
// CHECK-TRACE-NEXT: bb1(%{{.*}} : @owned $any OtherKlass):
396+
// CHECK-TRACE-NEXT: destroy_value
397+
// CHECK-TRACE-NEXT: br bb5(%{{.*}} : $Klass)
397398
sil shared [ossa] @$testCheckCastJumpThread : $@convention(thin) (@guaranteed Klass) -> @owned OtherKlass {
398399
bb0(%0 : @guaranteed $Klass):
399400
%1 = function_ref @get_klass : $@convention(thin) () -> @owned Klass
@@ -402,7 +403,7 @@ bb0(%0 : @guaranteed $Klass):
402403
%4 = copy_value %3 : $Klass
403404
checked_cast_br %3 : $Klass to OtherKlass, bb1, bb2
404405

405-
bb1(%5 : $OtherKlass):
406+
bb1(%5 : @owned $OtherKlass):
406407
destroy_value %5 : $OtherKlass
407408
%6 = integer_literal $Builtin.Int1, -1
408409
br bb3(%6 : $Builtin.Int1)
@@ -428,19 +429,20 @@ bb6:
428429
bb7(%16 : @owned $Klass):
429430
checked_cast_br %16 : $Klass to OtherKlass, bb9, bb8
430431

431-
bb8(%18 : $Klass):
432+
bb8(%18 : @owned $Klass):
432433
destroy_value %18 : $Klass
433434
br bb4
434435

435-
bb9(%20 : $OtherKlass):
436+
bb9(%20 : @owned $OtherKlass):
436437
return %20 : $OtherKlass
437438

438439
bb10(%22 : $Builtin.Int64):
439440
%23 = apply %1() : $@convention(thin) () -> @owned Klass
440441
%24 = copy_value %23 : $Klass
441442
checked_cast_br %23 : $Klass to OtherKlass, bb11, bb12
442443

443-
bb11(%25 : $OtherKlass):
444+
bb11(%25 : @owned $OtherKlass):
445+
destroy_value %25 : $OtherKlass
444446
%26 = integer_literal $Builtin.Int1, -1
445447
br bb13(%26 : $Builtin.Int1)
446448

@@ -465,3 +467,215 @@ bb16:
465467
bb17:
466468
br bb10(undef : $Builtin.Int64)
467469
}
470+
471+
// =============================================================================
472+
// Test OSSA lifetime fixup after removing redundant checked_cast_br
473+
474+
// Replace an owned result with a guaranteed value on the success path.
475+
// Introduce a copy for the new lifetime.
476+
//
477+
// CHECK-LABEL: sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_success : $@convention(method) (@owned Base) -> () {
478+
// CHECK: bb0(%0 : @owned $Base):
479+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base
480+
// CHECK: checked_cast_br [exact] [[BORROW]] : $Base to Base, bb1, bb2
481+
// CHECK: bb1([[EXACT:%.*]] : @guaranteed $Base):
482+
// CHECK-NEXT: [[NEWCP:%.*]] = copy_value [[EXACT]] : $Base
483+
// CHECK-NEXT: [[OLDCP:%.*]] = copy_value [[EXACT]] : $Base
484+
// CHECK-NEXT: end_borrow
485+
// CHECK: destroy_value [[OLDCP]] : $Base
486+
// CHECK: apply %{{.*}}([[NEWCP]]) : $@convention(method) (@guaranteed Base) -> ()
487+
// CHECK: destroy_value [[NEWCP]] : $Base
488+
// CHECK: br bb3
489+
// CHECK: bb2([[INEXACT:%.*]] : @guaranteed $Base):
490+
// CHECK: apply %{{.*}}([[INEXACT]]) : $@convention(method) (@guaranteed Base) -> ()
491+
// CHECK: end_borrow %1 : $Base
492+
// CHECK: br bb3
493+
// CHECK: bb3:
494+
// CHECK: destroy_value %0 : $Base
495+
// CHECK-LABEL: } // end sil function 'redundant_checked_cast_br_rauw_guaranteed_to_owned_success'
496+
sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_success : $@convention(method) (@owned Base) -> () {
497+
bb0(%0 : @owned $Base):
498+
%borrow = begin_borrow %0 : $Base
499+
%1 = class_method %0 : $Base, #Base.middle : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
500+
checked_cast_br [exact] %borrow : $Base to Base, bb1, bb6
501+
502+
bb1(%5 : @guaranteed $Base):
503+
%6 = copy_value %5 : $Base
504+
end_borrow %borrow : $Base
505+
%7 = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
506+
checked_cast_br [exact] %6 : $Base to Base, bb2, bb4
507+
508+
bb2(%9 : @owned $Base):
509+
%10 = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
510+
%11 = apply %10(%9) : $@convention(method) (@guaranteed Base) -> ()
511+
destroy_value %9 : $Base
512+
br bb3
513+
514+
bb3:
515+
%13 = tuple ()
516+
br bb5(%13 : $())
517+
518+
bb4(%defaultBB2 : @owned $Base):
519+
%15 = apply %7(%defaultBB2) : $@convention(method) (@guaranteed Base) -> ()
520+
destroy_value %defaultBB2 : $Base
521+
br bb3
522+
523+
bb5(%17 : $()):
524+
br bb7
525+
526+
bb6(%defaultBB0 : @guaranteed $Base):
527+
%19 = apply %1(%defaultBB0) : $@convention(method) (@guaranteed Base) -> ()
528+
end_borrow %borrow : $Base
529+
br bb7
530+
531+
bb7:
532+
destroy_value %0 : $Base
533+
%3 = tuple ()
534+
return %3 : $()
535+
}
536+
537+
// Replace an owned result with a guaranteed value on the merged path.
538+
// Introduce a copy for the new lifetime.
539+
// Simplify down to a single diamond.
540+
//
541+
// TODO: Simplify some of the obvisouly dead copy/destroy/borrows
542+
// on-the-fly after each simplify-cfg. Possible using CanonicalizeOSSALifetime.
543+
//
544+
// CHECK-LABEL: sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_merge : $@convention(method) (@owned Base) -> () {
545+
// CHECK: bb0(%0 : @owned $Base):
546+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base
547+
// CHECK: checked_cast_br [exact] [[BORROW]] : $Base to Base, bb1, bb3
548+
// CHECK: bb1([[ARG1:%.*]] : @guaranteed $Base):
549+
// CHECK: [[NEWCOPY1:%.*]] = copy_value [[ARG1]] : $Base
550+
// CHECK: apply %{{.*}}([[ARG1]]) : $@convention(method) (@guaranteed Base) -> ()
551+
// CHECK: [[OLDCOPY:%.*]] = copy_value [[BORROW]] : $Base
552+
// CHECK: end_borrow [[BORROW]] : $Base
553+
// CHECK: destroy_value [[OLDCOPY]] : $Base
554+
// CHECK: apply %{{.*}}([[NEWCOPY1]]) : $@convention(method) (@guaranteed Base) -> ()
555+
// CHECK: destroy_value [[NEWCOPY1]] : $Base
556+
// CHECK: br bb2
557+
// CHECK: bb2:
558+
// CHECK: destroy_value %0 : $Base
559+
// CHECK: return
560+
// CHECK: bb3([[ARG3:%.*]] : @guaranteed $Base):
561+
// CHECK: apply %1([[ARG3]]) : $@convention(method) (@guaranteed Base) -> ()
562+
// CHECK: [[NEWCOPY3:%.*]] = copy_value [[BORROW]] : $Base
563+
// CHECK: end_borrow [[BORROW]] : $Base
564+
// CHECK: apply %{{.*}}([[NEWCOPY3]]) : $@convention(method) (@guaranteed Base) -> ()
565+
// CHECK: destroy_value [[NEWCOPY3]] : $Base
566+
// CHECK: br bb2
567+
// CHECK-LABEL: } // end sil function 'redundant_checked_cast_br_rauw_guaranteed_to_owned_merge'
568+
sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_merge : $@convention(method) (@owned Base) -> () {
569+
bb0(%0 : @owned $Base):
570+
%m = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
571+
%f = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
572+
%1 = begin_borrow %0 : $Base
573+
checked_cast_br [exact] %1 : $Base to Base, bb1, bb2
574+
575+
bb1(%4 : @guaranteed $Base):
576+
%5 = apply %f(%4) : $@convention(method) (@guaranteed Base) -> ()
577+
br bb3
578+
579+
bb2(%7 : @guaranteed $Base):
580+
%8 = apply %m(%7) : $@convention(method) (@guaranteed Base) -> ()
581+
br bb3
582+
583+
bb3:
584+
%11 = copy_value %1 : $Base
585+
end_borrow %1 : $Base
586+
checked_cast_br [exact] %11 : $Base to Base, bb4, bb5
587+
588+
bb4(%14 : @owned $Base):
589+
%15 = apply %f(%14) : $@convention(method) (@guaranteed Base) -> ()
590+
destroy_value %14 : $Base
591+
br bb6
592+
593+
bb5(%20 : @owned $Base):
594+
%21 = apply %m(%20) : $@convention(method) (@guaranteed Base) -> ()
595+
destroy_value %20 : $Base
596+
br bb6
597+
598+
bb6:
599+
destroy_value %0 : $Base
600+
%27 = tuple ()
601+
return %27 : $()
602+
}
603+
604+
// Replace an owned result with a guaranteed value on the merged path.
605+
//
606+
// The merged path has an unknown predecessor, where the merged value
607+
// is produced by an apply.
608+
//
609+
// Clone the success path, introducing a copy on it.
610+
//
611+
// CHECK-LABEL: sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_mergecopy : $@convention(method) (@owned Base) -> () {
612+
// CHECK: bb0(%0 : @owned $Base):
613+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base
614+
// CHECK: checked_cast_br [exact] [[BORROW]] : $Base to Base, bb1, bb2
615+
// CHECK: bb1([[ARG1:%.*]] : @guaranteed $Base):
616+
// CHECK: [[CP1:%.*]] = copy_value [[ARG1]] : $Base
617+
// CHECK: apply %2([[ARG1]]) : $@convention(method) (@guaranteed Base) -> ()
618+
// CHECK: end_borrow [[BORROW]] : $Base
619+
// CHECK: br bb4([[CP1]] : $Base)
620+
// CHECK: bb2([[ARG2:%.*]] : @guaranteed $Base):
621+
// CHECK: apply %{{.*}}([[ARG2]]) : $@convention(method) (@guaranteed Base) -> ()
622+
// CHECK: [[RESULT:%.*]] = apply %{{.*}}() : $@convention(thin) () -> @owned Base
623+
// CHECK: end_borrow [[BORROW]] : $Base
624+
// CHECK: checked_cast_br [exact] %13 : $Base to Base, bb3, bb5
625+
// CHECK: bb3([[ARG3:%.*]] : @owned $Base):
626+
// CHECK: br bb4(%16 : $Base)
627+
// CHECK: bb4([[ARG4:%.*]] : @owned $Base):
628+
// CHECK: apply %{{.*}}([[ARG4]]) : $@convention(method) (@guaranteed Base) -> ()
629+
// CHECK: destroy_value [[ARG4]] : $Base
630+
// CHECK: br bb6
631+
// CHECK: bb5([[ARG5:%.*]] : @owned $Base):
632+
// CHECK: apply %{{.*}}([[ARG5]]) : $@convention(method) (@guaranteed Base) -> ()
633+
// CHECK: destroy_value [[ARG5]] : $Base
634+
// CHECK: br bb6
635+
// CHECK: bb6:
636+
// CHECK: destroy_value %0 : $Base
637+
// CHECK: return
638+
// CHECK-LABEL: } // end sil function 'redundant_checked_cast_br_rauw_guaranteed_to_owned_mergecopy'
639+
sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_mergecopy : $@convention(method) (@owned Base) -> () {
640+
bb0(%0 : @owned $Base):
641+
%1 = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
642+
643+
%2 = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
644+
%f = function_ref @get_base : $@convention(thin) () -> @owned Base
645+
%3 = begin_borrow %0 : $Base
646+
checked_cast_br [exact] %3 : $Base to Base, bb1, bb2
647+
648+
bb1(%6 : @guaranteed $Base):
649+
%7 = apply %2(%6) : $@convention(method) (@guaranteed Base) -> ()
650+
%8 = copy_value %6 : $Base
651+
br bb3(%8 : $Base)
652+
653+
bb2(%9 : @guaranteed $Base):
654+
%10 = apply %1(%9) : $@convention(method) (@guaranteed Base) -> ()
655+
%11 = apply %f() : $@convention(thin) () -> @owned Base
656+
br bb3(%11 : $Base)
657+
658+
bb3(%12 : @owned $Base):
659+
end_borrow %3 : $Base
660+
checked_cast_br [exact] %12 : $Base to Base, bb6, bb7
661+
662+
bb6(%16 : @owned $Base):
663+
%17 = apply %2(%16) : $@convention(method) (@guaranteed Base) -> ()
664+
destroy_value %16 : $Base
665+
br bb8
666+
667+
bb7(%20 : @owned $Base):
668+
%21 = apply %1(%20) : $@convention(method) (@guaranteed Base) -> ()
669+
destroy_value %20 : $Base
670+
br bb8
671+
672+
bb8:
673+
destroy_value %0 : $Base
674+
%25 = tuple ()
675+
return %25 : $()
676+
}
677+
678+
//!!!TODO: test replacing a guaranteed value with an ownedvalue
679+
// test borrowOverValue->borrowCopyOverScope path
680+
681+
//!!!TODO: test prepareUnowned paths

0 commit comments

Comments
 (0)