[polly] r244585 - Update isl to isl-0.15-117-ge42acfe

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 04:31:20 PDT 2015


Author: grosser
Date: Tue Aug 11 06:31:18 2015
New Revision: 244585

URL: http://llvm.org/viewvc/llvm-project?rev=244585&view=rev
Log:
Update isl to isl-0.15-117-ge42acfe

Besides other changes this version of isl contains a fundamental fix to memory
corruption issues we have seen with imath-32 backed isl_ints.

This update also contains a fix that ensures that the schedule-tree based
version of isl's dependence analysis takes the domain of the schedule into
account.

Added:
    polly/trunk/lib/External/isl/isl_multi_coalesce.c
Modified:
    polly/trunk/lib/External/isl/GIT_HEAD_ID
    polly/trunk/lib/External/isl/Makefile.am
    polly/trunk/lib/External/isl/Makefile.in
    polly/trunk/lib/External/isl/doc/manual.pdf
    polly/trunk/lib/External/isl/doc/user.pod
    polly/trunk/lib/External/isl/include/isl/aff.h
    polly/trunk/lib/External/isl/isl_aff.c
    polly/trunk/lib/External/isl/isl_affine_hull.c
    polly/trunk/lib/External/isl/isl_ast_build.c
    polly/trunk/lib/External/isl/isl_ast_build_private.h
    polly/trunk/lib/External/isl/isl_flow.c
    polly/trunk/lib/External/isl/isl_map.c
    polly/trunk/lib/External/isl/isl_map_private.h
    polly/trunk/lib/External/isl/isl_map_simplify.c
    polly/trunk/lib/External/isl/isl_test.c
    polly/trunk/lib/External/isl/test_inputs/codegen/omega/iter9-0.c
    polly/trunk/lib/External/isl/test_inputs/codegen/roman.c
    polly/trunk/lib/External/isl/test_inputs/codegen/separate2.c
    polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll
    polly/trunk/test/ScopInfo/multidim_srem.ll

Modified: polly/trunk/lib/External/isl/GIT_HEAD_ID
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/GIT_HEAD_ID?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/GIT_HEAD_ID (original)
+++ polly/trunk/lib/External/isl/GIT_HEAD_ID Tue Aug 11 06:31:18 2015
@@ -1 +1 @@
-isl-0.15-86-g595055e
+isl-0.15-117-ge42acfe

Modified: polly/trunk/lib/External/isl/Makefile.am
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/Makefile.am?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/Makefile.am (original)
+++ polly/trunk/lib/External/isl/Makefile.am Tue Aug 11 06:31:18 2015
@@ -317,6 +317,7 @@ EXTRA_DIST = \
 	isl_multi_apply_templ.c \
 	isl_multi_apply_set.c \
 	isl_multi_apply_union_set.c \
+	isl_multi_coalesce.c \
 	isl_multi_floor.c \
 	isl_multi_gist.c \
 	isl_multi_intersect.c \
@@ -369,3 +370,10 @@ install-data-local: $(srcdir)/isl.py
 		$(DESTDIR)$(libdir)/$$libisl-gdb.py; \
 	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"; \
 	$(INSTALL_DATA) $(srcdir)/isl.py $(DESTDIR)$(libdir)/$$libisl-gdb.py; esac
+
+uninstall-local:
+	@libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p;}" \
+		 $(builddir)/libisl.la`; \
+	if test -n "$${libisl}"; then \
+		rm -f $(DESTDIR)$(libdir)/$$libisl-gdb.py; \
+	fi

Modified: polly/trunk/lib/External/isl/Makefile.in
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/Makefile.in?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/Makefile.in (original)
+++ polly/trunk/lib/External/isl/Makefile.in Tue Aug 11 06:31:18 2015
@@ -1059,6 +1059,7 @@ EXTRA_DIST = \
 	isl_multi_apply_templ.c \
 	isl_multi_apply_set.c \
 	isl_multi_apply_union_set.c \
+	isl_multi_coalesce.c \
 	isl_multi_floor.c \
 	isl_multi_gist.c \
 	isl_multi_intersect.c \
@@ -2097,8 +2098,8 @@ ps: ps-recursive
 ps-am:
 
 uninstall-am: uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \
-	uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \
-	uninstall-pkgincludeHEADERS
+	uninstall-local uninstall-nodist_pkgincludeHEADERS \
+	uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS
 
 .MAKE: $(am__recursive_targets) all check-am install-am install-strip
 
@@ -2124,8 +2125,8 @@ uninstall-am: uninstall-deprecatedHEADER
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am \
 	uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \
-	uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \
-	uninstall-pkgincludeHEADERS
+	uninstall-local uninstall-nodist_pkgincludeHEADERS \
+	uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS
 
 
 dist-hook:
@@ -2146,6 +2147,13 @@ install-data-local: $(srcdir)/isl.py
 	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"; \
 	$(INSTALL_DATA) $(srcdir)/isl.py $(DESTDIR)$(libdir)/$$libisl-gdb.py; esac
 
+uninstall-local:
+	@libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p;}" \
+		 $(builddir)/libisl.la`; \
+	if test -n "$${libisl}"; then \
+		rm -f $(DESTDIR)$(libdir)/$$libisl-gdb.py; \
+	fi
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:

Modified: polly/trunk/lib/External/isl/doc/manual.pdf
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/doc/manual.pdf?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
Binary files polly/trunk/lib/External/isl/doc/manual.pdf (original) and polly/trunk/lib/External/isl/doc/manual.pdf Tue Aug 11 06:31:18 2015 differ

Modified: polly/trunk/lib/External/isl/doc/user.pod
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/doc/user.pod?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/doc/user.pod (original)
+++ polly/trunk/lib/External/isl/doc/user.pod Tue Aug 11 06:31:18 2015
@@ -4636,6 +4636,9 @@ basic set or relation.
 	__isl_give isl_union_pw_multi_aff *
 	isl_union_pw_multi_aff_coalesce(
 		__isl_take isl_union_pw_multi_aff *upma);
+	__isl_give isl_multi_union_pw_aff *
+	isl_multi_union_pw_aff_coalesce(
+		__isl_take isl_multi_union_pw_aff *aff);
 
 	#include <isl/polynomial.h>
 	__isl_give isl_pw_qpolynomial_fold *

Modified: polly/trunk/lib/External/isl/include/isl/aff.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/aff.h?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/aff.h (original)
+++ polly/trunk/lib/External/isl/include/isl/aff.h Tue Aug 11 06:31:18 2015
@@ -851,6 +851,8 @@ __isl_give isl_multi_union_pw_aff *isl_m
 __isl_give isl_union_set *isl_multi_union_pw_aff_domain(
 	__isl_take isl_multi_union_pw_aff *mupa);
 
+__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_coalesce(
+	__isl_take isl_multi_union_pw_aff *aff);
 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_gist(
 	__isl_take isl_multi_union_pw_aff *aff,
 	__isl_take isl_union_set *context);

Modified: polly/trunk/lib/External/isl/isl_aff.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_aff.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_aff.c (original)
+++ polly/trunk/lib/External/isl/isl_aff.c Tue Aug 11 06:31:18 2015
@@ -6005,6 +6005,7 @@ error:
 
 #include <isl_multi_templ.c>
 #include <isl_multi_apply_set.c>
+#include <isl_multi_coalesce.c>
 #include <isl_multi_gist.c>
 #include <isl_multi_intersect.c>
 
@@ -6375,32 +6376,6 @@ isl_bool isl_multi_pw_aff_is_equal(__isl
 	return isl_bool_true;
 }
 
