Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -3271,6 +3271,23 @@ 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; Index: polly/trunk/test/ScopInfo/exit_phi_accesses-2.ll =================================================================== --- polly/trunk/test/ScopInfo/exit_phi_accesses-2.ll +++ polly/trunk/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: polly/trunk/test/ScopInfo/exit_phi_accesses.ll =================================================================== --- polly/trunk/test/ScopInfo/exit_phi_accesses.ll +++ polly/trunk/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: polly/trunk/test/ScopInfo/read-only-scalar-used-in-phi.ll =================================================================== --- polly/trunk/test/ScopInfo/read-only-scalar-used-in-phi.ll +++ polly/trunk/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] };