Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -3272,7 +3272,11 @@ continue; // Check whether or not the use is in the SCoP. - if (!R->contains(UseParent)) { + // If there is single exiting block, the single incoming value exit for node + // PHIs are handled like any escaping SCALAR. Otherwise, as if the PHI + // belongs to the the scop region. + bool IsExitNodePHI = isa(UI) && UI->getParent() == R->getExit(); + if (!R->contains(UseParent) && (R->getExitingBlock() || !IsExitNodePHI)) { AnyCrossStmtUse = true; continue; } Index: test/ScopInfo/exit_phi_accesses-2.ll =================================================================== --- /dev/null +++ test/ScopInfo/exit_phi_accesses-2.ll @@ -0,0 +1,47 @@ +; RUN: opt %loadPolly -analyze -polly-scops %s | FileCheck %s + +; CHECK-LABEL: Function: foo +; CHECK: Statements { +; CHECK-NEXT: Stmt_body +; CHECK-NEXT: Domain := +; CHECK-NEXT: { Stmt_body[i0] : i0 <= 100 and i0 >= 0 }; +; CHECK-NEXT: Schedule := +; CHECK-NEXT: { Stmt_body[i0] -> [i0] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: { Stmt_body[i0] -> MemRef_sum__phi[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: { Stmt_body[i0] -> MemRef_sum__phi[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: { Stmt_body[i0] -> MemRef_A[i0] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: { Stmt_body[i0] -> MemRef_sum_next[] }; +; CHECK-NEXT: } + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define float @foo(float* %A) { +entry: + br label %header + +header: + fence seq_cst + br i1 true, label %body, label %exit + +body: + %i = phi i64 [ 0, %header ], [ %next, %body ] + %sum = phi float [ 0.0, %header ], [ %sum.next, %body ] + %arrayidx = getelementptr float, float* %A, i64 %i + %scalar = fadd float 0.0, 0.0 + %next = add nuw nsw i64 %i, 1 + %val = load float, float* %arrayidx + %sum.next = fadd float %sum, %val + %cond = icmp ne i64 %i, 100 + br i1 %cond, label %body, label %after + +after: + br label %exit + +exit: + %phi = phi float [%sum.next, %after], [0.0, %header] + ret float %phi +} Index: test/ScopInfo/exit_phi_accesses.ll =================================================================== --- test/ScopInfo/exit_phi_accesses.ll +++ test/ScopInfo/exit_phi_accesses.ll @@ -1,11 +1,9 @@ ; RUN: opt %loadPolly -analyze -polly-scops %s | FileCheck %s ; Check that PHI nodes only create PHI access and nothing else (e.g. unnecessary -; SCALAR accesses)In this case, for a PHI in the exit node, hence there is no +; SCALAR accesses). In this case, for a PHI in the exit node, hence there is no ; PHI ReadAccess. -; XFAIL: * - ; CHECK-LABEL: Function: foo ; CHECK: Statements { ; CHECK-NEXT: Stmt_header @@ -22,7 +20,7 @@ ; CHECK-NEXT: { Stmt_body[i0] -> [1, i0] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_body[i0] -> MemRef_phi[] }; -; CHECK-NEXT: } +; CHECK-NEXT: } target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/read-only-scalar-used-in-phi.ll =================================================================== --- test/ScopInfo/read-only-scalar-used-in-phi.ll +++ test/ScopInfo/read-only-scalar-used-in-phi.ll @@ -27,8 +27,6 @@ ; CHECK: { Stmt_bb1[i0] -> MemRef_phisum__phi[] }; ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: { Stmt_bb1[i0] -> MemRef_phisum__phi[] }; -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: { Stmt_bb1[i0] -> MemRef_phisum[] }; ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: { Stmt_bb1[i0] -> MemRef_A[i0] };