diff options
author | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-04-05 13:44:21 +0000 |
---|---|---|
committer | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-04-05 13:44:21 +0000 |
commit | 57c5f0b1c44754a6a07bd70be49e4c4beb878b67 (patch) | |
tree | 31d97692f1e1b65deaac7bae4ee6b8485ef0ec60 | |
parent | 97b3a762346a877c94543afb3d376f7e69823034 (diff) | |
download | bcm5719-llvm-57c5f0b1c44754a6a07bd70be49e4c4beb878b67.tar.gz bcm5719-llvm-57c5f0b1c44754a6a07bd70be49e4c4beb878b67.zip |
[FIX] Ensure SAI objects for exit PHIs
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
-rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 7 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll | 2 | ||||
-rw-r--r-- | polly/test/ScopInfo/exit-phi-1.ll | 2 | ||||
-rw-r--r-- | polly/test/ScopInfo/loop-multiexit-succ-cond.ll | 97 |
4 files changed, 106 insertions, 2 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 0e17241c0b9..ff1c337a837 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -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; diff --git a/polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll b/polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll index 7fa431ef67e..eda2f3ce25d 100644 --- a/polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll +++ b/polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll @@ -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: diff --git a/polly/test/ScopInfo/exit-phi-1.ll b/polly/test/ScopInfo/exit-phi-1.ll index 27a83340b39..b34f1b878b6 100644 --- a/polly/test/ScopInfo/exit-phi-1.ll +++ b/polly/test/ScopInfo/exit-phi-1.ll @@ -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 index 00000000000..d8fbb2d9adf --- /dev/null +++ b/polly/test/ScopInfo/loop-multiexit-succ-cond.ll @@ -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 +} |