partitionSetParts(__isl_take isl_set *S, unsigned Dim) {
for (unsigned u = 0, e = isl_set_n_dim(S); u < e; u++)
- S = isl_set_lower_bound_si(S, isl_dim_set, u, 0);
+ S = isl_set_lower_bound_si(S, isl_dim_set, u, u == Dim ? -1 : 0);
unsigned NumDimsS = isl_set_n_dim(S);
- isl_set *OnlyDimS = isl_set_copy(S);
+ isl_set *OnlyDimS = S;
// Remove dimensions that are greater than Dim as they are not interesting.
assert(NumDimsS >= Dim + 1);
// Remove the artificial upper bound parameters again.
BoundedParts = isl_set_remove_dims(BoundedParts, isl_dim_param, 0, Dim);
- isl_set *UnboundedParts = isl_set_subtract(S, isl_set_copy(BoundedParts));
+ isl_set *UnboundedParts = isl_set_complement(isl_set_copy(BoundedParts));
return std::make_pair(UnboundedParts, BoundedParts);
}
isl_set_project_out(BackedgeCondition, isl_dim_set, LoopDepth + 1,
LatchLoopDepth - LoopDepth);
- auto Parts = partitionSetParts(BackedgeCondition, LoopDepth);
+ isl_map *ForwardMap = isl_map_lex_le(isl_set_get_space(HeaderBBDom));
+ for (int i = 0; i < LoopDepth; i++)
+ ForwardMap = isl_map_equate(ForwardMap, isl_dim_in, i, isl_dim_out, i);
+
+ isl_set *BackedgeConditionComplement =
+ isl_set_complement(BackedgeCondition);
+ BackedgeConditionComplement = isl_set_lower_bound_si(
+ BackedgeConditionComplement, isl_dim_set, LoopDepth, 0);
+ BackedgeConditionComplement =
+ isl_set_apply(BackedgeConditionComplement, ForwardMap);
+ HeaderBBDom = isl_set_subtract(HeaderBBDom, BackedgeConditionComplement);
+
+ auto Parts = partitionSetParts(HeaderBBDom, LoopDepth);
// If a loop has an unbounded back edge condition part (here Parts.first)
// we do not want to assume the header will even be executed for the first
// iteration of an execution that will lead to an infinite loop. While it
// would not be wrong to do so, it does not seem helpful.
+ // TODO: Use the unbounded part to build runtime assumptions.
FirstIteration = isl_set_subtract(FirstIteration, Parts.first);
- BackedgeCondition = isl_set_apply(Parts.second, NextIterationMap);
- BackedgeCondition = isl_set_union(BackedgeCondition, FirstIteration);
- BackedgeCondition = isl_set_coalesce(BackedgeCondition);
+ HeaderBBDom = isl_set_apply(Parts.second, NextIterationMap);
+ HeaderBBDom = isl_set_coalesce(isl_set_union(HeaderBBDom, FirstIteration));
- HeaderBBDom = isl_set_intersect(HeaderBBDom, BackedgeCondition);
}
}
; but %call is a parameter of the SCoP and we need to make sure its value is
; properly forwarded to the subfunction.
-; AST: Stmt_for_body(0);
; AST: #pragma omp parallel for
-; AST: for (int c0 = 1; c0 < cols; c0 += 1)
+; AST: for (int c0 = 0; c0 < cols; c0 += 1)
; AST: Stmt_for_body(c0);
+; AST: if (cols <= 0)
+; AST: Stmt_for_body(0);
; IR: @foo_polly_subfn
; Another variation of this test case, now with even more of the index
; expression defined outside of the scop.
-; AST: Stmt_for_body(0);
; AST: #pragma omp parallel for
-; AST: for (int c0 = 1; c0 < cols; c0 += 1)
+; AST: for (int c0 = 0; c0 < cols; c0 += 1)
; AST: Stmt_for_body(c0);
+; AST: if (cols <= 0)
+; AST: Stmt_for_body(0);
; IR: @bar_polly_subfn
; of the scop, but does not contain the scop.
; AST: {
-; AST-NEXT: Stmt_while_body(0);
; AST-NEXT: #pragma simd
; AST-NEXT: #pragma omp parallel for
-; AST-NEXT: for (int c0 = 1; c0 < p_0 + symbol; c0 += 1)
+; AST-NEXT: for (int c0 = 0; c0 < p_0 + symbol; c0 += 1)
; AST-NEXT: Stmt_while_body(c0);
+; AST-NEXT: if (p_0 + symbol <= 0)
+; AST-NEXT: Stmt_while_body(0);
; AST-NEXT: }
; IR: @update_model_polly_subfn
; CHECK-LABEL: polly.start:
; CHECK-NEXT: store float 0.000000e+00, float* %tmp.0.phiops
-; CHECK-LABEL: polly.merge:
+; CHECK-LABEL: polly.merge2:
; CHECK-NEXT: br label %polly.merge_new_and_old
; CHECK-LABEL: polly.stmt.bb1{{[0-9]*}}:
; CHECK-NEXT: %tmp.0.phiops.reload[[R1:[0-9]*]] = load float, float* %tmp.0.phiops
; CHECK: store float %tmp.0.phiops.reload[[R1]], float* %tmp.0.s2a
-; CHECK-LABEL: polly.stmt.bb1{{[0-9]*}}:
-; CHECK-NEXT: %tmp.0.phiops.reload[[R2:[0-9]*]] = load float, float* %tmp.0.phiops
-; CHECK: store float %tmp.0.phiops.reload[[R2]], float* %tmp.0.s2a
-
-; CHECK-LABEL: polly.stmt.bb4: ; preds = %polly.then3
+; CHECK-LABEL: polly.stmt.bb4:
; CHECK: %tmp[[R5:[0-9]*]]_p_scalar_ = load float, float* %scevgep, align 4, !alias.scope !0, !noalias !2
; CHECK: %tmp.0.s2a.reload[[R3:[0-9]*]] = load float, float* %tmp.0.s2a
; CHECK: %p_tmp[[R4:[0-9]*]] = fadd float %tmp.0.s2a.reload[[R3]], %tmp[[R5]]_p_scalar_
; CHECK: store float %p_tmp[[R4]], float* %tmp.0.phiops
+; CHECK-LABEL: polly.stmt.bb1{{[0-9]*}}:
+; CHECK-NEXT: %tmp.0.phiops.reload[[R2:[0-9]*]] = load float, float* %tmp.0.phiops
+; CHECK: store float %tmp.0.phiops.reload[[R2]], float* %tmp.0.s2a
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(float* %A, i32 %N) {
; }
; CHECK-LABEL: polly.merge_new_and_old:
-; CHECK-NEXT: %tmp.0.merge = phi float [ %tmp.0.final_reload, %polly.merge ], [ %tmp.0, %bb8 ]
+; CHECK-NEXT: %tmp.0.merge = phi float [ %tmp.0.final_reload, %polly.merge2 ], [ %tmp.0, %bb8 ]
; CHECK-NEXT: br label %exit
; CHECK-LABEL: polly.start:
; CHECK-NEXT: store float 0.000000e+00, float* %tmp.0.phiops
-; CHECK-LABEL: polly.merge:
+; CHECK-LABEL: polly.merge2:
; CHECK-NEXT: %tmp.0.final_reload = load float, float* %tmp.0.s2a
; CHECK-NEXT: br label %polly.merge_new_and_old
; CHECK-NEXT: %tmp.0.phiops.reload[[R1:[0-9]*]] = load float, float* %tmp.0.phiops
; CHECK-: store float %tmp.0.phiops.reload[[R1]], float* %tmp.0.s2a
-; CHECK-LABEL: polly.stmt.bb1{{[0-9]*}}:
-; CHECK-NEXT: %tmp.0.phiops.reload[[R2:[0-9]*]] = load float, float* %tmp.0.phiops
-; CHECK: store float %tmp.0.phiops.reload[[R2]], float* %tmp.0.s2a
-
-; CHECK-LABEL: polly.stmt.bb4: ; preds = %polly.then3
+; CHECK-LABEL: polly.stmt.bb4:
; CHECK: %tmp[[R5:[0-9]*]]_p_scalar_ = load float, float* %scevgep, align 4, !alias.scope !0, !noalias !2
; CHECK: %tmp.0.s2a.reload[[R3:[0-9]*]] = load float, float* %tmp.0.s2a
; CHECK: %p_tmp[[R4:[0-9]*]] = fadd float %tmp.0.s2a.reload[[R3]], %tmp[[R5]]_p_scalar_
; CHECK: store float %p_tmp[[R4]], float* %tmp.0.phiops
+; CHECK-LABEL: polly.stmt.bb1{{[0-9]*}}:
+; CHECK-NEXT: %tmp.0.phiops.reload[[R2:[0-9]*]] = load float, float* %tmp.0.phiops
+; CHECK: store float %tmp.0.phiops.reload[[R2]], float* %tmp.0.s2a
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define float @f(float* %A, i32 %N) {
br label %for.cond
; CHECK-LABEL: polly.merge_new_and_old:
-; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge ], [ %x.addr.0, %for.cond ]
+; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge21 ], [ %x.addr.0, %for.cond ]
; CHECK: ret i32 %x.addr.0.merge
; CHECK-LABEL: polly.start:
; CHECK-NEXT: store i32 %x, i32* %x.addr.0.phiops
-; CHECK-LABEL: polly.merge:
+; CHECK-LABEL: polly.merge21:
; CHECK: %x.addr.0.final_reload = load i32, i32* %x.addr.0.s2a
for.cond: ; preds = %for.inc5, %entry
%cmp = icmp slt i64 %indvars.iv, %tmp
br i1 %cmp, label %for.body, label %for.end7
-; CHECK-LABEL: polly.stmt.for.cond{{[0-9]*}}:
-; CHECK: %x.addr.0.phiops.reload[[R1:[0-9]*]] = load i32, i32* %x.addr.0.phiops
-; CHECK: store i32 %x.addr.0.phiops.reload[[R1]], i32* %x.addr.0.s2a
-
for.body: ; preds = %for.cond
; CHECK-LABEL: polly.stmt.for.body:
; CHECK: %x.addr.0.s2a.reload[[R2:[0-9]*]] = load i32, i32* %x.addr.0.s2a
; hence modulo handling has been disabled completely. Once this is
; resolved this test should work again. Until then we approximate the
; whole loop body.
-; CHECK: Stmt_for_body__TO__if_end
+;
; CHECK: Domain :=
; CHECK: { Stmt_for_body__TO__if_end[i0] : i0 <= 15 and i0 >= 0 };
-
+;
;
; void foo(float *A) {
; for (long i = 0; i < 16; i++) {
; RUN: opt %loadPolly -polly-detect-unprofitable -polly-allow-non-scev-backedge-taken-count -polly-scops -analyze < %s | FileCheck %s
;
-; CHECK: [M, N] -> { Stmt_while_body[i0] : i0 >= 1 and 4i0 <= -M + N; Stmt_while_body[0] }
+; CHECK: [M, N] -> { Stmt_while_body[i0] : i0 >= 0 and 4i0 <= -M + N; Stmt_while_body[0] : N <= -1 + M }
;
; void f(int *A, int N, int M) {
; int i = 0;
; CHECK: Stmt_bb1
; CHECK: Domain :=
; CHECK: [N, M] -> { Stmt_bb1[i0, i1] :
-; CHECK-DAG: i0 >= 1
+; CHECK-DAG: i0 >= 0
; CHECK-DAG: and
; CHECK-DAG: i0 <= 2 + 4N + 7M
; CHECK-DAG: and
; CHECK-DAG: and
; CHECK-DAG: i1 <= 1 + 5N - i0
; CHECK-DAG: Stmt_bb1[0, i1] :
+; CHECK-DAG: 7M <= -3 - 4N
+; CHECK-DAG: and
; CHECK-DAG: i1 >= 0
; CHECK-DAG: and
; CHECK-DAG: i1 <= 1 + 5N
; RUN: opt %loadPolly -polly-scops -polly-detect-unprofitable -analyze < %s | FileCheck %s
;
; CHECK: Domain :=
-; CHECK: [N, P, Q] -> { Stmt_if_end[i0] : (i0 >= 2 + P and i0 >= 1 and i0 <= 1 + Q and i0 <= -1 + N) or (i0 >= 1 and i0 <= 1 + Q and i0 <= -1 + P and i0 <= -1 + N); Stmt_if_end[0] : (N >= 1 and P <= -1) or (N >= 1 and P >= 1) };
+; CHECK: [N, P, Q] -> { Stmt_if_end[i0] : (i0 >= 0 and i0 <= 1 + Q and i0 <= -1 + P and i0 <= -1 + N) or (P <= -1 and i0 >= 1 + P - Q and i0 >= 0 and i0 <= 1 + Q and i0 <= -1 + N); Stmt_if_end[0] : (N >= 1 and P <= -2 and Q <= -2) or (N >= 1 and P >= 1 and Q <= -2) or (P = -1 and N >= 1) }
;
; void f(int *A, int N, int P, int Q) {
; for (int i = 0; i < N; i++) {