[FIX] Ensure SAI objects for exit PHIs
authorJohannes Doerfert <doerfert@cs.uni-saarland.de>
Tue, 5 Apr 2016 13:44:21 +0000 (13:44 +0000)
committerJohannes Doerfert <doerfert@cs.uni-saarland.de>
Tue, 5 Apr 2016 13:44:21 +0000 (13:44 +0000)
  If all exiting blocks of a SCoP are error blocks and therefor not
  represented we will not generate accesses and consequently no SAI
  objects for exit PHIs. However, they are needed in the code generation
  to generate the merge PHIs between the original and optimized region.
  With this patch we enusre that the SAI objects for exit PHIs exist
  even if all exiting blocks turn out to be eror blocks.

  This fixes the crash reported in PR27207.

llvm-svn: 265393

polly/lib/Analysis/ScopInfo.cpp
polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll
polly/test/ScopInfo/exit-phi-1.ll
polly/test/ScopInfo/loop-multiexit-succ-cond.ll [new file with mode: 0644]

index 0e17241..ff1c337 100644 (file)
@@ -4448,6 +4448,13 @@ void ScopInfo::ensureValueRead(Value *V, BasicBlock *UserBB) {
 
 void ScopInfo::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock,
                               Value *IncomingValue, bool IsExitBlock) {
+  // As the incoming block might turn out to be an error statement ensure we
+  // will create an exit PHI SAI object. It is needed during code generation
+  // and would be created later anyway.
+  if (IsExitBlock)
+    scop->getOrCreateScopArrayInfo(PHI, PHI->getType(), {},
+                                   ScopArrayInfo::MK_ExitPHI);
+
   ScopStmt *IncomingStmt = scop->getStmtFor(IncomingBlock);
   if (!IncomingStmt)
     return;
index 7fa431e..eda2f3c 100644 (file)
@@ -34,8 +34,8 @@ sw.bb1.i30:                                       ; preds = %cond.end.i28
 }
 
 ; SCOP:      Arrays {
-; SCOP-NEXT:     i16 MemRef_next_0[*];
 ; SCOP-NEXT:     %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962* MemRef_next_0;
+; SCOP-NEXT:     i16 MemRef_next_0[*];
 ; SCOP-NEXT: }
 
 ; IR:      polly.merge_new_and_old:
index 27a8334..b34f1b8 100644 (file)
@@ -6,8 +6,8 @@
 ; CHECK: Region: %for.body
 ;
 ; CHECK:         Arrays {
-; CHECK-NEXT:        i32* MemRef_A[*]; // Element size 8
 ; CHECK-NEXT:        double MemRef_up_3_ph; // Element size 8
+; CHECK-NEXT:        i32* MemRef_A[*]; // Element size 8
 ; CHECK-NEXT:    }
 ;
 ; ModuleID = 'bugpoint-reduced-simplified.bc'
diff --git a/polly/test/ScopInfo/loop-multiexit-succ-cond.ll b/polly/test/ScopInfo/loop-multiexit-succ-cond.ll
new file mode 100644 (file)
index 0000000..d8fbb2d
--- /dev/null
@@ -0,0 +1,97 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s --check-prefix=IR
+;
+; Check that we do not crash and generate valid IR.
+;
+; CHECK:      Assumed Context:
+; CHECK-NEXT:   [count1, dobreak, count2] -> {  :  }
+; CHECK-NEXT: Invalid Context:
+; CHECK-NEXT:   [count1, dobreak, count2] -> {  : count1 <= 0 or (count1 > 0 and dobreak > 0) or (count1 > 0 and dobreak <= 0 and count2 > 0) }
+;
+; CHECK:      Stmt_loop_enter
+; CHECK-NEXT:     Domain :=
+; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_enter[] : count1 > 0 };
+
+; CHECK:      Stmt_loop_break
+; CHECK-NEXT:     Domain :=
+; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_break[] : count1 > 0 and dobreak > 0 };
+
+; CHECK:      Stmt_loop_finish
+; CHECK-NEXT:     Domain :=
+; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_finish[] : count1 > 0 and dobreak <= 0 and count2 > 0 };
+
+; CHECK:      Stmt_loop_skip
+; CHECK-NEXT:     Domain :=
+; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_skip[] : count1 <= 0 };
+
+; IR:      polly.merge_new_and_old:
+; IR-NEXT:   %phi.ph.merge = phi float [ %phi.ph.final_reload, %polly.exiting ], [ %phi.ph, %return.region_exiting ]
+; IR-NEXT:   br label %return
+;
+; IR:      return:
+; IR-NEXT:   %phi = phi float [ %phi.ph.merge, %polly.merge_new_and_old ]
+
+declare void @g();
+
+define void @func(i64 %count1, i64 %count2, i32 %dobreak, float* %A) {
+entry:
+  %fadd = fadd float undef, undef
+  br label %loopguard
+
+loopguard:
+  %cmp6 = icmp sgt i64 %count1, 0
+  br i1 %cmp6, label %loop_enter, label %loop_skip
+
+
+loop_enter:
+  store float 1.0, float* %A
+  br label %loop_header
+
+loop_header:
+  %indvars.iv63 = phi i64 [ %indvars.iv.next64, %loop_continue ], [ 0, %loop_enter ]
+  %indvars.iv.next64 = add nuw nsw i64 %indvars.iv63, 1
+  %add8 = add i64 undef, undef
+  %cmp_break = icmp sge i32 %dobreak, 1
+  br i1 %cmp_break, label %loop_break, label %loop_continue
+
+loop_continue:
+  %cmp9 = icmp eq i64 %indvars.iv.next64, %count2
+  br i1 %cmp9, label %loop_finish, label %loop_header
+
+
+loop_break:
+  store float 2.0, float* %A
+  br label %loop_break_error
+
+loop_break_error:
+  %cmp_loop_break = fcmp oeq float %fadd, 2.
+  br i1 %cmp_loop_break, label %loop_break_g, label %return
+
+loop_break_g:
+  call void @g()
+  br label %return
+
+
+loop_finish:
+    store float 3.0, float* %A
+  br label %loop_finish_error
+
+loop_finish_error:
+  call void @g()
+  br label %return
+
+
+loop_skip:
+  store float 4.0, float* %A
+  br label %loop_skip_error
+
+loop_skip_error:
+  call void @g()
+  br label %return
+
+
+return:
+  %phi = phi float [ 0.0, %loop_finish_error ], [ 0.0, %loop_break_error ], [ 2.0, %loop_break_g ], [ 3.0, %loop_skip_error ]
+  store float 1.0, float* %A
+  ret void
+}