Skip to content

Commit 366514b

Browse files
Merge pull request #69202 from nate-chandler/opaque-values/20231016/1/single-phi-incoming-value
[AddressLowering] Fixed single arg phi edge case.
2 parents 3180b16 + 43d26ce commit 366514b

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed

lib/SILOptimizer/Mandatory/PhiStorageOptimizer.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,14 @@ void CoalescedPhi::coalesce(PhiValue phi,
168168
void PhiStorageOptimizer::optimize() {
169169
// The single incoming value case always projects storage.
170170
if (auto *predecessor = phi.phiBlock->getSinglePredecessorBlock()) {
171-
coalescedPhi.coalescedOperands.push_back(phi.getOperand(predecessor));
171+
if (canCoalesceValue(phi.getValue()->getIncomingPhiValue(predecessor))) {
172+
// Storage will always be allocated for the phi. The optimization
173+
// attempts to let incoming values reuse the phi's storage. This isn't
174+
// always possible, even in the single incoming value case. For example,
175+
// it isn't possible when the incoming value is a function argument or
176+
// when the incoming value is already a projection.
177+
coalescedPhi.coalescedOperands.push_back(phi.getOperand(predecessor));
178+
}
172179
return;
173180
}
174181
for (auto *incomingPred : phi.phiBlock->getPredecessorBlocks()) {

test/SILOptimizer/address_lowering.sil

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,8 +1427,10 @@ nopers(%error : @owned $any Error):
14271427

14281428
// CHECK-LABEL: sil [ossa] @f262_testTryApplyIntoPhi : {{.*}} {
14291429
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] :
1430-
// CHECK: try_apply undef<R>([[ADDR]]) {{.*}}, normal [[NORMAL:bb[0-9]+]]
1431-
// CHECK: [[NORMAL]](%2 : $()):
1430+
// CHECK: [[STACK:%[^,]+]] = alloc_stack
1431+
// CHECK: try_apply undef<R>([[STACK]]) {{.*}}, normal [[NORMAL:bb[0-9]+]]
1432+
// CHECK: [[NORMAL]]({{%[^,]+}} : $()):
1433+
// CHECK: copy_addr [take] [[STACK]] to [init] [[ADDR]]
14321434
// CHECK: br [[EXIT:bb[0-9]+]]
14331435
// CHECK: [[EXIT]]:
14341436
// CHECK: return {{%[^,]+}} : $()

test/SILOptimizer/address_lowering_phi.sil

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ enum OuterEnum<T> {
3030
case inner(InnerEnum<T>, AnyObject)
3131
}
3232

33+
struct Box<T> {
34+
var t: T
35+
}
36+
3337
struct InnerStruct<T> {
3438
var t: T
3539
var object: AnyObject
@@ -536,3 +540,62 @@ exit(%instance_2 : @owned $T, %s_2 : $S):
536540
%retval = tuple ()
537541
return %retval : $()
538542
}
543+
544+
// Check behavior of non-coalesceable single incoming phi.
545+
// CHECK-LABEL: sil [ossa] @f120_single_phi_argument_forwarded_function_argument : {{.*}} {
546+
// CHECK: bb0([[T:%[^,]+]] :
547+
// CHECK: [[STORAGE:%[^,]+]] = alloc_stack
548+
// CHECK: copy_addr [take] [[T]] to [init] [[STORAGE]]
549+
// CHECK: br [[EXIT:bb[0-9]+]]
550+
// CHECK: [[EXIT]]:
551+
// CHECK: destroy_addr [[STORAGE]]
552+
// CHECK: dealloc_stack [[STORAGE]]
553+
// CHECK-LABEL: } // end sil function 'f120_single_phi_argument_forwarded_function_argument'
554+
sil [ossa]@f120_single_phi_argument_forwarded_function_argument : $@convention(thin) <T> (@in T) -> () {
555+
entry(%t : @owned $T):
556+
br exit(%t : $T)
557+
558+
exit(%t2 : @owned $T):
559+
destroy_value %t2 : $T
560+
%retval = tuple ()
561+
return %retval : $()
562+
}
563+
564+
// CHECK-LABEL: sil [ossa] @f121_single_phi_argument_forwarded_function_argument_returned : {{.*}} {
565+
// CHECK: bb0([[OUT:%[^,]+]] :
566+
// CHECK-SAME: [[IN:%[^,]+]] :
567+
// CHECK: copy_addr [take] [[IN]] to [init] [[OUT]]
568+
// CHECK: br [[EXIT:bb[0-9]+]]
569+
// CHECK: [[EXIT]]:
570+
// CHECK-LABEL: } // end sil function 'f121_single_phi_argument_forwarded_function_argument_returned'
571+
sil [ossa]@f121_single_phi_argument_forwarded_function_argument_returned : $@convention(thin) <T> (@in T) -> @out T {
572+
entry(%t : @owned $T):
573+
br exit(%t : $T)
574+
575+
exit(%t2 : @owned $T):
576+
return %t2 : $T
577+
}
578+
579+
// CHECK-LABEL: sil [ossa] @f122_single_phi_argument_destructure : $@convention(thin) <T> () -> () {
580+
// CHECK: [[PHI_ADDR:%[^,]+]] = alloc_stack $T
581+
// CHECK: [[BOX_ADDR:%[^,]+]] = alloc_stack $Box<T>
582+
// CHECK: apply undef<T>([[BOX_ADDR]])
583+
// CHECK: [[T_ADDR:%[^,]+]] = struct_element_addr [[BOX_ADDR]] : $*Box<T>, #Box.t
584+
// CHECK: copy_addr [take] [[T_ADDR]] to [init] [[PHI_ADDR]]
585+
// CHECK: br [[EXIT:bb[0-9]+]]
586+
// CHECK: [[EXIT]]:
587+
// CHECK: destroy_addr [[PHI_ADDR]]
588+
// CHECK: dealloc_stack [[BOX_ADDR]]
589+
// CHECK: dealloc_stack [[PHI_ADDR]]
590+
// CHECK-LABEL: } // end sil function 'f122_single_phi_argument_destructure'
591+
sil [ossa]@f122_single_phi_argument_destructure : $@convention(thin) <T> () -> () {
592+
entry:
593+
%box = apply undef<T>() : $@convention(thin) <T> () -> (@out Box<T>)
594+
%t = destructure_struct %box : $Box<T>
595+
br exit(%t : $T)
596+
597+
exit(%t2 : @owned $T):
598+
destroy_value %t2 : $T
599+
%retval = tuple ()
600+
return %retval : $()
601+
}

0 commit comments

Comments
 (0)