From fdf9c99e27483b8c1c4938072119cd8b7c2a4a37 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 21 Aug 2012 11:37:57 +0200 Subject: [PATCH] isl_set_dim_residue_class: correctly consider all basic sets in the set This commit fixes two closely related problems. Due to a typo, isl_set_dim_residue_class would only consider one of the basic sets in the input set. The information obtained from the individual basic sets was also combined incorrectly. In particular, the code would insist that all basic sets have the same residue if they have the same modulo and not consider adjusting the modulo of the combined basic sets to accommodate for the difference in residues. Signed-off-by: Sven Verdoolaege --- isl_equalities.c | 11 +++-------- isl_test.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/isl_equalities.c b/isl_equalities.c index 68d2c89..78078d4 100644 --- a/isl_equalities.c +++ b/isl_equalities.c @@ -670,20 +670,15 @@ int isl_set_dim_residue_class(struct isl_set *set, isl_int_init(r); for (i = 1; i < set->n; ++i) { - if (isl_basic_set_dim_residue_class(set->p[0], pos, &m, &r) < 0) + if (isl_basic_set_dim_residue_class(set->p[i], pos, &m, &r) < 0) goto error; isl_int_gcd(*modulo, *modulo, m); + isl_int_sub(m, *residue, r); + isl_int_gcd(*modulo, *modulo, m); if (!isl_int_is_zero(*modulo)) isl_int_fdiv_r(*residue, *residue, *modulo); if (isl_int_is_one(*modulo)) break; - if (!isl_int_is_zero(*modulo)) - isl_int_fdiv_r(r, r, *modulo); - if (isl_int_ne(*residue, r)) { - isl_int_set_si(*modulo, 1); - isl_int_set_si(*residue, 0); - break; - } } isl_int_clear(m); diff --git a/isl_test.c b/isl_test.c index 05c8364..5c267f2 100644 --- a/isl_test.c +++ b/isl_test.c @@ -2980,6 +2980,34 @@ int test_eliminate(isl_ctx *ctx) return 0; } +/* Check that isl_set_dim_residue_class detects that the values of j + * in the set below are all odd and that it does not detect any spurious + * strides. + */ +static int test_residue_class(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_int m, r; + int res; + + str = "{ [i,j] : j = 4 i + 1 and 0 <= i <= 100; " + "[i,j] : j = 4 i + 3 and 500 <= i <= 600 }"; + set = isl_set_read_from_str(ctx, str); + isl_int_init(m); + isl_int_init(r); + res = isl_set_dim_residue_class(set, 1, &m, &r); + if (res >= 0 && + (isl_int_cmp_si(m, 2) != 0 || isl_int_cmp_si(r, 1) != 0)) + isl_die(ctx, isl_error_unknown, "incorrect residue class", + res = -1); + isl_int_clear(r); + isl_int_clear(m); + isl_set_free(set); + + return res; +} + int test_align_parameters(isl_ctx *ctx) { const char *str; @@ -3017,6 +3045,7 @@ struct { } tests [] = { { "align parameters", &test_align_parameters }, { "eliminate", &test_eliminate }, + { "reisdue class", &test_residue_class }, { "div", &test_div }, { "slice", &test_slice }, { "fixed power", &test_fixed_power }, -- 2.7.4