Skip to content

Commit 53c728e

Browse files
committed
[SSADestroyHoisting] Don't fold trivial loads.
For trivial values, the pattern %val = load [trivial] %addr destroy_addr %addr arises. Don't fold these two into %val = load [take] %addr because that isn't valid SIL for trivial types in OSSA.
1 parent 553f49d commit 53c728e

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,13 @@ bool HoistDestroys::rewriteDestroys(const KnownStorageUses &knownUses,
389389
bool HoistDestroys::foldBarrier(SILInstruction *barrier) {
390390
if (auto *load = dyn_cast<LoadInst>(barrier)) {
391391
if (load->getOperand() == storageRoot) {
392-
assert(load->getOwnershipQualifier() == LoadOwnershipQualifier::Copy);
393-
load->setOwnershipQualifier(LoadOwnershipQualifier::Take);
394-
return true;
392+
if (load->getOwnershipQualifier() == LoadOwnershipQualifier::Copy) {
393+
load->setOwnershipQualifier(LoadOwnershipQualifier::Take);
394+
return true;
395+
} else {
396+
assert(load->getOperand()->getType().isTrivial(*load->getFunction()));
397+
return false;
398+
}
395399
}
396400
}
397401
if (auto *copy = dyn_cast<CopyAddrInst>(barrier)) {

test/SILOptimizer/hoist_destroy_addr.sil

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,16 @@ public enum E {
3939
case B
4040
}
4141

42+
struct TrivialStruct {
43+
var e: E
44+
}
45+
4246
sil @unknown : $@convention(thin) () -> ()
4347
sil @use_S : $@convention(thin) (@in_guaranteed S) -> ()
4448

4549
sil @f_out : $@convention(thin) <T> () -> @out T
4650
sil @f_bool : $@convention(thin) () -> Builtin.Int1
51+
sil [ossa] @take_trivial_struct : $@convention(thin) (TrivialStruct) -> ()
4752

4853
// CHECK-LABEL: sil [ossa] @test_simple
4954
// CHECK: bb0(%0 : $*S):
@@ -229,3 +234,23 @@ bb3:
229234
return %16 : $()
230235
}
231236

237+
// Hoist a destroy_addr of a trivial value over a function_ref. DO NOT fold
238+
// with the load [trivial].
239+
//
240+
// CHECK-LABEL: sil [ossa] @test_hoist_trivial : {{.*}} {
241+
// CHECK: load [trivial]
242+
// CHECK: function_ref
243+
// CHECK-LABEL: } // end sil function 'test_hoist_trivial'
244+
sil [ossa] @test_hoist_trivial : $@convention(thin) (TrivialStruct) -> () {
245+
entry(%instance : @none $TrivialStruct):
246+
%addr = alloc_stack $TrivialStruct
247+
store %instance to [trivial] %addr : $*TrivialStruct
248+
%copy = load [trivial] %addr : $*TrivialStruct
249+
%take_trivial_struct = function_ref @take_trivial_struct : $@convention(thin) (TrivialStruct) -> ()
250+
destroy_addr %addr : $*TrivialStruct
251+
apply %take_trivial_struct(%copy) : $@convention(thin) (TrivialStruct) -> ()
252+
dealloc_stack %addr : $*TrivialStruct
253+
254+
%retval = tuple ()
255+
return %retval : $()
256+
}

0 commit comments

Comments
 (0)