Skip to content

Commit aebebd9

Browse files
authored
Merge pull request #84463 from MAJKFL/fix-licm-missing-earlier-materializable-projection-check
LICM fix missing materializable projection check
2 parents 5d26d0a + 6788017 commit aebebd9

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
@@ -1001,8 +1001,20 @@ private extension LoadInst {
10011001
}
10021002

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

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)