diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp index 91be1aa3b056..5dd227990c73 100644 --- a/polly/lib/CodeGen/BlockGenerators.cpp +++ b/polly/lib/CodeGen/BlockGenerators.cpp @@ -1012,6 +1012,8 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S, assert(Stmt.isRegionStmt() && "Only region statements can be copied by the region generator"); + Scop *S = Stmt.getParent(); + // Forget all old mappings. BlockMap.clear(); RegionMaps.clear(); @@ -1037,6 +1039,17 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S, if (!R->contains(*PI)) BlockMap[*PI] = EntryBBCopy; + // Determine the original exit block of this subregion. If it the exit block + // is also the scop's exit, it it has been changed to polly.merge_new_and_old. + // We move one block back to find the original block. This only happens if the + // scop required simplification. + // If the whole scop consists of only this non-affine region, then they share + // the same Region object, such that we cannot change the exit of one and not + // the other. + BasicBlock *ExitBB = R->getExit(); + if (!S->hasSingleExitEdge() && ExitBB == S->getRegion().getExit()) + ExitBB = *(++pred_begin(ExitBB)); + // Iterate over all blocks in the region in a breadth-first search. std::deque Blocks; SmallPtrSet SeenBlocks; @@ -1078,7 +1091,7 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S, Blocks.push_back(*SI); // Remember value in case it is visible after this subregion. - if (DT.dominates(BB, R->getExit())) + if (DT.dominates(BB, ExitBB)) ValueMap.insert(RegionMap.begin(), RegionMap.end()); } @@ -1088,7 +1101,10 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S, ExitBBCopy->setName("polly.stmt." + R->getExit()->getName() + ".exit"); BlockMap[R->getExit()] = ExitBBCopy; - repairDominance(R->getExit(), ExitBBCopy); + if (ExitBB == R->getExit()) + repairDominance(ExitBB, ExitBBCopy); + else + DT.changeImmediateDominator(ExitBBCopy, BlockMap.lookup(ExitBB)); // As the block generator doesn't handle control flow we need to add the // region control flow by hand after all blocks have been copied. diff --git a/polly/test/Isl/CodeGen/non-affine-exit-node-dominance.ll b/polly/test/Isl/CodeGen/non-affine-exit-node-dominance.ll new file mode 100644 index 000000000000..077dd2de5007 --- /dev/null +++ b/polly/test/Isl/CodeGen/non-affine-exit-node-dominance.ll @@ -0,0 +1,30 @@ +; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s +; +; llvm.org/PR25439 +; The dominance of the generated non-affine subregion block was based on the +; scop's merge block, therefore resulted in an invalid DominanceTree. +; It resulted in some values as assumed to be unusable in the actual generated +; exit block. Here we check whether the value %escaping is taken from the +; generated block. +; +; CHECK-LABEL: polly.stmt.subregion_entry: +; CHECK: %p_escaping = select i1 undef, i32 undef, i32 undef +; +; CHECK-LABEL: polly.stmt.polly.merge_new_and_old.exit: +; CHECK: store i32 %p_escaping, i32* %escaping.s2a + +define i32 @func() { +entry: + br label %subregion_entry + +subregion_entry: + %escaping = select i1 undef, i32 undef, i32 undef + %cond = or i1 undef, undef + br i1 %cond, label %subregion_exit, label %subregion_if + +subregion_if: + br label %subregion_exit + +subregion_exit: + ret i32 %escaping +} diff --git a/polly/test/Isl/CodeGen/non-affine-region-implicit-store.ll b/polly/test/Isl/CodeGen/non-affine-region-implicit-store.ll index a0c0ba4becd4..e31b872a7b81 100644 --- a/polly/test/Isl/CodeGen/non-affine-region-implicit-store.ll +++ b/polly/test/Isl/CodeGen/non-affine-region-implicit-store.ll @@ -1,5 +1,5 @@ ; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s -; XFAIL: * +; ; llvm.org/PR25438 ; After loop versioning, a dominance check of a non-affine subregion's exit node ; causes the dominance check to always fail any block in the scop. The @@ -13,7 +13,7 @@ ; CHECK: a.phiops.reload = load i32, i32* %a.phiops ; ; CHECK-LABEL: polly.stmt.polly.merge_new_and_old.exit: -; CHECK: store i32 %a.phiops.reload, i32* %a.s2a +; CHECK: store i32 %polly.a, i32* %a.s2a define void @func() { entry: diff --git a/polly/test/Isl/CodeGen/pr25241.ll b/polly/test/Isl/CodeGen/pr25241.ll index e3cf817d25cb..c8f9c59ade8c 100644 --- a/polly/test/Isl/CodeGen/pr25241.ll +++ b/polly/test/Isl/CodeGen/pr25241.ll @@ -6,10 +6,11 @@ ; CHECK-LABEL: polly.stmt.if.then.862: ; CHECK: %[[R1:[0-9]+]] = add i32 %tmp, 1 +; CHECK: store i32 %0, i32* %curr.3.s2a ; CHECK: br label -; CHECK-LABEL: polly.stmt.while.body.740.region_exiting: -; CHECK: %polly.curr.3.ph = phi i32 [ undef, %polly.stmt.if.else.864 ], [ %[[R1]], %polly.stmt.if.then.862 ] +; CHECK-LABEL: polly.stmt.polly.merge_new_and_old.exit: +; CHECK: %curr.3.ph.final_reload = load i32, i32* %curr.3.s2a ; CHECK: br label