-/* Coalesce the elements of "mpa".
- *
- * Note that such coalescing does not change the meaning of "mpa"
- * so there is no need to cow.  We do need to be careful not to
- * destroy any other copies of "mpa" in case of failure.
- */
-__isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce(
-	__isl_take isl_multi_pw_aff *mpa)
-{
-	int i;
-
-	if (!mpa)
-		return NULL;
-
-	for (i = 0; i < mpa->n; ++i) {
-		isl_pw_aff *pa = isl_pw_aff_copy(mpa->p[i]);
-		pa = isl_pw_aff_coalesce(pa);
-		if (!pa)
-			return isl_multi_pw_aff_free(mpa);
-		isl_pw_aff_free(mpa->p[i]);
-		mpa->p[i] = pa;
-	}
-
-	return mpa;
-}
-
 /* Compute the pullback of "mpa" by the function represented by "ma".
  * In other words, plug in "ma" in "mpa".
  *
@@ -7693,6 +7668,7 @@ error:
 #include <isl_multi_templ.c>
 #include <isl_multi_apply_set.c>
 #include <isl_multi_apply_union_set.c>
+#include <isl_multi_coalesce.c>
 #include <isl_multi_floor.c>
 #include <isl_multi_gist.c>
 #include <isl_multi_intersect.c>

Modified: polly/trunk/lib/External/isl/isl_affine_hull.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_affine_hull.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_affine_hull.c (original)
+++ polly/trunk/lib/External/isl/isl_affine_hull.c Tue Aug 11 06:31:18 2015
@@ -1160,6 +1160,15 @@ __isl_give isl_basic_map *isl_basic_map_
 	return bmap;
 }
 
+/* Return the superset of "bset" described by the equalities
+ * satisfied by "bset" that are already known.
+ */
+__isl_give isl_basic_set *isl_basic_set_plain_affine_hull(
+	__isl_take isl_basic_set *bset)
+{
+	return isl_basic_map_plain_affine_hull(bset);
+}
+
 /* After computing the rational affine hull (by detecting the implicit
  * equalities), we compute the additional equalities satisfied by
  * the integer points (if any) and add the original equalities back in.

Modified: polly/trunk/lib/External/isl/isl_ast_build.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_ast_build.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_ast_build.c (original)
+++ polly/trunk/lib/External/isl/isl_ast_build.c Tue Aug 11 06:31:18 2015
@@ -982,31 +982,6 @@ __isl_give isl_ast_build *isl_ast_build_
 	return build;
 }
 
-/* Intersect build->pending and build->domain with "set",
- * where "set" is specified in terms of the internal schedule domain.
- */
-__isl_give isl_ast_build *isl_ast_build_restrict_pending(
-	__isl_take isl_ast_build *build, __isl_take isl_set *set)
-{
-	set = isl_set_compute_divs(set);
-	build = isl_ast_build_restrict_internal(build, isl_set_copy(set));
-	build = isl_ast_build_cow(build);
-	if (!build)
-		goto error;
-
-	build->pending = isl_set_intersect(build->pending, set);
-	build->pending = isl_set_coalesce(build->pending);
-
-	if (!build->pending)
-		return isl_ast_build_free(build);
-
-	return build;
-error:
-	isl_ast_build_free(build);
-	isl_set_free(set);
-	return NULL;
-}
-
 /* Intersect build->domain with "set", where "set" is specified
  * in terms of the external schedule domain.
  */

Modified: polly/trunk/lib/External/isl/isl_ast_build_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_ast_build_private.h?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_ast_build_private.h (original)
+++ polly/trunk/lib/External/isl/isl_ast_build_private.h Tue Aug 11 06:31:18 2015
@@ -244,8 +244,6 @@ __isl_give isl_ast_build *isl_ast_build_
 	__isl_take isl_ast_build *build, __isl_take isl_set *set);
 __isl_give isl_ast_build *isl_ast_build_replace_pending_by_guard(
 	__isl_take isl_ast_build *build, __isl_take isl_set *guard);
-__isl_give isl_ast_build *isl_ast_build_restrict_pending(
-	__isl_take isl_ast_build *build, __isl_take isl_set *set);
 __isl_give int isl_ast_build_need_schedule_map(
 	__isl_keep isl_ast_build *build);
 __isl_give isl_multi_aff *isl_ast_build_get_schedule_map_multi_aff(

Modified: polly/trunk/lib/External/isl/isl_flow.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_flow.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_flow.c (original)
+++ polly/trunk/lib/External/isl/isl_flow.c Tue Aug 11 06:31:18 2015
@@ -2079,7 +2079,8 @@ static isl_stat extract_sink_source(__is
 }
 
 /* isl_schedule_foreach_schedule_node_top_down callback for collecting
- * individual scheduled source and sink accesses.
+ * individual scheduled source and sink accesses (taking into account
+ * the domain of the schedule).
  *
  * We only collect accesses at the leaves of the schedule tree.
  * We prepend the schedule dimensions at the leaf to the iteration
@@ -2114,7 +2115,7 @@ static isl_bool collect_sink_source(__is
 
 	data->node = node;
 
-	prefix = isl_schedule_node_get_prefix_schedule_union_map(node);
+	prefix = isl_schedule_node_get_prefix_schedule_relation(node);
 	prefix = isl_union_map_reverse(prefix);
 	prefix = isl_union_map_range_map(prefix);
 
@@ -2282,6 +2283,8 @@ static __isl_give isl_union_flow *comput
  * the possible or definite source accesses that last accessed the
  * element accessed by the sink access before this sink access
  * in the sense that there is no intermediate definite source access.
+ * Only consider dependences between statement instances that belong
+ * to the domain of the schedule.
  *
  * The must_no_source and may_no_source elements of the result
  * are subsets of access->sink.  The elements must_dep and may_dep
@@ -2291,7 +2294,8 @@ static __isl_give isl_union_flow *comput
  * This function is used when a schedule tree representation
  * is available.
  *
- * We extract the individual scheduled source and sink access relations and
+ * We extract the individual scheduled source and sink access relations
+ * (taking into account the domain of the schedule) and
  * then compute dependences for each scheduled sink individually.
  */
 static __isl_give isl_union_flow *compute_flow_schedule(

Modified: polly/trunk/lib/External/isl/isl_map.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_map.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_map.c (original)
+++ polly/trunk/lib/External/isl/isl_map.c Tue Aug 11 06:31:18 2015
@@ -4566,9 +4566,10 @@ struct isl_basic_map *isl_basic_map_over
 	isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
 	isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like),
 			goto error);
-	if (isl_space_is_equal(bset->dim, like->dim) && like->n_div == 0) {
+	if (like->n_div == 0) {
+		isl_space *space = isl_basic_map_get_space(like);
 		isl_basic_map_free(like);
-		return (struct isl_basic_map *)bset;
+		return isl_basic_map_reset_space(bset, space);
 	}
 	bset = isl_basic_set_cow(bset);
 	if (!bset)
@@ -4694,21 +4695,32 @@ struct isl_set *isl_set_to_underlying_se
 }
 
 __isl_give isl_basic_map *isl_basic_map_reset_space(
-	__isl_take isl_basic_map *bmap, __isl_take isl_space *dim)
+	__isl_take isl_basic_map *bmap, __isl_take isl_space *space)
 {
+	isl_bool equal;
+
+	if (!bmap)
+		goto error;
+	equal = isl_space_is_equal(bmap->dim, space);
+	if (equal < 0)
+		goto error;
+	if (equal) {
+		isl_space_free(space);
+		return bmap;
+	}
 	bmap = isl_basic_map_cow(bmap);
-	if (!bmap || !dim)
+	if (!bmap || !space)
 		goto error;
 
 	isl_space_free(bmap->dim);
-	bmap->dim = dim;
+	bmap->dim = space;
 
 	bmap = isl_basic_map_finalize(bmap);
 
 	return bmap;
 error:
 	isl_basic_map_free(bmap);
-	isl_space_free(dim);
+	isl_space_free(space);
 	return NULL;
 }
 

Modified: polly/trunk/lib/External/isl/isl_map_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_map_private.h?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_map_private.h (original)
+++ polly/trunk/lib/External/isl/isl_map_private.h Tue Aug 11 06:31:18 2015
@@ -436,6 +436,8 @@ int isl_map_is_set(__isl_keep isl_map *m
 int isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
 	unsigned dim, isl_int *val);
 
+__isl_give isl_basic_set *isl_basic_set_plain_affine_hull(
+	__isl_take isl_basic_set *bset);
 __isl_give isl_basic_map *isl_basic_map_plain_affine_hull(
 	__isl_take isl_basic_map *bmap);
 

