forked from OSchip/llvm-project
Fix Codegen adding a second exit out of region
executeScopConditionally would destroy a predecessor region if it the scop's entry was the region's exit block by forking it to polly.start and thus creating a secnd exit out of the region. This patch "shrinks" the predecessor region s.t. polly.split_new_and_old is not the region's exit anymore. llvm-svn: 245294
This commit is contained in:
parent
a6593ff613
commit
d2b0360197
|
@ -103,6 +103,18 @@ BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) {
|
|||
splitEdge(EnteringBB, EntryBB, ".split_new_and_old", &DT, &LI, &RI);
|
||||
SplitBlock->setName("polly.split_new_and_old");
|
||||
|
||||
// If EntryBB is the exit block of the region that includes Prev, exclude
|
||||
// SplitBlock from that region by making it itself the exit block. This is
|
||||
// trivially possible because there is just one edge to EnteringBB.
|
||||
// This is necessary because we will add an outgoing edge from SplitBlock,
|
||||
// which would violate the single exit block requirement of PrevRegion.
|
||||
Region *PrevRegion = RI.getRegionFor(EnteringBB);
|
||||
while (PrevRegion->getExit() == EntryBB) {
|
||||
PrevRegion->replaceExit(SplitBlock);
|
||||
PrevRegion = PrevRegion->getParent();
|
||||
}
|
||||
RI.setRegionFor(SplitBlock, PrevRegion);
|
||||
|
||||
// Create a join block
|
||||
BasicBlock *ExitingBB = R.getExitingBlock();
|
||||
BasicBlock *ExitBB = R.getExit();
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
; RUN: opt %loadPolly -polly-detect-unprofitable -polly-no-early-exit -polly-detect -analyze < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly -polly-detect-unprofitable -polly-no-early-exit -polly-codegen -verify-region-info -analyze < %s
|
||||
;
|
||||
; This is a scop directly precedented by a region, i.e. the scop's entry is the
|
||||
; region's exit block. This test is to ensure that the RegionInfo is correctly
|
||||
; preserved.
|
||||
;
|
||||
; CHECK: Valid Region for Scop: region2 => return
|
||||
;
|
||||
define void @f1(i64* %A, i64 %N) nounwind {
|
||||
entry:
|
||||
br label %region1
|
||||
|
||||
region1:
|
||||
%indvar1 = phi i64 [ 0, %entry ], [ %indvar1.next, %region1 ]
|
||||
fence seq_cst
|
||||
%indvar1.next = add nsw i64 %indvar1, 1
|
||||
%exitcond1 = icmp eq i64 %indvar1.next, %N
|
||||
br i1 %exitcond1, label %region2, label %region1
|
||||
|
||||
region2:
|
||||
%indvar2 = phi i64 [ 0, %region1 ], [ %indvar2.next, %region2 ]
|
||||
%scevgep2 = getelementptr i64, i64* %A, i64 %indvar2
|
||||
store i64 %indvar2, i64* %scevgep2
|
||||
%indvar2.next = add nsw i64 %indvar2, 1
|
||||
%exitcond2 = icmp eq i64 %indvar2.next, %N
|
||||
br i1 %exitcond2, label %return, label %region2
|
||||
|
||||
return:
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue