Skip to content

Commit 237b70c

Browse files
authored
Merge pull request #72314 from meg-gupta/fixnonestructonly
Fix ownership of move-only structs in SIL
2 parents c27d1b8 + a15d5fe commit 237b70c

File tree

6 files changed

+58
-48
lines changed

6 files changed

+58
-48
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ class SILBuilder {
16431643
ArrayRef<SILValue> Elements) {
16441644
return createStruct(Loc, Ty, Elements,
16451645
hasOwnership()
1646-
? mergeSILValueOwnership(Elements)
1646+
? getSILValueOwnership(Elements, Ty)
16471647
: ValueOwnershipKind(OwnershipKind::None));
16481648
}
16491649

@@ -1659,7 +1659,7 @@ class SILBuilder {
16591659
ArrayRef<SILValue> Elements) {
16601660
return createTuple(Loc, Ty, Elements,
16611661
hasOwnership()
1662-
? mergeSILValueOwnership(Elements)
1662+
? getSILValueOwnership(Elements)
16631663
: ValueOwnershipKind(OwnershipKind::None));
16641664
}
16651665

@@ -2941,9 +2941,9 @@ class SILBuilder {
29412941
std::optional<SILValue> TransposeFunction = std::nullopt) {
29422942
auto ownershipKind =
29432943
hasOwnership()
2944-
? (TransposeFunction ? mergeSILValueOwnership(
2944+
? (TransposeFunction ? getSILValueOwnership(
29452945
{OriginalFunction, *TransposeFunction})
2946-
: mergeSILValueOwnership({OriginalFunction}))
2946+
: getSILValueOwnership({OriginalFunction}))
29472947
: ValueOwnershipKind(OwnershipKind::None);
29482948
return createLinearFunction(Loc, ParameterIndices, OriginalFunction,
29492949
ownershipKind, TransposeFunction);

include/swift/SIL/ValueUtils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ namespace swift {
2222
///
2323
/// NOTE: This assumes that the passed in SILValues are not values used as type
2424
/// dependent operands.
25-
ValueOwnershipKind mergeSILValueOwnership(ArrayRef<SILValue> values);
25+
ValueOwnershipKind getSILValueOwnership(ArrayRef<SILValue> values,
26+
SILType ty = SILType());
2627

2728
} // namespace swift
2829

lib/SIL/IR/SILInstructions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,7 @@ ValueOwnershipKind DifferentiableFunctionInst::getMergedOwnershipKind(
825825
SILValue OriginalFunction, ArrayRef<SILValue> DerivativeFunctions) {
826826
if (DerivativeFunctions.empty())
827827
return OriginalFunction->getOwnershipKind();
828-
return mergeSILValueOwnership(
828+
return getSILValueOwnership(
829829
{OriginalFunction, DerivativeFunctions[0], DerivativeFunctions[1]});
830830
}
831831

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4980,7 +4980,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
49804980
auto Ty2 = SILType::getPrimitiveObjectType(Ty->getCanonicalType());
49814981

49824982
ValueOwnershipKind forwardingOwnership =
4983-
F && F->hasOwnership() ? mergeSILValueOwnership(OpList)
4983+
F && F->hasOwnership() ? getSILValueOwnership(OpList)
49844984
: ValueOwnershipKind(OwnershipKind::None);
49854985

49864986
if (parseForwardingOwnershipKind(forwardingOwnership)
@@ -5540,7 +5540,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
55405540

55415541
if (Opcode == SILInstructionKind::StructInst) {
55425542
ValueOwnershipKind forwardingOwnership =
5543-
F && F->hasOwnership() ? mergeSILValueOwnership(OpList)
5543+
F && F->hasOwnership() ? getSILValueOwnership(OpList, Ty)
55445544
: ValueOwnershipKind(OwnershipKind::None);
55455545
if (parseForwardingOwnershipKind(forwardingOwnership)
55465546
|| parseSILDebugLocation(InstLoc, B)) {

lib/SIL/Utils/ValueUtils.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@
1616

1717
using namespace swift;
1818

19-
ValueOwnershipKind swift::mergeSILValueOwnership(ArrayRef<SILValue> values) {
20-
auto range = makeTransformRange(values,
21-
[](SILValue v) {
22-
assert(v->getType().isObject());
23-
return v->getOwnershipKind();
24-
});
25-
return ValueOwnershipKind::merge(range);
19+
ValueOwnershipKind swift::getSILValueOwnership(ArrayRef<SILValue> values,
20+
SILType ty) {
21+
auto range = makeTransformRange(values, [](SILValue v) {
22+
assert(v->getType().isObject());
23+
return v->getOwnershipKind();
24+
});
25+
26+
auto mergedOwnership = ValueOwnershipKind::merge(range);
27+
28+
// If we have a move only type, and the merged ownership is none, we return
29+
// Owned ownership kind.
30+
if (ty && ty.isMoveOnly() && mergedOwnership == OwnershipKind::None) {
31+
return OwnershipKind::Owned;
32+
}
33+
return mergedOwnership;
2634
}

test/SIL/moveonly_ownership.sil

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,42 @@
11
// RUN: %target-sil-opt -test-runner %s -o /dev/null 2>&1 | %FileCheck %s
22

3-
// rdar://124466060
4-
// UNSUPPORTED: CPU=armv7k
5-
63
sil_stage raw
74

85
import Builtin
96
import Swift
107
import SwiftShims
118

9+
struct FakeInt {
10+
var i: Builtin.Int32
11+
}
12+
1213
@_moveOnly struct MO_DEINIT {
13-
@_hasStorage var value: Int { get set }
14+
@_hasStorage var value: FakeInt { get set }
1415
deinit
15-
init(value: Int)
16+
init(value: FakeInt)
1617
}
1718

1819
struct NC_DEINIT : ~Copyable {
19-
@_hasStorage var value: Int { get set }
20+
@_hasStorage var value: FakeInt { get set }
2021
deinit
21-
init(value: Int)
22+
init(value: FakeInt)
2223
}
2324

2425
@_moveOnly struct MO {
25-
@_hasStorage var value: Int { get set }
26+
@_hasStorage var value: FakeInt { get set }
2627
}
2728

2829
struct NC : ~Copyable {
29-
@_hasStorage var value: Int { get set }
30+
@_hasStorage var value: FakeInt { get set }
3031
}
3132

3233
// CHECK: begin running test 1 of 4 on motest1: is-sil-trivial with: @instruction[2]
33-
// CHECK: %2 = struct $MO_DEINIT (%1 : $Int)
34+
// CHECK: %2 = struct $MO_DEINIT (%1 : $FakeInt)
3435
// CHECK: is not trivial
3536
// CHECK: end running test 1 of 4 on motest1: is-sil-trivial with: @instruction[2]
3637
// CHECK: begin running test 2 of 4 on motest1: get-ownership-kind with: @instruction[2]
37-
// CHECK: %2 = struct $MO_DEINIT (%1 : $Int)
38-
// CHECK: OwnershipKind: none
38+
// CHECK: %2 = struct $MO_DEINIT (%1 : $FakeInt)
39+
// CHECK: OwnershipKind: owned
3940
// CHECK: end running test 2 of 4 on motest1: get-ownership-kind with: @instruction[2]
4041
// CHECK: begin running test 3 of 4 on motest1: is-sil-trivial with: @instruction[4]
4142
// CHECK: %4 = move_value [lexical] %2 : $MO_DEINIT
@@ -52,9 +53,9 @@ bb0:
5253
specify_test "get-ownership-kind @instruction[2]"
5354
specify_test "is-sil-trivial @instruction[4]"
5455
specify_test "get-ownership-kind @instruction[4]"
55-
%0 = integer_literal $Builtin.Int64, 38
56-
%1 = struct $Int (%0 : $Builtin.Int64)
57-
%2 = struct $MO_DEINIT (%1 : $Int)
56+
%0 = integer_literal $Builtin.Int32, 38
57+
%1 = struct $FakeInt (%0 : $Builtin.Int32)
58+
%2 = struct $MO_DEINIT (%1 : $FakeInt)
5859
debug_value %2 : $MO_DEINIT, let, name "b"
5960
%4 = move_value [lexical] %2 : $MO_DEINIT
6061
destroy_value %4 : $MO_DEINIT
@@ -63,12 +64,12 @@ bb0:
6364
}
6465

6566
// CHECK: begin running test 1 of 4 on motest2: is-sil-trivial with: @instruction[2]
66-
// CHECK: %2 = struct $MO (%1 : $Int)
67+
// CHECK: %2 = struct $MO (%1 : $FakeInt)
6768
// CHECK: is not trivial
6869
// CHECK: end running test 1 of 4 on motest2: is-sil-trivial with: @instruction[2]
6970
// CHECK: begin running test 2 of 4 on motest2: get-ownership-kind with: @instruction[2]
70-
// CHECK: %2 = struct $MO (%1 : $Int)
71-
// CHECK: OwnershipKind: none
71+
// CHECK: %2 = struct $MO (%1 : $FakeInt)
72+
// CHECK: OwnershipKind: owned
7273
// CHECK: end running test 2 of 4 on motest2: get-ownership-kind with: @instruction[2]
7374
// CHECK: begin running test 3 of 4 on motest2: is-sil-trivial with: @instruction[4]
7475
// CHECK: %4 = move_value [lexical] %2 : $MO
@@ -85,9 +86,9 @@ bb0:
8586
specify_test "get-ownership-kind @instruction[2]"
8687
specify_test "is-sil-trivial @instruction[4]"
8788
specify_test "get-ownership-kind @instruction[4]"
88-
%0 = integer_literal $Builtin.Int64, 38
89-
%1 = struct $Int (%0 : $Builtin.Int64)
90-
%2 = struct $MO (%1 : $Int)
89+
%0 = integer_literal $Builtin.Int32, 38
90+
%1 = struct $FakeInt (%0 : $Builtin.Int32)
91+
%2 = struct $MO (%1 : $FakeInt)
9192
debug_value %2 : $MO, let, name "b"
9293
%4 = move_value [lexical] %2 : $MO
9394
destroy_value %4 : $MO
@@ -96,12 +97,12 @@ bb0:
9697
}
9798

9899
// CHECK: begin running test 1 of 4 on nctest1: is-sil-trivial with: @instruction[2]
99-
// CHECK: %2 = struct $NC_DEINIT (%1 : $Int)
100+
// CHECK: %2 = struct $NC_DEINIT (%1 : $FakeInt)
100101
// CHECK: is not trivial
101102
// CHECK: end running test 1 of 4 on nctest1: is-sil-trivial with: @instruction[2]
102103
// CHECK: begin running test 2 of 4 on nctest1: get-ownership-kind with: @instruction[2]
103-
// CHECK: %2 = struct $NC_DEINIT (%1 : $Int)
104-
// CHECK: OwnershipKind: none
104+
// CHECK: %2 = struct $NC_DEINIT (%1 : $FakeInt)
105+
// CHECK: OwnershipKind: owned
105106
// CHECK: end running test 2 of 4 on nctest1: get-ownership-kind with: @instruction[2]
106107
// CHECK: begin running test 3 of 4 on nctest1: is-sil-trivial with: @instruction[4]
107108
// CHECK: %4 = move_value [lexical] %2 : $NC_DEINIT
@@ -119,9 +120,9 @@ bb0:
119120
specify_test "get-ownership-kind @instruction[2]"
120121
specify_test "is-sil-trivial @instruction[4]"
121122
specify_test "get-ownership-kind @instruction[4]"
122-
%0 = integer_literal $Builtin.Int64, 38
123-
%1 = struct $Int (%0 : $Builtin.Int64)
124-
%2 = struct $NC_DEINIT (%1 : $Int)
123+
%0 = integer_literal $Builtin.Int32, 38
124+
%1 = struct $FakeInt (%0 : $Builtin.Int32)
125+
%2 = struct $NC_DEINIT (%1 : $FakeInt)
125126
debug_value %2 : $NC_DEINIT, let, name "b"
126127
%4 = move_value [lexical] %2 : $NC_DEINIT
127128
destroy_value %4 : $NC_DEINIT
@@ -130,12 +131,12 @@ bb0:
130131
}
131132

132133
// CHECK: begin running test 1 of 4 on nctest2: is-sil-trivial with: @instruction[2]
133-
// CHECK: %2 = struct $NC (%1 : $Int)
134+
// CHECK: %2 = struct $NC (%1 : $FakeInt)
134135
// CHECK: is not trivial
135136
// CHECK: end running test 1 of 4 on nctest2: is-sil-trivial with: @instruction[2]
136137
// CHECK: begin running test 2 of 4 on nctest2: get-ownership-kind with: @instruction[2]
137-
// CHECK: %2 = struct $NC (%1 : $Int)
138-
// CHECK: OwnershipKind: none
138+
// CHECK: %2 = struct $NC (%1 : $FakeInt)
139+
// CHECK: OwnershipKind: owned
139140
// CHECK: end running test 2 of 4 on nctest2: get-ownership-kind with: @instruction[2]
140141
// CHECK: begin running test 3 of 4 on nctest2: is-sil-trivial with: @instruction[4]
141142
// CHECK: %4 = move_value [lexical] %2 : $NC
@@ -152,9 +153,9 @@ bb0:
152153
specify_test "get-ownership-kind @instruction[2]"
153154
specify_test "is-sil-trivial @instruction[4]"
154155
specify_test "get-ownership-kind @instruction[4]"
155-
%0 = integer_literal $Builtin.Int64, 38
156-
%1 = struct $Int (%0 : $Builtin.Int64)
157-
%2 = struct $NC (%1 : $Int)
156+
%0 = integer_literal $Builtin.Int32, 38
157+
%1 = struct $FakeInt (%0 : $Builtin.Int32)
158+
%2 = struct $NC (%1 : $FakeInt)
158159
debug_value %2 : $NC, let, name "b"
159160
%4 = move_value [lexical] %2 : $NC
160161
destroy_value %4 : $NC

0 commit comments

Comments
 (0)