Modified: polly/trunk/lib/External/isl/isl_map_simplify.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_map_simplify.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_map_simplify.c (original)
+++ polly/trunk/lib/External/isl/isl_map_simplify.c Tue Aug 11 06:31:18 2015
@@ -1,7 +1,7 @@
 /*
  * Copyright 2008-2009 Katholieke Universiteit Leuven
  * Copyright 2012-2013 Ecole Normale Superieure
- * Copyright 2014      INRIA Rocquencourt
+ * Copyright 2014-2015 INRIA Rocquencourt
  *
  * Use of this software is governed by the MIT license
  *
@@ -760,23 +760,127 @@ static unsigned int round_up(unsigned in
 	return old_v << 1;
 }
 
-static int hash_index(isl_int ***index, unsigned int size, int bits,
-			struct isl_basic_map *bmap, int k)
+/* Hash table of inequalities in a basic map.
+ * "index" is an array of addresses of inequalities in the basic map, some
+ * of which are NULL.  The inequalities are hashed on the coefficients
+ * except the constant term.
+ * "size" is the number of elements in the array and is always a power of two
+ * "bits" is the number of bits need to represent an index into the array.
+ * "total" is the total dimension of the basic map.
+ */
+struct isl_constraint_index {
+	unsigned int size;
+	int bits;
+	isl_int ***index;
+	unsigned total;
+};
+
+/* Fill in the "ci" data structure for holding the inequalities of "bmap".
+ */
+static isl_stat create_constraint_index(struct isl_constraint_index *ci,
+	__isl_keep isl_basic_map *bmap)
+{
+	isl_ctx *ctx;
+
+	ci->index = NULL;
+	if (!bmap)
+		return isl_stat_error;
+	ci->total = isl_basic_set_total_dim(bmap);
+	if (bmap->n_ineq == 0)
+		return isl_stat_ok;
+	ci->size = round_up(4 * (bmap->n_ineq + 1) / 3 - 1);
+	ci->bits = ffs(ci->size) - 1;
+	ctx = isl_basic_map_get_ctx(bmap);
+	ci->index = isl_calloc_array(ctx, isl_int **, ci->size);
+	if (!ci->index)
+		return isl_stat_error;
+
+	return isl_stat_ok;
+}
+
+/* Free the memory allocated by create_constraint_index.
+ */
+static void constraint_index_free(struct isl_constraint_index *ci)
+{
+	free(ci->index);
+}
+
+/* Return the position in ci->index that contains the address of
+ * an inequality that is equal to *ineq up to the constant term,
+ * provided this address is not identical to "ineq".
+ * If there is no such inequality, then return the position where
+ * such an inequality should be inserted.
+ */
+static int hash_index_ineq(struct isl_constraint_index *ci, isl_int **ineq)
 {
 	int h;
-	unsigned total = isl_basic_map_total_dim(bmap);
-	uint32_t hash = isl_seq_get_hash_bits(bmap->ineq[k]+1, total, bits);
-	for (h = hash; index[h]; h = (h+1) % size)
-		if (&bmap->ineq[k] != index[h] &&
-		    isl_seq_eq(bmap->ineq[k]+1, index[h][0]+1, total))
+	uint32_t hash = isl_seq_get_hash_bits((*ineq) + 1, ci->total, ci->bits);
+	for (h = hash; ci->index[h]; h = (h+1) % ci->size)
+		if (ineq != ci->index[h] &&
+		    isl_seq_eq((*ineq) + 1, ci->index[h][0]+1, ci->total))
 			break;
 	return h;
 }
 
-static int set_hash_index(isl_int ***index, unsigned int size, int bits,
+/* Return the position in ci->index that contains the address of
+ * an inequality that is equal to the k'th inequality of "bmap"
+ * up to the constant term, provided it does not point to the very
+ * same inequality.
+ * If there is no such inequality, then return the position where
+ * such an inequality should be inserted.
+ */
+static int hash_index(struct isl_constraint_index *ci,
+	__isl_keep isl_basic_map *bmap, int k)
+{
+	return hash_index_ineq(ci, &bmap->ineq[k]);
+}
+
+static int set_hash_index(struct isl_constraint_index *ci,
 			  struct isl_basic_set *bset, int k)
 {
-	return hash_index(index, size, bits, (struct isl_basic_map *)bset, k);
+	return hash_index(ci, bset, k);
+}
+
+/* Fill in the "ci" data structure with the inequalities of "bset".
+ */
+static isl_stat setup_constraint_index(struct isl_constraint_index *ci,
+	__isl_keep isl_basic_set *bset)
+{
+	int k, h;
+
+	if (create_constraint_index(ci, bset) < 0)
+		return isl_stat_error;
+
+	for (k = 0; k < bset->n_ineq; ++k) {
+		h = set_hash_index(ci, bset, k);
+		ci->index[h] = &bset->ineq[k];
+	}
+
+	return isl_stat_ok;
+}
+
+/* Is the inequality ineq (obviously) redundant with respect
+ * to the constraints in "ci"?
+ *
+ * Look for an inequality in "ci" with the same coefficients and then
+ * check if the contant term of "ineq" is greater than or equal
+ * to the constant term of that inequality.  If so, "ineq" is clearly
+ * redundant.
+ *
+ * Note that hash_index_ineq ignores a stored constraint if it has
+ * the same address as the passed inequality.  It is ok to pass
+ * the address of a local variable here since it will never be
+ * the same as the address of a constraint in "ci".
+ */
+static isl_bool constraint_index_is_redundant(struct isl_constraint_index *ci,
+	isl_int *ineq)
+{
+	int h;
+
+	h = hash_index_ineq(ci, &ineq);
+	if (!ci->index[h])
+		return isl_bool_false;
+	return isl_int_ge(ineq[0], (*ci->index[h])[0]);
 }
 
 /* If we can eliminate more than one div, then we need to make
@@ -1196,36 +1300,28 @@ static struct isl_basic_map *check_for_d
 __isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints(
 	__isl_take isl_basic_map *bmap, int *progress, int detect_divs)
 {
-	unsigned int size;
-	isl_int ***index;
+	struct isl_constraint_index ci;
 	int k, l, h;
-	int bits;
 	unsigned total = isl_basic_map_total_dim(bmap);
 	isl_int sum;
-	isl_ctx *ctx;
 
 	if (!bmap || bmap->n_ineq <= 1)
 		return bmap;
 
-	size = round_up(4 * (bmap->n_ineq+1) / 3 - 1);
-	if (size == 0)
-		return bmap;
-	bits = ffs(size) - 1;
-	ctx = isl_basic_map_get_ctx(bmap);
-	index = isl_calloc_array(ctx, isl_int **, size);
-	if (!index)
+	if (create_constraint_index(&ci, bmap) < 0)
 		return bmap;
 
-	index[isl_seq_get_hash_bits(bmap->ineq[0]+1, total, bits)] = &bmap->ineq[0];
+	h = isl_seq_get_hash_bits(bmap->ineq[0] + 1, total, ci.bits);
+	ci.index[h] = &bmap->ineq[0];
 	for (k = 1; k < bmap->n_ineq; ++k) {
-		h = hash_index(index, size, bits, bmap, k);
-		if (!index[h]) {
-			index[h] = &bmap->ineq[k];
+		h = hash_index(&ci, bmap, k);
+		if (!ci.index[h]) {
+			ci.index[h] = &bmap->ineq[k];
 			continue;
 		}
 		if (progress)
 			*progress = 1;
-		l = index[h] - &bmap->ineq[0];
+		l = ci.index[h] - &bmap->ineq[0];
 		if (isl_int_lt(bmap->ineq[k][0], bmap->ineq[l][0]))
 			swap_inequality(bmap, k, l);
 		isl_basic_map_drop_inequality(bmap, k);
@@ -1234,11 +1330,11 @@ __isl_give isl_basic_map *isl_basic_map_
 	isl_int_init(sum);
 	for (k = 0; k < bmap->n_ineq-1; ++k) {
 		isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
-		h = hash_index(index, size, bits, bmap, k);
+		h = hash_index(&ci, bmap, k);
 		isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
-		if (!index[h])
+		if (!ci.index[h])
 			continue;
-		l = index[h] - &bmap->ineq[0];
+		l = ci.index[h] - &bmap->ineq[0];
 		isl_int_add(sum, bmap->ineq[k][0], bmap->ineq[l][0]);
 		if (isl_int_is_pos(sum)) {
 			if (detect_divs)
@@ -1262,7 +1358,7 @@ __isl_give isl_basic_map *isl_basic_map_
 	}
 	isl_int_clear(sum);
 
-	free(index);
+	constraint_index_free(&ci);
 	return bmap;
 }
 
@@ -1828,37 +1924,73 @@ error:
 	return NULL;
 }
 
+/* For each inequality in "ineq" that is a shifted (more relaxed)
+ * copy of an inequality in "context", mark the corresponding entry
+ * in "row" with -1.
+ * If an inequality only has a non-negative constant term, then
+ * mark it as well.
+ */
+static isl_stat mark_shifted_constraints(__isl_keep isl_mat *ineq,
+	__isl_keep isl_basic_set *context, int *row)
+{
+	struct isl_constraint_index ci;
+	int n_ineq;
+	unsigned total;
+	int k;
+
+	if (!ineq || !context)
+		return isl_stat_error;
+	if (context->n_ineq == 0)
+		return isl_stat_ok;
+	if (setup_constraint_index(&ci, context) < 0)
+		return isl_stat_error;
+
+	n_ineq = isl_mat_rows(ineq);
+	total = isl_mat_cols(ineq) - 1;
+	for (k = 0; k < n_ineq; ++k) {
+		int l;
+		isl_bool redundant;
+
+		l = isl_seq_first_non_zero(ineq->row[k] + 1, total);
+		if (l < 0 && isl_int_is_nonneg(ineq->row[k][0])) {
+			row[k] = -1;
+			continue;
+		}
+		redundant = constraint_index_is_redundant(&ci, ineq->row[k]);
+		if (redundant < 0)
+			goto error;
+		if (!redundant)
+			continue;
+		row[k] = -1;
+	}
+	constraint_index_free(&ci);
+	return isl_stat_ok;
+error:
+	constraint_index_free(&ci);
+	return isl_stat_error;
+}
+
 static struct isl_basic_set *remove_shifted_constraints(
 	struct isl_basic_set *bset, struct isl_basic_set *context)
 {
-	unsigned int size;
-	isl_int ***index;
-	int bits;
-	int k, h, l;
-	isl_ctx *ctx;
+	struct isl_constraint_index ci;
+	int k;
 
 	if (!bset || !context)
 		return bset;
 
-	size = round_up(4 * (context->n_ineq+1) / 3 - 1);
-	if (size == 0)
+	if (context->n_ineq == 0)
 		return bset;
-	bits = ffs(size) - 1;
-	ctx = isl_basic_set_get_ctx(bset);
-	index = isl_calloc_array(ctx, isl_int **, size);
-	if (!index)
+	if (setup_constraint_index(&ci, context) < 0)
 		return bset;
 
-	for (k = 0; k < context->n_ineq; ++k) {
-		h = set_hash_index(index, size, bits, context, k);
-		index[h] = &context->ineq[k];
-	}
 	for (k = 0; k < bset->n_ineq; ++k) {
-		h = set_hash_index(index, size, bits, bset, k);
-		if (!index[h])
-			continue;
-		l = index[h] - &context->ineq[0];
-		if (isl_int_lt(bset->ineq[k][0], context->ineq[l][0]))
+		isl_bool redundant;
+
+		redundant = constraint_index_is_redundant(&ci, bset->ineq[k]);
+		if (redundant < 0)
+			goto error;
+		if (!redundant)
 			continue;
 		bset = isl_basic_set_cow(bset);
 		if (!bset)
@@ -1866,10 +1998,10 @@ static struct isl_basic_set *remove_shif
 		isl_basic_set_drop_inequality(bset, k);
 		--k;
 	}
-	free(index);
+	constraint_index_free(&ci);
 	return bset;
 error:
-	free(index);
+	constraint_index_free(&ci);
 	return bset;
 }
 
@@ -1985,23 +2117,31 @@ static void update_groups(int dim, int *
 	}
 }
 
