Skip to content

Commit aedb40b

Browse files
committed
Update canTriviallyDeleteOSSAEndScopeInst and a related assertion
A destroy_value of Optional.none can be deleted. A move-only struct with deinit has a non trivial SILType but OwnershipKind::None, such values cannot be deleted.
1 parent 0b5de06 commit aedb40b

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,12 @@ static bool canTriviallyDeleteOSSAEndScopeInst(SILInstruction *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.

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)