[ScopInfo/CodeGen] ExitPHI reads are implicit.
authorMichael Kruse <llvm@meinersbur.de>
Wed, 12 Oct 2016 16:31:09 +0000 (16:31 +0000)
committerMichael Kruse <llvm@meinersbur.de>
Wed, 12 Oct 2016 16:31:09 +0000 (16:31 +0000)
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

polly/lib/Analysis/ScopBuilder.cpp
polly/lib/CodeGen/BlockGenerators.cpp
polly/test/ScopInfo/exit-phi-1.ll
polly/test/ScopInfo/exit-phi-2.ll [new file with mode: 0644]

index 7a47470..4c9fcec 100644 (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);
 }
index 79c4527..893cb15 100644 (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);
index b34f1b8..920bc68 100644 (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"
 
diff --git a/polly/test/ScopInfo/exit-phi-2.ll b/polly/test/ScopInfo/exit-phi-2.ll
new file mode 100644 (file)
index 0000000..4007ddc
--- /dev/null
@@ -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: }