-/* Drop constraints from "context" that are irrelevant for computing
- * the gist of "bset".
- *
- * In particular, drop constraints in variables that are not related
- * to any of the variables involved in the constraints of "bset"
- * in the sense that there is no sequence of constraints that connects them.
+/* Allocate an array of groups of variables, one for each variable
+ * in "context", initialized to zero.
+ */
+static int *alloc_groups(__isl_keep isl_basic_set *context)
+{
+	isl_ctx *ctx;
+	int dim;
+
+	dim = isl_basic_set_dim(context, isl_dim_set);
+	ctx = isl_basic_set_get_ctx(context);
+	return isl_calloc_array(ctx, int, dim);
+}
+
+/* Drop constraints from "context" that only involve variables that are
+ * not related to any of the variables marked with a "-1" in "group".
  *
  * We construct groups of variables that collect variables that
  * (indirectly) appear in some common constraint of "context".
  * Each group is identified by the first variable in the group,
- * except for the special group of variables that appear in "bset"
- * (or are related to those variables), which is identified by -1.
+ * except for the special group of variables that was already identified
+ * in the input as -1 (or are related to those variables).
  * If group[i] is equal to i (or -1), then the group of i is i (or -1),
  * otherwise the group of i is the group of group[i].
  *
- * We first initialize the -1 group with the variables that appear in "bset".
- * Then we initialize groups for the remaining variables.
+ * We first initialize groups for the remaining variables.
  * Then we iterate over the constraints of "context" and update the
  * group of the variables in the constraint by the smallest group.
  * Finally, we resolve indirect references to groups by running over
@@ -2010,25 +2150,68 @@ static void update_groups(int dim, int *
  * After computing the groups, we drop constraints that do not involve
  * any variables in the -1 group.
  */
