Skip to content

Commit b0c9e69

Browse files
committed
SideEffectAnalysis: don't assume that arguments with trivial type cannot be pointers.
Even values of trivial type can contain a Builtin.RawPointer, which can be used to read/write from/to. To compensate for the removed check, enable the escape-analysis check in MemBehavior (as it was before). This fixes a recently introduced miscompile. rdar://problem/70220876
1 parent 4512717 commit b0c9e69

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,7 @@ class MemoryBehaviorVisitor
215215
SIMPLE_MEMBEHAVIOR_INST(CondFailInst, None)
216216
#undef SIMPLE_MEMBEHAVIOR_INST
217217

218-
// If we are asked to treat ref count increments as being inert, return None
219-
// for these.
220-
//
221-
// FIXME: Once we separate the notion of ref counts from reading/writing
222-
// memory this will be unnecessary.
218+
// Incrementing reference counts doesn't have an observable memory effect.
223219
#define REFCOUNTINC_MEMBEHAVIOR_INST(Name) \
224220
MemBehavior visit##Name(Name *I) { \
225221
return MemBehavior::None; \
@@ -455,7 +451,7 @@ MemBehavior MemoryBehaviorVisitor::getApplyBehavior(FullApplySite AS) {
455451
behavior = MemBehavior::MayRead;
456452

457453
// Ask escape analysis.
458-
if (!nonEscapingAddress && !EA->canEscapeTo(V, AS))
454+
if (!EA->canEscapeTo(V, AS))
459455
behavior = MemBehavior::None;
460456
}
461457
LLVM_DEBUG(llvm::dbgs() << " Found apply, returning " << behavior << '\n');

lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,6 @@ FunctionSideEffects::getMemBehavior(RetainObserveKind ScanKind) const {
222222
MemoryBehavior
223223
FunctionSideEffects::getArgumentBehavior(FullApplySite applySite,
224224
unsigned argIdx) {
225-
// Rule out trivial non-address argument types.
226-
SILType argType = applySite.getArgument(argIdx)->getType();
227-
if (!argType.isAddress() && argType.isTrivial(*applySite.getFunction()))
228-
return MemoryBehavior::None;
229-
230225
// The overall argument effect is the combination of the argument and the
231226
// global effects.
232227
MemoryBehavior behavior =

test/SILOptimizer/dead_store_elim.sil

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,28 @@ bb3:
469469
return %9999 : $()
470470
}
471471

472+
sil @read_from_raw_pointer : $@convention(thin) (Builtin.RawPointer) -> UInt8 {
473+
bb0(%0 : $Builtin.RawPointer):
474+
%1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*UInt8
475+
%2 = load %1 : $*UInt8
476+
return %2 : $UInt8
477+
}
478+
479+
// CHECK-LABEL: sil @dont_remove_store_to_escaping_allocstack_to_known_function : $@convention(thin) (UInt8) -> UInt8
480+
// CHECK: alloc_stack
481+
// CHECK-NEXT: store
482+
// CHECK: } // end sil function 'dont_remove_store_to_escaping_allocstack_to_known_function'
483+
sil @dont_remove_store_to_escaping_allocstack_to_known_function : $@convention(thin) (UInt8) -> UInt8 {
484+
bb0(%0 : $UInt8):
485+
%1 = alloc_stack $UInt8
486+
store %0 to %1 : $*UInt8
487+
%3 = address_to_pointer %1 : $*UInt8 to $Builtin.RawPointer
488+
%4 = function_ref @read_from_raw_pointer : $@convention(thin) (Builtin.RawPointer) -> UInt8
489+
%5 = apply %4(%3) : $@convention(thin) (Builtin.RawPointer) -> UInt8
490+
dealloc_stack %1 : $*UInt8
491+
return %5 : $UInt8
492+
}
493+
472494
sil @unknown : $@convention(thin) () -> ()
473495

474496
// CHECK-LABEL: sil @inout_is_not_aliasing : $@convention(thin) (@inout Builtin.Int32) -> () {

test/SILOptimizer/mem-behavior.sil

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ bb0(%0 : $X):
3535
return %r : $()
3636
}
3737

38+
sil @read_from_raw_pointer : $@convention(thin) (Builtin.RawPointer) -> UInt8 {
39+
bb0(%0 : $Builtin.RawPointer):
40+
%1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*UInt8
41+
%2 = load %1 : $*UInt8
42+
return %2 : $UInt8
43+
}
44+
3845
// CHECK-LABEL: @call_unknown_func
3946
// CHECK: PAIR #1.
4047
// CHECK-NEXT: %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @in Int32) -> ()
@@ -224,6 +231,21 @@ bb0(%0 : $*Int32):
224231
return %5 : $Int32
225232
}
226233

234+
// CHECK-LABEL: @escaping_allocstack_to_known_function
235+
// CHECK: PAIR #1.
236+
// CHECK-NEXT: %5 = apply %4(%3) : $@convention(thin) (Builtin.RawPointer) -> UInt8 // user: %7
237+
// CHECK-NEXT: %1 = alloc_stack $UInt8 // users: %6, %3, %2
238+
// CHECK-NEXT: r=1,w=0
239+
sil @escaping_allocstack_to_known_function : $@convention(thin) (UInt8) -> UInt8 {
240+
bb0(%0 : $UInt8):
241+
%1 = alloc_stack $UInt8
242+
store %0 to %1 : $*UInt8
243+
%3 = address_to_pointer %1 : $*UInt8 to $Builtin.RawPointer
244+
%4 = function_ref @read_from_raw_pointer : $@convention(thin) (Builtin.RawPointer) -> UInt8
245+
%5 = apply %4(%3) : $@convention(thin) (Builtin.RawPointer) -> UInt8
246+
dealloc_stack %1 : $*UInt8
247+
return %5 : $UInt8
248+
}
227249

228250
// CHECK-LABEL: @tryapply_allocstack_and_copyaddr
229251
// CHECK: PAIR #0.

0 commit comments

Comments
 (0)