From 46d6f9f0e8fc8ca1f3a18af8eba47463650c74ff Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 18 Feb 2016 16:10:56 +0100 Subject: [PATCH] isl_basic_set_expand_divs: avoid moving coefficients in extra integer divisions isl_basic_set_expand_divs needs to move the integer divisions in its input to the right position and introduce additional integer divisions. It would do these two tasks together, but this could result in an additional integer division getting added that refers to an earlier integer division that had not yet been added, the position instead being occupied by an integer division that still had to be moved. The outer integer division would then end up referring to this moved integer division instead of to the integer division that eventually ends up in that position. Move the integer divisions into their new positions before adding new ones. Signed-off-by: Sven Verdoolaege --- isl_map.c | 21 +++++++++++++++------ isl_test.c | 4 ++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/isl_map.c b/isl_map.c index 56e1cd85..945cdd8c 100644 --- a/isl_map.c +++ b/isl_map.c @@ -8100,6 +8100,12 @@ error: /* Apply the expansion computed by isl_merge_divs. * The expansion itself is given by "exp" while the resulting * list of divs is given by "div". + * + * Move the integer divisions of "bset" into the right position + * according to "exp" and then introduce the additional integer + * divisions, adding div constraints. + * The moving should be done first to avoid moving coefficients + * in the definitions of the extra integer divisions. */ __isl_give isl_basic_set *isl_basic_set_expand_divs( __isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp) @@ -8124,12 +8130,15 @@ __isl_give isl_basic_set *isl_basic_set_expand_divs( if (isl_basic_set_alloc_div(bset) < 0) goto error; - j = n_div - 1; - for (i = div->n_row - 1; i >= 0; --i) { - if (j >= 0 && exp[j] == i) { - if (i != j) - isl_basic_map_swap_div(bset, i, j); - j--; + for (j = n_div - 1; j >= 0; --j) { + if (exp[j] == j) + break; + isl_basic_map_swap_div(bset, j, exp[j]); + } + j = 0; + for (i = 0; i < div->n_row; ++i) { + if (j < n_div && exp[j] == i) { + j++; } else { isl_seq_cpy(bset->div[i], div->row[i], div->n_col); if (isl_basic_map_add_div_constraints(bset, i) < 0) diff --git a/isl_test.c b/isl_test.c index 33641270..add7c235 100644 --- a/isl_test.c +++ b/isl_test.c @@ -2228,6 +2228,10 @@ struct { } opt_tests[] = { { "{ [-1]; [1] }", "{ [x] -> [x] }", &isl_set_min_val, "-1" }, { "{ [-1]; [1] }", "{ [x] -> [x] }", &isl_set_max_val, "1" }, + { "{ [a, b] : 0 <= a, b <= 100 and b mod 2 = 0}", + "{ [a, b] -> [floor((b - 2*floor((-a)/4))/5)] }", + &isl_set_max_val, "30" }, + }; /* Perform basic isl_set_min_val and isl_set_max_val tests. -- 2.11.4.GIT