From 959424486bf7bc2a918d14bc7ee142143debec5d Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 5 Apr 2021 21:29:12 +0200 Subject: [PATCH] isl_basic_map_set_to_empty: modify input even if it is already marked empty Commit isl-0.22.1-2-g36a719fd8f (isl_basic_map_set_to_empty: do not modify input if already marked empty, Mon Mar 16 22:33:00 2020 +0100) changed isl_basic_map_set_to_empty to not change the internal representation if the input basic map is already marked empty to avoid a case where the basic map was marked empty and subsequently had all its constraints removed from resulting in an error. However, other parts of the code depend on the canonical representation of an empty basic map, or at least that the internal representation does not look like it needs further processing. In particular, if there are any non-trivial equality constraints involving local variables then isl_basic_map_drop_redundant_divs will try to exploit those equality constraints to derive an explicit representation for a local variable. However, it only prepares the input for isl_basic_map_simplify, while isl_basic_map_simplify skips all processing on an input that is marked empty. This results in an infinite recursion on isl_basic_map_drop_redundant_divs. Adjust isl_basic_map_set_to_empty to only skip the modification if the input is both marked empty and has no constraints. Signed-off-by: Sven Verdoolaege --- isl_map.c | 9 ++++++--- isl_test.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/isl_map.c b/isl_map.c index 6b6f3010..e827198a 100644 --- a/isl_map.c +++ b/isl_map.c @@ -2103,19 +2103,22 @@ static __isl_give isl_basic_map *isl_basic_map_swap_vars( * Since the basic map has conflicting constraints, * it must have at least one constraint, except perhaps * if it was already explicitly marked as being empty. - * Do nothing in the latter case. + * Do nothing in the latter case, i.e., if it has been marked empty and + * has no constraints. */ __isl_give isl_basic_map *isl_basic_map_set_to_empty( __isl_take isl_basic_map *bmap) { int i = 0; isl_bool empty; + isl_size n; isl_size total; + n = isl_basic_map_n_constraint(bmap); empty = isl_basic_map_plain_is_empty(bmap); - if (empty < 0) + if (n < 0 || empty < 0) return isl_basic_map_free(bmap); - if (empty) + if (n == 0 && empty) return bmap; total = isl_basic_map_dim(bmap, isl_dim_all); if (total < 0) diff --git a/isl_test.c b/isl_test.c index 4ac519a3..c6761667 100644 --- a/isl_test.c +++ b/isl_test.c @@ -8721,6 +8721,34 @@ int test_sample(isl_ctx *ctx) return 0; } +/* Perform a projection on a basic set that is known to be empty + * but that has not been assigned a canonical representation. + * Earlier versions of isl would run into a stack overflow + * on this example. + */ +static int test_empty_projection(isl_ctx *ctx) +{ + const char *str; + isl_bool empty; + isl_basic_set *bset; + + str = "{ [a, b, c, d, e, f, g, h] : 5f = 1 + 4a - b + 5c - d - 2e and " + "3h = 2 + b + c and 14c >= 9 - 3a + 25b and " + "4c <= 50 - 3a + 23b and 6b <= -39 + a and " + "9g >= -6 + 3a + b + c and e < a + b - 2d and " + "7d >= -5 + 2a + 2b and 5g >= -14 + a - 4b + d + 2e and " + "9g <= -28 - 5b - 2c + 3d + 6e }"; + bset = isl_basic_set_read_from_str(ctx, str); + empty = isl_basic_set_is_empty(bset); + bset = isl_basic_set_params(bset); + isl_basic_set_free(bset); + + if (empty < 0) + return -1; + + return 0; +} + int test_fixed_power(isl_ctx *ctx) { const char *str; @@ -10853,6 +10881,7 @@ struct { { "slice", &test_slice }, { "fixed power", &test_fixed_power }, { "sample", &test_sample }, + { "empty projection", &test_empty_projection }, { "output", &test_output }, { "vertices", &test_vertices }, { "chambers", &test_chambers },