Index: include/polly/CodeGen/BlockGenerators.h =================================================================== --- include/polly/CodeGen/BlockGenerators.h +++ include/polly/CodeGen/BlockGenerators.h @@ -403,8 +403,10 @@ /// @param Inst The current instruction we check. /// @param InstCopy The copy of the instruction @p Inst in the optimized /// SCoP. - void handleOutsideUsers(const Region &R, ValueMapT &GlobalMap, - Instruction *Inst, Value *InstCopy); + /// @param Address If given it is used as the escape address for @p Inst. + void handleOutsideUsers(const Region &R, ValueMapT *GlobalMap, + Instruction *Inst, Value *InstCopy, + AllocaInst *Address = nullptr); /// @brief Initialize the memory of demoted scalars. /// Index: include/polly/ScopDetection.h =================================================================== --- include/polly/ScopDetection.h +++ include/polly/ScopDetection.h @@ -223,13 +223,6 @@ /// @return True if all blocks in R are valid, false otherwise. bool allBlocksValid(DetectionContext &Context) const; - /// @brief Check the exit block of a region is valid. - /// - /// @param Context The context of scop detection. - /// - /// @return True if the exit of R is valid, false otherwise. - bool isValidExit(DetectionContext &Context) const; - /// @brief Check if a region is a Scop. /// /// @param Context The context of scop detection. Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -796,6 +796,9 @@ /// Flag to indicate that the scheduler actually optimized the SCoP. bool IsOptimized; + /// @brief True if the underlying region has a single exiting block. + bool HasSingleExitEdge; + /// Max loop depth. unsigned MaxLoopDepth; @@ -1189,6 +1192,9 @@ /// @brief Align the parameters in the statement to the scop context void realignParams(); + /// @brief Return true if the underlying region has a single exiting block. + bool hasSingleExitEdge() const { return HasSingleExitEdge; } + /// @brief Print the static control part. /// /// @param OS The output stream the static control part is printed to. Index: include/polly/TempScopInfo.h =================================================================== --- include/polly/TempScopInfo.h +++ include/polly/TempScopInfo.h @@ -256,8 +256,9 @@ /// @param R The SCoP region /// @param Functions The access functions of the current BB /// @param NonAffineSubRegion The non affine sub-region @p PHI is in. + /// @param IsExitBlock Flag to indicate that @p PHI is in the exit BB. void buildPHIAccesses(PHINode *PHI, Region &R, AccFuncSetType &Functions, - Region *NonAffineSubRegion); + Region *NonAffineSubRegion, bool IsExitBlock = false); /// @brief Build the access functions for the subregion @p SR. /// @@ -270,8 +271,10 @@ /// @param R The SCoP region. /// @param BB A basic block in @p R. /// @param NonAffineSubRegion The non affine sub-region @p BB is in. + /// @param IsExitBlock Flag to indicate that @p BB is in the exit BB. void buildAccessFunctions(Region &R, BasicBlock &BB, - Region *NonAffineSubRegion = nullptr); + Region *NonAffineSubRegion = nullptr, + bool IsExitBlock = false); public: static char ID; Index: lib/Analysis/ScopDetection.cpp =================================================================== --- lib/Analysis/ScopDetection.cpp +++ lib/Analysis/ScopDetection.cpp @@ -814,8 +814,7 @@ DEBUG(dbgs() << "\t\tTrying " << ExpandedRegion->getNameStr() << "\n"); // Only expand when we did not collect errors. - // Check the exit first (cheap) - if (isValidExit(Context) && !Context.Log.hasErrors()) { + if (!Context.Log.hasErrors()) { // If the exit is valid check all blocks // - if true, a valid region was found => store it + keep expanding // - if false, .tbd. => stop (should this really end the loop?) @@ -957,18 +956,6 @@ return true; } -bool ScopDetection::isValidExit(DetectionContext &Context) const { - - // PHI nodes are not allowed in the exit basic block. - if (BasicBlock *Exit = Context.CurRegion.getExit()) { - BasicBlock::iterator I = Exit->begin(); - if (I != Exit->end() && isa(*I)) - return invalid(Context, /*Assert=*/true, I); - } - - return true; -} - bool ScopDetection::isValidRegion(DetectionContext &Context) const { Region &CurRegion = Context.CurRegion; @@ -1014,9 +1001,6 @@ if (!DetectUnprofitable && !hasMoreThanOneLoop(&CurRegion)) invalid(Context, /*Assert=*/true, &CurRegion); - if (!isValidExit(Context)) - return false; - if (!allBlocksValid(Context)) return false; Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1813,7 +1813,8 @@ Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, DominatorTree &DT, isl_ctx *Context, unsigned MaxLoopDepth) : DT(DT), SE(&ScalarEvolution), R(R), IsOptimized(false), - MaxLoopDepth(MaxLoopDepth), IslCtx(Context), Affinator(this) {} + HasSingleExitEdge(R.getExitingBlock()), MaxLoopDepth(MaxLoopDepth), + IslCtx(Context), Affinator(this) {} void Scop::initFromTempScop(TempScop &TempScop, LoopInfo &LI, ScopDetection &SD, AliasAnalysis &AA) { Index: lib/Analysis/TempScopInfo.cpp =================================================================== --- lib/Analysis/TempScopInfo.cpp +++ lib/Analysis/TempScopInfo.cpp @@ -92,8 +92,18 @@ void TempScopInfo::buildPHIAccesses(PHINode *PHI, Region &R, AccFuncSetType &Functions, - Region *NonAffineSubRegion) { - if (canSynthesize(PHI, LI, SE, &R)) + Region *NonAffineSubRegion, + bool IsExitBlock) { + + // PHI nodes that are in the ExitBlock of the region, hence if IsExitBlock is + // true, are not modelt as ordinary PHI nodes as they are not part of the + // region. However, we model the operands in the predecessor blocks that are + // part of the region as regular scalar accesses. + + // If we can synthesize a PHI we can skip it, however only if it is in + // the region. If it is not it can only be in the exit block of the region. + // In this case we model the operands but not the PHI itself. + if (!IsExitBlock && canSynthesize(PHI, LI, SE, &R)) return; // PHI nodes are modeled as if they had been demoted prior to the SCoP @@ -133,13 +143,13 @@ OpI = OpBB->getTerminator(); IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true, Op, - /* IsPHI */ true); + /* IsPHI */ !IsExitBlock); AccFuncMap[OpBB].push_back(std::make_pair(ScalarAccess, OpI)); } if (!OnlyNonAffineSubRegionOperands) { IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true, PHI, - /* IsPHI */ true); + /* IsPHI */ !IsExitBlock); Functions.push_back(std::make_pair(ScalarAccess, PHI)); } } @@ -297,7 +307,8 @@ } void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB, - Region *NonAffineSubRegion) { + Region *NonAffineSubRegion, + bool IsExitBlock) { AccFuncSetType Functions; Loop *L = LI->getLoopFor(&BB); @@ -306,6 +317,15 @@ for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) { Instruction *Inst = I; + + PHINode *PHI = dyn_cast(Inst); + if (PHI) + buildPHIAccesses(PHI, R, Functions, NonAffineSubRegion, IsExitBlock); + + // For the exit block we stop modeling after the last PHI node. + if (!PHI && IsExitBlock) + break; + if (isa(Inst) || isa(Inst)) Functions.push_back( std::make_pair(buildIRAccess(Inst, L, &R, BoxedLoops), Inst)); @@ -313,9 +333,6 @@ if (isIgnoredIntrinsic(Inst)) continue; - if (PHINode *PHI = dyn_cast(Inst)) - buildPHIAccesses(PHI, R, Functions, NonAffineSubRegion); - if (buildScalarDependences(Inst, &R, NonAffineSubRegion)) { // If the Instruction is used outside the statement, we need to build the // write access. @@ -339,6 +356,15 @@ buildAccessFunctions(R, R); + // In case the region does not have an exiting block we will later (during + // code generation) split the exit block. This will move potential PHI nodes + // in the exit block into the region that are at this point not part of it. + // To handle these PHI nodes later on we will model their operands as scalar + // accesses. Note that we do not model anything in the exit block if we have + // a exiting block in the region, hence there will not be any splitting later. + if (!R.getExitingBlock()) + buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true); + return TScop; } Index: lib/CodeGen/BlockGenerators.cpp =================================================================== --- lib/CodeGen/BlockGenerators.cpp +++ lib/CodeGen/BlockGenerators.cpp @@ -321,7 +321,7 @@ const Region &R = Stmt.getParent()->getRegion(); for (Instruction &Inst : *BB) - handleOutsideUsers(R, GlobalMap, &Inst, BBMap[&Inst]); + handleOutsideUsers(R, &GlobalMap, &Inst, BBMap[&Inst]); } Value *BlockGenerator::getOrCreateAlloca(Value *ScalarBase, @@ -363,8 +363,9 @@ return getOrCreateAlloca(ScalarBase, PHIOpMap, GlobalMap, ".phiops"); } -void BlockGenerator::handleOutsideUsers(const Region &R, ValueMapT &GlobalMap, - Instruction *Inst, Value *InstCopy) { +void BlockGenerator::handleOutsideUsers(const Region &R, ValueMapT *GlobalMap, + Instruction *Inst, Value *InstCopy, + AllocaInst *Address) { // If there are escape users we get the alloca for this instruction and put it // in the EscapeMap for later finalization. Lastly, if the instruction was // copied multiple times we already did this and can exit. @@ -391,7 +392,8 @@ // Get or create an escape alloca for this instruction. auto *ScalarAddr = - cast(getOrCreateScalarAlloca(Inst, &GlobalMap)); + Address ? Address + : cast(getOrCreateScalarAlloca(Inst, GlobalMap)); // Remember that this instruction has escape uses and the escape alloca. EscapeMap[Inst] = std::make_pair(ScalarAddr, std::move(EscapeUsers)); @@ -519,6 +521,11 @@ if (Inst && R.contains(Inst)) continue; + // PHI nodes that are not marked as such in their SAI object are exit PHI + // nodes we model as common scalars but do not need to initialize. + if (Inst && isa(Inst)) + continue; + ValueMapT EmptyMap; Builder.CreateStore(Array->getBasePtr(), getOrCreateScalarAlloca(Array->getBasePtr(), nullptr)); @@ -570,6 +577,23 @@ } void BlockGenerator::finalizeSCoP(Scop &S) { + + // Handle PHI nodes that were in the original exit and are now + // moved into the region exiting block. + if (!S.hasSingleExitEdge()) { + for (Instruction &I : *S.getRegion().getExitingBlock()) { + PHINode *PHI = dyn_cast(&I); + if (!PHI) + break; + + assert(PHI->getNumUses() == 1); + assert(ScalarMap.count(PHI->user_back())); + + handleOutsideUsers(S.getRegion(), nullptr, PHI, nullptr, + ScalarMap[PHI->user_back()]); + } + } + createScalarInitialization(S); createScalarFinalization(S.getRegion()); } Index: test/Isl/CodeGen/phi_in_exit_early_lnt_failure_1.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_in_exit_early_lnt_failure_1.ll @@ -0,0 +1,42 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s +; +; This caused an lnt crash at some point, just verify it will run through. +; +; CHECK-LABEL: polly.merge_new_and_old: +; CHECK-NEXT: br label %for.body.6 +; +; CHECK-LABEL: for.body.6: +; CHECK-NEXT: %i.14 = phi i32 [ undef, %for.body.6 ], [ 0, %polly.merge_new_and_old ] +; +@recd = external hidden global [255 x i32], align 16 + +define void @rsdec_204(i8* %data_in) { +entry: + br i1 undef, label %if.then, label %for.body + +if.then: ; preds = %entry + unreachable + +for.body: ; preds = %for.body, %entry + %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i8, i8* %data_in, i64 0 + %0 = load i8, i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %arrayidx2 = getelementptr inbounds [255 x i32], [255 x i32]* @recd, i64 0, i64 0 + store i32 %conv, i32* %arrayidx2, align 4 + %inc = add nuw nsw i32 %i.05, 1 + br i1 false, label %for.body, label %for.body.6 + +for.body.6: ; preds = %for.body.6, %for.body + %i.14 = phi i32 [ undef, %for.body.6 ], [ 0, %for.body ] + br i1 undef, label %for.body.6, label %for.body.16 + +for.body.16: ; preds = %for.body.16, %for.body.6 + br i1 undef, label %for.body.16, label %for.body.29 + +for.body.29: ; preds = %for.body.29, %for.body.16 + br i1 undef, label %for.body.29, label %for.end.38 + +for.end.38: ; preds = %for.body.29 + unreachable +} Index: test/Isl/CodeGen/phi_in_exit_early_lnt_failure_2.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_in_exit_early_lnt_failure_2.ll @@ -0,0 +1,48 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s +; +; This caused an lnt crash at some point, just verify it will run through and +; produce the PHI node in the exit we are looking for. +; +; CHECK: %eps1.addr.0.s2a = alloca double +; CHECK-NOT: %eps1.addr.0.ph.s2a = alloca double +; +; CHECK-LABEL: polly.merge_new_and_old: +; CHECK: %eps1.addr.0.ph.merge = phi double [ %eps1.addr.0.ph.final_reload, %polly.stmt.if.end.47.region_exiting.exit ], [ %eps1.addr.0.ph, %if.end.47.region_exiting ] +; +; CHECK-LABEL: polly.start: +; CHECK-NEXT: store double %eps1, double* %eps1.s2a +; +; CHECK-LABEL: polly.stmt.if.end.47.region_exiting.exit: +; CEHCK-NEXT: %eps1.addr.0.ph.final_reload = load double, double* %eps1.addr.0.s2a +; +define void @dbisect(double* %c, double* %b, double %eps1, double* %eps2) { +entry: + br label %entry.split + +entry.split: ; preds = %entry + store double 0.000000e+00, double* %b, align 8 + br i1 false, label %for.inc, label %for.end + +if.end: ; preds = %if.then, %for.body + %arrayidx33 = getelementptr inbounds double, double* %c, i64 0 + %0 = load double, double* %arrayidx33, align 8 + br label %for.inc + +for.inc: ; preds = %if.then.36, %if.end + br i1 false, label %if.end, label %for.cond.for.end_crit_edge + +for.cond.for.end_crit_edge: ; preds = %for.inc + br label %for.end + +for.end: ; preds = %for.cond.for.end_crit_edge, %entry.split + %cmp45 = fcmp ugt double %eps1, 0.000000e+00 + br i1 %cmp45, label %if.end.47, label %if.then.46 + +if.then.46: ; preds = %for.end + %1 = load double, double* %eps2, align 8 + br label %if.end.47 + +if.end.47: ; preds = %if.then.46, %for.end + %eps1.addr.0 = phi double [ %1, %if.then.46 ], [ %eps1, %for.end ] + ret void +} Index: test/Isl/CodeGen/phi_in_exit_early_lnt_failure_3.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_in_exit_early_lnt_failure_3.ll @@ -0,0 +1,64 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s +; +; This caused an lnt crash at some point, just verify it will run through and +; produce the PHI node in the exit we are looking for. +; +; CHECK-LABEL: polly.merge_new_and_old: +; CHECK-NEXT: %n2ptr.2.ph.merge = phi i8* [ %n2ptr.2.ph.final_reload, %polly.merge ], [ %n2ptr.2.ph, %if.end.45.region_exiting ] +; +; CHECK-LABEL: if.end.45: +; CHECK-NEXT: %n2ptr.2 = phi i8* [ %add.ptr25, %entry ], [ %add.ptr25, %while.cond.preheader ], [ %n2ptr.2.ph.merge, %polly.merge_new_and_old ] + +%struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121 = type { i32, i32, i32, i32, [1024 x i8] } + +; Function Attrs: nounwind uwtable +declare %struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121* @new_num() #0 + +; Function Attrs: nounwind uwtable +define void @_do_add(%struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121* %n2) #0 { +entry: + %call = tail call %struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121* @new_num() + %0 = load i32, i32* undef, align 4 + %add.ptr22 = getelementptr inbounds %struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121, %struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121* %n2, i64 0, i32 4, i64 0 + %add.ptr24 = getelementptr inbounds i8, i8* %add.ptr22, i64 0 + %add.ptr25 = getelementptr inbounds i8, i8* %add.ptr24, i64 -1 + %add.ptr29 = getelementptr inbounds %struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121, %struct.bc_struct.0.2.4.6.8.15.24.27.29.32.38.46.48.92.93.94.95.97.99.100.102.105.107.111.118.119.121* %call, i64 0, i32 4, i64 0 + %add.ptr31 = getelementptr inbounds i8, i8* %add.ptr29, i64 0 + %add.ptr32 = getelementptr inbounds i8, i8* %add.ptr31, i64 -1 + br i1 undef, label %if.end.45, label %if.then + +if.then: ; preds = %entry + br i1 undef, label %while.cond.preheader, label %while.cond.38.preheader + +while.cond.38.preheader: ; preds = %if.then + %cmp39.39 = icmp sgt i32 %0, 0 + br i1 %cmp39.39, label %while.body.40.lr.ph, label %if.end.45 + +while.body.40.lr.ph: ; preds = %while.cond.38.preheader + br label %while.body.40 + +while.cond.preheader: ; preds = %if.then + br i1 undef, label %while.body.lr.ph, label %if.end.45 + +while.body.lr.ph: ; preds = %while.cond.preheader + br label %while.body + +while.body: ; preds = %while.body, %while.body.lr.ph + br label %while.body + +while.body.40: ; preds = %while.body.40, %while.body.40.lr.ph + %sumptr.141 = phi i8* [ %add.ptr32, %while.body.40.lr.ph ], [ %incdec.ptr42, %while.body.40 ] + %n2ptr.040 = phi i8* [ %add.ptr25, %while.body.40.lr.ph ], [ %incdec.ptr41, %while.body.40 ] + %incdec.ptr41 = getelementptr inbounds i8, i8* %n2ptr.040, i64 -1 + %1 = load i8, i8* %n2ptr.040, align 1 + %incdec.ptr42 = getelementptr inbounds i8, i8* %sumptr.141, i64 -1 + store i8 %1, i8* %sumptr.141, align 1 + br i1 false, label %while.body.40, label %while.cond.38.if.end.45.loopexit9_crit_edge + +while.cond.38.if.end.45.loopexit9_crit_edge: ; preds = %while.body.40 + br label %if.end.45 + +if.end.45: ; preds = %while.cond.38.if.end.45.loopexit9_crit_edge, %while.cond.preheader, %while.cond.38.preheader, %entry + %n2ptr.2 = phi i8* [ %add.ptr25, %entry ], [ %add.ptr25, %while.cond.preheader ], [ undef, %while.cond.38.if.end.45.loopexit9_crit_edge ], [ %add.ptr25, %while.cond.38.preheader ] + ret void +} Index: test/Isl/CodeGen/phi_in_exit_early_lnt_failure_4.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_in_exit_early_lnt_failure_4.ll @@ -0,0 +1,62 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s +; +; This caused an lnt crash at some point, just verify it will run through and +; produce the PHI node in the exit we are looking for. +; +; CHECK-LABEL: polly.merge_new_and_old: +; CHECK-NEXT: %.merge = phi %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826* [ %.final_reload, %polly.stmt.for.end.298 ], [ %13, %for.end.298 ] +; +%struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826 = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, float, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8**, i8**, i32, i32***, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [9 x [16 x [16 x i16]]], [5 x [16 x [16 x i16]]], [9 x [8 x [8 x i16]]], [2 x [4 x [16 x [16 x i16]]]], [16 x [16 x i16]], [16 x [16 x i32]], i32****, i32***, i32***, i32***, i32****, i32****, %struct.Picture.8.32.56.80.104.320.536.752.1016.1040.1184.1232.1352.1376.1400.1424.1496.1568.1664.1736.1832.2048.2120.2336.2384.2840.2864.2888.2912.3584.3800.3823*, %struct.Slice.7.31.55.79.103.319.535.751.1015.1039.1183.1231.1351.1375.1399.1423.1495.1567.1663.1735.1831.2047.2119.2335.2383.2839.2863.2887.2911.3583.3799.3822*, %struct.macroblock.9.33.57.81.105.321.537.753.1017.1041.1185.1233.1353.1377.1401.1425.1497.1569.1665.1737.1833.2049.2121.2337.2385.2841.2865.2889.2913.3585.3801.3824*, i32*, i32*, i32, i32, i32, i32, [4 x [4 x i32]], i32, i32, i32, i32, i32, double, i32, i32, i32, i32, i16******, i16******, i16******, i16******, [15 x i16], i32, i32, i32, i32, i32, i32, i32, i32, [6 x [32 x i32]], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [1 x i32], i32, i32, [2 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.DecRefPicMarking_s.10.34.58.82.106.322.538.754.1018.1042.1186.1234.1354.1378.1402.1426.1498.1570.1666.1738.1834.2050.2122.2338.2386.2842.2866.2890.2914.3586.3802.3825*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, double**, double***, i32***, double**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [3 x [2 x i32]], [2 x i32], i32, i32, i16, i32, i32, i32, i32, i32 } +%struct.Picture.8.32.56.80.104.320.536.752.1016.1040.1184.1232.1352.1376.1400.1424.1496.1568.1664.1736.1832.2048.2120.2336.2384.2840.2864.2888.2912.3584.3800.3823 = type { i32, i32, [100 x %struct.Slice.7.31.55.79.103.319.535.751.1015.1039.1183.1231.1351.1375.1399.1423.1495.1567.1663.1735.1831.2047.2119.2335.2383.2839.2863.2887.2911.3583.3799.3822*], i32, float, float, float } +%struct.Slice.7.31.55.79.103.319.535.751.1015.1039.1183.1231.1351.1375.1399.1423.1495.1567.1663.1735.1831.2047.2119.2335.2383.2839.2863.2887.2911.3583.3799.3822 = type { i32, i32, i32, i32, i32, i32, %struct.datapartition.3.27.51.75.99.315.531.747.1011.1035.1179.1227.1347.1371.1395.1419.1491.1563.1659.1731.1827.2043.2115.2331.2379.2835.2859.2883.2907.3579.3795.3818*, %struct.MotionInfoContexts.5.29.53.77.101.317.533.749.1013.1037.1181.1229.1349.1373.1397.1421.1493.1565.1661.1733.1829.2045.2117.2333.2381.2837.2861.2885.2909.3581.3797.3820*, %struct.TextureInfoContexts.6.30.54.78.102.318.534.750.1014.1038.1182.1230.1350.1374.1398.1422.1494.1566.1662.1734.1830.2046.2118.2334.2382.2838.2862.2886.2910.3582.3798.3821*, i32, i32*, i32*, i32*, i32, i32*, i32*, i32*, i32 (i32)*, [3 x [2 x i32]] } +%struct.datapartition.3.27.51.75.99.315.531.747.1011.1035.1179.1227.1347.1371.1395.1419.1491.1563.1659.1731.1827.2043.2115.2331.2379.2835.2859.2883.2907.3579.3795.3818 = type { %struct.Bitstream.1.25.49.73.97.313.529.745.1009.1033.1177.1225.1345.1369.1393.1417.1489.1561.1657.1729.1825.2041.2113.2329.2377.2833.2857.2881.2905.3577.3793.3816*, %struct.EncodingEnvironment.2.26.50.74.98.314.530.746.1010.1034.1178.1226.1346.1370.1394.1418.1490.1562.1658.1730.1826.2042.2114.2330.2378.2834.2858.2882.2906.3578.3794.3817, %struct.EncodingEnvironment.2.26.50.74.98.314.530.746.1010.1034.1178.1226.1346.1370.1394.1418.1490.1562.1658.1730.1826.2042.2114.2330.2378.2834.2858.2882.2906.3578.3794.3817 } +%struct.Bitstream.1.25.49.73.97.313.529.745.1009.1033.1177.1225.1345.1369.1393.1417.1489.1561.1657.1729.1825.2041.2113.2329.2377.2833.2857.2881.2905.3577.3793.3816 = type { i32, i32, i8, i32, i32, i8, i8, i32, i32, i8*, i32 } +%struct.EncodingEnvironment.2.26.50.74.98.314.530.746.1010.1034.1178.1226.1346.1370.1394.1418.1490.1562.1658.1730.1826.2042.2114.2330.2378.2834.2858.2882.2906.3578.3794.3817 = type { i32, i32, i32, i32, i32, i8*, i32*, i32, i32 } +%struct.MotionInfoContexts.5.29.53.77.101.317.533.749.1013.1037.1181.1229.1349.1373.1397.1421.1493.1565.1661.1733.1829.2045.2117.2333.2381.2837.2861.2885.2909.3581.3797.3820 = type { [3 x [11 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [2 x [9 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [2 x [10 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [2 x [6 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [4 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819], [4 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819], [3 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819] } +%struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819 = type { i16, i8, i64 } +%struct.TextureInfoContexts.6.30.54.78.102.318.534.750.1014.1038.1182.1230.1350.1374.1398.1422.1494.1566.1662.1734.1830.2046.2118.2334.2382.2838.2862.2886.2910.3582.3798.3821 = type { [2 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819], [4 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819], [3 x [4 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [10 x [4 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [10 x [15 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [10 x [15 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [10 x [5 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [10 x [5 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [10 x [15 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]], [10 x [15 x %struct.BiContextType.4.28.52.76.100.316.532.748.1012.1036.1180.1228.1348.1372.1396.1420.1492.1564.1660.1732.1828.2044.2116.2332.2380.2836.2860.2884.2908.3580.3796.3819]] } +%struct.macroblock.9.33.57.81.105.321.537.753.1017.1041.1185.1233.1353.1377.1401.1425.1497.1569.1665.1737.1833.2049.2121.2337.2385.2841.2865.2889.2913.3585.3801.3824 = type { i32, i32, i32, [2 x i32], i32, [8 x i32], %struct.macroblock.9.33.57.81.105.321.537.753.1017.1041.1185.1233.1353.1377.1401.1425.1497.1569.1665.1737.1833.2049.2121.2337.2385.2841.2865.2889.2913.3585.3801.3824*, %struct.macroblock.9.33.57.81.105.321.537.753.1017.1041.1185.1233.1353.1377.1401.1425.1497.1569.1665.1737.1833.2049.2121.2337.2385.2841.2865.2889.2913.3585.3801.3824*, i32, [2 x [4 x [4 x [2 x i32]]]], [16 x i8], [16 x i8], i32, i64, [4 x i32], [4 x i32], i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, double, i32, i32, i32, i32, i32, i32, i32, i32, i32 } +%struct.DecRefPicMarking_s.10.34.58.82.106.322.538.754.1018.1042.1186.1234.1354.1378.1402.1426.1498.1570.1666.1738.1834.2050.2122.2338.2386.2842.2866.2890.2914.3586.3802.3825 = type { i32, i32, i32, i32, i32, %struct.DecRefPicMarking_s.10.34.58.82.106.322.538.754.1018.1042.1186.1234.1354.1378.1402.1426.1498.1570.1666.1738.1834.2050.2122.2338.2386.2842.2866.2890.2914.3586.3802.3825* } + +@img = external global %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826*, align 8 + +; Function Attrs: nounwind uwtable +define void @intrapred_luma() #0 { +entry: + %PredPel = alloca [13 x i16], align 16 + br label %for.body + +for.body: ; preds = %for.body, %entry + br i1 undef, label %for.body, label %for.body.262 + +for.body.262: ; preds = %for.body + %0 = load %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826*, %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826** @img, align 8 + br label %for.body.280 + +for.body.280: ; preds = %for.body.280, %for.body.262 + %indvars.iv66 = phi i64 [ 0, %for.body.262 ], [ %indvars.iv.next67, %for.body.280 ] + %arrayidx282 = getelementptr inbounds [13 x i16], [13 x i16]* %PredPel, i64 0, i64 1 + %arrayidx283 = getelementptr inbounds i16, i16* %arrayidx282, i64 %indvars.iv66 + %1 = load i16, i16* %arrayidx283, align 2 + %arrayidx289 = getelementptr inbounds %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826, %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826* %0, i64 0, i32 47, i64 0, i64 2, i64 %indvars.iv66 + store i16 %1, i16* %arrayidx289, align 2 + %indvars.iv.next67 = add nuw nsw i64 %indvars.iv66, 1 + br i1 false, label %for.body.280, label %for.end.298 + +for.end.298: ; preds = %for.body.280 + %2 = load %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826*, %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826** @img, align 8 + br label %for.body.310 + +for.body.310: ; preds = %for.body.310, %for.end.298 + %indvars.iv = phi i64 [ 0, %for.end.298 ], [ %indvars.iv.next, %for.body.310 ] + %arrayidx312 = getelementptr inbounds [13 x i16], [13 x i16]* %PredPel, i64 0, i64 9 + %arrayidx313 = getelementptr inbounds i16, i16* %arrayidx312, i64 %indvars.iv + %3 = load i16, i16* %arrayidx313, align 2 + %arrayidx322 = getelementptr inbounds %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826, %struct.ImageParameters.11.35.59.83.107.323.539.755.1019.1043.1187.1235.1355.1379.1403.1427.1499.1571.1667.1739.1835.2051.2123.2339.2387.2843.2867.2891.2915.3587.3803.3826* %2, i64 0, i32 47, i64 1, i64 %indvars.iv, i64 1 + store i16 %3, i16* %arrayidx322, align 2 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br i1 false, label %for.body.310, label %for.end.328 + +for.end.328: ; preds = %for.body.310 + ret void +} Index: test/Isl/CodeGen/phi_in_exit_early_lnt_failure_5.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_in_exit_early_lnt_failure_5.ll @@ -0,0 +1,139 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s +; +; This caused an lnt crash at some point, just verify it will run through and +; produce the PHI node in the exit we are looking for. +; +; CHECK-LABEL: polly.merge_new_and_old: +; CHECK-NEXT: %eps1.addr.0.ph.merge = phi double [ %eps1.addr.0.ph.final_reload, %polly.stmt.if.end.47.region_exiting.exit ], [ %eps1.addr.0.ph, %if.end.47.region_exiting ] +; CHECK-NEXT: br label %if.end.47 +; +; CHECK-LABEL: if.end.47: +; CHECK-NEXT: %eps1.addr.0 = phi double [ %eps1.addr.0.ph.merge, %polly.merge_new_and_old ] +; +define void @dbisect(double* %c, double* %b, double %eps1, double* %eps2) { +entry: + br label %entry.split + +entry.split: ; preds = %entry + store double 0.000000e+00, double* %b, align 8 + %arrayidx9 = getelementptr inbounds double, double* %c, i64 0 + %0 = load double, double* %arrayidx9, align 8 + br i1 false, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry.split + br label %for.body + +for.body: ; preds = %for.inc, %for.body.lr.ph + br i1 false, label %if.then, label %if.end + +if.then: ; preds = %for.body + br label %if.end + +if.end: ; preds = %if.then, %for.body + br i1 false, label %if.then.36, label %for.inc + +if.then.36: ; preds = %if.end + br label %for.inc + +for.inc: ; preds = %if.then.36, %if.end + br i1 false, label %for.body, label %for.cond.for.end_crit_edge + +for.cond.for.end_crit_edge: ; preds = %for.inc + br label %for.end + +for.end: ; preds = %for.cond.for.end_crit_edge, %entry.split + store double undef, double* %eps2, align 8 + %cmp45 = fcmp ugt double %eps1, 0.000000e+00 + br i1 %cmp45, label %if.end.47, label %if.then.46 + +if.then.46: ; preds = %for.end + br label %if.end.47 + +if.end.47: ; preds = %if.then.46, %for.end + %eps1.addr.0 = phi double [ undef, %if.then.46 ], [ %eps1, %for.end ] + br i1 undef, label %if.then.55, label %for.cond.58.preheader + +for.cond.58.preheader: ; preds = %if.end.47 + br i1 undef, label %for.end.68, label %for.body.61.lr.ph + +for.body.61.lr.ph: ; preds = %for.cond.58.preheader + br label %for.body.61 + +if.then.55: ; preds = %if.end.47 + unreachable + +for.body.61: ; preds = %for.body.61, %for.body.61.lr.ph + br i1 undef, label %for.body.61, label %for.cond.58.for.end.68_crit_edge + +for.cond.58.for.end.68_crit_edge: ; preds = %for.body.61 + br label %for.end.68 + +for.end.68: ; preds = %for.cond.58.for.end.68_crit_edge, %for.cond.58.preheader + br i1 undef, label %for.end.137, label %for.cond.73.preheader.lr.ph + +for.cond.73.preheader.lr.ph: ; preds = %for.end.68 + br label %for.cond.73.preheader + +for.cond.73.preheader: ; preds = %while.end, %for.cond.73.preheader.lr.ph + br i1 undef, label %for.end.87.loopexit, label %for.body.76.lr.ph + +for.body.76.lr.ph: ; preds = %for.cond.73.preheader + br label %for.body.76 + +for.body.76: ; preds = %for.inc.85, %for.body.76.lr.ph + br i1 undef, label %if.then.81, label %for.inc.85 + +if.then.81: ; preds = %for.body.76 + br label %for.end.87 + +for.inc.85: ; preds = %for.body.76 + br i1 undef, label %for.body.76, label %for.cond.73.for.end.87.loopexit_crit_edge + +for.cond.73.for.end.87.loopexit_crit_edge: ; preds = %for.inc.85 + br label %for.end.87.loopexit + +for.end.87.loopexit: ; preds = %for.cond.73.for.end.87.loopexit_crit_edge, %for.cond.73.preheader + br label %for.end.87 + +for.end.87: ; preds = %for.end.87.loopexit, %if.then.81 + br i1 undef, label %if.then.92, label %if.end.95 + +if.then.92: ; preds = %for.end.87 + br label %if.end.95 + +if.end.95: ; preds = %if.then.92, %for.end.87 + br i1 undef, label %while.body.lr.ph, label %while.end + +while.body.lr.ph: ; preds = %if.end.95 + br label %while.body + +while.body: ; preds = %if.end.128, %while.body.lr.ph + br i1 undef, label %if.then.109, label %if.end.128 + +if.then.109: ; preds = %while.body + br i1 undef, label %if.then.112, label %if.else + +if.then.112: ; preds = %if.then.109 + br label %if.end.128 + +if.else: ; preds = %if.then.109 + br i1 undef, label %if.then.122, label %if.end.128 + +if.then.122: ; preds = %if.else + br label %if.end.128 + +if.end.128: ; preds = %if.then.122, %if.else, %if.then.112, %while.body + br i1 undef, label %while.body, label %while.cond.while.end_crit_edge + +while.cond.while.end_crit_edge: ; preds = %if.end.128 + br label %while.end + +while.end: ; preds = %while.cond.while.end_crit_edge, %if.end.95 + br i1 undef, label %for.cond.73.preheader, label %for.cond.69.for.end.137_crit_edge + +for.cond.69.for.end.137_crit_edge: ; preds = %while.end + br label %for.end.137 + +for.end.137: ; preds = %for.cond.69.for.end.137_crit_edge, %for.end.68 + ret void +} Index: test/Isl/CodeGen/phi_with_multi_exiting_edges_2.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_with_multi_exiting_edges_2.ll @@ -0,0 +1,41 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s +; +; CHECK: polly.merge_new_and_old: +; CHECK: %result.ph.merge = phi float [ %result.ph.final_reload, %polly.merge ], [ %result.ph, %next.region_exiting ] +; CHECK: br label %next +; +; CHECK: next: +; CHECK: %result = phi float [ %result.ph.merge, %polly.merge_new_and_old ] +; CHECK: ret float %result + +define float @foo(float* %A, i64 %param) { +entry: + br label %entry.split + +entry.split: + %branchcond = icmp slt i64 %param, 64 + br i1 %branchcond, label %loopA, label %loopB + +loopA: + %indvarA = phi i64 [0, %entry.split], [%indvar.nextA, %loopA] + %indvar.nextA = add i64 %indvarA, 1 + %valA = load float, float* %A + %sumA = fadd float %valA, %valA + store float %valA, float* %A + %cndA = icmp eq i64 %indvar.nextA, 100 + br i1 %cndA, label %next, label %loopA + +loopB: + %indvarB = phi i64 [0, %entry.split], [%indvar.nextB, %loopB] + %indvar.nextB = add i64 %indvarB, 1 + %valB = load float, float* %A + %sumB = fadd float %valB, %valB + store float %valB, float* %A + %cndB = icmp eq i64 %indvar.nextB, 100 + br i1 %cndB, label %next, label %loopB + +next: + %result = phi float [%sumA, %loopA], [%sumB, %loopB] + ret float %result + +} Index: test/Isl/CodeGen/phi_with_one_exit_edge.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_with_one_exit_edge.ll @@ -0,0 +1,32 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-codegen -polly-no-early-exit -S < %s | FileCheck %s +; +; +; CHECK: polly.merge_new_and_old: +; CHECK: %sumA.merge = phi float [ %sumA.final_reload, %polly.loop_exit ], [ %sumA, %loopA ] +; CHECK: br label %next +; +; CHECK: next: +; CHECK: %result = phi float [ %sumA.merge, %polly.merge_new_and_old ] +; CHECK: ret float %result +; +define float @foo(float* %A, i64 %param) { +entry: + br label %entry.split + +entry.split: + br label %loopA + +loopA: + %indvarA = phi i64 [0, %entry.split], [%indvar.nextA, %loopA] + %indvar.nextA = add i64 %indvarA, 1 + %valA = load float, float* %A + %sumA = fadd float %valA, %valA + store float %valA, float* %A + %cndA = icmp eq i64 %indvar.nextA, 100 + br i1 %cndA, label %next, label %loopA + +next: + %result = phi float [%sumA, %loopA] + ret float %result + +} Index: test/ScopDetect/keep_going_expansion.ll =================================================================== --- test/ScopDetect/keep_going_expansion.ll +++ test/ScopDetect/keep_going_expansion.ll @@ -42,4 +42,4 @@ ret i32 %add } -; CHECK: Valid Region for Scop: for.body => for.cond2.preheader +; CHECK: Valid Region for Scop: for.body => for.body4 Index: test/ScopDetect/multidim_indirect_access.ll =================================================================== --- test/ScopDetect/multidim_indirect_access.ll +++ test/ScopDetect/multidim_indirect_access.ll @@ -1,17 +1,6 @@ ; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect -analyze < %s | FileCheck %s ; -; The outer loop of this function will correctly not be recognized with the -; message: -; -; Non affine access function: (sext i32 %tmp to i64) -; -; The access A[x] might mistakenly be treated as a multidimensional access with -; dimension size x. This test will check that we correctly invalidate the -; region and do not detect an outer SCoP. -; -; FIXME: -; We should detect the inner region but the PHI node in the exit blocks -; prohibits that. +; Check that we will recognize this SCoP. ; ; void f(int *A, long N) { ; int j = 0; @@ -25,7 +14,7 @@ ; } ; } ; -; CHECK-NOT: Valid Region for Scop: bb0 => bb13 +; CHECK: Valid Region for Scop: bb1 => bb0 ; target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopDetect/non-affine-loop-condition-dependent-access_2.ll =================================================================== --- test/ScopDetect/non-affine-loop-condition-dependent-access_2.ll +++ test/ScopDetect/non-affine-loop-condition-dependent-access_2.ll @@ -14,9 +14,9 @@ ; innermost loop as a SCoP of depth 1, we have to reject the loop nest if not ; both, non-affine loops as well as non-affine accesses are allowed. ; -; REJECTNONAFFINELOOPS: Valid Region for Scop: bb15 => bb26 +; REJECTNONAFFINELOOPS: Valid Region for Scop: bb15 => bb13 ; REJECTNONAFFINELOOPS-NOT: Valid -; ALLOWNONAFFINELOOPS: Valid Region for Scop: bb15 => bb26 +; ALLOWNONAFFINELOOPS: Valid Region for Scop: bb15 => bb13 ; ALLOWNONAFFINELOOPS-NOT: Valid ; ALLOWNONAFFINELOOPSANDACCESSES: Valid Region for Scop: bb11 => bb29 ; Index: test/ScopDetect/non-affine-loop-condition-dependent-access_3.ll =================================================================== --- test/ScopDetect/non-affine-loop-condition-dependent-access_3.ll +++ test/ScopDetect/non-affine-loop-condition-dependent-access_3.ll @@ -14,9 +14,9 @@ ; innermost loop as a SCoP of depth 1, we have to reject the loop nest if not ; both, non-affine loops as well as non-affine accesses are allowed. ; -; REJECTNONAFFINELOOPS: Valid Region for Scop: bb15 => bb26 +; REJECTNONAFFINELOOPS: Valid Region for Scop: bb15 => bb13 ; REJECTNONAFFINELOOPS-NOT: Valid -; ALLOWNONAFFINELOOPS: Valid Region for Scop: bb15 => bb26 +; ALLOWNONAFFINELOOPS: Valid Region for Scop: bb15 => bb13 ; ALLOWNONAFFINELOOPS-NOT: Valid ; ALLOWNONAFFINELOOPSANDACCESSES: Valid Region for Scop: bb11 => bb29 ; Index: test/ScopDetect/phi_with_multi_exiting_edges.ll =================================================================== --- test/ScopDetect/phi_with_multi_exiting_edges.ll +++ test/ScopDetect/phi_with_multi_exiting_edges.ll @@ -1,7 +1,5 @@ ; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect -analyze -S < %s | FileCheck %s ; -; XFAIL: * -; ; Region with an exit node that has a PHI node multiple incoming edges from ; inside the region. Motivation for supporting such cases in Polly. ; Index: test/ScopDetect/simple_non_single_entry.ll =================================================================== --- test/ScopDetect/simple_non_single_entry.ll +++ test/ScopDetect/simple_non_single_entry.ll @@ -1,5 +1,4 @@ ; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect-scops-in-regions-without-loops -polly-detect -analyze < %s | FileCheck %s -; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect-scops-in-regions-without-loops -polly-detect -analyze < %s | FileCheck %s ; void f(long A[], long N) { ; long i; @@ -65,4 +64,4 @@ ret void } -; CHECK: Valid Region for Scop: next => for.i.head1 +; CHECK: Valid Region for Scop: next => for.i Index: test/ScopInfo/NonAffine/non-affine-loop-condition-dependent-access_2.ll =================================================================== --- test/ScopInfo/NonAffine/non-affine-loop-condition-dependent-access_2.ll +++ test/ScopInfo/NonAffine/non-affine-loop-condition-dependent-access_2.ll @@ -16,7 +16,7 @@ ; access. ; ; INNERMOST: Function: f -; INNERMOST: Region: %bb15---%bb26 +; INNERMOST: Region: %bb15---%bb13 ; INNERMOST: Max Loop Depth: 1 ; INNERMOST: p0: {0,+,{0,+,1}<%bb11>}<%bb13> ; INNERMOST: p1: {0,+,{0,+,-1}<%bb11>}<%bb13> @@ -39,6 +39,15 @@ ; INNERMOST: [p_0, p_1, p_2, p_3, p_4] -> { Stmt_bb16[i0] -> MemRef_A[o0] : 4o0 = p_4 + 4i0 }; ; INNERMOST: MustWriteAccess := [Reduction Type: +] [Scalar: 0] ; INNERMOST: [p_0, p_1, p_2, p_3, p_4] -> { Stmt_bb16[i0] -> MemRef_A[o0] : 4o0 = p_4 + 4i0 }; +; INNERMOST: Stmt_bb26 +; INNERMOST: Domain := +; INNERMOST: [p_0, p_1, p_2, p_3, p_4] -> { Stmt_bb26[] }; +; INNERMOST: Schedule := +; INNERMOST: [p_0, p_1, p_2, p_3, p_4] -> { Stmt_bb26[] -> [1, 0] }; +; INNERMOST: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; INNERMOST: [p_0, p_1, p_2, p_3, p_4] -> { Stmt_bb26[] -> MemRef_indvars_iv_next6[] }; +; INNERMOST: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; INNERMOST: [p_0, p_1, p_2, p_3, p_4] -> { Stmt_bb26[] -> MemRef_indvars_iv_next4[] }; ; INNERMOST: } ; ; ALL: Function: f Index: test/ScopInfo/NonAffine/non-affine-loop-condition-dependent-access_3.ll =================================================================== --- test/ScopInfo/NonAffine/non-affine-loop-condition-dependent-access_3.ll +++ test/ScopInfo/NonAffine/non-affine-loop-condition-dependent-access_3.ll @@ -15,7 +15,7 @@ ; access. ; ; INNERMOST: Function: f -; INNERMOST: Region: %bb15---%bb26 +; INNERMOST: Region: %bb15---%bb13 ; INNERMOST: Max Loop Depth: 1 ; INNERMOST: Context: ; INNERMOST: [p_0, p_1, p_2] -> { : p_0 >= 0 and p_0 <= 2147483647 and p_1 >= 0 and p_1 <= 4096 and p_2 >= 0 and p_2 <= 4096 } @@ -35,7 +35,7 @@ ; INNERMOST-DAG: i0 <= -1 + p_0 ; INNERMOST-DAG: }; ; INNERMOST: Schedule := -; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> [i0] }; +; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> [0, i0] }; ; INNERMOST: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[o0] : 4o0 = p_1 }; ; INNERMOST: ReadAccess := [Reduction Type: NONE] [Scalar: 0] @@ -44,6 +44,15 @@ ; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[i0] }; ; INNERMOST: MustWriteAccess := [Reduction Type: +] [Scalar: 0] ; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[i0] }; +; INNERMOST: Stmt_bb26 +; INNERMOST: Domain := +; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb26[] }; +; INNERMOST: Schedule := +; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb26[] -> [1, 0] }; +; INNERMOST: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb26[] -> MemRef_indvars_iv_next6[] }; +; INNERMOST: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; INNERMOST: [p_0, p_1, p_2] -> { Stmt_bb26[] -> MemRef_indvars_iv_next4[] }; ; INNERMOST: } ; ; ALL: Function: f