Skip to content

Commit 0392b18

Browse files
authored
Merge pull request swiftlang#30197 from gottesmm/pr-e70e6d7bd61594b156ccf191c4e903753dbd3f83
[ownership] Ban cond_br from having any non-trivial operands.
2 parents 516b3e4 + 2b0b7f2 commit 0392b18

File tree

4 files changed

+24
-266
lines changed

4 files changed

+24
-266
lines changed

lib/SIL/SILVerifier.cpp

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4303,37 +4303,46 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
43034303
"branch argument types do not match arguments for dest bb");
43044304
}
43054305

4306-
void checkCondBranchInst(CondBranchInst *CBI) {
4306+
void checkCondBranchInst(CondBranchInst *cbi) {
43074307
// It is important that cond_br keeps an i1 type. ARC Sequence Opts assumes
43084308
// that cond_br does not use reference counted values or decrement reference
43094309
// counted values under the assumption that the instruction that computes
43104310
// the i1 is the use/decrement that ARC cares about and that after that
43114311
// instruction is evaluated, the scalar i1 has a different identity and the
43124312
// object can be deallocated.
4313-
requireSameType(CBI->getCondition()->getType(),
4313+
requireSameType(cbi->getCondition()->getType(),
43144314
SILType::getBuiltinIntegerType(
4315-
1, CBI->getCondition()->getType().getASTContext()),
4315+
1, cbi->getCondition()->getType().getASTContext()),
43164316
"condition of conditional branch must have Int1 type");
43174317

4318-
require(CBI->getTrueArgs().size() == CBI->getTrueBB()->args_size(),
4318+
require(cbi->getTrueArgs().size() == cbi->getTrueBB()->args_size(),
43194319
"true branch has wrong number of arguments for dest bb");
4320-
require(CBI->getTrueBB() != CBI->getFalseBB(),
4321-
"identical destinations");
4322-
require(std::equal(CBI->getTrueArgs().begin(), CBI->getTrueArgs().end(),
4323-
CBI->getTrueBB()->args_begin(),
4320+
require(cbi->getTrueBB() != cbi->getFalseBB(), "identical destinations");
4321+
require(std::equal(cbi->getTrueArgs().begin(), cbi->getTrueArgs().end(),
4322+
cbi->getTrueBB()->args_begin(),
43244323
[&](SILValue branchArg, SILArgument *bbArg) {
43254324
return verifyBranchArgs(branchArg, bbArg);
43264325
}),
43274326
"true branch argument types do not match arguments for dest bb");
43284327

4329-
require(CBI->getFalseArgs().size() == CBI->getFalseBB()->args_size(),
4328+
require(cbi->getFalseArgs().size() == cbi->getFalseBB()->args_size(),
43304329
"false branch has wrong number of arguments for dest bb");
4331-
require(std::equal(CBI->getFalseArgs().begin(), CBI->getFalseArgs().end(),
4332-
CBI->getFalseBB()->args_begin(),
4330+
require(std::equal(cbi->getFalseArgs().begin(), cbi->getFalseArgs().end(),
4331+
cbi->getFalseBB()->args_begin(),
43334332
[&](SILValue branchArg, SILArgument *bbArg) {
43344333
return verifyBranchArgs(branchArg, bbArg);
43354334
}),
43364335
"false branch argument types do not match arguments for dest bb");
4336+
// When we are in ossa, cond_br can not have any arguments that are
4337+
// non-trivial.
4338+
if (!F.hasOwnership())
4339+
return;
4340+
4341+
require(llvm::all_of(cbi->getOperandValues(),
4342+
[&](SILValue v) -> bool {
4343+
return v->getType().isTrivial(*cbi->getFunction());
4344+
}),
4345+
"cond_br must not have a non-trivial value in ossa.");
43374346
}
43384347

43394348
void checkDynamicMethodBranchInst(DynamicMethodBranchInst *DMBI) {
@@ -4905,38 +4914,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
49054914
CurInstruction = TI;
49064915

49074916
// Check for non-cond_br critical edges.
4908-
auto *CBI = dyn_cast<CondBranchInst>(TI);
4909-
if (!CBI) {
4910-
for (unsigned Idx = 0, e = BB.getSuccessors().size(); Idx != e; ++Idx) {
4911-
require(!isCriticalEdgePred(TI, Idx),
4912-
"non cond_br critical edges not allowed");
4913-
}
4917+
if (isa<CondBranchInst>(TI)) {
49144918
continue;
49154919
}
4916-
// In ownership qualified SIL, ban critical edges from CondBranchInst that
4917-
// have non-trivial arguments.
4918-
//
4919-
// FIXME: it would be far simpler to ban all critical edges in general.
4920-
if (!F->hasOwnership())
4921-
continue;
49224920

4923-
if (isCriticalEdgePred(CBI, CondBranchInst::TrueIdx)) {
4924-
require(
4925-
llvm::all_of(CBI->getTrueArgs(),
4926-
[](SILValue V) -> bool {
4927-
return V.getOwnershipKind() ==
4928-
ValueOwnershipKind::None;
4929-
}),
4930-
"cond_br with critical edges must not have a non-trivial value");
4931-
}
4932-
if (isCriticalEdgePred(CBI, CondBranchInst::FalseIdx)) {
4933-
require(
4934-
llvm::all_of(CBI->getFalseArgs(),
4935-
[](SILValue V) -> bool {
4936-
return V.getOwnershipKind() ==
4937-
ValueOwnershipKind::None;
4938-
}),
4939-
"cond_br with critical edges must not have a non-trivial value");
4921+
for (unsigned Idx = 0, e = BB.getSuccessors().size(); Idx != e; ++Idx) {
4922+
require(!isCriticalEdgePred(TI, Idx),
4923+
"non cond_br critical edges not allowed");
49404924
}
49414925
}
49424926
}

test/SIL/ownership-verifier/arguments.sil

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -474,54 +474,6 @@ bb1(%1 : @owned $Builtin.NativeObject):
474474
return %9999 : $()
475475
}
476476

477-
// CHECK-LABEL: Function: 'owned_argument_overuse_condbr1'
478-
// CHECK-NEXT: Found over consume?!
479-
// CHECK-NEXT: Value: %0 = argument of bb0 : $Builtin.NativeObject
480-
// CHECK-NEXT: User: cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2
481-
// CHECK-NEXT: Block: bb0
482-
//
483-
// CHECK-LABEL: Function: 'owned_argument_overuse_condbr1'
484-
// CHECK-NEXT: Error! Found a leak due to a consuming post-dominance failure!
485-
// CHECK-NEXT: Value: %0 = argument of bb0
486-
// CHECK-NEXT: Post Dominating Failure Blocks:
487-
// CHECK-NEXT: bb2
488-
//
489-
// CHECK-LABEL: Function: 'owned_argument_overuse_condbr1'
490-
// CHECK-NEXT: Error! Found a leaked owned value that was never consumed.
491-
// CHECK-NEXT: Value: %3 = argument of bb1 : $Builtin.NativeObject
492-
// CHECK-NOT: Function: 'owned_argument_overuse_condbr1'
493-
sil [ossa] @owned_argument_overuse_condbr1 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
494-
bb0(%0 : @owned $Builtin.NativeObject):
495-
destroy_value %0 : $Builtin.NativeObject
496-
cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2
497-
498-
bb1(%1 : @owned $Builtin.NativeObject):
499-
br bb2
500-
501-
bb2:
502-
%9999 = tuple()
503-
return %9999 : $()
504-
}
505-
506-
// CHECK-LABEL: Function: 'owned_argument_overuse_condbr2'
507-
// CHECK-NEXT: Found over consume?!
508-
// CHECK-NEXT: Value: %0 = argument of bb0 : $Builtin.NativeObject
509-
// CHECK-NEXT: User: cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2
510-
// CHECK-NEXT: Block: bb0
511-
sil [ossa] @owned_argument_overuse_condbr2 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
512-
bb0(%0 : @owned $Builtin.NativeObject):
513-
destroy_value %0 : $Builtin.NativeObject
514-
cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2
515-
516-
bb1(%1 : @owned $Builtin.NativeObject):
517-
destroy_value %1 : $Builtin.NativeObject
518-
br bb2
519-
520-
bb2:
521-
%9999 = tuple()
522-
return %9999 : $()
523-
}
524-
525477
/////////////////////////////////////////
526478
// Movable Guaranteed Scope Test Cases //
527479
/////////////////////////////////////////

test/SIL/ownership-verifier/cond_br_crash.sil

Lines changed: 0 additions & 92 deletions
This file was deleted.

test/SIL/ownership-verifier/cond_br_no_crash.sil

Lines changed: 0 additions & 86 deletions
This file was deleted.

0 commit comments

Comments
 (0)