Skip to content

Commit 90cbaec

Browse files
authored
Merge pull request #78781 from eeckstein/fix-loop-rotate
LoopRotate: don't rotate loops where the header block branches to a dead-end block.
2 parents e268842 + 5dc80f6 commit 90cbaec

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

lib/SILOptimizer/LoopTransforms/LoopRotate.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/SIL/SILBuilder.h"
1919
#include "swift/SIL/SILInstruction.h"
2020
#include "swift/SILOptimizer/Analysis/Analysis.h"
21+
#include "swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
2122
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
2223
#include "swift/SILOptimizer/Analysis/LoopAnalysis.h"
2324
#include "swift/SILOptimizer/PassManager/Passes.h"
@@ -374,6 +375,15 @@ static bool rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
374375
return false;
375376
}
376377

378+
// Incomplete liveranges in the dead-end exit block can cause a missing adjacent
379+
// phi-argument for a re-borrow if there is a borrow-scope is in the loop.
380+
// But even when we have complete lifetimes, it's probably not worth rotating
381+
// a loop where the header block branches to a dead-end block.
382+
auto *deBlocks = pm->getAnalysis<DeadEndBlocksAnalysis>()->get(exit->getParent());
383+
if (deBlocks->isDeadEnd(exit)) {
384+
return false;
385+
}
386+
377387
// We don't want to rotate such that we merge two headers of separate loops
378388
// into one. This can be turned into an assert again once we have guaranteed
379389
// preheader insertions.

test/SILOptimizer/looprotate_ossa.sil

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Bar {
1818
@objc func foo_objc()
1919
}
2020

21+
sil [ossa] @getBar : $@convention(thin) () -> @owned Bar
2122
sil [ossa] @_TFC4main3Bar3foofS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> ()
2223
sil [ossa] @_TFC4main3Bar3boofS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> Int64
2324
sil [ossa] @_TFC4main3Bar3foo_objcfS0_FT_T_ : $@convention(objc_method) (Bar) -> ()
@@ -713,3 +714,39 @@ bb14:
713714
return %27
714715
}
715716

717+
// Incomplete liveranges in dead-end exit blocks can cause a missing phi in the rotated loop.
718+
// CHECK-LABEL: sil [ossa] @incomplete_liverange_in_dead_end_exit :
719+
// CHECK: bb1:
720+
// CHECK: apply
721+
// CHECK: bb2:
722+
// CHECK-LABEL: } // end sil function 'incomplete_liverange_in_dead_end_exit'
723+
sil [ossa] @incomplete_liverange_in_dead_end_exit : $@convention(thin) () -> () {
724+
bb0:
725+
br bb1
726+
727+
bb1:
728+
%1 = function_ref @getBar : $@convention(thin) () -> @owned Bar
729+
%2 = apply %1() : $@convention(thin) () -> @owned Bar
730+
%3 = begin_borrow %2
731+
cond_br undef, bb3, bb2
732+
733+
bb2:
734+
br bb4
735+
736+
bb3:
737+
end_borrow %3
738+
unreachable
739+
740+
bb4:
741+
end_borrow %3
742+
destroy_value %2
743+
cond_br undef, bb6, bb5
744+
745+
bb5:
746+
br bb1
747+
748+
bb6:
749+
%12 = tuple ()
750+
return %12
751+
}
752+

0 commit comments

Comments
 (0)