Skip to content

Commit f8c8288

Browse files
committed
Fix wrong combination of MemoryBehavior.
Instead of taking the maximum we need to handle the special case MayRead + MayWrite = MayReadWrite
1 parent b05363b commit f8c8288

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,21 @@ class SILInstruction : public ValueBase,public llvm::ilist_node<SILInstruction>{
282282
bool isTriviallyDuplicatable() const;
283283
};
284284

285+
/// Returns the combined behavior of \p B1 and \p B2.
286+
inline SILInstruction::MemoryBehavior
287+
combineMemoryBehavior(SILInstruction::MemoryBehavior B1,
288+
SILInstruction::MemoryBehavior B2) {
289+
// Basically the combined behavior is the maximum of both operands.
290+
auto Result = std::max(B1, B2);
291+
292+
// With one exception: MayRead, MayWrite -> MayReadWrite.
293+
if (Result == SILInstruction::MemoryBehavior::MayWrite &&
294+
(B1 == SILInstruction::MemoryBehavior::MayRead ||
295+
B2 == SILInstruction::MemoryBehavior::MayRead))
296+
return SILInstruction::MemoryBehavior::MayReadWrite;
297+
return Result;
298+
}
299+
285300
#ifndef NDEBUG
286301
/// Pretty-print the MemoryBehavior.
287302
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,13 @@ MemBehavior MemoryBehaviorVisitor::visitApplyInst(ApplyInst *AI) {
253253
Idx < End && Behavior < MemBehavior::MayHaveSideEffects; ++Idx) {
254254
auto &ArgEffect = ApplyEffects.getParameterEffects()[Idx];
255255
auto ArgBehavior = ArgEffect.getMemBehavior(InspectionMode);
256-
if (ArgBehavior > Behavior) {
256+
auto NewBehavior = combineMemoryBehavior(Behavior, ArgBehavior);
257+
if (NewBehavior != Behavior) {
257258
SILValue Arg = AI->getArgument(Idx);
258259
// We only consider the argument effects if the argument aliases V.
259260
if (!Arg.getType().isAddress() ||
260261
!AA->isNoAlias(Arg, V, computeTBAAType(Arg), getValueTBAAType())) {
261-
Behavior = ArgBehavior;
262+
Behavior = NewBehavior;
262263
}
263264
}
264265
}

lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ FunctionEffects::getMemBehavior(RetainObserveKind ScanKind) const {
3737
for (auto &ParamEffect : ParamEffects) {
3838
MemoryBehavior ArgBehavior = ParamEffect.getMemBehavior(ScanKind);
3939

40-
if (ArgBehavior > Behavior)
41-
Behavior = ArgBehavior;
40+
Behavior = combineMemoryBehavior(Behavior, ArgBehavior);
4241

4342
// Stop the scan if we've reached the highest level of side effect.
4443
if (Behavior == MemoryBehavior::MayHaveSideEffects)

test/SILOptimizer/mem-behavior.sil

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,32 @@ bb0(%0 : $*X):
167167
return %2 : $()
168168
}
169169

170+
struct TwoInts {
171+
var i1 : Int32
172+
var i2 : Int32
173+
}
174+
175+
// CHECK-LABEL: @combination_of_read_and_write_effects
176+
// CHECK: PAIR #1.
177+
// CHECK-NEXT: (0): %4 = apply %3(%1, %2) : $@convention(thin) (@inout Int32, @inout Int32) -> ()
178+
// CHECK-NEXT: (1): %0 = alloc_stack $TwoInts // users: %1, %2, %5
179+
// CHECK-NEXT: r=1,w=1,se=1
180+
sil @combination_of_read_and_write_effects : $@convention(thin) () -> () {
181+
bb0:
182+
%0 = alloc_stack $TwoInts
183+
%1 = struct_element_addr %0#1 : $*TwoInts, #TwoInts.i1
184+
%2 = struct_element_addr %0#1 : $*TwoInts, #TwoInts.i2
185+
%3 = function_ref @copy_ints : $@convention(thin) (@inout Int32, @inout Int32) -> ()
186+
apply %3 (%1, %2) : $@convention(thin) (@inout Int32, @inout Int32) -> ()
187+
dealloc_stack %0#0 : $*@local_storage TwoInts
188+
%r = tuple()
189+
return %r : $()
190+
}
191+
192+
sil @copy_ints : $@convention(thin) (@inout Int32, @inout Int32) -> () {
193+
bb0(%0 : $*Int32, %1 : $*Int32):
194+
%2 = load %0 : $*Int32
195+
store %2 to %1 : $*Int32
196+
%r = tuple()
197+
return %r : $()
198+
}

0 commit comments

Comments
 (0)