Skip to content

Commit 59153a0

Browse files
authored
Merge pull request #72019 from meg-gupta/instdeleterassertfix
Update canTriviallyDeleteOSSAEndScopeInst and a related assertion
2 parents d83d046 + eb7772c commit 59153a0

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed

include/swift/SILOptimizer/Utils/InstOptUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ bool isInstructionTriviallyDeletable(SILInstruction *inst);
128128
/// This routine only examines the state of the instruction at hand.
129129
bool isInstructionTriviallyDead(SILInstruction *inst);
130130

131+
bool canTriviallyDeleteOSSAEndScopeInst(SILInstruction *inst);
132+
131133
/// Return true if this is a release instruction that's not going to
132134
/// free the object.
133135
bool isIntermediateRelease(SILInstruction *inst, EpilogueARCFunctionInfo *erfi);

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,17 @@ swift::createDecrementBefore(SILValue ptr, SILInstruction *insertPt) {
127127

128128
/// Returns true if OSSA scope ending instructions end_borrow/destroy_value can
129129
/// be deleted trivially
130-
static bool canTriviallyDeleteOSSAEndScopeInst(SILInstruction *i) {
130+
bool swift::canTriviallyDeleteOSSAEndScopeInst(SILInstruction *i) {
131131
if (!isa<EndBorrowInst>(i) && !isa<DestroyValueInst>(i))
132132
return false;
133133
if (isa<StoreBorrowInst>(i->getOperand(0)))
134134
return false;
135-
return i->getOperand(0)->getOwnershipKind() == OwnershipKind::None;
135+
136+
auto opValue = i->getOperand(0);
137+
// We can delete destroy_value with operands of none ownership unless
138+
// they are move-only values, which can have custom deinit
139+
return opValue->getOwnershipKind() == OwnershipKind::None &&
140+
!opValue->getType().isMoveOnly();
136141
}
137142

138143
/// Perform a fast local check to see if the instruction is dead.

lib/SILOptimizer/Utils/InstructionDeleter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ bool InstructionDeleter::trackIfDead(SILInstruction *inst) {
180180
bool fixLifetime = inst->getFunction()->hasOwnership();
181181
if (isInstructionTriviallyDead(inst)
182182
|| isScopeAffectingInstructionDead(inst, fixLifetime)) {
183-
assert(!isIncidentalUse(inst) && !isa<DestroyValueInst>(inst) &&
183+
assert(!isIncidentalUse(inst) &&
184+
(!isa<DestroyValueInst>(inst) ||
185+
canTriviallyDeleteOSSAEndScopeInst(inst)) &&
184186
"Incidental uses cannot be removed in isolation. "
185187
"They would be removed iff the operand is dead");
186188
getCallbacks().notifyWillBeDeleted(inst);

test/SILOptimizer/simplify_cfg_ossa_jump_threading.sil

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,46 @@ bb6:
275275
%t = tuple ()
276276
return %t : $()
277277
}
278+
279+
sil @_swift_stdlib_isNSString : $@convention(c) (AnyObject) -> UInt8
280+
281+
// Ensure no crash in compiler
282+
sil hidden [ossa] @test_clone_destroy_none : $@convention(thin) (@guaranteed AnyObject) -> Bool {
283+
bb0(%0 : @guaranteed $AnyObject):
284+
%3 = enum $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>, #Optional.none!enumelt
285+
%4 = begin_borrow %3 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
286+
switch_enum %4 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
287+
288+
bb1(%6 : @guaranteed $(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)):
289+
end_borrow %4 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
290+
%8 = integer_literal $Builtin.Int1, -1
291+
br bb3(%8 : $Builtin.Int1)
292+
293+
bb2:
294+
end_borrow %4 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
295+
%11 = integer_literal $Builtin.Int1, 0
296+
br bb3(%11 : $Builtin.Int1)
297+
298+
bb3(%13 : $Builtin.Int1):
299+
destroy_value %3 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
300+
cond_br %13, bb4, bb5
301+
302+
bb4:
303+
%16 = integer_literal $Builtin.Int1, -1
304+
%17 = struct $Bool (%16 : $Builtin.Int1)
305+
br bb6(%17 : $Bool)
306+
307+
bb5:
308+
%19 = function_ref @_swift_stdlib_isNSString : $@convention(c) (AnyObject) -> UInt8
309+
%20 = apply %19(%0) : $@convention(c) (AnyObject) -> UInt8
310+
%21 = integer_literal $Builtin.Int8, 0
311+
%22 = struct_extract %20 : $UInt8, #UInt8._value
312+
%23 = builtin "cmp_eq_Int8"(%22 : $Builtin.Int8, %21 : $Builtin.Int8) : $Builtin.Int1
313+
%24 = integer_literal $Builtin.Int1, -1
314+
%25 = builtin "xor_Int1"(%23 : $Builtin.Int1, %24 : $Builtin.Int1) : $Builtin.Int1
315+
%26 = struct $Bool (%25 : $Builtin.Int1)
316+
br bb6(%26 : $Bool)
317+
318+
bb6(%28 : $Bool):
319+
return %28 : $Bool
320+
}

0 commit comments

Comments
 (0)