Skip to content

Commit a83148d

Browse files
committed
AccessUtils: fix handling of indexing in overlap checks
Indexing is not a projection where the base overlaps the "projected" address. Fixes a miscompile. rdar://115747816
1 parent 8e923e1 commit a83148d

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/AccessUtils.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,13 @@ struct AccessPath : CustomStringConvertible {
329329
if !base.isEqual(to: other.base) {
330330
return nil
331331
}
332-
return projectionPath.subtract(from: other.projectionPath)
332+
if let resultPath = projectionPath.subtract(from: other.projectionPath),
333+
// Indexing is not a projection where the base overlaps the projected address.
334+
!resultPath.pop().kind.isIndexedElement
335+
{
336+
return resultPath
337+
}
338+
return nil
333339
}
334340

335341
/// Like `getProjection`, but also requires that the resulting projection path is materializable.

SwiftCompilerSources/Sources/SIL/SmallProjectionPath.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public struct SmallProjectionPath : Hashable, CustomStringConvertible, NoReflect
103103
}
104104
}
105105

106-
var isIndexedElement: Bool {
106+
public var isIndexedElement: Bool {
107107
switch self {
108108
case .anyIndexedElement, .indexedElement:
109109
return true

test/SILOptimizer/dead_store_elim.sil

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,3 +1660,35 @@ bb0(%0 : $*(Klass, Klass)):
16601660
%7 = tuple ()
16611661
return %7 : $()
16621662
}
1663+
1664+
// CHECK-LABEL: sil @indexing_is_not_overlapping :
1665+
// CHECK: store %0
1666+
// CHECK: store %0
1667+
// CHECK: end sil function 'indexing_is_not_overlapping'
1668+
sil @indexing_is_not_overlapping : $@convention(thin) (Int, Builtin.RawPointer) -> () {
1669+
bb0(%0 : $Int, %1 : $Builtin.RawPointer):
1670+
%2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Int
1671+
%3 = integer_literal $Builtin.Word, 3
1672+
%4 = index_addr [stack_protection] %2 : $*Int, %3 : $Builtin.Word
1673+
store %0 to %4 : $*Int
1674+
store %0 to %2 : $*Int
1675+
%r = tuple ()
1676+
return %r : $()
1677+
}
1678+
1679+
// CHECK-LABEL: sil @indexing_is_not_overlapping2 :
1680+
// CHECK: store %1
1681+
// CHECK: store %0
1682+
// CHECK: end sil function 'indexing_is_not_overlapping2'
1683+
sil @indexing_is_not_overlapping2 : $@convention(thin) (Int, Builtin.Int64, Builtin.RawPointer) -> () {
1684+
bb0(%0 : $Int, %1 : $Builtin.Int64, %2 : $Builtin.RawPointer):
1685+
%3 = pointer_to_address %2 : $Builtin.RawPointer to [strict] $*Int
1686+
%4 = integer_literal $Builtin.Word, 3
1687+
%5 = index_addr [stack_protection] %3 : $*Int, %4 : $Builtin.Word
1688+
%6 = struct_element_addr %5 : $*Int, #Int.value
1689+
store %1 to %6 : $*Builtin.Int64
1690+
store %0 to %3 : $*Int
1691+
%r = tuple ()
1692+
return %r : $()
1693+
}
1694+

0 commit comments

Comments
 (0)