From 5e2bd4b64083284477ba37fcf47d45ad94748223 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 29 Jan 2015 11:49:51 +0100 Subject: [PATCH] isl_tab.c: drop_col: drop column before dropping corresponding variable Since c557799 (add isl_tab_insert_var, Fri Oct 10 11:44:09 2014 +0200), we allow the insertion of variables in the tableau at positions other than the final position. This requires all subsequent variables to be moved up. During an undo, these changes need to be undone, but they need to be postponed until the colum is removed since the column may need to be moved into the last position and this requires the positions of the variables involved, including the variable that is about to be removed. Reported-by: Sven Wuytack Signed-off-by: Sven Verdoolaege --- isl_tab.c | 13 ++++++++++--- isl_test.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/isl_tab.c b/isl_tab.c index be75caef..a1258d0a 100644 --- a/isl_tab.c +++ b/isl_tab.c @@ -1839,15 +1839,22 @@ static int drop_row(struct isl_tab *tab, int row) return 0; } -/* Drop the variable in column "col". +/* Drop the variable in column "col" along with the column. + * The column is removed first because it may need to be moved + * into the last position and this process requires + * the contents of the col_var array in a state + * before the removal of the variable. */ static int drop_col(struct isl_tab *tab, int col) { - if (var_drop_entry(tab, tab->col_var[col]) < 0) - return -1; + int var; + + var = tab->col_var[col]; if (col != tab->n_col - 1) swap_cols(tab, col, tab->n_col - 1); tab->n_col--; + if (var_drop_entry(tab, var) < 0) + return -1; return 0; } diff --git a/isl_test.c b/isl_test.c index 324d3d6b..62eb1507 100644 --- a/isl_test.c +++ b/isl_test.c @@ -1531,6 +1531,45 @@ struct { "i8 >= -40 + i0 and i8 <= -10 + i0)) }" }, }; +/* A specialized coalescing test case that would result + * in a segmentation fault or a failed assertion in earlier versions of isl. + */ +static int test_coalesce_special(struct isl_ctx *ctx) +{ + const char *str; + isl_map *map1, *map2; + + str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[1, o1]] : " + "(y = 201 and o1 <= 239 and o1 >= 212) or " + "(exists (e0 = [(y)/3]: 3e0 = y and y <= 198 and y >= 3 and " + "o1 <= 239 and o1 >= 212)) or " + "(exists (e0 = [(y)/3]: 3e0 = y and y <= 201 and y >= 3 and " + "o1 <= 241 and o1 >= 240));" + "[S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[0, o1]] : " + "(y = 2 and o1 <= 241 and o1 >= 212) or " + "(exists (e0 = [(-2 + y)/3]: 3e0 = -2 + y and y <= 200 and " + "y >= 5 and o1 <= 241 and o1 >= 212)) }"; + map1 = isl_map_read_from_str(ctx, str); + map1 = isl_map_align_divs(map1); + map1 = isl_map_coalesce(map1); + str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[o0, o1]] : " + "exists (e0 = [(-1 - y + o0)/3]: 3e0 = -1 - y + o0 and " + "y <= 201 and o0 <= 2 and o1 >= 212 and o1 <= 241 and " + "o0 >= 3 - y and o0 <= -2 + y and o0 >= 0) }"; + map2 = isl_map_read_from_str(ctx, str); + map2 = isl_map_union(map2, map1); + map2 = isl_map_align_divs(map2); + map2 = isl_map_coalesce(map2); + isl_map_free(map2); + if (!map2) + return -1; + + return 0; +} + /* Test the functionality of isl_set_coalesce. * That is, check that the output is always equal to the input * and in some cases that the result consists of a single disjunct. @@ -1548,6 +1587,8 @@ static int test_coalesce(struct isl_ctx *ctx) if (test_coalesce_unbounded_wrapping(ctx) < 0) return -1; + if (test_coalesce_special(ctx) < 0) + return -1; return 0; } -- 2.11.4.GIT