+static __isl_give isl_basic_set *group_and_drop_irrelevant_constraints(
+	__isl_take isl_basic_set *context, __isl_take int *group)
+{
+	int dim;
+	int i;
+	int last;
+
+	dim = isl_basic_set_dim(context, isl_dim_set);
+
+	last = -1;
+	for (i = 0; i < dim; ++i)
+		if (group[i] >= 0)
+			last = group[i] = i;
+	if (last < 0) {
+		free(group);
+		return context;
+	}
+
+	for (i = 0; i < context->n_eq; ++i)
+		update_groups(dim, group, context->eq[i] + 1);
+	for (i = 0; i < context->n_ineq; ++i)
+		update_groups(dim, group, context->ineq[i] + 1);
+
+	for (i = 0; i < dim; ++i)
+		if (group[i] >= 0)
+			group[i] = group[group[i]];
+
+	for (i = 0; i < dim; ++i)
+		group[i] = group[i] == -1;
+
+	context = drop_unrelated_constraints(context, group);
+
+	free(group);
+	return context;
+}
+
+/* Drop constraints from "context" that are irrelevant for computing
+ * the gist of "bset".
+ *
+ * In particular, drop constraints in variables that are not related
+ * to any of the variables involved in the constraints of "bset"
+ * in the sense that there is no sequence of constraints that connects them.
+ *
+ * We first mark all variables that appear in "bset" as belonging
+ * to a "-1" group and then continue with group_and_drop_irrelevant_constraints.
+ */
 static __isl_give isl_basic_set *drop_irrelevant_constraints(
 	__isl_take isl_basic_set *context, __isl_keep isl_basic_set *bset)
 {
-	isl_ctx *ctx;
 	int *group;
 	int dim;
 	int i, j;
-	int last;
 
 	if (!context || !bset)
 		return isl_basic_set_free(context);
 
-	dim = isl_basic_set_dim(bset, isl_dim_set);
-	ctx = isl_basic_set_get_ctx(bset);
-	group = isl_calloc_array(ctx, int, dim);
+	group = alloc_groups(context);
 
 	if (!group)
-		goto error;
+		return isl_basic_set_free(context);
 
+	dim = isl_basic_set_dim(bset, isl_dim_set);
 	for (i = 0; i < dim; ++i) {
 		for (j = 0; j < bset->n_eq; ++j)
 			if (!isl_int_is_zero(bset->eq[j][1 + i]))
@@ -2044,40 +2227,147 @@ static __isl_give isl_basic_set *drop_ir
 			group[i] = -1;
 	}
 
-	last = -1;
-	for (i = 0; i < dim; ++i)
-		if (group[i] >= 0)
-			last = group[i] = i;
-	if (last < 0) {
-		free(group);
-		return context;
+	return group_and_drop_irrelevant_constraints(context, group);
+}
+
+/* Drop constraints from "context" that are irrelevant for computing
+ * the gist of the inequalities "ineq".
+ * Inequalities in "ineq" for which the corresponding element of row
+ * is set to -1 have already been marked for removal and should be ignored.
+ *
+ * In particular, drop constraints in variables that are not related
+ * to any of the variables involved in "ineq"
+ * in the sense that there is no sequence of constraints that connects them.
+ *
+ * We first mark all variables that appear in "bset" as belonging
+ * to a "-1" group and then continue with group_and_drop_irrelevant_constraints.
+ */
+static __isl_give isl_basic_set *drop_irrelevant_constraints_marked(
+	__isl_take isl_basic_set *context, __isl_keep isl_mat *ineq, int *row)
+{
+	int *group;
+	int dim;
+	int i, j, n;
+
+	if (!context || !ineq)
+		return isl_basic_set_free(context);
+
+	group = alloc_groups(context);
+
+	if (!group)
+		return isl_basic_set_free(context);
+
+	dim = isl_basic_set_dim(context, isl_dim_set);
+	n = isl_mat_rows(ineq);
+	for (i = 0; i < dim; ++i) {
+		for (j = 0; j < n; ++j) {
+			if (row[j] < 0)
+				continue;
+			if (!isl_int_is_zero(ineq->row[j][1 + i]))
+				break;
+		}
+		if (j < n)
+			group[i] = -1;
 	}
 
-	for (i = 0; i < context->n_eq; ++i)
-		update_groups(dim, group, context->eq[i] + 1);
-	for (i = 0; i < context->n_ineq; ++i)
-		update_groups(dim, group, context->ineq[i] + 1);
+	return group_and_drop_irrelevant_constraints(context, group);
+}
 
-	for (i = 0; i < dim; ++i)
-		if (group[i] >= 0)
-			group[i] = group[group[i]];
+/* Do all "n" entries of "row" contain a negative value?
+ */
+static int all_neg(int *row, int n)
+{
+	int i;
 
-	for (i = 0; i < dim; ++i)
-		group[i] = group[i] == -1;
+	for (i = 0; i < n; ++i)
+		if (row[i] >= 0)
+			return 0;
 
-	context = drop_unrelated_constraints(context, group);
+	return 1;
+}
 
-	free(group);
-	return context;
-error:
-	free(group);
-	return isl_basic_set_free(context);
+/* Update the inequalities in "bset" based on the information in "row"
+ * and "tab".
+ *
+ * In particular, the array "row" contains either -1, meaning that
+ * the corresponding inequality of "bset" is redundant, or the index
+ * of an inequality in "tab".
+ *
+ * If the row entry is -1, then drop the inequality.
+ * Otherwise, if the constraint is marked redundant in the tableau,
+ * then drop the inequality.  Similarly, if it is marked as an equality
+ * in the tableau, then turn the inequality into an equality and
+ * perform Gaussian elimination.
+ */
+static __isl_give isl_basic_set *update_ineq(__isl_take isl_basic_set *bset,
+	__isl_keep int *row, struct isl_tab *tab)
+{
+	int i;
+	unsigned n_ineq;
+	unsigned n_eq;
+	int found_equality = 0;
+
+	if (!bset)
+		return NULL;
+	if (tab && tab->empty)
+		return isl_basic_set_set_to_empty(bset);
+
+	n_ineq = bset->n_ineq;
+	for (i = n_ineq - 1; i >= 0; --i) {
+		if (row[i] < 0) {
+			if (isl_basic_set_drop_inequality(bset, i) < 0)
+				return isl_basic_set_free(bset);
+			continue;
+		}
+		if (!tab)
+			continue;
+		n_eq = tab->n_eq;
+		if (isl_tab_is_equality(tab, n_eq + row[i])) {
+			isl_basic_map_inequality_to_equality(bset, i);
+			found_equality = 1;
+		} else if (isl_tab_is_redundant(tab, n_eq + row[i])) {
+			if (isl_basic_set_drop_inequality(bset, i) < 0)
+				return isl_basic_set_free(bset);
+		}
+	}
+
+	if (found_equality)
+		bset = isl_basic_set_gauss(bset, NULL);
+	bset = isl_basic_set_finalize(bset);
+	return bset;
+}
+
+/* Update the inequalities in "bset" based on the information in "row"
+ * and "tab" and free all arguments (other than "bset").
+ */
+static __isl_give isl_basic_set *update_ineq_free(
+	__isl_take isl_basic_set *bset, __isl_take isl_mat *ineq,
+	__isl_take isl_basic_set *context, __isl_take int *row,
+	struct isl_tab *tab)
+{
+	isl_mat_free(ineq);
+	isl_basic_set_free(context);
+
+	bset = update_ineq(bset, row, tab);
+
+	free(row);
+	isl_tab_free(tab);
+	return bset;
 }
 
 /* Remove all information from bset that is redundant in the context
- * of context.  Both bset and context are assumed to be full-dimensional.
+ * of context.
+ * "ineq" contains the (possibly transformed) inequalities of "bset",
+ * in the same order.
+ * The (explicit) equalities of "bset" are assumed to have been taken
+ * into account by the transformation such that only the inequalities
+ * are relevant.
+ *
+ * "row" keeps track of the constraint index of a "bset" inequality in "tab".
+ * A value of -1 means that the inequality is obviously redundant and may
+ * not even appear in  "tab".
  *
- * We first remove the inequalities from "bset"
+ * We first mark the inequalities of "bset"
  * that are obviously redundant with respect to some inequality in "context".
  * Then we remove those constraints from "context" that have become
  * irrelevant for computing the gist of "bset".
@@ -2097,96 +2387,96 @@ error:
  * Finally, we update bset according to the results.
  */
 static __isl_give isl_basic_set *uset_gist_full(__isl_take isl_basic_set *bset,
-	__isl_take isl_basic_set *context)
+	__isl_take isl_mat *ineq, __isl_take isl_basic_set *context)
 {
-	int i, k;
+	int i, r;
+	int *row = NULL;
+	isl_ctx *ctx;
 	isl_basic_set *combined = NULL;
 	struct isl_tab *tab = NULL;
-	unsigned context_ineq;
+	unsigned n_eq, context_ineq;
 	unsigned total;
 
-	if (!bset || !context)
+	if (!bset || !ineq || !context)
 		goto error;
 
-	if (isl_basic_set_is_universe(bset)) {
+	if (bset->n_ineq == 0 || isl_basic_set_is_universe(context)) {
 		isl_basic_set_free(context);
+		isl_mat_free(ineq);
 		return bset;
 	}
 
-	if (isl_basic_set_is_universe(context)) {
-		isl_basic_set_free(context);
-		return bset;
-	}
+	ctx = isl_basic_set_get_ctx(context);
+	row = isl_calloc_array(ctx, int, bset->n_ineq);
+	if (!row)
+		goto error;
 
-	bset = remove_shifted_constraints(bset, context);
-	if (!bset)
+	if (mark_shifted_constraints(ineq, context, row) < 0)
 		goto error;
-	if (bset->n_ineq == 0)
-		goto done;
+	if (all_neg(row, bset->n_ineq))
+		return update_ineq_free(bset, ineq, context, row, NULL);
 
-	context = drop_irrelevant_constraints(context, bset);
+	context = drop_irrelevant_constraints_marked(context, ineq, row);
 	if (!context)
 		goto error;
-	if (isl_basic_set_is_universe(context)) {
-		isl_basic_set_free(context);
-		return bset;
-	}
+	if (isl_basic_set_is_universe(context))
+		return update_ineq_free(bset, ineq, context, row, NULL);
 
+	n_eq = context->n_eq;
 	context_ineq = context->n_ineq;
 	combined = isl_basic_set_cow(isl_basic_set_copy(context));
 	combined = isl_basic_set_extend_constraints(combined, 0, bset->n_ineq);
 	tab = isl_tab_from_basic_set(combined, 0);
 	for (i = 0; i < context_ineq; ++i)
-		if (isl_tab_freeze_constraint(tab, i) < 0)
+		if (isl_tab_freeze_constraint(tab, n_eq + i) < 0)
 			goto error;
 	if (isl_tab_extend_cons(tab, bset->n_ineq) < 0)
 		goto error;
-	for (i = 0; i < bset->n_ineq; ++i)
-		if (isl_tab_add_ineq(tab, bset->ineq[i]) < 0)
+	r = context_ineq;
+	for (i = 0; i < bset->n_ineq; ++i) {
+		if (row[i] < 0)
+			continue;
+		combined = isl_basic_set_add_ineq(combined, ineq->row[i]);
+		if (isl_tab_add_ineq(tab, ineq->row[i]) < 0)
 			goto error;
-	bset = isl_basic_set_add_constraints(combined, bset, 0);
-	combined = NULL;
-	if (!bset)
+		row[i] = r++;
+	}
+	if (isl_tab_detect_implicit_equalities(tab) < 0)
 		goto error;
 	if (isl_tab_detect_redundant(tab) < 0)
 		goto error;
 	total = isl_basic_set_total_dim(bset);
-	for (i = context_ineq; i < bset->n_ineq; ++i) {
+	for (i = bset->n_ineq - 1; i >= 0; --i) {
+		isl_basic_set *test;
 		int is_empty;
-		if (tab->con[i].is_redundant)
+
+		if (row[i] < 0)
 			continue;
-		tab->con[i].is_redundant = 1;
-		combined = isl_basic_set_dup(bset);
-		combined = isl_basic_set_update_from_tab(combined, tab);
-		combined = isl_basic_set_extend_constraints(combined, 0, 1);
-		k = isl_basic_set_alloc_inequality(combined);
-		if (k < 0)
-			goto error;
-		isl_seq_neg(combined->ineq[k], bset->ineq[i], 1 + total);
-		isl_int_sub_ui(combined->ineq[k][0], combined->ineq[k][0], 1);
-		is_empty = isl_basic_set_is_empty(combined);
+		r = row[i];
+		if (tab->con[n_eq + r].is_redundant)
+			continue;
+		test = isl_basic_set_dup(combined);
+		if (isl_inequality_negate(test, r) < 0)
+			test = isl_basic_set_free(test);
+		test = isl_basic_set_update_from_tab(test, tab);
+		is_empty = isl_basic_set_is_empty(test);
+		isl_basic_set_free(test);
 		if (is_empty < 0)
 			goto error;
-		isl_basic_set_free(combined);
-		combined = NULL;
-		if (!is_empty)
-			tab->con[i].is_redundant = 0;
+		if (is_empty)
+			tab->con[n_eq + r].is_redundant = 1;
 	}
-	for (i = 0; i < context_ineq; ++i)
-		tab->con[i].is_redundant = 1;
-	bset = isl_basic_set_update_from_tab(bset, tab);
+	bset = update_ineq_free(bset, ineq, context, row, tab);
 	if (bset) {
 		ISL_F_SET(bset, ISL_BASIC_SET_NO_IMPLICIT);
 		ISL_F_SET(bset, ISL_BASIC_SET_NO_REDUNDANT);
 	}
 
-	isl_tab_free(tab);
-done:
-	bset = isl_basic_set_simplify(bset);
-	bset = isl_basic_set_finalize(bset);
-	isl_basic_set_free(context);
+	isl_basic_set_free(combined);
 	return bset;
 error:
+	free(row);
+	isl_mat_free(ineq);
 	isl_tab_free(tab);
 	isl_basic_set_free(combined);
 	isl_basic_set_free(context);
@@ -2194,6 +2484,141 @@ error:
 	return NULL;
 }
 
+/* Extract the inequalities of "bset" as an isl_mat.
+ */
+static __isl_give isl_mat *extract_ineq(__isl_keep isl_basic_set *bset)
+{
+	unsigned total;
+	isl_ctx *ctx;
+	isl_mat *ineq;
+
+	if (!bset)
+		return NULL;
+
+	ctx = isl_basic_set_get_ctx(bset);
+	total = isl_basic_set_total_dim(bset);
+	ineq = isl_mat_sub_alloc6(ctx, bset->ineq, 0, bset->n_ineq,
+				    0, 1 + total);
+
+	return ineq;
+}
+
+/* Remove all information from "bset" that is redundant in the context
+ * of "context", for the case where both "bset" and "context" are
+ * full-dimensional.
+ */
+static __isl_give isl_basic_set *uset_gist_uncompressed(
+	__isl_take isl_basic_set *bset, __isl_take isl_basic_set *context)
+{
+	isl_mat *ineq;
+
+	ineq = extract_ineq(bset);
+	return uset_gist_full(bset, ineq, context);
+}
+
+/* Remove all information from "bset" that is redundant in the context
+ * of "context", for the case where the combined equalities of
+ * "bset" and "context" allow for a compression that can be obtained
+ * by preapplication of "T".
+ *
+ * "bset" itself is not transformed by "T".  Instead, the inequalities
+ * are extracted from "bset" and those are transformed by "T".
+ * uset_gist_full then determines which of the transformed inequalities
+ * are redundant with respect to the transformed "context" and removes
+ * the corresponding inequalities from "bset".
+ *
+ * After preapplying "T" to the inequalities, any common factor is
+ * removed from the coefficients.  If this results in a tightening
+ * of the constant term, then the same tightening is applied to
+ * the corresponding untransformed inequality in "bset".
+ * That is, if after plugging in T, a constraint f(x) >= 0 is of the form
+ *
+ *	g f'(x) + r >= 0
+ *
+ * with 0 <= r < g, then it is equivalent to
+ *
+ *	f'(x) >= 0
+ *
+ * This means that f(x) >= 0 is equivalent to f(x) - r >= 0 in the affine
+ * subspace compressed by T since the latter would be transformed to
+ *
+ *	g f'(x) >= 0
+ */
+static __isl_give isl_basic_set *uset_gist_compressed(
+	__isl_take isl_basic_set *bset, __isl_take isl_basic_set *context,
+	__isl_take isl_mat *T)
+{
+	isl_ctx *ctx;
+	isl_mat *ineq;
+	int i, n_row, n_col;
+	isl_int rem;
+
+	ineq = extract_ineq(bset);
+	ineq = isl_mat_product(ineq, isl_mat_copy(T));
+	context = isl_basic_set_preimage(context, T);
+
+	if (!ineq)
+		goto error;
+
+	ctx = isl_mat_get_ctx(ineq);
+	n_row = isl_mat_rows(ineq);
+	n_col = isl_mat_cols(ineq);
+	isl_int_init(rem);
+	for (i = 0; i < n_row; ++i) {
+		isl_seq_gcd(ineq->row[i] + 1, n_col - 1, &ctx->normalize_gcd);
+		if (isl_int_is_zero(ctx->normalize_gcd))
+			continue;
+		if (isl_int_is_one(ctx->normalize_gcd))
+			continue;
+		isl_seq_scale_down(ineq->row[i] + 1, ineq->row[i] + 1,
+				    ctx->normalize_gcd, n_col - 1);
+		isl_int_fdiv_r(rem, ineq->row[i][0], ctx->normalize_gcd);
+		isl_int_fdiv_q(ineq->row[i][0],
+				ineq->row[i][0], ctx->normalize_gcd);
+		if (isl_int_is_zero(rem))
+			continue;
+		bset = isl_basic_set_cow(bset);
+		if (!bset)
+			break;
+		isl_int_sub(bset->ineq[i][0], bset->ineq[i][0], rem);
+	}
+	isl_int_clear(rem);
+
+	return uset_gist_full(bset, ineq, context);
+error:
+	isl_mat_free(ineq);
+	isl_basic_set_free(context);
+	isl_basic_set_free(bset);
+	return NULL;
+}
+
+/* Project "bset" onto the variables that are involved in "template".
+ */
+static __isl_give isl_basic_set *project_onto_involved(
+	__isl_take isl_basic_set *bset, __isl_keep isl_basic_set *template)
+{
+	int i, n;
+
+	if (!bset || !template)
+		return isl_basic_set_free(bset);
+
+	n = isl_basic_set_dim(template, isl_dim_set);
+
+	for (i = 0; i < n; ++i) {
+		isl_bool involved;
+
+		involved = isl_basic_set_involves_dims(template,
+							isl_dim_set, i, 1);
+		if (involved < 0)
+			return isl_basic_set_free(bset);
+		if (involved)
+			continue;
+		bset = isl_basic_set_eliminate_vars(bset, i, 1);
+	}
+
+	return bset;
+}
+
 /* Remove all information from bset that is redundant in the context
  * of context.  In particular, equalities that are linear combinations
  * of those in context are removed.  Then the inequalities that are
@@ -2204,9 +2629,11 @@ error:
  * that are irrelevant for computing the gist of "bset".
  * Alternatively, we could factorize the intersection of "context" and "bset".
  *
- * We first compute the integer affine hull of the intersection,
- * compute the gist inside this affine hull and then add back
- * those equalities that are not implied by the context.
+ * We first compute the intersection of the integer affine hulls
+ * of "bset" and "context",
+ * compute the gist inside this intersection and then reduce
+ * the constraints with respect to the equalities of the context
+ * that only involve variables already involved in the input.
  *
  * If two constraints are mutually redundant, then uset_gist_full
  * will remove the second of those constraints.  We therefore first
@@ -2219,7 +2646,7 @@ static __isl_give isl_basic_set *uset_gi
 	__isl_take isl_basic_set *context)
 {
 	isl_mat *eq;
-	isl_mat *T, *T2;
+	isl_mat *T;
 	isl_basic_set *aff;
 	isl_basic_set *aff_context;
 	unsigned total;
@@ -2229,9 +2656,13 @@ static __isl_give isl_basic_set *uset_gi
 
 	context = drop_irrelevant_constraints(context, bset);
 
+	bset = isl_basic_set_detect_equalities(bset);
 	aff = isl_basic_set_copy(bset);
-	aff = isl_basic_set_intersect(aff, isl_basic_set_copy(context));
-	aff = isl_basic_set_affine_hull(aff);
+	aff = isl_basic_set_plain_affine_hull(aff);
+	context = isl_basic_set_detect_equalities(context);
+	aff_context = isl_basic_set_copy(context);
+	aff_context = isl_basic_set_plain_affine_hull(aff_context);
+	aff = isl_basic_set_intersect(aff, aff_context);
 	if (!aff)
 		goto error;
 	if (isl_basic_set_plain_is_empty(aff)) {
@@ -2242,28 +2673,23 @@ static __isl_give isl_basic_set *uset_gi
 	bset = isl_basic_set_sort_constraints(bset);
 	if (aff->n_eq == 0) {
 		isl_basic_set_free(aff);
-		return uset_gist_full(bset, context);
+		return uset_gist_uncompressed(bset, context);
 	}
 	total = isl_basic_set_total_dim(bset);
 	eq = isl_mat_sub_alloc6(bset->ctx, aff->eq, 0, aff->n_eq, 0, 1 + total);
 	eq = isl_mat_cow(eq);
-	T = isl_mat_variable_compression(eq, &T2);
+	T = isl_mat_variable_compression(eq, NULL);
+	isl_basic_set_free(aff);
 	if (T && T->n_col == 0) {
 		isl_mat_free(T);
-		isl_mat_free(T2);
 		isl_basic_set_free(context);
-		isl_basic_set_free(aff);
 		return isl_basic_set_set_to_empty(bset);
 	}
 
 	aff_context = isl_basic_set_affine_hull(isl_basic_set_copy(context));
+	aff_context = project_onto_involved(aff_context, bset);
 
-	bset = isl_basic_set_preimage(bset, isl_mat_copy(T));
-	context = isl_basic_set_preimage(context, T);
-
-	bset = uset_gist_full(bset, context);
-	bset = isl_basic_set_preimage(bset, T2);
-	bset = isl_basic_set_intersect(bset, aff);
+	bset = uset_gist_compressed(bset, context, T);
 	bset = isl_basic_set_reduce_using_equalities(bset, aff_context);
 
 	if (bset) {
@@ -2278,46 +2704,6 @@ error:
 	return NULL;
 }
 
-/* Normalize the divs in "bmap" in the context of the equalities in "context".
- * We simply add the equalities in context to bmap and then do a regular
- * div normalizations.  Better results can be obtained by normalizing
- * only the divs in bmap than do not also appear in context.
- * We need to be careful to reduce the divs using the equalities
- * so that later calls to isl_basic_map_overlying_set wouldn't introduce
- * spurious constraints.
- */
-static struct isl_basic_map *normalize_divs_in_context(
-	struct isl_basic_map *bmap, struct isl_basic_map *context)
-{
-	int i;
-	unsigned total_context;
-	int div_eq;
-
-	div_eq = n_pure_div_eq(bmap);
-	if (div_eq == 0)
-		return bmap;
-
-	bmap = isl_basic_map_cow(bmap);
-	if (context->n_div > 0)
-		bmap = isl_basic_map_align_divs(bmap, context);
-
-	total_context = isl_basic_map_total_dim(context);
-	bmap = isl_basic_map_extend_constraints(bmap, context->n_eq, 0);
-	for (i = 0; i < context->n_eq; ++i) {
-		int k;
-		k = isl_basic_map_alloc_equality(bmap);
-		if (k < 0)
-			return isl_basic_map_free(bmap);
-		isl_seq_cpy(bmap->eq[k], context->eq[i], 1 + total_context);
-		isl_seq_clr(bmap->eq[k] + 1 + total_context,
-				isl_basic_map_total_dim(bmap) - total_context);
-	}
-	bmap = isl_basic_map_gauss(bmap, NULL);
-	bmap = normalize_divs(bmap, NULL);
-	bmap = isl_basic_map_gauss(bmap, NULL);
-	return bmap;
-}
-
 /* Return a basic map that has the same intersection with "context" as "bmap"
  * and that is as "simple" as possible.
  *
@@ -2339,7 +2725,7 @@ struct isl_basic_map *isl_basic_map_gist
 {
 	isl_basic_set *bset, *eq;
 	isl_basic_map *eq_bmap;
-	unsigned n_div, n_eq, n_ineq;
+	unsigned total, n_div, extra, n_eq, n_ineq;
 
 	if (!bmap || !context)
 		goto error;
@@ -2364,15 +2750,16 @@ struct isl_basic_map *isl_basic_map_gist
 	if (!context)
 		goto error;
 
-	if (context->n_eq)
-		bmap = normalize_divs_in_context(bmap, context);
-
 	context = isl_basic_map_align_divs(context, bmap);
-	bmap = isl_basic_map_align_divs(bmap, context);
-	n_div = isl_basic_map_dim(bmap, isl_dim_div);
+	n_div = isl_basic_map_dim(context, isl_dim_div);
+	total = isl_basic_map_dim(bmap, isl_dim_all);
+	extra = n_div - isl_basic_map_dim(bmap, isl_dim_div);
 
-	bset = uset_gist(isl_basic_map_underlying_set(isl_basic_map_copy(bmap)),
+	bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
+	bset = isl_basic_set_add_dims(bset, isl_dim_set, extra);
+	bset = uset_gist(bset,
 		    isl_basic_map_underlying_set(isl_basic_map_copy(context)));
+	bset = isl_basic_set_project_out(bset, isl_dim_set, total, extra);
 
 	if (!bset || bset->n_eq == 0 || n_div == 0 ||
 	    isl_basic_set_plain_is_empty(bset)) {
@@ -2977,23 +3364,23 @@ static int div_find_coalesce(struct isl_
  *	f_l e_u + f_u e_l + f_l - 1 + f_u - 1 + 1 >= f_u f_l g
  */
 static void construct_test_ineq(struct isl_basic_map *bmap, int i,
-	int l, int u, isl_int *ineq, isl_int g, isl_int fl, isl_int fu)
+	int l, int u, isl_int *ineq, isl_int *g, isl_int *fl, isl_int *fu)
 {
 	unsigned dim;
 	dim = isl_space_dim(bmap->dim, isl_dim_all);
 
-	isl_int_gcd(g, bmap->ineq[l][1 + dim + i], bmap->ineq[u][1 + dim + i]);
-	isl_int_divexact(fl, bmap->ineq[l][1 + dim + i], g);
-	isl_int_divexact(fu, bmap->ineq[u][1 + dim + i], g);
-	isl_int_neg(fu, fu);
-	isl_seq_combine(ineq, fl, bmap->ineq[u], fu, bmap->ineq[l],
+	isl_int_gcd(*g, bmap->ineq[l][1 + dim + i], bmap->ineq[u][1 + dim + i]);
+	isl_int_divexact(*fl, bmap->ineq[l][1 + dim + i], *g);
+	isl_int_divexact(*fu, bmap->ineq[u][1 + dim + i], *g);
+	isl_int_neg(*fu, *fu);
+	isl_seq_combine(ineq, *fl, bmap->ineq[u], *fu, bmap->ineq[l],
 			1 + dim + bmap->n_div);
-	isl_int_add(ineq[0], ineq[0], fl);
-	isl_int_add(ineq[0], ineq[0], fu);
+	isl_int_add(ineq[0], ineq[0], *fl);
+	isl_int_add(ineq[0], ineq[0], *fu);
 	isl_int_sub_ui(ineq[0], ineq[0], 1);
-	isl_int_mul(g, g, fl);
-	isl_int_mul(g, g, fu);
-	isl_int_sub(ineq[0], ineq[0], g);
+	isl_int_mul(*g, *g, *fl);
+	isl_int_mul(*g, *g, *fu);
+	isl_int_sub(ineq[0], ineq[0], *g);
 }
 
 /* Remove more kinds of divs that are not strictly needed.
@@ -3046,7 +3433,7 @@ static struct isl_basic_map *drop_more_r
 				if (!isl_int_is_neg(bmap->ineq[u][1 + dim + i]))
 					continue;
 				construct_test_ineq(bmap, i, l, u,
-						    vec->el, g, fl, fu);
+						    vec->el, &g, &fl, &fu);
 				res = isl_tab_min(tab, vec->el,
 						  bmap->ctx->one, &g, NULL, 0);
 				if (res == isl_lp_error)

Added: polly/trunk/lib/External/isl/isl_multi_coalesce.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_multi_coalesce.c?rev=244585&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/isl_multi_coalesce.c (added)
+++ polly/trunk/lib/External/isl/isl_multi_coalesce.c Tue Aug 11 06:31:18 2015
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013      Ecole Normale Superieure
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
+ */
+
+#include <isl_multi_macro.h>
+
+/* Coalesce the elements of "multi".
+ *
+ * Note that such coalescing does not change the meaning of "multi"
+ * so there is no need to cow.  We do need to be careful not to
+ * destroy any other copies of "multi" in case of failure.
+ */
+__isl_give MULTI(BASE) *FN(MULTI(BASE),coalesce)(__isl_take MULTI(BASE) *multi)
+{
+	int i;
+
+	if (!multi)
+		return NULL;
+
+	for (i = 0; i < multi->n; ++i) {
+		EL *el = FN(EL,copy)(multi->p[i]);
+		el = FN(EL,coalesce)(el);
+		if (!el)
+			return FN(MULTI(BASE),free)(multi);
+		FN(EL,free)(multi->p[i]);
+		multi->p[i] = el;
+	}
+
+	return multi;
+}

Modified: polly/trunk/lib/External/isl/isl_test.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_test.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_test.c (original)
+++ polly/trunk/lib/External/isl/isl_test.c Tue Aug 11 06:31:18 2015
@@ -1277,6 +1277,38 @@ struct {
 			"(n >= 1 and a >= 0 and b <= 2148 - n - a and "
 			"b >= 0) }",
 	  "{ [m, n, ku, kl] }" },
+	{ "{ [a, a, b] : a >= 10 }",
+	  "{ [a, b, c] : c >= a and c <= b and c >= 2 }",
+	  "{ [a, a, b] : a >= 10 }" },
+	{ "{ [i, j] : i >= 0 and i + j >= 0 }", "{ [i, j] : i <= 0 }",
+	  "{ [0, j] : j >= 0 }" },
+	/* Check that no constraints on i6 are introduced in the gist */
+	{ "[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): "
+		"20e0 <= 1530 - 4t1 - 5i4 and 20e0 >= 1511 - 4t1 - 5i4 and "
+		"5e0 <= 381 - t1 and i4 <= 1) }",
+	  "[t1] -> { [i4, i6] : exists (e0 = floor((-t1 + i6)/5): "
+		"5e0 = -t1 + i6 and i6 <= 6 and i6 >= 3) }",
+	  "[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): "
+		"i4 <= 1 and 5e0 <= 381 - t1 and 20e0 <= 1530 - 4t1 - 5i4 and "
+		"20e0 >= 1511 - 4t1 - 5i4) }" },
+	/* Check that no constraints on i6 are introduced in the gist */
+	{ "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((1 + i4)/2), "
+		"e1 = floor((1530 - 4t1 - 5i4)/20), "
+		"e2 = floor((-4t1 - 5i4 + 10*floor((1 + i4)/2))/20), "
+		"e3 = floor((-1 + i4)/2): t2 = 0 and 2e3 = -1 + i4 and "
+			"20e2 >= -19 - 4t1 - 5i4 + 10e0 and 5e2 <= 1 - t1 and "
+			"2e0 <= 1 + i4 and 2e0 >= i4 and "
+			"20e1 <= 1530 - 4t1 - 5i4 and "
+			"20e1 >= 1511 - 4t1 - 5i4 and i4 <= 1 and "
+			"5e1 <= 381 - t1 and 20e2 <= -4t1 - 5i4 + 10e0) }",
+	  "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((-17 + i4)/2), "
+		"e1 = floor((-t1 + i6)/5): 5e1 = -t1 + i6 and "
+			"2e0 <= -17 + i4 and 2e0 >= -18 + i4 and "
+			"10e0 <= -91 + 5i4 + 4i6 and "
+			"10e0 >= -105 + 5i4 + 4i6) }",
+	  "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((381 - t1)/5), "
+		"e1 = floor((-1 + i4)/2): t2 = 0 and 2e1 = -1 + i4 and "
+		"i4 <= 1 and 5e0 <= 381 - t1 and 20e0 >= 1511 - 4t1 - 5i4) }" },
 };
 
 static int test_gist(struct isl_ctx *ctx)

Modified: polly/trunk/lib/External/isl/test_inputs/codegen/omega/iter9-0.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/codegen/omega/iter9-0.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/codegen/omega/iter9-0.c (original)
+++ polly/trunk/lib/External/isl/test_inputs/codegen/omega/iter9-0.c Tue Aug 11 06:31:18 2015
@@ -6,6 +6,6 @@ for (int c0 = 1; c0 <= 15; c0 += 1) {
     s2(c0);
     s1(c0);
   }
-  if (((-exprVar1 + 15) % 8) + c0 <= 15 || (c0 >= 9 && (exprVar1 - c0 + 1) % 8 == 0))
+  if (((-exprVar1 + 15) % 8) + c0 <= 15 || (exprVar1 - c0 + 1) % 8 == 0)
     s5(c0);
 }

