From e1ac81f426b8ddc50f9df99a19186785b5385288 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 3 Jul 2013 12:34:18 +0200 Subject: [PATCH] isl_ast_expr_from_aff: clear denominator before calling extract_modulos extract_modulos essentially assumes that the denominator of the affine expression is one. In particular, it depends on the caller to divide the extracted modulo expression by the denominator. Moreover, in a544f6d (isl_ast_expr_from_*: use isl_val, Tue May 28 15:18:53 2013 +0200), call to isl_aff_get_coefficient (which extracts the numerator of the coefficient) was replaced by a call to isl_aff_get_coefficient_val (which extracts the entire, possibly rational, coefficient). Rather than trying to extract the numerator from this coefficient, which is tricky because it may have been reduced already, we impose that the denominator is one. The same commit already imposed that condition on (most of) the body of isl_ast_expr_from_aff. We now simply do so before the call to extract_modulos. Signed-off-by: Sven Verdoolaege --- isl_ast_build_expr.c | 14 +++++++------- test_inputs/codegen/separate2.c | 9 +++++++++ test_inputs/codegen/separate2.in | 4 ++++ 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 test_inputs/codegen/separate2.c create mode 100644 test_inputs/codegen/separate2.in diff --git a/isl_ast_build_expr.c b/isl_ast_build_expr.c index d601e666..92f7ec7b 100644 --- a/isl_ast_build_expr.c +++ b/isl_ast_build_expr.c @@ -441,23 +441,23 @@ static __isl_give isl_aff *extract_modulo(__isl_take isl_aff *aff, * to those modulo computations to *pos and/or *neg. * We only do this if the option ast_build_prefer_pdiv is set. * + * "aff" is assumed to be an integer affine expression. + * * A modulo expression is of the form * * a mod m = a - m * floor(a / m) * * To detect them in aff, we look for terms of the form * - * (f * m * floor(a / m)) / d + * f * m * floor(a / m) * * rewrite them as * - * (f * (a - (a mod m))) / d = (f * a) / d - (f * (a mod m)) / d + * f * (a - (a mod m)) = f * a - f * (a mod m) * * and extract out -f * (a mod m). * In particular, if f > 0, we add (f * (a mod m)) to *neg. * If f < 0, we add ((-f) * (a mod m)) to *pos. - * - * The caller is responsible for dividing *neg and/or *pos by d. */ static __isl_give isl_aff *extract_modulos(__isl_take isl_aff *aff, __isl_keep isl_ast_expr **pos, __isl_keep isl_ast_expr **neg, @@ -519,12 +519,12 @@ __isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff, expr = isl_ast_expr_alloc_int_si(ctx, 0); expr_neg = isl_ast_expr_alloc_int_si(ctx, 0); - aff = extract_modulos(aff, &expr, &expr_neg, build); - expr = ast_expr_sub(expr, expr_neg); - d = isl_aff_get_denominator_val(aff); aff = isl_aff_scale_val(aff, isl_val_copy(d)); + aff = extract_modulos(aff, &expr, &expr_neg, build); + expr = ast_expr_sub(expr, expr_neg); + ls = isl_aff_get_domain_local_space(aff); for (i = 0; i < 3; ++i) { diff --git a/test_inputs/codegen/separate2.c b/test_inputs/codegen/separate2.c new file mode 100644 index 00000000..a16064b2 --- /dev/null +++ b/test_inputs/codegen/separate2.c @@ -0,0 +1,9 @@ +if ((length - 1) % 16 <= 14) + for (int c0 = 0; c0 <= 1; c0 += 1) + for (int c5 = 0; c5 <= 31; c5 += 1) + for (int c6 = 0; c6 <= 30; c6 += 1) { + if ((2 * c5 - c6 + 31) % 32 == 31 && 2 * ((length - 1) % 16) + 2 * c5 == 2 * ((length - 1) % 32) + c6 && c6 + 62 >= 2 * ((length - 1) % 16) + 2 * c5 && 2 * length + c6 >= 2 * ((length - 1) % 16) + 4 && 2 * ((length - 1) % 16) >= c6 && 2 * ((length - 1) % 16) + 2 * c5 >= c6) + S_3(c0, 0, (-(2 * ((length - 1) % 16)) + 2 * length + c6 - 2) / 2); + if (length <= 16 && length >= c5 + 1 && c6 >= 1 && length >= c6) + S_0(c0, c5, c6 - 1); + } diff --git a/test_inputs/codegen/separate2.in b/test_inputs/codegen/separate2.in new file mode 100644 index 00000000..8f4ebf1a --- /dev/null +++ b/test_inputs/codegen/separate2.in @@ -0,0 +1,4 @@ +# Check that rational affine expressions are printer properly. +[tsteps, length] -> { S_0[iter, i, j] -> [iter, 0, o2, o3, 0, o5, o6, 4] : exists (e0 = [(o2)/32], e1 = [(o3)/32], e2 = [(-i + o5)/32], e3 = [(-31 + j - o6)/32]: tsteps = 2 and 32e0 = o2 and 32e1 = o3 and 32e2 = -i + o5 and 32e3 = -31 + j - o6 and o2 <= i and o2 >= -31 + i and o3 <= 1 + j and o3 >= -30 + j and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 31 and i <= -1 + length and i >= 0 and iter >= 0 and iter <= 1 and j <= -1 + length and j >= 0 and o2 >= -31 + length and o3 >= -30 + 2length); S_3[iter, 0, j] -> [iter, 0, o2, o3, o4, o5, o6, 2] : exists (e0 = [(o2)/32], e1 = [(o3)/32], e2 = [(o4)/32], e3 = [(-2o5 + o6)/32], e4 = [(j - o5)/32]: tsteps = 2 and 32e0 = o2 and 32e1 = o3 and 32e2 = o4 and 32e3 = -2o5 + o6 and 32e4 = j - o5 and iter <= 1 and j <= -1 + length and o2 <= j and o2 >= -31 + j and o3 <= 2j and o3 >= -30 + 2j and o4 >= 0 and o4 <= 31 and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 30 and j >= 1 and iter >= 0 and o2 >= -31 + length and o3 >= -30 + 2length) } +[tsteps, length] -> { : length >= 1 and length <= 1024 and tsteps = 2 } +{ [o0,o1,o2,o3,o4,o5,o6,o7] -> separate[x] } -- 2.11.4.GIT