Skip to content

Commit 1f42e86

Browse files
committed
Add checkOperandOwnershipInvariants for OSSA verification
A place to define invariants on OperandOwnership that passes can rely on for convenience. Starting with a simple invariant the OperandOwnership::Borrow is a valid BorrowingOperand.
1 parent b001b0b commit 1f42e86

File tree

3 files changed

+37
-14
lines changed

3 files changed

+37
-14
lines changed

include/swift/SIL/SILValue.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,9 @@ inline bool canAcceptUnownedValue(OperandOwnership operandOwnership) {
904904
llvm_unreachable("covered switch");
905905
}
906906

907+
/// Return true if all OperandOwnership invariants hold.
908+
bool checkOperandOwnershipInvariants(const Operand *operand);
909+
907910
/// Return the OperandOwnership for a forwarded operand when the forwarding
908911
/// operation has this "forwarding ownership" (as returned by
909912
/// getForwardingOwnershipKind()). \p allowUnowned is true for a subset of

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@
1919

2020
using namespace swift;
2121

22+
/// Return true if all OperandOwnership invariants hold.
23+
bool swift::checkOperandOwnershipInvariants(const Operand *operand) {
24+
OperandOwnership opOwnership = operand->getOperandOwnership();
25+
if (opOwnership == OperandOwnership::Borrow) {
26+
// Must be a valid BorrowingOperand.
27+
return bool(BorrowingOperand::get(operand));
28+
}
29+
return true;
30+
}
31+
2232
//===----------------------------------------------------------------------===//
2333
// OperandOwnershipClassifier
2434
//===----------------------------------------------------------------------===//

lib/SIL/Verifier/SILOwnershipVerifier.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -735,21 +735,31 @@ void SILInstruction::verifyOperandOwnership() const {
735735
if (isTypeDependentOperand(op))
736736
continue;
737737

738-
if (op.satisfiesConstraints())
739-
continue;
738+
if (!checkOperandOwnershipInvariants(&op)) {
739+
errorBuilder->handleMalformedSIL([&] {
740+
llvm::errs() << "Found an operand with invalid invariants.\n";
741+
llvm::errs() << "Value: " << op.get();
742+
llvm::errs() << "Instruction:\n";
743+
printInContext(llvm::errs());
744+
llvm::errs() << "OperandOwnership: " << op.getOperandOwnership()
745+
<< "\n";
746+
});
747+
}
740748

741-
auto constraint = op.getOwnershipConstraint();
742-
SILValue opValue = op.get();
743-
auto valueOwnershipKind = opValue.getOwnershipKind();
744-
errorBuilder->handleMalformedSIL([&] {
745-
llvm::errs() << "Found an operand with a value that is not compatible "
746-
"with the operand's operand ownership kind map.\n";
747-
llvm::errs() << "Value: " << opValue;
748-
llvm::errs() << "Value Ownership Kind: " << valueOwnershipKind << "\n";
749-
llvm::errs() << "Instruction:\n";
750-
printInContext(llvm::errs());
751-
llvm::errs() << "Constraint: " << constraint << "\n";
752-
});
749+
if (!op.satisfiesConstraints()) {
750+
auto constraint = op.getOwnershipConstraint();
751+
SILValue opValue = op.get();
752+
auto valueOwnershipKind = opValue.getOwnershipKind();
753+
errorBuilder->handleMalformedSIL([&] {
754+
llvm::errs() << "Found an operand with a value that is not compatible "
755+
"with the operand's operand ownership kind map.\n";
756+
llvm::errs() << "Value: " << opValue;
757+
llvm::errs() << "Value Ownership Kind: " << valueOwnershipKind << "\n";
758+
llvm::errs() << "Instruction:\n";
759+
printInContext(llvm::errs());
760+
llvm::errs() << "Constraint: " << constraint << "\n";
761+
});
762+
}
753763
}
754764
}
755765

0 commit comments

Comments
 (0)