Modified: polly/trunk/lib/External/isl/test_inputs/codegen/roman.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/codegen/roman.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/codegen/roman.c (original)
+++ polly/trunk/lib/External/isl/test_inputs/codegen/roman.c Tue Aug 11 06:31:18 2015
@@ -17,7 +17,7 @@
       S_24(c1, c3);
       S_19(c1, c3);
     }
-    if (np1 >= i && i + c1 <= 21) {
+    if (i + c1 <= 21) {
       S_15(c1, i + c1 - 2);
       for (int c5 = 0; c5 < i + c1 - 2; c5 += 1) {
         S_16(c1, i + c1 - 2, c5);

Modified: polly/trunk/lib/External/isl/test_inputs/codegen/separate2.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/codegen/separate2.c?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/codegen/separate2.c (original)
+++ polly/trunk/lib/External/isl/test_inputs/codegen/separate2.c Tue Aug 11 06:31:18 2015
@@ -4,6 +4,6 @@ if ((length - 1) % 16 <= 14)
       for (int c6 = max(0, 2 * ((length - 1) % 16) + 2 * c5 - 60); c6 <= 30; c6 += 1) {
         if (2 * length + c6 >= 2 * ((length - 1) % 16) + 4 && 2 * ((length - 1) % 16) >= c6 && 2 * ((length - 1) % 16) + 2 * c5 >= c6 && c6 + 62 >= 2 * ((length - 1) % 16) + 2 * c5 && 2 * ((length - 1) % 16) + 2 * c5 == 2 * ((length - 1) % 32) + c6 && (2 * c5 - c6) % 32 == 0)
           S_3(c0, 0, (c6 / 2) - ((length - 1) % 16) + length - 1);
-        if (length <= 16 && length >= c5 + 1 && c6 >= 1 && length >= c6)
+        if (length <= 15 && length >= c5 + 1 && c6 >= 1 && length >= c6)
           S_0(c0, c5, c6 - 1);
       }

Modified: polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll (original)
+++ polly/trunk/test/ScopInfo/NonAffine/non_affine_loop_used_later.ll Tue Aug 11 06:31:18 2015
@@ -18,7 +18,7 @@
 ; CHECK:            Domain :=
 ; CHECK:                [N] -> { Stmt_bb2[i0] : i0 >= 0 and N >= 1 and i0 <= N; Stmt_bb2[0] : N <= 0 }
 ; CHECK:            Schedule :=
-; CHECK:                [N] -> { Stmt_bb2[i0] -> [i0, 0] : i0 <= N and N >= 1; Stmt_bb2[0] -> [0, 0] : N <= 0 }
+; CHECK:                [N] -> { Stmt_bb2[i0] -> [i0, 0] : N >= 1 and i0 <= N; Stmt_bb2[0] -> [0, 0] : N <= 0 }
 ; CHECK:            ReadAccess := [Reduction Type: NONE] [Scalar: 1]
 ; CHECK:                [N] -> { Stmt_bb2[i0] -> MemRef_j_0__phi[] };
 ; CHECK:            MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]

Modified: polly/trunk/test/ScopInfo/multidim_srem.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_srem.ll?rev=244585&r1=244584&r2=244585&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_srem.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_srem.ll Tue Aug 11 06:31:18 2015
@@ -8,9 +8,9 @@
 ;    }
 ;
 ; CHECK: ReadAccess :=	[Reduction Type: NONE] [Scalar: 0]
-; CHECK:     [n] -> { Stmt_for_body_8[i0, i1, i2] -> MemRef_A[o0, i1, i2] : exists (e0 = floor((-i0 + o0)/2): 2e0 = -i0 + o0 and o0 >= 0 and o0 <= 1) };
+; CHECK:     [n] -> { Stmt_for_body_8[i0, i1, i2] -> MemRef_A[o0, i1, i2] : exists (e0 = floor((-i0 + o0)/2): 2e0 = -i0 + o0 and o0 <= 1 and o0 >= 0) };
 ; CHECK: MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
-; CHECK:     [n] -> { Stmt_for_body_8[i0, i1, i2] -> MemRef_A[o0, i1, i2] : exists (e0 = floor((-i0 + o0)/2): 2e0 = -i0 + o0 and o0 >= 0 and o0 <= 1) };
+; CHECK:     [n] -> { Stmt_for_body_8[i0, i1, i2] -> MemRef_A[o0, i1, i2] : exists (e0 = floor((-i0 + o0)/2): 2e0 = -i0 + o0 and o0 <= 1 and o0 >= 0) };
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 




More information about the llvm-commits mailing list