Skip to content

Commit b80a08e

Browse files
committed
CodeMotion: check the ownership of arguments when sinking arguments
So far we only checked the ownership of incoming values. But even if the incoming instruction has no ownership, the argument may have. This can happen with enums which are constructed with a non-payload case: %1 = enum $Optional<C>, #Optional.none!enumelt br bb3(%1) bb1(%3 : @owned $Optional<C>): Fixes an ownership verification error: rdar://142506300
1 parent db96d63 commit b80a08e

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

lib/SILOptimizer/Transforms/SILCodeMotion.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,16 @@ static bool sinkArgument(EnumCaseDataflowContext &Context, SILBasicBlock *BB, un
11841184
if (hasOwnershipOperandsOrResults(FSI))
11851185
return false;
11861186

1187+
// Even if the incoming instruction has no ownership, the argument may have.
1188+
// This can happen with enums which are constructed with a non-payload case:
1189+
//
1190+
// %1 = enum $Optional<C>, #Optional.none!enumelt
1191+
// br bb3(%1)
1192+
// bb1(%3 : @owned $Optional<C>):
1193+
//
1194+
if (BB->getArgument(ArgNum)->getOwnershipKind() != OwnershipKind::None)
1195+
return false;
1196+
11871197
// The list of identical instructions.
11881198
SmallVector<SingleValueInstruction *, 8> Clones;
11891199
Clones.push_back(FSI);

test/SILOptimizer/earlycodemotion.sil

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,28 @@ bb3(%12 : $Bool):
552552
return %12 : $Bool
553553
}
554554

555+
// CHECK-LABEL: sil [ossa] @dont_sink_owned_trivial_enum :
556+
// CHECK: bb1:
557+
// CHECK-NEXT: enum
558+
// CHECK: bb2:
559+
// CHECK-NEXT: enum
560+
// CHECK: bb3([[A:%.*]] : @owned $Optional<C>):
561+
// CHECK-NEXT: return [[A]]
562+
// CHECK: } // end sil function 'dont_sink_owned_trivial_enum'
563+
sil [ossa] @dont_sink_owned_trivial_enum : $@convention(thin) () -> @owned Optional<C> {
564+
bb0:
565+
cond_br undef, bb1, bb2
566+
bb1:
567+
%2 = enum $Optional<C>, #Optional.none!enumelt
568+
br bb3(%2)
569+
bb2:
570+
%4 = enum $Optional<C>, #Optional.none!enumelt
571+
br bb3(%4)
572+
bb3(%6 : @owned $Optional<C>):
573+
return %6
574+
}
575+
576+
555577
// Sink retain down the successors so we can pair up retain with release on the
556578
// fast path.
557579
class Test {

0 commit comments

Comments
 (0)