Skip to content

Commit 6788017

Browse files
committed
Add earlier check before load projection that bails when it's not materializable.
1 parent f78a3c7 commit 6788017

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LoopInvariantCodeMotion.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -998,8 +998,20 @@ private extension LoadInst {
998998
}
999999

10001000
func overlaps(accessPath: AccessPath) -> Bool {
1001-
// Don't use `AccessPath.mayOverlap`. We only want definite overlap.
1002-
return accessPath.isEqualOrContains(self.operand.value.accessPath) || self.operand.value.accessPath.isEqualOrContains(accessPath)
1001+
if let path = accessPath.getProjection(to: self.operand.value.accessPath),
1002+
// If the accessPath is wider than load, it needs to be materializable.
1003+
// Otherwise we won't be able to project it.
1004+
path.isMaterializable {
1005+
// The load is narrower than the access path.
1006+
return true
1007+
}
1008+
1009+
if self.operand.value.accessPath.isEqualOrContains(accessPath) {
1010+
// The load is wider than the access path.
1011+
return true
1012+
}
1013+
1014+
return false
10031015
}
10041016
}
10051017

test/SILOptimizer/licm.sil

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,45 @@ bb6:
586586
return %12 : $()
587587
}
588588

589+
// CHECK-LABEL: sil @dont_sink_store_with_nonmaterializable_load_projection
590+
// CHECK: alloc_stack
591+
// CHECK-NOT: store
592+
// CHECK: bb1(%8 : $Builtin.Int64, %9 : $Builtin.Int64):
593+
// CHECK: store
594+
// CHECK: [[INDEXADDR:%.*]] = index_addr
595+
// CHECK: load [[INDEXADDR]]
596+
// CHECK: bb3:
597+
// CHECK-NOT: store
598+
// CHECK: dealloc_stack
599+
// CHECK: } // end sil function 'dont_sink_store_with_nonmaterializable_load_projection'
600+
sil @dont_sink_store_with_nonmaterializable_load_projection : $@convention(method) (InlineArray<3, Int>) -> () {
601+
bb0(%0 : $InlineArray<3, Int>):
602+
%1 = integer_literal $Builtin.Int64, 0
603+
%2 = integer_literal $Builtin.Int64, 1
604+
%3 = integer_literal $Builtin.Int1, -1
605+
%4 = struct_extract %0, #InlineArray._storage
606+
%5 = alloc_stack $Builtin.FixedArray<3, Int>
607+
%6 = vector_base_addr %5
608+
br bb1(%1, %1)
609+
610+
bb1(%8 : $Builtin.Int64, %9 : $Builtin.Int64):
611+
%10 = builtin "sadd_with_overflow_Int64"(%8, %2, %3) : $(Builtin.Int64, Builtin.Int1)
612+
%11 = tuple_extract %10, 0
613+
store %4 to %5
614+
%13 = builtin "truncOrBitCast_Int64_Word"(%9) : $Builtin.Word
615+
%14 = index_addr [stack_protection] %6, %13
616+
%15 = load %14
617+
cond_br undef, bb2, bb3
618+
619+
bb2:
620+
br bb1(%1, %1)
621+
622+
bb3:
623+
dealloc_stack %5
624+
%18 = tuple ()
625+
return %18
626+
}
627+
589628
// CHECK-LABEL: sil @hoist_loads_and_stores_multiple_exits
590629
// CHECK: [[V1:%[0-9]+]] = load %0
591630
// CHECK: br bb1([[V1]] : $Int32)

0 commit comments

Comments
 (0)