2016-04-05 21:44:21 +08:00
|
|
|
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
|
|
|
|
; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s --check-prefix=IR
|
|
|
|
;
|
2018-04-26 02:53:33 +08:00
|
|
|
; The SCoP contains a loop with multiple exit blocks (BBs after leaving
|
|
|
|
; the loop). The current implementation of deriving their domain derives
|
|
|
|
; only a common domain for all of the exit blocks. We disabled loops with
|
|
|
|
; multiple exit blocks until this is fixed.
|
|
|
|
; XFAIL: *
|
|
|
|
;
|
2016-04-05 21:44:21 +08:00
|
|
|
; Check that we do not crash and generate valid IR.
|
|
|
|
;
|
|
|
|
; CHECK: Assumed Context:
|
|
|
|
; CHECK-NEXT: [count1, dobreak, count2] -> { : }
|
|
|
|
; CHECK-NEXT: Invalid Context:
|
2016-04-12 21:27:35 +08:00
|
|
|
; CHECK-NEXT: [count1, dobreak, count2] -> { : (count1 > 0 and dobreak > 0) or count1 <= 0 or (count1 > 0 and dobreak <= 0 and count2 > 0) }
|
2016-04-05 21:44:21 +08:00
|
|
|
;
|
|
|
|
; 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
|
|
|
|
}
|