Skip to content

Commit 02b4bac

Browse files
authored
Merge pull request #78083 from eeckstein/fix-ssa-updater
SSAUpdater: fix an ownership violation
2 parents c6556d8 + 710c4b1 commit 02b4bac

File tree

2 files changed

+216
-5
lines changed

2 files changed

+216
-5
lines changed

lib/SILOptimizer/Utils/SILSSAUpdater.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/SIL/SILBuilder.h"
2020
#include "swift/SIL/SILModule.h"
2121
#include "swift/SIL/SILUndef.h"
22+
#include "swift/SIL/Test.h"
2223
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
2324
#include "llvm/ADT/DenseMap.h"
2425
#include "llvm/ADT/SmallVector.h"
@@ -229,18 +230,19 @@ SILValue SILSSAUpdater::getValueInMiddleOfBlock(SILBasicBlock *block) {
229230
if (predVals.empty())
230231
return SILUndef::get(block->getParent(), type);
231232

232-
if (singularValue)
233-
return singularValue;
234-
235233
// Check if we already have an equivalent phi.
236234
if (!block->getArguments().empty()) {
237235
llvm::SmallDenseMap<SILBasicBlock *, SILValue, 8> valueMap(predVals.begin(),
238236
predVals.end());
239-
for (auto *arg : block->getSILPhiArguments())
240-
if (isEquivalentPHI(arg, valueMap))
237+
for (auto *arg : block->getSILPhiArguments()) {
238+
if (arg->isPhi() && isEquivalentPHI(arg, valueMap))
241239
return arg;
240+
}
242241
}
243242

243+
if (singularValue)
244+
return singularValue;
245+
244246
// Create a new phi node.
245247
SILPhiArgument *phiArg = block->createPhiArgument(type, ownershipKind);
246248
for (auto &pair : predVals) {
@@ -567,3 +569,30 @@ SILValue swift::replaceBBArgWithCast(SILPhiArgument *arg) {
567569
return replaceBBArgWithStruct(arg, argValues);
568570
return nullptr;
569571
}
572+
573+
namespace swift::test {
574+
// Arguments:
575+
// * the first arguments are values, which are added as "available values" to the SSA-updater
576+
// * the next arguments are operands, which are set to the computed values at that place
577+
static FunctionTest SSAUpdaterTest("update_ssa", [](auto &function,
578+
auto &arguments,
579+
auto &test) {
580+
SILSSAUpdater updater;
581+
SILValue firstVal = arguments.takeValue();
582+
updater.initialize(&function, firstVal->getType(), firstVal->getOwnershipKind());
583+
updater.addAvailableValue(firstVal->getParentBlock(), firstVal);
584+
585+
while (arguments.hasUntaken()) {
586+
auto &arg = arguments.takeArgument();
587+
if (isa<ValueArgument>(arg)) {
588+
SILValue val = cast<ValueArgument>(arg).getValue();
589+
updater.addAvailableValue(val->getParentBlock(), val);
590+
} else if (isa<OperandArgument>(arg)) {
591+
Operand *op = cast<OperandArgument>(arg).getValue();
592+
SILValue newValue = updater.getValueInMiddleOfBlock(op->getUser()->getParent());
593+
op->set(newValue);
594+
}
595+
}
596+
});
597+
} // end namespace swift::test
598+

test/SILOptimizer/ssa-updater.sil

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// RUN: %target-sil-opt -test-runner %s -sil-disable-input-verify | %FileCheck %s
2+
3+
// Arguments to specify_test:
4+
// * the first arguments are values, which are added as "available values" to the SSA-updater
5+
// * the next arguments are operands, which are set to the computed values at that place
6+
7+
sil_stage canonical
8+
9+
import Builtin
10+
11+
class C {}
12+
13+
sil @c2 : $@convention(thin) (@guaranteed C) -> @owned C
14+
15+
// CHECK-LABEL: sil [ossa] @reuse_phi_arg1 :
16+
// CHECK: bb17([[P:%.*]] : @owned $C):
17+
// CHECK: apply {{%[0-9]+}}([[P]])
18+
// CHECK-NEXT: destroy_value [[P]]
19+
// CHECK: } // end sil function 'reuse_phi_arg1'
20+
sil [ossa] @reuse_phi_arg1 : $@convention(thin) (@owned C) -> () {
21+
bb0(%0 : @owned $C):
22+
br bb3
23+
24+
bb1(%2 : @owned $C):
25+
cond_br undef, bb2, bb22
26+
27+
bb2:
28+
br bb18
29+
30+
bb3:
31+
cond_br undef, bb4, bb5
32+
33+
bb4:
34+
br bb17
35+
36+
bb5:
37+
cond_br undef, bb9, bb6
38+
39+
bb6:
40+
cond_br undef, bb8, bb7
41+
42+
bb7:
43+
br bb12
44+
45+
bb8:
46+
br bb11
47+
48+
bb9:
49+
br bb10
50+
51+
bb10:
52+
br bb18
53+
54+
bb11:
55+
br bb17
56+
57+
bb12:
58+
cond_br undef, bb16, bb13
59+
60+
bb13:
61+
cond_br undef, bb15, bb14
62+
63+
bb14:
64+
br bb12
65+
66+
bb15:
67+
br bb11
68+
69+
bb16:
70+
br bb10
71+
72+
bb17:
73+
%19 = function_ref @c2 : $@convention(thin) (@guaranteed C) -> @owned C
74+
specify_test "update_ssa %0 %2 @instruction[+3].operand @instruction[+1].operand @instruction[+0].operand[1]"
75+
%20 = apply %19(%2) : $@convention(thin) (@guaranteed C) -> @owned C
76+
destroy_value %2
77+
cond_br undef, bb19, bb20
78+
79+
bb18:
80+
destroy_value %2
81+
br bb21
82+
83+
bb19:
84+
destroy_value %20
85+
br bb21
86+
87+
bb20:
88+
br bb1(%20)
89+
90+
bb21:
91+
%28 = tuple ()
92+
return %28
93+
94+
bb22:
95+
br bb3
96+
}
97+
98+
// CHECK-LABEL: sil [ossa] @reuse_phi_arg2 :
99+
// CHECK: bb17([[P:%.*]] : @owned $C):
100+
// CHECK: apply {{%[0-9]+}}([[P]])
101+
// CHECK-NEXT: destroy_value [[P]]
102+
// CHECK: } // end sil function 'reuse_phi_arg2'
103+
sil [ossa] @reuse_phi_arg2 : $@convention(thin) (@owned C) -> () {
104+
bb0(%0 : @owned $C):
105+
br bb3
106+
107+
bb1(%2 : @owned $C):
108+
cond_br undef, bb2, bb23
109+
110+
bb2:
111+
br bb19
112+
113+
bb3:
114+
cond_br undef, bb4, bb5
115+
116+
bb4:
117+
br bb17
118+
119+
bb5:
120+
cond_br undef, bb9, bb6
121+
122+
bb6:
123+
cond_br undef, bb8, bb7
124+
125+
bb7:
126+
br bb12
127+
128+
bb8:
129+
br bb11
130+
131+
bb9:
132+
br bb10
133+
134+
bb10:
135+
br bb19
136+
137+
bb11:
138+
br bb17
139+
140+
bb12:
141+
cond_br undef, bb16, bb13
142+
143+
bb13:
144+
cond_br undef, bb15, bb14
145+
146+
bb14:
147+
br bb12
148+
149+
bb15:
150+
br bb11
151+
152+
bb16:
153+
br bb10
154+
155+
bb17:
156+
br bb18
157+
158+
bb18:
159+
%19 = function_ref @c2 : $@convention(thin) (@guaranteed C) -> @owned C
160+
specify_test "update_ssa %0 %2 @instruction[+3].operand @instruction[+1].operand @instruction[+0].operand[1]"
161+
%20 = apply %19(%2) : $@convention(thin) (@guaranteed C) -> @owned C
162+
destroy_value %2
163+
cond_br undef, bb20, bb21
164+
bb19:
165+
destroy_value %2
166+
br bb22
167+
168+
bb20:
169+
destroy_value %20
170+
br bb22
171+
172+
bb21:
173+
br bb1(%20)
174+
175+
bb22:
176+
%28 = tuple ()
177+
return %28
178+
179+
bb23:
180+
br bb3
181+
182+
}

0 commit comments

Comments
 (0)