isl_basic_set_opt: avoid invalid access on error path
[platform/upstream/isl.git] / isl_test.c
index 745c4ed..fb6a5f4 100644 (file)
@@ -1534,6 +1534,20 @@ void test_lexmin(struct isl_ctx *ctx)
        assert(isl_map_is_equal(map, map2));
        isl_map_free(map);
        isl_map_free(map2);
+
+       /* Check that empty pieces are properly combined. */
+       str = "[K, N] -> { [x, y] -> [a, b] : K+2<=N<=K+4 and x>=4 and "
+               "2N-6<=x<K+N and N-1<=a<=K+N-1 and N+b-6<=a<=2N-4 and "
+               "b<=2N-3K+a and 3b<=4N-K+1 and b>=N and a>=x+1 }";
+       map = isl_map_read_from_str(ctx, str);
+       map = isl_map_lexmin(map);
+       str = "[K, N] -> { [x, y] -> [1 + x, N] : x >= -6 + 2N and "
+               "x <= -5 + 2N and x >= -1 + 3K - N and x <= -2 + K + N and "
+               "x >= 4 }";
+       map2 = isl_map_read_from_str(ctx, str);
+       assert(isl_map_is_equal(map, map2));
+       isl_map_free(map);
+       isl_map_free(map2);
 }
 
 struct must_may {
@@ -2348,6 +2362,43 @@ int test_special_schedule(isl_ctx *ctx, const char *domain,
        return 0;
 }
 
+/* Check that the schedule map is properly padded, even after being
+ * reconstructed from the band forest.
+ */
+static int test_padded_schedule(isl_ctx *ctx)
+{
+       const char *str;
+       isl_union_set *D;
+       isl_union_map *validity, *proximity;
+       isl_schedule *sched;
+       isl_union_map *map1, *map2;
+       isl_band_list *list;
+       int equal;
+
+       str = "[N] -> { S0[i] : 0 <= i <= N; S1[i, j] : 0 <= i, j <= N }";
+       D = isl_union_set_read_from_str(ctx, str);
+       validity = isl_union_map_empty(isl_union_set_get_space(D));
+       proximity = isl_union_map_copy(validity);
+       sched = isl_union_set_compute_schedule(D, validity, proximity);
+       map1 = isl_schedule_get_map(sched);
+       list = isl_schedule_get_band_forest(sched);
+       isl_band_list_free(list);
+       map2 = isl_schedule_get_map(sched);
+       isl_schedule_free(sched);
+       equal = isl_union_map_is_equal(map1, map2);
+       isl_union_map_free(map1);
+       isl_union_map_free(map2);
+
+       if (equal < 0)
+               return -1;
+       if (!equal)
+               isl_die(ctx, isl_error_unknown,
+                       "reconstructed schedule map not the same as original",
+                       return -1);
+
+       return 0;
+}
+
 int test_schedule(isl_ctx *ctx)
 {
        const char *D, *W, *R, *V, *P, *S;
@@ -2608,6 +2659,23 @@ int test_schedule(isl_ctx *ctx)
        if (test_has_schedule(ctx, D, V, P) < 0)
                return -1;
 
+       if (test_padded_schedule(ctx) < 0)
+               return -1;
+
+       /* Check that check for progress is not confused by rational
+        * solution.
+        */
+       D = "[N] -> { S0[i, j] : i >= 0 and i <= N and j >= 0 and j <= N }";
+       V = "[N] -> { S0[i0, -1 + N] -> S0[2 + i0, 0] : i0 >= 0 and "
+                                                       "i0 <= -2 + N; "
+                       "S0[i0, i1] -> S0[i0, 1 + i1] : i0 >= 0 and "
+                               "i0 <= N and i1 >= 0 and i1 <= -1 + N }";
+       P = "{}";
+       ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER;
+       if (test_has_schedule(ctx, D, V, P) < 0)
+               return -1;
+       ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL;
+
        return 0;
 }
 
@@ -3867,10 +3935,36 @@ static int test_simplify(isl_ctx *ctx)
        return 0;
 }
 
+/* This is a regression test for a bug where isl_tab_basic_map_partial_lexopt
+ * with gbr context would fail to disable the use of the shifted tableau
+ * when transferring equalities for the input to the context, resulting
+ * in invalid sample values.
+ */
+static int test_partial_lexmin(isl_ctx *ctx)
+{
+       const char *str;
+       isl_basic_set *bset;
+       isl_basic_map *bmap;
+       isl_map *map;
+
+       str = "{ [1, b, c, 1 - c] -> [e] : 2e <= -c and 2e >= -3 + c }";
+       bmap = isl_basic_map_read_from_str(ctx, str);
+       str = "{ [a, b, c, d] : c <= 1 and 2d >= 6 - 4b - c }";
+       bset = isl_basic_set_read_from_str(ctx, str);
+       map = isl_basic_map_partial_lexmin(bmap, bset, NULL);
+       isl_map_free(map);
+
+       if (!map)
+               return -1;
+
+       return 0;
+}
+
 struct {
        const char *name;
        int (*fn)(isl_ctx *ctx);
 } tests [] = {
+       { "partial lexmin", &test_partial_lexmin },
        { "simplify", &test_simplify },
        { "curry", &test_curry },
        { "piecewise multi affine expressions", &test_pw_multi_aff },