Allow PHI nodes in the region exit block

While we do not need to model PHI nodes in the region exit (as it is not part
  of the SCoP), we need to prepare for the case that the exit block is split in
  code generation to create a single exiting block. If this will happen, hence
  if the region did not have a single exiting block before, we will model the
  operands of the PHI nodes as escaping scalars in the SCoP.

Differential Revision: http://reviews.llvm.org/D12051

llvm-svn: 247078
This commit is contained in:
Johannes Doerfert 2015-09-08 21:44:27 +00:00
parent b9fe03d4a9
commit 717b866798
23 changed files with 534 additions and 63 deletions

View File

@ -386,7 +386,9 @@ protected:
/// @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, Instruction *Inst, Value *InstCopy);
/// @param Address If given it is used as the escape address for @p Inst.
void handleOutsideUsers(const Region &R, Instruction *Inst, Value *InstCopy,
AllocaInst *Address = nullptr);
/// @brief Initialize the memory of demoted scalars.
///

View File

@ -223,13 +223,6 @@ private:
/// @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.

View File

@ -799,6 +799,9 @@ private:
/// 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;
@ -1192,6 +1195,9 @@ public:
/// @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.

View File

@ -256,8 +256,9 @@ class TempScopInfo : public RegionPass {
/// @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 @@ class TempScopInfo : public RegionPass {
/// @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;

View File

@ -802,8 +802,7 @@ Region *ScopDetection::expandRegion(Region &R) {
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?)
@ -945,18 +944,6 @@ bool ScopDetection::allBlocksValid(DetectionContext &Context) const {
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<PHINode>(*I))
return invalid<ReportPHIinExit>(Context, /*Assert=*/true, I);
}
return true;
}
bool ScopDetection::isValidRegion(DetectionContext &Context) const {
Region &CurRegion = Context.CurRegion;
@ -1002,9 +989,6 @@ bool ScopDetection::isValidRegion(DetectionContext &Context) const {
if (!DetectUnprofitable && !hasMoreThanOneLoop(&CurRegion))
invalid<ReportUnprofitable>(Context, /*Assert=*/true, &CurRegion);
if (!isValidExit(Context))
return false;
if (!allBlocksValid(Context))
return false;

View File

@ -1819,7 +1819,8 @@ static unsigned getMaxLoopDepthInRegion(const Region &R, LoopInfo &LI,
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) {

View File

@ -92,8 +92,18 @@ void TempScop::printDetail(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI,
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 exit block of the region, hence if IsExitBlock is
// true, are not modeled 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 @@ void TempScopInfo::buildPHIAccesses(PHINode *PHI, Region &R,
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, Region &SR) {
}
void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB,
Region *NonAffineSubRegion) {
Region *NonAffineSubRegion,
bool IsExitBlock) {
AccFuncSetType Functions;
Loop *L = LI->getLoopFor(&BB);
@ -306,6 +317,15 @@ void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB,
for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) {
Instruction *Inst = I;
PHINode *PHI = dyn_cast<PHINode>(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<LoadInst>(Inst) || isa<StoreInst>(Inst))
Functions.push_back(
std::make_pair(buildIRAccess(Inst, L, &R, BoxedLoops), Inst));
@ -313,9 +333,6 @@ void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB,
if (isIgnoredIntrinsic(Inst))
continue;
if (PHINode *PHI = dyn_cast<PHINode>(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,16 @@ TempScop *TempScopInfo::buildTempScop(Region &R) {
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
// from the current exit block into the new region exiting block. Hence, PHI
// nodes that are at this point not part of the region will be.
// To handle these PHI nodes later we will now model their operands as scalar
// accesses. Note that we do not model anything in the exit block if we have
// an exiting block in the region, as there will not be any splitting later.
if (!R.getExitingBlock())
buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true);
return TScop;
}

View File

@ -365,7 +365,7 @@ Value *BlockGenerator::getOrCreatePHIAlloca(Value *ScalarBase) {
}
void BlockGenerator::handleOutsideUsers(const Region &R, Instruction *Inst,
Value *InstCopy) {
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 +391,8 @@ void BlockGenerator::handleOutsideUsers(const Region &R, Instruction *Inst,
return;
// Get or create an escape alloca for this instruction.
auto *ScalarAddr = cast<AllocaInst>(getOrCreateScalarAlloca(Inst));
auto *ScalarAddr =
Address ? Address : cast<AllocaInst>(getOrCreateScalarAlloca(Inst));
// Remember that this instruction has escape uses and the escape alloca.
EscapeMap[Inst] = std::make_pair(ScalarAddr, std::move(EscapeUsers));
@ -516,6 +517,11 @@ void BlockGenerator::createScalarInitialization(Scop &S) {
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<PHINode>(Inst))
continue;
ValueMapT EmptyMap;
Builder.CreateStore(Array->getBasePtr(),
getOrCreateScalarAlloca(Array->getBasePtr()));
@ -567,6 +573,23 @@ void BlockGenerator::createScalarFinalization(Region &R) {
}
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<PHINode>(&I);
if (!PHI)
break;
assert(PHI->getNumUses() == 1);
assert(ScalarMap.count(PHI->user_back()));
handleOutsideUsers(S.getRegion(), PHI, nullptr,
ScalarMap[PHI->user_back()]);
}
}
createScalarInitialization(S);
createScalarFinalization(S.getRegion());
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -42,4 +42,4 @@ for.end9: ; preds = %for.body4
ret i32 %add
}
; CHECK: Valid Region for Scop: for.body => for.cond2.preheader
; CHECK: Valid Region for Scop: for.body => for.body4

View File

@ -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"

View File

@ -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
;

View File

@ -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
;

View File

@ -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.
;

View File

@ -1,5 +1,4 @@
; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect-unprofitable -polly-detect -analyze < %s | FileCheck %s
; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect-unprofitable -polly-detect -analyze < %s | FileCheck %s
; void f(long A[], long N) {
; long i;
@ -65,4 +64,4 @@ return:
ret void
}
; CHECK: Valid Region for Scop: next => for.i.head1
; CHECK: Valid Region for Scop: next => for.i

View File

@ -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}<nuw><nsw><%bb11>}<nuw><nsw><%bb13>
; INNERMOST: p1: {0,+,{0,+,-1}<nw><%bb11>}<nw><%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

View File

@ -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