Skip to content

Commit bbd6a87

Browse files
committed
Fix simplifyArguments for a few edges cases in OSSA
1 parent 93d6f93 commit bbd6a87

File tree

2 files changed

+103
-9
lines changed

2 files changed

+103
-9
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ bool SimplifyCFG::threadEdge(const ThreadInfo &ti) {
233233
Builder.createBranch(SEI->getLoc(), ThreadedSuccessorBlock, {UED});
234234
} else {
235235
assert(SEI->getDefaultBB() == ThreadedSuccessorBlock);
236-
Builder.createBranch(SEI->getLoc(), ThreadedSuccessorBlock, SEI->getOperand());
236+
Builder.createBranch(SEI->getLoc(), ThreadedSuccessorBlock,
237+
SEI->getOperand());
237238
}
238239
} else {
239240
Builder.createBranch(SEI->getLoc(), ThreadedSuccessorBlock,
@@ -3688,6 +3689,19 @@ bool SimplifyCFG::simplifyArgument(SILBasicBlock *BB, unsigned i) {
36883689
auto *Use = *A->use_begin();
36893690
auto *User = Use->getUser();
36903691

3692+
auto disableInOSSA = [](SingleValueInstruction *inst) {
3693+
assert(isa<StructInst>(inst) || isa<TupleInst>(inst) ||
3694+
isa<EnumInst>(inst));
3695+
if (!inst->getFunction()->hasOwnership()) {
3696+
return false;
3697+
}
3698+
if (inst->getOwnershipKind() == OwnershipKind::Owned)
3699+
return !inst->getSingleUse();
3700+
if (BorrowedValue borrow = BorrowedValue(inst->getOperand(0)))
3701+
return borrow.isLocalScope();
3702+
return false;
3703+
};
3704+
36913705
// Handle projections.
36923706
if (!isa<StructExtractInst>(User) &&
36933707
!isa<TupleExtractInst>(User) &&
@@ -3702,15 +3716,17 @@ bool SimplifyCFG::simplifyArgument(SILBasicBlock *BB, unsigned i) {
37023716
return false;
37033717
auto *Branch = cast<BranchInst>(Pred->getTerminator());
37043718
SILValue BranchArg = Branch->getArg(i);
3705-
if (isa<StructInst>(BranchArg))
3706-
continue;
3707-
if (isa<TupleInst>(BranchArg))
3708-
continue;
3719+
if (!isa<StructInst>(BranchArg) && !isa<TupleInst>(BranchArg) &&
3720+
!isa<EnumInst>(BranchArg)) {
3721+
return false;
3722+
}
37093723
if (auto *EI = dyn_cast<EnumInst>(BranchArg)) {
3710-
if (EI->getElement() == cast<UncheckedEnumDataInst>(proj)->getElement())
3711-
continue;
3724+
if (EI->getElement() != cast<UncheckedEnumDataInst>(proj)->getElement())
3725+
return false;
3726+
}
3727+
if (disableInOSSA(cast<SingleValueInstruction>(BranchArg))) {
3728+
return false;
37123729
}
3713-
return false;
37143730
}
37153731

37163732
// Okay, we'll replace the BB arg with one with the right type, replace

test/SILOptimizer/simplify_cfg_ossa_bbargs.sil

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ enum FakeOptional<T> {
1111
case none
1212
}
1313

14+
struct NonTrivialStruct {
15+
var val: Klass
16+
}
17+
1418
sil @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
1519

1620
// CHECK-LABEL: sil [ossa] @test_simplify_args1 :
@@ -172,7 +176,7 @@ bb4:
172176
}
173177

174178
// CHECK-LABEL: sil [ossa] @test_simplify_args8 :
175-
// CHECK-NOT: unchecked_enum_date
179+
// CHECK-NOT: unchecked_enum_data
176180
// CHECK-LABEL: } // end sil function 'test_simplify_args8'
177181
sil [ossa] @test_simplify_args8 : $@convention(thin) (@guaranteed Klass) -> () {
178182
bb0(%0 : @guaranteed $Klass):
@@ -235,3 +239,77 @@ bb3(%4 : $Builtin.Int32):
235239
return %5 : $()
236240
}
237241

242+
// CHECK-LABEL: sil [ossa] @test_simplify_enum_arg_owned :
243+
// CHECK: bb1([[ARG:%.*]] : @owned $FakeOptional<Klass>)
244+
// CHECK-LABEL: } // end sil function 'test_simplify_enum_arg_owned'
245+
sil [ossa] @test_simplify_enum_arg_owned : $@convention(thin) (@owned Klass) -> () {
246+
bb0(%0 : @owned $Klass):
247+
test_specification "simplify-cfg-simplify-argument @block[1] 0"
248+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
249+
%c = copy_value %1 : $FakeOptional<Klass>
250+
br bb1(%1 : $FakeOptional<Klass>)
251+
252+
bb1(%3 : @owned $FakeOptional<Klass>):
253+
%4 = unchecked_enum_data %3 : $FakeOptional<Klass>, #FakeOptional.some!enumelt
254+
%f = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
255+
apply %f(%4) : $@convention(thin) (@guaranteed Klass) -> ()
256+
br bb2
257+
258+
bb2:
259+
destroy_value %4 : $Klass
260+
br bb3
261+
262+
bb3:
263+
destroy_value %c : $FakeOptional<Klass>
264+
%t = tuple ()
265+
return %t : $()
266+
}
267+
268+
// CHECK-LABEL: sil [ossa] @test_simplify_enum_arg_guaranteed1 :
269+
// CHECK: bb1([[ARG:%.*]] : @guaranteed $FakeOptional<Klass>)
270+
// CHECK-LABEL: } // end sil function 'test_simplify_enum_arg_guaranteed1'
271+
sil [ossa] @test_simplify_enum_arg_guaranteed1 : $@convention(thin) (@owned Klass) -> () {
272+
bb0(%0 : @owned $Klass):
273+
test_specification "simplify-cfg-simplify-argument @block[1] 0"
274+
%b = begin_borrow %0 : $Klass
275+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %b : $Klass
276+
%c = copy_value %1 : $FakeOptional<Klass>
277+
br bb1(%1 : $FakeOptional<Klass>)
278+
279+
bb1(%3 : @guaranteed $FakeOptional<Klass>):
280+
%4 = unchecked_enum_data %3 : $FakeOptional<Klass>, #FakeOptional.some!enumelt
281+
%f = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
282+
apply %f(%4) : $@convention(thin) (@guaranteed Klass) -> ()
283+
br bb2
284+
285+
bb2:
286+
destroy_value %c : $FakeOptional<Klass>
287+
end_borrow %b : $Klass
288+
destroy_value %0 : $Klass
289+
%t = tuple ()
290+
return %t : $()
291+
}
292+
293+
// CHECK: bb1([[ARG:%.*]] : @guaranteed $NonTrivialStruct)
294+
sil [ossa] @test_simplify_enum_arg_guaranteed2 : $@convention(thin) (@owned Klass) -> () {
295+
bb0(%0 : @owned $Klass):
296+
test_specification "simplify-cfg-simplify-argument @block[1] 0"
297+
%b = begin_borrow %0 : $Klass
298+
%1 = struct $NonTrivialStruct(%b : $Klass)
299+
%c = copy_value %1 : $NonTrivialStruct
300+
br bb1(%1 : $NonTrivialStruct)
301+
302+
bb1(%3 : @guaranteed $NonTrivialStruct):
303+
%4 = struct_extract %3 : $NonTrivialStruct, #NonTrivialStruct.val
304+
%f = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> ()
305+
apply %f(%4) : $@convention(thin) (@guaranteed Klass) -> ()
306+
br bb2
307+
308+
bb2:
309+
destroy_value %c : $NonTrivialStruct
310+
end_borrow %b : $Klass
311+
destroy_value %0 : $Klass
312+
%t = tuple ()
313+
return %t : $()
314+
}
315+

0 commit comments

Comments
 (0)