Skip to content

Commit 0f16053

Browse files
committed
[CopyPropagation] Don't canonicalize lex values.
The destroys of lexical values can't be hoisted over deinit barriers because their lifetimes are lexical.
1 parent 7d4f6ff commit 0f16053

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/SILOptimizer/Utils/CanonicalOSSALifetime.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,9 @@ bool CanonicalizeOSSALifetime::canonicalizeValueLifetime(SILValue def) {
772772
if (def.getOwnershipKind() != OwnershipKind::Owned)
773773
return false;
774774

775+
if (def->isLexical())
776+
return false;
777+
775778
if (poisonRefsMode && !shouldCanonicalizeWithPoison(def))
776779
return false;
777780

test/SILOptimizer/copy_propagation.sil

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class C {
2828
}
2929

3030
sil [ossa] @dummy : $@convention(thin) () -> ()
31+
sil [ossa] @barrier : $@convention(thin) () -> ()
3132
sil [ossa] @getOwnedC : $@convention(thin) () -> (@owned C)
3233
sil [ossa] @takeOwnedC : $@convention(thin) (@owned C) -> ()
3334
sil [ossa] @takeOwnedCTwice : $@convention(thin) (@owned C, @owned C) -> ()
@@ -836,3 +837,26 @@ bb0(%0 : @owned $C):
836837
%7 = begin_borrow %6 : $C
837838
unreachable
838839
}
840+
841+
// Test that copy propagation doesn't hoist a destroy_value corresponding to
842+
// a move value [lexical] over a barrier.
843+
// CHECK-ONONE-LABEL: sil [ossa] @dont_hoist_move_value_lexical_destroy_over_barrier_apply : {{.*}} {
844+
// CHECK-ONONE: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
845+
// CHECK-ONONE: [[LIFETIME:%[^,]+]] = move_value [lexical] [[INSTANCE]]
846+
// CHECK-ONONE: [[BARRIER:%[^,]+]] = function_ref @barrier
847+
// CHECK-ONONE: [[TAKE_GUARANTEED_C:%[^,]+]] = function_ref @takeGuaranteedC
848+
// CHECK-ONONE: apply [[TAKE_GUARANTEED_C]]([[LIFETIME]])
849+
// CHECK-ONONE: apply [[BARRIER]]()
850+
// CHECK-ONONE: destroy_value [[LIFETIME]]
851+
// CHECK-ONONE-LABEL: } // end sil function 'dont_hoist_move_value_lexical_destroy_over_barrier_apply'
852+
sil [ossa] @dont_hoist_move_value_lexical_destroy_over_barrier_apply : $@convention(thin) (@owned C) -> () {
853+
entry(%instance : @owned $C):
854+
%lifetime = move_value [lexical] %instance : $C
855+
%barrier = function_ref @barrier : $@convention(thin) () -> ()
856+
%takeGuaranteedC = function_ref @takeGuaranteedC : $@convention(thin) (@guaranteed C) -> ()
857+
apply %takeGuaranteedC(%lifetime) : $@convention(thin) (@guaranteed C) -> ()
858+
apply %barrier() : $@convention(thin) () -> ()
859+
destroy_value %lifetime : $C
860+
%retval = tuple ()
861+
return %retval : $()
862+
}

0 commit comments

Comments
 (0)