Index: polly/trunk/include/polly/CodeGen/BlockGenerators.h =================================================================== --- polly/trunk/include/polly/CodeGen/BlockGenerators.h +++ polly/trunk/include/polly/CodeGen/BlockGenerators.h @@ -771,6 +771,39 @@ void addOperandToPHI(ScopStmt &Stmt, const PHINode *PHI, PHINode *PHICopy, BasicBlock *IncomingBB, LoopToScevMapT <S); + /// @brief Create a PHI that combines the incoming values from all incoming + /// blocks that are in the subregion. + /// + /// PHIs in the subregion's exit block can have incoming edges from within and + /// outside the subregion. This function combines the incoming values from + /// within the subregion to appear as if there is only one incoming edge from + /// the subregion (an additional exit block is created by RegionGenerator). + /// This is to avoid that a value is written to the .phiops location without + /// leaving the subregion because the exiting block as an edge back into the + /// subregion. + /// + /// @param MA The WRITE of MK_PHI/MK_ExitPHI for a PHI in the subregion's + /// exit block. + /// @param LTS Virtual induction variable mapping. + /// @param BBMap A mapping from old values to their new values in this block. + /// @param L Loop surrounding this region statement. + /// + /// @returns The constructed PHI node. + PHINode *buildExitPHI(MemoryAccess *MA, LoopToScevMapT <S, ValueMapT &BBMap, + Loop *L); + + /// @param Return the new value of a scalar write, creating a PHINode if + /// necessary. + /// + /// @param MA A scalar WRITE MemoryAccess. + /// @param LTS Virtual induction variable mapping. + /// @param BBMap A mapping from old values to their new values in this block. + /// + /// @returns The effective value of @p MA's written value when leaving the + /// subregion. + /// @see buildExitPHI + Value *getExitScalar(MemoryAccess *MA, LoopToScevMapT <S, ValueMapT &BBMap); + /// @brief Generate the scalar stores for the given statement. /// /// After the statement @p Stmt was copied all inner-SCoP scalar dependences Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/include/polly/ScopInfo.h @@ -499,13 +499,16 @@ /// write access is the instruction that defines the llvm::Value. Instruction *AccessInstruction; + /// @brief Incoming block and value of a PHINode. + SmallVector, 4> Incoming; + /// @brief The value associated with this memory access. /// /// - For array memory accesses (MK_Array) it is the loaded result or the /// stored value. /// - For accesses of kind MK_Value it is the access instruction itself. - /// - For accesses of kind MK_PHI or MK_ExitPHI it is the operand value - /// of the PHI node. + /// - For accesses of kind MK_PHI or MK_ExitPHI it is the PHI node itself + /// (for both, READ and WRITE accesses). /// AssertingVH AccessValue; @@ -603,6 +606,27 @@ StringRef BaseName); ~MemoryAccess(); + /// @brief Add a new incoming block/value pairs for this PHI/ExitPHI access. + /// + /// @param IncomingBlock The PHI's incoming block. + /// @param IncomingValue The value when reacing the PHI from the @p + /// IncomingBlock. + void addIncoming(BasicBlock *IncomingBlock, Value *IncomingValue) { + assert(isAnyPHIKind()); + Incoming.emplace_back(std::make_pair(IncomingBlock, IncomingValue)); + } + + /// @brief Return the list of possible PHI/ExitPHI values. + /// + /// After code generation moves some PHIs around during region simplification, + /// we cannot reliably locate the original PHI node and its incoming values + /// anymore. For this reason we remember these explicitely for all PHI-kind + /// accesses. + ArrayRef> getIncoming() const { + assert(isAnyPHIKind()); + return Incoming; + } + /// @brief Get the type of a memory access. enum AccessType getType() { return AccType; } @@ -712,6 +736,9 @@ /// SCoP's exit block? bool isExitPHIKind() const { return Kind == ScopArrayInfo::MK_ExitPHI; } + /// @brief Does this access orginate from one of the two PHI types? + bool isAnyPHIKind() const { return isPHIKind() || isExitPHIKind(); } + /// @brief Get the statement that contains this memory access. ScopStmt *getStatement() const { return Statement; } @@ -839,6 +866,15 @@ /// elsewhere, mapped to their MK_Value WRITE MemoryAccesses. DenseMap ValueWrites; + /// @brief Map from PHI nodes to its incoming value when coming from this + /// statement. + /// + /// Non-affine subregions can have multiple exiting blocks that are incoming + /// blocks of the PHI nodes. This map ensures that there is only one write + /// operation for the complete subregion. A PHI selecting the relevant value + /// will be inserted. + DenseMap PHIWrites; + //@} /// @brief A SCoP statement represents either a basic block (affine/precise @@ -1017,6 +1053,14 @@ return ValueReads.lookup(Inst); } + /// @brief Return the PHI write MemoryAccess for the incoming values from any + /// basic block in this ScopStmt, or nullptr if not existing, + /// respectively not yet added. + MemoryAccess *lookupPHIWriteOf(PHINode *PHI) const { + assert(isBlockStmt() || R->getExit() == PHI->getParent()); + return PHIWrites.lookup(PHI); + } + void setBasicBlock(BasicBlock *Block) { // TODO: Handle the case where the statement is a region statement, thus // the entry block was split and needs to be changed in the region R. @@ -1910,12 +1954,16 @@ /// @param Subscripts Access subscripts per dimension. /// @param Sizes The array diminsion's sizes. /// @param Kind The kind of memory accessed. - void addMemoryAccess(BasicBlock *BB, Instruction *Inst, - MemoryAccess::AccessType Type, Value *BaseAddress, - unsigned ElemBytes, bool Affine, Value *AccessValue, - ArrayRef Subscripts, - ArrayRef Sizes, - ScopArrayInfo::MemoryKind Kind); + /// + /// @return The created MemoryAccess, or nullptr if the access is not within + /// the SCoP. + MemoryAccess *addMemoryAccess(BasicBlock *BB, Instruction *Inst, + MemoryAccess::AccessType Type, + Value *BaseAddress, unsigned ElemBytes, + bool Affine, Value *AccessValue, + ArrayRef Subscripts, + ArrayRef Sizes, + ScopArrayInfo::MemoryKind Kind); /// @brief Create a MemoryAccess that represents either a LoadInst or /// StoreInst. @@ -1965,8 +2013,8 @@ /// PHINode in the SCoP region's exit block. /// @see addPHIReadAccess() /// @see ScopArrayInfo::MemoryKind - void addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock, - Value *IncomingValue, bool IsExitBlock); + void ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, + Value *IncomingValue, bool IsExitBlock); /// @brief Create a MemoryAccess for reading the value of a phi. /// @@ -1976,7 +2024,7 @@ /// /// @param PHI PHINode under consideration; the READ access will be added /// here. - /// @see addPHIWriteAccess() + /// @see ensurePHIWrite() /// @see ScopArrayInfo::MemoryKind void addPHIReadAccess(PHINode *PHI); Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -917,6 +917,11 @@ assert(!ValueReads.lookup(AccessVal)); ValueReads[AccessVal] = Access; + } else if (Access->isAnyPHIKind() && Access->isWrite()) { + PHINode *PHI = cast(Access->getBaseAddr()); + assert(!PHIWrites.lookup(PHI)); + + PHIWrites[PHI] = Access; } MemAccs.push_back(Access); @@ -3576,7 +3581,7 @@ ensureValueRead(Op, OpBB); } - addPHIWriteAccess(PHI, OpBB, Op, IsExitBlock); + ensurePHIWrite(PHI, OpBB, Op, IsExitBlock); } if (!OnlyNonAffineSubRegionOperands && !IsExitBlock) { @@ -3894,19 +3899,19 @@ } } -void ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst, - MemoryAccess::AccessType Type, - Value *BaseAddress, unsigned ElemBytes, - bool Affine, Value *AccessValue, - ArrayRef Subscripts, - ArrayRef Sizes, - ScopArrayInfo::MemoryKind Kind) { +MemoryAccess *ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst, + MemoryAccess::AccessType Type, + Value *BaseAddress, unsigned ElemBytes, + bool Affine, Value *AccessValue, + ArrayRef Subscripts, + ArrayRef Sizes, + ScopArrayInfo::MemoryKind Kind) { ScopStmt *Stmt = scop->getStmtForBasicBlock(BB); // Do not create a memory access for anything not in the SCoP. It would be // ignored anyway. if (!Stmt) - return; + return nullptr; AccFuncSetType &AccList = AccFuncMap[BB]; Value *BaseAddr = BaseAddress; @@ -3927,12 +3932,19 @@ isKnownMustAccess = true; } + // Non-affine PHI writes do not "happen" at a particular instruction, but + // after exiting the statement. Therefore they are guaranteed execute and + // overwrite the old value. + if (Kind == ScopArrayInfo::MK_PHI || Kind == ScopArrayInfo::MK_ExitPHI) + isKnownMustAccess = true; + if (!isKnownMustAccess && Type == MemoryAccess::MUST_WRITE) Type = MemoryAccess::MAY_WRITE; AccList.emplace_back(Stmt, Inst, Type, BaseAddress, ElemBytes, Affine, Subscripts, Sizes, AccessValue, Kind, BaseName); Stmt->addAccess(&AccList.back()); + return &AccList.back(); } void ScopInfo::addArrayAccess(Instruction *MemAccInst, @@ -3978,13 +3990,25 @@ ArrayRef(), ArrayRef(), ScopArrayInfo::MK_Value); } -void ScopInfo::addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock, - Value *IncomingValue, bool IsExitBlock) { - addMemoryAccess(IncomingBlock, IncomingBlock->getTerminator(), - MemoryAccess::MUST_WRITE, PHI, 1, true, IncomingValue, - ArrayRef(), ArrayRef(), - IsExitBlock ? ScopArrayInfo::MK_ExitPHI - : ScopArrayInfo::MK_PHI); +void ScopInfo::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, + Value *IncomingValue, bool IsExitBlock) { + ScopStmt *IncomingStmt = scop->getStmtForBasicBlock(IncomingBlock); + + // Do not add more than one MemoryAccess per PHINode and ScopStmt. + if (MemoryAccess *Acc = IncomingStmt->lookupPHIWriteOf(PHI)) { + assert(Acc->getAccessInstruction() == PHI); + Acc->addIncoming(IncomingBlock, IncomingValue); + return; + } + + MemoryAccess *Acc = addMemoryAccess( + IncomingStmt->isBlockStmt() ? IncomingBlock + : IncomingStmt->getRegion()->getEntry(), + PHI, MemoryAccess::MUST_WRITE, PHI, 1, true, PHI, + ArrayRef(), ArrayRef(), + IsExitBlock ? ScopArrayInfo::MK_ExitPHI : ScopArrayInfo::MK_PHI); + assert(Acc); + Acc->addIncoming(IncomingBlock, IncomingValue); } void ScopInfo::addPHIReadAccess(PHINode *PHI) { addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, PHI, Index: polly/trunk/lib/CodeGen/BlockGenerators.cpp =================================================================== --- polly/trunk/lib/CodeGen/BlockGenerators.cpp +++ polly/trunk/lib/CodeGen/BlockGenerators.cpp @@ -423,6 +423,17 @@ continue; Value *Val = MA->getAccessValue(); + if (MA->isAnyPHIKind()) { + assert(MA->getIncoming().size() >= 1 && + "Block statements have exactly one exiting block, or multiple but " + "with same incoming block and value"); + assert(std::all_of(MA->getIncoming().begin(), MA->getIncoming().end(), + [&](std::pair p) -> bool { + return p.first == Stmt.getBasicBlock(); + }) && + "Incoming block must be statement's block"); + Val = MA->getIncoming()[0].second; + } auto *Address = getOrCreateAlloca(*MA); Val = getNewValue(Stmt, Val, BBMap, LTS, L); @@ -1179,47 +1190,85 @@ IncompletePHINodeMap.clear(); } +PHINode *RegionGenerator::buildExitPHI(MemoryAccess *MA, LoopToScevMapT <S, + ValueMapT &BBMap, Loop *L) { + ScopStmt *Stmt = MA->getStatement(); + Region *SubR = Stmt->getRegion(); + auto Incoming = MA->getIncoming(); + + PollyIRBuilder::InsertPointGuard IPGuard(Builder); + PHINode *OrigPHI = cast(MA->getAccessInstruction()); + BasicBlock *NewSubregionExit = Builder.GetInsertBlock(); + + // This can happen if the subregion is simplified after the ScopStmts + // have been created; simplification happens as part of CodeGeneration. + if (OrigPHI->getParent() != SubR->getExit()) { + BasicBlock *FormerExit = SubR->getExitingBlock(); + if (FormerExit) + NewSubregionExit = BlockMap.lookup(FormerExit); + } + + PHINode *NewPHI = PHINode::Create(OrigPHI->getType(), Incoming.size(), + "polly." + OrigPHI->getName(), + NewSubregionExit->getFirstNonPHI()); + + // Add the incoming values to the PHI. + for (auto &Pair : Incoming) { + BasicBlock *OrigIncomingBlock = Pair.first; + BasicBlock *NewIncomingBlock = BlockMap.lookup(OrigIncomingBlock); + Builder.SetInsertPoint(NewIncomingBlock->getTerminator()); + assert(RegionMaps.count(NewIncomingBlock)); + ValueMapT *LocalBBMap = &RegionMaps[NewIncomingBlock]; + + Value *OrigIncomingValue = Pair.second; + Value *NewIncomingValue = + getNewValue(*Stmt, OrigIncomingValue, *LocalBBMap, LTS, L); + NewPHI->addIncoming(NewIncomingValue, NewIncomingBlock); + } + + return NewPHI; +} + +Value *RegionGenerator::getExitScalar(MemoryAccess *MA, LoopToScevMapT <S, + ValueMapT &BBMap) { + ScopStmt *Stmt = MA->getStatement(); + + // TODO: Add some test cases that ensure this is really the right choice. + Loop *L = LI.getLoopFor(Stmt->getRegion()->getExit()); + + if (MA->isAnyPHIKind()) { + auto Incoming = MA->getIncoming(); + assert(!Incoming.empty() && + "PHI WRITEs must have originate from at least one incoming block"); + + // If there is only one incoming value, we do not need to create a PHI. + if (Incoming.size() == 1) { + Value *OldVal = Incoming[0].second; + return getNewValue(*Stmt, OldVal, BBMap, LTS, L); + } + + return buildExitPHI(MA, LTS, BBMap, L); + } + + // MK_Value accesses leaving the subregion must dominate the exit block; just + // pass the copied value + Value *OldVal = MA->getAccessValue(); + return getNewValue(*Stmt, OldVal, BBMap, LTS, L); +} + void RegionGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT <S, ValueMapT &BBMap) { assert(Stmt.getRegion() && "Block statements need to use the generateScalarStores() " "function in the BlockGenerator"); - // TODO: Add some test cases that ensure this is really the right choice. - Loop *L = LI.getLoopFor(Stmt.getRegion()->getExit()); - for (MemoryAccess *MA : Stmt) { if (MA->isArrayKind() || MA->isRead()) continue; - Instruction *ScalarInst = MA->getAccessInstruction(); - Value *Val = MA->getAccessValue(); - - // In case we add the store into an exiting block, we need to restore the - // position for stores in the exit node. - BasicBlock *SavedInsertBB = Builder.GetInsertBlock(); - auto SavedInsertionPoint = Builder.GetInsertPoint(); - ValueMapT *LocalBBMap = &BBMap; - - // Scalar writes induced by PHIs must be written in the incoming blocks. - if (MA->isPHIKind() || MA->isExitPHIKind()) { - BasicBlock *ExitingBB = ScalarInst->getParent(); - BasicBlock *ExitingBBCopy = BlockMap[ExitingBB]; - Builder.SetInsertPoint(ExitingBBCopy->getTerminator()); - - // For the incoming blocks, use the block's BBMap instead of the one for - // the entire region. - LocalBBMap = &RegionMaps[ExitingBBCopy]; - } - - auto Address = getOrCreateAlloca(*MA); - - Val = getNewValue(Stmt, Val, *LocalBBMap, LTS, L); - Builder.CreateStore(Val, Address); - - // Restore the insertion point if necessary. - if (MA->isPHIKind() || MA->isExitPHIKind()) - Builder.SetInsertPoint(SavedInsertBB, SavedInsertionPoint); + Value *NewVal = getExitScalar(MA, LTS, BBMap); + Value *Address = getOrCreateAlloca(*MA); + Builder.CreateStore(NewVal, Address); } } Index: polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-2.ll =================================================================== --- polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-2.ll +++ polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-2.ll @@ -10,13 +10,14 @@ ; CHECK: br i1 %p_tmp8, label %polly.stmt.bb9, label %polly.stmt.bb10 ; CHECK: polly.stmt.bb9: ; preds = %polly.stmt.bb3 -; CHECK: store double 1.000000e+00, double* %tmp12.phiops ; CHECK: br label %polly.stmt.bb11.exit ; CHECK: polly.stmt.bb10: ; preds = %polly.stmt.bb3 -; CHECK: store double 2.000000e+00, double* %tmp12.phiops ; CHECK: br label %polly.stmt.bb11.exit +; CHECK: polly.stmt.bb11.exit: ; preds = %polly.stmt.bb10, %polly.stmt.bb9 +; CHECK: %polly.tmp12 = phi double [ 1.000000e+00, %polly.stmt.bb9 ], [ 2.000000e+00, %polly.stmt.bb10 ] +; CHECK: store double %polly.tmp12, double* %tmp12.phiops define void @hoge(i32 %arg, [1024 x double]* %arg1) { bb: Index: polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-3.ll =================================================================== --- polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-3.ll +++ polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-3.ll @@ -16,23 +16,23 @@ ; CHECK-NEXT: %p_val0 = fadd float 1.000000e+00, 2.000000e+00 ; CHECK-NEXT: %p_val1 = fadd float 1.000000e+00, 2.000000e+00 ; CHECK-NEXT: %p_val2 = fadd float 1.000000e+00, 2.000000e+00 -; CHECK-NEXT: store float %p_val0, float* %merge.phiops ; CHECK-NEXT: br i1 branch1: br i1 %cond1, label %branch2, label %backedge ; CHECK-LABEL: polly.stmt.branch1: -; CHECK-NEXT: store float %p_val1, float* %merge.phiops ; CHECK-NEXT: br i1 branch2: br label %backedge ; CHECK-LABEL: polly.stmt.branch2: -; CHECK-NEXT: store float %p_val2, float* %merge.phiops ; CHECK-NEXT: br label +; CHECK-LABEL: polly.stmt.backedge.exit: +; CHECK: %polly.merge = phi float [ %p_val0, %polly.stmt.loop ], [ %p_val1, %polly.stmt.branch1 ], [ %p_val2, %polly.stmt.branch2 ] + backedge: %merge = phi float [%val0, %loop], [%val1, %branch1], [%val2, %branch2] %indvar.next = add i64 %indvar, 1 Index: polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-4.ll =================================================================== --- polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-4.ll +++ polly/trunk/test/Isl/CodeGen/non-affine-phi-node-expansion-4.ll @@ -14,7 +14,6 @@ ; CHECK-LABEL: polly.stmt.loop: ; CHECK-NEXT: %p_val0 = fadd float 1.000000e+00, 2.000000e+00 ; CHECK-NEXT: %p_val1 = fadd float 1.000000e+00, 2.000000e+00 -; CHECK-NEXT: store float %p_val0, float* %merge.phiops ; CHECK-NEXT: br i1 ; The interesting instruction here is %val2, which does not dominate the exit of @@ -27,16 +26,17 @@ ; CHECK-LABEL: polly.stmt.branch1: ; CHECK-NEXT: %p_val2 = fadd float 1.000000e+00, 2.000000e+00 -; CHECK-NEXT: store float %p_val1, float* %merge.phiops ; CHECK-NEXT: br i1 branch2: br label %backedge ; CHECK-LABEL: polly.stmt.branch2: -; CHECK-NEXT: store float %p_val2, float* %merge.phiops ; CHECK-NEXT: br label +; CHECK-LABEL: polly.stmt.backedge.exit: +; CHECK: %polly.merge = phi float [ %p_val0, %polly.stmt.loop ], [ %p_val1, %polly.stmt.branch1 ], [ %p_val2, %polly.stmt.branch2 ] + backedge: %merge = phi float [%val0, %loop], [%val1, %branch1], [%val2, %branch2] %indvar.next = add i64 %indvar, 1 Index: polly/trunk/test/Isl/CodeGen/non-affine-region-exit-phi-incoming-synthesize.ll =================================================================== --- polly/trunk/test/Isl/CodeGen/non-affine-region-exit-phi-incoming-synthesize.ll +++ polly/trunk/test/Isl/CodeGen/non-affine-region-exit-phi-incoming-synthesize.ll @@ -8,14 +8,12 @@ ; ; CHECK-LABEL: polly.stmt.subregion_entry: ; CHECK: %[[R0:[0-9]*]] = add i32 %n, -2 -; CHECK: store i32 %[[R0]], i32* %retval.s2a ; ; CHECK-LABEL: polly.stmt.subregion_if: ; CHECK: %[[R1:[0-9]*]] = add i32 %n, -2 -; CHECK: store i32 %[[R1]], i32* %retval.s2a ; -; CHECK-LABEL: polly.stmt.polly.merge_new_and_old.exit: -; CHECK: load i32, i32* %retval.s2a +; CHECK-LABEL: polly.stmt.subregion_exit.region_exiting: +; CHECK: %polly.retval = phi i32 [ %[[R1]], %polly.stmt.subregion_if ], [ %[[R0]], %polly.stmt.subregion_entry ] define i32 @func(i32 %n){ entry: Index: polly/trunk/test/Isl/CodeGen/pr25241.ll =================================================================== --- polly/trunk/test/Isl/CodeGen/pr25241.ll +++ polly/trunk/test/Isl/CodeGen/pr25241.ll @@ -6,10 +6,17 @@ ; 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 = phi i32 [ %[[R1]], %polly.stmt.if.then.862 ], [ undef, %polly.stmt.if.else.864 ] +; CHECK: br label %polly.stmt.polly.merge_new_and_old.exit + ; CHECK-LABEL: polly.stmt.polly.merge_new_and_old.exit: +; CHECK: store i32 %polly.curr.3, i32* %curr.3.s2a +; CHECK: br label %polly.exiting + +; CHECK-LABEL: polly.exiting: ; CHECK: %curr.3.ph.final_reload = load i32, i32* %curr.3.s2a ; CHECK: br label Index: polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll =================================================================== --- polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll +++ polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll @@ -62,12 +62,10 @@ ; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_A[i0] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_smax[] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_j_2__phi[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_j_0[] }; -; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_j_2__phi[] }; ; CHECK-NEXT: Stmt_bb18 ; CHECK-NEXT: Domain := ; CHECK-NEXT: [N] -> { Stmt_bb18[i0] : 0 <= i0 < N }; Index: polly/trunk/test/ScopInfo/intra-non-affine-stmt-phi-node.ll =================================================================== --- polly/trunk/test/ScopInfo/intra-non-affine-stmt-phi-node.ll +++ polly/trunk/test/ScopInfo/intra-non-affine-stmt-phi-node.ll @@ -9,10 +9,6 @@ ; CHECK-NEXT: { Stmt_loop__TO__backedge[i0] -> [i0, 0] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_loop__TO__backedge[i0] -> MemRef_merge__phi[] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_loop__TO__backedge[i0] -> MemRef_merge__phi[] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_loop__TO__backedge[i0] -> MemRef_merge__phi[] }; ; CHECK-NEXT: Stmt_backedge ; CHECK-NEXT: Domain := ; CHECK-NEXT: { Stmt_backedge[i0] : 0 <= i0 <= 100 }; Index: polly/trunk/test/ScopInfo/non_affine_region_2.ll =================================================================== --- polly/trunk/test/ScopInfo/non_affine_region_2.ll +++ polly/trunk/test/ScopInfo/non_affine_region_2.ll @@ -29,8 +29,6 @@ ; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> [i0, 0] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_A[i0] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_x_2__phi[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_x_2__phi[] }; ; CHECK-NEXT: Stmt_bb18 Index: polly/trunk/test/ScopInfo/non_affine_region_3.ll =================================================================== --- polly/trunk/test/ScopInfo/non_affine_region_3.ll +++ polly/trunk/test/ScopInfo/non_affine_region_3.ll @@ -29,16 +29,10 @@ ; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> [i0, 0] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_A[i0] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_x_2__phi[] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_x_2__phi[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_b[] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_x_2__phi[] }; -; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb3__TO__bb18[i0] -> MemRef_x_2__phi[] }; ; CHECK-NEXT: Stmt_bb18 ; CHECK-NEXT: Domain := ; CHECK-NEXT: { Stmt_bb18[i0] : 0 <= i0 <= 1023 }; Index: polly/trunk/test/ScopInfo/non_affine_region_4.ll =================================================================== --- polly/trunk/test/ScopInfo/non_affine_region_4.ll +++ polly/trunk/test/ScopInfo/non_affine_region_4.ll @@ -36,8 +36,6 @@ ; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_A[i0] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_x[] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_y__phi[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_y__phi[] }; ; CHECK-NEXT: Stmt_bb7