Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -1898,13 +1898,12 @@ /// dataflow dependencies) of an instruction. /// /// @param Inst The instruction to be analyzed - /// @param R The SCoP region - /// @param NonAffineSubRegion The non affine sub-region @p Inst is in. - /// - /// @return True if the Instruction is used in other BB and a scalar write - /// Access is required. - bool buildScalarDependences(Instruction *Inst, Region *R, - Region *NonAffineSubRegio); + void buildScalarDependences(Instruction *Inst); + + /// @brief Search for uses of the llvm::Value defined by @p Inst that are not + /// within the SCoP. If there is such use, add a SCALAR WRITE such that it is + /// available after the SCoP as escaping value. + void buildEscapingDependences(Instruction *Inst); /// @brief Create MemoryAccesses for the given PHI node in the given region. /// Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -3562,25 +3562,6 @@ continue; OnlyNonAffineSubRegionOperands = false; - - if (!R.contains(OpBB)) - continue; - - Instruction *OpI = dyn_cast(Op); - if (OpI) { - BasicBlock *OpIBB = OpI->getParent(); - // As we pretend there is a use (or more precise a write) of OpI in OpBB - // we have to insert a scalar dependence from the definition of OpI to - // OpBB if the definition is not in OpBB. - if (scop->getStmtForBasicBlock(OpIBB) != - scop->getStmtForBasicBlock(OpBB)) { - ensureValueRead(OpI, OpBB); - ensureValueWrite(OpI); - } - } else if (ModelReadOnlyScalars && !isa(Op)) { - ensureValueRead(Op, OpBB); - } - ensurePHIWrite(PHI, OpBB, Op, IsExitBlock); } @@ -3589,115 +3570,41 @@ } } -bool ScopInfo::buildScalarDependences(Instruction *Inst, Region *R, - Region *NonAffineSubRegion) { - bool canSynthesizeInst = canSynthesize(Inst, LI, SE, R); - if (isIgnoredIntrinsic(Inst)) - return false; - - bool AnyCrossStmtUse = false; - BasicBlock *ParentBB = Inst->getParent(); - - for (User *U : Inst->users()) { - Instruction *UI = dyn_cast(U); - - // Ignore the strange user - if (UI == 0) - continue; - - BasicBlock *UseParent = UI->getParent(); - - // Ignore basic block local uses. A value that is defined in a scop, but - // used in a PHI node in the same basic block does not count as basic block - // local, as for such cases a control flow edge is passed between definition - // and use. - if (UseParent == ParentBB && !isa(UI)) - continue; - - // Uses by PHI nodes in the entry node count as external uses in case the - // use is through an incoming block that is itself not contained in the - // region. - if (R->getEntry() == UseParent) { - if (auto *PHI = dyn_cast(UI)) { - bool ExternalUse = false; - for (unsigned i = 0; i < PHI->getNumIncomingValues(); i++) { - if (PHI->getIncomingValue(i) == Inst && - !R->contains(PHI->getIncomingBlock(i))) { - ExternalUse = true; - break; - } - } - - if (ExternalUse) { - AnyCrossStmtUse = true; - continue; - } - } - } - - // Do not build scalar dependences inside a non-affine subregion. - if (NonAffineSubRegion && NonAffineSubRegion->contains(UseParent)) - continue; - - // Check for PHI nodes in the region exit and skip them, if they will be - // modeled as PHI nodes. - // - // PHI nodes in the region exit that have more than two incoming edges need - // to be modeled as PHI-Nodes to correctly model the fact that depending on - // the control flow a different value will be assigned to the PHI node. In - // case this is the case, there is no need to create an additional normal - // scalar dependence. Hence, bail out before we register an "out-of-region" - // use for this definition. - if (isa(UI) && UI->getParent() == R->getExit() && - !R->getExitingBlock()) - continue; - - // Check whether or not the use is in the SCoP. - if (!R->contains(UseParent)) { - AnyCrossStmtUse = true; - continue; - } +void ScopInfo::buildScalarDependences(Instruction *Inst) { + assert(!isa(Inst)); - // If the instruction can be synthesized and the user is in the region - // we do not need to add scalar dependences. - if (canSynthesizeInst) - continue; + // Pull-in required operands. + for (auto &Op : Inst->operands()) + ensureValueRead(Op.get(), Inst->getParent()); +} - // No need to translate these scalar dependences into polyhedral form, - // because synthesizable scalars can be generated by the code generator. - if (canSynthesize(UI, LI, SE, R)) - continue; +void ScopInfo::buildEscapingDependences(Instruction *Inst) { + Region *R = &scop->getRegion(); - // Skip PHI nodes in the region as they handle their operands on their own. - if (isa(UI)) + // Check for uses of this instruction outside the scop. Because we do not + // iterate over such instructions and therefore did not "ensure" the existence + // of a write, we must determine such use here. + for (Use &U : Inst->uses()) { + Instruction *UI = dyn_cast(U.getUser()); + if (!UI) continue; - // Now U is used in another statement. - AnyCrossStmtUse = true; - - // Do not build a read access that is not in the current SCoP - // Use the def instruction as base address of the MemoryAccess, so that it - // will become the name of the scalar access in the polyhedral form. - ensureValueRead(Inst, UI->getParent()); - } - - if (ModelReadOnlyScalars && !isa(Inst)) { - for (Value *Op : Inst->operands()) { - if (canSynthesize(Op, LI, SE, R)) - continue; - - if (Instruction *OpInst = dyn_cast(Op)) - if (R->contains(OpInst)) - continue; - - if (isa(Op)) - continue; - - ensureValueRead(Op, Inst->getParent()); + BasicBlock *UseParent = getUseBlock(U); + BasicBlock *UserParent = UI->getParent(); + + // An escaping value is either used by an instruction not within the scop, + // or (when the scop region's exit needs to be simplified) by a PHI in the + // scop's exit block. This is because region simplification before code + // generation inserts new basic blocks before the PHI such that its incoming + // blocks are not in the scop anymore. + if (!R->contains(UseParent) || + (isa(UI) && UserParent == R->getExit() && + R->getExitingBlock())) { + // At least one escaping use found. + ensureValueWrite(Inst); + break; } } - - return AnyCrossStmtUse; } extern MapInsnToMemAcc InsnToMemAcc; @@ -3866,10 +3773,9 @@ // The set of loads that are required to be invariant. auto &ScopRIL = *SD->getRequiredInvariantLoads(&R); - for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) { - Instruction *Inst = &*I; + for (Instruction &Inst : BB) { - PHINode *PHI = dyn_cast(Inst); + PHINode *PHI = dyn_cast(&Inst); if (PHI) buildPHIAccesses(PHI, R, NonAffineSubRegion, IsExitBlock); @@ -3882,20 +3788,20 @@ // there might be other invariant accesses that will be hoisted and // that would allow to make a non-affine access affine. if (isa(Inst) || isa(Inst)) - buildMemoryAccess(Inst, L, &R, BoxedLoops, ScopRIL); + buildMemoryAccess(&Inst, L, &R, BoxedLoops, ScopRIL); - if (isIgnoredIntrinsic(Inst)) + if (isIgnoredIntrinsic(&Inst)) continue; // Do not build scalar dependences for required invariant loads as we will // hoist them later on anyway or drop the SCoP if we cannot. - if (ScopRIL.count(dyn_cast(Inst))) + if (ScopRIL.count(dyn_cast(&Inst))) continue; - if (buildScalarDependences(Inst, &R, NonAffineSubRegion)) { - if (!isa(Inst)) - ensureValueWrite(Inst); - } + if (!PHI) + buildScalarDependences(&Inst); + if (!IsExitBlock) + buildEscapingDependences(&Inst); } } @@ -4012,13 +3918,25 @@ if (UserStmt->lookupValueReadOf(Value)) return; - addMemoryAccess(UserBB, nullptr, MemoryAccess::READ, Value, 1, true, Value, - ArrayRef(), ArrayRef(), - ScopArrayInfo::MK_Value); + auto Acc = addMemoryAccess(UserBB, nullptr, MemoryAccess::READ, Value, 1, + true, Value, ArrayRef(), + ArrayRef(), ScopArrayInfo::MK_Value); + assert(Acc); + if (ValueInst) + ensureValueWrite(ValueInst); } void ScopInfo::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, Value *IncomingValue, bool IsExitBlock) { ScopStmt *IncomingStmt = scop->getStmtForBasicBlock(IncomingBlock); + if (!IncomingStmt) + return; + + // Take care for the incoming value being available in the incoming block. + // This must be done before the check for multiple PHI writes because multiple + // exiting edges from subregion each can be the effective written value of the + // subregion. As such, all of them must be made available in the subregion + // statement. + ensureValueRead(IncomingValue, IncomingBlock); // Do not add more than one MemoryAccess per PHINode and ScopStmt. if (MemoryAccess *Acc = IncomingStmt->lookupPHIWriteOf(PHI)) { Index: test/Isl/CodeGen/MemAccess/update_access_functions.ll =================================================================== --- test/Isl/CodeGen/MemAccess/update_access_functions.ll +++ test/Isl/CodeGen/MemAccess/update_access_functions.ll @@ -8,8 +8,8 @@ ; CHECK: polly.stmt.loop3: ; CHECK-NEXT: %val.s2a.reload = load double, double* %val.s2a -; CHECK-NEXT: %polly.access.A20 = getelementptr double, double* %A, i64 42 -; CHECK-NEXT: store double %val.s2a.reload, double* %polly.access.A20 +; CHECK-NEXT: %scevgep[[R21:[0-9]*]] = getelementptr double, double* %scevgep{{[0-9]*}}, i64 %polly.indvar16 +; CHECK-NEXT: store double %val.s2a.reload, double* %scevgep[[R21]] target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/Isl/CodeGen/phi_escaping_phi_incoming_user_1.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/phi_escaping_phi_incoming_user_1.ll @@ -0,0 +1,57 @@ +; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s + +; The scop's entry has a PHI with incoming block from inside and outside the +; scop, where %phi is defined within the scop, but also escaping it because the +; incoming block for the incoming value is not in the SCoP. + +; TODO: Because of the phi with 3 incoming blocks, the loop for => outofscop is +; not recognized as a loop, but as a non-affine subregion. + +define void @func(i32 %n, double* nonnull noalias %A) { +entry: + br label %for + +for: + %phi = phi double [0.0, %entry], [0.0, %inc], [%phi, %outofscop] + %j = phi i32 [0, %entry], [%j.inc, %inc], [0, %outofscop] + %j.cmp = icmp slt i32 %j, %n + br i1 %j.cmp, label %body, label %outofscop + +body: + store double 4.2, double* %A + br label %inc + +inc: + %j.inc = add nuw nsw i32 %j, 1 + br label %for + +outofscop: + fence seq_cst + br i1 true, label %return, label %for + +return: + ret void +} + +; CHECK-LABEL: for.region_entering: +; CHECK: %phi.ph = phi double [ %phi.merge, %outofscop ], [ 0.000000e+00, %entry ] +; +; CHECK-LABEL: polly.merge_new_and_old: +; CHECK: %phi.merge = phi double [ %phi.final_reload, %polly.exiting ], [ %phi, %for ] +; CHECK: br label +; +; CHECK-LABEL: polly.start: +; CHECK: store double %phi.ph, double* %phi.phiops +; +; CHECK-LABEL: polly.stmt.for.entry: +; CHECK: %phi.phiops.reload[[R1:[0-9]+]] = load double, double* %phi.phiops +; +; CHECK-LABEL: polly.stmt.for: +; CHECK: %polly.phi = phi double [ %phi.phiops.reload[[R1]], %polly.stmt.for.entry ], [ 0.000000e+00, %polly.stmt.inc ] +; +; CHECK-LABEL: polly.stmt.polly.merge_new_and_old.exit: +; CHECK: %phi.s2a.reload = load double, double* %phi.s2a +; CHECK: store double %phi.s2a.reload, double* %phi.s2a +; +; CHECK-LABEL: polly.exiting: +; CHECK: %phi.final_reload = load double, double* %phi.s2a Index: test/ScopInfo/invariant-loads-leave-read-only-statements.ll =================================================================== --- test/ScopInfo/invariant-loads-leave-read-only-statements.ll +++ test/ScopInfo/invariant-loads-leave-read-only-statements.ll @@ -9,24 +9,36 @@ ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> [0, 0, 0, 0] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> MemRef_25[] }; -; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> MemRef_26[] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> MemRef_25[] }; ; CHECK-NEXT: Stmt_L_4 ; CHECK-NEXT: Domain := ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] : i0 >= 0 and i0 <= -1 + p_0 and i1 >= 0 and i1 <= -1 + p_0 and i2 >= 0 and i2 <= -1 + p_0 }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> [1, i0, i1, i2] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_25[] }; +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_22[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_19[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_19[i1, i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_8[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_5[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_5[i2, i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_15[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_12[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_12[i2, i1] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_19[i1, i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_25[] }; ; CHECK-NEXT: } ; target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/many-scalar-dependences.ll =================================================================== --- test/ScopInfo/many-scalar-dependences.ll +++ test/ScopInfo/many-scalar-dependences.ll @@ -91,12 +91,12 @@ ; CHECK: { Stmt_bb12[i0, i1, i2] -> [i0, 2, i1, 2, i2, 3] }; ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: { Stmt_bb12[i0, i1, i2] -> MemRef_x_3__phi[] }; -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: { Stmt_bb12[i0, i1, i2] -> MemRef_x_3[] }; ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: { Stmt_bb12[i0, i1, i2] -> MemRef_a[i0, i1] }; ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: { Stmt_bb12[i0, i1, i2] -> MemRef_a[i0, i1] }; +; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK: { Stmt_bb12[i0, i1, i2] -> MemRef_x_3[] }; ; CHECK: Stmt_bb16 ; CHECK: Domain := ; CHECK: { Stmt_bb16[i0, i1, i2] : i0 <= 99 and i0 >= 0 and i1 <= 99 and i1 >= 0 and i2 <= 99 and i2 >= 0 }; Index: test/ScopInfo/non_affine_region_4.ll =================================================================== --- test/ScopInfo/non_affine_region_4.ll +++ test/ScopInfo/non_affine_region_4.ll @@ -16,14 +16,14 @@ ; ; CHECK: Arrays { ; CHECK: i32 MemRef_A[*]; -; CHECK: i32 MemRef_x; [BasePtrOrigin: MemRef_A] ; CHECK: i32 MemRef_y__phi; +; CHECK: i32 MemRef_x; [BasePtrOrigin: MemRef_A] ; CHECK: } ; ; CHECK: Arrays (Bounds as pw_affs) { ; CHECK: i32 MemRef_A[*]; -; CHECK: i32 MemRef_x; [BasePtrOrigin: MemRef_A] ; CHECK: i32 MemRef_y__phi; +; CHECK: i32 MemRef_x; [BasePtrOrigin: MemRef_A] ; CHECK: } ; ; CHECK: Stmt_bb2__TO__bb7 @@ -38,9 +38,9 @@ ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: { Stmt_bb2__TO__bb7[i0] -> MemRef_A[i0] }; ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: { Stmt_bb2__TO__bb7[i0] -> MemRef_x[] }; -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: { Stmt_bb2__TO__bb7[i0] -> MemRef_y__phi[] }; +; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK: { Stmt_bb2__TO__bb7[i0] -> MemRef_x[] }; ; CHECK: Stmt_bb7 ; CHECK: Domain := ; CHECK: { Stmt_bb7[i0] : @@ -51,9 +51,9 @@ ; CHECK: Schedule := ; CHECK: { Stmt_bb7[i0] -> [i0, 1] }; ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: { Stmt_bb7[i0] -> MemRef_x[] }; -; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: { Stmt_bb7[i0] -> MemRef_y__phi[] }; +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK: { Stmt_bb7[i0] -> MemRef_x[] }; ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: { Stmt_bb7[i0] -> MemRef_A[i0] }; ; Index: test/ScopInfo/phi_condition_modeling_2.ll =================================================================== --- test/ScopInfo/phi_condition_modeling_2.ll +++ test/ScopInfo/phi_condition_modeling_2.ll @@ -32,12 +32,12 @@ ; CHECK-NOT: Access ; CHECK-LABEL: Stmt_bb8b ; CHECK-NOT: Access -; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: [N, c] -> { Stmt_bb8b[i0] -> MemRef_tmp_0[] }; -; CHECK-NOT: Access ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: [N, c] -> { Stmt_bb8b[i0] -> MemRef_A[i0] }; ; CHECK-NOT: Access +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK: [N, c] -> { Stmt_bb8b[i0] -> MemRef_tmp_0[] }; +; CHECK-NOT: Access ; CHECK: } target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/phi_loop_carried_float.ll =================================================================== --- test/ScopInfo/phi_loop_carried_float.ll +++ test/ScopInfo/phi_loop_carried_float.ll @@ -21,10 +21,10 @@ ; CHECK: [N] -> { Stmt_bb4[i0] -> MemRef_tmp_0__phi[] }; ; CHECK-NOT: Access ; CHECK: ReadAccess := [Reduction Type: NONE] -; CHECK: [N] -> { Stmt_bb4[i0] -> MemRef_tmp_0[] }; +; CHECK: [N] -> { Stmt_bb4[i0] -> MemRef_A[i0] }; ; CHECK-NOT: Access ; CHECK: ReadAccess := [Reduction Type: NONE] -; CHECK: [N] -> { Stmt_bb4[i0] -> MemRef_A[i0] }; +; CHECK: [N] -> { Stmt_bb4[i0] -> MemRef_tmp_0[] }; ; CHECK-NOT: Access ; CHECK: } target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/phi_scalar_simple_1.ll =================================================================== --- test/ScopInfo/phi_scalar_simple_1.ll +++ test/ScopInfo/phi_scalar_simple_1.ll @@ -68,12 +68,12 @@ ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_x_addr_1__phi[] }; ; CHECK-NOT: Access -; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_x_addr_1[] }; -; CHECK-NOT: Access ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_A[1 + i0] }; ; CHECK-NOT: Access +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_x_addr_1[] }; +; CHECK-NOT: Access %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv %tmp1 = load i32, i32* %arrayidx, align 4 %add = add nsw i32 %x.addr.1, %tmp1 Index: test/ScopInfo/phi_scalar_simple_2.ll =================================================================== --- test/ScopInfo/phi_scalar_simple_2.ll +++ test/ScopInfo/phi_scalar_simple_2.ll @@ -75,12 +75,12 @@ if.then: ; preds = %for.body3 ; CHECK-LABEL: Stmt_if_then ; CHECK-NOT: Access -; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_x_addr_1[] }; -; CHECK-NOT: Access ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_A[i0] }; ; CHECK-NOT: Access +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_x_addr_1[] }; +; CHECK-NOT: Access ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_x_addr_2__phi[] }; ; CHECK-NOT: Access Index: test/ScopInfo/scalar.ll =================================================================== --- test/ScopInfo/scalar.ll +++ test/ScopInfo/scalar.ll @@ -53,7 +53,7 @@ ; CHECK: [N] -> { Stmt_S2[i0] : i0 >= 0 and i0 <= -1 + N }; ; CHECK: Schedule := ; CHECK: [N] -> { Stmt_S2[i0] -> [i0, 1] }; -; CHECK: ReadAccess := -; CHECK: [N] -> { Stmt_S2[i0] -> MemRef_val[] }; ; CHECK: MustWriteAccess := ; CHECK: [N] -> { Stmt_S2[i0] -> MemRef_a[i0] }; +; CHECK: ReadAccess := +; CHECK: [N] -> { Stmt_S2[i0] -> MemRef_val[] }; Index: test/ScopInfo/tempscop-printing.ll =================================================================== --- test/ScopInfo/tempscop-printing.ll +++ test/ScopInfo/tempscop-printing.ll @@ -77,10 +77,10 @@ %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ] %scevgep = getelementptr i64, i64* %A, i64 %indvar.j store i64 %init, i64* %scevgep -; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] -> MemRef_init[] }; ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] -> MemRef_A[i1] }; +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] -> MemRef_init[] }; %indvar.j.next = add nsw i64 %indvar.j, 1 %exitcond.j = icmp eq i64 %indvar.j.next, %N br i1 %exitcond.j, label %for.i.end, label %for.j