[ScopInfo/CodeGen] ExitPHI reads are implicit.

Under some conditions MK_Value read accessed where converted to MK_ExitPHI read
accessed. This is unexpected because MK_ExitPHI read accesses are implicit after
the scop execution. This behaviour was introduced in r265261, which fixed a
failed assertion/crash in CodeGen.

Instead, we fix this failure in CodeGen itself. createExitPHINodeMerges(),
despite its name, also handles accesses of kind MK_Value, only to skip them
because they access values that are usually not PHI nodes in the SCoP region's
exit block. Except in the situation observed in r265261.

Do not convert value accessed to ExitPHI accesses and do not handle
value accesses like ExitPHI accessed in CodeGen anymore.

llvm-svn: 284023
This commit is contained in:
Michael Kruse 2016-10-12 16:31:09 +00:00
parent c6eb6bd9cb
commit fa53c86dc1
4 changed files with 63 additions and 9 deletions

View File

@ -590,13 +590,9 @@ void ScopBuilder::ensureValueRead(Value *V, BasicBlock *UserBB) {
if (UserStmt->lookupValueReadOf(V))
return;
// For exit PHIs use the MK_ExitPHI MemoryKind not MK_Value.
ScopArrayInfo::MemoryKind Kind = ScopArrayInfo::MK_Value;
if (!ValueStmt && isa<PHINode>(V))
Kind = ScopArrayInfo::MK_ExitPHI;
addMemoryAccess(UserBB, nullptr, MemoryAccess::READ, V, V->getType(), true, V,
ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(), Kind);
ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
ScopArrayInfo::MK_Value);
if (ValueInst)
ensureValueWrite(ValueInst);
}

View File

@ -670,7 +670,7 @@ void BlockGenerator::createExitPHINodeMerges(Scop &S) {
// the original PHI's value or the reloaded incoming values from the
// generated code. An llvm::Value is merged between the original code's
// value or the generated one.
if (!SAI->isValueKind() && !SAI->isExitPHIKind())
if (!SAI->isExitPHIKind())
continue;
PHINode *PHI = dyn_cast<PHINode>(Val);

View File

@ -1,15 +1,31 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
; RUN: opt %loadPolly -polly-codegen -disable-output < %s
; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s --check-prefix=CODEGEN
;
; Verify we only create one SAI object for up.3.ph as it is outside the SCoP.
; Check for correct code generation of exit PHIs, even if the same PHI value
; is used again inside the the SCoP.
; Note that if.else113 is removed from the SCoP because it is never executed.
;
; CHECK: Region: %for.body
;
; CHECK: Arrays {
; CHECK-NEXT: double MemRef_up_3_ph; // Element size 8
; CHECK-NEXT: i32* MemRef_A[*]; // Element size 8
; CHECK-NEXT: double MemRef_up_3_ph; // Element size 8
; CHECK-NEXT: }
;
; CODEGEN: polly.merge_new_and_old:
; CODEGEN-NEXT: %up.3.ph.ph.merge = phi double [ %up.3.ph.ph.final_reload, %polly.exiting ], [ undef, %for.cond.outer304.region_exiting ]
;
; CODEGEN: for.cond.outer304:
; CODEGEN-NEXT: %indvar = phi i64 [ %indvar.next, %polly.merge_new_and_old ], [ 0, %entry ]
; CODEGEN-NEXT: %up.3.ph = phi double [ 0.000000e+00, %entry ], [ %up.3.ph.ph.merge, %polly.merge_new_and_old ]
;
; CODEGEN: polly.stmt.if.then111:
; CODEGEN-NEXT: store double undef, double* %up.3.ph.s2a
;
; CODEGEN: polly.exiting:
; CODEGEN-NEXT: %up.3.ph.ph.final_reload = load double, double* %up.3.ph.s2a
;
; ModuleID = 'bugpoint-reduced-simplified.bc'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

View File

@ -0,0 +1,42 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
;
; Check that there is no MK_ExitPHI READ access.
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @local_book_besterror() {
entry:
%0 = load i64, i64* undef, align 8
%conv = trunc i64 %0 to i32
br label %for.body64
for.body64:
%bestf.011 = phi float [ 0.000000e+00, %entry ], [ %this.0.bestf.0, %if.end92 ]
br label %for.body74
for.body74:
br i1 false, label %for.body74, label %for.cond71.for.end85_crit_edge
for.cond71.for.end85_crit_edge:
%cmp88 = fcmp olt float undef, %bestf.011
%this.0.bestf.0 = select i1 undef, float undef, float %bestf.011
br label %if.end92
if.end92:
br i1 undef, label %for.body64, label %for.cond60.if.end96.loopexit_crit_edge
for.cond60.if.end96.loopexit_crit_edge: ; preds = %if.end92
ret void
}
; CHECK: Statements {
; CHECK-NEXT: Stmt_for_cond71_for_end85_crit_edge
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_for_cond71_for_end85_crit_edge[] };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_for_cond71_for_end85_crit_edge[] -> [] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_cond71_for_end85_crit_edge[] -> MemRef_bestf_011[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_cond71_for_end85_crit_edge[] -> MemRef_this_0_bestf_0[] };
; CHECK-NEXT: }