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);
|
splitEdge(EnteringBB, EntryBB, ".split_new_and_old", &DT, &LI, &RI);
|
||||||
SplitBlock->setName("polly.split_new_and_old");
|
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
|
// Create a join block
|
||||||
BasicBlock *ExitingBB = R.getExitingBlock();
|
BasicBlock *ExitingBB = R.getExitingBlock();
|
||||||
BasicBlock *ExitBB = R.getExit();
|
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