From 56798a073916c14d9671f11ccf3438b2762e09a1 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 5 Mar 2013 21:35:22 +0100 Subject: [PATCH] isl_ast_build_ast_from_schedule: fix unrolling corner case In some rare cases, the constraint added to perform the unrolling could get simplied away and then dropped after a simplification of the domain. We add the constraint back after the simplification to ensure that it is present in the result. Reported-by: Tobias Grosser Signed-off-by: Sven Verdoolaege --- isl_ast_codegen.c | 24 +++++++++++++----------- test_inputs/codegen/unroll3.c | 2 ++ test_inputs/codegen/unroll3.in | 6 ++++++ 3 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 test_inputs/codegen/unroll3.c create mode 100644 test_inputs/codegen/unroll3.in diff --git a/isl_ast_codegen.c b/isl_ast_codegen.c index e9355502..c524768d 100644 --- a/isl_ast_codegen.c +++ b/isl_ast_codegen.c @@ -2166,22 +2166,17 @@ error: return isl_aff_free(data.lower); } -/* Intersect "set" with the constraint +/* Return the constraint * * i_"depth" = aff + offset */ -static __isl_give isl_set *at_offset(__isl_take isl_set *set, int depth, - __isl_keep isl_aff *aff, int offset) +static __isl_give isl_constraint *at_offset(int depth, __isl_keep isl_aff *aff, + int offset) { - isl_constraint *eq; - aff = isl_aff_copy(aff); aff = isl_aff_add_coefficient_si(aff, isl_dim_in, depth, -1); aff = isl_aff_add_constant_si(aff, offset); - eq = isl_equality_from_aff(aff); - set = isl_set_add_constraint(set, eq); - - return set; + return isl_equality_from_aff(aff); } /* Return a list of basic sets, one for each value of the current dimension @@ -2207,7 +2202,10 @@ static __isl_give isl_set *at_offset(__isl_take isl_set *set, int depth, * * We compute the unshifted simple hull of each slice to ensure that * we have a single basic set per offset. The slicing constraint - * is preserved by taking the unshifted simple hull, so these basic sets + * may get simplified away before the unshifted simple hull is taken + * and may therefore in some rare cases disappear from the result. + * We therefore explicitly add the constraint back after computing + * the unshifted simple hull to ensure that the basic sets * remain disjoint. The constraints that are dropped by taking the hull * will be taken into account at the next level, as in the case of the * atomic option. @@ -2252,9 +2250,13 @@ static __isl_give isl_basic_set_list *do_unroll(__isl_take isl_set *domain, for (i = 0; list && i < n; ++i) { isl_set *set; isl_basic_set *bset; + isl_constraint *slice; - set = at_offset(isl_set_copy(domain), depth, lower, i); + slice = at_offset(depth, lower, i); + set = isl_set_copy(domain); + set = isl_set_add_constraint(set, isl_constraint_copy(slice)); bset = isl_set_unshifted_simple_hull(set); + bset = isl_basic_set_add_constraint(bset, slice); bset = isl_basic_set_apply(bset, isl_basic_map_copy(bmap)); list = isl_basic_set_list_add(list, bset); } diff --git a/test_inputs/codegen/unroll3.c b/test_inputs/codegen/unroll3.c new file mode 100644 index 00000000..95a30ba7 --- /dev/null +++ b/test_inputs/codegen/unroll3.c @@ -0,0 +1,2 @@ +if ((t1 + 121) % 128 <= 123) + write_shared_A(((t1 + 125) % 128) - 3); diff --git a/test_inputs/codegen/unroll3.in b/test_inputs/codegen/unroll3.in new file mode 100644 index 00000000..098e5010 --- /dev/null +++ b/test_inputs/codegen/unroll3.in @@ -0,0 +1,6 @@ +# Check that the entire schedule is completely unrolled and +# in particular that no spurious loop is introduced. +[t1] -> { write_shared_A[i2] -> [1, 3, 6 + i2, 0, t1] : (exists (e0 = [(-6 + t1 - i2)/128]: 128e0 = -6 + t1 - i2 and i2 <= 122 and i2 >= 1 and t1 >= 0 and t1 <= 127)) or (exists (e0 = [(-6 + t1 - i2)/128]: 128e0 = -6 + t1 - i2 and i2 >= 123 and i2 <= 124 and t1 <= 127 and t1 >= 0 )) } +[t1] -> { : t1 >= 0 and t1 <= 127 } +[t1] -> { [i0, i1, i2, i3, i4] -> unroll[o0] } + -- 2.11.4.GIT