[Polly] Update isl to isl-0.23-61-g24e8cd12.

This fixes llvm.org/PR48554

Some test cases had to be updated because the hash function for
union_maps have been changed which affects the output order.

GitOrigin-RevId: 842314b5f078b5c63df1d7e271fc6fad8461d44f
diff --git a/lib/External/isl/AUTHORS b/lib/External/isl/AUTHORS
index 8ce9223..8c65c60 100644
--- a/lib/External/isl/AUTHORS
+++ b/lib/External/isl/AUTHORS
@@ -23,8 +23,8 @@
 	    Domaine de Voluceau - Rocquencourt, B.P. 105
 	    78153 Le Chesnay
 	    France
-2015-2019   Polly Labs
-2018-2019   Cerebras Systems
+2015-2020   Polly Labs
+2018-2020   Cerebras Systems
 	    175 S San Antonio Rd
 	    Los Altos, CA
 	    USA
@@ -54,6 +54,7 @@
 Andreas Simbuerger
 Malhar Thakkar
 Sergei Trofimovich
+Miheer Vaidya
 Sven van Haastregt
 Oleksandr Zinenko
 
diff --git a/lib/External/isl/ChangeLog b/lib/External/isl/ChangeLog
index 2193a72..dd4a6b7 100644
--- a/lib/External/isl/ChangeLog
+++ b/lib/External/isl/ChangeLog
@@ -1,3 +1,11 @@
+version: 0.23
+date: Sun 01 Nov 2020 02:41:20 PM CET
+changes:
+	- minor improvements to coalescing
+	- use build compiler to build extract_interface
+	- add some convenience functions
+	- ignore parameters in isl_union_* hash tables
+---
 version: 0.22.1
 date: Sun Jan 12 10:48:18 CET 2020
 changes:
@@ -6,6 +14,7 @@
 version: 0.22
 date: Fri Nov  1 18:39:30 CET 2019
 changes:
+	- require C++11 to generate bindings
 	- improved bindings
 	- scheduler fix involving fixed dimensions
 	- accept ranges in tuples during parsing
diff --git a/lib/External/isl/GIT_HEAD_ID b/lib/External/isl/GIT_HEAD_ID
index ca7fd96..cdd3042 100644
--- a/lib/External/isl/GIT_HEAD_ID
+++ b/lib/External/isl/GIT_HEAD_ID
@@ -1 +1 @@
-isl-0.22.1-416-g61d6dc75
+isl-0.23-61-g24e8cd12
diff --git a/lib/External/isl/Makefile.am b/lib/External/isl/Makefile.am
index 75b7817..b526126 100644
--- a/lib/External/isl/Makefile.am
+++ b/lib/External/isl/Makefile.am
@@ -141,6 +141,7 @@
 	isl_ilp_private.h \
 	isl_input.c \
 	isl_int.h \
+	isl_list_private.h \
 	isl_local_private.h \
 	isl_local.h \
 	isl_local.c \
@@ -465,7 +466,9 @@
 	isl_check_named_params_templ.c \
 	check_reparse_templ.c \
 	check_reparse_test_templ.c \
+	check_single_reference_templ.c \
 	check_type_range_templ.c \
+	isl_copy_tuple_id_templ.c \
 	isl_domain_factor_templ.c \
 	extract_key.c \
 	isl_ilp_opt_multi_val_templ.c \
@@ -558,6 +561,7 @@
 	isl_type_check_equal_space_templ.c \
 	isl_type_has_equal_space_bin_templ.c \
 	isl_type_has_equal_space_templ.c \
+	isl_type_has_space_templ.c \
 	isl_unbind_params_templ.c \
 	uset_to_umap.c \
 	uset_from_umap.c \
@@ -567,6 +571,7 @@
 	isl_union_multi.c \
 	isl_union_eval.c \
 	isl_union_locals_templ.c \
+	isl_union_map_lex_templ.c \
 	isl_union_neg.c \
 	isl_union_pw_templ.c \
 	libisl-gdb.py \
diff --git a/lib/External/isl/Makefile.in b/lib/External/isl/Makefile.in
index 7a74b4d..0b72eb3 100644
--- a/lib/External/isl/Makefile.in
+++ b/lib/External/isl/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -151,16 +151,13 @@
 CONFIG_CLEAN_FILES = isl_srcdir.c bound_test.sh codegen_test.sh \
 	pip_test.sh flow_test.sh schedule_test.sh
 CONFIG_CLEAN_VPATH_FILES =
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_1 =  \
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp$(EXEEXT)
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_2 = isl_test_cpp-checked$(EXEEXT) \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp-checked-conversion$(EXEEXT)
+@IMATH_FOR_MP_TRUE@am__EXEEXT_3 = isl_test_imath$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
 LIBRARIES = $(noinst_LIBRARIES)
-ARFLAGS = cru
-AM_V_AR = $(am__v_AR_@AM_V@)
-am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
-am__v_AR_0 = @echo "  AR      " $@;
-am__v_AR_1 = 
-libdep_a_AR = $(AR) $(ARFLAGS)
-libdep_a_LIBADD =
-am_libdep_a_OBJECTS = dep.$(OBJEXT)
-libdep_a_OBJECTS = $(am_libdep_a_OBJECTS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -191,6 +188,15 @@
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
 	"$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_@AM_V@)
+am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libdep_a_AR = $(AR) $(ARFLAGS)
+libdep_a_LIBADD =
+am_libdep_a_OBJECTS = dep.$(OBJEXT)
+libdep_a_OBJECTS = $(am_libdep_a_OBJECTS)
 libisl_la_DEPENDENCIES =
 am__libisl_la_SOURCES_DIST = mp_get_memory_functions.c isl_int_gmp.h \
 	isl_gmp.c isl_val_gmp.c isl_imath.c isl_imath.h \
@@ -211,17 +217,18 @@
 	isl_factorization.c isl_factorization.h isl_farkas.c isl_ffs.c \
 	isl_flow.c isl_fold.c isl_hash.c isl_id_to_ast_expr.c \
 	isl_id_to_id.c isl_id_to_pw_aff.c isl_ilp.c isl_ilp_private.h \
-	isl_input.c isl_int.h isl_local_private.h isl_local.h \
-	isl_local.c isl_local_space_private.h isl_local_space.c \
-	isl_lp.c isl_lp_private.h isl_map.c isl_map_list.c \
-	isl_map_simplify.c isl_map_subtract.c isl_map_private.h \
-	isl_map_to_basic_set.c isl_mat.c isl_mat_private.h isl_morph.c \
-	isl_morph.h isl_id.c isl_id_private.h isl_obj.c isl_options.c \
-	isl_options_private.h isl_output.c isl_output_private.h \
-	isl_point_private.h isl_point.c isl_polynomial_private.h \
-	isl_polynomial.c isl_printer_private.h isl_printer.c print.c \
-	isl_range.c isl_range.h isl_reordering.c isl_reordering.h \
-	isl_sample.h isl_sample.c isl_scan.c isl_scan.h isl_schedule.c \
+	isl_input.c isl_int.h isl_list_private.h isl_local_private.h \
+	isl_local.h isl_local.c isl_local_space_private.h \
+	isl_local_space.c isl_lp.c isl_lp_private.h isl_map.c \
+	isl_map_list.c isl_map_simplify.c isl_map_subtract.c \
+	isl_map_private.h isl_map_to_basic_set.c isl_mat.c \
+	isl_mat_private.h isl_morph.c isl_morph.h isl_id.c \
+	isl_id_private.h isl_obj.c isl_options.c isl_options_private.h \
+	isl_output.c isl_output_private.h isl_point_private.h \
+	isl_point.c isl_polynomial_private.h isl_polynomial.c \
+	isl_printer_private.h isl_printer.c print.c isl_range.c \
+	isl_range.h isl_reordering.c isl_reordering.h isl_sample.h \
+	isl_sample.c isl_scan.c isl_scan.h isl_schedule.c \
 	isl_schedule_band.c isl_schedule_band.h isl_schedule_node.c \
 	isl_schedule_node_private.h isl_schedule_read.c \
 	isl_schedule_tree.c isl_schedule_tree.h isl_schedule_private.h \
@@ -281,12 +288,6 @@
 libisl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(libisl_la_LDFLAGS) $(LDFLAGS) -o $@
-@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_1 =  \
-@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp$(EXEEXT)
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_2 = isl_test_cpp-checked$(EXEEXT) \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp-checked-conversion$(EXEEXT)
-@IMATH_FOR_MP_TRUE@am__EXEEXT_3 = isl_test_imath$(EXEEXT)
-PROGRAMS = $(noinst_PROGRAMS)
 am_isl_bound_OBJECTS = bound.$(OBJEXT)
 isl_bound_OBJECTS = $(am_isl_bound_OBJECTS)
 isl_bound_DEPENDENCIES = libisl.la
@@ -410,7 +411,70 @@
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/basis_reduction_tab.Plo \
+	./$(DEPDIR)/bound.Po ./$(DEPDIR)/cat.Po ./$(DEPDIR)/closure.Po \
+	./$(DEPDIR)/codegen.Po ./$(DEPDIR)/dep.Po ./$(DEPDIR)/flow.Po \
+	./$(DEPDIR)/flow_cmp.Po ./$(DEPDIR)/isl_aff.Plo \
+	./$(DEPDIR)/isl_aff_map.Plo ./$(DEPDIR)/isl_affine_hull.Plo \
+	./$(DEPDIR)/isl_arg.Plo ./$(DEPDIR)/isl_ast.Plo \
+	./$(DEPDIR)/isl_ast_build.Plo \
+	./$(DEPDIR)/isl_ast_build_expr.Plo \
+	./$(DEPDIR)/isl_ast_codegen.Plo ./$(DEPDIR)/isl_ast_graft.Plo \
+	./$(DEPDIR)/isl_bernstein.Plo ./$(DEPDIR)/isl_blk.Plo \
+	./$(DEPDIR)/isl_bound.Plo ./$(DEPDIR)/isl_box.Plo \
+	./$(DEPDIR)/isl_coalesce.Plo ./$(DEPDIR)/isl_constraint.Plo \
+	./$(DEPDIR)/isl_convex_hull.Plo ./$(DEPDIR)/isl_ctx.Plo \
+	./$(DEPDIR)/isl_deprecated.Plo ./$(DEPDIR)/isl_dim_map.Plo \
+	./$(DEPDIR)/isl_equalities.Plo \
+	./$(DEPDIR)/isl_factorization.Plo ./$(DEPDIR)/isl_farkas.Plo \
+	./$(DEPDIR)/isl_ffs.Plo ./$(DEPDIR)/isl_flow.Plo \
+	./$(DEPDIR)/isl_fold.Plo ./$(DEPDIR)/isl_gmp.Plo \
+	./$(DEPDIR)/isl_hash.Plo ./$(DEPDIR)/isl_id.Plo \
+	./$(DEPDIR)/isl_id_to_ast_expr.Plo \
+	./$(DEPDIR)/isl_id_to_id.Plo ./$(DEPDIR)/isl_id_to_pw_aff.Plo \
+	./$(DEPDIR)/isl_ilp.Plo ./$(DEPDIR)/isl_imath.Plo \
+	./$(DEPDIR)/isl_input.Plo ./$(DEPDIR)/isl_int_sioimath.Plo \
+	./$(DEPDIR)/isl_local.Plo ./$(DEPDIR)/isl_local_space.Plo \
+	./$(DEPDIR)/isl_lp.Plo ./$(DEPDIR)/isl_map.Plo \
+	./$(DEPDIR)/isl_map_list.Plo ./$(DEPDIR)/isl_map_simplify.Plo \
+	./$(DEPDIR)/isl_map_subtract.Plo \
+	./$(DEPDIR)/isl_map_to_basic_set.Plo ./$(DEPDIR)/isl_mat.Plo \
+	./$(DEPDIR)/isl_morph.Plo ./$(DEPDIR)/isl_obj.Plo \
+	./$(DEPDIR)/isl_options.Plo ./$(DEPDIR)/isl_output.Plo \
+	./$(DEPDIR)/isl_point.Plo ./$(DEPDIR)/isl_polynomial.Plo \
+	./$(DEPDIR)/isl_printer.Plo ./$(DEPDIR)/isl_range.Plo \
+	./$(DEPDIR)/isl_reordering.Plo ./$(DEPDIR)/isl_sample.Plo \
+	./$(DEPDIR)/isl_scan.Plo ./$(DEPDIR)/isl_schedule.Plo \
+	./$(DEPDIR)/isl_schedule_band.Plo \
+	./$(DEPDIR)/isl_schedule_constraints.Plo \
+	./$(DEPDIR)/isl_schedule_node.Plo \
+	./$(DEPDIR)/isl_schedule_read.Plo \
+	./$(DEPDIR)/isl_schedule_tree.Plo \
+	./$(DEPDIR)/isl_scheduler.Plo ./$(DEPDIR)/isl_seq.Plo \
+	./$(DEPDIR)/isl_set_list.Plo \
+	./$(DEPDIR)/isl_set_to_ast_graft_list.Plo \
+	./$(DEPDIR)/isl_sort.Plo ./$(DEPDIR)/isl_space.Plo \
+	./$(DEPDIR)/isl_stream.Plo ./$(DEPDIR)/isl_stride.Plo \
+	./$(DEPDIR)/isl_tab.Plo ./$(DEPDIR)/isl_tab_pip.Plo \
+	./$(DEPDIR)/isl_tarjan.Plo ./$(DEPDIR)/isl_test.Po \
+	./$(DEPDIR)/isl_test_cpp-checked-conversion.Po \
+	./$(DEPDIR)/isl_test_cpp-checked.Po \
+	./$(DEPDIR)/isl_test_cpp.Po ./$(DEPDIR)/isl_test_imath.Po \
+	./$(DEPDIR)/isl_test_int.Po \
+	./$(DEPDIR)/isl_transitive_closure.Plo \
+	./$(DEPDIR)/isl_union_map.Plo ./$(DEPDIR)/isl_val.Plo \
+	./$(DEPDIR)/isl_val_gmp.Plo ./$(DEPDIR)/isl_val_imath.Plo \
+	./$(DEPDIR)/isl_val_sioimath.Plo ./$(DEPDIR)/isl_vec.Plo \
+	./$(DEPDIR)/isl_version.Plo ./$(DEPDIR)/isl_vertices.Plo \
+	./$(DEPDIR)/mp_get_memory_functions.Plo ./$(DEPDIR)/pip.Po \
+	./$(DEPDIR)/polyhedron_detect_equalities.Po \
+	./$(DEPDIR)/polyhedron_minimize.Po \
+	./$(DEPDIR)/polyhedron_sample.Po ./$(DEPDIR)/polytope_scan.Po \
+	./$(DEPDIR)/print.Plo ./$(DEPDIR)/schedule.Po \
+	./$(DEPDIR)/schedule_cmp.Po \
+	imath_wrap/$(DEPDIR)/gmp_compat.Plo \
+	imath_wrap/$(DEPDIR)/imath.Plo imath_wrap/$(DEPDIR)/imrat.Plo
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -522,7 +586,8 @@
   $(RECURSIVE_CLEAN_TARGETS) \
   $(am__extra_recursive_targets)
 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
-	cscope check recheck distdir dist dist-all distcheck
+	cscope check recheck distdir distdir-am dist dist-all \
+	distcheck
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
 	$(LISP)isl_config.h.in
 # Read a list of newline-separated strings from the standard input,
@@ -1006,6 +1071,7 @@
 	isl_ilp_private.h \
 	isl_input.c \
 	isl_int.h \
+	isl_list_private.h \
 	isl_local_private.h \
 	isl_local.h \
 	isl_local.c \
@@ -1278,7 +1344,9 @@
 	isl_check_named_params_templ.c \
 	check_reparse_templ.c \
 	check_reparse_test_templ.c \
+	check_single_reference_templ.c \
 	check_type_range_templ.c \
+	isl_copy_tuple_id_templ.c \
 	isl_domain_factor_templ.c \
 	extract_key.c \
 	isl_ilp_opt_multi_val_templ.c \
@@ -1371,6 +1439,7 @@
 	isl_type_check_equal_space_templ.c \
 	isl_type_has_equal_space_bin_templ.c \
 	isl_type_has_equal_space_templ.c \
+	isl_type_has_space_templ.c \
 	isl_unbind_params_templ.c \
 	uset_to_umap.c \
 	uset_from_umap.c \
@@ -1380,6 +1449,7 @@
 	isl_union_multi.c \
 	isl_union_eval.c \
 	isl_union_locals_templ.c \
+	isl_union_map_lex_templ.c \
 	isl_union_neg.c \
 	isl_union_pw_templ.c \
 	libisl-gdb.py \
@@ -1432,8 +1502,8 @@
 	    echo ' $(SHELL) ./config.status'; \
 	    $(SHELL) ./config.status;; \
 	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
 	esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -1472,14 +1542,18 @@
 schedule_test.sh: $(top_builddir)/config.status $(srcdir)/schedule_test.sh.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
 clean-noinstLIBRARIES:
 	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
 
-libdep.a: $(libdep_a_OBJECTS) $(libdep_a_DEPENDENCIES) $(EXTRA_libdep_a_DEPENDENCIES) 
-	$(AM_V_at)-rm -f libdep.a
-	$(AM_V_AR)$(libdep_a_AR) libdep.a $(libdep_a_OBJECTS) $(libdep_a_LIBADD)
-	$(AM_V_at)$(RANLIB) libdep.a
-
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
 	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
@@ -1514,6 +1588,11 @@
 	  echo rm -f $${locs}; \
 	  rm -f $${locs}; \
 	}
+
+libdep.a: $(libdep_a_OBJECTS) $(libdep_a_DEPENDENCIES) $(EXTRA_libdep_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libdep.a
+	$(AM_V_AR)$(libdep_a_AR) libdep.a $(libdep_a_OBJECTS) $(libdep_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libdep.a
 imath_wrap/$(am__dirstamp):
 	@$(MKDIR_P) imath_wrap
 	@: > imath_wrap/$(am__dirstamp)
@@ -1530,15 +1609,6 @@
 libisl.la: $(libisl_la_OBJECTS) $(libisl_la_DEPENDENCIES) $(EXTRA_libisl_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(libisl_la_LINK) -rpath $(libdir) $(libisl_la_OBJECTS) $(libisl_la_LIBADD) $(LIBS)
 
-clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
-
 isl_bound$(EXEEXT): $(isl_bound_OBJECTS) $(isl_bound_DEPENDENCIES) $(EXTRA_isl_bound_DEPENDENCIES) 
 	@rm -f isl_bound$(EXEEXT)
 	$(AM_V_CCLD)$(isl_bound_LINK) $(isl_bound_OBJECTS) $(isl_bound_LDADD) $(LIBS)
@@ -1623,113 +1693,119 @@
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basis_reduction_tab.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bound.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cat.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codegen.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dep.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow_cmp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_aff.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_aff_map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_affine_hull.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_arg.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build_expr.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_codegen.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_graft.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bernstein.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_blk.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bound.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_box.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_coalesce.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_constraint.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_convex_hull.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ctx.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_deprecated.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_dim_map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_equalities.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_factorization.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_farkas.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ffs.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_flow.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_fold.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_gmp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_hash.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_ast_expr.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_id.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_pw_aff.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ilp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_imath.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_input.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_int_sioimath.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_local.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_local_space.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_lp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_list.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_simplify.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_subtract.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_to_basic_set.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_mat.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_morph.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_obj.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_options.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_output.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_point.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polynomial.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_printer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_range.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_reordering.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sample.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scan.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_band.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_constraints.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_node.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_read.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_tree.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scheduler.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_seq.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_set_list.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_set_to_ast_graft_list.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sort.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_space.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stream.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stride.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab_pip.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tarjan.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked-conversion.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_imath.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_int.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_transitive_closure.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_union_map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_gmp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_imath.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_sioimath.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vec.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_version.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vertices.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp_get_memory_functions.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pip.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_detect_equalities.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_minimize.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_sample.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polytope_scan.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule_cmp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/gmp_compat.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imath.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imrat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basis_reduction_tab.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bound.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cat.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codegen.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dep.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow_cmp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_aff.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_aff_map.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_affine_hull.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_arg.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build_expr.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_codegen.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_graft.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bernstein.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_blk.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bound.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_box.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_coalesce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_constraint.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_convex_hull.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ctx.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_deprecated.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_dim_map.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_equalities.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_factorization.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_farkas.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ffs.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_flow.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_fold.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_gmp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_hash.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_ast_expr.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_id.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_pw_aff.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ilp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_imath.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_input.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_int_sioimath.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_local.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_local_space.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_lp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_list.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_simplify.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_subtract.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_to_basic_set.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_mat.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_morph.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_obj.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_options.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_output.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_point.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polynomial.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_printer.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_range.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_reordering.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sample.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scan.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_band.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_constraints.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_node.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_read.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_tree.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scheduler.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_seq.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_set_list.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_set_to_ast_graft_list.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sort.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_space.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stream.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stride.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab_pip.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tarjan.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked-conversion.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_imath.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_int.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_transitive_closure.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_union_map.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_gmp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_imath.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_sioimath.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vec.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_version.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vertices.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp_get_memory_functions.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pip.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_detect_equalities.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_minimize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_sample.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polytope_scan.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule_cmp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/gmp_compat.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imath.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imrat.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+	@$(MKDIR_P) $(@D)
+	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -2078,7 +2154,7 @@
 	fi;								\
 	$$success || exit 1
 
-check-TESTS:
+check-TESTS: 
 	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
 	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
 	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@@ -2191,7 +2267,10 @@
 @am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_PY_LOG_DRIVER_FLAGS) $(PY_LOG_DRIVER_FLAGS) -- $(PY_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
 	$(am__remove_distdir)
 	test -d "$(distdir)" || mkdir "$(distdir)"
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -2386,7 +2465,7 @@
 	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) check-recursive
-all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(DATA) \
+all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(LTLIBRARIES) $(DATA) \
 		$(HEADERS) isl_config.h
 installdirs: installdirs-recursive
 installdirs-am:
@@ -2439,7 +2518,113 @@
 
 distclean: distclean-recursive
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf ./$(DEPDIR) imath_wrap/$(DEPDIR)
+		-rm -f ./$(DEPDIR)/basis_reduction_tab.Plo
+	-rm -f ./$(DEPDIR)/bound.Po
+	-rm -f ./$(DEPDIR)/cat.Po
+	-rm -f ./$(DEPDIR)/closure.Po
+	-rm -f ./$(DEPDIR)/codegen.Po
+	-rm -f ./$(DEPDIR)/dep.Po
+	-rm -f ./$(DEPDIR)/flow.Po
+	-rm -f ./$(DEPDIR)/flow_cmp.Po
+	-rm -f ./$(DEPDIR)/isl_aff.Plo
+	-rm -f ./$(DEPDIR)/isl_aff_map.Plo
+	-rm -f ./$(DEPDIR)/isl_affine_hull.Plo
+	-rm -f ./$(DEPDIR)/isl_arg.Plo
+	-rm -f ./$(DEPDIR)/isl_ast.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_build.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_build_expr.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_codegen.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_graft.Plo
+	-rm -f ./$(DEPDIR)/isl_bernstein.Plo
+	-rm -f ./$(DEPDIR)/isl_blk.Plo
+	-rm -f ./$(DEPDIR)/isl_bound.Plo
+	-rm -f ./$(DEPDIR)/isl_box.Plo
+	-rm -f ./$(DEPDIR)/isl_coalesce.Plo
+	-rm -f ./$(DEPDIR)/isl_constraint.Plo
+	-rm -f ./$(DEPDIR)/isl_convex_hull.Plo
+	-rm -f ./$(DEPDIR)/isl_ctx.Plo
+	-rm -f ./$(DEPDIR)/isl_deprecated.Plo
+	-rm -f ./$(DEPDIR)/isl_dim_map.Plo
+	-rm -f ./$(DEPDIR)/isl_equalities.Plo
+	-rm -f ./$(DEPDIR)/isl_factorization.Plo
+	-rm -f ./$(DEPDIR)/isl_farkas.Plo
+	-rm -f ./$(DEPDIR)/isl_ffs.Plo
+	-rm -f ./$(DEPDIR)/isl_flow.Plo
+	-rm -f ./$(DEPDIR)/isl_fold.Plo
+	-rm -f ./$(DEPDIR)/isl_gmp.Plo
+	-rm -f ./$(DEPDIR)/isl_hash.Plo
+	-rm -f ./$(DEPDIR)/isl_id.Plo
+	-rm -f ./$(DEPDIR)/isl_id_to_ast_expr.Plo
+	-rm -f ./$(DEPDIR)/isl_id_to_id.Plo
+	-rm -f ./$(DEPDIR)/isl_id_to_pw_aff.Plo
+	-rm -f ./$(DEPDIR)/isl_ilp.Plo
+	-rm -f ./$(DEPDIR)/isl_imath.Plo
+	-rm -f ./$(DEPDIR)/isl_input.Plo
+	-rm -f ./$(DEPDIR)/isl_int_sioimath.Plo
+	-rm -f ./$(DEPDIR)/isl_local.Plo
+	-rm -f ./$(DEPDIR)/isl_local_space.Plo
+	-rm -f ./$(DEPDIR)/isl_lp.Plo
+	-rm -f ./$(DEPDIR)/isl_map.Plo
+	-rm -f ./$(DEPDIR)/isl_map_list.Plo
+	-rm -f ./$(DEPDIR)/isl_map_simplify.Plo
+	-rm -f ./$(DEPDIR)/isl_map_subtract.Plo
+	-rm -f ./$(DEPDIR)/isl_map_to_basic_set.Plo
+	-rm -f ./$(DEPDIR)/isl_mat.Plo
+	-rm -f ./$(DEPDIR)/isl_morph.Plo
+	-rm -f ./$(DEPDIR)/isl_obj.Plo
+	-rm -f ./$(DEPDIR)/isl_options.Plo
+	-rm -f ./$(DEPDIR)/isl_output.Plo
+	-rm -f ./$(DEPDIR)/isl_point.Plo
+	-rm -f ./$(DEPDIR)/isl_polynomial.Plo
+	-rm -f ./$(DEPDIR)/isl_printer.Plo
+	-rm -f ./$(DEPDIR)/isl_range.Plo
+	-rm -f ./$(DEPDIR)/isl_reordering.Plo
+	-rm -f ./$(DEPDIR)/isl_sample.Plo
+	-rm -f ./$(DEPDIR)/isl_scan.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_band.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_constraints.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_node.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_read.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_tree.Plo
+	-rm -f ./$(DEPDIR)/isl_scheduler.Plo
+	-rm -f ./$(DEPDIR)/isl_seq.Plo
+	-rm -f ./$(DEPDIR)/isl_set_list.Plo
+	-rm -f ./$(DEPDIR)/isl_set_to_ast_graft_list.Plo
+	-rm -f ./$(DEPDIR)/isl_sort.Plo
+	-rm -f ./$(DEPDIR)/isl_space.Plo
+	-rm -f ./$(DEPDIR)/isl_stream.Plo
+	-rm -f ./$(DEPDIR)/isl_stride.Plo
+	-rm -f ./$(DEPDIR)/isl_tab.Plo
+	-rm -f ./$(DEPDIR)/isl_tab_pip.Plo
+	-rm -f ./$(DEPDIR)/isl_tarjan.Plo
+	-rm -f ./$(DEPDIR)/isl_test.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp-checked.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp.Po
+	-rm -f ./$(DEPDIR)/isl_test_imath.Po
+	-rm -f ./$(DEPDIR)/isl_test_int.Po
+	-rm -f ./$(DEPDIR)/isl_transitive_closure.Plo
+	-rm -f ./$(DEPDIR)/isl_union_map.Plo
+	-rm -f ./$(DEPDIR)/isl_val.Plo
+	-rm -f ./$(DEPDIR)/isl_val_gmp.Plo
+	-rm -f ./$(DEPDIR)/isl_val_imath.Plo
+	-rm -f ./$(DEPDIR)/isl_val_sioimath.Plo
+	-rm -f ./$(DEPDIR)/isl_vec.Plo
+	-rm -f ./$(DEPDIR)/isl_version.Plo
+	-rm -f ./$(DEPDIR)/isl_vertices.Plo
+	-rm -f ./$(DEPDIR)/mp_get_memory_functions.Plo
+	-rm -f ./$(DEPDIR)/pip.Po
+	-rm -f ./$(DEPDIR)/polyhedron_detect_equalities.Po
+	-rm -f ./$(DEPDIR)/polyhedron_minimize.Po
+	-rm -f ./$(DEPDIR)/polyhedron_sample.Po
+	-rm -f ./$(DEPDIR)/polytope_scan.Po
+	-rm -f ./$(DEPDIR)/print.Plo
+	-rm -f ./$(DEPDIR)/schedule.Po
+	-rm -f ./$(DEPDIR)/schedule_cmp.Po
+	-rm -f imath_wrap/$(DEPDIR)/gmp_compat.Plo
+	-rm -f imath_wrap/$(DEPDIR)/imath.Plo
+	-rm -f imath_wrap/$(DEPDIR)/imrat.Plo
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-libtool distclean-tags
@@ -2488,7 +2673,113 @@
 maintainer-clean: maintainer-clean-recursive
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf ./$(DEPDIR) imath_wrap/$(DEPDIR)
+		-rm -f ./$(DEPDIR)/basis_reduction_tab.Plo
+	-rm -f ./$(DEPDIR)/bound.Po
+	-rm -f ./$(DEPDIR)/cat.Po
+	-rm -f ./$(DEPDIR)/closure.Po
+	-rm -f ./$(DEPDIR)/codegen.Po
+	-rm -f ./$(DEPDIR)/dep.Po
+	-rm -f ./$(DEPDIR)/flow.Po
+	-rm -f ./$(DEPDIR)/flow_cmp.Po
+	-rm -f ./$(DEPDIR)/isl_aff.Plo
+	-rm -f ./$(DEPDIR)/isl_aff_map.Plo
+	-rm -f ./$(DEPDIR)/isl_affine_hull.Plo
+	-rm -f ./$(DEPDIR)/isl_arg.Plo
+	-rm -f ./$(DEPDIR)/isl_ast.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_build.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_build_expr.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_codegen.Plo
+	-rm -f ./$(DEPDIR)/isl_ast_graft.Plo
+	-rm -f ./$(DEPDIR)/isl_bernstein.Plo
+	-rm -f ./$(DEPDIR)/isl_blk.Plo
+	-rm -f ./$(DEPDIR)/isl_bound.Plo
+	-rm -f ./$(DEPDIR)/isl_box.Plo
+	-rm -f ./$(DEPDIR)/isl_coalesce.Plo
+	-rm -f ./$(DEPDIR)/isl_constraint.Plo
+	-rm -f ./$(DEPDIR)/isl_convex_hull.Plo
+	-rm -f ./$(DEPDIR)/isl_ctx.Plo
+	-rm -f ./$(DEPDIR)/isl_deprecated.Plo
+	-rm -f ./$(DEPDIR)/isl_dim_map.Plo
+	-rm -f ./$(DEPDIR)/isl_equalities.Plo
+	-rm -f ./$(DEPDIR)/isl_factorization.Plo
+	-rm -f ./$(DEPDIR)/isl_farkas.Plo
+	-rm -f ./$(DEPDIR)/isl_ffs.Plo
+	-rm -f ./$(DEPDIR)/isl_flow.Plo
+	-rm -f ./$(DEPDIR)/isl_fold.Plo
+	-rm -f ./$(DEPDIR)/isl_gmp.Plo
+	-rm -f ./$(DEPDIR)/isl_hash.Plo
+	-rm -f ./$(DEPDIR)/isl_id.Plo
+	-rm -f ./$(DEPDIR)/isl_id_to_ast_expr.Plo
+	-rm -f ./$(DEPDIR)/isl_id_to_id.Plo
+	-rm -f ./$(DEPDIR)/isl_id_to_pw_aff.Plo
+	-rm -f ./$(DEPDIR)/isl_ilp.Plo
+	-rm -f ./$(DEPDIR)/isl_imath.Plo
+	-rm -f ./$(DEPDIR)/isl_input.Plo
+	-rm -f ./$(DEPDIR)/isl_int_sioimath.Plo
+	-rm -f ./$(DEPDIR)/isl_local.Plo
+	-rm -f ./$(DEPDIR)/isl_local_space.Plo
+	-rm -f ./$(DEPDIR)/isl_lp.Plo
+	-rm -f ./$(DEPDIR)/isl_map.Plo
+	-rm -f ./$(DEPDIR)/isl_map_list.Plo
+	-rm -f ./$(DEPDIR)/isl_map_simplify.Plo
+	-rm -f ./$(DEPDIR)/isl_map_subtract.Plo
+	-rm -f ./$(DEPDIR)/isl_map_to_basic_set.Plo
+	-rm -f ./$(DEPDIR)/isl_mat.Plo
+	-rm -f ./$(DEPDIR)/isl_morph.Plo
+	-rm -f ./$(DEPDIR)/isl_obj.Plo
+	-rm -f ./$(DEPDIR)/isl_options.Plo
+	-rm -f ./$(DEPDIR)/isl_output.Plo
+	-rm -f ./$(DEPDIR)/isl_point.Plo
+	-rm -f ./$(DEPDIR)/isl_polynomial.Plo
+	-rm -f ./$(DEPDIR)/isl_printer.Plo
+	-rm -f ./$(DEPDIR)/isl_range.Plo
+	-rm -f ./$(DEPDIR)/isl_reordering.Plo
+	-rm -f ./$(DEPDIR)/isl_sample.Plo
+	-rm -f ./$(DEPDIR)/isl_scan.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_band.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_constraints.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_node.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_read.Plo
+	-rm -f ./$(DEPDIR)/isl_schedule_tree.Plo
+	-rm -f ./$(DEPDIR)/isl_scheduler.Plo
+	-rm -f ./$(DEPDIR)/isl_seq.Plo
+	-rm -f ./$(DEPDIR)/isl_set_list.Plo
+	-rm -f ./$(DEPDIR)/isl_set_to_ast_graft_list.Plo
+	-rm -f ./$(DEPDIR)/isl_sort.Plo
+	-rm -f ./$(DEPDIR)/isl_space.Plo
+	-rm -f ./$(DEPDIR)/isl_stream.Plo
+	-rm -f ./$(DEPDIR)/isl_stride.Plo
+	-rm -f ./$(DEPDIR)/isl_tab.Plo
+	-rm -f ./$(DEPDIR)/isl_tab_pip.Plo
+	-rm -f ./$(DEPDIR)/isl_tarjan.Plo
+	-rm -f ./$(DEPDIR)/isl_test.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp-checked.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp.Po
+	-rm -f ./$(DEPDIR)/isl_test_imath.Po
+	-rm -f ./$(DEPDIR)/isl_test_int.Po
+	-rm -f ./$(DEPDIR)/isl_transitive_closure.Plo
+	-rm -f ./$(DEPDIR)/isl_union_map.Plo
+	-rm -f ./$(DEPDIR)/isl_val.Plo
+	-rm -f ./$(DEPDIR)/isl_val_gmp.Plo
+	-rm -f ./$(DEPDIR)/isl_val_imath.Plo
+	-rm -f ./$(DEPDIR)/isl_val_sioimath.Plo
+	-rm -f ./$(DEPDIR)/isl_vec.Plo
+	-rm -f ./$(DEPDIR)/isl_version.Plo
+	-rm -f ./$(DEPDIR)/isl_vertices.Plo
+	-rm -f ./$(DEPDIR)/mp_get_memory_functions.Plo
+	-rm -f ./$(DEPDIR)/pip.Po
+	-rm -f ./$(DEPDIR)/polyhedron_detect_equalities.Po
+	-rm -f ./$(DEPDIR)/polyhedron_minimize.Po
+	-rm -f ./$(DEPDIR)/polyhedron_sample.Po
+	-rm -f ./$(DEPDIR)/polytope_scan.Po
+	-rm -f ./$(DEPDIR)/print.Plo
+	-rm -f ./$(DEPDIR)/schedule.Po
+	-rm -f ./$(DEPDIR)/schedule_cmp.Po
+	-rm -f imath_wrap/$(DEPDIR)/gmp_compat.Plo
+	-rm -f imath_wrap/$(DEPDIR)/imath.Plo
+	-rm -f imath_wrap/$(DEPDIR)/imrat.Plo
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -2513,8 +2804,8 @@
 	install-strip
 
 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
-	am--refresh check check-TESTS check-am clean clean-cscope \
-	clean-generic clean-libLTLIBRARIES clean-libtool \
+	am--depfiles am--refresh check check-TESTS check-am clean \
+	clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \
 	clean-noinstLIBRARIES clean-noinstPROGRAMS cscope \
 	cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
 	dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \
diff --git a/lib/External/isl/aclocal.m4 b/lib/External/isl/aclocal.m4
index d889694..8600931 100644
--- a/lib/External/isl/aclocal.m4
+++ b/lib/External/isl/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+# Copyright (C) 2002-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15.1], [],
+m4_if([$1], [1.16.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +51,14 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -110,7 +110,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +141,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -332,13 +332,12 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@@ -346,49 +345,41 @@
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  AS_CASE([$CONFIG_FILES],
+          [*\'*], [eval set x "$CONFIG_FILES"],
+          [*], [set x $CONFIG_FILES])
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`AS_DIRNAME("$mf")`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`AS_DIRNAME(["$file"])`
-      AS_MKDIR_P([$dirpart/$fdir])
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`AS_DIRNAME(["$am_mf"])`
+    am_filepart=`AS_BASENAME(["$am_mf"])`
+    AM_RUN_LOG([cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles]) || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).])
+  fi
+  AS_UNSET([am_dirpart])
+  AS_UNSET([am_filepart])
+  AS_UNSET([am_mf])
+  AS_UNSET([am_rc])
+  rm -f conftest-deps.mk
 }
 ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
 
@@ -397,18 +388,17 @@
 # -----------------------------
 # This macro should only be invoked once -- use via AC_REQUIRE.
 #
-# This code is only required when automatic dependency tracking
-# is enabled.  FIXME.  This creates each '.P' file that we will
-# need in order to bootstrap the dependency handling code.
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
 AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 [AC_CONFIG_COMMANDS([depfiles],
      [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
-     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
+     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -495,8 +485,8 @@
 AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
 # We need awk for the "check" target (and possibly the TAP driver).  The
 # system "awk" is bad on some platforms.
@@ -563,7 +553,7 @@
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -605,7 +595,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -626,7 +616,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2017 Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -647,7 +637,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -655,49 +645,42 @@
 
 # AM_MAKE_INCLUDE()
 # -----------------
-# Check to see how make treats includes.
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
 AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
 am__doit:
-	@echo this is the am__doit target
+	@echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+  AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+      ['0:this is the am__doit target'],
+      [AS_CASE([$s],
+          [BSD], [am__include='.include' am__quote='"'],
+          [am__include='include' am__quote=''])])
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -736,7 +719,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -765,7 +748,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -812,7 +795,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -845,10 +828,12 @@
  [
   dnl Find a Python interpreter.  Python versions prior to 2.0 are not
   dnl supported. (2.0 was released on October 16, 2000).
-  dnl FIXME: Remove the need to hard-code Python versions here.
   m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
-[python python2 python3 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
- python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
+[python python2 python3 dnl
+ python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl
+ python3.2 python3.1 python3.0 dnl
+ python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl
+ python2.0])
 
   AC_ARG_VAR([PYTHON], [the Python interpreter])
 
@@ -1048,7 +1033,7 @@
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1067,7 +1052,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1148,7 +1133,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2017 Free Software Foundation, Inc.
+# Copyright (C) 2009-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1208,7 +1193,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1236,7 +1221,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2017 Free Software Foundation, Inc.
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1255,7 +1240,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2017 Free Software Foundation, Inc.
+# Copyright (C) 2004-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/lib/External/isl/check_single_reference_templ.c b/lib/External/isl/check_single_reference_templ.c
new file mode 100644
index 0000000..20970b4
--- /dev/null
+++ b/lib/External/isl/check_single_reference_templ.c
@@ -0,0 +1,19 @@
+#define xFN(TYPE,NAME) TYPE ## _ ## NAME
+#define FN(TYPE,NAME) xFN(TYPE,NAME)
+
+/* Check that "obj" has a single reference.
+ * That is, check that "obj" can be changed inplace.
+ */
+isl_stat FN(TYPE,check_single_reference)(__isl_keep TYPE *obj)
+{
+	isl_bool single;
+
+	single = FN(TYPE,has_single_reference)(obj);
+	if (single < 0)
+		return isl_stat_error;
+	if (!single)
+		isl_die(FN(TYPE,get_ctx)(obj), isl_error_invalid,
+			"object should have a single reference",
+			return isl_stat_error);
+	return isl_stat_ok;
+}
diff --git a/lib/External/isl/compile b/lib/External/isl/compile
index a85b723..99e5052 100755
--- a/lib/External/isl/compile
+++ b/lib/External/isl/compile
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand '-c -o'.
 
-scriptversion=2012-10-14.11; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -255,7 +255,8 @@
     echo "compile $scriptversion"
     exit $?
     ;;
-  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
+  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
     func_cl_wrapper "$@"      # Doesn't return...
     ;;
 esac
@@ -339,9 +340,9 @@
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/lib/External/isl/configure b/lib/External/isl/configure
index 8a7f777..211a648 100755
--- a/lib/External/isl/configure
+++ b/lib/External/isl/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for isl 0.22.1.
+# Generated by GNU Autoconf 2.69 for isl 0.23.
 #
 # Report bugs to <isl-development@googlegroups.com>.
 #
@@ -590,8 +590,8 @@
 # Identity of this package.
 PACKAGE_NAME='isl'
 PACKAGE_TARNAME='isl'
-PACKAGE_VERSION='0.22.1'
-PACKAGE_STRING='isl 0.22.1'
+PACKAGE_VERSION='0.23'
+PACKAGE_STRING='isl 0.23'
 PACKAGE_BUGREPORT='isl-development@googlegroups.com'
 PACKAGE_URL=''
 
@@ -734,7 +734,6 @@
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
-am__quote
 am__include
 DEPDIR
 OBJEXT
@@ -810,7 +809,8 @@
 PACKAGE_TARNAME
 PACKAGE_NAME
 PATH_SEPARATOR
-SHELL'
+SHELL
+am__quote'
 ac_subst_files=''
 ac_user_opts='
 enable_option_checking
@@ -1400,7 +1400,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures isl 0.22.1 to adapt to many kinds of systems.
+\`configure' configures isl 0.23 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1471,7 +1471,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of isl 0.22.1:";;
+     short | recursive ) echo "Configuration of isl 0.23:";;
    esac
   cat <<\_ACEOF
 
@@ -1602,7 +1602,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-isl configure 0.22.1
+isl configure 0.23
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2375,7 +2375,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by isl $as_me 0.22.1, which was
+It was created by isl $as_me 0.23, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2753,7 +2753,7 @@
 
 
 
-am__api_version='1.15'
+am__api_version='1.16'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -3239,7 +3239,7 @@
 
 # Define the identity of the package.
  PACKAGE='isl'
- VERSION='0.22.1'
+ VERSION='0.23'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3269,8 +3269,8 @@
 
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
 # We need awk for the "check" target (and possibly the TAP driver).  The
@@ -3321,7 +3321,7 @@
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -3372,7 +3372,7 @@
 AM_BACKSLASH='\'
 
 
-versioninfo=22:1:0
+versioninfo=23:0:0
 
 if test "x$prefix" != "xNONE"; then
 	prefix_wd=`cd $prefix && pwd`
@@ -4237,45 +4237,45 @@
 
 ac_config_commands="$ac_config_commands depfiles"
 
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
 am__doit:
-	@echo this is the am__doit target
+	@echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+   (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+  case $?:`cat confinc.out 2>/dev/null` in #(
+  '0:this is the am__doit target') :
+    case $s in #(
+  BSD) :
+    am__include='.include' am__quote='"' ;; #(
+  *) :
+    am__include='include' am__quote='' ;;
+esac ;; #(
+  *) :
      ;;
-   esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
+esac
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
 
 # Check whether --enable-dependency-tracking was given.
 if test "${enable_dependency_tracking+set}" = set; then :
@@ -9767,7 +9767,7 @@
 fi
 
 : ${AR=ar}
-: ${AR_FLAGS=cru}
+: ${AR_FLAGS=cr}
 
 
 
@@ -10268,11 +10268,8 @@
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
-  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
 	mv -f "$nlist"T "$nlist"
@@ -11491,8 +11488,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
-      echo "$AR cru libconftest.a conftest.o" >&5
-      $AR cru libconftest.a conftest.o 2>&5
+      echo "$AR cr libconftest.a conftest.o" >&5
+      $AR cr libconftest.a conftest.o 2>&5
       echo "$RANLIB libconftest.a" >&5
       $RANLIB libconftest.a 2>&5
       cat > conftest.c << _LT_EOF
@@ -12494,6 +12491,12 @@
 	lt_prog_compiler_pic='-KPIC'
 	lt_prog_compiler_static='-static'
         ;;
+      # flang / f18. f95 an alias for gfortran or flang on Debian
+      flang* | f18* | f95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -16436,7 +16439,7 @@
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -16928,7 +16931,7 @@
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -16993,7 +16996,7 @@
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
 	    if test yes = "$GXX"; then
@@ -17332,7 +17335,7 @@
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
 	    else
 	      # FIXME: insert proper C++ library support
@@ -17416,7 +17419,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
@@ -17427,7 +17430,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 	      fi
 
 	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -19482,7 +19485,7 @@
   $as_echo_n "(cached) " >&6
 else
 
-	for am_cv_pathless_PYTHON in python python2 python3 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7  python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
+	for am_cv_pathless_PYTHON in python python2 python3  python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3  python3.2 python3.1 python3.0  python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1  python2.0 none; do
 	  test "$am_cv_pathless_PYTHON" = none && break
 	  prog="import sys
 # split strings by '.' and convert to numeric.  Append some zeros
@@ -21762,7 +21765,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by isl $as_me 0.22.1, which was
+This file was extended by isl $as_me 0.23, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21828,7 +21831,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-isl config.status 0.22.1
+isl config.status 0.23
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -21947,7 +21950,7 @@
 #
 # INIT-COMMANDS
 #
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
 
 
 # The HP-UX ksh and POSIX shell print the target directory to stdout
@@ -22990,29 +22993,35 @@
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  case $CONFIG_FILES in #(
+  *\'*) :
+    eval set x "$CONFIG_FILES" ;; #(
+  *) :
+    set x $CONFIG_FILES ;; #(
+  *) :
+     ;;
+esac
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$mf" : 'X\(//\)[^/]' \| \
-	 X"$mf" : 'X\(//\)$' \| \
-	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$am_mf" : 'X\(//\)[^/]' \| \
+	 X"$am_mf" : 'X\(//\)$' \| \
+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -23030,53 +23039,48 @@
 	    q
 	  }
 	  s/.*/./; q'`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$file" : 'X\(//\)[^/]' \| \
-	 X"$file" : 'X\(//\)$' \| \
-	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+    am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$am_mf" : 'X\(//\)$' \| \
+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
 	  }
-	  /^X\(\/\/\)[^/].*/{
+	  /^X\/\(\/\/\)$/{
 	    s//\1/
 	    q
 	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
+	  /^X\/\(\/\).*/{
 	    s//\1/
 	    q
 	  }
 	  s/.*/./; q'`
-      as_dir=$dirpart/$fdir; as_fn_mkdir_p
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    { echo "$as_me:$LINENO: cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles" >&5
+   (cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+  { am_dirpart=; unset am_dirpart;}
+  { am_filepart=; unset am_filepart;}
+  { am_mf=; unset am_mf;}
+  { am_rc=; unset am_rc;}
+  rm -f conftest-deps.mk
 }
  ;;
     "libtool":C)
diff --git a/lib/External/isl/configure.ac b/lib/External/isl/configure.ac
index bd878e9..0e28a8c 100644
--- a/lib/External/isl/configure.ac
+++ b/lib/External/isl/configure.ac
@@ -1,10 +1,10 @@
-AC_INIT([isl], [0.22.1], [isl-development@googlegroups.com])
+AC_INIT([isl], [0.23], [isl-development@googlegroups.com])
 AC_CONFIG_AUX_DIR([.])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign])
 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 AC_SUBST(versioninfo)
-versioninfo=22:1:0
+versioninfo=23:0:0
 
 if test "x$prefix" != "xNONE"; then
 	prefix_wd=`cd $prefix && pwd`
diff --git a/lib/External/isl/depcomp b/lib/External/isl/depcomp
index b39f98f..65cbf70 100755
--- a/lib/External/isl/depcomp
+++ b/lib/External/isl/depcomp
@@ -1,9 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2016-01-11.22; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -783,7 +783,7 @@
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
 # time-stamp-time-zone: "UTC0"
diff --git a/lib/External/isl/doc/Makefile.in b/lib/External/isl/doc/Makefile.in
index 1b1f06a..5efda3a 100644
--- a/lib/External/isl/doc/Makefile.in
+++ b/lib/External/isl/doc/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -330,8 +330,8 @@
 	  *config.status*) \
 	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
 	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
 	esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -355,7 +355,10 @@
 cscope cscopelist:
 
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	list='$(DISTFILES)'; \
diff --git a/lib/External/isl/doc/user.pod b/lib/External/isl/doc/user.pod
index e7842bc..6d3d9a5 100644
--- a/lib/External/isl/doc/user.pod
+++ b/lib/External/isl/doc/user.pod
@@ -2725,6 +2725,8 @@
 	__isl_give isl_aff *isl_aff_var_on_domain(
 		__isl_take isl_local_space *ls,
 		enum isl_dim_type type, unsigned pos);
+	__isl_give isl_aff *isl_aff_nan_on_domain_space(
+		__isl_take isl_space *space);
 	__isl_give isl_aff *isl_aff_nan_on_domain(
 		__isl_take isl_local_space *ls);
 
@@ -3417,10 +3419,15 @@
 	__isl_give isl_pw_aff *isl_pw_aff_var_on_domain(
 		__isl_take isl_local_space *ls,
 		enum isl_dim_type type, unsigned pos);
+	__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space(
+		__isl_take isl_space *space);
 	__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(
 		__isl_take isl_local_space *ls);
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(
 		__isl_take isl_space *space);
+	__isl_give isl_pw_multi_aff *
+	isl_pw_multi_aff_identity_on_domain_space(
+		__isl_take isl_space *space)
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
 		__isl_take isl_space *space);
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map(
@@ -4019,6 +4026,10 @@
 	isl_union_pw_qpolynomial_read_from_str(
 		isl_ctx *ctx, const char *str);
 
+	__isl_give isl_pw_qpolynomial_fold *
+	isl_pw_qpolynomial_fold_read_from_str(
+		isl_ctx *ctx, const char *str);
+
 For sets and relations,
 the input format is autodetected and may be either the C<PolyLib> format
 or the C<isl> format.
@@ -5595,12 +5606,6 @@
 		__isl_take isl_map *map,
 		enum isl_dim_type type, unsigned pos,
 		__isl_take isl_val *value);
-	__isl_give isl_map *isl_map_lower_bound_multi_val(
-		__isl_take isl_map *map,
-		__isl_take isl_multi_val *lower);
-	__isl_give isl_map *isl_map_upper_bound_multi_val(
-		__isl_take isl_map *map,
-		__isl_take isl_multi_val *upper);
 	__isl_give isl_map *isl_map_lower_bound_multi_pw_aff(
 		__isl_take isl_map *map,
 		__isl_take isl_multi_pw_aff *lower);
@@ -5614,6 +5619,9 @@
 For functions taking a multi expression,
 this applies to all set dimensions.
 Those that bound a map, bound the range of that map.
+If the multi expression is zero-dimensional but has an explicit domain,
+then the (parameter) domain of the set or map is intersected
+with this explicit domain.
 
 	__isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
 		enum isl_dim_type type1, int pos1,
@@ -5775,6 +5783,16 @@
 The functions above construct a (basic, regular or union) relation
 that maps (a wrapped version of) the input relation to its delta set.
 
+=item * Translation
+
+	#include <isl/map.h>
+	__isl_give isl_map *isl_set_translation(
+		__isl_take isl_set *deltas);
+
+This function performs essentially the opposite operation
+of C<isl_map_deltas>.  In particular, it returns pairs
+of elements in the same space that have a difference in C<deltas>.
+
 =item * Coalescing
 
 Simplify the representation of a set, relation or functions by trying
@@ -6959,6 +6977,10 @@
 		__isl_take isl_map *map1,
 		__isl_take isl_map *map2);
 	__isl_give isl_map *
+	isl_map_intersect_domain_factor_domain(
+		__isl_take isl_map *map,
+		__isl_take isl_map *factor);
+	__isl_give isl_map *
 	isl_map_intersect_domain_factor_range(
 		__isl_take isl_map *map,
 		__isl_take isl_map *factor);
@@ -7009,6 +7031,10 @@
 		__isl_take isl_union_map *umap1,
 		__isl_take isl_union_map *umap2);
 	__isl_give isl_union_map *
+	isl_union_map_intersect_domain_factor_domain(
+		__isl_take isl_union_map *umap,
+		__isl_take isl_union_map *factor);
+	__isl_give isl_union_map *
 	isl_union_map_intersect_domain_factor_range(
 		__isl_take isl_union_map *umap,
 		__isl_take isl_union_map *factor);
@@ -7539,9 +7565,19 @@
 		__isl_take isl_union_map *umap,
 		__isl_take isl_union_pw_multi_aff *upma);
 
+	#include <isl/aff.h>
+	__isl_give isl_pw_multi_aff *
+	isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
+		__isl_take isl_pw_multi_aff *pma1,
+		__isl_take isl_pw_multi_aff *pma2);
+	__isl_give isl_union_pw_multi_aff *
+	isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(
+		__isl_take isl_union_pw_multi_aff *upma1,
+		__isl_take isl_union_pw_multi_aff *upma2);
+
 These functions compute the preimage of the given set or map domain/range under
 the given function.  In other words, the expression is plugged
-into the set description or into the domain/range of the map.
+into the set description or into the domain/range of the map or function.
 
 =item * Pullback
 
@@ -7765,12 +7801,20 @@
 		__isl_take isl_union_map *umap,
 		__isl_take isl_multi_union_pw_aff *mupa);
 	__isl_give isl_union_map *
+	isl_union_map_lex_le_at_multi_union_pw_aff(
+		__isl_take isl_union_map *umap,
+		__isl_take isl_multi_union_pw_aff *mupa);
+	__isl_give isl_union_map *
 	isl_union_map_lex_gt_at_multi_union_pw_aff(
 		__isl_take isl_union_map *umap,
 		__isl_take isl_multi_union_pw_aff *mupa);
+	__isl_give isl_union_map *
+	isl_union_map_lex_ge_at_multi_union_pw_aff(
+		__isl_take isl_union_map *umap,
+		__isl_take isl_multi_union_pw_aff *mupa);
 
 These functions select the subset of elements in the union map
-that have an equal or lexicographically smaller function value.
+that have an equal or lexicographically smaller or greater function value.
 
 =item * Cartesian Product
 
@@ -8886,7 +8930,7 @@
 C<isl_val>, C<isl_id>, C<isl_aff>, C<isl_pw_aff>, C<isl_pw_multi_aff>,
 C<isl_union_pw_aff>,
 C<isl_union_pw_multi_aff>,
-C<isl_pw_qpolynomial>, C<isl_pw_qpolynomial_fold>,
+C<isl_qpolynomial>, C<isl_pw_qpolynomial>, C<isl_pw_qpolynomial_fold>,
 C<isl_constraint>,
 C<isl_basic_set>, C<isl_set>, C<isl_basic_map>, C<isl_map>, C<isl_union_set>,
 C<isl_union_map>, C<isl_ast_expr> and C<isl_ast_node>.
diff --git a/lib/External/isl/imath/gmp_compat.c b/lib/External/isl/imath/gmp_compat.c
index fb45547..620c4ca 100644
--- a/lib/External/isl/imath/gmp_compat.c
+++ b/lib/External/isl/imath/gmp_compat.c
@@ -24,18 +24,20 @@
   SOFTWARE.
  */
 #include "gmp_compat.h"
-#include <stdlib.h>
 #include <assert.h>
 #include <ctype.h>
-#include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #if defined(_MSC_VER)
 #include <BaseTsd.h>
 typedef SSIZE_T ssize_t;
+#else
+#include <sys/types.h>
 #endif
 
-#ifdef  NDEBUG
+#ifdef NDEBUG
 #define CHECK(res) (res)
 #else
 #define CHECK(res) assert(((res) == MP_OK) && "expected MP_OK")
@@ -53,34 +55,24 @@
  *
  *************************************************************************/
 /* gmp: mpq_clear */
-void GMPQAPI(clear)(mp_rat x) {
-  mp_rat_clear(x);
-}
+void GMPQAPI(clear)(mp_rat x) { mp_rat_clear(x); }
 
 /* gmp: mpq_cmp */
-int GMPQAPI(cmp)(mp_rat op1, mp_rat op2) {
-  return mp_rat_compare(op1, op2);
-}
+int GMPQAPI(cmp)(mp_rat op1, mp_rat op2) { return mp_rat_compare(op1, op2); }
 
 /* gmp: mpq_init */
-void GMPQAPI(init)(mp_rat x) {
-  CHECK(mp_rat_init(x));
-}
+void GMPQAPI(init)(mp_rat x) { CHECK(mp_rat_init(x)); }
 
 /* gmp: mpq_mul */
 void GMPQAPI(mul)(mp_rat product, mp_rat multiplier, mp_rat multiplicand) {
   CHECK(mp_rat_mul(multiplier, multiplicand, product));
 }
 
-/* gmp: mpq_set*/
-void GMPQAPI(set)(mp_rat rop, mp_rat op) {
-  CHECK(mp_rat_copy(op, rop));
-}
+/* gmp: mpq_set */
+void GMPQAPI(set)(mp_rat rop, mp_rat op) { CHECK(mp_rat_copy(op, rop)); }
 
 /* gmp: mpz_abs */
-void GMPZAPI(abs)(mp_int rop, mp_int op) {
-  CHECK(mp_int_abs(op, rop));
-}
+void GMPZAPI(abs)(mp_int rop, mp_int op) { CHECK(mp_int_abs(op, rop)); }
 
 /* gmp: mpz_add */
 void GMPZAPI(add)(mp_int rop, mp_int op1, mp_int op2) {
@@ -88,9 +80,7 @@
 }
 
 /* gmp: mpz_clear */
-void GMPZAPI(clear)(mp_int x) {
-  mp_int_clear(x);
-}
+void GMPZAPI(clear)(mp_int x) { mp_int_clear(x); }
 
 /* gmp: mpz_cmp_si */
 int GMPZAPI(cmp_si)(mp_int op1, long op2) {
@@ -103,14 +93,10 @@
 }
 
 /* gmp: mpz_cmp */
-int GMPZAPI(cmp)(mp_int op1, mp_int op2) {
-  return mp_int_compare(op1, op2);
-}
+int GMPZAPI(cmp)(mp_int op1, mp_int op2) { return mp_int_compare(op1, op2); }
 
 /* gmp: mpz_init */
-void GMPZAPI(init)(mp_int x) {
-  CHECK(mp_int_init(x));
-}
+void GMPZAPI(init)(mp_int x) { CHECK(mp_int_init(x)); }
 
 /* gmp: mpz_mul */
 void GMPZAPI(mul)(mp_int rop, mp_int op1, mp_int op2) {
@@ -118,19 +104,13 @@
 }
 
 /* gmp: mpz_neg */
-void GMPZAPI(neg)(mp_int rop, mp_int op) {
-  CHECK(mp_int_neg(op, rop));
-}
+void GMPZAPI(neg)(mp_int rop, mp_int op) { CHECK(mp_int_neg(op, rop)); }
 
 /* gmp: mpz_set_si */
-void GMPZAPI(set_si)(mp_int rop, long op) {
-  CHECK(mp_int_set_value(rop, op));
-}
+void GMPZAPI(set_si)(mp_int rop, long op) { CHECK(mp_int_set_value(rop, op)); }
 
 /* gmp: mpz_set */
-void GMPZAPI(set)(mp_int rop, mp_int op) {
-  CHECK(mp_int_copy(op, rop));
-}
+void GMPZAPI(set)(mp_int rop, mp_int op) { CHECK(mp_int_copy(op, rop)); }
 
 /* gmp: mpz_sub */
 void GMPZAPI(sub)(mp_int rop, mp_int op1, mp_int op2) {
@@ -138,19 +118,13 @@
 }
 
 /* gmp: mpz_swap */
-void GMPZAPI(swap)(mp_int rop1, mp_int rop2) {
-  mp_int_swap(rop1, rop2);
-}
+void GMPZAPI(swap)(mp_int rop1, mp_int rop2) { mp_int_swap(rop1, rop2); }
 
 /* gmp: mpq_sgn */
-int GMPQAPI(sgn)(mp_rat op) {
-  return mp_rat_compare_zero(op);
-}
+int GMPQAPI(sgn)(mp_rat op) { return mp_rat_compare_zero(op); }
 
 /* gmp: mpz_sgn */
-int GMPZAPI(sgn)(mp_int op) {
-  return mp_int_compare_zero(op);
-}
+int GMPZAPI(sgn)(mp_int op) { return mp_int_compare_zero(op); }
 
 /* gmp: mpq_set_ui */
 void GMPQAPI(set_ui)(mp_rat rop, unsigned long op1, unsigned long op2) {
@@ -163,25 +137,18 @@
 }
 
 /* gmp: mpq_den_ref */
-mp_int GMPQAPI(denref)(mp_rat op) {
-  return mp_rat_denom_ref(op);
-}
+mp_int GMPQAPI(denref)(mp_rat op) { return mp_rat_denom_ref(op); }
 
 /* gmp: mpq_num_ref */
-mp_int GMPQAPI(numref)(mp_rat op) {
-  return mp_rat_numer_ref(op);
-}
+mp_int GMPQAPI(numref)(mp_rat op) { return mp_rat_numer_ref(op); }
 
 /* gmp: mpq_canonicalize */
-void GMPQAPI(canonicalize)(mp_rat op) {
-  CHECK(mp_rat_reduce(op));
-}
+void GMPQAPI(canonicalize)(mp_rat op) { CHECK(mp_rat_reduce(op)); }
 
-/*************************************************************************
- *
+/*
  * Functions that can be implemented as a combination of imath functions
- *
- *************************************************************************/
+ */
+
 /* gmp: mpz_addmul */
 /* gmp: rop = rop + (op1 * op2) */
 void GMPZAPI(addmul)(mp_int rop, mp_int op1, mp_int op2) {
@@ -212,8 +179,7 @@
   /* check for d = 0 */
   int n_is_zero = mp_int_compare_zero(n) == 0;
   int d_is_zero = mp_int_compare_zero(d) == 0;
-  if (d_is_zero)
-    return n_is_zero;
+  if (d_is_zero) return n_is_zero;
 
   /* return true if remainder is 0 */
   CHECK(mp_int_init(r));
@@ -320,13 +286,12 @@
 }
 
 /* gmp: mpz_get_str */
-char* GMPZAPI(get_str)(char *str, int radix, mp_int op) {
+char *GMPZAPI(get_str)(char *str, int radix, mp_int op) {
   int i, r, len;
 
   /* Support negative radix like gmp */
   r = radix;
-  if (r < 0)
-    r = -r;
+  if (r < 0) r = -r;
 
   /* Compute the length of the string needed to hold the int */
   len = mp_int_string_len(op, r);
@@ -338,16 +303,18 @@
   CHECK(mp_int_to_string(op, r, str, len));
 
   /* Change case to match gmp */
-  for (i = 0; i < len - 1; i++)
-    if (radix < 0)
+  for (i = 0; i < len - 1; i++) {
+    if (radix < 0) {
       str[i] = toupper(str[i]);
-    else
+    } else {
       str[i] = tolower(str[i]);
+    }
+  }
   return str;
 }
 
 /* gmp: mpq_get_str */
-char* GMPQAPI(get_str)(char *str, int radix, mp_rat op) {
+char *GMPQAPI(get_str)(char *str, int radix, mp_rat op) {
   int i, r, len;
 
   /* Only print numerator if it is a whole number */
@@ -356,8 +323,7 @@
 
   /* Support negative radix like gmp */
   r = radix;
-  if (r < 0)
-    r = -r;
+  if (r < 0) r = -r;
 
   /* Compute the length of the string needed to hold the int */
   len = mp_rat_string_len(op, r);
@@ -369,11 +335,13 @@
   CHECK(mp_rat_to_string(op, r, str, len));
 
   /* Change case to match gmp */
-  for (i = 0; i < len; i++)
-    if (radix < 0)
+  for (i = 0; i < len; i++) {
+    if (radix < 0) {
       str[i] = toupper(str[i]);
-    else
+    } else {
       str[i] = tolower(str[i]);
+    }
+  }
 
   return str;
 }
@@ -393,26 +361,27 @@
   int res = 0;
 
   /* Copy string to temporary storage so we can modify it below */
-  str = malloc(strlen(s)+1);
+  str = malloc(strlen(s) + 1);
   strcpy(str, s);
 
   /* Properly format the string as an int by terminating at the / */
   slash = strchr(str, '/');
-  if (slash)
-    *slash = '\0';
+  if (slash) *slash = '\0';
 
   /* Parse numerator */
   resN = mp_int_read_string(mp_rat_numer_ref(rop), base, str);
 
-  /* Parse denomenator if given or set to 1 if not */
-  if (slash)
-    resD = mp_int_read_string(mp_rat_denom_ref(rop), base, slash+1);
-  else
+  /* Parse denominator if given or set to 1 if not */
+  if (slash) {
+    resD = mp_int_read_string(mp_rat_denom_ref(rop), base, slash + 1);
+  } else {
     resD = mp_int_set_uvalue(mp_rat_denom_ref(rop), 1);
+  }
 
   /* Return failure if either parse failed */
-  if (resN != MP_OK || resD != MP_OK)
+  if (resN != MP_OK || resD != MP_OK) {
     res = -1;
+  }
 
   free(str);
   return res;
@@ -423,18 +392,24 @@
    * the least significant digits that will fit into the long.  Read the digits
    * into the long starting at the most significant digit that fits into a
    * long. The long is shifted over by MP_DIGIT_BIT before each digit is added.
-   * The shift is decomposed into two steps to follow the patten used in the
-   * rest of the imath library. The two step shift is used to accomedate
-   * architectures that don't deal well with 32-bit shifts. */
-  mp_size num_digits_in_long = sizeof(unsigned long) / sizeof(mp_digit);
+   *
+   * The shift is decomposed into two steps (following the pattern used in the
+   * rest of the imath library) to accommodate architectures that don't deal
+   * well with 32-bit shifts.
+   */
+  mp_size digits_to_copy =
+      (sizeof(unsigned long) + sizeof(mp_digit) - 1) / sizeof(mp_digit);
+  if (digits_to_copy > MP_USED(op)) {
+    digits_to_copy = MP_USED(op);
+  }
+
   mp_digit *digits = MP_DIGITS(op);
   unsigned long out = 0;
-  int i;
 
-  for (i = num_digits_in_long - 1; i >= 0; i--) {
-    out <<= (MP_DIGIT_BIT/2);
-    out <<= (MP_DIGIT_BIT/2);
-    out  |= digits[i];
+  for (int i = digits_to_copy - 1; i >= 0; i--) {
+    out <<= (MP_DIGIT_BIT / 2);
+    out <<= (MP_DIGIT_BIT / 2);
+    out |= digits[i];
   }
 
   return out;
@@ -446,14 +421,12 @@
 
   /* Try a standard conversion that fits into an unsigned long */
   mp_result res = mp_int_to_uint(op, &out);
-  if (res == MP_OK)
-    return out;
+  if (res == MP_OK) return out;
 
   /* Abort the try if we don't have a range error in the conversion.
    * The range error indicates that the value cannot fit into a long. */
   CHECK(res == MP_RANGE ? MP_OK : MP_RANGE);
-  if (res != MP_RANGE)
-    return 0;
+  if (res != MP_RANGE) return 0;
 
   return get_long_bits(op);
 }
@@ -466,14 +439,12 @@
 
   /* Try a standard conversion that fits into a long */
   mp_result res = mp_int_to_int(op, &out);
-  if (res == MP_OK)
-    return out;
+  if (res == MP_OK) return out;
 
   /* Abort the try if we don't have a range error in the conversion.
    * The range error indicates that the value cannot fit into a long. */
   CHECK(res == MP_RANGE ? MP_OK : MP_RANGE);
-  if (res != MP_RANGE)
-    return 0;
+  if (res != MP_RANGE) return 0;
 
   /* get least significant bits into an unsigned long */
   uout = get_long_bits(op);
@@ -483,10 +454,11 @@
   uout &= (~(1UL << long_msb));
 
   /* convert to negative if needed based on sign of op */
-  if (MP_SIGN(op) == MP_NEG)
+  if (MP_SIGN(op) == MP_NEG) {
     uout = 0 - uout;
+  }
 
-  out = (long) uout;
+  out = (long)uout;
   return out;
 }
 
@@ -513,11 +485,9 @@
     CHECK(mp_int_mul_pow2(op1, op2, rop));
 }
 
-/*************************************************************************
- *
+/*
  * Functions needing expanded functionality
- *
- *************************************************************************/
+ */
 /* [Note]Overview of division implementation
 
     All division operations (N / D) compute q and r such that
@@ -578,9 +548,8 @@
     if (rsign != 0) { /* r != 0 */
       CHECK(mp_int_add_value(q, 1, q));
     }
-  }
-  else if (qsign == 0) { /* q == 0 */
-    if (rsign != 0) {    /* r != 0 */
+  } else if (qsign == 0) { /* q == 0 */
+    if (rsign != 0) {      /* r != 0 */
       if ((nsign > 0 && dsign > 0) || (nsign < 0 && dsign < 0)) {
         CHECK(mp_int_set_value(q, 1));
       }
@@ -610,9 +579,8 @@
     if (rsign != 0) { /* r != 0 */
       CHECK(mp_int_sub_value(q, 1, q));
     }
-  }
-  else if (qsign == 0) { /* q == 0 */
-    if (rsign != 0) {    /* r != 0 */
+  } else if (qsign == 0) { /* q == 0 */
+    if (rsign != 0) {      /* r != 0 */
       if ((nsign < 0 && dsign > 0) || (nsign > 0 && dsign < 0)) {
         CHECK(mp_int_set_value(q, -1));
       }
@@ -684,31 +652,32 @@
 }
 
 /* gmp: mpz_export */
-void* GMPZAPI(export)(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, mp_int op) {
-  int i, j;
-  int num_used_bytes;
+void *GMPZAPI(export)(void *rop, size_t *countp, int order, size_t size,
+                      int endian, size_t nails, mp_int op) {
+  size_t i, j;
+  size_t num_used_bytes;
   size_t num_words, num_missing_bytes;
   ssize_t word_offset;
-  unsigned char* dst;
-  mp_digit* src;
+  unsigned char *dst;
+  mp_digit *src;
   int src_bits;
 
   /* We do not have a complete implementation. Assert to ensure our
-   * restrictions are in place. */
-  assert(nails  == 0 && "Do not support non-full words");
+   * restrictions are in place.
+   */
+  assert(nails == 0 && "Do not support non-full words");
   assert(endian == 1 || endian == 0 || endian == -1);
   assert(order == 1 || order == -1);
 
   /* Test for zero */
   if (mp_int_compare_zero(op) == 0) {
-    if (countp)
-      *countp = 0;
+    if (countp) *countp = 0;
     return rop;
   }
 
   /* Calculate how many words we need */
-  num_used_bytes  = mp_int_unsigned_len(op);
-  num_words       = (num_used_bytes + (size-1)) / size; /* ceil division */
+  num_used_bytes = mp_int_unsigned_len(op);
+  num_words = (num_used_bytes + (size - 1)) / size; /* ceil division */
   assert(num_used_bytes > 0);
 
   /* Check to see if we will have missing bytes in the last word.
@@ -720,7 +689,7 @@
      pad the word with extra zeros. Otherwise, the missing bytes can be filled
      directly from the zeros in the last digit in the number.
    */
-  num_missing_bytes   = (size * num_words) - num_used_bytes;
+  num_missing_bytes = (size * num_words) - num_used_bytes;
   assert(num_missing_bytes < size);
 
   /* Allocate space for the result if needed */
@@ -733,7 +702,8 @@
   }
 
   /* Initialize dst and src pointers */
-  dst = (unsigned char *) rop + (order >= 0 ? (num_words-1) * size : 0) + (endian >= 0 ? size-1 : 0);
+  dst = (unsigned char *)rop + (order >= 0 ? (num_words - 1) * size : 0) +
+        (endian >= 0 ? size - 1 : 0);
   src = MP_DIGITS(op);
   src_bits = MP_DIGIT_BIT;
 
@@ -756,13 +726,13 @@
     dst += word_offset;
   }
 
-  if (countp)
-    *countp = num_words;
+  if (countp) *countp = num_words;
   return rop;
 }
 
 /* gmp: mpz_import */
-void GMPZAPI(import)(mp_int rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op) {
+void GMPZAPI(import)(mp_int rop, size_t count, int order, size_t size,
+                     int endian, size_t nails, const void *op) {
   mpz_t tmpz;
   mp_int tmp = &tmpz;
   size_t total_size;
@@ -771,13 +741,12 @@
   const unsigned char *src;
   mp_digit *dst;
   int dst_bits;
-  int i, j;
-  if (count == 0 || op == NULL)
-    return;
+  size_t i, j;
+  if (count == 0 || op == NULL) return;
 
   /* We do not have a complete implementation. Assert to ensure our
    * restrictions are in place. */
-  assert(nails  == 0 && "Do not support non-full words");
+  assert(nails == 0 && "Do not support non-full words");
   assert(endian == 1 || endian == 0 || endian == -1);
   assert(order == 1 || order == -1);
 
@@ -791,11 +760,11 @@
 
   /* Init temporary */
   mp_int_init_size(tmp, num_digits);
-  for (i = 0; i < num_digits; i++)
-    tmp->digits[i] = 0;
+  for (i = 0; i < num_digits; i++) tmp->digits[i] = 0;
 
   /* Copy bytes */
-  src = (const unsigned char *) op + (order >= 0 ? (count-1) * size : 0) + (endian >= 0 ? size-1 : 0);
+  src = (const unsigned char *)op + (order >= 0 ? (count - 1) * size : 0) +
+        (endian >= 0 ? size - 1 : 0);
   dst = MP_DIGITS(tmp);
   dst_bits = 0;
 
@@ -814,15 +783,14 @@
     src += word_offset;
   }
 
-  MP_USED(tmp) = num_digits;
+  tmp->used = num_digits;
 
   /* Remove leading zeros from number */
   {
-    mp_size uz_   = MP_USED(tmp);
-    mp_digit *dz_ = MP_DIGITS(tmp) + uz_ -1;
-    while (uz_ > 1 && (*dz_-- == 0))
-      --uz_;
-    MP_USED(tmp) = uz_;
+    mp_size uz_ = tmp->used;
+    mp_digit *dz_ = MP_DIGITS(tmp) + uz_ - 1;
+    while (uz_ > 1 && (*dz_-- == 0)) --uz_;
+    tmp->used = uz_;
   }
 
   /* Copy to destination */
@@ -836,8 +804,7 @@
   size_t size;
 
   /* If op == 0, return 1 */
-  if (mp_int_compare_zero(op) == 0)
-    return 1;
+  if (mp_int_compare_zero(op) == 0) return 1;
 
   /* Compute string length in base */
   res = mp_int_string_len(op, base);
@@ -850,8 +817,7 @@
   size -= 1;
 
   /* subtract one for the negative sign */
-  if (mp_int_compare_zero(op) < 0)
-    size -= 1;
+  if (mp_int_compare_zero(op) < 0) size -= 1;
 
   return size;
 }
diff --git a/lib/External/isl/imath/imath.c b/lib/External/isl/imath/imath.c
index be99305..26dc91f 100644
--- a/lib/External/isl/imath/imath.c
+++ b/lib/External/isl/imath/imath.c
@@ -1,7 +1,7 @@
 /*
   Name:     imath.c
   Purpose:  Arbitrary precision integer arithmetic routines.
-  Author:   M. J. Fromberger <http://spinning-yarns.org/michael/>
+  Author:   M. J. Fromberger
 
   Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
 
@@ -26,51 +26,29 @@
 
 #include "imath.h"
 
-#if DEBUG
-#include <stdio.h>
-#endif
-
+#include <assert.h>
+#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 
-#include <assert.h>
-
-#if DEBUG
-#define STATIC /* public */
-#else
-#define STATIC static
-#endif
-
-const mp_result MP_OK     = 0;  /* no error, all is well  */
-const mp_result MP_FALSE  = 0;  /* boolean false          */
-const mp_result MP_TRUE   = -1; /* boolean true           */
+const mp_result MP_OK = 0;      /* no error, all is well  */
+const mp_result MP_FALSE = 0;   /* boolean false          */
+const mp_result MP_TRUE = -1;   /* boolean true           */
 const mp_result MP_MEMORY = -2; /* out of memory          */
-const mp_result MP_RANGE  = -3; /* argument out of range  */
-const mp_result MP_UNDEF  = -4; /* result undefined       */
-const mp_result MP_TRUNC  = -5; /* output truncated       */
+const mp_result MP_RANGE = -3;  /* argument out of range  */
+const mp_result MP_UNDEF = -4;  /* result undefined       */
+const mp_result MP_TRUNC = -5;  /* output truncated       */
 const mp_result MP_BADARG = -6; /* invalid null argument  */
 const mp_result MP_MINERR = -6;
 
-const mp_sign   MP_NEG  = 1;    /* value is strictly negative */
-const mp_sign   MP_ZPOS = 0;    /* value is non-negative      */
+const mp_sign MP_NEG = 1;  /* value is strictly negative */
+const mp_sign MP_ZPOS = 0; /* value is non-negative      */
 
-STATIC const char *s_unknown_err = "unknown result code";
-STATIC const char *s_error_msg[] = {
-  "error code 0",
-  "boolean true",
-  "out of memory",
-  "argument out of range",
-  "result undefined",
-  "output truncated",
-  "invalid argument",
-  NULL
-};
-
-/* Argument checking macros
-   Use CHECK() where a return value is required; NRCHECK() elsewhere */
-#define CHECK(TEST)   assert(TEST)
-#define NRCHECK(TEST) assert(TEST)
+static const char *s_unknown_err = "unknown result code";
+static const char *s_error_msg[] = {"error code 0",     "boolean true",
+                                    "out of memory",    "argument out of range",
+                                    "result undefined", "output truncated",
+                                    "invalid argument", NULL};
 
 /* The ith entry of this table gives the value of log_i(2).
 
@@ -83,548 +61,538 @@
 
    If MP_MAX_RADIX is increased, this table should be expanded too.
  */
-STATIC const double s_log2[] = {
-   0.000000000, 0.000000000, 1.000000000, 0.630929754, 	/* (D)(D) 2  3 */
-   0.500000000, 0.430676558, 0.386852807, 0.356207187, 	/*  4  5  6  7 */
-   0.333333333, 0.315464877, 0.301029996, 0.289064826, 	/*  8  9 10 11 */
-   0.278942946, 0.270238154, 0.262649535, 0.255958025, 	/* 12 13 14 15 */
-   0.250000000, 0.244650542, 0.239812467, 0.235408913, 	/* 16 17 18 19 */
-   0.231378213, 0.227670249, 0.224243824, 0.221064729, 	/* 20 21 22 23 */
-   0.218104292, 0.215338279, 0.212746054, 0.210309918, 	/* 24 25 26 27 */
-   0.208014598, 0.205846832, 0.203795047, 0.201849087, 	/* 28 29 30 31 */
-   0.200000000, 0.198239863, 0.196561632, 0.194959022, 	/* 32 33 34 35 */
-   0.193426404,                                         /* 36          */
+static const double s_log2[] = {
+    0.000000000, 0.000000000, 1.000000000, 0.630929754, /* (D)(D) 2  3 */
+    0.500000000, 0.430676558, 0.386852807, 0.356207187, /*  4  5  6  7 */
+    0.333333333, 0.315464877, 0.301029996, 0.289064826, /*  8  9 10 11 */
+    0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */
+    0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */
+    0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */
+    0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */
+    0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */
+    0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */
+    0.193426404,                                        /* 36          */
 };
 
-
-
 /* Return the number of digits needed to represent a static value */
 #define MP_VALUE_DIGITS(V) \
-((sizeof(V)+(sizeof(mp_digit)-1))/sizeof(mp_digit))
+  ((sizeof(V) + (sizeof(mp_digit) - 1)) / sizeof(mp_digit))
 
 /* Round precision P to nearest word boundary */
-#define ROUND_PREC(P) ((mp_size)(2*(((P)+1)/2)))
+static inline mp_size s_round_prec(mp_size P) { return 2 * ((P + 1) / 2); }
 
 /* Set array P of S digits to zero */
-#define ZERO(P, S) \
-do{ \
-  mp_size i__ = (S) * sizeof(mp_digit); \
-  mp_digit *p__ = (P); \
-  memset(p__, 0, i__); \
-} while(0)
+static inline void ZERO(mp_digit *P, mp_size S) {
+  mp_size i__ = S * sizeof(mp_digit);
+  mp_digit *p__ = P;
+  memset(p__, 0, i__);
+}
 
 /* Copy S digits from array P to array Q */
-#define COPY(P, Q, S) \
-do{ \
-  mp_size i__ = (S) * sizeof(mp_digit); \
-  mp_digit *p__ = (P), *q__ = (Q); \
-  memcpy(q__, p__, i__); \
-} while(0)
+static inline void COPY(mp_digit *P, mp_digit *Q, mp_size S) {
+  mp_size i__ = S * sizeof(mp_digit);
+  mp_digit *p__ = P;
+  mp_digit *q__ = Q;
+  memcpy(q__, p__, i__);
+}
 
-/* Reverse N elements of type T in array A */
-#define REV(T, A, N) \
-do{ \
-  T *u_ = (A), *v_ = u_ + (N) - 1; \
-  while (u_ < v_) { \
-    T xch = *u_; \
-    *u_++ = *v_; \
-    *v_-- = xch; \
-  } \
-} while(0)
+/* Reverse N elements of unsigned char in A. */
+static inline void REV(unsigned char *A, int N) {
+  unsigned char *u_ = A;
+  unsigned char *v_ = u_ + N - 1;
+  while (u_ < v_) {
+    unsigned char xch = *u_;
+    *u_++ = *v_;
+    *v_-- = xch;
+  }
+}
 
-#define CLAMP(Z) \
-do{ \
-  mp_int z_ = (Z); \
-  mp_size uz_ = MP_USED(z_); \
-  mp_digit *dz_ = MP_DIGITS(z_) + uz_ -1; \
-  while (uz_ > 1 && (*dz_-- == 0)) \
-    --uz_; \
-  MP_USED(z_) = uz_; \
-} while(0)
+/* Strip leading zeroes from z_ in-place. */
+static inline void CLAMP(mp_int z_) {
+  mp_size uz_ = MP_USED(z_);
+  mp_digit *dz_ = MP_DIGITS(z_) + uz_ - 1;
+  while (uz_ > 1 && (*dz_-- == 0)) --uz_;
+  z_->used = uz_;
+}
 
-/* Select min/max.  Do not provide expressions for which multiple
-   evaluation would be problematic, e.g. x++ */
-#define MIN(A, B) ((B)<(A)?(B):(A))
-#define MAX(A, B) ((B)>(A)?(B):(A))
+/* Select min/max. */
+static inline int MIN(int A, int B) { return (B < A ? B : A); }
+static inline mp_size MAX(mp_size A, mp_size B) { return (B > A ? B : A); }
 
 /* Exchange lvalues A and B of type T, e.g.
    SWAP(int, x, y) where x and y are variables of type int. */
 #define SWAP(T, A, B) \
-do{ \
-  T t_ = (A); \
-  A = (B); \
-  B = t_; \
-} while(0)
+  do {                \
+    T t_ = (A);       \
+    A = (B);          \
+    B = t_;           \
+  } while (0)
 
-/* Used to set up and access simple temp stacks within functions. */
-#define DECLARE_TEMP(N) \
-  mpz_t temp[(N)]; \
-  int last__ = 0
-#define CLEANUP_TEMP() \
- CLEANUP: \
-  while (--last__ >= 0) \
-    mp_int_clear(TEMP(last__))
-#define TEMP(K) (temp + (K))
-#define LAST_TEMP() TEMP(last__)
-#define SETUP(E) \
-do{ \
-  if ((res = (E)) != MP_OK) \
-    goto CLEANUP; \
-  ++(last__); \
-} while(0)
+/* Declare a block of N temporary mpz_t values.
+   These values are initialized to zero.
+   You must add CLEANUP_TEMP() at the end of the function.
+   Use TEMP(i) to access a pointer to the ith value.
+ */
+#define DECLARE_TEMP(N)                   \
+  struct {                                \
+    mpz_t value[(N)];                     \
+    int len;                              \
+    mp_result err;                        \
+  } temp_ = {                             \
+      .len = (N),                         \
+      .err = MP_OK,                       \
+  };                                      \
+  do {                                    \
+    for (int i = 0; i < temp_.len; i++) { \
+      mp_int_init(TEMP(i));               \
+    }                                     \
+  } while (0)
+
+/* Clear all allocated temp values. */
+#define CLEANUP_TEMP()                    \
+  CLEANUP:                                \
+  do {                                    \
+    for (int i = 0; i < temp_.len; i++) { \
+      mp_int_clear(TEMP(i));              \
+    }                                     \
+    if (temp_.err != MP_OK) {             \
+      return temp_.err;                   \
+    }                                     \
+  } while (0)
+
+/* A pointer to the kth temp value. */
+#define TEMP(K) (temp_.value + (K))
+
+/* Evaluate E, an expression of type mp_result expected to return MP_OK.  If
+   the value is not MP_OK, the error is cached and control resumes at the
+   cleanup handler, which returns it.
+*/
+#define REQUIRE(E)                        \
+  do {                                    \
+    temp_.err = (E);                      \
+    if (temp_.err != MP_OK) goto CLEANUP; \
+  } while (0)
 
 /* Compare value to zero. */
-#define CMPZ(Z) \
-(((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1)
+static inline int CMPZ(mp_int Z) {
+  if (Z->used == 1 && Z->digits[0] == 0) return 0;
+  return (Z->sign == MP_NEG) ? -1 : 1;
+}
 
-/* Multiply X by Y into Z, ignoring signs.  Requires that Z have
-   enough storage preallocated to hold the result. */
-#define UMUL(X, Y, Z) \
-do{ \
-  mp_size ua_ = MP_USED(X), ub_ = MP_USED(Y); \
-  mp_size o_ = ua_ + ub_; \
-  ZERO(MP_DIGITS(Z), o_); \
-  (void) s_kmul(MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_); \
-  MP_USED(Z) = o_; \
-  CLAMP(Z); \
-} while(0)
+static inline mp_word UPPER_HALF(mp_word W) { return (W >> MP_DIGIT_BIT); }
+static inline mp_digit LOWER_HALF(mp_word W) { return (mp_digit)(W); }
 
-/* Square X into Z.  Requires that Z have enough storage to hold the
-   result. */
-#define USQR(X, Z) \
-do{ \
-  mp_size ua_ = MP_USED(X), o_ = ua_ + ua_; \
-  ZERO(MP_DIGITS(Z), o_); \
-  (void) s_ksqr(MP_DIGITS(X), MP_DIGITS(Z), ua_); \
-  MP_USED(Z) = o_; \
-  CLAMP(Z); \
-} while(0)
+/* Report whether the highest-order bit of W is 1. */
+static inline bool HIGH_BIT_SET(mp_word W) {
+  return (W >> (MP_WORD_BIT - 1)) != 0;
+}
 
-#define UPPER_HALF(W)           ((mp_word)((W) >> MP_DIGIT_BIT))
-#define LOWER_HALF(W)           ((mp_digit)(W))
-#define HIGH_BIT_SET(W)         ((W) >> (MP_WORD_BIT - 1))
-#define ADD_WILL_OVERFLOW(W, V) ((MP_WORD_MAX - (V)) < (W))
-
-
+/* Report whether adding W + V will carry out. */
+static inline bool ADD_WILL_OVERFLOW(mp_word W, mp_word V) {
+  return ((MP_WORD_MAX - V) < W);
+}
 
 /* Default number of digits allocated to a new mp_int */
-#if IMATH_TEST
-mp_size default_precision = MP_DEFAULT_PREC;
-#else
-STATIC const mp_size default_precision = MP_DEFAULT_PREC;
-#endif
+static mp_size default_precision = 8;
+
+void mp_int_default_precision(mp_size size) {
+  assert(size > 0);
+  default_precision = size;
+}
 
 /* Minimum number of digits to invoke recursive multiply */
-#if IMATH_TEST
-mp_size multiply_threshold = MP_MULT_THRESH;
-#else
-STATIC const mp_size multiply_threshold = MP_MULT_THRESH;
-#endif
+static mp_size multiply_threshold = 32;
+
+void mp_int_multiply_threshold(mp_size thresh) {
+  assert(thresh >= sizeof(mp_word));
+  multiply_threshold = thresh;
+}
 
 /* Allocate a buffer of (at least) num digits, or return
    NULL if that couldn't be done.  */
-STATIC mp_digit *s_alloc(mp_size num);
+static mp_digit *s_alloc(mp_size num);
 
 /* Release a buffer of digits allocated by s_alloc(). */
-STATIC void s_free(void *ptr);
+static void s_free(void *ptr);
 
 /* Insure that z has at least min digits allocated, resizing if
    necessary.  Returns true if successful, false if out of memory. */
-STATIC int  s_pad(mp_int z, mp_size min);
+static bool s_pad(mp_int z, mp_size min);
+
+/* Ensure Z has at least N digits allocated. */
+static inline mp_result GROW(mp_int Z, mp_size N) {
+  return s_pad(Z, N) ? MP_OK : MP_MEMORY;
+}
 
 /* Fill in a "fake" mp_int on the stack with a given value */
-STATIC void      s_fake(mp_int z, mp_small value, mp_digit vbuf[]);
-STATIC void      s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]);
+static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]);
+static void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]);
 
 /* Compare two runs of digits of given length, returns <0, 0, >0 */
-STATIC int       s_cdig(mp_digit *da, mp_digit *db, mp_size len);
+static int s_cdig(mp_digit *da, mp_digit *db, mp_size len);
 
 /* Pack the unsigned digits of v into array t */
-STATIC int       s_uvpack(mp_usmall v, mp_digit t[]);
+static int s_uvpack(mp_usmall v, mp_digit t[]);
 
 /* Compare magnitudes of a and b, returns <0, 0, >0 */
-STATIC int       s_ucmp(mp_int a, mp_int b);
+static int s_ucmp(mp_int a, mp_int b);
 
 /* Compare magnitudes of a and v, returns <0, 0, >0 */
-STATIC int       s_vcmp(mp_int a, mp_small v);
-STATIC int       s_uvcmp(mp_int a, mp_usmall uv);
+static int s_vcmp(mp_int a, mp_small v);
+static int s_uvcmp(mp_int a, mp_usmall uv);
 
 /* Unsigned magnitude addition; assumes dc is big enough.
    Carry out is returned (no memory allocated). */
-STATIC mp_digit  s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
-		        mp_size size_a, mp_size size_b);
+static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                       mp_size size_b);
 
 /* Unsigned magnitude subtraction.  Assumes dc is big enough. */
-STATIC void      s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
-		        mp_size size_a, mp_size size_b);
+static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                   mp_size size_b);
 
 /* Unsigned recursive multiplication.  Assumes dc is big enough. */
-STATIC int       s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
-			mp_size size_a, mp_size size_b);
+static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                  mp_size size_b);
 
 /* Unsigned magnitude multiplication.  Assumes dc is big enough. */
-STATIC void      s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
-			mp_size size_a, mp_size size_b);
+static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                   mp_size size_b);
 
 /* Unsigned recursive squaring.  Assumes dc is big enough. */
-STATIC int       s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a);
+static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a);
 
 /* Unsigned magnitude squaring.  Assumes dc is big enough. */
-STATIC void      s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a);
+static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a);
 
 /* Single digit addition.  Assumes a is big enough. */
-STATIC void      s_dadd(mp_int a, mp_digit b);
+static void s_dadd(mp_int a, mp_digit b);
 
 /* Single digit multiplication.  Assumes a is big enough. */
-STATIC void      s_dmul(mp_int a, mp_digit b);
+static void s_dmul(mp_int a, mp_digit b);
 
 /* Single digit multiplication on buffers; assumes dc is big enough. */
-STATIC void      s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc,
-			 mp_size size_a);
+static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a);
 
 /* Single digit division.  Replaces a with the quotient,
    returns the remainder.  */
-STATIC mp_digit  s_ddiv(mp_int a, mp_digit b);
+static mp_digit s_ddiv(mp_int a, mp_digit b);
 
 /* Quick division by a power of 2, replaces z (no allocation) */
-STATIC void      s_qdiv(mp_int z, mp_size p2);
+static void s_qdiv(mp_int z, mp_size p2);
 
 /* Quick remainder by a power of 2, replaces z (no allocation) */
-STATIC void      s_qmod(mp_int z, mp_size p2);
+static void s_qmod(mp_int z, mp_size p2);
 
 /* Quick multiplication by a power of 2, replaces z.
    Allocates if necessary; returns false in case this fails. */
-STATIC int       s_qmul(mp_int z, mp_size p2);
+static int s_qmul(mp_int z, mp_size p2);
 
 /* Quick subtraction from a power of 2, replaces z.
    Allocates if necessary; returns false in case this fails. */
-STATIC int       s_qsub(mp_int z, mp_size p2);
+static int s_qsub(mp_int z, mp_size p2);
 
 /* Return maximum k such that 2^k divides z. */
-STATIC int       s_dp2k(mp_int z);
+static int s_dp2k(mp_int z);
 
 /* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */
-STATIC int       s_isp2(mp_int z);
+static int s_isp2(mp_int z);
 
 /* Set z to 2^k.  May allocate; returns false in case this fails. */
-STATIC int       s_2expt(mp_int z, mp_small k);
+static int s_2expt(mp_int z, mp_small k);
 
 /* Normalize a and b for division, returns normalization constant */
-STATIC int       s_norm(mp_int a, mp_int b);
+static int s_norm(mp_int a, mp_int b);
 
 /* Compute constant mu for Barrett reduction, given modulus m, result
    replaces z, m is untouched. */
-STATIC mp_result s_brmu(mp_int z, mp_int m);
+static mp_result s_brmu(mp_int z, mp_int m);
 
 /* Reduce a modulo m, using Barrett's algorithm. */
-STATIC int       s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2);
+static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2);
 
 /* Modular exponentiation, using Barrett reduction */
-STATIC mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
+static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
 
 /* Unsigned magnitude division.  Assumes |a| > |b|.  Allocates temporaries;
    overwrites a with quotient, b with remainder. */
-STATIC mp_result s_udiv_knuth(mp_int a, mp_int b);
+static mp_result s_udiv_knuth(mp_int a, mp_int b);
 
 /* Compute the number of digits in radix r required to represent the given
    value.  Does not account for sign flags, terminators, etc. */
-STATIC int       s_outlen(mp_int z, mp_size r);
+static int s_outlen(mp_int z, mp_size r);
 
 /* Guess how many digits of precision will be needed to represent a radix r
    value of the specified number of digits.  Returns a value guaranteed to be
    no smaller than the actual number required. */
-STATIC mp_size   s_inlen(int len, mp_size r);
+static mp_size s_inlen(int len, mp_size r);
 
 /* Convert a character to a digit value in radix r, or
    -1 if out of range */
-STATIC int       s_ch2val(char c, int r);
+static int s_ch2val(char c, int r);
 
 /* Convert a digit value to a character */
-STATIC char      s_val2ch(int v, int caps);
+static char s_val2ch(int v, int caps);
 
 /* Take 2's complement of a buffer in place */
-STATIC void      s_2comp(unsigned char *buf, int len);
+static void s_2comp(unsigned char *buf, int len);
 
 /* Convert a value to binary, ignoring sign.  On input, *limpos is the bound on
    how many bytes should be written to buf; on output, *limpos is set to the
    number of bytes actually written. */
-STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad);
+static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad);
 
-#if DEBUG
-/* Dump a representation of the mp_int to standard output */
-void      s_print(char *tag, mp_int z);
-void      s_print_buf(char *tag, mp_digit *buf, mp_size num);
-#endif
+/* Multiply X by Y into Z, ignoring signs.  Requires that Z have enough storage
+   preallocated to hold the result. */
+static inline void UMUL(mp_int X, mp_int Y, mp_int Z) {
+  mp_size ua_ = MP_USED(X);
+  mp_size ub_ = MP_USED(Y);
+  mp_size o_ = ua_ + ub_;
+  ZERO(MP_DIGITS(Z), o_);
+  (void)s_kmul(MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_);
+  Z->used = o_;
+  CLAMP(Z);
+}
 
-mp_result mp_int_init(mp_int z)
-{
-  if (z == NULL)
-    return MP_BADARG;
+/* Square X into Z.  Requires that Z have enough storage to hold the result. */
+static inline void USQR(mp_int X, mp_int Z) {
+  mp_size ua_ = MP_USED(X);
+  mp_size o_ = ua_ + ua_;
+  ZERO(MP_DIGITS(Z), o_);
+  (void)s_ksqr(MP_DIGITS(X), MP_DIGITS(Z), ua_);
+  Z->used = o_;
+  CLAMP(Z);
+}
+
+mp_result mp_int_init(mp_int z) {
+  if (z == NULL) return MP_BADARG;
 
   z->single = 0;
   z->digits = &(z->single);
-  z->alloc  = 1;
-  z->used   = 1;
-  z->sign   = MP_ZPOS;
+  z->alloc = 1;
+  z->used = 1;
+  z->sign = MP_ZPOS;
 
   return MP_OK;
 }
 
-mp_int    mp_int_alloc(void)
-{
+mp_int mp_int_alloc(void) {
   mp_int out = malloc(sizeof(mpz_t));
 
-  if (out != NULL)
-    mp_int_init(out);
+  if (out != NULL) mp_int_init(out);
 
   return out;
 }
 
-mp_result mp_int_init_size(mp_int z, mp_size prec)
-{
-  CHECK(z != NULL);
+mp_result mp_int_init_size(mp_int z, mp_size prec) {
+  assert(z != NULL);
 
-  if (prec == 0)
+  if (prec == 0) {
     prec = default_precision;
-  else if (prec == 1)
+  } else if (prec == 1) {
     return mp_int_init(z);
-  else
-    prec = (mp_size) ROUND_PREC(prec);
+  } else {
+    prec = s_round_prec(prec);
+  }
 
-  if ((MP_DIGITS(z) = s_alloc(prec)) == NULL)
-    return MP_MEMORY;
+  z->digits = s_alloc(prec);
+  if (MP_DIGITS(z) == NULL) return MP_MEMORY;
 
   z->digits[0] = 0;
-  MP_USED(z) = 1;
-  MP_ALLOC(z) = prec;
-  MP_SIGN(z) = MP_ZPOS;
+  z->used = 1;
+  z->alloc = prec;
+  z->sign = MP_ZPOS;
 
   return MP_OK;
 }
 
-mp_result mp_int_init_copy(mp_int z, mp_int old)
-{
-  mp_result res;
-  mp_size uold;
+mp_result mp_int_init_copy(mp_int z, mp_int old) {
+  assert(z != NULL && old != NULL);
 
-  CHECK(z != NULL && old != NULL);
-
-  uold = MP_USED(old);
+  mp_size uold = MP_USED(old);
   if (uold == 1) {
     mp_int_init(z);
-  }
-  else {
+  } else {
     mp_size target = MAX(uold, default_precision);
-
-    if ((res = mp_int_init_size(z, target)) != MP_OK)
-      return res;
+    mp_result res = mp_int_init_size(z, target);
+    if (res != MP_OK) return res;
   }
 
-  MP_USED(z) = uold;
-  MP_SIGN(z) = MP_SIGN(old);
+  z->used = uold;
+  z->sign = old->sign;
   COPY(MP_DIGITS(old), MP_DIGITS(z), uold);
 
   return MP_OK;
 }
 
-mp_result mp_int_init_value(mp_int z, mp_small value)
-{
-  mpz_t    vtmp;
+mp_result mp_int_init_value(mp_int z, mp_small value) {
+  mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(value)];
 
   s_fake(&vtmp, value, vbuf);
   return mp_int_init_copy(z, &vtmp);
 }
 
-mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue)
-{
-  mpz_t    vtmp;
+mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue) {
+  mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(uvalue)];
 
   s_ufake(&vtmp, uvalue, vbuf);
   return mp_int_init_copy(z, &vtmp);
 }
 
-mp_result  mp_int_set_value(mp_int z, mp_small value)
-{
-  mpz_t    vtmp;
+mp_result mp_int_set_value(mp_int z, mp_small value) {
+  mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(value)];
 
   s_fake(&vtmp, value, vbuf);
   return mp_int_copy(&vtmp, z);
 }
 
-mp_result  mp_int_set_uvalue(mp_int z, mp_usmall uvalue)
-{
-  mpz_t    vtmp;
+mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue) {
+  mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(uvalue)];
 
   s_ufake(&vtmp, uvalue, vbuf);
   return mp_int_copy(&vtmp, z);
 }
 
-void      mp_int_clear(mp_int z)
-{
-  if (z == NULL)
-    return;
+void mp_int_clear(mp_int z) {
+  if (z == NULL) return;
 
   if (MP_DIGITS(z) != NULL) {
-    if (MP_DIGITS(z) != &(z->single))
-      s_free(MP_DIGITS(z));
+    if (MP_DIGITS(z) != &(z->single)) s_free(MP_DIGITS(z));
 
-    MP_DIGITS(z) = NULL;
+    z->digits = NULL;
   }
 }
 
-void      mp_int_free(mp_int z)
-{
-  NRCHECK(z != NULL);
+void mp_int_free(mp_int z) {
+  assert(z != NULL);
 
   mp_int_clear(z);
   free(z); /* note: NOT s_free() */
 }
 
-mp_result mp_int_copy(mp_int a, mp_int c)
-{
-  CHECK(a != NULL && c != NULL);
+mp_result mp_int_copy(mp_int a, mp_int c) {
+  assert(a != NULL && c != NULL);
 
   if (a != c) {
     mp_size ua = MP_USED(a);
     mp_digit *da, *dc;
 
-    if (!s_pad(c, ua))
-      return MP_MEMORY;
+    if (!s_pad(c, ua)) return MP_MEMORY;
 
-    da = MP_DIGITS(a); dc = MP_DIGITS(c);
+    da = MP_DIGITS(a);
+    dc = MP_DIGITS(c);
     COPY(da, dc, ua);
 
-    MP_USED(c) = ua;
-    MP_SIGN(c) = MP_SIGN(a);
+    c->used = ua;
+    c->sign = a->sign;
   }
 
   return MP_OK;
 }
 
-void      mp_int_swap(mp_int a, mp_int c)
-{
+void mp_int_swap(mp_int a, mp_int c) {
   if (a != c) {
     mpz_t tmp = *a;
 
     *a = *c;
     *c = tmp;
 
-    if (MP_DIGITS(a) == &(c->single))
-      MP_DIGITS(a) = &(a->single);
-    if (MP_DIGITS(c) == &(a->single))
-      MP_DIGITS(c) = &(c->single);
+    if (MP_DIGITS(a) == &(c->single)) a->digits = &(a->single);
+    if (MP_DIGITS(c) == &(a->single)) c->digits = &(c->single);
   }
 }
 
-void      mp_int_zero(mp_int z)
-{
-  NRCHECK(z != NULL);
+void mp_int_zero(mp_int z) {
+  assert(z != NULL);
 
   z->digits[0] = 0;
-  MP_USED(z) = 1;
-  MP_SIGN(z) = MP_ZPOS;
+  z->used = 1;
+  z->sign = MP_ZPOS;
 }
 
-mp_result mp_int_abs(mp_int a, mp_int c)
-{
+mp_result mp_int_abs(mp_int a, mp_int c) {
+  assert(a != NULL && c != NULL);
+
   mp_result res;
+  if ((res = mp_int_copy(a, c)) != MP_OK) return res;
 
-  CHECK(a != NULL && c != NULL);
-
-  if ((res = mp_int_copy(a, c)) != MP_OK)
-    return res;
-
-  MP_SIGN(c) = MP_ZPOS;
+  c->sign = MP_ZPOS;
   return MP_OK;
 }
 
-mp_result mp_int_neg(mp_int a, mp_int c)
-{
+mp_result mp_int_neg(mp_int a, mp_int c) {
+  assert(a != NULL && c != NULL);
+
   mp_result res;
+  if ((res = mp_int_copy(a, c)) != MP_OK) return res;
 
-  CHECK(a != NULL && c != NULL);
-
-  if ((res = mp_int_copy(a, c)) != MP_OK)
-    return res;
-
-  if (CMPZ(c) != 0)
-    MP_SIGN(c) = 1 - MP_SIGN(a);
+  if (CMPZ(c) != 0) c->sign = 1 - MP_SIGN(a);
 
   return MP_OK;
 }
 
-mp_result mp_int_add(mp_int a, mp_int b, mp_int c)
-{
-  mp_size ua, ub, uc, max;
+mp_result mp_int_add(mp_int a, mp_int b, mp_int c) {
+  assert(a != NULL && b != NULL && c != NULL);
 
-  CHECK(a != NULL && b != NULL && c != NULL);
-
-  ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c);
-  max = MAX(ua, ub);
+  mp_size ua = MP_USED(a);
+  mp_size ub = MP_USED(b);
+  mp_size max = MAX(ua, ub);
 
   if (MP_SIGN(a) == MP_SIGN(b)) {
     /* Same sign -- add magnitudes, preserve sign of addends */
-    mp_digit carry;
+    if (!s_pad(c, max)) return MP_MEMORY;
 
-    if (!s_pad(c, max))
-      return MP_MEMORY;
-
-    carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
-    uc = max;
+    mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
+    mp_size uc = max;
 
     if (carry) {
-      if (!s_pad(c, max + 1))
-	return MP_MEMORY;
+      if (!s_pad(c, max + 1)) return MP_MEMORY;
 
       c->digits[max] = carry;
       ++uc;
     }
 
-    MP_USED(c) = uc;
-    MP_SIGN(c) = MP_SIGN(a);
+    c->used = uc;
+    c->sign = a->sign;
 
-  }
-  else {
+  } else {
     /* Different signs -- subtract magnitudes, preserve sign of greater */
-    mp_int  x, y;
-    int     cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */
+    int cmp = s_ucmp(a, b); /* magnitude comparison, sign ignored */
 
     /* Set x to max(a, b), y to min(a, b) to simplify later code.
        A special case yields zero for equal magnitudes.
     */
+    mp_int x, y;
     if (cmp == 0) {
       mp_int_zero(c);
       return MP_OK;
-    }
-    else if (cmp < 0) {
-      x = b; y = a;
-    }
-    else {
-      x = a; y = b;
+    } else if (cmp < 0) {
+      x = b;
+      y = a;
+    } else {
+      x = a;
+      y = b;
     }
 
-    if (!s_pad(c, MP_USED(x)))
-      return MP_MEMORY;
+    if (!s_pad(c, MP_USED(x))) return MP_MEMORY;
 
     /* Subtract smaller from larger */
     s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y));
-    MP_USED(c) = MP_USED(x);
+    c->used = x->used;
     CLAMP(c);
 
     /* Give result the sign of the larger */
-    MP_SIGN(c) = MP_SIGN(x);
+    c->sign = x->sign;
   }
 
   return MP_OK;
 }
 
-mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c)
-{
-  mpz_t    vtmp;
+mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c) {
+  mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(value)];
 
   s_fake(&vtmp, value, vbuf);
@@ -632,69 +600,61 @@
   return mp_int_add(a, &vtmp, c);
 }
 
-mp_result mp_int_sub(mp_int a, mp_int b, mp_int c)
-{
-  mp_size ua, ub, uc, max;
+mp_result mp_int_sub(mp_int a, mp_int b, mp_int c) {
+  assert(a != NULL && b != NULL && c != NULL);
 
-  CHECK(a != NULL && b != NULL && c != NULL);
-
-  ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c);
-  max = MAX(ua, ub);
+  mp_size ua = MP_USED(a);
+  mp_size ub = MP_USED(b);
+  mp_size max = MAX(ua, ub);
 
   if (MP_SIGN(a) != MP_SIGN(b)) {
     /* Different signs -- add magnitudes and keep sign of a */
-    mp_digit carry;
+    if (!s_pad(c, max)) return MP_MEMORY;
 
-    if (!s_pad(c, max))
-      return MP_MEMORY;
-
-    carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
-    uc = max;
+    mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
+    mp_size uc = max;
 
     if (carry) {
-      if (!s_pad(c, max + 1))
-	return MP_MEMORY;
+      if (!s_pad(c, max + 1)) return MP_MEMORY;
 
       c->digits[max] = carry;
       ++uc;
     }
 
-    MP_USED(c) = uc;
-    MP_SIGN(c) = MP_SIGN(a);
+    c->used = uc;
+    c->sign = a->sign;
 
-  }
-  else {
+  } else {
     /* Same signs -- subtract magnitudes */
-    mp_int  x, y;
+    if (!s_pad(c, max)) return MP_MEMORY;
+    mp_int x, y;
     mp_sign osign;
-    int     cmp = s_ucmp(a, b);
 
-    if (!s_pad(c, max))
-      return MP_MEMORY;
-
+    int cmp = s_ucmp(a, b);
     if (cmp >= 0) {
-      x = a; y = b; osign = MP_ZPOS;
-    }
-    else {
-      x = b; y = a; osign = MP_NEG;
+      x = a;
+      y = b;
+      osign = MP_ZPOS;
+    } else {
+      x = b;
+      y = a;
+      osign = MP_NEG;
     }
 
-    if (MP_SIGN(a) == MP_NEG && cmp != 0)
-      osign = 1 - osign;
+    if (MP_SIGN(a) == MP_NEG && cmp != 0) osign = 1 - osign;
 
     s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y));
-    MP_USED(c) = MP_USED(x);
+    c->used = x->used;
     CLAMP(c);
 
-    MP_SIGN(c) = osign;
+    c->sign = osign;
   }
 
   return MP_OK;
 }
 
-mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c)
-{
-  mpz_t    vtmp;
+mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c) {
+  mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(value)];
 
   s_fake(&vtmp, value, vbuf);
@@ -702,13 +662,8 @@
   return mp_int_sub(a, &vtmp, c);
 }
 
-mp_result mp_int_mul(mp_int a, mp_int b, mp_int c)
-{
-  mp_digit *out;
-  mp_size   osize, ua, ub, p = 0;
-  mp_sign   osign;
-
-  CHECK(a != NULL && b != NULL && c != NULL);
+mp_result mp_int_mul(mp_int a, mp_int b, mp_int c) {
+  assert(a != NULL && b != NULL && c != NULL);
 
   /* If either input is zero, we can shortcut multiplication */
   if (mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) {
@@ -717,52 +672,48 @@
   }
 
   /* Output is positive if inputs have same sign, otherwise negative */
-  osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG;
+  mp_sign osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG;
 
   /* If the output is not identical to any of the inputs, we'll write the
      results directly; otherwise, allocate a temporary space. */
-  ua = MP_USED(a); ub = MP_USED(b);
-  osize = MAX(ua, ub);
+  mp_size ua = MP_USED(a);
+  mp_size ub = MP_USED(b);
+  mp_size osize = MAX(ua, ub);
   osize = 4 * ((osize + 1) / 2);
 
+  mp_digit *out;
+  mp_size p = 0;
   if (c == a || c == b) {
-    p = ROUND_PREC(osize);
-    p = MAX(p, default_precision);
+    p = MAX(s_round_prec(osize), default_precision);
 
-    if ((out = s_alloc(p)) == NULL)
-      return MP_MEMORY;
-  }
-  else {
-    if (!s_pad(c, osize))
-      return MP_MEMORY;
+    if ((out = s_alloc(p)) == NULL) return MP_MEMORY;
+  } else {
+    if (!s_pad(c, osize)) return MP_MEMORY;
 
     out = MP_DIGITS(c);
   }
   ZERO(out, osize);
 
-  if (!s_kmul(MP_DIGITS(a), MP_DIGITS(b), out, ua, ub))
-    return MP_MEMORY;
+  if (!s_kmul(MP_DIGITS(a), MP_DIGITS(b), out, ua, ub)) return MP_MEMORY;
 
   /* If we allocated a new buffer, get rid of whatever memory c was already
      using, and fix up its fields to reflect that.
    */
   if (out != MP_DIGITS(c)) {
-    if ((void *) MP_DIGITS(c) != (void *) c)
-      s_free(MP_DIGITS(c));
-    MP_DIGITS(c) = out;
-    MP_ALLOC(c) = p;
+    if ((void *)MP_DIGITS(c) != (void *)c) s_free(MP_DIGITS(c));
+    c->digits = out;
+    c->alloc = p;
   }
 
-  MP_USED(c) = osize; /* might not be true, but we'll fix it ... */
-  CLAMP(c);           /* ... right here */
-  MP_SIGN(c) = osign;
+  c->used = osize; /* might not be true, but we'll fix it ... */
+  CLAMP(c);        /* ... right here */
+  c->sign = osign;
 
   return MP_OK;
 }
 
-mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c)
-{
-  mpz_t    vtmp;
+mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c) {
+  mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(value)];
 
   s_fake(&vtmp, value, vbuf);
@@ -770,39 +721,33 @@
   return mp_int_mul(a, &vtmp, c);
 }
 
-mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c)
-{
-  mp_result res;
-  CHECK(a != NULL && c != NULL && p2 >= 0);
+mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c) {
+  assert(a != NULL && c != NULL && p2 >= 0);
 
-  if ((res = mp_int_copy(a, c)) != MP_OK)
-    return res;
+  mp_result res = mp_int_copy(a, c);
+  if (res != MP_OK) return res;
 
-  if (s_qmul(c, (mp_size) p2))
+  if (s_qmul(c, (mp_size)p2)) {
     return MP_OK;
-  else
+  } else {
     return MP_MEMORY;
+  }
 }
 
-mp_result mp_int_sqr(mp_int a, mp_int c)
-{
-  mp_digit *out;
-  mp_size   osize, p = 0;
-
-  CHECK(a != NULL && c != NULL);
+mp_result mp_int_sqr(mp_int a, mp_int c) {
+  assert(a != NULL && c != NULL);
 
   /* Get a temporary buffer big enough to hold the result */
-  osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2);
+  mp_size osize = (mp_size)4 * ((MP_USED(a) + 1) / 2);
+  mp_size p = 0;
+  mp_digit *out;
   if (a == c) {
-    p = ROUND_PREC(osize);
+    p = s_round_prec(osize);
     p = MAX(p, default_precision);
 
-    if ((out = s_alloc(p)) == NULL)
-      return MP_MEMORY;
-  }
-  else {
-    if (!s_pad(c, osize))
-      return MP_MEMORY;
+    if ((out = s_alloc(p)) == NULL) return MP_MEMORY;
+  } else {
+    if (!s_pad(c, osize)) return MP_MEMORY;
 
     out = MP_DIGITS(c);
   }
@@ -814,56 +759,48 @@
      reflect the new digit array it's using
    */
   if (out != MP_DIGITS(c)) {
-    if ((void *) MP_DIGITS(c) != (void *) c)
-      s_free(MP_DIGITS(c));
-    MP_DIGITS(c) = out;
-    MP_ALLOC(c) = p;
+    if ((void *)MP_DIGITS(c) != (void *)c) s_free(MP_DIGITS(c));
+    c->digits = out;
+    c->alloc = p;
   }
 
-  MP_USED(c) = osize; /* might not be true, but we'll fix it ... */
-  CLAMP(c);           /* ... right here */
-  MP_SIGN(c) = MP_ZPOS;
+  c->used = osize; /* might not be true, but we'll fix it ... */
+  CLAMP(c);        /* ... right here */
+  c->sign = MP_ZPOS;
 
   return MP_OK;
 }
 
-mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
-{
-  int cmp, lg;
+mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) {
+  assert(a != NULL && b != NULL && q != r);
+
+  int cmp;
   mp_result res = MP_OK;
   mp_int qout, rout;
-  mp_sign sa = MP_SIGN(a), sb = MP_SIGN(b);
-  DECLARE_TEMP(2);
-
-  CHECK(a != NULL && b != NULL && q != r);
-
-  if (CMPZ(b) == 0)
+  mp_sign sa = MP_SIGN(a);
+  mp_sign sb = MP_SIGN(b);
+  if (CMPZ(b) == 0) {
     return MP_UNDEF;
-  else if ((cmp = s_ucmp(a, b)) < 0) {
+  } else if ((cmp = s_ucmp(a, b)) < 0) {
     /* If |a| < |b|, no division is required:
        q = 0, r = a
      */
-    if (r && (res = mp_int_copy(a, r)) != MP_OK)
-      return res;
+    if (r && (res = mp_int_copy(a, r)) != MP_OK) return res;
 
-    if (q)
-      mp_int_zero(q);
+    if (q) mp_int_zero(q);
 
     return MP_OK;
-  }
-  else if (cmp == 0) {
+  } else if (cmp == 0) {
     /* If |a| = |b|, no division is required:
        q = 1 or -1, r = 0
      */
-    if (r)
-      mp_int_zero(r);
+    if (r) mp_int_zero(r);
 
     if (q) {
       mp_int_zero(q);
       q->digits[0] = 1;
 
-      if (sa != sb)
-	MP_SIGN(q) = MP_NEG;
+      if (sa != sb) q->sign = MP_NEG;
     }
 
     return MP_OK;
@@ -873,336 +810,260 @@
      quotient and remainder, but q and r are allowed to be NULL or to overlap
      with the inputs.
    */
+  DECLARE_TEMP(2);
+  int lg;
   if ((lg = s_isp2(b)) < 0) {
     if (q && b != q) {
-      if ((res = mp_int_copy(a, q)) != MP_OK)
-	goto CLEANUP;
-      else
-	qout = q;
-    }
-    else {
-      qout = LAST_TEMP();
-      SETUP(mp_int_init_copy(LAST_TEMP(), a));
+      REQUIRE(mp_int_copy(a, q));
+      qout = q;
+    } else {
+      REQUIRE(mp_int_copy(a, TEMP(0)));
+      qout = TEMP(0);
     }
 
     if (r && a != r) {
-      if ((res = mp_int_copy(b, r)) != MP_OK)
-	goto CLEANUP;
-      else
-	rout = r;
-    }
-    else {
-      rout = LAST_TEMP();
-      SETUP(mp_int_init_copy(LAST_TEMP(), b));
+      REQUIRE(mp_int_copy(b, r));
+      rout = r;
+    } else {
+      REQUIRE(mp_int_copy(b, TEMP(1)));
+      rout = TEMP(1);
     }
 
-    if ((res = s_udiv_knuth(qout, rout)) != MP_OK) goto CLEANUP;
-  }
-  else {
-    if (q && (res = mp_int_copy(a, q)) != MP_OK) goto CLEANUP;
-    if (r && (res = mp_int_copy(a, r)) != MP_OK) goto CLEANUP;
+    REQUIRE(s_udiv_knuth(qout, rout));
+  } else {
+    if (q) REQUIRE(mp_int_copy(a, q));
+    if (r) REQUIRE(mp_int_copy(a, r));
 
-    if (q) s_qdiv(q, (mp_size) lg); qout = q;
-    if (r) s_qmod(r, (mp_size) lg); rout = r;
+    if (q) s_qdiv(q, (mp_size)lg);
+    qout = q;
+    if (r) s_qmod(r, (mp_size)lg);
+    rout = r;
   }
 
   /* Recompute signs for output */
   if (rout) {
-    MP_SIGN(rout) = sa;
-    if (CMPZ(rout) == 0)
-      MP_SIGN(rout) = MP_ZPOS;
+    rout->sign = sa;
+    if (CMPZ(rout) == 0) rout->sign = MP_ZPOS;
   }
   if (qout) {
-    MP_SIGN(qout) = (sa == sb) ? MP_ZPOS : MP_NEG;
-    if (CMPZ(qout) == 0)
-      MP_SIGN(qout) = MP_ZPOS;
+    qout->sign = (sa == sb) ? MP_ZPOS : MP_NEG;
+    if (CMPZ(qout) == 0) qout->sign = MP_ZPOS;
   }
 
-  if (q && (res = mp_int_copy(qout, q)) != MP_OK) goto CLEANUP;
-  if (r && (res = mp_int_copy(rout, r)) != MP_OK) goto CLEANUP;
-
+  if (q) REQUIRE(mp_int_copy(qout, q));
+  if (r) REQUIRE(mp_int_copy(rout, r));
   CLEANUP_TEMP();
   return res;
 }
 
-mp_result mp_int_mod(mp_int a, mp_int m, mp_int c)
-{
-  mp_result res;
-  mpz_t     tmp;
-  mp_int    out;
-
-  if (m == c) {
-    mp_int_init(&tmp);
-    out = &tmp;
+mp_result mp_int_mod(mp_int a, mp_int m, mp_int c) {
+  DECLARE_TEMP(1);
+  mp_int out = (m == c) ? TEMP(0) : c;
+  REQUIRE(mp_int_div(a, m, NULL, out));
+  if (CMPZ(out) < 0) {
+    REQUIRE(mp_int_add(out, m, c));
+  } else {
+    REQUIRE(mp_int_copy(out, c));
   }
-  else {
-    out = c;
-  }
-
-  if ((res = mp_int_div(a, m, NULL, out)) != MP_OK)
-    goto CLEANUP;
-
-  if (CMPZ(out) < 0)
-    res = mp_int_add(out, m, c);
-  else
-    res = mp_int_copy(out, c);
-
- CLEANUP:
-  if (out != c)
-    mp_int_clear(&tmp);
-
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
-mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r)
-{
-  mpz_t     vtmp, rtmp;
-  mp_digit  vbuf[MP_VALUE_DIGITS(value)];
-  mp_result res;
-
-  mp_int_init(&rtmp);
+mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r) {
+  mpz_t vtmp;
+  mp_digit vbuf[MP_VALUE_DIGITS(value)];
   s_fake(&vtmp, value, vbuf);
 
-  if ((res = mp_int_div(a, &vtmp, q, &rtmp)) != MP_OK)
-    goto CLEANUP;
+  DECLARE_TEMP(1);
+  REQUIRE(mp_int_div(a, &vtmp, q, TEMP(0)));
 
-  if (r)
-    (void) mp_int_to_int(&rtmp, r); /* can't fail */
+  if (r) (void)mp_int_to_int(TEMP(0), r); /* can't fail */
 
- CLEANUP:
-  mp_int_clear(&rtmp);
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
-mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r)
-{
+mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r) {
+  assert(a != NULL && p2 >= 0 && q != r);
+
   mp_result res = MP_OK;
+  if (q != NULL && (res = mp_int_copy(a, q)) == MP_OK) {
+    s_qdiv(q, (mp_size)p2);
+  }
 
-  CHECK(a != NULL && p2 >= 0 && q != r);
-
-  if (q != NULL && (res = mp_int_copy(a, q)) == MP_OK)
-    s_qdiv(q, (mp_size) p2);
-
-  if (res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK)
-    s_qmod(r, (mp_size) p2);
+  if (res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK) {
+    s_qmod(r, (mp_size)p2);
+  }
 
   return res;
 }
 
-mp_result mp_int_expt(mp_int a, mp_small b, mp_int c)
-{
-  mpz_t t;
-  mp_result res;
+mp_result mp_int_expt(mp_int a, mp_small b, mp_int c) {
+  assert(c != NULL);
+  if (b < 0) return MP_RANGE;
+
+  DECLARE_TEMP(1);
+  REQUIRE(mp_int_copy(a, TEMP(0)));
+
+  (void)mp_int_set_value(c, 1);
   unsigned int v = labs(b);
-
-  CHECK(c != NULL);
-  if (b < 0)
-    return MP_RANGE;
-
-  if ((res = mp_int_init_copy(&t, a)) != MP_OK)
-    return res;
-
-  (void) mp_int_set_value(c, 1);
   while (v != 0) {
     if (v & 1) {
-      if ((res = mp_int_mul(c, &t, c)) != MP_OK)
-	goto CLEANUP;
+      REQUIRE(mp_int_mul(c, TEMP(0), c));
     }
 
     v >>= 1;
     if (v == 0) break;
 
-    if ((res = mp_int_sqr(&t, &t)) != MP_OK)
-      goto CLEANUP;
+    REQUIRE(mp_int_sqr(TEMP(0), TEMP(0)));
   }
 
- CLEANUP:
-  mp_int_clear(&t);
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
-mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c)
-{
-  mpz_t     t;
-  mp_result res;
+mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c) {
+  assert(c != NULL);
+  if (b < 0) return MP_RANGE;
+
+  DECLARE_TEMP(1);
+  REQUIRE(mp_int_set_value(TEMP(0), a));
+
+  (void)mp_int_set_value(c, 1);
   unsigned int v = labs(b);
-
-  CHECK(c != NULL);
-  if (b < 0)
-    return MP_RANGE;
-
-  if ((res = mp_int_init_value(&t, a)) != MP_OK)
-    return res;
-
-  (void) mp_int_set_value(c, 1);
   while (v != 0) {
     if (v & 1) {
-      if ((res = mp_int_mul(c, &t, c)) != MP_OK)
-	goto CLEANUP;
+      REQUIRE(mp_int_mul(c, TEMP(0), c));
     }
 
     v >>= 1;
     if (v == 0) break;
 
-    if ((res = mp_int_sqr(&t, &t)) != MP_OK)
-      goto CLEANUP;
+    REQUIRE(mp_int_sqr(TEMP(0), TEMP(0)));
   }
 
- CLEANUP:
-  mp_int_clear(&t);
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
-mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c)
-{
-  mpz_t t;
-  mp_result res;
-  unsigned ix, jx;
+mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c) {
+  assert(a != NULL && b != NULL && c != NULL);
+  if (MP_SIGN(b) == MP_NEG) return MP_RANGE;
 
-  CHECK(a != NULL && b != NULL && c != NULL);
-  if (MP_SIGN(b) == MP_NEG)
-    return MP_RANGE;
+  DECLARE_TEMP(1);
+  REQUIRE(mp_int_copy(a, TEMP(0)));
 
-  if ((res = mp_int_init_copy(&t, a)) != MP_OK)
-    return res;
-
-  (void) mp_int_set_value(c, 1);
-  for (ix = 0; ix < MP_USED(b); ++ix) {
+  (void)mp_int_set_value(c, 1);
+  for (unsigned ix = 0; ix < MP_USED(b); ++ix) {
     mp_digit d = b->digits[ix];
 
-    for (jx = 0; jx < MP_DIGIT_BIT; ++jx) {
+    for (unsigned jx = 0; jx < MP_DIGIT_BIT; ++jx) {
       if (d & 1) {
-	if ((res = mp_int_mul(c, &t, c)) != MP_OK)
-	  goto CLEANUP;
+        REQUIRE(mp_int_mul(c, TEMP(0), c));
       }
 
       d >>= 1;
-      if (d == 0 && ix + 1 == MP_USED(b))
-	break;
-      if ((res = mp_int_sqr(&t, &t)) != MP_OK)
-	goto CLEANUP;
+      if (d == 0 && ix + 1 == MP_USED(b)) break;
+      REQUIRE(mp_int_sqr(TEMP(0), TEMP(0)));
     }
   }
 
- CLEANUP:
-  mp_int_clear(&t);
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
-int       mp_int_compare(mp_int a, mp_int b)
-{
-  mp_sign sa;
+int mp_int_compare(mp_int a, mp_int b) {
+  assert(a != NULL && b != NULL);
 
-  CHECK(a != NULL && b != NULL);
-
-  sa = MP_SIGN(a);
+  mp_sign sa = MP_SIGN(a);
   if (sa == MP_SIGN(b)) {
     int cmp = s_ucmp(a, b);
 
     /* If they're both zero or positive, the normal comparison applies; if both
        negative, the sense is reversed. */
-    if (sa == MP_ZPOS)
+    if (sa == MP_ZPOS) {
       return cmp;
-    else
+    } else {
       return -cmp;
-
-  }
-  else {
-    if (sa == MP_ZPOS)
-      return 1;
-    else
-      return -1;
+    }
+  } else if (sa == MP_ZPOS) {
+    return 1;
+  } else {
+    return -1;
   }
 }
 
-int       mp_int_compare_unsigned(mp_int a, mp_int b)
-{
-  NRCHECK(a != NULL && b != NULL);
+int mp_int_compare_unsigned(mp_int a, mp_int b) {
+  assert(a != NULL && b != NULL);
 
   return s_ucmp(a, b);
 }
 
-int       mp_int_compare_zero(mp_int z)
-{
-  NRCHECK(z != NULL);
+int mp_int_compare_zero(mp_int z) {
+  assert(z != NULL);
 
-  if (MP_USED(z) == 1 && z->digits[0] == 0)
+  if (MP_USED(z) == 1 && z->digits[0] == 0) {
     return 0;
-  else if (MP_SIGN(z) == MP_ZPOS)
+  } else if (MP_SIGN(z) == MP_ZPOS) {
     return 1;
-  else
+  } else {
     return -1;
+  }
 }
 
-int       mp_int_compare_value(mp_int z, mp_small value)
-{
+int mp_int_compare_value(mp_int z, mp_small value) {
+  assert(z != NULL);
+
   mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS;
-  int cmp;
-
-  CHECK(z != NULL);
-
   if (vsign == MP_SIGN(z)) {
-    cmp = s_vcmp(z, value);
+    int cmp = s_vcmp(z, value);
 
     return (vsign == MP_ZPOS) ? cmp : -cmp;
-  }
-  else {
+  } else {
     return (value < 0) ? 1 : -1;
   }
 }
 
-int       mp_int_compare_uvalue(mp_int z, mp_usmall uv)
-{
-  CHECK(z != NULL);
+int mp_int_compare_uvalue(mp_int z, mp_usmall uv) {
+  assert(z != NULL);
 
-  if (MP_SIGN(z) == MP_NEG)
+  if (MP_SIGN(z) == MP_NEG) {
     return -1;
-  else
+  } else {
     return s_uvcmp(z, uv);
+  }
 }
 
-mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c)
-{
-  mp_result res;
-  mp_size um;
-  mp_int s;
-  DECLARE_TEMP(3);
-
-  CHECK(a != NULL && b != NULL && c != NULL && m != NULL);
+mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) {
+  assert(a != NULL && b != NULL && c != NULL && m != NULL);
 
   /* Zero moduli and negative exponents are not considered. */
-  if (CMPZ(m) == 0)
-    return MP_UNDEF;
-  if (CMPZ(b) < 0)
-    return MP_RANGE;
+  if (CMPZ(m) == 0) return MP_UNDEF;
+  if (CMPZ(b) < 0) return MP_RANGE;
 
-  um = MP_USED(m);
-  SETUP(mp_int_init_size(TEMP(0), 2 * um));
-  SETUP(mp_int_init_size(TEMP(1), 2 * um));
+  mp_size um = MP_USED(m);
+  DECLARE_TEMP(3);
+  REQUIRE(GROW(TEMP(0), 2 * um));
+  REQUIRE(GROW(TEMP(1), 2 * um));
 
+  mp_int s;
   if (c == b || c == m) {
-    SETUP(mp_int_init_size(TEMP(2), 2 * um));
+    REQUIRE(GROW(TEMP(2), 2 * um));
     s = TEMP(2);
-  }
-  else {
+  } else {
     s = c;
   }
 
-  if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP;
-
-  if ((res = s_brmu(TEMP(1), m)) != MP_OK) goto CLEANUP;
-
-  if ((res = s_embar(TEMP(0), b, m, TEMP(1), s)) != MP_OK)
-    goto CLEANUP;
-
-  res = mp_int_copy(s, c);
+  REQUIRE(mp_int_mod(a, m, TEMP(0)));
+  REQUIRE(s_brmu(TEMP(1), m));
+  REQUIRE(s_embar(TEMP(0), b, m, TEMP(1), s));
+  REQUIRE(mp_int_copy(s, c));
 
   CLEANUP_TEMP();
-  return res;
+  return MP_OK;
 }
 
-mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c)
-{
+mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c) {
   mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(value)];
 
@@ -1211,9 +1072,7 @@
   return mp_int_exptmod(a, &vtmp, m, c);
 }
 
-mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b,
-				mp_int m, mp_int c)
-{
+mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c) {
   mpz_t vtmp;
   mp_digit vbuf[MP_VALUE_DIGITS(value)];
 
@@ -1222,228 +1081,184 @@
   return mp_int_exptmod(&vtmp, b, m, c);
 }
 
-mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
-{
-  mp_result res;
-  mp_size um;
-  mp_int s;
-  DECLARE_TEMP(2);
-
-  CHECK(a && b && m && c);
+mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu,
+                               mp_int c) {
+  assert(a && b && m && c);
 
   /* Zero moduli and negative exponents are not considered. */
-  if (CMPZ(m) == 0)
-    return MP_UNDEF;
-  if (CMPZ(b) < 0)
-    return MP_RANGE;
+  if (CMPZ(m) == 0) return MP_UNDEF;
+  if (CMPZ(b) < 0) return MP_RANGE;
 
-  um = MP_USED(m);
-  SETUP(mp_int_init_size(TEMP(0), 2 * um));
+  DECLARE_TEMP(2);
+  mp_size um = MP_USED(m);
+  REQUIRE(GROW(TEMP(0), 2 * um));
 
+  mp_int s;
   if (c == b || c == m) {
-    SETUP(mp_int_init_size(TEMP(1), 2 * um));
+    REQUIRE(GROW(TEMP(1), 2 * um));
     s = TEMP(1);
-  }
-  else {
+  } else {
     s = c;
   }
 
-  if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP;
-
-  if ((res = s_embar(TEMP(0), b, m, mu, s)) != MP_OK)
-    goto CLEANUP;
-
-  res = mp_int_copy(s, c);
+  REQUIRE(mp_int_mod(a, m, TEMP(0)));
+  REQUIRE(s_embar(TEMP(0), b, m, mu, s));
+  REQUIRE(mp_int_copy(s, c));
 
   CLEANUP_TEMP();
-  return res;
+  return MP_OK;
 }
 
-mp_result mp_int_redux_const(mp_int m, mp_int c)
-{
-  CHECK(m != NULL && c != NULL && m != c);
+mp_result mp_int_redux_const(mp_int m, mp_int c) {
+  assert(m != NULL && c != NULL && m != c);
 
   return s_brmu(c, m);
 }
 
-mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c)
-{
-  mp_result res;
-  mp_sign sa;
+mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c) {
+  assert(a != NULL && m != NULL && c != NULL);
+
+  if (CMPZ(a) == 0 || CMPZ(m) <= 0) return MP_RANGE;
+
   DECLARE_TEMP(2);
 
-  CHECK(a != NULL && m != NULL && c != NULL);
-
-  if (CMPZ(a) == 0 || CMPZ(m) <= 0)
-    return MP_RANGE;
-
-  sa = MP_SIGN(a); /* need this for the result later */
-
-  for (last__ = 0; last__ < 2; ++last__)
-    mp_int_init(LAST_TEMP());
-
-  if ((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK)
-    goto CLEANUP;
+  REQUIRE(mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL));
 
   if (mp_int_compare_value(TEMP(0), 1) != 0) {
-    res = MP_UNDEF;
-    goto CLEANUP;
+    REQUIRE(MP_UNDEF);
   }
 
   /* It is first necessary to constrain the value to the proper range */
-  if ((res = mp_int_mod(TEMP(1), m, TEMP(1))) != MP_OK)
-    goto CLEANUP;
+  REQUIRE(mp_int_mod(TEMP(1), m, TEMP(1)));
 
   /* Now, if 'a' was originally negative, the value we have is actually the
      magnitude of the negative representative; to get the positive value we
      have to subtract from the modulus.  Otherwise, the value is okay as it
      stands.
    */
-  if (sa == MP_NEG)
-    res = mp_int_sub(m, TEMP(1), c);
-  else
-    res = mp_int_copy(TEMP(1), c);
+  if (MP_SIGN(a) == MP_NEG) {
+    REQUIRE(mp_int_sub(m, TEMP(1), c));
+  } else {
+    REQUIRE(mp_int_copy(TEMP(1), c));
+  }
 
   CLEANUP_TEMP();
-  return res;
+  return MP_OK;
 }
 
 /* Binary GCD algorithm due to Josef Stein, 1961 */
-mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
-{
-  int ca, cb, k = 0;
-  mpz_t u, v, t;
-  mp_result res;
+mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c) {
+  assert(a != NULL && b != NULL && c != NULL);
 
-  CHECK(a != NULL && b != NULL && c != NULL);
-
-  ca = CMPZ(a);
-  cb = CMPZ(b);
-  if (ca == 0 && cb == 0)
+  int ca = CMPZ(a);
+  int cb = CMPZ(b);
+  if (ca == 0 && cb == 0) {
     return MP_UNDEF;
-  else if (ca == 0)
+  } else if (ca == 0) {
     return mp_int_abs(b, c);
-  else if (cb == 0)
+  } else if (cb == 0) {
     return mp_int_abs(a, c);
+  }
 
-  mp_int_init(&t);
-  if ((res = mp_int_init_copy(&u, a)) != MP_OK)
-    goto U;
-  if ((res = mp_int_init_copy(&v, b)) != MP_OK)
-    goto V;
+  DECLARE_TEMP(3);
+  REQUIRE(mp_int_copy(a, TEMP(0)));
+  REQUIRE(mp_int_copy(b, TEMP(1)));
 
-  MP_SIGN(&u) = MP_ZPOS; MP_SIGN(&v) = MP_ZPOS;
+  TEMP(0)->sign = MP_ZPOS;
+  TEMP(1)->sign = MP_ZPOS;
 
+  int k = 0;
   { /* Divide out common factors of 2 from u and v */
-    int div2_u = s_dp2k(&u), div2_v = s_dp2k(&v);
+    int div2_u = s_dp2k(TEMP(0));
+    int div2_v = s_dp2k(TEMP(1));
 
     k = MIN(div2_u, div2_v);
-    s_qdiv(&u, (mp_size) k);
-    s_qdiv(&v, (mp_size) k);
+    s_qdiv(TEMP(0), (mp_size)k);
+    s_qdiv(TEMP(1), (mp_size)k);
   }
 
-  if (mp_int_is_odd(&u)) {
-    if ((res = mp_int_neg(&v, &t)) != MP_OK)
-      goto CLEANUP;
-  }
-  else {
-    if ((res = mp_int_copy(&u, &t)) != MP_OK)
-      goto CLEANUP;
+  if (mp_int_is_odd(TEMP(0))) {
+    REQUIRE(mp_int_neg(TEMP(1), TEMP(2)));
+  } else {
+    REQUIRE(mp_int_copy(TEMP(0), TEMP(2)));
   }
 
   for (;;) {
-    s_qdiv(&t, s_dp2k(&t));
+    s_qdiv(TEMP(2), s_dp2k(TEMP(2)));
 
-    if (CMPZ(&t) > 0) {
-      if ((res = mp_int_copy(&t, &u)) != MP_OK)
-	goto CLEANUP;
-    }
-    else {
-      if ((res = mp_int_neg(&t, &v)) != MP_OK)
-	goto CLEANUP;
+    if (CMPZ(TEMP(2)) > 0) {
+      REQUIRE(mp_int_copy(TEMP(2), TEMP(0)));
+    } else {
+      REQUIRE(mp_int_neg(TEMP(2), TEMP(1)));
     }
 
-    if ((res = mp_int_sub(&u, &v, &t)) != MP_OK)
-      goto CLEANUP;
+    REQUIRE(mp_int_sub(TEMP(0), TEMP(1), TEMP(2)));
 
-    if (CMPZ(&t) == 0)
-      break;
+    if (CMPZ(TEMP(2)) == 0) break;
   }
 
-  if ((res = mp_int_abs(&u, c)) != MP_OK)
-    goto CLEANUP;
-  if (!s_qmul(c, (mp_size) k))
-    res = MP_MEMORY;
+  REQUIRE(mp_int_abs(TEMP(0), c));
+  if (!s_qmul(c, (mp_size)k)) REQUIRE(MP_MEMORY);
 
- CLEANUP:
-  mp_int_clear(&v);
- V: mp_int_clear(&u);
- U: mp_int_clear(&t);
-
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
 /* This is the binary GCD algorithm again, but this time we keep track of the
    elementary matrix operations as we go, so we can get values x and y
    satisfying c = ax + by.
  */
-mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
-		      mp_int x, mp_int y)
-{
-  int k, ca, cb;
-  mp_result res;
-  DECLARE_TEMP(8);
+mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y) {
+  assert(a != NULL && b != NULL && c != NULL && (x != NULL || y != NULL));
 
-  CHECK(a != NULL && b != NULL && c != NULL &&
-	(x != NULL || y != NULL));
-
-  ca = CMPZ(a);
-  cb = CMPZ(b);
-  if (ca == 0 && cb == 0)
+  mp_result res = MP_OK;
+  int ca = CMPZ(a);
+  int cb = CMPZ(b);
+  if (ca == 0 && cb == 0) {
     return MP_UNDEF;
-  else if (ca == 0) {
+  } else if (ca == 0) {
     if ((res = mp_int_abs(b, c)) != MP_OK) return res;
-    mp_int_zero(x); (void) mp_int_set_value(y, 1); return MP_OK;
-  }
-  else if (cb == 0) {
+    mp_int_zero(x);
+    (void)mp_int_set_value(y, 1);
+    return MP_OK;
+  } else if (cb == 0) {
     if ((res = mp_int_abs(a, c)) != MP_OK) return res;
-    (void) mp_int_set_value(x, 1); mp_int_zero(y); return MP_OK;
+    (void)mp_int_set_value(x, 1);
+    mp_int_zero(y);
+    return MP_OK;
   }
 
   /* Initialize temporaries:
      A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */
-  for (last__ = 0; last__ < 4; ++last__)
-    mp_int_init(LAST_TEMP());
-  TEMP(0)->digits[0] = 1;
-  TEMP(3)->digits[0] = 1;
-
-  SETUP(mp_int_init_copy(TEMP(4), a));
-  SETUP(mp_int_init_copy(TEMP(5), b));
+  DECLARE_TEMP(8);
+  REQUIRE(mp_int_set_value(TEMP(0), 1));
+  REQUIRE(mp_int_set_value(TEMP(3), 1));
+  REQUIRE(mp_int_copy(a, TEMP(4)));
+  REQUIRE(mp_int_copy(b, TEMP(5)));
 
   /* We will work with absolute values here */
-  MP_SIGN(TEMP(4)) = MP_ZPOS;
-  MP_SIGN(TEMP(5)) = MP_ZPOS;
+  TEMP(4)->sign = MP_ZPOS;
+  TEMP(5)->sign = MP_ZPOS;
 
+  int k = 0;
   { /* Divide out common factors of 2 from u and v */
-    int  div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5));
+    int div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5));
 
     k = MIN(div2_u, div2_v);
     s_qdiv(TEMP(4), k);
     s_qdiv(TEMP(5), k);
   }
 
-  SETUP(mp_int_init_copy(TEMP(6), TEMP(4)));
-  SETUP(mp_int_init_copy(TEMP(7), TEMP(5)));
+  REQUIRE(mp_int_copy(TEMP(4), TEMP(6)));
+  REQUIRE(mp_int_copy(TEMP(5), TEMP(7)));
 
   for (;;) {
     while (mp_int_is_even(TEMP(4))) {
       s_qdiv(TEMP(4), 1);
 
       if (mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) {
-	if ((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK)
-	  goto CLEANUP;
-	if ((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK)
-	  goto CLEANUP;
+        REQUIRE(mp_int_add(TEMP(0), TEMP(7), TEMP(0)));
+        REQUIRE(mp_int_sub(TEMP(1), TEMP(6), TEMP(1)));
       }
 
       s_qdiv(TEMP(0), 1);
@@ -1454,10 +1269,8 @@
       s_qdiv(TEMP(5), 1);
 
       if (mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) {
-	if ((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK)
-	  goto CLEANUP;
-	if ((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK)
-	  goto CLEANUP;
+        REQUIRE(mp_int_add(TEMP(2), TEMP(7), TEMP(2)));
+        REQUIRE(mp_int_sub(TEMP(3), TEMP(6), TEMP(3)));
       }
 
       s_qdiv(TEMP(2), 1);
@@ -1465,26 +1278,23 @@
     }
 
     if (mp_int_compare(TEMP(4), TEMP(5)) >= 0) {
-      if ((res = mp_int_sub(TEMP(4), TEMP(5), TEMP(4))) != MP_OK) goto CLEANUP;
-      if ((res = mp_int_sub(TEMP(0), TEMP(2), TEMP(0))) != MP_OK) goto CLEANUP;
-      if ((res = mp_int_sub(TEMP(1), TEMP(3), TEMP(1))) != MP_OK) goto CLEANUP;
-    }
-    else {
-      if ((res = mp_int_sub(TEMP(5), TEMP(4), TEMP(5))) != MP_OK) goto CLEANUP;
-      if ((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP;
-      if ((res = mp_int_sub(TEMP(3), TEMP(1), TEMP(3))) != MP_OK) goto CLEANUP;
+      REQUIRE(mp_int_sub(TEMP(4), TEMP(5), TEMP(4)));
+      REQUIRE(mp_int_sub(TEMP(0), TEMP(2), TEMP(0)));
+      REQUIRE(mp_int_sub(TEMP(1), TEMP(3), TEMP(1)));
+    } else {
+      REQUIRE(mp_int_sub(TEMP(5), TEMP(4), TEMP(5)));
+      REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2)));
+      REQUIRE(mp_int_sub(TEMP(3), TEMP(1), TEMP(3)));
     }
 
     if (CMPZ(TEMP(4)) == 0) {
-      if (x && (res = mp_int_copy(TEMP(2), x)) != MP_OK) goto CLEANUP;
-      if (y && (res = mp_int_copy(TEMP(3), y)) != MP_OK) goto CLEANUP;
+      if (x) REQUIRE(mp_int_copy(TEMP(2), x));
+      if (y) REQUIRE(mp_int_copy(TEMP(3), y));
       if (c) {
-	if (!s_qmul(TEMP(5), k)) {
-	  res = MP_MEMORY;
-	  goto CLEANUP;
-	}
-
-	res = mp_int_copy(TEMP(5), c);
+        if (!s_qmul(TEMP(5), k)) {
+          REQUIRE(MP_MEMORY);
+        }
+        REQUIRE(mp_int_copy(TEMP(5), c));
       }
 
       break;
@@ -1492,15 +1302,11 @@
   }
 
   CLEANUP_TEMP();
-  return res;
+  return MP_OK;
 }
 
-mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c)
-{
-  mpz_t lcm;
-  mp_result res;
-
-  CHECK(a != NULL && b != NULL && c != NULL);
+mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c) {
+  assert(a != NULL && b != NULL && c != NULL);
 
   /* Since a * b = gcd(a, b) * lcm(a, b), we can compute
      lcm(a, b) = (a / gcd(a, b)) * b.
@@ -1508,36 +1314,27 @@
      This formulation insures everything works even if the input
      variables share space.
    */
-  if ((res = mp_int_init(&lcm)) != MP_OK)
-    return res;
-  if ((res = mp_int_gcd(a, b, &lcm)) != MP_OK)
-    goto CLEANUP;
-  if ((res = mp_int_div(a, &lcm, &lcm, NULL)) != MP_OK)
-    goto CLEANUP;
-  if ((res = mp_int_mul(&lcm, b, &lcm)) != MP_OK)
-    goto CLEANUP;
+  DECLARE_TEMP(1);
+  REQUIRE(mp_int_gcd(a, b, TEMP(0)));
+  REQUIRE(mp_int_div(a, TEMP(0), TEMP(0), NULL));
+  REQUIRE(mp_int_mul(TEMP(0), b, TEMP(0)));
+  REQUIRE(mp_int_copy(TEMP(0), c));
 
-  res = mp_int_copy(&lcm, c);
-
-  CLEANUP:
-    mp_int_clear(&lcm);
-
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
-int       mp_int_divisible_value(mp_int a, mp_small v)
-{
+bool mp_int_divisible_value(mp_int a, mp_small v) {
   mp_small rem = 0;
 
-  if (mp_int_div_value(a, v, NULL, &rem) != MP_OK)
-    return 0;
-
+  if (mp_int_div_value(a, v, NULL, &rem) != MP_OK) {
+    return false;
+  }
   return rem == 0;
 }
 
-int       mp_int_is_pow2(mp_int z)
-{
-  CHECK(z != NULL);
+int mp_int_is_pow2(mp_int z) {
+  assert(z != NULL);
 
   return s_isp2(z);
 }
@@ -1546,149 +1343,114 @@
    contributed by Hal Finkel <half@halssoftware.com>
    modified by M. J. Fromberger.
  */
-mp_result mp_int_root(mp_int a, mp_small b, mp_int c)
-{
-  mp_result res = MP_OK;
-  int flips = 0;
-  DECLARE_TEMP(5);
-
-  CHECK(a != NULL && c != NULL && b > 0);
+mp_result mp_int_root(mp_int a, mp_small b, mp_int c) {
+  assert(a != NULL && c != NULL && b > 0);
 
   if (b == 1) {
     return mp_int_copy(a, c);
   }
+  bool flips = false;
   if (MP_SIGN(a) == MP_NEG) {
-    if (b % 2 == 0)
+    if (b % 2 == 0) {
       return MP_UNDEF; /* root does not exist for negative a with even b */
-    else
-      flips = 1;
+    } else {
+      flips = true;
+    }
   }
 
-  SETUP(mp_int_init_copy(LAST_TEMP(), a));
-  SETUP(mp_int_init_copy(LAST_TEMP(), a));
-  SETUP(mp_int_init(LAST_TEMP()));
-  SETUP(mp_int_init(LAST_TEMP()));
-  SETUP(mp_int_init(LAST_TEMP()));
-
-  (void) mp_int_abs(TEMP(0), TEMP(0));
-  (void) mp_int_abs(TEMP(1), TEMP(1));
+  DECLARE_TEMP(5);
+  REQUIRE(mp_int_copy(a, TEMP(0)));
+  REQUIRE(mp_int_copy(a, TEMP(1)));
+  TEMP(0)->sign = MP_ZPOS;
+  TEMP(1)->sign = MP_ZPOS;
 
   for (;;) {
-    if ((res = mp_int_expt(TEMP(1), b, TEMP(2))) != MP_OK)
-      goto CLEANUP;
+    REQUIRE(mp_int_expt(TEMP(1), b, TEMP(2)));
 
-    if (mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0)
-      break;
+    if (mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) break;
 
-    if ((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK)
-      goto CLEANUP;
-    if ((res = mp_int_expt(TEMP(1), b - 1, TEMP(3))) != MP_OK)
-      goto CLEANUP;
-    if ((res = mp_int_mul_value(TEMP(3), b, TEMP(3))) != MP_OK)
-      goto CLEANUP;
-    if ((res = mp_int_div(TEMP(2), TEMP(3), TEMP(4), NULL)) != MP_OK)
-      goto CLEANUP;
-    if ((res = mp_int_sub(TEMP(1), TEMP(4), TEMP(4))) != MP_OK)
-      goto CLEANUP;
+    REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2)));
+    REQUIRE(mp_int_expt(TEMP(1), b - 1, TEMP(3)));
+    REQUIRE(mp_int_mul_value(TEMP(3), b, TEMP(3)));
+    REQUIRE(mp_int_div(TEMP(2), TEMP(3), TEMP(4), NULL));
+    REQUIRE(mp_int_sub(TEMP(1), TEMP(4), TEMP(4)));
 
     if (mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) {
-      if ((res = mp_int_sub_value(TEMP(4), 1, TEMP(4))) != MP_OK)
-	goto CLEANUP;
+      REQUIRE(mp_int_sub_value(TEMP(4), 1, TEMP(4)));
     }
-    if ((res = mp_int_copy(TEMP(4), TEMP(1))) != MP_OK)
-      goto CLEANUP;
+    REQUIRE(mp_int_copy(TEMP(4), TEMP(1)));
   }
 
-  if ((res = mp_int_copy(TEMP(1), c)) != MP_OK)
-    goto CLEANUP;
+  REQUIRE(mp_int_copy(TEMP(1), c));
 
   /* If the original value of a was negative, flip the output sign. */
-  if (flips)
-    (void) mp_int_neg(c, c); /* cannot fail */
+  if (flips) (void)mp_int_neg(c, c); /* cannot fail */
 
   CLEANUP_TEMP();
-  return res;
+  return MP_OK;
 }
 
-mp_result mp_int_to_int(mp_int z, mp_small *out)
-{
-  mp_usmall uv = 0;
-  mp_size   uz;
-  mp_digit *dz;
-  mp_sign   sz;
-
-  CHECK(z != NULL);
+mp_result mp_int_to_int(mp_int z, mp_small *out) {
+  assert(z != NULL);
 
   /* Make sure the value is representable as a small integer */
-  sz = MP_SIGN(z);
+  mp_sign sz = MP_SIGN(z);
   if ((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) ||
-      mp_int_compare_value(z, MP_SMALL_MIN) < 0)
+      mp_int_compare_value(z, MP_SMALL_MIN) < 0) {
     return MP_RANGE;
+  }
 
-  uz = MP_USED(z);
-  dz = MP_DIGITS(z) + uz - 1;
-
+  mp_usmall uz = MP_USED(z);
+  mp_digit *dz = MP_DIGITS(z) + uz - 1;
+  mp_small uv = 0;
   while (uz > 0) {
-    uv <<= MP_DIGIT_BIT/2;
-    uv = (uv << (MP_DIGIT_BIT/2)) | *dz--;
+    uv <<= MP_DIGIT_BIT / 2;
+    uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--;
     --uz;
   }
 
-  if (out)
-    *out = (mp_small)((sz == MP_NEG) ? -uv : uv);
+  if (out) *out = (mp_small)((sz == MP_NEG) ? -uv : uv);
 
   return MP_OK;
 }
 
-mp_result mp_int_to_uint(mp_int z, mp_usmall *out)
-{
-  mp_usmall uv = 0;
-  mp_size   uz;
-  mp_digit *dz;
-  mp_sign   sz;
-  
-  CHECK(z != NULL);
+mp_result mp_int_to_uint(mp_int z, mp_usmall *out) {
+  assert(z != NULL);
 
   /* Make sure the value is representable as an unsigned small integer */
-  sz = MP_SIGN(z);
-  if (sz == MP_NEG || mp_int_compare_uvalue(z, MP_USMALL_MAX) > 0)
+  mp_size sz = MP_SIGN(z);
+  if (sz == MP_NEG || mp_int_compare_uvalue(z, MP_USMALL_MAX) > 0) {
     return MP_RANGE;
-     
-  uz = MP_USED(z);
-  dz = MP_DIGITS(z) + uz - 1;
-  
+  }
+
+  mp_size uz = MP_USED(z);
+  mp_digit *dz = MP_DIGITS(z) + uz - 1;
+  mp_usmall uv = 0;
+
   while (uz > 0) {
-    uv <<= MP_DIGIT_BIT/2;
-    uv = (uv << (MP_DIGIT_BIT/2)) | *dz--;
+    uv <<= MP_DIGIT_BIT / 2;
+    uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--;
     --uz;
   }
-  
-  if (out)
-    *out = uv;
-  
+
+  if (out) *out = uv;
+
   return MP_OK;
 }
 
-mp_result mp_int_to_string(mp_int z, mp_size radix,
-			   char *str, int limit)
-{
-  mp_result res;
-  int       cmp = 0;
+mp_result mp_int_to_string(mp_int z, mp_size radix, char *str, int limit) {
+  assert(z != NULL && str != NULL && limit >= 2);
+  assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX);
 
-  CHECK(z != NULL && str != NULL && limit >= 2);
-
-  if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
-    return MP_RANGE;
-
+  int cmp = 0;
   if (CMPZ(z) == 0) {
     *str++ = s_val2ch(0, 1);
-  }
-  else {
+  } else {
+    mp_result res;
     mpz_t tmp;
-    char  *h, *t;
+    char *h, *t;
 
-    if ((res = mp_int_init_copy(&tmp, z)) != MP_OK)
-      return res;
+    if ((res = mp_int_init_copy(&tmp, z)) != MP_OK) return res;
 
     if (MP_SIGN(z) == MP_NEG) {
       *str++ = '-';
@@ -1700,8 +1462,7 @@
     for (/* */; limit > 0; --limit) {
       mp_digit d;
 
-      if ((cmp = CMPZ(&tmp)) == 0)
-	break;
+      if ((cmp = CMPZ(&tmp)) == 0) break;
 
       d = s_ddiv(&tmp, (mp_digit)radix);
       *str++ = s_val2ch(d, 1);
@@ -1719,71 +1480,60 @@
   }
 
   *str = '\0';
-  if (cmp == 0)
+  if (cmp == 0) {
     return MP_OK;
-  else
+  } else {
     return MP_TRUNC;
+  }
 }
 
-mp_result mp_int_string_len(mp_int z, mp_size radix)
-{
-  int  len;
+mp_result mp_int_string_len(mp_int z, mp_size radix) {
+  assert(z != NULL);
+  assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX);
 
-  CHECK(z != NULL);
-
-  if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
-    return MP_RANGE;
-
-  len = s_outlen(z, radix) + 1; /* for terminator */
+  int len = s_outlen(z, radix) + 1; /* for terminator */
 
   /* Allow for sign marker on negatives */
-  if (MP_SIGN(z) == MP_NEG)
-    len += 1;
+  if (MP_SIGN(z) == MP_NEG) len += 1;
 
   return len;
 }
 
 /* Read zero-terminated string into z */
-mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str)
-{
+mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str) {
   return mp_int_read_cstring(z, radix, str, NULL);
 }
 
-mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end)
-{
-  int ch;
-
-  CHECK(z != NULL && str != NULL);
-
-  if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
-    return MP_RANGE;
+mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
+                              char **end) {
+  assert(z != NULL && str != NULL);
+  assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX);
 
   /* Skip leading whitespace */
-  while (isspace((int)*str))
-    ++str;
+  while (isspace((unsigned char)*str)) ++str;
 
   /* Handle leading sign tag (+/-, positive default) */
   switch (*str) {
-  case '-':
-    MP_SIGN(z) = MP_NEG;
-    ++str;
-    break;
-  case '+':
-    ++str; /* fallthrough */
-  default:
-    MP_SIGN(z) = MP_ZPOS;
-    break;
+    case '-':
+      z->sign = MP_NEG;
+      ++str;
+      break;
+    case '+':
+      ++str; /* fallthrough */
+    default:
+      z->sign = MP_ZPOS;
+      break;
   }
 
   /* Skip leading zeroes */
-  while ((ch = s_ch2val(*str, radix)) == 0)
-    ++str;
+  int ch;
+  while ((ch = s_ch2val(*str, radix)) == 0) ++str;
 
   /* Make sure there is enough space for the value */
-  if (!s_pad(z, s_inlen(strlen(str), radix)))
-    return MP_MEMORY;
+  if (!s_pad(z, s_inlen(strlen(str), radix))) return MP_MEMORY;
 
-  MP_USED(z) = 1; z->digits[0] = 0;
+  z->used = 1;
+  z->digits[0] = 0;
 
   while (*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) {
     s_dmul(z, (mp_digit)radix);
@@ -1794,34 +1544,28 @@
   CLAMP(z);
 
   /* Override sign for zero, even if negative specified. */
-  if (CMPZ(z) == 0)
-    MP_SIGN(z) = MP_ZPOS;
+  if (CMPZ(z) == 0) z->sign = MP_ZPOS;
 
-  if (end != NULL)
-    *end = (char *)str;
+  if (end != NULL) *end = (char *)str;
 
   /* Return a truncation error if the string has unprocessed characters
      remaining, so the caller can tell if the whole string was done */
-  if (*str != '\0')
+  if (*str != '\0') {
     return MP_TRUNC;
-  else
+  } else {
     return MP_OK;
+  }
 }
 
-mp_result mp_int_count_bits(mp_int z)
-{
-  mp_size  nbits = 0, uz;
-  mp_digit d;
+mp_result mp_int_count_bits(mp_int z) {
+  assert(z != NULL);
 
-  CHECK(z != NULL);
-
-  uz = MP_USED(z);
-  if (uz == 1 && z->digits[0] == 0)
-    return 1;
+  mp_size uz = MP_USED(z);
+  if (uz == 1 && z->digits[0] == 0) return 1;
 
   --uz;
-  nbits = uz * MP_DIGIT_BIT;
-  d = z->digits[uz];
+  mp_size nbits = uz * MP_DIGIT_BIT;
+  mp_digit d = z->digits[uz];
 
   while (d != 0) {
     d >>= 1;
@@ -1831,215 +1575,173 @@
   return nbits;
 }
 
-mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit)
-{
+mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit) {
   static const int PAD_FOR_2C = 1;
 
-  mp_result res;
+  assert(z != NULL && buf != NULL);
+
   int limpos = limit;
+  mp_result res = s_tobin(z, buf, &limpos, PAD_FOR_2C);
 
-  CHECK(z != NULL && buf != NULL);
-
-  res = s_tobin(z, buf, &limpos, PAD_FOR_2C);
-
-  if (MP_SIGN(z) == MP_NEG)
-    s_2comp(buf, limpos);
+  if (MP_SIGN(z) == MP_NEG) s_2comp(buf, limpos);
 
   return res;
 }
 
-mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len)
-{
-  mp_size need, i;
-  unsigned char *tmp;
-  mp_digit *dz;
-
-  CHECK(z != NULL && buf != NULL && len > 0);
+mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len) {
+  assert(z != NULL && buf != NULL && len > 0);
 
   /* Figure out how many digits are needed to represent this value */
-  need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
-  if (!s_pad(z, need))
-    return MP_MEMORY;
+  mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
+  if (!s_pad(z, need)) return MP_MEMORY;
 
   mp_int_zero(z);
 
   /* If the high-order bit is set, take the 2's complement before reading the
      value (it will be restored afterward) */
   if (buf[0] >> (CHAR_BIT - 1)) {
-    MP_SIGN(z) = MP_NEG;
+    z->sign = MP_NEG;
     s_2comp(buf, len);
   }
 
-  dz = MP_DIGITS(z);
-  for (tmp = buf, i = len; i > 0; --i, ++tmp) {
-    s_qmul(z, (mp_size) CHAR_BIT);
+  mp_digit *dz = MP_DIGITS(z);
+  unsigned char *tmp = buf;
+  for (int i = len; i > 0; --i, ++tmp) {
+    s_qmul(z, (mp_size)CHAR_BIT);
     *dz |= *tmp;
   }
 
   /* Restore 2's complement if we took it before */
-  if (MP_SIGN(z) == MP_NEG)
-    s_2comp(buf, len);
+  if (MP_SIGN(z) == MP_NEG) s_2comp(buf, len);
 
   return MP_OK;
 }
 
-mp_result mp_int_binary_len(mp_int z)
-{
-  mp_result  res = mp_int_count_bits(z);
-  int        bytes = mp_int_unsigned_len(z);
+mp_result mp_int_binary_len(mp_int z) {
+  mp_result res = mp_int_count_bits(z);
+  if (res <= 0) return res;
 
-  if (res <= 0)
-    return res;
-
-  bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT;
+  int bytes = mp_int_unsigned_len(z);
 
   /* If the highest-order bit falls exactly on a byte boundary, we need to pad
      with an extra byte so that the sign will be read correctly when reading it
      back in. */
-  if (bytes * CHAR_BIT == res)
-    ++bytes;
+  if (bytes * CHAR_BIT == res) ++bytes;
 
   return bytes;
 }
 
-mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit)
-{
+mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit) {
   static const int NO_PADDING = 0;
 
-  CHECK(z != NULL && buf != NULL);
+  assert(z != NULL && buf != NULL);
 
   return s_tobin(z, buf, &limit, NO_PADDING);
 }
 
-mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len)
-{
-  mp_size need, i;
-  unsigned char *tmp;
-
-  CHECK(z != NULL && buf != NULL && len > 0);
+mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len) {
+  assert(z != NULL && buf != NULL && len > 0);
 
   /* Figure out how many digits are needed to represent this value */
-  need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
-  if (!s_pad(z, need))
-    return MP_MEMORY;
+  mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
+  if (!s_pad(z, need)) return MP_MEMORY;
 
   mp_int_zero(z);
 
-  for (tmp = buf, i = len; i > 0; --i, ++tmp) {
-    (void) s_qmul(z, CHAR_BIT);
+  unsigned char *tmp = buf;
+  for (int i = len; i > 0; --i, ++tmp) {
+    (void)s_qmul(z, CHAR_BIT);
     *MP_DIGITS(z) |= *tmp;
   }
 
   return MP_OK;
 }
 
-mp_result mp_int_unsigned_len(mp_int z)
-{
-  mp_result  res = mp_int_count_bits(z);
-  int        bytes;
+mp_result mp_int_unsigned_len(mp_int z) {
+  mp_result res = mp_int_count_bits(z);
+  if (res <= 0) return res;
 
-  if (res <= 0)
-    return res;
-
-  bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT;
-
+  int bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT;
   return bytes;
 }
 
-const char *mp_error_string(mp_result res)
-{
-  int ix;
-  if (res > 0)
-    return s_unknown_err;
+const char *mp_error_string(mp_result res) {
+  if (res > 0) return s_unknown_err;
 
   res = -res;
+  int ix;
   for (ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix)
     ;
 
-  if (s_error_msg[ix] != NULL)
+  if (s_error_msg[ix] != NULL) {
     return s_error_msg[ix];
-  else
+  } else {
     return s_unknown_err;
+  }
 }
 
 /*------------------------------------------------------------------------*/
 /* Private functions for internal use.  These make assumptions.           */
 
-STATIC mp_digit *s_alloc(mp_size num)
-{
-  mp_digit *out = malloc(num * sizeof(mp_digit));
-
-  assert(out != NULL); /* for debugging */
-#if DEBUG > 1
-  {
-    mp_digit v = (mp_digit) 0xdeadbeef;
-    int      ix;
-
-    for (ix = 0; ix < num; ++ix)
-      out[ix] = v;
-  }
+#if DEBUG
+static const mp_digit fill = (mp_digit)0xdeadbeefabad1dea;
 #endif
 
+static mp_digit *s_alloc(mp_size num) {
+  mp_digit *out = malloc(num * sizeof(mp_digit));
+  assert(out != NULL);
+
+#if DEBUG
+  for (mp_size ix = 0; ix < num; ++ix) out[ix] = fill;
+#endif
   return out;
 }
 
-STATIC mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize)
-{
-#if DEBUG > 1
+static mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize) {
+#if DEBUG
   mp_digit *new = s_alloc(nsize);
-  int       ix;
+  assert(new != NULL);
 
-  for (ix = 0; ix < nsize; ++ix)
-    new[ix] = (mp_digit) 0xdeadbeef;
-
+  for (mp_size ix = 0; ix < nsize; ++ix) new[ix] = fill;
   memcpy(new, old, osize * sizeof(mp_digit));
 #else
   mp_digit *new = realloc(old, nsize * sizeof(mp_digit));
-
-  assert(new != NULL); /* for debugging */
+  assert(new != NULL);
 #endif
+
   return new;
 }
 
-STATIC void s_free(void *ptr)
-{
-  free(ptr);
-}
+static void s_free(void *ptr) { free(ptr); }
 
-STATIC int      s_pad(mp_int z, mp_size min)
-{
+static bool s_pad(mp_int z, mp_size min) {
   if (MP_ALLOC(z) < min) {
-    mp_size nsize = ROUND_PREC(min);
+    mp_size nsize = s_round_prec(min);
     mp_digit *tmp;
 
-    if ((void *)z->digits == (void *)z) {
-      if ((tmp = s_alloc(nsize)) == NULL)
-        return 0;
-
-      COPY(MP_DIGITS(z), tmp, MP_USED(z));
+    if (z->digits == &(z->single)) {
+      if ((tmp = s_alloc(nsize)) == NULL) return false;
+      tmp[0] = z->single;
+    } else if ((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) {
+      return false;
     }
-    else if ((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL)
-      return 0;
 
-    MP_DIGITS(z) = tmp;
-    MP_ALLOC(z) = nsize;
+    z->digits = tmp;
+    z->alloc = nsize;
   }
 
-  return 1;
+  return true;
 }
 
 /* Note: This will not work correctly when value == MP_SMALL_MIN */
-STATIC void      s_fake(mp_int z, mp_small value, mp_digit vbuf[])
-{
-  mp_usmall uv = (mp_usmall) (value < 0) ? -value : value;
+static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]) {
+  mp_usmall uv = (mp_usmall)(value < 0) ? -value : value;
   s_ufake(z, uv, vbuf);
-  if (value < 0)
-    z->sign = MP_NEG;
+  if (value < 0) z->sign = MP_NEG;
 }
 
-STATIC void      s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[])
-{
-  mp_size ndig = (mp_size) s_uvpack(value, vbuf);
+static void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]) {
+  mp_size ndig = (mp_size)s_uvpack(value, vbuf);
 
   z->used = ndig;
   z->alloc = MP_VALUE_DIGITS(value);
@@ -2047,57 +1749,54 @@
   z->digits = vbuf;
 }
 
-STATIC int      s_cdig(mp_digit *da, mp_digit *db, mp_size len)
-{
+static int s_cdig(mp_digit *da, mp_digit *db, mp_size len) {
   mp_digit *dat = da + len - 1, *dbt = db + len - 1;
 
   for (/* */; len != 0; --len, --dat, --dbt) {
-    if (*dat > *dbt)
+    if (*dat > *dbt) {
       return 1;
-    else if (*dat < *dbt)
+    } else if (*dat < *dbt) {
       return -1;
+    }
   }
 
   return 0;
 }
 
-STATIC int       s_uvpack(mp_usmall uv, mp_digit t[])
-{
+static int s_uvpack(mp_usmall uv, mp_digit t[]) {
   int ndig = 0;
 
   if (uv == 0)
     t[ndig++] = 0;
   else {
     while (uv != 0) {
-      t[ndig++] = (mp_digit) uv;
-      uv >>= MP_DIGIT_BIT/2;
-      uv >>= MP_DIGIT_BIT/2;
+      t[ndig++] = (mp_digit)uv;
+      uv >>= MP_DIGIT_BIT / 2;
+      uv >>= MP_DIGIT_BIT / 2;
     }
   }
 
   return ndig;
 }
 
-STATIC int      s_ucmp(mp_int a, mp_int b)
-{
-  mp_size  ua = MP_USED(a), ub = MP_USED(b);
+static int s_ucmp(mp_int a, mp_int b) {
+  mp_size ua = MP_USED(a), ub = MP_USED(b);
 
-  if (ua > ub)
+  if (ua > ub) {
     return 1;
-  else if (ub > ua)
+  } else if (ub > ua) {
     return -1;
-  else
+  } else {
     return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua);
+  }
 }
 
-STATIC int      s_vcmp(mp_int a, mp_small v)
-{
-  mp_usmall uv = (v < 0) ? -(mp_usmall) v : (mp_usmall) v;
+static int s_vcmp(mp_int a, mp_small v) {
+  mp_usmall uv = (v < 0) ? -(mp_usmall)v : (mp_usmall)v;
   return s_uvcmp(a, uv);
 }
 
-STATIC int      s_uvcmp(mp_int a, mp_usmall uv)
-{
+static int s_uvcmp(mp_int a, mp_usmall uv) {
   mpz_t vtmp;
   mp_digit vdig[MP_VALUE_DIGITS(uv)];
 
@@ -2105,9 +1804,8 @@
   return s_ucmp(a, &vtmp);
 }
 
-STATIC mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
-		       mp_size size_a, mp_size size_b)
-{
+static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                       mp_size size_b) {
   mp_size pos;
   mp_word w = 0;
 
@@ -2119,7 +1817,7 @@
 
   /* Add corresponding digits until the shorter number runs out */
   for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) {
-    w = w + (mp_word) *da + (mp_word) *db;
+    w = w + (mp_word)*da + (mp_word)*db;
     *dc = LOWER_HALF(w);
     w = UPPER_HALF(w);
   }
@@ -2136,9 +1834,8 @@
   return (mp_digit)w;
 }
 
-STATIC void     s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
-		       mp_size size_a, mp_size size_b)
-{
+static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                   mp_size size_b) {
   mp_size pos;
   mp_word w = 0;
 
@@ -2147,8 +1844,9 @@
 
   /* Subtract corresponding digits and propagate borrow */
   for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) {
-    w = ((mp_word)MP_DIGIT_MAX + 1 +  /* MP_RADIX */
-	 (mp_word)*da) - w - (mp_word)*db;
+    w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */
+         (mp_word)*da) -
+        w - (mp_word)*db;
 
     *dc = LOWER_HALF(w);
     w = (UPPER_HALF(w) == 0);
@@ -2156,8 +1854,9 @@
 
   /* Finish the subtraction for remaining upper digits of da */
   for (/* */; pos < size_a; ++pos, ++da, ++dc) {
-    w = ((mp_word)MP_DIGIT_MAX + 1 +  /* MP_RADIX */
-	 (mp_word)*da) - w;
+    w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */
+         (mp_word)*da) -
+        w;
 
     *dc = LOWER_HALF(w);
     w = (UPPER_HALF(w) == 0);
@@ -2167,10 +1866,9 @@
   assert(w == 0);
 }
 
-STATIC int       s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
-			mp_size size_a, mp_size size_b)
-{
-  mp_size  bot_size;
+static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                  mp_size size_b) {
+  mp_size bot_size;
 
   /* Make sure b is the smaller of the two input values */
   if (size_b > size_a) {
@@ -2187,18 +1885,15 @@
      algorithm to compute the product; otherwise use the normal multiplication
      algorithm
    */
-  if (multiply_threshold &&
-      size_a >= multiply_threshold &&
-      size_b > bot_size) {
-
+  if (multiply_threshold && size_a >= multiply_threshold && size_b > bot_size) {
     mp_digit *t1, *t2, *t3, carry;
 
     mp_digit *a_top = da + bot_size;
     mp_digit *b_top = db + bot_size;
 
-    mp_size  at_size = size_a - bot_size;
-    mp_size  bt_size = size_b - bot_size;
-    mp_size  buf_size = 2 * bot_size;
+    mp_size at_size = size_a - bot_size;
+    mp_size bt_size = size_b - bot_size;
+    mp_size buf_size = 2 * bot_size;
 
     /* Do a single allocation for all three temporary buffers needed; each
        buffer must be big enough to hold the product of two bottom halves, and
@@ -2213,21 +1908,21 @@
     /* t1 and t2 are initially used as temporaries to compute the inner product
        (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0
      */
-    carry = s_uadd(da, a_top, t1, bot_size, at_size);      /* t1 = a1 + a0 */
+    carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */
     t1[bot_size] = carry;
 
-    carry = s_uadd(db, b_top, t2, bot_size, bt_size);      /* t2 = b1 + b0 */
+    carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */
     t2[bot_size] = carry;
 
-    (void) s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */
+    (void)s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */
 
     /* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so that
        we're left with only the pieces we want:  t3 = a1b0 + a0b1
      */
     ZERO(t1, buf_size);
     ZERO(t2, buf_size);
-    (void) s_kmul(da, db, t1, bot_size, bot_size);     /* t1 = a0 * b0 */
-    (void) s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */
+    (void)s_kmul(da, db, t1, bot_size, bot_size);     /* t1 = a0 * b0 */
+    (void)s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */
 
     /* Subtract out t1 and t2 to get the inner product */
     s_usub(t3, t1, t3, buf_size + 2, buf_size);
@@ -2235,26 +1930,23 @@
 
     /* Assemble the output value */
     COPY(t1, dc, buf_size);
-    carry = s_uadd(t3, dc + bot_size, dc + bot_size,
-		   buf_size + 1, buf_size);
+    carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size);
     assert(carry == 0);
 
-    carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size,
-		   buf_size, buf_size);
+    carry =
+        s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size);
     assert(carry == 0);
 
     s_free(t1); /* note t2 and t3 are just internal pointers to t1 */
-  }
-  else {
+  } else {
     s_umul(da, db, dc, size_a, size_b);
   }
 
   return 1;
 }
 
-STATIC void     s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
-		       mp_size size_a, mp_size size_b)
-{
+static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a,
+                   mp_size size_b) {
   mp_size a, b;
   mp_word w;
 
@@ -2262,8 +1954,7 @@
     mp_digit *dct = dc;
     mp_digit *dbt = db;
 
-    if (*da == 0)
-      continue;
+    if (*da == 0) continue;
 
     w = 0;
     for (b = 0; b < size_b; ++b, ++dbt, ++dct) {
@@ -2277,24 +1968,23 @@
   }
 }
 
-STATIC int       s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a)
-{
+static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) {
   if (multiply_threshold && size_a > multiply_threshold) {
-    mp_size  bot_size = (size_a + 1) / 2;
+    mp_size bot_size = (size_a + 1) / 2;
     mp_digit *a_top = da + bot_size;
     mp_digit *t1, *t2, *t3, carry;
-    mp_size  at_size = size_a - bot_size;
-    mp_size  buf_size = 2 * bot_size;
+    mp_size at_size = size_a - bot_size;
+    mp_size buf_size = 2 * bot_size;
 
     if ((t1 = s_alloc(4 * buf_size)) == NULL) return 0;
     t2 = t1 + buf_size;
     t3 = t2 + buf_size;
     ZERO(t1, 4 * buf_size);
 
-    (void) s_ksqr(da, t1, bot_size);    /* t1 = a0 ^ 2 */
-    (void) s_ksqr(a_top, t2, at_size);  /* t2 = a1 ^ 2 */
+    (void)s_ksqr(da, t1, bot_size);   /* t1 = a0 ^ 2 */
+    (void)s_ksqr(a_top, t2, at_size); /* t2 = a1 ^ 2 */
 
-    (void) s_kmul(da, a_top, t3, bot_size, at_size);  /* t3 = a0 * a1 */
+    (void)s_kmul(da, a_top, t3, bot_size, at_size); /* t3 = a0 * a1 */
 
     /* Quick multiply t3 by 2, shifting left (can't overflow) */
     {
@@ -2302,79 +1992,75 @@
       mp_word w, save = 0;
 
       for (i = 0; i < top; ++i) {
-	w = t3[i];
-	w = (w << 1) | save;
-	t3[i] = LOWER_HALF(w);
-	save = UPPER_HALF(w);
+        w = t3[i];
+        w = (w << 1) | save;
+        t3[i] = LOWER_HALF(w);
+        save = UPPER_HALF(w);
       }
       t3[i] = LOWER_HALF(save);
     }
 
     /* Assemble the output value */
     COPY(t1, dc, 2 * bot_size);
-    carry = s_uadd(t3, dc + bot_size, dc + bot_size,
-		   buf_size + 1, buf_size);
+    carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size);
     assert(carry == 0);
 
-    carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size,
-		   buf_size, buf_size);
+    carry =
+        s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size);
     assert(carry == 0);
 
     s_free(t1); /* note that t2 and t2 are internal pointers only */
 
-  } 
-  else {
+  } else {
     s_usqr(da, dc, size_a);
   }
 
   return 1;
 }
 
-STATIC void      s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a)
-{
+static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) {
   mp_size i, j;
   mp_word w;
 
   for (i = 0; i < size_a; ++i, dc += 2, ++da) {
-    mp_digit  *dct = dc, *dat = da;
+    mp_digit *dct = dc, *dat = da;
 
-    if (*da == 0)
-      continue;
+    if (*da == 0) continue;
 
     /* Take care of the first digit, no rollover */
     w = (mp_word)*dat * (mp_word)*dat + (mp_word)*dct;
     *dct = LOWER_HALF(w);
     w = UPPER_HALF(w);
-    ++dat; ++dct;
+    ++dat;
+    ++dct;
 
     for (j = i + 1; j < size_a; ++j, ++dat, ++dct) {
-      mp_word  t = (mp_word)*da * (mp_word)*dat;
-      mp_word  u = w + (mp_word)*dct, ov = 0;
+      mp_word t = (mp_word)*da * (mp_word)*dat;
+      mp_word u = w + (mp_word)*dct, ov = 0;
 
       /* Check if doubling t will overflow a word */
-      if (HIGH_BIT_SET(t))
-	ov = 1;
+      if (HIGH_BIT_SET(t)) ov = 1;
 
       w = t + t;
 
       /* Check if adding u to w will overflow a word */
-      if (ADD_WILL_OVERFLOW(w, u))
-	ov = 1;
+      if (ADD_WILL_OVERFLOW(w, u)) ov = 1;
 
       w += u;
 
       *dct = LOWER_HALF(w);
       w = UPPER_HALF(w);
       if (ov) {
-	w += MP_DIGIT_MAX; /* MP_RADIX */
-	++w;
+        w += MP_DIGIT_MAX; /* MP_RADIX */
+        ++w;
       }
     }
 
     w = w + *dct;
     *dct = (mp_digit)w;
     while ((w = UPPER_HALF(w)) != 0) {
-      ++dct; w = w + *dct;
+      ++dct;
+      w = w + *dct;
       *dct = LOWER_HALF(w);
     }
 
@@ -2382,8 +2068,7 @@
   }
 }
 
-STATIC void      s_dadd(mp_int a, mp_digit b)
-{
+static void s_dadd(mp_int a, mp_digit b) {
   mp_word w = 0;
   mp_digit *da = MP_DIGITS(a);
   mp_size ua = MP_USED(a);
@@ -2401,12 +2086,11 @@
 
   if (w) {
     *da = (mp_digit)w;
-    MP_USED(a) += 1;
+    a->used += 1;
   }
 }
 
-STATIC void      s_dmul(mp_int a, mp_digit b)
-{
+static void s_dmul(mp_int a, mp_digit b) {
   mp_word w = 0;
   mp_digit *da = MP_DIGITS(a);
   mp_size ua = MP_USED(a);
@@ -2420,13 +2104,12 @@
 
   if (w) {
     *da = (mp_digit)w;
-    MP_USED(a) += 1;
+    a->used += 1;
   }
 }
 
-STATIC void      s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a)
-{
-  mp_word  w = 0;
+static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) {
+  mp_word w = 0;
 
   while (size_a > 0) {
     w = (mp_word)*da++ * (mp_word)b + w;
@@ -2436,12 +2119,10 @@
     --size_a;
   }
 
-  if (w)
-    *dc = LOWER_HALF(w);
+  if (w) *dc = LOWER_HALF(w);
 }
 
-STATIC mp_digit  s_ddiv(mp_int a, mp_digit b)
-{
+static mp_digit s_ddiv(mp_int a, mp_digit b) {
   mp_word w = 0, qdigit;
   mp_size ua = MP_USED(a);
   mp_digit *da = MP_DIGITS(a) + ua - 1;
@@ -2452,8 +2133,7 @@
     if (w >= b) {
       qdigit = w / b;
       w = w % b;
-    }
-    else {
+    } else {
       qdigit = 0;
     }
 
@@ -2464,13 +2144,12 @@
   return (mp_digit)w;
 }
 
-STATIC void     s_qdiv(mp_int z, mp_size p2)
-{
+static void s_qdiv(mp_int z, mp_size p2) {
   mp_size ndig = p2 / MP_DIGIT_BIT, nbits = p2 % MP_DIGIT_BIT;
   mp_size uz = MP_USED(z);
 
   if (ndig) {
-    mp_size  mark;
+    mp_size mark;
     mp_digit *to, *from;
 
     if (ndig >= uz) {
@@ -2478,17 +2157,19 @@
       return;
     }
 
-    to = MP_DIGITS(z); from = to + ndig;
+    to = MP_DIGITS(z);
+    from = to + ndig;
 
-    for (mark = ndig; mark < uz; ++mark)
+    for (mark = ndig; mark < uz; ++mark) {
       *to++ = *from++;
+    }
 
-    MP_USED(z) = uz - ndig;
+    z->used = uz - ndig;
   }
 
   if (nbits) {
     mp_digit d = 0, *dz, save;
-    mp_size  up = MP_DIGIT_BIT - nbits;
+    mp_size up = MP_DIGIT_BIT - nbits;
 
     uz = MP_USED(z);
     dz = MP_DIGITS(z) + uz - 1;
@@ -2503,33 +2184,30 @@
     CLAMP(z);
   }
 
-  if (MP_USED(z) == 1 && z->digits[0] == 0)
-    MP_SIGN(z) = MP_ZPOS;
+  if (MP_USED(z) == 1 && z->digits[0] == 0) z->sign = MP_ZPOS;
 }
 
-STATIC void     s_qmod(mp_int z, mp_size p2)
-{
+static void s_qmod(mp_int z, mp_size p2) {
   mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT;
   mp_size uz = MP_USED(z);
   mp_digit mask = (1u << rest) - 1;
 
   if (start <= uz) {
-    MP_USED(z) = start;
+    z->used = start;
     z->digits[start - 1] &= mask;
     CLAMP(z);
   }
 }
 
-STATIC int      s_qmul(mp_int z, mp_size p2)
-{
-  mp_size   uz, need, rest, extra, i;
+static int s_qmul(mp_int z, mp_size p2) {
+  mp_size uz, need, rest, extra, i;
   mp_digit *from, *to, d;
 
-  if (p2 == 0)
-    return 1;
+  if (p2 == 0) return 1;
 
-  uz = MP_USED(z); 
-  need = p2 / MP_DIGIT_BIT; rest = p2 % MP_DIGIT_BIT;
+  uz = MP_USED(z);
+  need = p2 / MP_DIGIT_BIT;
+  rest = p2 % MP_DIGIT_BIT;
 
   /* Figure out if we need an extra digit at the top end; this occurs if the
      topmost `rest' bits of the high-order digit of z are not zero, meaning
@@ -2538,12 +2216,10 @@
   if (rest != 0) {
     mp_digit *dz = MP_DIGITS(z) + uz - 1;
 
-    if ((*dz >> (MP_DIGIT_BIT - rest)) != 0)
-      extra = 1;
+    if ((*dz >> (MP_DIGIT_BIT - rest)) != 0) extra = 1;
   }
 
-  if (!s_pad(z, uz + need + extra))
-    return 0;
+  if (!s_pad(z, uz + need + extra)) return 0;
 
   /* If we need to shift by whole digits, do that in one pass, then
      to back and shift by partial digits.
@@ -2552,8 +2228,7 @@
     from = MP_DIGITS(z) + uz - 1;
     to = from + need;
 
-    for (i = 0; i < uz; ++i)
-      *to-- = *from--;
+    for (i = 0; i < uz; ++i) *to-- = *from--;
 
     ZERO(MP_DIGITS(z), need);
     uz += need;
@@ -2563,7 +2238,7 @@
     d = 0;
     for (i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) {
       mp_digit save = *from;
-      
+
       *from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest));
       d = save;
     }
@@ -2575,7 +2250,7 @@
     }
   }
 
-  MP_USED(z) = uz;
+  z->used = uz;
   CLAMP(z);
 
   return 1;
@@ -2584,40 +2259,36 @@
 /* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z|
    The sign of the result is always zero/positive.
  */
-STATIC int       s_qsub(mp_int z, mp_size p2)
-{
-  mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), *zp;
-  mp_size  tdig = (p2 / MP_DIGIT_BIT), pos;
-  mp_word  w = 0;
+static int s_qsub(mp_int z, mp_size p2) {
+  mp_digit hi = (1u << (p2 % MP_DIGIT_BIT)), *zp;
+  mp_size tdig = (p2 / MP_DIGIT_BIT), pos;
+  mp_word w = 0;
 
-  if (!s_pad(z, tdig + 1))
-    return 0;
+  if (!s_pad(z, tdig + 1)) return 0;
 
   for (pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp) {
-    w = ((mp_word) MP_DIGIT_MAX + 1) - w - (mp_word)*zp;
+    w = ((mp_word)MP_DIGIT_MAX + 1) - w - (mp_word)*zp;
 
     *zp = LOWER_HALF(w);
     w = UPPER_HALF(w) ? 0 : 1;
   }
 
-  w = ((mp_word) MP_DIGIT_MAX + 1 + hi) - w - (mp_word)*zp;
+  w = ((mp_word)MP_DIGIT_MAX + 1 + hi) - w - (mp_word)*zp;
   *zp = LOWER_HALF(w);
 
   assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */
 
-  MP_SIGN(z) = MP_ZPOS;
+  z->sign = MP_ZPOS;
   CLAMP(z);
 
   return 1;
 }
 
-STATIC int      s_dp2k(mp_int z)
-{
-  int       k = 0;
+static int s_dp2k(mp_int z) {
+  int k = 0;
   mp_digit *dp = MP_DIGITS(z), d;
 
-  if (MP_USED(z) == 1 && *dp == 0)
-    return 1;
+  if (MP_USED(z) == 1 && *dp == 0) return 1;
 
   while (*dp == 0) {
     k += MP_DIGIT_BIT;
@@ -2633,49 +2304,44 @@
   return k;
 }
 
-STATIC int       s_isp2(mp_int z)
-{
+static int s_isp2(mp_int z) {
   mp_size uz = MP_USED(z), k = 0;
   mp_digit *dz = MP_DIGITS(z), d;
 
   while (uz > 1) {
-    if (*dz++ != 0)
-      return -1;
+    if (*dz++ != 0) return -1;
     k += MP_DIGIT_BIT;
     --uz;
   }
 
   d = *dz;
   while (d > 1) {
-    if (d & 1)
-      return -1;
-    ++k; d >>= 1;
+    if (d & 1) return -1;
+    ++k;
+    d >>= 1;
   }
 
-  return (int) k;
+  return (int)k;
 }
 
-STATIC int       s_2expt(mp_int z, mp_small k)
-{
-  mp_size  ndig, rest;
+static int s_2expt(mp_int z, mp_small k) {
+  mp_size ndig, rest;
   mp_digit *dz;
 
   ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT;
   rest = k % MP_DIGIT_BIT;
 
-  if (!s_pad(z, ndig))
-    return 0;
+  if (!s_pad(z, ndig)) return 0;
 
   dz = MP_DIGITS(z);
   ZERO(dz, ndig);
-  *(dz + ndig - 1) = (1 << rest);
-  MP_USED(z) = ndig;
+  *(dz + ndig - 1) = (1u << rest);
+  z->used = ndig;
 
   return 1;
 }
 
-STATIC int      s_norm(mp_int a, mp_int b)
-{
+static int s_norm(mp_int a, mp_int b) {
   mp_digit d = b->digits[MP_USED(b) - 1];
   int k = 0;
 
@@ -2686,33 +2352,29 @@
 
   /* These multiplications can't fail */
   if (k != 0) {
-    (void) s_qmul(a, (mp_size) k);
-    (void) s_qmul(b, (mp_size) k);
+    (void)s_qmul(a, (mp_size)k);
+    (void)s_qmul(b, (mp_size)k);
   }
 
   return k;
 }
 
-STATIC mp_result s_brmu(mp_int z, mp_int m)
-{
+static mp_result s_brmu(mp_int z, mp_int m) {
   mp_size um = MP_USED(m) * 2;
 
-  if (!s_pad(z, um))
-    return MP_MEMORY;
+  if (!s_pad(z, um)) return MP_MEMORY;
 
   s_2expt(z, MP_DIGIT_BIT * um);
   return mp_int_div(z, m, z, NULL);
 }
 
-STATIC int       s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2)
-{
-  mp_size   um = MP_USED(m), umb_p1, umb_m1;
+static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) {
+  mp_size um = MP_USED(m), umb_p1, umb_m1;
 
   umb_p1 = (um + 1) * MP_DIGIT_BIT;
   umb_m1 = (um - 1) * MP_DIGIT_BIT;
 
-  if (mp_int_copy(x, q1) != MP_OK)
-    return 0;
+  if (mp_int_copy(x, q1) != MP_OK) return 0;
 
   /* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */
   s_qdiv(q1, umb_m1);
@@ -2728,19 +2390,19 @@
    */
   UMUL(q2, m, q1);
   s_qmod(q1, umb_p1);
-  (void) mp_int_sub(x, q1, x); /* can't fail */
+  (void)mp_int_sub(x, q1, x); /* can't fail */
 
   /* The result may be < 0; if it is, add b^(k+1) to pin it in the proper
      range. */
-  if ((CMPZ(x) < 0) && !s_qsub(x, umb_p1))
-    return 0;
+  if ((CMPZ(x) < 0) && !s_qsub(x, umb_p1)) return 0;
 
   /* If x > m, we need to back it off until it is in range.  This will be
      required at most twice.  */
   if (mp_int_compare(x, m) >= 0) {
-    (void) mp_int_sub(x, m, x);
-    if (mp_int_compare(x, m) >= 0)
-      (void) mp_int_sub(x, m, x);
+    (void)mp_int_sub(x, m, x);
+    if (mp_int_compare(x, m) >= 0) {
+      (void)mp_int_sub(x, m, x);
+    }
   }
 
   /* At this point, x has been properly reduced. */
@@ -2749,40 +2411,39 @@
 
 /* Perform modular exponentiation using Barrett's method, where mu is the
    reduction constant for m.  Assumes a < m, b > 0. */
-STATIC mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
-{
-  mp_digit  *db, *dbt, umu, d;
-  mp_result res;
+static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) {
+  mp_digit umu = MP_USED(mu);
+  mp_digit *db = MP_DIGITS(b);
+  mp_digit *dbt = db + MP_USED(b) - 1;
+
   DECLARE_TEMP(3);
+  REQUIRE(GROW(TEMP(0), 4 * umu));
+  REQUIRE(GROW(TEMP(1), 4 * umu));
+  REQUIRE(GROW(TEMP(2), 4 * umu));
+  ZERO(TEMP(0)->digits, TEMP(0)->alloc);
+  ZERO(TEMP(1)->digits, TEMP(1)->alloc);
+  ZERO(TEMP(2)->digits, TEMP(2)->alloc);
 
-  umu = MP_USED(mu); db = MP_DIGITS(b); dbt = db + MP_USED(b) - 1;
-
-  while (last__ < 3) {
-    SETUP(mp_int_init_size(LAST_TEMP(), 4 * umu));
-    ZERO(MP_DIGITS(TEMP(last__ - 1)), MP_ALLOC(TEMP(last__ - 1)));
-  }
-
-  (void) mp_int_set_value(c, 1);
+  (void)mp_int_set_value(c, 1);
 
   /* Take care of low-order digits */
   while (db < dbt) {
-    int      i;
+    mp_digit d = *db;
 
-    for (d = *db, i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) {
+    for (int i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) {
       if (d & 1) {
-	/* The use of a second temporary avoids allocation */
-	UMUL(c, a, TEMP(0));
-	if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
-	  res = MP_MEMORY; goto CLEANUP;
-	}
-	mp_int_copy(TEMP(0), c);
+        /* The use of a second temporary avoids allocation */
+        UMUL(c, a, TEMP(0));
+        if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
+          REQUIRE(MP_MEMORY);
+        }
+        mp_int_copy(TEMP(0), c);
       }
 
-
       USQR(a, TEMP(0));
       assert(MP_SIGN(TEMP(0)) == MP_ZPOS);
       if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
-	res = MP_MEMORY; goto CLEANUP;
+        REQUIRE(MP_MEMORY);
       }
       assert(MP_SIGN(TEMP(0)) == MP_ZPOS);
       mp_int_copy(TEMP(0), a);
@@ -2792,12 +2453,12 @@
   }
 
   /* Take care of highest-order digit */
-  d = *dbt;
+  mp_digit d = *dbt;
   for (;;) {
     if (d & 1) {
       UMUL(c, a, TEMP(0));
       if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
-	res = MP_MEMORY; goto CLEANUP;
+        REQUIRE(MP_MEMORY);
       }
       mp_int_copy(TEMP(0), c);
     }
@@ -2807,13 +2468,13 @@
 
     USQR(a, TEMP(0));
     if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) {
-      res = MP_MEMORY; goto CLEANUP;
+      REQUIRE(MP_MEMORY);
     }
-    (void) mp_int_copy(TEMP(0), a);
+    (void)mp_int_copy(TEMP(0), a);
   }
 
   CLEANUP_TEMP();
-  return res;
+  return MP_OK;
 }
 
 /* Division of nonnegative integers
@@ -2836,21 +2497,15 @@
   outputs: u / v stored in u
            u % v stored in v
  */
-STATIC mp_result s_udiv_knuth(mp_int u, mp_int v) {
-  mpz_t q, r, t;
-  mp_result
-  res = MP_OK;
-  int k,j;
-  mp_size m,n;
-
+static mp_result s_udiv_knuth(mp_int u, mp_int v) {
   /* Force signs to positive */
-  MP_SIGN(u) = MP_ZPOS;
-  MP_SIGN(v) = MP_ZPOS;
+  u->sign = MP_ZPOS;
+  v->sign = MP_ZPOS;
 
   /* Use simple division algorithm when v is only one digit long */
   if (MP_USED(v) == 1) {
     mp_digit d, rem;
-    d   = v->digits[0];
+    d = v->digits[0];
     rem = s_ddiv(u, d);
     mp_int_set_value(v, rem);
     return MP_OK;
@@ -2863,10 +2518,10 @@
      v is an n+m digit number with digits from v_{m+n-1}..v_0.
      We require that n > 1 and m >= 0
    */
-  n = MP_USED(v);
-  m = MP_USED(u) - n;
+  mp_size n = MP_USED(v);
+  mp_size m = MP_USED(u) - n;
   assert(n > 1);
-  assert(m >= 0);
+  /* assert(m >= 0) follows because m is unsigned. */
 
   /* D1: Normalize.
      The normalization step provides the necessary condition for Theorem B,
@@ -2881,7 +2536,7 @@
      That is, qhat is always greater than the actual quotient digit q,
      and it is never more than two larger than the actual quotient digit.
    */
-  k = s_norm(u, v);
+  int k = s_norm(u, v);
 
   /* Extend size of u by one if needed.
 
@@ -2891,10 +2546,9 @@
      a leading zero here.
    */
   if (k == 0 || MP_USED(u) != m + n + 1) {
-    if (!s_pad(u, m+n+1))
-      return MP_MEMORY;
-    u->digits[m+n] = 0;
-    u->used = m+n+1;
+    if (!s_pad(u, m + n + 1)) return MP_MEMORY;
+    u->digits[m + n] = 0;
+    u->used = m + n + 1;
   }
 
   /* Add a leading 0 to v.
@@ -2903,40 +2557,42 @@
      add the leading zero to v here to ensure that the multiplication will
      produce the full n+1 digit result.
    */
-  if (!s_pad(v, n+1)) return MP_MEMORY; v->digits[n] = 0;
+  if (!s_pad(v, n + 1)) return MP_MEMORY;
+  v->digits[n] = 0;
 
   /* Initialize temporary variables q and t.
      q allocates space for m+1 digits to store the quotient digits
      t allocates space for n+1 digits to hold the result of q_j*v
    */
-  if ((res = mp_int_init_size(&q, m + 1)) != MP_OK) return res;
-  if ((res = mp_int_init_size(&t, n + 1)) != MP_OK) goto CLEANUP;
+  DECLARE_TEMP(2);
+  REQUIRE(GROW(TEMP(0), m + 1));
+  REQUIRE(GROW(TEMP(1), n + 1));
 
   /* D2: Initialize j */
-  j = m;
-  r.digits = MP_DIGITS(u) + j;  /* The contents of r are shared with u */
-  r.used   = n + 1;
-  r.sign   = MP_ZPOS;
-  r.alloc  = MP_ALLOC(u);
-  ZERO(t.digits, t.alloc);
+  int j = m;
+  mpz_t r;
+  r.digits = MP_DIGITS(u) + j; /* The contents of r are shared with u */
+  r.used = n + 1;
+  r.sign = MP_ZPOS;
+  r.alloc = MP_ALLOC(u);
+  ZERO(TEMP(1)->digits, TEMP(1)->alloc);
 
   /* Calculate the m+1 digits of the quotient result */
   for (; j >= 0; j--) {
     /* D3: Calculate q' */
     /* r->digits is aligned to position j of the number u */
     mp_word pfx, qhat;
-    pfx   = r.digits[n];
+    pfx = r.digits[n];
     pfx <<= MP_DIGIT_BIT / 2;
     pfx <<= MP_DIGIT_BIT / 2;
-    pfx |= r.digits[n-1]; /* pfx = u_{j+n}{j+n-1} */
+    pfx |= r.digits[n - 1]; /* pfx = u_{j+n}{j+n-1} */
 
-    qhat = pfx / v->digits[n-1];
+    qhat = pfx / v->digits[n - 1];
     /* Check to see if qhat > b, and decrease qhat if so.
        Theorem B guarantess that qhat is at most 2 larger than the
        actual value, so it is possible that qhat is greater than
        the maximum value that will fit in a digit */
-    if (qhat > MP_DIGIT_MAX)
-      qhat = MP_DIGIT_MAX;
+    if (qhat > MP_DIGIT_MAX) qhat = MP_DIGIT_MAX;
 
     /* D4,D5,D6: Multiply qhat * v and test for a correct value of q
 
@@ -2947,26 +2603,29 @@
        decrease qhat by one and try again. We may need to decrease qhat one
        more time before we get a value that is smaller than r.
 
-       This way is less efficent than Knuth becuase we do more multiplies, but
+       This way is less efficent than Knuth because we do more multiplies, but
        we do not need to worry about underflow this way.
      */
     /* t = qhat * v */
-    s_dbmul(MP_DIGITS(v), (mp_digit) qhat, t.digits, n+1); t.used = n + 1;
-    CLAMP(&t);
+    s_dbmul(MP_DIGITS(v), (mp_digit)qhat, TEMP(1)->digits, n + 1);
+    TEMP(1)->used = n + 1;
+    CLAMP(TEMP(1));
 
     /* Clamp r for the comparison. Comparisons do not like leading zeros. */
     CLAMP(&r);
-    if (s_ucmp(&t, &r) > 0) {   /* would the remainder be negative? */
-      qhat -= 1;   /* try a smaller q */
-      s_dbmul(MP_DIGITS(v), (mp_digit) qhat, t.digits, n+1);
-      t.used = n + 1; CLAMP(&t);
-      if (s_ucmp(&t, &r) > 0) { /* would the remainder be negative? */
+    if (s_ucmp(TEMP(1), &r) > 0) { /* would the remainder be negative? */
+      qhat -= 1;                   /* try a smaller q */
+      s_dbmul(MP_DIGITS(v), (mp_digit)qhat, TEMP(1)->digits, n + 1);
+      TEMP(1)->used = n + 1;
+      CLAMP(TEMP(1));
+      if (s_ucmp(TEMP(1), &r) > 0) { /* would the remainder be negative? */
         assert(qhat > 0);
         qhat -= 1; /* try a smaller q */
-        s_dbmul(MP_DIGITS(v), (mp_digit) qhat, t.digits, n+1);
-        t.used = n + 1; CLAMP(&t);
+        s_dbmul(MP_DIGITS(v), (mp_digit)qhat, TEMP(1)->digits, n + 1);
+        TEMP(1)->used = n + 1;
+        CLAMP(TEMP(1));
       }
-      assert(s_ucmp(&t, &r) <=  0 && "The mathematics failed us.");
+      assert(s_ucmp(TEMP(1), &r) <= 0 && "The mathematics failed us.");
     }
     /* Unclamp r. The D algorithm expects r = u_{j+n}..u_j to always be n+1
        digits long. */
@@ -2976,7 +2635,7 @@
 
        Note: The multiply was completed above so we only need to subtract here.
      */
-    s_usub(r.digits, t.digits, r.digits, r.used, t.used);
+    s_usub(r.digits, TEMP(1)->digits, r.digits, r.used, TEMP(1)->used);
 
     /* D5: Test remainder
 
@@ -2984,7 +2643,7 @@
              before performing the subtract.  Value cast to mp_digit to prevent
              warning, qhat has been clamped to MP_DIGIT_MAX
      */
-    q.digits[j] = (mp_digit)qhat;
+    TEMP(0)->digits[j] = (mp_digit)qhat;
 
     /* D6: Add back
        Note: Not needed because we always check that qhat is the correct value
@@ -2993,84 +2652,79 @@
 
     /* D7: Loop on j */
     r.digits--;
-    ZERO(t.digits, t.alloc);
+    ZERO(TEMP(1)->digits, TEMP(1)->alloc);
   }
 
   /* Get rid of leading zeros in q */
-  q.used = m + 1;
-  CLAMP(&q);
+  TEMP(0)->used = m + 1;
+  CLAMP(TEMP(0));
 
   /* Denormalize the remainder */
   CLAMP(u); /* use u here because the r.digits pointer is off-by-one */
-  if (k != 0)
-    s_qdiv(u, k);
+  if (k != 0) s_qdiv(u, k);
 
-  mp_int_copy(u, v);  /* ok:  0 <= r < v */
-  mp_int_copy(&q, u); /* ok:  q <= u     */
+  mp_int_copy(u, v);       /* ok:  0 <= r < v */
+  mp_int_copy(TEMP(0), u); /* ok:  q <= u     */
 
-  mp_int_clear(&t);
- CLEANUP:
-  mp_int_clear(&q);
-  return res;
+  CLEANUP_TEMP();
+  return MP_OK;
 }
 
-STATIC int       s_outlen(mp_int z, mp_size r)
-{
-  mp_result bits;
-  double raw;
-
+static int s_outlen(mp_int z, mp_size r) {
   assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX);
 
-  bits = mp_int_count_bits(z);
-  raw = (double)bits * s_log2[r];
+  mp_result bits = mp_int_count_bits(z);
+  double raw = (double)bits * s_log2[r];
 
   return (int)(raw + 0.999999);
 }
 
-STATIC mp_size   s_inlen(int len, mp_size r)
-{
-  double  raw = (double)len / s_log2[r];
+static mp_size s_inlen(int len, mp_size r) {
+  double raw = (double)len / s_log2[r];
   mp_size bits = (mp_size)(raw + 0.5);
 
   return (mp_size)((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT) + 1;
 }
 
-STATIC int       s_ch2val(char c, int r)
-{
+static int s_ch2val(char c, int r) {
   int out;
 
-  if (isdigit((unsigned char) c))
+  /*
+   * In some locales, isalpha() accepts characters outside the range A-Z,
+   * producing out<0 or out>=36.  The "out >= r" check will always catch
+   * out>=36.  Though nothing explicitly catches out<0, our caller reacts the
+   * same way to every negative return value.
+   */
+  if (isdigit((unsigned char)c))
     out = c - '0';
-  else if (r > 10 && isalpha((unsigned char) c))
-    out = toupper(c) - 'A' + 10;
+  else if (r > 10 && isalpha((unsigned char)c))
+    out = toupper((unsigned char)c) - 'A' + 10;
   else
     return -1;
 
   return (out >= r) ? -1 : out;
 }
 
-STATIC char      s_val2ch(int v, int caps)
-{
+static char s_val2ch(int v, int caps) {
   assert(v >= 0);
 
-  if (v < 10)
+  if (v < 10) {
     return v + '0';
-  else {
+  } else {
     char out = (v - 10) + 'a';
 
-    if (caps)
-      return toupper(out);
-    else
+    if (caps) {
+      return toupper((unsigned char)out);
+    } else {
       return out;
+    }
   }
 }
 
-STATIC void      s_2comp(unsigned char *buf, int len)
-{
-  int i;
+static void s_2comp(unsigned char *buf, int len) {
   unsigned short s = 1;
 
-  for (i = len - 1; i >= 0; --i) {
+  for (int i = len - 1; i >= 0; --i) {
     unsigned char c = ~buf[i];
 
     s = c + s;
@@ -3083,13 +2737,11 @@
   /* last carry out is ignored */
 }
 
-STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad)
-{
-  mp_size uz;
-  mp_digit *dz;
+static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) {
   int pos = 0, limit = *limpos;
+  mp_size uz = MP_USED(z);
+  mp_digit *dz = MP_DIGITS(z);
 
-  uz = MP_USED(z); dz = MP_DIGITS(z);
   while (uz > 0 && pos < limit) {
     mp_digit d = *dz++;
     int i;
@@ -3099,8 +2751,7 @@
       d >>= CHAR_BIT;
 
       /* Don't write leading zeroes */
-      if (d == 0 && uz == 1)
-	i = 0; /* exit loop without signaling truncation */
+      if (d == 0 && uz == 1) i = 0; /* exit loop without signaling truncation */
     }
 
     /* Detect truncation (loop exited with pos >= limit) */
@@ -3110,14 +2761,15 @@
   }
 
   if (pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) {
-    if (pos < limit)
+    if (pos < limit) {
       buf[pos++] = 0;
-    else
+    } else {
       uz = 1;
+    }
   }
 
   /* Digits are in reverse order, fix that */
-  REV(unsigned char, buf, pos);
+  REV(buf, pos);
 
   /* Return the number of bytes actually written */
   *limpos = pos;
@@ -3125,32 +2777,4 @@
   return (uz == 0) ? MP_OK : MP_TRUNC;
 }
 
-#if DEBUG
-void      s_print(char *tag, mp_int z)
-{
-  int  i;
-
-  fprintf(stderr, "%s: %c ", tag,
-	  (MP_SIGN(z) == MP_NEG) ? '-' : '+');
-
-  for (i = MP_USED(z) - 1; i >= 0; --i)
-    fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), z->digits[i]);
-
-  fputc('\n', stderr);
-
-}
-
-void      s_print_buf(char *tag, mp_digit *buf, mp_size num)
-{
-  int i;
-
-  fprintf(stderr, "%s: ", tag);
-
-  for (i = num - 1; i >= 0; --i)
-    fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), buf[i]);
-
-  fputc('\n', stderr);
-}
-#endif
-
 /* Here there be dragons */
diff --git a/lib/External/isl/imath/imath.h b/lib/External/isl/imath/imath.h
index a9f5e40..7d30487 100644
--- a/lib/External/isl/imath/imath.h
+++ b/lib/External/isl/imath/imath.h
@@ -1,7 +1,7 @@
 /*
   Name:     imath.h
   Purpose:  Arbitrary precision integer arithmetic routines.
-  Author:   M. J. Fromberger <http://spinning-yarns.org/michael/>
+  Author:   M. J. Fromberger
 
   Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
 
@@ -27,44 +27,46 @@
 #ifndef IMATH_H_
 #define IMATH_H_
 
-#include <stdint.h>
 #include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef unsigned char      mp_sign;
-typedef unsigned int       mp_size;
-typedef int                mp_result;
-typedef long               mp_small;  /* must be a signed type */
-typedef unsigned long      mp_usmall; /* must be an unsigned type */
+typedef unsigned char  mp_sign;
+typedef unsigned int   mp_size;
+typedef int            mp_result;
+typedef long           mp_small;  /* must be a signed type */
+typedef unsigned long  mp_usmall; /* must be an unsigned type */
 
-/* Force building with uint64_t so that the library builds consistently
- * whether we build from the makefile or by embedding imath in another project.
- */
-#undef  USE_64BIT_WORDS
-#define USE_64BIT_WORDS
-#ifdef  USE_64BIT_WORDS
-typedef uint32_t           mp_digit;
-typedef uint64_t           mp_word;
+
+/* Build with words as uint64_t by default. */
+#ifdef USE_32BIT_WORDS
+typedef uint16_t        mp_digit;
+typedef uint32_t        mp_word;
+#  define MP_DIGIT_MAX  (UINT16_MAX * 1UL)
+#  define MP_WORD_MAX   (UINT32_MAX * 1UL)
 #else
-typedef uint16_t           mp_digit;
-typedef uint32_t           mp_word;
+typedef uint32_t        mp_digit;
+typedef uint64_t        mp_word;
+#  define MP_DIGIT_MAX  (UINT32_MAX * UINT64_C(1))
+#  define MP_WORD_MAX   (UINT64_MAX)
 #endif
 
-typedef struct mpz {
-  mp_digit    single;
-  mp_digit   *digits;
-  mp_size     alloc;
-  mp_size     used;
-  mp_sign     sign;
+typedef struct {
+  mp_digit  single;
+  mp_digit* digits;
+  mp_size   alloc;
+  mp_size   used;
+  mp_sign   sign;
 } mpz_t, *mp_int;
 
-#define MP_DIGITS(Z) ((Z)->digits)
-#define MP_ALLOC(Z)  ((Z)->alloc)
-#define MP_USED(Z)   ((Z)->used)
-#define MP_SIGN(Z)   ((Z)->sign)
+static inline mp_digit* MP_DIGITS(mp_int Z) { return Z->digits; }
+static inline mp_size   MP_ALLOC(mp_int Z)  { return Z->alloc; }
+static inline mp_size   MP_USED(mp_int Z)   { return Z->used; }
+static inline mp_sign   MP_SIGN(mp_int Z)   { return Z->sign; }
 
 extern const mp_result MP_OK;
 extern const mp_result MP_FALSE;
@@ -76,156 +78,343 @@
 extern const mp_result MP_BADARG;
 extern const mp_result MP_MINERR;
 
-#define MP_DIGIT_BIT    (sizeof(mp_digit) * CHAR_BIT)
-#define MP_WORD_BIT     (sizeof(mp_word) * CHAR_BIT)
-#define MP_SMALL_MIN    LONG_MIN
-#define MP_SMALL_MAX    LONG_MAX
-#define MP_USMALL_MIN   ULONG_MIN
-#define MP_USMALL_MAX   ULONG_MAX
+#define MP_DIGIT_BIT   (sizeof(mp_digit) * CHAR_BIT)
+#define MP_WORD_BIT    (sizeof(mp_word) * CHAR_BIT)
+#define MP_SMALL_MIN   LONG_MIN
+#define MP_SMALL_MAX   LONG_MAX
+#define MP_USMALL_MAX  ULONG_MAX
 
-#ifdef USE_64BIT_WORDS
-#  define MP_DIGIT_MAX   (UINT32_MAX * UINT64_C(1))
-#  define MP_WORD_MAX    (UINT64_MAX)
-#else
-#  define MP_DIGIT_MAX   (UINT16_MAX * 1UL)
-#  define MP_WORD_MAX    (UINT32_MAX * 1UL)
-#endif
+#define MP_MIN_RADIX   2
+#define MP_MAX_RADIX   36
 
-#define MP_MIN_RADIX    2
-#define MP_MAX_RADIX    36
+/** Sets the default number of digits allocated to an `mp_int` constructed by
+    `mp_int_init_size()` with `prec == 0`. Allocations are rounded up to
+    multiples of this value. `MP_DEFAULT_PREC` is the default value. Requires
+    `ndigits > 0`. */
+void mp_int_default_precision(mp_size ndigits);
 
-/* Values with fewer than this many significant digits use the standard
-   multiplication algorithm; otherwise, a recursive algorithm is used.  
-   Choose a value to suit your platform.
- */
-#define MP_MULT_THRESH  22
+/** Sets the number of digits below which multiplication will use the standard
+    quadratic "schoolbook" multiplication algorithm rather than Karatsuba-Ofman.
+    Requires `ndigits >= sizeof(mp_word)`. */
+void mp_int_multiply_threshold(mp_size ndigits);
 
-#define MP_DEFAULT_PREC 8   /* default memory allocation, in digits */
+/** A sign indicating a (strictly) negative value. */
+extern const mp_sign MP_NEG;
 
-extern const mp_sign   MP_NEG;
-extern const mp_sign   MP_ZPOS;
+/** A sign indicating a zero or positive value. */
+extern const mp_sign MP_ZPOS;
 
-#define mp_int_is_odd(Z)  ((Z)->digits[0] & 1)
-#define mp_int_is_even(Z) !((Z)->digits[0] & 1)
+/** Reports whether `z` is odd, having remainder 1 when divided by 2. */
+static inline bool mp_int_is_odd(mp_int z) { return (z->digits[0] & 1) != 0; }
 
+/** Reports whether `z` is even, having remainder 0 when divided by 2. */
+static inline bool mp_int_is_even(mp_int z) { return (z->digits[0] & 1) == 0; }
+
+/** Initializes `z` with 1-digit precision and sets it to zero.  This function
+    cannot fail unless `z == NULL`. */
 mp_result mp_int_init(mp_int z);
-mp_int    mp_int_alloc(void);
+
+/** Allocates a fresh zero-valued `mpz_t` on the heap, returning NULL in case
+    of error. The only possible error is out-of-memory. */
+mp_int mp_int_alloc(void);
+
+/** Initializes `z` with at least `prec` digits of storage, and sets it to
+    zero. If `prec` is zero, the default precision is used. In either case the
+    size is rounded up to the nearest multiple of the word size. */
 mp_result mp_int_init_size(mp_int z, mp_size prec);
+
+/** Initializes `z` to be a copy of an already-initialized value in `old`. The
+    new copy does not share storage with the original. */
 mp_result mp_int_init_copy(mp_int z, mp_int old);
+
+/** Initializes `z` to the specified signed `value` at default precision. */
 mp_result mp_int_init_value(mp_int z, mp_small value);
+
+/** Initializes `z` to the specified unsigned `value` at default precision. */
 mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue);
+
+/** Sets `z` to the value of the specified signed `value`. */
 mp_result mp_int_set_value(mp_int z, mp_small value);
+
+/** Sets `z` to the value of the specified unsigned `value`. */
 mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue);
-void      mp_int_clear(mp_int z);
-void      mp_int_free(mp_int z);
 
-mp_result mp_int_copy(mp_int a, mp_int c);           /* c = a     */
-void      mp_int_swap(mp_int a, mp_int c);           /* swap a, c */
-void      mp_int_zero(mp_int z);                     /* z = 0     */
-mp_result mp_int_abs(mp_int a, mp_int c);            /* c = |a|   */
-mp_result mp_int_neg(mp_int a, mp_int c);            /* c = -a    */
-mp_result mp_int_add(mp_int a, mp_int b, mp_int c);  /* c = a + b */
+/** Releases the storage used by `z`. */
+void mp_int_clear(mp_int z);
+
+/** Releases the storage used by `z` and also `z` itself.
+    This should only be used for `z` allocated by `mp_int_alloc()`. */
+void mp_int_free(mp_int z);
+
+/** Replaces the value of `c` with a copy of the value of `a`. No new memory is
+    allocated unless `a` has more significant digits than `c` has allocated. */
+mp_result mp_int_copy(mp_int a, mp_int c);
+
+/** Swaps the values and storage between `a` and `c`. */
+void mp_int_swap(mp_int a, mp_int c);
+
+/** Sets `z` to zero. The allocated storage of `z` is not changed. */
+void mp_int_zero(mp_int z);
+
+/** Sets `c` to the absolute value of `a`. */
+mp_result mp_int_abs(mp_int a, mp_int c);
+
+/** Sets `c` to the additive inverse (negation) of `a`. */
+mp_result mp_int_neg(mp_int a, mp_int c);
+
+/** Sets `c` to the sum of `a` and `b`. */
+mp_result mp_int_add(mp_int a, mp_int b, mp_int c);
+
+/** Sets `c` to the sum of `a` and `value`. */
 mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c);
-mp_result mp_int_sub(mp_int a, mp_int b, mp_int c);  /* c = a - b */
+
+/** Sets `c` to the difference of `a` less `b`. */
+mp_result mp_int_sub(mp_int a, mp_int b, mp_int c);
+
+/** Sets `c` to the difference of `a` less `value`. */
 mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c);
-mp_result mp_int_mul(mp_int a, mp_int b, mp_int c);  /* c = a * b */
+
+/** Sets `c` to the product of `a` and `b`. */
+mp_result mp_int_mul(mp_int a, mp_int b, mp_int c);
+
+/** Sets `c` to the product of `a` and `value`. */
 mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c);
+
+/** Sets `c` to the product of `a` and `2^p2`. Requires `p2 >= 0`. */
 mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c);
-mp_result mp_int_sqr(mp_int a, mp_int c);            /* c = a * a */
-mp_result mp_int_div(mp_int a, mp_int b,             /* q = a / b */
-		     mp_int q, mp_int r);            /* r = a % b */
-mp_result mp_int_div_value(mp_int a, mp_small value, /* q = a / value */
-			   mp_int q, mp_small *r);   /* r = a % value */
-mp_result mp_int_div_pow2(mp_int a, mp_small p2,     /* q = a / 2^p2  */
-			  mp_int q, mp_int r);       /* r = q % 2^p2  */
-mp_result mp_int_mod(mp_int a, mp_int m, mp_int c);  /* c = a % m */
-#define   mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R))
-mp_result mp_int_expt(mp_int a, mp_small b, mp_int c);         /* c = a^b */
-mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c); /* c = a^b */
-mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c);      /* c = a^b */
 
-int       mp_int_compare(mp_int a, mp_int b);          /* a <=> b     */
-int       mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */
-int       mp_int_compare_zero(mp_int z);                 /* a <=> 0  */
-int       mp_int_compare_value(mp_int z, mp_small v);    /* a <=> v  */
-int       mp_int_compare_uvalue(mp_int z, mp_usmall uv); /* a <=> uv */
+/** Sets `c` to the square of `a`. */
+mp_result mp_int_sqr(mp_int a, mp_int c);
 
-/* Returns true if v|a, false otherwise (including errors) */
-int       mp_int_divisible_value(mp_int a, mp_small v);
+/** Sets `q` and `r` to the quotent and remainder of `a / b`. Division by
+    powers of 2 is detected and handled efficiently.  The remainder is pinned
+    to `0 <= r < b`.
 
-/* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */
-int       mp_int_is_pow2(mp_int z);
+    Either of `q` or `r` may be NULL, but not both, and `q` and `r` may not
+    point to the same value. */
+mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r);
 
-mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m,
-			 mp_int c);                    /* c = a^b (mod m) */
-mp_result mp_int_exptmod_evalue(mp_int a, mp_small value,
-				mp_int m, mp_int c);   /* c = a^v (mod m) */
-mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b,
-				mp_int m, mp_int c);   /* c = v^b (mod m) */
-mp_result mp_int_exptmod_known(mp_int a, mp_int b,
-			       mp_int m, mp_int mu,
-			       mp_int c);              /* c = a^b (mod m) */
+/** Sets `q` and `*r` to the quotent and remainder of `a / value`. Division by
+    powers of 2 is detected and handled efficiently. The remainder is pinned to
+    `0 <= *r < b`. Either of `q` or `r` may be NULL. */
+mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r);
+
+/** Sets `q` and `r` to the quotient and remainder of `a / 2^p2`. This is a
+    special case for division by powers of two that is more efficient than
+    using ordinary division. Note that `mp_int_div()` will automatically handle
+    this case, this function is for cases where you have only the exponent. */
+mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r);
+
+/** Sets `c` to the remainder of `a / m`.
+    The remainder is pinned to `0 <= c < m`. */
+mp_result mp_int_mod(mp_int a, mp_int m, mp_int c);
+
+/** Sets `c` to the value of `a` raised to the `b` power.
+    It returns `MP_RANGE` if `b < 0`. */
+mp_result mp_int_expt(mp_int a, mp_small b, mp_int c);
+
+/** Sets `c` to the value of `a` raised to the `b` power.
+    It returns `MP_RANGE` if `b < 0`. */
+mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c);
+
+/** Sets `c` to the value of `a` raised to the `b` power.
+    It returns `MP_RANGE`) if `b < 0`. */
+mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c);
+
+/** Sets `*r` to the remainder of `a / value`.
+    The remainder is pinned to `0 <= r < value`. */
+static inline
+mp_result mp_int_mod_value(mp_int a, mp_small value, mp_small* r) {
+  return mp_int_div_value(a, value, 0, r);
+}
+
+/** Returns the comparator of `a` and `b`. */
+int mp_int_compare(mp_int a, mp_int b);
+
+/** Returns the comparator of the magnitudes of `a` and `b`, disregarding their
+    signs. Neither `a` nor `b` is modified by the comparison. */
+int mp_int_compare_unsigned(mp_int a, mp_int b);
+
+/** Returns the comparator of `z` and zero. */
+int mp_int_compare_zero(mp_int z);
+
+/** Returns the comparator of `z` and the signed value `v`. */
+int mp_int_compare_value(mp_int z, mp_small v);
+
+/** Returns the comparator of `z` and the unsigned value `uv`. */
+int mp_int_compare_uvalue(mp_int z, mp_usmall uv);
+
+/** Reports whether `a` is divisible by `v`. */
+bool mp_int_divisible_value(mp_int a, mp_small v);
+
+/** Returns `k >= 0` such that `z` is `2^k`, if such a `k` exists. If no such
+    `k` exists, the function returns -1. */
+int mp_int_is_pow2(mp_int z);
+
+/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`.
+    It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */
+mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c);
+
+/** Sets `c` to the value of `a` raised to the `value` power, modulo `m`.
+    It returns `MP_RANGE` if `value < 0` or `MP_UNDEF` if `m == 0`. */
+mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c);
+
+/** Sets `c` to the value of `value` raised to the `b` power, modulo `m`.
+    It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */
+mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c);
+
+/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`,
+    given a precomputed reduction constant `mu` defined for Barrett's modular
+    reduction algorithm.
+
+    It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */
+mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
+
+/** Sets `c` to the reduction constant for Barrett reduction by modulus `m`.
+    Requires that `c` and `m` point to distinct locations. */
 mp_result mp_int_redux_const(mp_int m, mp_int c);
 
-mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */
+/** Sets `c` to the multiplicative inverse of `a` modulo `m`, if it exists.
+    The least non-negative representative of the congruence class is computed.
 
-mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c);    /* c = gcd(a, b)   */
+    It returns `MP_UNDEF` if the inverse does not exist, or `MP_RANGE` if `a ==
+    0` or `m <= 0`. */
+mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c);
 
-mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,    /* c = gcd(a, b)   */
-		      mp_int x, mp_int y);             /* c = ax + by     */
+/** Sets `c` to the greatest common divisor of `a` and `b`.
 
-mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c);    /* c = lcm(a, b)   */
+    It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a`
+    and `b` are both zero. */
+mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c);
 
-mp_result mp_int_root(mp_int a, mp_small b, mp_int c); /* c = floor(a^{1/b}) */
-#define   mp_int_sqrt(a, c) mp_int_root(a, 2, c)       /* c = floor(sqrt(a)) */
+/** Sets `c` to the greatest common divisor of `a` and `b`, and sets `x` and
+    `y` to values satisfying Bezout's identity `gcd(a, b) = ax + by`.
 
-/* Convert to a small int, if representable; else MP_RANGE */
+    It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a`
+    and `b` are both zero. */
+mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y);
+
+/** Sets `c` to the least common multiple of `a` and `b`.
+
+    It returns `MP_UNDEF` if the LCM is undefined, such as for example if `a`
+    and `b` are both zero. */
+mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c);
+
+/** Sets `c` to the greatest integer not less than the `b`th root of `a`,
+    using Newton's root-finding algorithm.
+    It returns `MP_UNDEF` if `a < 0` and `b` is even. */
+mp_result mp_int_root(mp_int a, mp_small b, mp_int c);
+
+/** Sets `c` to the greatest integer not less than the square root of `a`.
+    This is a special case of `mp_int_root()`. */
+static inline
+mp_result mp_int_sqrt(mp_int a, mp_int c) { return mp_int_root(a, 2, c); }
+
+/** Returns `MP_OK` if `z` is representable as `mp_small`, else `MP_RANGE`.
+    If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */
 mp_result mp_int_to_int(mp_int z, mp_small *out);
+
+/** Returns `MP_OK` if `z` is representable as `mp_usmall`, or `MP_RANGE`.
+    If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */
 mp_result mp_int_to_uint(mp_int z, mp_usmall *out);
 
-/* Convert to nul-terminated string with the specified radix, writing at
-   most limit characters including the nul terminator  */
-mp_result mp_int_to_string(mp_int z, mp_size radix,
-			   char *str, int limit);
+/** Converts `z` to a zero-terminated string of characters in the specified
+    `radix`, writing at most `limit` characters to `str` including the
+    terminating NUL value. A leading `-` is used to indicate a negative value.
 
-/* Return the number of characters required to represent
-   z in the given radix.  May over-estimate. */
+    Returns `MP_TRUNC` if `limit` was to small to write all of `z`.
+    Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
+mp_result mp_int_to_string(mp_int z, mp_size radix, char *str, int limit);
+
+/** Reports the minimum number of characters required to represent `z` as a
+    zero-terminated string in the given `radix`.
+    Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
 mp_result mp_int_string_len(mp_int z, mp_size radix);
 
-/* Read zero-terminated string into z */
-mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str);
-mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
-			      char **end);
+/** Reads a string of ASCII digits in the specified `radix` from the zero
+    terminated `str` provided into `z`. For values of `radix > 10`, the letters
+    `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect
+    to case.
 
-/* Return the number of significant bits in z */
+    Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a
+    sign flag. Processing stops when a NUL or any other character out of range
+    for a digit in the given radix is encountered.
+
+    If the whole string was consumed, `MP_OK` is returned; otherwise
+    `MP_TRUNC`. is returned.
+
+    Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
+mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str);
+
+/** Reads a string of ASCII digits in the specified `radix` from the zero
+    terminated `str` provided into `z`. For values of `radix > 10`, the letters
+    `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect
+    to case.
+
+    Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a
+    sign flag. Processing stops when a NUL or any other character out of range
+    for a digit in the given radix is encountered.
+
+    If the whole string was consumed, `MP_OK` is returned; otherwise
+    `MP_TRUNC`. is returned. If `end` is not NULL, `*end` is set to point to
+    the first unconsumed byte of the input string (the NUL byte if the whole
+    string was consumed). This emulates the behavior of the standard C
+    `strtol()` function.
+
+    Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
+mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end);
+
+/** Returns the number of significant bits in `z`. */
 mp_result mp_int_count_bits(mp_int z);
 
-/* Convert z to two's complement binary, writing at most limit bytes */
+/** Converts `z` to 2's complement binary, writing at most `limit` bytes into
+    the given `buf`.  Returns `MP_TRUNC` if the buffer limit was too small to
+    contain the whole value.  If this occurs, the contents of buf will be
+    effectively garbage, as the function uses the buffer as scratch space.
+
+    The binary representation of `z` is in base-256 with digits ordered from
+    most significant to least significant (network byte ordering).  The
+    high-order bit of the first byte is set for negative values, clear for
+    non-negative values.
+
+    As a result, non-negative values will be padded with a leading zero byte if
+    the high-order byte of the base-256 magnitude is set.  This extra byte is
+    accounted for by the `mp_int_binary_len()` function. */
 mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit);
 
-/* Read a two's complement binary value into z from the given buffer */
+/** Reads a 2's complement binary value from `buf` into `z`, where `len` is the
+    length of the buffer.  The contents of `buf` may be overwritten during
+    processing, although they will be restored when the function returns. */
 mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len);
 
-/* Return the number of bytes required to represent z in binary. */
+/** Returns the number of bytes to represent `z` in 2's complement binary. */
 mp_result mp_int_binary_len(mp_int z);
 
-/* Convert z to unsigned binary, writing at most limit bytes */
+/** Converts the magnitude of `z` to unsigned binary, writing at most `limit`
+    bytes into the given `buf`.  The sign of `z` is ignored, but `z` is not
+    modified.  Returns `MP_TRUNC` if the buffer limit was too small to contain
+    the whole value.  If this occurs, the contents of `buf` will be effectively
+    garbage, as the function uses the buffer as scratch space during
+    conversion.
+
+    The binary representation of `z` is in base-256 with digits ordered from
+    most significant to least significant (network byte ordering). */
 mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit);
 
-/* Read an unsigned binary value into z from the given buffer */
+/** Reads an unsigned binary value from `buf` into `z`, where `len` is the
+    length of the buffer. The contents of `buf` are not modified during
+    processing. */
 mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len);
 
-/* Return the number of bytes required to represent z as unsigned output */
+/** Returns the number of bytes required to represent `z` as an unsigned binary
+    value in base 256. */
 mp_result mp_int_unsigned_len(mp_int z);
 
-/* Return a statically allocated string describing error code res */
+/** Returns a pointer to a brief, human-readable, zero-terminated string
+    describing `res`. The returned string is statically allocated and must not
+    be freed by the caller. */
 const char *mp_error_string(mp_result res);
 
-#if DEBUG
-void      s_print(char *tag, mp_int z);
-void      s_print_buf(char *tag, mp_digit *buf, mp_size num);
-#endif
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/External/isl/imath/imrat.c b/lib/External/isl/imath/imrat.c
index 49448fe..afcfdaf 100644
--- a/lib/External/isl/imath/imrat.c
+++ b/lib/External/isl/imath/imrat.c
@@ -1,7 +1,7 @@
 /*
   Name:     imrat.c
   Purpose:  Arbitrary precision rational arithmetic routines.
-  Author:   M. J. Fromberger <http://spinning-yarns.org/michael/>
+  Author:   M. J. Fromberger
 
   Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
 
@@ -25,19 +25,20 @@
  */
 
 #include "imrat.h"
+#include <assert.h>
+#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-#include <assert.h>
+
+#define MP_NUMER_SIGN(Q) (MP_NUMER_P(Q)->sign)
+#define MP_DENOM_SIGN(Q) (MP_DENOM_P(Q)->sign)
 
 #define TEMP(K) (temp + (K))
-#define SETUP(E, C) \
-do{if((res = (E)) != MP_OK) goto CLEANUP; ++(C);}while(0)
-
-/* Argument checking:
-   Use CHECK() where a return value is required; NRCHECK() elsewhere */
-#define CHECK(TEST)   assert(TEST)
-#define NRCHECK(TEST) assert(TEST)
+#define SETUP(E, C)                         \
+  do {                                      \
+    if ((res = (E)) != MP_OK) goto CLEANUP; \
+    ++(C);                                  \
+  } while (0)
 
 /* Reduce the given rational, in place, to lowest terms and canonical form.
    Zero is represented as 0/1, one as 1/1.  Signs are adjusted so that the sign
@@ -46,14 +47,12 @@
 
 /* Common code for addition and subtraction operations on rationals. */
 static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c,
-			       mp_result (*comb_f)(mp_int, mp_int, mp_int));
+                               mp_result (*comb_f)(mp_int, mp_int, mp_int));
 
-mp_result mp_rat_init(mp_rat r)
-{
+mp_result mp_rat_init(mp_rat r) {
   mp_result res;
 
-  if ((res = mp_int_init(MP_NUMER_P(r))) != MP_OK)
-    return res;
+  if ((res = mp_int_init(MP_NUMER_P(r))) != MP_OK) return res;
   if ((res = mp_int_init(MP_DENOM_P(r))) != MP_OK) {
     mp_int_clear(MP_NUMER_P(r));
     return res;
@@ -62,8 +61,7 @@
   return mp_int_set_value(MP_DENOM_P(r), 1);
 }
 
-mp_rat mp_rat_alloc(void)
-{
+mp_rat mp_rat_alloc(void) {
   mp_rat out = malloc(sizeof(*out));
 
   if (out != NULL) {
@@ -76,456 +74,429 @@
   return out;
 }
 
-mp_result mp_rat_reduce(mp_rat r) {
-  return s_rat_reduce(r);
-}
+mp_result mp_rat_reduce(mp_rat r) { return s_rat_reduce(r); }
 
-mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec)
-{
+mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec) {
   mp_result res;
 
-  if ((res = mp_int_init_size(MP_NUMER_P(r), n_prec)) != MP_OK)
+  if ((res = mp_int_init_size(MP_NUMER_P(r), n_prec)) != MP_OK) {
     return res;
+  }
   if ((res = mp_int_init_size(MP_DENOM_P(r), d_prec)) != MP_OK) {
     mp_int_clear(MP_NUMER_P(r));
     return res;
   }
-  
+
   return mp_int_set_value(MP_DENOM_P(r), 1);
 }
 
-mp_result mp_rat_init_copy(mp_rat r, mp_rat old)
-{
+mp_result mp_rat_init_copy(mp_rat r, mp_rat old) {
   mp_result res;
 
-  if ((res = mp_int_init_copy(MP_NUMER_P(r), MP_NUMER_P(old))) != MP_OK)
+  if ((res = mp_int_init_copy(MP_NUMER_P(r), MP_NUMER_P(old))) != MP_OK) {
     return res;
-  if ((res = mp_int_init_copy(MP_DENOM_P(r), MP_DENOM_P(old))) != MP_OK) 
+  }
+  if ((res = mp_int_init_copy(MP_DENOM_P(r), MP_DENOM_P(old))) != MP_OK)
     mp_int_clear(MP_NUMER_P(r));
-  
+
   return res;
 }
 
-mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom)
-{
+mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom) {
   mp_result res;
 
-  if (denom == 0)
-    return MP_UNDEF;
+  if (denom == 0) return MP_UNDEF;
 
-  if ((res = mp_int_set_value(MP_NUMER_P(r), numer)) != MP_OK)
+  if ((res = mp_int_set_value(MP_NUMER_P(r), numer)) != MP_OK) {
     return res;
-  if ((res = mp_int_set_value(MP_DENOM_P(r), denom)) != MP_OK)
+  }
+  if ((res = mp_int_set_value(MP_DENOM_P(r), denom)) != MP_OK) {
     return res;
+  }
 
   return s_rat_reduce(r);
 }
 
-mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom)
-{
+mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom) {
   mp_result res;
 
-  if (denom == 0)
-    return MP_UNDEF;
+  if (denom == 0) return MP_UNDEF;
 
-  if ((res = mp_int_set_uvalue(MP_NUMER_P(r), numer)) != MP_OK)
+  if ((res = mp_int_set_uvalue(MP_NUMER_P(r), numer)) != MP_OK) {
     return res;
-  if ((res = mp_int_set_uvalue(MP_DENOM_P(r), denom)) != MP_OK)
+  }
+  if ((res = mp_int_set_uvalue(MP_DENOM_P(r), denom)) != MP_OK) {
     return res;
+  }
 
   return s_rat_reduce(r);
 }
 
-void      mp_rat_clear(mp_rat r)
-{
+void mp_rat_clear(mp_rat r) {
   mp_int_clear(MP_NUMER_P(r));
   mp_int_clear(MP_DENOM_P(r));
-
 }
 
-void      mp_rat_free(mp_rat r)
-{
-  NRCHECK(r != NULL);
-  
-  if (r->num.digits != NULL)
-    mp_rat_clear(r);
+void mp_rat_free(mp_rat r) {
+  assert(r != NULL);
+
+  if (r->num.digits != NULL) mp_rat_clear(r);
 
   free(r);
 }
 
-mp_result mp_rat_numer(mp_rat r, mp_int z)
-{
+mp_result mp_rat_numer(mp_rat r, mp_int z) {
   return mp_int_copy(MP_NUMER_P(r), z);
 }
 
-mp_int mp_rat_numer_ref(mp_rat r)
-{
-  return MP_NUMER_P(r);
-}
+mp_int mp_rat_numer_ref(mp_rat r) { return MP_NUMER_P(r); }
 
-
-mp_result mp_rat_denom(mp_rat r, mp_int z)
-{
+mp_result mp_rat_denom(mp_rat r, mp_int z) {
   return mp_int_copy(MP_DENOM_P(r), z);
 }
 
-mp_int    mp_rat_denom_ref(mp_rat r)
-{
-  return MP_DENOM_P(r);
-}
+mp_int mp_rat_denom_ref(mp_rat r) { return MP_DENOM_P(r); }
 
-mp_sign   mp_rat_sign(mp_rat r)
-{
-  return MP_SIGN(MP_NUMER_P(r));
-}
+mp_sign mp_rat_sign(mp_rat r) { return MP_NUMER_SIGN(r); }
 
-mp_result mp_rat_copy(mp_rat a, mp_rat c)
-{
+mp_result mp_rat_copy(mp_rat a, mp_rat c) {
   mp_result res;
 
-  if ((res = mp_int_copy(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK)
+  if ((res = mp_int_copy(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) {
     return res;
-  
+  }
+
   res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c));
   return res;
 }
 
-void      mp_rat_zero(mp_rat r)
-{
+void mp_rat_zero(mp_rat r) {
   mp_int_zero(MP_NUMER_P(r));
   mp_int_set_value(MP_DENOM_P(r), 1);
-  
 }
 
-mp_result mp_rat_abs(mp_rat a, mp_rat c)
-{
+mp_result mp_rat_abs(mp_rat a, mp_rat c) {
   mp_result res;
 
-  if ((res = mp_int_abs(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK)
+  if ((res = mp_int_abs(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) {
     return res;
-  
+  }
+
   res = mp_int_abs(MP_DENOM_P(a), MP_DENOM_P(c));
   return res;
 }
 
-mp_result mp_rat_neg(mp_rat a, mp_rat c)
-{
+mp_result mp_rat_neg(mp_rat a, mp_rat c) {
   mp_result res;
 
-  if ((res = mp_int_neg(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK)
+  if ((res = mp_int_neg(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) {
     return res;
+  }
 
   res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c));
   return res;
 }
 
-mp_result mp_rat_recip(mp_rat a, mp_rat c)
-{
+mp_result mp_rat_recip(mp_rat a, mp_rat c) {
   mp_result res;
 
-  if (mp_rat_compare_zero(a) == 0)
-    return MP_UNDEF;
+  if (mp_rat_compare_zero(a) == 0) return MP_UNDEF;
 
-  if ((res = mp_rat_copy(a, c)) != MP_OK)
-    return res;
+  if ((res = mp_rat_copy(a, c)) != MP_OK) return res;
 
   mp_int_swap(MP_NUMER_P(c), MP_DENOM_P(c));
 
   /* Restore the signs of the swapped elements */
   {
-    mp_sign tmp = MP_SIGN(MP_NUMER_P(c));
+    mp_sign tmp = MP_NUMER_SIGN(c);
 
-    MP_SIGN(MP_NUMER_P(c)) = MP_SIGN(MP_DENOM_P(c));
-    MP_SIGN(MP_DENOM_P(c)) = tmp;
+    MP_NUMER_SIGN(c) = MP_DENOM_SIGN(c);
+    MP_DENOM_SIGN(c) = tmp;
   }
 
   return MP_OK;
 }
 
-mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c)
-{
+mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c) {
   return s_rat_combine(a, b, c, mp_int_add);
-
 }
 
-mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c)
-{
+mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c) {
   return s_rat_combine(a, b, c, mp_int_sub);
-
 }
 
-mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c)
-{
+mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c) {
   mp_result res;
 
   if ((res = mp_int_mul(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != MP_OK)
     return res;
 
   if (mp_int_compare_zero(MP_NUMER_P(c)) != 0) {
-    if ((res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c))) != MP_OK)
+    res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c));
+    if (res != MP_OK) {
       return res;
+    }
   }
 
   return s_rat_reduce(c);
 }
 
-mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c)
-{
+mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c) {
   mp_result res = MP_OK;
 
-  if (mp_rat_compare_zero(b) == 0)
-    return MP_UNDEF;
+  if (mp_rat_compare_zero(b) == 0) return MP_UNDEF;
 
   if (c == a || c == b) {
     mpz_t tmp;
 
     if ((res = mp_int_init(&tmp)) != MP_OK) return res;
-    if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), &tmp)) != MP_OK) 
+    if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), &tmp)) != MP_OK) {
       goto CLEANUP;
-    if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != MP_OK)
+    }
+    if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) !=
+        MP_OK) {
       goto CLEANUP;
+    }
     res = mp_int_copy(&tmp, MP_NUMER_P(c));
 
   CLEANUP:
     mp_int_clear(&tmp);
-  }
-  else {
-    if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), MP_NUMER_P(c))) != MP_OK)
+  } else {
+    if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), MP_NUMER_P(c))) !=
+        MP_OK) {
       return res;
-    if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != MP_OK)
+    }
+    if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) !=
+        MP_OK) {
       return res;
+    }
   }
 
-  if (res != MP_OK)
+  if (res != MP_OK) {
     return res;
-  else
+  } else {
     return s_rat_reduce(c);
+  }
 }
 
-mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c)
-{
+mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c) {
   mpz_t tmp;
   mp_result res;
 
-  if ((res = mp_int_init_copy(&tmp, b)) != MP_OK)
+  if ((res = mp_int_init_copy(&tmp, b)) != MP_OK) {
     return res;
-
-  if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK)
+  }
+  if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK) {
     goto CLEANUP;
-
-  if ((res = mp_rat_copy(a, c)) != MP_OK)
+  }
+  if ((res = mp_rat_copy(a, c)) != MP_OK) {
     goto CLEANUP;
-
-  if ((res = mp_int_add(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK)
+  }
+  if ((res = mp_int_add(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) {
     goto CLEANUP;
+  }
 
   res = s_rat_reduce(c);
 
- CLEANUP:
+CLEANUP:
   mp_int_clear(&tmp);
   return res;
 }
 
-mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c)
-{
+mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c) {
   mpz_t tmp;
   mp_result res;
 
-  if ((res = mp_int_init_copy(&tmp, b)) != MP_OK)
+  if ((res = mp_int_init_copy(&tmp, b)) != MP_OK) {
     return res;
-
-  if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK)
+  }
+  if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK) {
     goto CLEANUP;
-
-  if ((res = mp_rat_copy(a, c)) != MP_OK)
+  }
+  if ((res = mp_rat_copy(a, c)) != MP_OK) {
     goto CLEANUP;
-
-  if ((res = mp_int_sub(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK)
+  }
+  if ((res = mp_int_sub(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) {
     goto CLEANUP;
+  }
 
   res = s_rat_reduce(c);
 
- CLEANUP:
+CLEANUP:
   mp_int_clear(&tmp);
   return res;
 }
 
-mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c)
-{
+mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c) {
   mp_result res;
 
-  if ((res = mp_rat_copy(a, c)) != MP_OK)
+  if ((res = mp_rat_copy(a, c)) != MP_OK) {
     return res;
-
-  if ((res = mp_int_mul(MP_NUMER_P(c), b, MP_NUMER_P(c))) != MP_OK)
+  }
+  if ((res = mp_int_mul(MP_NUMER_P(c), b, MP_NUMER_P(c))) != MP_OK) {
     return res;
+  }
 
   return s_rat_reduce(c);
 }
 
-mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c)
-{
+mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c) {
   mp_result res;
 
-  if (mp_int_compare_zero(b) == 0)
+  if (mp_int_compare_zero(b) == 0) {
     return MP_UNDEF;
-
-  if ((res = mp_rat_copy(a, c)) != MP_OK)
+  }
+  if ((res = mp_rat_copy(a, c)) != MP_OK) {
     return res;
-
-  if ((res = mp_int_mul(MP_DENOM_P(c), b, MP_DENOM_P(c))) != MP_OK)
+  }
+  if ((res = mp_int_mul(MP_DENOM_P(c), b, MP_DENOM_P(c))) != MP_OK) {
     return res;
+  }
 
   return s_rat_reduce(c);
 }
 
-mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c)
-{
-  mp_result  res;
+mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c) {
+  mp_result res;
 
   /* Special cases for easy powers. */
-  if (b == 0)
+  if (b == 0) {
     return mp_rat_set_value(c, 1, 1);
-  else if(b == 1)
+  } else if (b == 1) {
     return mp_rat_copy(a, c);
+  }
 
   /* Since rationals are always stored in lowest terms, it is not necessary to
      reduce again when raising to an integer power. */
-  if ((res = mp_int_expt(MP_NUMER_P(a), b, MP_NUMER_P(c))) != MP_OK)
+  if ((res = mp_int_expt(MP_NUMER_P(a), b, MP_NUMER_P(c))) != MP_OK) {
     return res;
+  }
 
   return mp_int_expt(MP_DENOM_P(a), b, MP_DENOM_P(c));
 }
 
-int       mp_rat_compare(mp_rat a, mp_rat b)
-{
+int mp_rat_compare(mp_rat a, mp_rat b) {
   /* Quick check for opposite signs.  Works because the sign of the numerator
      is always definitive. */
-  if (MP_SIGN(MP_NUMER_P(a)) != MP_SIGN(MP_NUMER_P(b))) {
-    if (MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS)
+  if (MP_NUMER_SIGN(a) != MP_NUMER_SIGN(b)) {
+    if (MP_NUMER_SIGN(a) == MP_ZPOS) {
       return 1;
-    else
+    } else {
       return -1;
-  }
-  else {
+    }
+  } else {
     /* Compare absolute magnitudes; if both are positive, the answer stands,
        otherwise it needs to be reflected about zero. */
     int cmp = mp_rat_compare_unsigned(a, b);
 
-    if (MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS)
+    if (MP_NUMER_SIGN(a) == MP_ZPOS) {
       return cmp;
-    else
+    } else {
       return -cmp;
+    }
   }
 }
 
-int       mp_rat_compare_unsigned(mp_rat a, mp_rat b)
-{
+int mp_rat_compare_unsigned(mp_rat a, mp_rat b) {
   /* If the denominators are equal, we can quickly compare numerators without
      multiplying.  Otherwise, we actually have to do some work. */
-  if (mp_int_compare_unsigned(MP_DENOM_P(a), MP_DENOM_P(b)) == 0)
+  if (mp_int_compare_unsigned(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) {
     return mp_int_compare_unsigned(MP_NUMER_P(a), MP_NUMER_P(b));
+  }
 
   else {
-    mpz_t  temp[2];
+    mpz_t temp[2];
     mp_result res;
-    int  cmp = INT_MAX, last = 0;
+    int cmp = INT_MAX, last = 0;
 
     /* t0 = num(a) * den(b), t1 = num(b) * den(a) */
     SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last);
     SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last);
 
     if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK ||
-	(res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK)
+        (res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) {
       goto CLEANUP;
-    
+    }
+
     cmp = mp_int_compare_unsigned(TEMP(0), TEMP(1));
-    
+
   CLEANUP:
-    while (--last >= 0)
+    while (--last >= 0) {
       mp_int_clear(TEMP(last));
+    }
 
     return cmp;
   }
 }
 
-int       mp_rat_compare_zero(mp_rat r)
-{
-  return mp_int_compare_zero(MP_NUMER_P(r));
-}
+int mp_rat_compare_zero(mp_rat r) { return mp_int_compare_zero(MP_NUMER_P(r)); }
 
-int       mp_rat_compare_value(mp_rat r, mp_small n, mp_small d)
-{
+int mp_rat_compare_value(mp_rat r, mp_small n, mp_small d) {
   mpq_t tmp;
   mp_result res;
-  int  out = INT_MAX;
+  int out = INT_MAX;
 
-  if ((res = mp_rat_init(&tmp)) != MP_OK)
+  if ((res = mp_rat_init(&tmp)) != MP_OK) {
     return out;
-  if ((res = mp_rat_set_value(&tmp, n, d)) != MP_OK)
+  }
+  if ((res = mp_rat_set_value(&tmp, n, d)) != MP_OK) {
     goto CLEANUP;
-  
+  }
+
   out = mp_rat_compare(r, &tmp);
-  
- CLEANUP:
+
+CLEANUP:
   mp_rat_clear(&tmp);
   return out;
 }
 
-int       mp_rat_is_integer(mp_rat r)
-{
+bool mp_rat_is_integer(mp_rat r) {
   return (mp_int_compare_value(MP_DENOM_P(r), 1) == 0);
 }
 
-mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den)
-{
+mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den) {
   mp_result res;
 
-  if ((res = mp_int_to_int(MP_NUMER_P(r), num)) != MP_OK)
+  if ((res = mp_int_to_int(MP_NUMER_P(r), num)) != MP_OK) {
     return res;
+  }
 
   res = mp_int_to_int(MP_DENOM_P(r), den);
   return res;
 }
 
-mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit)
-{
-  char *start;
-  int   len;
-  mp_result res;
-
+mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit) {
   /* Write the numerator.  The sign of the rational number is written by the
      underlying integer implementation. */
-  if ((res = mp_int_to_string(MP_NUMER_P(r), radix, str, limit)) != MP_OK)
+  mp_result res;
+  if ((res = mp_int_to_string(MP_NUMER_P(r), radix, str, limit)) != MP_OK) {
     return res;
+  }
 
   /* If the value is zero, don't bother writing any denominator */
-  if (mp_int_compare_zero(MP_NUMER_P(r)) == 0)
+  if (mp_int_compare_zero(MP_NUMER_P(r)) == 0) {
     return MP_OK;
-  
+  }
+
   /* Locate the end of the numerator, and make sure we are not going to exceed
      the limit by writing a slash. */
-  len = strlen(str);
-  start = str + len;
+  int len = strlen(str);
+  char *start = str + len;
   limit -= len;
-  if(limit == 0)
-    return MP_TRUNC;
+  if (limit == 0) return MP_TRUNC;
 
   *start++ = '/';
   limit -= 1;
-  
-  res = mp_int_to_string(MP_DENOM_P(r), radix, start, limit);
-  return res;
+
+  return mp_int_to_string(MP_DENOM_P(r), radix, start, limit);
 }
 
 mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec,
-                            mp_round_mode round, char *str, int limit)
-{
+                            mp_round_mode round, char *str, int limit) {
   mpz_t temp[3];
   mp_result res;
-  char *start = str;
-  int len, lead_0, left = limit, last = 0;
-    
+  int last = 0;
+
   SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(r)), last);
   SETUP(mp_int_init(TEMP(last)), last);
   SETUP(mp_int_init(TEMP(last)), last);
@@ -533,32 +504,39 @@
   /* Get the unsigned integer part by dividing denominator into the absolute
      value of the numerator. */
   mp_int_abs(TEMP(0), TEMP(0));
-  if ((res = mp_int_div(TEMP(0), MP_DENOM_P(r), TEMP(0), TEMP(1))) != MP_OK)
+  if ((res = mp_int_div(TEMP(0), MP_DENOM_P(r), TEMP(0), TEMP(1))) != MP_OK) {
     goto CLEANUP;
+  }
 
   /* Now:  T0 = integer portion, unsigned;
            T1 = remainder, from which fractional part is computed. */
 
   /* Count up leading zeroes after the radix point. */
-  for (lead_0 = 0; lead_0 < prec && mp_int_compare(TEMP(1), MP_DENOM_P(r)) < 0; 
-      ++lead_0) {
-    if ((res = mp_int_mul_value(TEMP(1), radix, TEMP(1))) != MP_OK)
+  int zprec = (int)prec;
+  int lead_0;
+  for (lead_0 = 0; lead_0 < zprec && mp_int_compare(TEMP(1), MP_DENOM_P(r)) < 0;
+       ++lead_0) {
+    if ((res = mp_int_mul_value(TEMP(1), radix, TEMP(1))) != MP_OK) {
       goto CLEANUP;
+    }
   }
 
   /* Multiply remainder by a power of the radix sufficient to get the right
      number of significant figures. */
-  if (prec > lead_0) {
-    if ((res = mp_int_expt_value(radix, prec - lead_0, TEMP(2))) != MP_OK)
+  if (zprec > lead_0) {
+    if ((res = mp_int_expt_value(radix, zprec - lead_0, TEMP(2))) != MP_OK) {
       goto CLEANUP;
-    if ((res = mp_int_mul(TEMP(1), TEMP(2), TEMP(1))) != MP_OK)
+    }
+    if ((res = mp_int_mul(TEMP(1), TEMP(2), TEMP(1))) != MP_OK) {
       goto CLEANUP;
+    }
   }
-  if ((res = mp_int_div(TEMP(1), MP_DENOM_P(r), TEMP(1), TEMP(2))) != MP_OK)
+  if ((res = mp_int_div(TEMP(1), MP_DENOM_P(r), TEMP(1), TEMP(2))) != MP_OK) {
     goto CLEANUP;
+  }
 
   /* Now:  T1 = significant digits of fractional part;
-           T2 = leftovers, to use for rounding. 
+           T2 = leftovers, to use for rounding.
 
      At this point, what we do depends on the rounding mode.  The default is
      MP_ROUND_DOWN, for which everything is as it should be already.
@@ -566,64 +544,70 @@
   switch (round) {
     int cmp;
 
-  case MP_ROUND_UP:
-    if (mp_int_compare_zero(TEMP(2)) != 0) {
-      if (prec == 0)
-	res = mp_int_add_value(TEMP(0), 1, TEMP(0));
-      else
-	res = mp_int_add_value(TEMP(1), 1, TEMP(1));
-    }
-    break;
+    case MP_ROUND_UP:
+      if (mp_int_compare_zero(TEMP(2)) != 0) {
+        if (prec == 0) {
+          res = mp_int_add_value(TEMP(0), 1, TEMP(0));
+        } else {
+          res = mp_int_add_value(TEMP(1), 1, TEMP(1));
+        }
+      }
+      break;
 
-  case MP_ROUND_HALF_UP:
-  case MP_ROUND_HALF_DOWN:
-    if ((res = mp_int_mul_pow2(TEMP(2), 1, TEMP(2))) != MP_OK)
-      goto CLEANUP;
+    case MP_ROUND_HALF_UP:
+    case MP_ROUND_HALF_DOWN:
+      if ((res = mp_int_mul_pow2(TEMP(2), 1, TEMP(2))) != MP_OK) {
+        goto CLEANUP;
+      }
 
-    cmp = mp_int_compare(TEMP(2), MP_DENOM_P(r));    
+      cmp = mp_int_compare(TEMP(2), MP_DENOM_P(r));
 
-    if (round == MP_ROUND_HALF_UP)
-      cmp += 1;
+      if (round == MP_ROUND_HALF_UP) cmp += 1;
 
-    if (cmp > 0) {
-      if (prec == 0)
-	res = mp_int_add_value(TEMP(0), 1, TEMP(0));
-      else
-	res = mp_int_add_value(TEMP(1), 1, TEMP(1));
-    }
-    break;
-    
-  case MP_ROUND_DOWN:
-    break;  /* No action required */
+      if (cmp > 0) {
+        if (prec == 0) {
+          res = mp_int_add_value(TEMP(0), 1, TEMP(0));
+        } else {
+          res = mp_int_add_value(TEMP(1), 1, TEMP(1));
+        }
+      }
+      break;
 
-  default: 
-    return MP_BADARG; /* Invalid rounding specifier */
+    case MP_ROUND_DOWN:
+      break; /* No action required */
+
+    default:
+      return MP_BADARG; /* Invalid rounding specifier */
+  }
+  if (res != MP_OK) {
+    goto CLEANUP;
   }
 
   /* The sign of the output should be the sign of the numerator, but if all the
      displayed digits will be zero due to the precision, a negative shouldn't
      be shown. */
-  if (MP_SIGN(MP_NUMER_P(r)) == MP_NEG &&
-      (mp_int_compare_zero(TEMP(0)) != 0 ||
-       mp_int_compare_zero(TEMP(1)) != 0)) {
+  char *start = str;
+  int left = limit;
+  if (MP_NUMER_SIGN(r) == MP_NEG && (mp_int_compare_zero(TEMP(0)) != 0 ||
+                                     mp_int_compare_zero(TEMP(1)) != 0)) {
     *start++ = '-';
     left -= 1;
   }
 
-  if ((res = mp_int_to_string(TEMP(0), radix, start, left)) != MP_OK)
+  if ((res = mp_int_to_string(TEMP(0), radix, start, left)) != MP_OK) {
     goto CLEANUP;
-  
-  len = strlen(start);
+  }
+
+  int len = strlen(start);
   start += len;
   left -= len;
-  
-  if (prec == 0) 
-    goto CLEANUP;
-  
+
+  if (prec == 0) goto CLEANUP;
+
   *start++ = '.';
   left -= 1;
-  
-  if (left < prec + 1) {
+
+  if (left < zprec + 1) {
     res = MP_TRUNC;
     goto CLEANUP;
   }
@@ -634,21 +618,19 @@
 
   res = mp_int_to_string(TEMP(1), radix, start, left);
 
- CLEANUP:
-  while (--last >= 0)
-    mp_int_clear(TEMP(last));
-  
+CLEANUP:
+  while (--last >= 0) mp_int_clear(TEMP(last));
+
   return res;
 }
 
-mp_result mp_rat_string_len(mp_rat r, mp_size radix)
-{
-  mp_result n_len, d_len = 0;
+mp_result mp_rat_string_len(mp_rat r, mp_size radix) {
+  mp_result d_len = 0;
+  mp_result n_len = mp_int_string_len(MP_NUMER_P(r), radix);
 
-  n_len = mp_int_string_len(MP_NUMER_P(r), radix);
-
-  if (mp_int_compare_zero(MP_NUMER_P(r)) != 0)
+  if (mp_int_compare_zero(MP_NUMER_P(r)) != 0) {
     d_len = mp_int_string_len(MP_DENOM_P(r), radix);
+  }
 
   /* Though simplistic, this formula is correct.  Space for the sign flag is
      included in n_len, and the space for the NUL that is counted in n_len
@@ -656,57 +638,56 @@
      counts for the final terminator here. */
 
   return n_len + d_len;
-
 }
 
-mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec)
-{
-  int  z_len, f_len;
+mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec) {
+  int f_len;
+  int z_len = mp_int_string_len(MP_NUMER_P(r), radix);
 
-  z_len = mp_int_string_len(MP_NUMER_P(r), radix);
-  
-  if (prec == 0)
+  if (prec == 0) {
     f_len = 1; /* terminator only */
-  else
+  } else {
     f_len = 1 + prec + 1; /* decimal point, digits, terminator */
-  
+  }
+
   return z_len + f_len;
 }
 
-mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str)
-{
+mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str) {
   return mp_rat_read_cstring(r, radix, str, NULL);
 }
 
-mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str, 
-			      char **end)
-{
+mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str,
+                              char **end) {
   mp_result res;
   char *endp;
 
   if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK &&
-      (res != MP_TRUNC))
+      (res != MP_TRUNC)) {
     return res;
+  }
 
   /* Skip whitespace between numerator and (possible) separator */
-  while (isspace((unsigned char) *endp))
+  while (isspace((unsigned char)*endp)) {
     ++endp;
-  
+  }
+
   /* If there is no separator, we will stop reading at this point. */
   if (*endp != '/') {
     mp_int_set_value(MP_DENOM_P(r), 1);
-    if (end != NULL)
-      *end = endp;
+    if (end != NULL) *end = endp;
     return res;
   }
-  
+
   ++endp; /* skip separator */
-  if ((res = mp_int_read_cstring(MP_DENOM_P(r), radix, endp, end)) != MP_OK)
+  if ((res = mp_int_read_cstring(MP_DENOM_P(r), radix, endp, end)) != MP_OK) {
     return res;
-  
+  }
+
   /* Make sure the value is well-defined */
-  if (mp_int_compare_zero(MP_DENOM_P(r)) == 0)
+  if (mp_int_compare_zero(MP_DENOM_P(r)) == 0) {
     return MP_UNDEF;
+  }
 
   /* Reduce to lowest terms */
   return s_rat_reduce(r);
@@ -717,63 +698,51 @@
 
    This function will accept either a/b notation or decimal notation.
  */
-mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str, 
-			      char **end)
-{
-  char      *endp;
-  mp_result  res;
+mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str,
+                              char **end) {
+  char *endp = "";
+  mp_result res;
 
-  if (radix == 0)
-    radix = 10;  /* default to decimal input */
+  if (radix == 0) radix = 10; /* default to decimal input */
 
-  if ((res = mp_rat_read_cstring(r, radix, str, &endp)) != MP_OK) {
-    if (res == MP_TRUNC) {
-      if (*endp == '.')
-	res = mp_rat_read_cdecimal(r, radix, str, &endp);
-    }
-    else
-      return res;
+  res = mp_rat_read_cstring(r, radix, str, &endp);
+  if (res == MP_TRUNC && *endp == '.') {
+    res = mp_rat_read_cdecimal(r, radix, str, &endp);
   }
-
-  if (end != NULL)
-    *end = endp;
-
+  if (end != NULL) *end = endp;
   return res;
 }
 
-mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str)
-{
+mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str) {
   return mp_rat_read_cdecimal(r, radix, str, NULL);
 }
 
-mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str, 
-			       char **end)
-{
+mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str,
+                               char **end) {
   mp_result res;
-  mp_sign   osign;
+  mp_sign osign;
   char *endp;
 
-  while (isspace((unsigned char) *str))
-    ++str;
-  
+  while (isspace((unsigned char)*str)) ++str;
+
   switch (*str) {
-  case '-':
-    osign = MP_NEG;
-    break;
-  default:
-    osign = MP_ZPOS;
+    case '-':
+      osign = MP_NEG;
+      break;
+    default:
+      osign = MP_ZPOS;
   }
-  
+
   if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK &&
-     (res != MP_TRUNC))
+      (res != MP_TRUNC)) {
     return res;
+  }
 
   /* This needs to be here. */
-  (void) mp_int_set_value(MP_DENOM_P(r), 1);
+  (void)mp_int_set_value(MP_DENOM_P(r), 1);
 
   if (*endp != '.') {
-    if (end != NULL)
-      *end = endp;
+    if (end != NULL) *end = endp;
     return res;
   }
 
@@ -788,55 +757,60 @@
   */
   ++endp;
   if (*endp == '\0') {
-    if (end != NULL)
-      *end = endp;
+    if (end != NULL) *end = endp;
     return MP_OK;
-  }
-  else if(isspace((unsigned char) *endp) || *endp == '-' || *endp == '+') {
+  } else if (isspace((unsigned char)*endp) || *endp == '-' || *endp == '+') {
     return MP_TRUNC;
-  }
-  else {
-    mpz_t  frac;
+  } else {
+    mpz_t frac;
     mp_result save_res;
-    char  *save = endp;
-    int    num_lz = 0;
+    char *save = endp;
+    int num_lz = 0;
 
     /* Make a temporary to hold the part after the decimal point. */
-    if ((res = mp_int_init(&frac)) != MP_OK)
+    if ((res = mp_int_init(&frac)) != MP_OK) {
       return res;
-    
+    }
+
     if ((res = mp_int_read_cstring(&frac, radix, endp, &endp)) != MP_OK &&
-       (res != MP_TRUNC))
+        (res != MP_TRUNC)) {
       goto CLEANUP;
+    }
 
     /* Save this response for later. */
     save_res = res;
 
-    if (mp_int_compare_zero(&frac) == 0)
-      goto FINISHED;
+    if (mp_int_compare_zero(&frac) == 0) goto FINISHED;
 
     /* Discard trailing zeroes (somewhat inefficiently) */
-    while (mp_int_divisible_value(&frac, radix))
-      if ((res = mp_int_div_value(&frac, radix, &frac, NULL)) != MP_OK)
-	goto CLEANUP;
-    
+    while (mp_int_divisible_value(&frac, radix)) {
+      if ((res = mp_int_div_value(&frac, radix, &frac, NULL)) != MP_OK) {
+        goto CLEANUP;
+      }
+    }
+
     /* Count leading zeros after the decimal point */
-    while (save[num_lz] == '0')
+    while (save[num_lz] == '0') {
       ++num_lz;
+    }
 
     /* Find the least power of the radix that is at least as large as the
        significant value of the fractional part, ignoring leading zeroes.  */
-    (void) mp_int_set_value(MP_DENOM_P(r), radix); 
-    
+    (void)mp_int_set_value(MP_DENOM_P(r), radix);
+
     while (mp_int_compare(MP_DENOM_P(r), &frac) < 0) {
-      if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != MP_OK)
-	goto CLEANUP;
+      if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) !=
+          MP_OK) {
+        goto CLEANUP;
+      }
     }
-    
+
     /* Also shift by enough to account for leading zeroes */
     while (num_lz > 0) {
-      if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != MP_OK)
-	goto CLEANUP;
+      if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) !=
+          MP_OK) {
+        goto CLEANUP;
+      }
 
       --num_lz;
     }
@@ -844,26 +818,27 @@
     /* Having found this power, shift the numerator leftward that many, digits,
        and add the nonzero significant digits of the fractional part to get the
        result. */
-    if ((res = mp_int_mul(MP_NUMER_P(r), MP_DENOM_P(r), MP_NUMER_P(r))) != MP_OK)
+    if ((res = mp_int_mul(MP_NUMER_P(r), MP_DENOM_P(r), MP_NUMER_P(r))) !=
+        MP_OK) {
       goto CLEANUP;
-    
-    { /* This addition needs to be unsigned. */
-      MP_SIGN(MP_NUMER_P(r)) = MP_ZPOS;
-      if ((res = mp_int_add(MP_NUMER_P(r), &frac, MP_NUMER_P(r))) != MP_OK)
-	goto CLEANUP;
-
-      MP_SIGN(MP_NUMER_P(r)) = osign;
     }
-    if ((res = s_rat_reduce(r)) != MP_OK)
-      goto CLEANUP;
+
+    { /* This addition needs to be unsigned. */
+      MP_NUMER_SIGN(r) = MP_ZPOS;
+      if ((res = mp_int_add(MP_NUMER_P(r), &frac, MP_NUMER_P(r))) != MP_OK) {
+        goto CLEANUP;
+      }
+
+      MP_NUMER_SIGN(r) = osign;
+    }
+    if ((res = s_rat_reduce(r)) != MP_OK) goto CLEANUP;
 
     /* At this point, what we return depends on whether reading the fractional
        part was truncated or not.  That information is saved from when we
        called mp_int_read_string() above. */
   FINISHED:
     res = save_res;
-    if (end != NULL)
-      *end = endp;
+    if (end != NULL) *end = endp;
 
   CLEANUP:
     mp_int_clear(&frac);
@@ -875,8 +850,7 @@
 /* Private functions for internal use.  Make unchecked assumptions about format
    and validity of inputs. */
 
-static mp_result s_rat_reduce(mp_rat r)
-{
+static mp_result s_rat_reduce(mp_rat r) {
   mpz_t gcd;
   mp_result res = MP_OK;
 
@@ -887,71 +861,79 @@
 
   /* If the greatest common divisor of the numerator and denominator is greater
      than 1, divide it out. */
-  if ((res = mp_int_init(&gcd)) != MP_OK)
-    return res;
+  if ((res = mp_int_init(&gcd)) != MP_OK) return res;
 
-  if ((res = mp_int_gcd(MP_NUMER_P(r), MP_DENOM_P(r), &gcd)) != MP_OK)
+  if ((res = mp_int_gcd(MP_NUMER_P(r), MP_DENOM_P(r), &gcd)) != MP_OK) {
     goto CLEANUP;
+  }
 
   if (mp_int_compare_value(&gcd, 1) != 0) {
-    if ((res = mp_int_div(MP_NUMER_P(r), &gcd, MP_NUMER_P(r), NULL)) != MP_OK)
+    if ((res = mp_int_div(MP_NUMER_P(r), &gcd, MP_NUMER_P(r), NULL)) != MP_OK) {
       goto CLEANUP;
-    if ((res = mp_int_div(MP_DENOM_P(r), &gcd, MP_DENOM_P(r), NULL)) != MP_OK)
+    }
+    if ((res = mp_int_div(MP_DENOM_P(r), &gcd, MP_DENOM_P(r), NULL)) != MP_OK) {
       goto CLEANUP;
+    }
   }
 
   /* Fix up the signs of numerator and denominator */
-  if (MP_SIGN(MP_NUMER_P(r)) == MP_SIGN(MP_DENOM_P(r)))
-    MP_SIGN(MP_NUMER_P(r)) = MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS;
-  else {
-    MP_SIGN(MP_NUMER_P(r)) = MP_NEG;
-    MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS;
+  if (MP_NUMER_SIGN(r) == MP_DENOM_SIGN(r)) {
+    MP_NUMER_SIGN(r) = MP_DENOM_SIGN(r) = MP_ZPOS;
+  } else {
+    MP_NUMER_SIGN(r) = MP_NEG;
+    MP_DENOM_SIGN(r) = MP_ZPOS;
   }
 
- CLEANUP:
+CLEANUP:
   mp_int_clear(&gcd);
 
   return res;
 }
 
-static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c, 
-			       mp_result (*comb_f)(mp_int, mp_int, mp_int))
-{
+static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c,
+                               mp_result (*comb_f)(mp_int, mp_int, mp_int)) {
   mp_result res;
 
   /* Shortcut when denominators are already common */
   if (mp_int_compare(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) {
-    if ((res = (comb_f)(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != MP_OK)
+    if ((res = (comb_f)(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) !=
+        MP_OK) {
       return res;
-    if ((res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c))) != MP_OK)
+    }
+    if ((res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c))) != MP_OK) {
       return res;
-    
+    }
+
     return s_rat_reduce(c);
-  }
-  else {
-    mpz_t  temp[2];
-    int    last = 0;
+  } else {
+    mpz_t temp[2];
+    int last = 0;
 
     SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last);
     SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last);
-    
-    if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK)
+
+    if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK) {
       goto CLEANUP;
-    if ((res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK)
+    }
+    if ((res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) {
       goto CLEANUP;
-    if ((res = (comb_f)(TEMP(0), TEMP(1), MP_NUMER_P(c))) != MP_OK)
+    }
+    if ((res = (comb_f)(TEMP(0), TEMP(1), MP_NUMER_P(c))) != MP_OK) {
       goto CLEANUP;
+    }
 
     res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c));
 
   CLEANUP:
-    while (--last >= 0) 
+    while (--last >= 0) {
       mp_int_clear(TEMP(last));
+    }
 
-    if (res == MP_OK)
+    if (res == MP_OK) {
       return s_rat_reduce(c);
-    else
+    } else {
       return res;
+    }
   }
 }
 
diff --git a/lib/External/isl/imath/imrat.h b/lib/External/isl/imath/imrat.h
index a3678a2..87e167f 100644
--- a/lib/External/isl/imath/imrat.h
+++ b/lib/External/isl/imath/imrat.h
@@ -1,7 +1,7 @@
 /*
   Name:     imrat.h
   Purpose:  Arbitrary precision rational arithmetic routines.
-  Author:   M. J. Fromberger <http://spinning-yarns.org/michael/>
+  Author:   M. J. Fromberger
 
   Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
 
@@ -27,19 +27,24 @@
 #ifndef IMRAT_H_
 #define IMRAT_H_
 
+#include <stdbool.h>
+
 #include "imath.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef struct mpq {
+typedef struct {
   mpz_t   num;    /* Numerator         */
   mpz_t   den;    /* Denominator, <> 0 */
 } mpq_t, *mp_rat;
 
-#define MP_NUMER_P(Q)  (&((Q)->num)) /* Pointer to numerator   */
-#define MP_DENOM_P(Q)  (&((Q)->den)) /* Pointer to denominator */
+/* Return a pointer to the numerator. */
+static inline mp_int MP_NUMER_P(mp_rat Q) { return &(Q->num); }
+
+/* Return a pointer to the denominator. */
+static inline mp_int MP_DENOM_P(mp_rat Q) { return &(Q->den); }
 
 /* Rounding constants */
 typedef enum {
@@ -49,72 +54,213 @@
   MP_ROUND_HALF_DOWN
 } mp_round_mode;
 
+/** Initializes `r` with 1-digit precision and sets it to zero. This function
+    cannot fail unless `r` is NULL. */
 mp_result mp_rat_init(mp_rat r);
-mp_rat    mp_rat_alloc(void);
+
+/** Allocates a fresh zero-valued `mpq_t` on the heap, returning NULL in case
+    of error. The only possible error is out-of-memory. */
+mp_rat mp_rat_alloc(void);
+
+/** Reduces `r` in-place to lowest terms and canonical form.
+
+    Zero is represented as 0/1, one as 1/1, and signs are adjusted so that the
+    sign of the value is carried by the numerator. */
 mp_result mp_rat_reduce(mp_rat r);
+
+/** Initializes `r` with at least `n_prec` digits of storage for the numerator
+    and `d_prec` digits of storage for the denominator, and value zero.
+
+    If either precision is zero, the default precision is used, rounded up to
+    the nearest word size. */
 mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec);
+
+/** Initializes `r` to be a copy of an already-initialized value in `old`. The
+    new copy does not share storage with the original. */
 mp_result mp_rat_init_copy(mp_rat r, mp_rat old);
+
+/** Sets the value of `r` to the ratio of signed `numer` to signed `denom`.  It
+    returns `MP_UNDEF` if `denom` is zero. */
 mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom);
+
+/** Sets the value of `r` to the ratio of unsigned `numer` to unsigned
+    `denom`. It returns `MP_UNDEF` if `denom` is zero. */
 mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom);
-void      mp_rat_clear(mp_rat r);
-void      mp_rat_free(mp_rat r);
-mp_result mp_rat_numer(mp_rat r, mp_int z);             /* z = num(r)  */
-mp_int    mp_rat_numer_ref(mp_rat r);                   /* &num(r)     */
-mp_result mp_rat_denom(mp_rat r, mp_int z);             /* z = den(r)  */
-mp_int    mp_rat_denom_ref(mp_rat r);                   /* &den(r)     */
-mp_sign   mp_rat_sign(mp_rat r);
 
-mp_result mp_rat_copy(mp_rat a, mp_rat c);              /* c = a       */
-void      mp_rat_zero(mp_rat r);                        /* r = 0       */
-mp_result mp_rat_abs(mp_rat a, mp_rat c);               /* c = |a|     */
-mp_result mp_rat_neg(mp_rat a, mp_rat c);               /* c = -a      */
-mp_result mp_rat_recip(mp_rat a, mp_rat c);             /* c = 1 / a   */
-mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c);     /* c = a + b   */
-mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c);     /* c = a - b   */
-mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c);     /* c = a * b   */
-mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c);     /* c = a / b   */
+/** Releases the storage used by `r`. */
+void mp_rat_clear(mp_rat r);
 
-mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c); /* c = a + b   */
-mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c); /* c = a - b   */
-mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c); /* c = a * b   */
-mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c); /* c = a / b   */
-mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c);  /* c = a ^ b   */
+/** Releases the storage used by `r` and also `r` itself.
+    This should only be used for `r` allocated by `mp_rat_alloc()`. */
+void mp_rat_free(mp_rat r);
 
-int       mp_rat_compare(mp_rat a, mp_rat b);           /* a <=> b     */
-int       mp_rat_compare_unsigned(mp_rat a, mp_rat b);  /* |a| <=> |b| */
-int       mp_rat_compare_zero(mp_rat r);                /* r <=> 0     */
-int       mp_rat_compare_value(mp_rat r, mp_small n, mp_small d); /* r <=> n/d */
-int       mp_rat_is_integer(mp_rat r);
+/** Sets `z` to a copy of the numerator of `r`. */
+mp_result mp_rat_numer(mp_rat r, mp_int z);
 
-/* Convert to integers, if representable (returns MP_RANGE if not). */
+/** Returns a pointer to the numerator of `r`. */
+mp_int mp_rat_numer_ref(mp_rat r);
+
+/** Sets `z` to a copy of the denominator of `r`. */
+mp_result mp_rat_denom(mp_rat r, mp_int z);
+
+/** Returns a pointer to the denominator of `r`. */
+mp_int mp_rat_denom_ref(mp_rat r);
+
+/** Reports the sign of `r`. */
+mp_sign mp_rat_sign(mp_rat r);
+
+/** Sets `c` to a copy of the value of `a`. No new memory is allocated unless a
+    term of `a` has more significant digits than the corresponding term of `c`
+    has allocated. */
+mp_result mp_rat_copy(mp_rat a, mp_rat c);
+
+/** Sets `r` to zero. The allocated storage of `r` is not changed. */
+void mp_rat_zero(mp_rat r);
+
+/** Sets `c` to the absolute value of `a`. */
+mp_result mp_rat_abs(mp_rat a, mp_rat c);
+
+/** Sets `c` to the absolute value of `a`. */
+mp_result mp_rat_neg(mp_rat a, mp_rat c);
+
+/** Sets `c` to the reciprocal of `a` if the reciprocal is defined.
+    It returns `MP_UNDEF` if `a` is zero. */
+mp_result mp_rat_recip(mp_rat a, mp_rat c);
+
+/** Sets `c` to the sum of `a` and `b`. */
+mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c);
+
+/** Sets `c` to the difference of `a` less `b`. */
+mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c);
+
+/** Sets `c` to the product of `a` and `b`. */
+mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c);
+
+/** Sets `c` to the ratio `a / b` if that ratio is defined.
+    It returns `MP_UNDEF` if `b` is zero. */
+mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c);
+
+/** Sets `c` to the sum of `a` and integer `b`. */
+mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c);
+
+/** Sets `c` to the difference of `a` less integer `b`. */
+mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c);
+
+/** Sets `c` to the product of `a` and integer `b`. */
+mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c);
+
+/** Sets `c` to the ratio `a / b` if that ratio is defined.
+    It returns `MP_UNDEF` if `b` is zero. */
+mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c);
+
+/** Sets `c` to the value of `a` raised to the `b` power.
+    It returns `MP_RANGE` if `b < 0`. */
+mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c);
+
+/** Returns the comparator of `a` and `b`. */
+int mp_rat_compare(mp_rat a, mp_rat b);
+
+/** Returns the comparator of the magnitudes of `a` and `b`, disregarding their
+    signs. Neither `a` nor `b` is modified by the comparison. */
+int mp_rat_compare_unsigned(mp_rat a, mp_rat b);
+
+/** Returns the comparator of `r` and zero. */
+int mp_rat_compare_zero(mp_rat r);
+
+/** Returns the comparator of `r` and the signed ratio `n / d`.
+    It returns `MP_UNDEF` if `d` is zero. */
+int mp_rat_compare_value(mp_rat r, mp_small n, mp_small d);
+
+/** Reports whether `r` is an integer, having canonical denominator 1. */
+bool mp_rat_is_integer(mp_rat r);
+
+/** Reports whether the numerator and denominator of `r` can be represented as
+    small signed integers, and if so stores the corresponding values to `num`
+    and `den`. It returns `MP_RANGE` if either cannot be so represented. */
 mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den);
 
-/* Convert to nul-terminated string with the specified radix, writing
-   at most limit characters including the nul terminator. */
+/** Converts `r` to a zero-terminated string of the format `"n/d"` with `n` and
+    `d` in the specified radix and writing no more than `limit` bytes to the
+    given output buffer `str`. The output of the numerator includes a sign flag
+    if `r` is negative.  Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
 mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit);
 
-/* Convert to decimal format in the specified radix and precision,
-   writing at most limit characters including a nul terminator. */
+/** Converts the value of `r` to a string in decimal-point notation with the
+    specified radix, writing no more than `limit` bytes of data to the given
+    output buffer.  It generates `prec` digits of precision, and requires
+    `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
+
+    Ratios usually must be rounded when they are being converted for output as
+    a decimal value.  There are four rounding modes currently supported:
+
+      MP_ROUND_DOWN
+        Truncates the value toward zero.
+        Example:  12.009 to 2dp becomes 12.00
+
+      MP_ROUND_UP
+        Rounds the value away from zero:
+        Example:  12.001 to 2dp becomes 12.01, but
+                  12.000 to 2dp remains 12.00
+
+      MP_ROUND_HALF_DOWN
+         Rounds the value to nearest digit, half goes toward zero.
+         Example:  12.005 to 2dp becomes 12.00, but
+                   12.006 to 2dp becomes 12.01
+
+      MP_ROUND_HALF_UP
+         Rounds the value to nearest digit, half rounds upward.
+         Example:  12.005 to 2dp becomes 12.01, but
+                   12.004 to 2dp becomes 12.00
+*/
 mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec,
                             mp_round_mode round, char *str, int limit);
 
-/* Return the number of characters required to represent r in the given
-   radix.  May over-estimate. */
+/** Reports the minimum number of characters required to represent `r` as a
+    zero-terminated string in the given `radix`.
+    Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
 mp_result mp_rat_string_len(mp_rat r, mp_size radix);
 
-/* Return the number of characters required to represent r in decimal
-   format with the given radix and precision.  May over-estimate. */
+/** Reports the length in bytes of the buffer needed to convert `r` using the
+    `mp_rat_to_decimal()` function with the specified `radix` and `prec`. The
+    buffer size estimate may slightly exceed the actual required capacity. */
 mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec);
 
-/* Read zero-terminated string into r */
+/** Sets `r` to the value represented by a zero-terminated string `str` in the
+    format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded
+    denominator has value zero. */
 mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str);
+
+/** Sets `r` to the value represented by a zero-terminated string `str` in the
+    format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded
+    denominator has value zero. If `end` is not NULL then `*end` is set to
+    point to the first unconsumed character in the string, after parsing.
+*/
 mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str,
 			      char **end);
+
+/** Sets `r` to the value represented by a zero-terminated string `str` having
+    one of the following formats, each with an optional leading sign flag:
+
+       n         : integer format, e.g. "123"
+       n/d       : ratio format, e.g., "-12/5"
+       z.ffff    : decimal format, e.g., "1.627"
+
+    It returns `MP_UNDEF` if the effective denominator is zero. If `end` is not
+    NULL then `*end` is set to point to the first unconsumed character in the
+    string, after parsing.
+*/
 mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str,
 			      char **end);
 
-/* Read zero-terminated string in decimal format into r */
+/** Sets `r` to the value represented by a zero-terminated string `str` in the
+    format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the
+    effective denominator. */
 mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str);
+
+/** Sets `r` to the value represented by a zero-terminated string `str` in the
+    format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the
+    effective denominator. If `end` is not NULL then `*end` is set to point to
+    the first unconsumed character in the string, after parsing. */
 mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str,
 			       char **end);
 
diff --git a/lib/External/isl/include/isl/aff.h b/lib/External/isl/include/isl/aff.h
index 156175e..ba77025 100644
--- a/lib/External/isl/include/isl/aff.h
+++ b/lib/External/isl/include/isl/aff.h
@@ -26,6 +26,7 @@
 	__isl_take isl_val *val);
 __isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls,
 	enum isl_dim_type type, unsigned pos);
+__isl_give isl_aff *isl_aff_nan_on_domain_space(__isl_take isl_space *space);
 __isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls);
 __isl_give isl_aff *isl_aff_param_on_domain_space_id(
 	__isl_take isl_space *space, __isl_take isl_id *id);
@@ -50,6 +51,7 @@
 
 const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
 	enum isl_dim_type type, unsigned pos);
+__isl_export
 __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff);
 __isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff,
 	enum isl_dim_type type, int pos);
@@ -73,6 +75,7 @@
 __isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
 	enum isl_dim_type type, int pos, __isl_take isl_val *v);
 
+__isl_export
 isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff);
 
 __isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff,
@@ -215,6 +218,8 @@
 	__isl_take isl_local_space *ls);
 __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
 	enum isl_dim_type type, unsigned pos);
+__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space(
+	__isl_take isl_space *space);
 __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls);
 __isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain,
 	__isl_take isl_val *v);
@@ -561,6 +566,9 @@
 
 __isl_export
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space);
+__isl_overload
+__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space(
+	__isl_take isl_space *space);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
 	__isl_take isl_space *space);
 __isl_export
@@ -752,6 +760,10 @@
 __isl_overload
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_pullback_pw_multi_aff(
 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2);
+__isl_overload
+__isl_give isl_pw_multi_aff *
+isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
+	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2);
 
 __isl_export
 isl_size isl_pw_multi_aff_n_piece(__isl_keep isl_pw_multi_aff *pma);
@@ -871,6 +883,11 @@
 isl_union_pw_multi_aff_apply_union_pw_multi_aff(
 	__isl_take isl_union_pw_multi_aff *upma1,
 	__isl_take isl_union_pw_multi_aff *upma2);
+__isl_overload
+__isl_give isl_union_pw_multi_aff *
+isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(
+	__isl_take isl_union_pw_multi_aff *upma1,
+	__isl_take isl_union_pw_multi_aff *upma2);
 
 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_align_params(
 	__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *model);
diff --git a/lib/External/isl/include/isl/cpp-checked.h b/lib/External/isl/include/isl/cpp-checked.h
index 4c3586d..3192225 100644
--- a/lib/External/isl/include/isl/cpp-checked.h
+++ b/lib/External/isl/include/isl/cpp-checked.h
@@ -328,8 +328,11 @@
   inline isl::checked::val eval(isl::checked::point pnt) const;
   inline isl::checked::aff floor() const;
   inline isl::checked::set ge_set(isl::checked::aff aff2) const;
+  inline isl::checked::val constant_val() const;
+  inline isl::checked::val get_constant_val() const;
   inline isl::checked::aff gist(isl::checked::set context) const;
   inline isl::checked::set gt_set(isl::checked::aff aff2) const;
+  inline boolean is_cst() const;
   inline isl::checked::set le_set(isl::checked::aff aff2) const;
   inline isl::checked::set lt_set(isl::checked::aff aff2) const;
   inline isl::checked::aff mod(isl::checked::val mod) const;
@@ -1491,8 +1494,12 @@
   inline isl::checked::map gist_domain(isl::checked::set context) const;
   inline isl::checked::map intersect(isl::checked::map map2) const;
   inline isl::checked::map intersect_domain(isl::checked::set set) const;
+  inline isl::checked::map intersect_domain_factor_domain(isl::checked::map factor) const;
+  inline isl::checked::map intersect_domain_factor_range(isl::checked::map factor) const;
   inline isl::checked::map intersect_params(isl::checked::set params) const;
   inline isl::checked::map intersect_range(isl::checked::set set) const;
+  inline isl::checked::map intersect_range_factor_domain(isl::checked::map factor) const;
+  inline isl::checked::map intersect_range_factor_range(isl::checked::map factor) const;
   inline boolean is_bijective() const;
   inline boolean is_disjoint(const isl::checked::map &map2) const;
   inline boolean is_empty() const;
@@ -1510,7 +1517,6 @@
   inline isl::checked::map lexmin() const;
   inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const;
   inline isl::checked::map lower_bound(isl::checked::multi_pw_aff lower) const;
-  inline isl::checked::map lower_bound(isl::checked::multi_val lower) const;
   inline isl::checked::multi_pw_aff max_multi_pw_aff() const;
   inline isl::checked::multi_pw_aff min_multi_pw_aff() const;
   inline isl::checked::basic_map polyhedral_hull() const;
@@ -1519,6 +1525,7 @@
   inline isl::checked::map preimage_domain(isl::checked::pw_multi_aff pma) const;
   inline isl::checked::map preimage_range(isl::checked::multi_aff ma) const;
   inline isl::checked::map preimage_range(isl::checked::pw_multi_aff pma) const;
+  inline isl::checked::map product(isl::checked::map map2) const;
   inline isl::checked::map project_out_all_params() const;
   inline isl::checked::set range() const;
   inline isl::checked::map range_factor_domain() const;
@@ -1533,8 +1540,8 @@
   static inline isl::checked::map universe(isl::checked::space space);
   inline isl::checked::basic_map unshifted_simple_hull() const;
   inline isl::checked::map upper_bound(isl::checked::multi_pw_aff upper) const;
-  inline isl::checked::map upper_bound(isl::checked::multi_val upper) const;
   inline isl::checked::set wrap() const;
+  inline isl::checked::map zip() const;
 };
 
 // declarations for isl::multi_aff
@@ -1588,6 +1595,7 @@
   static inline isl::checked::multi_aff identity_on_domain(isl::checked::space space);
   inline isl::checked::multi_aff insert_domain(isl::checked::space domain) const;
   inline boolean involves_locals() const;
+  inline boolean involves_nan() const;
   inline isl::checked::multi_aff neg() const;
   inline boolean plain_is_equal(const isl::checked::multi_aff &multi2) const;
   inline isl::checked::multi_aff product(isl::checked::multi_aff multi2) const;
@@ -1701,6 +1709,7 @@
   inline isl::checked::multi_pw_aff insert_domain(isl::checked::space domain) const;
   inline isl::checked::multi_pw_aff intersect_domain(isl::checked::set domain) const;
   inline isl::checked::multi_pw_aff intersect_params(isl::checked::set set) const;
+  inline boolean involves_nan() const;
   inline boolean involves_param(const isl::checked::id &id) const;
   inline boolean involves_param(const std::string &id) const;
   inline boolean involves_param(const isl::checked::id_list &list) const;
@@ -1772,6 +1781,7 @@
   inline isl::checked::multi_union_pw_aff gist(isl::checked::union_set context) const;
   inline isl::checked::multi_union_pw_aff intersect_domain(isl::checked::union_set uset) const;
   inline isl::checked::multi_union_pw_aff intersect_params(isl::checked::set params) const;
+  inline boolean involves_nan() const;
   inline isl::checked::multi_union_pw_aff neg() const;
   inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::multi_union_pw_aff pullback(isl::checked::union_pw_multi_aff upma) const;
@@ -1826,6 +1836,7 @@
   inline isl::checked::val_list get_list() const;
   inline isl::checked::space space() const;
   inline isl::checked::space get_space() const;
+  inline boolean involves_nan() const;
   inline isl::checked::multi_val max(isl::checked::multi_val multi2) const;
   inline isl::checked::multi_val min(isl::checked::multi_val multi2) const;
   inline isl::checked::multi_val neg() const;
@@ -2029,6 +2040,7 @@
   inline isl::checked::space space() const;
   inline isl::checked::space get_space() const;
   inline isl::checked::pw_multi_aff gist(isl::checked::set set) const;
+  static inline isl::checked::pw_multi_aff identity_on_domain(isl::checked::space space);
   inline isl::checked::pw_multi_aff insert_domain(isl::checked::space domain) const;
   inline isl::checked::pw_multi_aff intersect_domain(isl::checked::set set) const;
   inline isl::checked::pw_multi_aff intersect_params(isl::checked::set set) const;
@@ -2037,6 +2049,7 @@
   inline isl::checked::multi_val max_multi_val() const;
   inline isl::checked::multi_val min_multi_val() const;
   inline class size n_piece() const;
+  inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const;
   inline isl::checked::pw_multi_aff product(isl::checked::pw_multi_aff pma2) const;
   inline isl::checked::pw_multi_aff pullback(isl::checked::multi_aff ma) const;
   inline isl::checked::pw_multi_aff pullback(isl::checked::pw_multi_aff pma2) const;
@@ -2119,6 +2132,8 @@
   inline isl::checked::ctx ctx() const;
 
   static inline isl::checked::schedule from_domain(isl::checked::union_set domain);
+  inline isl::checked::union_set domain() const;
+  inline isl::checked::union_set get_domain() const;
   inline isl::checked::union_map map() const;
   inline isl::checked::union_map get_map() const;
   inline isl::checked::schedule_node root() const;
@@ -2590,6 +2605,7 @@
   inline isl::checked::basic_set sample() const;
   inline isl::checked::point sample_point() const;
   inline isl::checked::set subtract(isl::checked::set set2) const;
+  inline isl::checked::map translation() const;
   inline isl::checked::set unbind_params(isl::checked::multi_id tuple) const;
   inline isl::checked::map unbind_params_insert_domain(isl::checked::multi_id domain) const;
   inline isl::checked::set unite(isl::checked::set set2) const;
@@ -2628,6 +2644,7 @@
   inline isl::checked::space add_named_tuple(isl::checked::id tuple_id, unsigned int dim) const;
   inline isl::checked::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const;
   inline isl::checked::space add_unnamed_tuple(unsigned int dim) const;
+  inline isl::checked::space curry() const;
   inline isl::checked::space domain() const;
   inline isl::checked::space flatten_domain() const;
   inline isl::checked::space flatten_range() const;
@@ -2635,7 +2652,11 @@
   inline boolean is_wrapping() const;
   inline isl::checked::space map_from_set() const;
   inline isl::checked::space params() const;
+  inline isl::checked::space product(isl::checked::space right) const;
   inline isl::checked::space range() const;
+  inline isl::checked::space range_reverse() const;
+  inline isl::checked::space reverse() const;
+  inline isl::checked::space uncurry() const;
   static inline isl::checked::space unit(isl::checked::ctx ctx);
   inline isl::checked::space unwrap() const;
   inline isl::checked::space wrap() const;
@@ -2780,9 +2801,13 @@
   inline isl::checked::union_map intersect(isl::checked::union_map umap2) const;
   inline isl::checked::union_map intersect_domain(isl::checked::space space) const;
   inline isl::checked::union_map intersect_domain(isl::checked::union_set uset) const;
+  inline isl::checked::union_map intersect_domain_factor_domain(isl::checked::union_map factor) const;
+  inline isl::checked::union_map intersect_domain_factor_range(isl::checked::union_map factor) const;
   inline isl::checked::union_map intersect_params(isl::checked::set set) const;
   inline isl::checked::union_map intersect_range(isl::checked::space space) const;
   inline isl::checked::union_map intersect_range(isl::checked::union_set uset) const;
+  inline isl::checked::union_map intersect_range_factor_domain(isl::checked::union_map factor) const;
+  inline isl::checked::union_map intersect_range_factor_range(isl::checked::union_map factor) const;
   inline boolean is_bijective() const;
   inline boolean is_disjoint(const isl::checked::union_map &umap2) const;
   inline boolean is_empty() const;
@@ -2955,6 +2980,7 @@
   inline boolean involves_locals() const;
   inline boolean isa_pw_multi_aff() const;
   inline boolean plain_is_empty() const;
+  inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(isl::checked::union_pw_multi_aff upma2) const;
   inline isl::checked::union_pw_multi_aff pullback(isl::checked::union_pw_multi_aff upma2) const;
   inline isl::checked::union_pw_multi_aff range_factor_domain() const;
   inline isl::checked::union_pw_multi_aff range_factor_range() const;
@@ -3323,6 +3349,17 @@
   return manage(res);
 }
 
+isl::checked::val aff::constant_val() const
+{
+  auto res = isl_aff_get_constant_val(get());
+  return manage(res);
+}
+
+isl::checked::val aff::get_constant_val() const
+{
+  return constant_val();
+}
+
 isl::checked::aff aff::gist(isl::checked::set context) const
 {
   auto res = isl_aff_gist(copy(), context.release());
@@ -3335,6 +3372,12 @@
   return manage(res);
 }
 
+boolean aff::is_cst() const
+{
+  auto res = isl_aff_is_cst(get());
+  return manage(res);
+}
+
 isl::checked::set aff::le_set(isl::checked::aff aff2) const
 {
   auto res = isl_aff_le_set(copy(), aff2.release());
@@ -6343,6 +6386,18 @@
   return manage(res);
 }
 
+isl::checked::map map::intersect_domain_factor_domain(isl::checked::map factor) const
+{
+  auto res = isl_map_intersect_domain_factor_domain(copy(), factor.release());
+  return manage(res);
+}
+
+isl::checked::map map::intersect_domain_factor_range(isl::checked::map factor) const
+{
+  auto res = isl_map_intersect_domain_factor_range(copy(), factor.release());
+  return manage(res);
+}
+
 isl::checked::map map::intersect_params(isl::checked::set params) const
 {
   auto res = isl_map_intersect_params(copy(), params.release());
@@ -6355,6 +6410,18 @@
   return manage(res);
 }
 
+isl::checked::map map::intersect_range_factor_domain(isl::checked::map factor) const
+{
+  auto res = isl_map_intersect_range_factor_domain(copy(), factor.release());
+  return manage(res);
+}
+
+isl::checked::map map::intersect_range_factor_range(isl::checked::map factor) const
+{
+  auto res = isl_map_intersect_range_factor_range(copy(), factor.release());
+  return manage(res);
+}
+
 boolean map::is_bijective() const
 {
   auto res = isl_map_is_bijective(get());
@@ -6457,12 +6524,6 @@
   return manage(res);
 }
 
-isl::checked::map map::lower_bound(isl::checked::multi_val lower) const
-{
-  auto res = isl_map_lower_bound_multi_val(copy(), lower.release());
-  return manage(res);
-}
-
 isl::checked::multi_pw_aff map::max_multi_pw_aff() const
 {
   auto res = isl_map_max_multi_pw_aff(copy());
@@ -6511,6 +6572,12 @@
   return manage(res);
 }
 
+isl::checked::map map::product(isl::checked::map map2) const
+{
+  auto res = isl_map_product(copy(), map2.release());
+  return manage(res);
+}
+
 isl::checked::map map::project_out_all_params() const
 {
   auto res = isl_map_project_out_all_params(copy());
@@ -6595,18 +6662,18 @@
   return manage(res);
 }
 
-isl::checked::map map::upper_bound(isl::checked::multi_val upper) const
-{
-  auto res = isl_map_upper_bound_multi_val(copy(), upper.release());
-  return manage(res);
-}
-
 isl::checked::set map::wrap() const
 {
   auto res = isl_map_wrap(copy());
   return manage(res);
 }
 
+isl::checked::map map::zip() const
+{
+  auto res = isl_map_zip(copy());
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const map &obj)
 {
   char *str = isl_map_to_str(obj.get());
@@ -6823,6 +6890,12 @@
   return manage(res);
 }
 
+boolean multi_aff::involves_nan() const
+{
+  auto res = isl_multi_aff_involves_nan(get());
+  return manage(res);
+}
+
 isl::checked::multi_aff multi_aff::neg() const
 {
   auto res = isl_multi_aff_neg(copy());
@@ -7297,6 +7370,12 @@
   return manage(res);
 }
 
+boolean multi_pw_aff::involves_nan() const
+{
+  auto res = isl_multi_pw_aff_involves_nan(get());
+  return manage(res);
+}
+
 boolean multi_pw_aff::involves_param(const isl::checked::id &id) const
 {
   auto res = isl_multi_pw_aff_involves_param_id(get(), id.get());
@@ -7620,6 +7699,12 @@
   return manage(res);
 }
 
+boolean multi_union_pw_aff::involves_nan() const
+{
+  auto res = isl_multi_union_pw_aff_involves_nan(get());
+  return manage(res);
+}
+
 isl::checked::multi_union_pw_aff multi_union_pw_aff::neg() const
 {
   auto res = isl_multi_union_pw_aff_neg(copy());
@@ -7841,6 +7926,12 @@
   return space();
 }
 
+boolean multi_val::involves_nan() const
+{
+  auto res = isl_multi_val_involves_nan(get());
+  return manage(res);
+}
+
 isl::checked::multi_val multi_val::max(isl::checked::multi_val multi2) const
 {
   auto res = isl_multi_val_max(copy(), multi2.release());
@@ -8675,6 +8766,12 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_multi_aff::identity_on_domain(isl::checked::space space)
+{
+  auto res = isl_pw_multi_aff_identity_on_domain_space(space.release());
+  return manage(res);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::insert_domain(isl::checked::space domain) const
 {
   auto res = isl_pw_multi_aff_insert_domain(copy(), domain.release());
@@ -8723,6 +8820,12 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const
+{
+  auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release());
+  return manage(res);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::product(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_product(copy(), pma2.release());
@@ -9026,6 +9129,17 @@
   return manage(res);
 }
 
+isl::checked::union_set schedule::domain() const
+{
+  auto res = isl_schedule_get_domain(get());
+  return manage(res);
+}
+
+isl::checked::union_set schedule::get_domain() const
+{
+  return domain();
+}
+
 isl::checked::union_map schedule::map() const
 {
   auto res = isl_schedule_get_map(get());
@@ -9783,28 +9897,24 @@
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_default(int pos) const
 {
   auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_default);
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_atomic(int pos) const
 {
   auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_atomic);
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_unroll(int pos) const
 {
   auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_unroll);
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_separate(int pos) const
 {
   auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_separate);
@@ -10654,6 +10764,12 @@
   return manage(res);
 }
 
+isl::checked::map set::translation() const
+{
+  auto res = isl_set_translation(copy());
+  return manage(res);
+}
+
 isl::checked::set set::unbind_params(isl::checked::multi_id tuple) const
 {
   auto res = isl_set_unbind_params(copy(), tuple.release());
@@ -10784,6 +10900,12 @@
   return manage(res);
 }
 
+isl::checked::space space::curry() const
+{
+  auto res = isl_space_curry(copy());
+  return manage(res);
+}
+
 isl::checked::space space::domain() const
 {
   auto res = isl_space_domain(copy());
@@ -10826,12 +10948,36 @@
   return manage(res);
 }
 
+isl::checked::space space::product(isl::checked::space right) const
+{
+  auto res = isl_space_product(copy(), right.release());
+  return manage(res);
+}
+
 isl::checked::space space::range() const
 {
   auto res = isl_space_range(copy());
   return manage(res);
 }
 
+isl::checked::space space::range_reverse() const
+{
+  auto res = isl_space_range_reverse(copy());
+  return manage(res);
+}
+
+isl::checked::space space::reverse() const
+{
+  auto res = isl_space_reverse(copy());
+  return manage(res);
+}
+
+isl::checked::space space::uncurry() const
+{
+  auto res = isl_space_uncurry(copy());
+  return manage(res);
+}
+
 isl::checked::space space::unit(isl::checked::ctx ctx)
 {
   auto res = isl_space_unit(ctx.release());
@@ -11413,6 +11559,18 @@
   return manage(res);
 }
 
+isl::checked::union_map union_map::intersect_domain_factor_domain(isl::checked::union_map factor) const
+{
+  auto res = isl_union_map_intersect_domain_factor_domain(copy(), factor.release());
+  return manage(res);
+}
+
+isl::checked::union_map union_map::intersect_domain_factor_range(isl::checked::union_map factor) const
+{
+  auto res = isl_union_map_intersect_domain_factor_range(copy(), factor.release());
+  return manage(res);
+}
+
 isl::checked::union_map union_map::intersect_params(isl::checked::set set) const
 {
   auto res = isl_union_map_intersect_params(copy(), set.release());
@@ -11431,6 +11589,18 @@
   return manage(res);
 }
 
+isl::checked::union_map union_map::intersect_range_factor_domain(isl::checked::union_map factor) const
+{
+  auto res = isl_union_map_intersect_range_factor_domain(copy(), factor.release());
+  return manage(res);
+}
+
+isl::checked::union_map union_map::intersect_range_factor_range(isl::checked::union_map factor) const
+{
+  auto res = isl_union_map_intersect_range_factor_range(copy(), factor.release());
+  return manage(res);
+}
+
 boolean union_map::is_bijective() const
 {
   auto res = isl_union_map_is_bijective(get());
@@ -12176,6 +12346,12 @@
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff union_pw_multi_aff::preimage_domain_wrapped_domain(isl::checked::union_pw_multi_aff upma2) const
+{
+  auto res = isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(copy(), upma2.release());
+  return manage(res);
+}
+
 isl::checked::union_pw_multi_aff union_pw_multi_aff::pullback(isl::checked::union_pw_multi_aff upma2) const
 {
   auto res = isl_union_pw_multi_aff_pullback_union_pw_multi_aff(copy(), upma2.release());
diff --git a/lib/External/isl/include/isl/cpp.h b/lib/External/isl/include/isl/cpp.h
index 0d885a5..147cc05 100644
--- a/lib/External/isl/include/isl/cpp.h
+++ b/lib/External/isl/include/isl/cpp.h
@@ -392,8 +392,11 @@
   inline isl::val eval(isl::point pnt) const;
   inline isl::aff floor() const;
   inline isl::set ge_set(isl::aff aff2) const;
+  inline isl::val constant_val() const;
+  inline isl::val get_constant_val() const;
   inline isl::aff gist(isl::set context) const;
   inline isl::set gt_set(isl::aff aff2) const;
+  inline bool is_cst() const;
   inline isl::set le_set(isl::aff aff2) const;
   inline isl::set lt_set(isl::aff aff2) const;
   inline isl::aff mod(isl::val mod) const;
@@ -1556,8 +1559,12 @@
   inline isl::map gist_domain(isl::set context) const;
   inline isl::map intersect(isl::map map2) const;
   inline isl::map intersect_domain(isl::set set) const;
+  inline isl::map intersect_domain_factor_domain(isl::map factor) const;
+  inline isl::map intersect_domain_factor_range(isl::map factor) const;
   inline isl::map intersect_params(isl::set params) const;
   inline isl::map intersect_range(isl::set set) const;
+  inline isl::map intersect_range_factor_domain(isl::map factor) const;
+  inline isl::map intersect_range_factor_range(isl::map factor) const;
   inline bool is_bijective() const;
   inline bool is_disjoint(const isl::map &map2) const;
   inline bool is_empty() const;
@@ -1575,7 +1582,6 @@
   inline isl::map lexmin() const;
   inline isl::pw_multi_aff lexmin_pw_multi_aff() const;
   inline isl::map lower_bound(isl::multi_pw_aff lower) const;
-  inline isl::map lower_bound(isl::multi_val lower) const;
   inline isl::multi_pw_aff max_multi_pw_aff() const;
   inline isl::multi_pw_aff min_multi_pw_aff() const;
   inline isl::basic_map polyhedral_hull() const;
@@ -1584,6 +1590,7 @@
   inline isl::map preimage_domain(isl::pw_multi_aff pma) const;
   inline isl::map preimage_range(isl::multi_aff ma) const;
   inline isl::map preimage_range(isl::pw_multi_aff pma) const;
+  inline isl::map product(isl::map map2) const;
   inline isl::map project_out_all_params() const;
   inline isl::set range() const;
   inline isl::map range_factor_domain() const;
@@ -1598,8 +1605,8 @@
   static inline isl::map universe(isl::space space);
   inline isl::basic_map unshifted_simple_hull() const;
   inline isl::map upper_bound(isl::multi_pw_aff upper) const;
-  inline isl::map upper_bound(isl::multi_val upper) const;
   inline isl::set wrap() const;
+  inline isl::map zip() const;
 };
 
 // declarations for isl::multi_aff
@@ -1653,6 +1660,7 @@
   static inline isl::multi_aff identity_on_domain(isl::space space);
   inline isl::multi_aff insert_domain(isl::space domain) const;
   inline bool involves_locals() const;
+  inline bool involves_nan() const;
   inline isl::multi_aff neg() const;
   inline bool plain_is_equal(const isl::multi_aff &multi2) const;
   inline isl::multi_aff product(isl::multi_aff multi2) const;
@@ -1766,6 +1774,7 @@
   inline isl::multi_pw_aff insert_domain(isl::space domain) const;
   inline isl::multi_pw_aff intersect_domain(isl::set domain) const;
   inline isl::multi_pw_aff intersect_params(isl::set set) const;
+  inline bool involves_nan() const;
   inline bool involves_param(const isl::id &id) const;
   inline bool involves_param(const std::string &id) const;
   inline bool involves_param(const isl::id_list &list) const;
@@ -1837,6 +1846,7 @@
   inline isl::multi_union_pw_aff gist(isl::union_set context) const;
   inline isl::multi_union_pw_aff intersect_domain(isl::union_set uset) const;
   inline isl::multi_union_pw_aff intersect_params(isl::set params) const;
+  inline bool involves_nan() const;
   inline isl::multi_union_pw_aff neg() const;
   inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
   inline isl::multi_union_pw_aff pullback(isl::union_pw_multi_aff upma) const;
@@ -1891,6 +1901,7 @@
   inline isl::val_list get_list() const;
   inline isl::space space() const;
   inline isl::space get_space() const;
+  inline bool involves_nan() const;
   inline isl::multi_val max(isl::multi_val multi2) const;
   inline isl::multi_val min(isl::multi_val multi2) const;
   inline isl::multi_val neg() const;
@@ -2094,6 +2105,7 @@
   inline isl::space space() const;
   inline isl::space get_space() const;
   inline isl::pw_multi_aff gist(isl::set set) const;
+  static inline isl::pw_multi_aff identity_on_domain(isl::space space);
   inline isl::pw_multi_aff insert_domain(isl::space domain) const;
   inline isl::pw_multi_aff intersect_domain(isl::set set) const;
   inline isl::pw_multi_aff intersect_params(isl::set set) const;
@@ -2102,6 +2114,7 @@
   inline isl::multi_val max_multi_val() const;
   inline isl::multi_val min_multi_val() const;
   inline unsigned n_piece() const;
+  inline isl::pw_multi_aff preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const;
   inline isl::pw_multi_aff product(isl::pw_multi_aff pma2) const;
   inline isl::pw_multi_aff pullback(isl::multi_aff ma) const;
   inline isl::pw_multi_aff pullback(isl::pw_multi_aff pma2) const;
@@ -2184,6 +2197,8 @@
   inline isl::ctx ctx() const;
 
   static inline isl::schedule from_domain(isl::union_set domain);
+  inline isl::union_set domain() const;
+  inline isl::union_set get_domain() const;
   inline isl::union_map map() const;
   inline isl::union_map get_map() const;
   inline isl::schedule_node root() const;
@@ -2655,6 +2670,7 @@
   inline isl::basic_set sample() const;
   inline isl::point sample_point() const;
   inline isl::set subtract(isl::set set2) const;
+  inline isl::map translation() const;
   inline isl::set unbind_params(isl::multi_id tuple) const;
   inline isl::map unbind_params_insert_domain(isl::multi_id domain) const;
   inline isl::set unite(isl::set set2) const;
@@ -2693,6 +2709,7 @@
   inline isl::space add_named_tuple(isl::id tuple_id, unsigned int dim) const;
   inline isl::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const;
   inline isl::space add_unnamed_tuple(unsigned int dim) const;
+  inline isl::space curry() const;
   inline isl::space domain() const;
   inline isl::space flatten_domain() const;
   inline isl::space flatten_range() const;
@@ -2700,7 +2717,11 @@
   inline bool is_wrapping() const;
   inline isl::space map_from_set() const;
   inline isl::space params() const;
+  inline isl::space product(isl::space right) const;
   inline isl::space range() const;
+  inline isl::space range_reverse() const;
+  inline isl::space reverse() const;
+  inline isl::space uncurry() const;
   static inline isl::space unit(isl::ctx ctx);
   inline isl::space unwrap() const;
   inline isl::space wrap() const;
@@ -2845,9 +2866,13 @@
   inline isl::union_map intersect(isl::union_map umap2) const;
   inline isl::union_map intersect_domain(isl::space space) const;
   inline isl::union_map intersect_domain(isl::union_set uset) const;
+  inline isl::union_map intersect_domain_factor_domain(isl::union_map factor) const;
+  inline isl::union_map intersect_domain_factor_range(isl::union_map factor) const;
   inline isl::union_map intersect_params(isl::set set) const;
   inline isl::union_map intersect_range(isl::space space) const;
   inline isl::union_map intersect_range(isl::union_set uset) const;
+  inline isl::union_map intersect_range_factor_domain(isl::union_map factor) const;
+  inline isl::union_map intersect_range_factor_range(isl::union_map factor) const;
   inline bool is_bijective() const;
   inline bool is_disjoint(const isl::union_map &umap2) const;
   inline bool is_empty() const;
@@ -3020,6 +3045,7 @@
   inline bool involves_locals() const;
   inline bool isa_pw_multi_aff() const;
   inline bool plain_is_empty() const;
+  inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(isl::union_pw_multi_aff upma2) const;
   inline isl::union_pw_multi_aff pullback(isl::union_pw_multi_aff upma2) const;
   inline isl::union_pw_multi_aff range_factor_domain() const;
   inline isl::union_pw_multi_aff range_factor_range() const;
@@ -3464,6 +3490,23 @@
   return manage(res);
 }
 
+isl::val aff::constant_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_get_constant_val(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::val aff::get_constant_val() const
+{
+  return constant_val();
+}
+
 isl::aff aff::gist(isl::set context) const
 {
   if (!ptr || context.is_null())
@@ -3488,6 +3531,18 @@
   return manage(res);
 }
 
+bool aff::is_cst() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_is_cst(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::set aff::le_set(isl::aff aff2) const
 {
   if (!ptr || aff2.is_null())
@@ -7714,6 +7769,30 @@
   return manage(res);
 }
 
+isl::map map::intersect_domain_factor_domain(isl::map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_intersect_domain_factor_domain(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::intersect_domain_factor_range(isl::map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_intersect_domain_factor_range(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::map map::intersect_params(isl::set params) const
 {
   if (!ptr || params.is_null())
@@ -7738,6 +7817,30 @@
   return manage(res);
 }
 
+isl::map map::intersect_range_factor_domain(isl::map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_intersect_range_factor_domain(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::intersect_range_factor_range(isl::map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_intersect_range_factor_range(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 bool map::is_bijective() const
 {
   if (!ptr)
@@ -7942,18 +8045,6 @@
   return manage(res);
 }
 
-isl::map map::lower_bound(isl::multi_val lower) const
-{
-  if (!ptr || lower.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_map_lower_bound_multi_val(copy(), lower.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 isl::multi_pw_aff map::max_multi_pw_aff() const
 {
   if (!ptr)
@@ -8050,6 +8141,18 @@
   return manage(res);
 }
 
+isl::map map::product(isl::map map2) const
+{
+  if (!ptr || map2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_product(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::map map::project_out_all_params() const
 {
   if (!ptr)
@@ -8218,18 +8321,6 @@
   return manage(res);
 }
 
-isl::map map::upper_bound(isl::multi_val upper) const
-{
-  if (!ptr || upper.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_map_upper_bound_multi_val(copy(), upper.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 isl::set map::wrap() const
 {
   if (!ptr)
@@ -8242,6 +8333,18 @@
   return manage(res);
 }
 
+isl::map map::zip() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_zip(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const map &obj)
 {
   if (!obj.get())
@@ -8600,6 +8703,18 @@
   return res;
 }
 
+bool multi_aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_involves_nan(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::multi_aff multi_aff::neg() const
 {
   if (!ptr)
@@ -9404,6 +9519,18 @@
   return manage(res);
 }
 
+bool multi_pw_aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_involves_nan(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 bool multi_pw_aff::involves_param(const isl::id &id) const
 {
   if (!ptr || id.is_null())
@@ -9975,6 +10102,18 @@
   return manage(res);
 }
 
+bool multi_union_pw_aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_involves_nan(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::multi_union_pw_aff multi_union_pw_aff::neg() const
 {
   if (!ptr)
@@ -10342,6 +10481,18 @@
   return space();
 }
 
+bool multi_val::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_involves_nan(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::multi_val multi_val::max(isl::multi_val multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -11766,6 +11917,18 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_multi_aff::identity_on_domain(isl::space space)
+{
+  if (space.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = space.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_identity_on_domain_space(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::pw_multi_aff pw_multi_aff::insert_domain(isl::space domain) const
 {
   if (!ptr || domain.is_null())
@@ -11862,6 +12025,18 @@
   return res;
 }
 
+isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const
+{
+  if (!ptr || pma2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::pw_multi_aff pw_multi_aff::product(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -12355,6 +12530,23 @@
   return manage(res);
 }
 
+isl::union_set schedule::domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_get_domain(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_set schedule::get_domain() const
+{
+  return domain();
+}
+
 isl::union_map schedule::map() const
 {
   if (!ptr)
@@ -13610,7 +13802,6 @@
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_default(int pos) const
 {
   if (!ptr)
@@ -13623,7 +13814,6 @@
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_atomic(int pos) const
 {
   if (!ptr)
@@ -13636,7 +13826,6 @@
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_unroll(int pos) const
 {
   if (!ptr)
@@ -13649,7 +13838,6 @@
   return manage(res).as<schedule_node_band>();
 }
 
-
 schedule_node_band schedule_node_band::member_set_ast_loop_separate(int pos) const
 {
   if (!ptr)
@@ -14929,6 +15117,18 @@
   return manage(res);
 }
 
+isl::map set::translation() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_translation(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::set set::unbind_params(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -15137,6 +15337,18 @@
   return manage(res);
 }
 
+isl::space space::curry() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_curry(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::space space::domain() const
 {
   if (!ptr)
@@ -15221,6 +15433,18 @@
   return manage(res);
 }
 
+isl::space space::product(isl::space right) const
+{
+  if (!ptr || right.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_product(copy(), right.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::space space::range() const
 {
   if (!ptr)
@@ -15233,6 +15457,42 @@
   return manage(res);
 }
 
+isl::space space::range_reverse() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_range_reverse(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space space::reverse() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_reverse(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space space::uncurry() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_uncurry(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::space space::unit(isl::ctx ctx)
 {
   auto saved_ctx = ctx;
@@ -16204,6 +16464,30 @@
   return manage(res);
 }
 
+isl::union_map union_map::intersect_domain_factor_domain(isl::union_map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_intersect_domain_factor_domain(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map union_map::intersect_domain_factor_range(isl::union_map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_intersect_domain_factor_range(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_map union_map::intersect_params(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -16240,6 +16524,30 @@
   return manage(res);
 }
 
+isl::union_map union_map::intersect_range_factor_domain(isl::union_map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_intersect_range_factor_domain(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map union_map::intersect_range_factor_range(isl::union_map factor) const
+{
+  if (!ptr || factor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_intersect_range_factor_range(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 bool union_map::is_bijective() const
 {
   if (!ptr)
@@ -17557,6 +17865,18 @@
   return res;
 }
 
+isl::union_pw_multi_aff union_pw_multi_aff::preimage_domain_wrapped_domain(isl::union_pw_multi_aff upma2) const
+{
+  if (!ptr || upma2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(copy(), upma2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_pw_multi_aff union_pw_multi_aff::pullback(isl::union_pw_multi_aff upma2) const
 {
   if (!ptr || upma2.is_null())
diff --git a/lib/External/isl/include/isl/map.h b/lib/External/isl/include/isl/map.h
index 2fcffff..7fdd356 100644
--- a/lib/External/isl/include/isl/map.h
+++ b/lib/External/isl/include/isl/map.h
@@ -203,12 +203,6 @@
 	__isl_take isl_basic_map *bmap,
 	enum isl_dim_type type, unsigned pos, int value);
 __isl_overload
-__isl_give isl_map *isl_map_lower_bound_multi_val(__isl_take isl_map *map,
-	__isl_take isl_multi_val *lower);
-__isl_overload
-__isl_give isl_map *isl_map_upper_bound_multi_val(__isl_take isl_map *map,
-	__isl_take isl_multi_val *upper);
-__isl_overload
 __isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map,
 	__isl_take isl_multi_pw_aff *lower);
 __isl_overload
@@ -327,10 +321,16 @@
 __isl_give isl_map *isl_map_intersect_range(
 		__isl_take isl_map *map,
 		__isl_take isl_set *set);
+__isl_export
+__isl_give isl_map *isl_map_intersect_domain_factor_domain(
+	__isl_take isl_map *map, __isl_take isl_map *factor);
+__isl_export
 __isl_give isl_map *isl_map_intersect_domain_factor_range(
 	__isl_take isl_map *map, __isl_take isl_map *factor);
+__isl_export
 __isl_give isl_map *isl_map_intersect_range_factor_domain(
 	__isl_take isl_map *map, __isl_take isl_map *factor);
+__isl_export
 __isl_give isl_map *isl_map_intersect_range_factor_range(
 	__isl_take isl_map *map, __isl_take isl_map *factor);
 __isl_export
@@ -358,6 +358,7 @@
 	__isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa);
 __isl_give isl_basic_map *isl_basic_map_product(
 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2);
+__isl_export
 __isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
 	__isl_take isl_map *map2);
 __isl_give isl_basic_map *isl_basic_map_domain_product(
@@ -498,6 +499,8 @@
 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2);
 
 __isl_export
+__isl_give isl_map *isl_set_translation(__isl_take isl_set *deltas);
+__isl_export
 __isl_give isl_map *isl_set_identity(__isl_take isl_set *set);
 
 __isl_export
@@ -593,6 +596,7 @@
 isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap);
 isl_bool isl_map_can_zip(__isl_keep isl_map *map);
 __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap);
+__isl_export
 __isl_give isl_map *isl_map_zip(__isl_take isl_map *map);
 
 isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap);
diff --git a/lib/External/isl/include/isl/multi.h b/lib/External/isl/include/isl/multi.h
index b9e13da..52bac4a 100644
--- a/lib/External/isl/include/isl/multi.h
+++ b/lib/External/isl/include/isl/multi.h
@@ -144,6 +144,7 @@
 	__isl_take isl_space *space);
 
 #define ISL_DECLARE_MULTI_NAN(BASE)					\
+__isl_export								\
 isl_bool isl_multi_##BASE##_involves_nan(				\
 	__isl_keep isl_multi_##BASE *multi);
 
diff --git a/lib/External/isl/include/isl/polynomial.h b/lib/External/isl/include/isl/polynomial.h
index ee76d5b..0be4f0a 100644
--- a/lib/External/isl/include/isl/polynomial.h
+++ b/lib/External/isl/include/isl/polynomial.h
@@ -315,7 +315,8 @@
 
 isl_bool isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold);
 isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold);
-int isl_qpolynomial_fold_plain_is_equal(__isl_keep isl_qpolynomial_fold *fold1,
+isl_bool isl_qpolynomial_fold_plain_is_equal(
+	__isl_keep isl_qpolynomial_fold *fold1,
 	__isl_keep isl_qpolynomial_fold *fold2);
 
 __isl_give isl_space *isl_qpolynomial_fold_get_domain_space(
@@ -487,6 +488,8 @@
 __isl_give isl_qpolynomial_fold *isl_pw_qpolynomial_fold_as_qpolynomial_fold(
 	__isl_take isl_pw_qpolynomial_fold *pwf);
 
+__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_read_from_str(
+	isl_ctx *ctx, const char *str);
 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
 	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf);
 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
@@ -814,6 +817,7 @@
 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_to_polynomial(
 	__isl_take isl_union_pw_qpolynomial *upwqp, int sign);
 
+ISL_DECLARE_LIST_FN(qpolynomial)
 ISL_DECLARE_LIST_FN(pw_qpolynomial)
 ISL_DECLARE_LIST_FN(pw_qpolynomial_fold)
 
diff --git a/lib/External/isl/include/isl/polynomial_type.h b/lib/External/isl/include/isl/polynomial_type.h
index f260219..f4a3f20 100644
--- a/lib/External/isl/include/isl/polynomial_type.h
+++ b/lib/External/isl/include/isl/polynomial_type.h
@@ -4,6 +4,8 @@
 struct isl_qpolynomial;
 typedef struct isl_qpolynomial isl_qpolynomial;
 
+ISL_DECLARE_LIST_TYPE(qpolynomial)
+
 struct isl_term;
 typedef struct isl_term isl_term;
 
diff --git a/lib/External/isl/include/isl/schedule.h b/lib/External/isl/include/isl/schedule.h
index 3792f94..880a1c2 100644
--- a/lib/External/isl/include/isl/schedule.h
+++ b/lib/External/isl/include/isl/schedule.h
@@ -144,6 +144,7 @@
 __isl_export
 __isl_give isl_schedule_node *isl_schedule_get_root(
 	__isl_keep isl_schedule *schedule);
+__isl_export
 __isl_give isl_union_set *isl_schedule_get_domain(
 	__isl_keep isl_schedule *schedule);
 
diff --git a/lib/External/isl/include/isl/space.h b/lib/External/isl/include/isl/space.h
index 5b71333..6f3da5b 100644
--- a/lib/External/isl/include/isl/space.h
+++ b/lib/External/isl/include/isl/space.h
@@ -85,6 +85,7 @@
 	enum isl_dim_type type, unsigned pos, unsigned n);
 __isl_give isl_space *isl_space_join(__isl_take isl_space *left,
 	__isl_take isl_space *right);
+__isl_export
 __isl_give isl_space *isl_space_product(__isl_take isl_space *left,
 	__isl_take isl_space *right);
 __isl_give isl_space *isl_space_domain_product(__isl_take isl_space *left,
@@ -105,7 +106,9 @@
 __isl_give isl_space *isl_space_map_from_set(__isl_take isl_space *space);
 __isl_give isl_space *isl_space_map_from_domain_and_range(
 	__isl_take isl_space *domain, __isl_take isl_space *range);
+__isl_export
 __isl_give isl_space *isl_space_reverse(__isl_take isl_space *space);
+__isl_export
 __isl_give isl_space *isl_space_range_reverse(__isl_take isl_space *space);
 __isl_give isl_space *isl_space_drop_dims(__isl_take isl_space *space,
 	enum isl_dim_type type, unsigned first, unsigned num);
@@ -151,12 +154,14 @@
 __isl_give isl_space *isl_space_zip(__isl_take isl_space *space);
 
 isl_bool isl_space_can_curry(__isl_keep isl_space *space);
+__isl_export
 __isl_give isl_space *isl_space_curry(__isl_take isl_space *space);
 
 isl_bool isl_space_can_range_curry(__isl_keep isl_space *space);
 __isl_give isl_space *isl_space_range_curry(__isl_take isl_space *space);
 
 isl_bool isl_space_can_uncurry(__isl_keep isl_space *space);
+__isl_export
 __isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space);
 
 isl_bool isl_space_is_domain(__isl_keep isl_space *space1,
diff --git a/lib/External/isl/include/isl/union_map.h b/lib/External/isl/include/isl/union_map.h
index 2cf5101..4cae611 100644
--- a/lib/External/isl/include/isl/union_map.h
+++ b/lib/External/isl/include/isl/union_map.h
@@ -164,10 +164,16 @@
 	__isl_take isl_union_map *umap, __isl_take isl_space *space);
 __isl_give isl_union_map *isl_union_map_intersect_range(
 	__isl_take isl_union_map *umap, __isl_take isl_union_set *uset);
+__isl_export
+__isl_give isl_union_map *isl_union_map_intersect_domain_factor_domain(
+	__isl_take isl_union_map *umap, __isl_take isl_union_map *factor);
+__isl_export
 __isl_give isl_union_map *isl_union_map_intersect_domain_factor_range(
 	__isl_take isl_union_map *umap, __isl_take isl_union_map *factor);
+__isl_export
 __isl_give isl_union_map *isl_union_map_intersect_range_factor_domain(
 	__isl_take isl_union_map *umap, __isl_take isl_union_map *factor);
+__isl_export
 __isl_give isl_union_map *isl_union_map_intersect_range_factor_range(
 	__isl_take isl_union_map *umap, __isl_take isl_union_map *factor);
 
@@ -310,9 +316,15 @@
 __isl_give isl_union_map *isl_union_map_eq_at_multi_union_pw_aff(
 	__isl_take isl_union_map *umap,
 	__isl_take isl_multi_union_pw_aff *mupa);
+__isl_give isl_union_map *isl_union_map_lex_le_at_multi_union_pw_aff(
+	__isl_take isl_union_map *umap,
+	__isl_take isl_multi_union_pw_aff *mupa);
 __isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff(
 	__isl_take isl_union_map *umap,
 	__isl_take isl_multi_union_pw_aff *mupa);
+__isl_give isl_union_map *isl_union_map_lex_ge_at_multi_union_pw_aff(
+	__isl_take isl_union_map *umap,
+	__isl_take isl_multi_union_pw_aff *mupa);
 __isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff(
 	__isl_take isl_union_map *umap,
 	__isl_take isl_multi_union_pw_aff *mupa);
diff --git a/lib/External/isl/install-sh b/lib/External/isl/install-sh
index 59990a1..8175c64 100755
--- a/lib/External/isl/install-sh
+++ b/lib/External/isl/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2014-09-12.12; # UTC
+scriptversion=2018-03-11.20; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -271,15 +271,18 @@
     fi
     dst=$dst_arg
 
-    # If destination is a directory, append the input filename; won't work
-    # if double slashes aren't ignored.
+    # If destination is a directory, append the input filename.
     if test -d "$dst"; then
       if test "$is_target_a_directory" = never; then
         echo "$0: $dst_arg: Is a directory" >&2
         exit 1
       fi
       dstdir=$dst
-      dst=$dstdir/`basename "$src"`
+      dstbase=`basename "$src"`
+      case $dst in
+	*/) dst=$dst$dstbase;;
+	*)  dst=$dst/$dstbase;;
+      esac
       dstdir_status=0
     else
       dstdir=`dirname "$dst"`
@@ -288,6 +291,11 @@
     fi
   fi
 
+  case $dstdir in
+    */) dstdirslash=$dstdir;;
+    *)  dstdirslash=$dstdir/;;
+  esac
+
   obsolete_mkdir_used=false
 
   if test $dstdir_status != 0; then
@@ -324,14 +332,16 @@
             # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
             ;;
           *)
-            # $RANDOM is not portable (e.g. dash);  use it when possible to
-            # lower collision chance
+            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
+            # here however when possible just to lower collision chance.
             tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
             trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
 
-            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
-            # create the $tmpdir first (and fail if unsuccessful) to make sure
-            # that nobody tries to guess the $tmpdir name.
+            # Because "mkdir -p" follows existing symlinks and we likely work
+            # directly in world-writeable /tmp, make sure that the '$tmpdir'
+            # directory is successfully created first before we actually test
+            # 'mkdir -p' feature.
             if (umask $mkdir_umask &&
                 $mkdirprog $mkdir_mode "$tmpdir" &&
                 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
@@ -434,8 +444,8 @@
   else
 
     # Make a couple of temp file names in the proper directory.
-    dsttmp=$dstdir/_inst.$$_
-    rmtmp=$dstdir/_rm.$$_
+    dsttmp=${dstdirslash}_inst.$$_
+    rmtmp=${dstdirslash}_rm.$$_
 
     # Trap to clean up those temp files at exit.
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@@ -500,9 +510,9 @@
 done
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/lib/External/isl/interface/Makefile.in b/lib/External/isl/interface/Makefile.in
index 8273927..4b4ce99 100644
--- a/lib/External/isl/interface/Makefile.in
+++ b/lib/External/isl/interface/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +141,12 @@
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/extract_interface-cpp.Po \
+	./$(DEPDIR)/extract_interface-cpp_conversion.Po \
+	./$(DEPDIR)/extract_interface-extract_interface.Po \
+	./$(DEPDIR)/extract_interface-generator.Po \
+	./$(DEPDIR)/extract_interface-python.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -416,8 +421,8 @@
 	    echo ' $(SHELL) ./config.status'; \
 	    $(SHELL) ./config.status;; \
 	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
 	esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -463,11 +468,17 @@
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-cpp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-cpp_conversion.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-extract_interface.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-generator.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-python.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-cpp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-cpp_conversion.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-extract_interface.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-generator.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-python.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+	@$(MKDIR_P) $(@D)
+	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -628,7 +639,10 @@
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
 	$(am__remove_distdir)
 	test -d "$(distdir)" || mkdir "$(distdir)"
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -832,7 +846,11 @@
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf ./$(DEPDIR)
+		-rm -f ./$(DEPDIR)/extract_interface-cpp.Po
+	-rm -f ./$(DEPDIR)/extract_interface-cpp_conversion.Po
+	-rm -f ./$(DEPDIR)/extract_interface-extract_interface.Po
+	-rm -f ./$(DEPDIR)/extract_interface-generator.Po
+	-rm -f ./$(DEPDIR)/extract_interface-python.Po
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-libtool distclean-tags
@@ -880,7 +898,11 @@
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf ./$(DEPDIR)
+		-rm -f ./$(DEPDIR)/extract_interface-cpp.Po
+	-rm -f ./$(DEPDIR)/extract_interface-cpp_conversion.Po
+	-rm -f ./$(DEPDIR)/extract_interface-extract_interface.Po
+	-rm -f ./$(DEPDIR)/extract_interface-generator.Po
+	-rm -f ./$(DEPDIR)/extract_interface-python.Po
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -901,22 +923,22 @@
 
 .MAKE: all install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
-	clean-cscope clean-generic clean-libtool clean-noinstPROGRAMS \
-	cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
-	dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
-	distcheck distclean distclean-compile distclean-generic \
-	distclean-hdr distclean-libtool distclean-tags distcleancheck \
-	distdir distuninstallcheck dvi dvi-am html html-am info \
-	info-am install install-am install-data install-data-am \
-	install-dvi install-dvi-am install-exec install-exec-am \
-	install-html install-html-am install-info install-info-am \
-	install-man install-pdf install-pdf-am install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \
+	check-am clean clean-cscope clean-generic clean-libtool \
+	clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
+	dist-xz dist-zip distcheck distclean distclean-compile \
+	distclean-generic distclean-hdr distclean-libtool \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am
 
 .PRECIOUS: Makefile
 
diff --git a/lib/External/isl/interface/aclocal.m4 b/lib/External/isl/interface/aclocal.m4
index 065a590..e3797c0 100644
--- a/lib/External/isl/interface/aclocal.m4
+++ b/lib/External/isl/interface/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+# Copyright (C) 2002-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15.1], [],
+m4_if([$1], [1.16.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +51,14 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -110,7 +110,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +141,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -332,13 +332,12 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@@ -346,49 +345,41 @@
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  AS_CASE([$CONFIG_FILES],
+          [*\'*], [eval set x "$CONFIG_FILES"],
+          [*], [set x $CONFIG_FILES])
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`AS_DIRNAME("$mf")`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`AS_DIRNAME(["$file"])`
-      AS_MKDIR_P([$dirpart/$fdir])
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`AS_DIRNAME(["$am_mf"])`
+    am_filepart=`AS_BASENAME(["$am_mf"])`
+    AM_RUN_LOG([cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles]) || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).])
+  fi
+  AS_UNSET([am_dirpart])
+  AS_UNSET([am_filepart])
+  AS_UNSET([am_mf])
+  AS_UNSET([am_rc])
+  rm -f conftest-deps.mk
 }
 ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
 
@@ -397,18 +388,17 @@
 # -----------------------------
 # This macro should only be invoked once -- use via AC_REQUIRE.
 #
-# This code is only required when automatic dependency tracking
-# is enabled.  FIXME.  This creates each '.P' file that we will
-# need in order to bootstrap the dependency handling code.
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
 AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 [AC_CONFIG_COMMANDS([depfiles],
      [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
-     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
+     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -495,8 +485,8 @@
 AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
 # We need awk for the "check" target (and possibly the TAP driver).  The
 # system "awk" is bad on some platforms.
@@ -563,7 +553,7 @@
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -605,7 +595,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -626,7 +616,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2017 Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -647,7 +637,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -655,49 +645,42 @@
 
 # AM_MAKE_INCLUDE()
 # -----------------
-# Check to see how make treats includes.
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
 AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
 am__doit:
-	@echo this is the am__doit target
+	@echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+  AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+      ['0:this is the am__doit target'],
+      [AS_CASE([$s],
+          [BSD], [am__include='.include' am__quote='"'],
+          [am__include='include' am__quote=''])])
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -736,7 +719,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -765,7 +748,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -812,7 +795,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -831,7 +814,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -912,7 +895,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2017 Free Software Foundation, Inc.
+# Copyright (C) 2009-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -972,7 +955,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1000,7 +983,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2017 Free Software Foundation, Inc.
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1019,7 +1002,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2017 Free Software Foundation, Inc.
+# Copyright (C) 2004-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/lib/External/isl/interface/compile b/lib/External/isl/interface/compile
index a85b723..99e5052 100644
--- a/lib/External/isl/interface/compile
+++ b/lib/External/isl/interface/compile
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand '-c -o'.
 
-scriptversion=2012-10-14.11; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -255,7 +255,8 @@
     echo "compile $scriptversion"
     exit $?
     ;;
-  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
+  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
     func_cl_wrapper "$@"      # Doesn't return...
     ;;
 esac
@@ -339,9 +340,9 @@
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/lib/External/isl/interface/configure b/lib/External/isl/interface/configure
index 8acfb2f..30e35b1 100644
--- a/lib/External/isl/interface/configure
+++ b/lib/External/isl/interface/configure
@@ -700,7 +700,6 @@
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
-am__quote
 am__include
 DEPDIR
 OBJEXT
@@ -775,7 +774,8 @@
 PACKAGE_TARNAME
 PACKAGE_NAME
 PATH_SEPARATOR
-SHELL'
+SHELL
+am__quote'
 ac_subst_files=''
 ac_user_opts='
 enable_option_checking
@@ -2437,7 +2437,7 @@
 
 
 
-am__api_version='1.15'
+am__api_version='1.16'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -2953,8 +2953,8 @@
 
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
 # We need awk for the "check" target (and possibly the TAP driver).  The
@@ -3005,7 +3005,7 @@
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -3566,45 +3566,45 @@
 
 ac_config_commands="$ac_config_commands depfiles"
 
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
 am__doit:
-	@echo this is the am__doit target
+	@echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+   (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+  case $?:`cat confinc.out 2>/dev/null` in #(
+  '0:this is the am__doit target') :
+    case $s in #(
+  BSD) :
+    am__include='.include' am__quote='"' ;; #(
+  *) :
+    am__include='include' am__quote='' ;;
+esac ;; #(
+  *) :
      ;;
-   esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
+esac
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
 
 # Check whether --enable-dependency-tracking was given.
 if test "${enable_dependency_tracking+set}" = set; then :
@@ -8137,7 +8137,7 @@
 fi
 
 : ${AR=ar}
-: ${AR_FLAGS=cru}
+: ${AR_FLAGS=cr}
 
 
 
@@ -8638,11 +8638,8 @@
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
-  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
 	mv -f "$nlist"T "$nlist"
@@ -9861,8 +9858,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
-      echo "$AR cru libconftest.a conftest.o" >&5
-      $AR cru libconftest.a conftest.o 2>&5
+      echo "$AR cr libconftest.a conftest.o" >&5
+      $AR cr libconftest.a conftest.o 2>&5
       echo "$RANLIB libconftest.a" >&5
       $RANLIB libconftest.a 2>&5
       cat > conftest.c << _LT_EOF
@@ -10835,6 +10832,12 @@
 	lt_prog_compiler_pic='-KPIC'
 	lt_prog_compiler_static='-static'
         ;;
+      # flang / f18. f95 an alias for gfortran or flang on Debian
+      flang* | f18* | f95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -14777,7 +14780,7 @@
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -15269,7 +15272,7 @@
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -15334,7 +15337,7 @@
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
 	    if test yes = "$GXX"; then
@@ -15673,7 +15676,7 @@
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
 	    else
 	      # FIXME: insert proper C++ library support
@@ -15757,7 +15760,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
@@ -15768,7 +15771,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 	      fi
 
 	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -19319,7 +19322,7 @@
 #
 # INIT-COMMANDS
 #
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
 
 
 # The HP-UX ksh and POSIX shell print the target directory to stdout
@@ -20313,29 +20316,35 @@
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  case $CONFIG_FILES in #(
+  *\'*) :
+    eval set x "$CONFIG_FILES" ;; #(
+  *) :
+    set x $CONFIG_FILES ;; #(
+  *) :
+     ;;
+esac
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$mf" : 'X\(//\)[^/]' \| \
-	 X"$mf" : 'X\(//\)$' \| \
-	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$am_mf" : 'X\(//\)[^/]' \| \
+	 X"$am_mf" : 'X\(//\)$' \| \
+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -20353,53 +20362,48 @@
 	    q
 	  }
 	  s/.*/./; q'`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$file" : 'X\(//\)[^/]' \| \
-	 X"$file" : 'X\(//\)$' \| \
-	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+    am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$am_mf" : 'X\(//\)$' \| \
+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
 	  }
-	  /^X\(\/\/\)[^/].*/{
+	  /^X\/\(\/\/\)$/{
 	    s//\1/
 	    q
 	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
+	  /^X\/\(\/\).*/{
 	    s//\1/
 	    q
 	  }
 	  s/.*/./; q'`
-      as_dir=$dirpart/$fdir; as_fn_mkdir_p
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    { echo "$as_me:$LINENO: cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles" >&5
+   (cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+  { am_dirpart=; unset am_dirpart;}
+  { am_filepart=; unset am_filepart;}
+  { am_mf=; unset am_mf;}
+  { am_rc=; unset am_rc;}
+  rm -f conftest-deps.mk
 }
  ;;
     "libtool":C)
diff --git a/lib/External/isl/interface/cpp.cc b/lib/External/isl/interface/cpp.cc
index aed7df6..1295b9c 100644
--- a/lib/External/isl/interface/cpp.cc
+++ b/lib/External/isl/interface/cpp.cc
@@ -397,7 +397,7 @@
  * 	inline explicit val(ctx ctx, const std::string &str);
  */
 void cpp_generator::print_constructors_decl(ostream &os,
-       const isl_class &clazz)
+	const isl_class &clazz)
 {
 	function_set::const_iterator in;
 	const function_set &constructors = clazz.constructors;
@@ -643,7 +643,7 @@
  * public methods for setting the persistent callbacks.
  */
 void cpp_generator::print_persistent_callbacks_decl(ostream &os,
-       const isl_class &clazz)
+	const isl_class &clazz)
 {
 	std::string cppstring = type2cpp(clazz);
 	const char *cppname = cppstring.c_str();
@@ -1223,7 +1223,7 @@
 /* Print implementations of constructors for class "clazz" to "os".
  */
 void cpp_generator::print_constructors_impl(ostream &os,
-       const isl_class &clazz)
+	const isl_class &clazz)
 {
 	function_set::const_iterator in;
 	const function_set constructors = clazz.constructors;
@@ -1405,7 +1405,7 @@
  * of "clazz".
  */
 void cpp_generator::print_persistent_callbacks_impl(ostream &os,
-       const isl_class &clazz)
+	const isl_class &clazz)
 {
 	std::string cppstring = type2cpp(clazz);
 	const char *cppname = cppstring.c_str();
@@ -1502,7 +1502,6 @@
 	const vector<set_enum> &set_enums = clazz.set_enums.at(fd);
 
 	for (it = set_enums.begin(); it != set_enums.end(); ++it) {
-		osprintf(os, "\n");
 		print_set_enum_impl(os, clazz, fd, it->name, it->method_name);
 	}
 }
@@ -1984,7 +1983,8 @@
  * For static functions and constructors all parameters of the original isl
  * function are exposed.
  *
- * Parameters that are defined as __isl_keep or are of type string, are passed
+ * Parameters that are defined as __isl_keep, are of type string or
+ * are callbacks, are passed
  * as const reference, which allows the compiler to optimize the parameter
  * transfer.
  *
diff --git a/lib/External/isl/interface/depcomp b/lib/External/isl/interface/depcomp
index b39f98f..65cbf70 100644
--- a/lib/External/isl/interface/depcomp
+++ b/lib/External/isl/interface/depcomp
@@ -1,9 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2016-01-11.22; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -783,7 +783,7 @@
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
 # time-stamp-time-zone: "UTC0"
diff --git a/lib/External/isl/interface/generator.cc b/lib/External/isl/interface/generator.cc
index 68a9ea6..dc6ebea 100644
--- a/lib/External/isl/interface/generator.cc
+++ b/lib/External/isl/interface/generator.cc
@@ -367,6 +367,8 @@
  * functions as belonging to the subclasses.
  * Sort the names of the functions based on their lengths
  * to ensure that nested subclasses are handled later.
+ *
+ * Also extract information about automatic conversion functions.
  */
 generator::generator(SourceManager &SM, set<RecordDecl *> &exported_types,
 	set<FunctionDecl *> exported_functions, set<FunctionDecl *> functions) :
diff --git a/lib/External/isl/interface/install-sh b/lib/External/isl/interface/install-sh
index 59990a1..8175c64 100644
--- a/lib/External/isl/interface/install-sh
+++ b/lib/External/isl/interface/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2014-09-12.12; # UTC
+scriptversion=2018-03-11.20; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -271,15 +271,18 @@
     fi
     dst=$dst_arg
 
-    # If destination is a directory, append the input filename; won't work
-    # if double slashes aren't ignored.
+    # If destination is a directory, append the input filename.
     if test -d "$dst"; then
       if test "$is_target_a_directory" = never; then
         echo "$0: $dst_arg: Is a directory" >&2
         exit 1
       fi
       dstdir=$dst
-      dst=$dstdir/`basename "$src"`
+      dstbase=`basename "$src"`
+      case $dst in
+	*/) dst=$dst$dstbase;;
+	*)  dst=$dst/$dstbase;;
+      esac
       dstdir_status=0
     else
       dstdir=`dirname "$dst"`
@@ -288,6 +291,11 @@
     fi
   fi
 
+  case $dstdir in
+    */) dstdirslash=$dstdir;;
+    *)  dstdirslash=$dstdir/;;
+  esac
+
   obsolete_mkdir_used=false
 
   if test $dstdir_status != 0; then
@@ -324,14 +332,16 @@
             # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
             ;;
           *)
-            # $RANDOM is not portable (e.g. dash);  use it when possible to
-            # lower collision chance
+            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
+            # here however when possible just to lower collision chance.
             tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
             trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
 
-            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
-            # create the $tmpdir first (and fail if unsuccessful) to make sure
-            # that nobody tries to guess the $tmpdir name.
+            # Because "mkdir -p" follows existing symlinks and we likely work
+            # directly in world-writeable /tmp, make sure that the '$tmpdir'
+            # directory is successfully created first before we actually test
+            # 'mkdir -p' feature.
             if (umask $mkdir_umask &&
                 $mkdirprog $mkdir_mode "$tmpdir" &&
                 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
@@ -434,8 +444,8 @@
   else
 
     # Make a couple of temp file names in the proper directory.
-    dsttmp=$dstdir/_inst.$$_
-    rmtmp=$dstdir/_rm.$$_
+    dsttmp=${dstdirslash}_inst.$$_
+    rmtmp=${dstdirslash}_rm.$$_
 
     # Trap to clean up those temp files at exit.
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@@ -500,9 +510,9 @@
 done
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/lib/External/isl/interface/isl.py b/lib/External/isl/interface/isl.py
index ddfe5af..9196cf4 100644
--- a/lib/External/isl/interface/isl.py
+++ b/lib/External/isl/interface/isl.py
@@ -1,4 +1,4 @@
-isl_dlname='libisl.so.22'
+isl_dlname='libisl.so.23'
 import os
 from ctypes import *
 from ctypes.util import find_library
@@ -286,6 +286,13 @@
         if res < 0:
             raise
         return bool(res)
+    def preimage_domain_wrapped_domain(*args):
+        if len(args) == 2 and args[1].__class__ is union_pw_multi_aff:
+            ctx = args[0].ctx
+            res = isl.isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr))
+            obj = union_pw_multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def pullback(*args):
         if len(args) == 2 and args[1].__class__ is union_pw_multi_aff:
             ctx = args[0].ctx
@@ -412,6 +419,8 @@
 isl.isl_union_pw_multi_aff_involves_locals.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_isa_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_plain_is_empty.argtypes = [c_void_p]
+isl.isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff.restype = c_void_p
+isl.isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_multi_aff_pullback_union_pw_multi_aff.restype = c_void_p
 isl.isl_union_pw_multi_aff_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_multi_aff_range_factor_domain.restype = c_void_p
@@ -623,6 +632,17 @@
         res = isl.isl_multi_union_pw_aff_intersect_params(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = multi_union_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def involves_nan(arg0):
+        try:
+            if not arg0.__class__ is multi_union_pw_aff:
+                arg0 = multi_union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_union_pw_aff_involves_nan(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def neg(arg0):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -805,6 +825,7 @@
 isl.isl_multi_union_pw_aff_intersect_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_intersect_params.restype = c_void_p
 isl.isl_multi_union_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_union_pw_aff_involves_nan.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_neg.restype = c_void_p
 isl.isl_multi_union_pw_aff_neg.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_plain_is_equal.argtypes = [c_void_p, c_void_p]
@@ -1375,6 +1396,17 @@
         res = isl.isl_multi_pw_aff_intersect_params(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = multi_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def involves_nan(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_involves_nan(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def involves_param(*args):
         if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
             args = list(args)
@@ -1685,6 +1717,7 @@
 isl.isl_multi_pw_aff_intersect_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_intersect_params.restype = c_void_p
 isl.isl_multi_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_pw_aff_involves_nan.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_involves_param_id.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_involves_param_id_list.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_max.restype = c_void_p
@@ -1943,6 +1976,14 @@
         res = isl.isl_pw_multi_aff_gist(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = pw_multi_aff(ctx=ctx, ptr=res)
         return obj
+    @staticmethod
+    def identity_on_domain(*args):
+        if len(args) == 1 and args[0].__class__ is space:
+            ctx = args[0].ctx
+            res = isl.isl_pw_multi_aff_identity_on_domain_space(isl.isl_space_copy(args[0].ptr))
+            obj = pw_multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def insert_domain(arg0, arg1):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -2041,6 +2082,13 @@
         if res < 0:
             raise
         return int(res)
+    def preimage_domain_wrapped_domain(*args):
+        if len(args) == 2 and args[1].__class__ is pw_multi_aff:
+            ctx = args[0].ctx
+            res = isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr))
+            obj = pw_multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def product(arg0, arg1):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -2228,6 +2276,8 @@
 isl.isl_pw_multi_aff_get_space.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_gist.restype = c_void_p
 isl.isl_pw_multi_aff_gist.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_identity_on_domain_space.restype = c_void_p
+isl.isl_pw_multi_aff_identity_on_domain_space.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_insert_domain.restype = c_void_p
 isl.isl_pw_multi_aff_insert_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_intersect_domain.restype = c_void_p
@@ -2241,6 +2291,8 @@
 isl.isl_pw_multi_aff_min_multi_val.restype = c_void_p
 isl.isl_pw_multi_aff_min_multi_val.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_n_piece.argtypes = [c_void_p]
+isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff.restype = c_void_p
+isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_product.restype = c_void_p
 isl.isl_pw_multi_aff_product.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_pullback_multi_aff.restype = c_void_p
@@ -3187,6 +3239,17 @@
         if res < 0:
             raise
         return bool(res)
+    def involves_nan(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_involves_nan(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def neg(arg0):
         try:
             if not arg0.__class__ is multi_aff:
@@ -3406,6 +3469,7 @@
 isl.isl_multi_aff_insert_domain.restype = c_void_p
 isl.isl_multi_aff_insert_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_involves_locals.argtypes = [c_void_p]
+isl.isl_multi_aff_involves_nan.argtypes = [c_void_p]
 isl.isl_multi_aff_neg.restype = c_void_p
 isl.isl_multi_aff_neg.argtypes = [c_void_p]
 isl.isl_multi_aff_plain_is_equal.argtypes = [c_void_p, c_void_p]
@@ -3592,6 +3656,18 @@
         res = isl.isl_aff_ge_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
+    def constant_val(arg0):
+        try:
+            if not arg0.__class__ is aff:
+                arg0 = aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_aff_get_constant_val(arg0.ptr)
+        obj = val(ctx=ctx, ptr=res)
+        return obj
+    def get_constant_val(arg0):
+        return arg0.constant_val()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is aff:
@@ -3622,6 +3698,17 @@
         res = isl.isl_aff_gt_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
+    def is_cst(arg0):
+        try:
+            if not arg0.__class__ is aff:
+                arg0 = aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_aff_is_cst(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def le_set(arg0, arg1):
         try:
             if not arg0.__class__ is aff:
@@ -3797,10 +3884,13 @@
 isl.isl_aff_floor.argtypes = [c_void_p]
 isl.isl_aff_ge_set.restype = c_void_p
 isl.isl_aff_ge_set.argtypes = [c_void_p, c_void_p]
+isl.isl_aff_get_constant_val.restype = c_void_p
+isl.isl_aff_get_constant_val.argtypes = [c_void_p]
 isl.isl_aff_gist.restype = c_void_p
 isl.isl_aff_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_aff_gt_set.restype = c_void_p
 isl.isl_aff_gt_set.argtypes = [c_void_p, c_void_p]
+isl.isl_aff_is_cst.argtypes = [c_void_p]
 isl.isl_aff_le_set.restype = c_void_p
 isl.isl_aff_le_set.argtypes = [c_void_p, c_void_p]
 isl.isl_aff_lt_set.restype = c_void_p
@@ -6641,6 +6731,36 @@
             obj = union_map(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def intersect_domain_factor_domain(arg0, arg1):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is union_map:
+                arg1 = union_map(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_intersect_domain_factor_domain(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr))
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
+    def intersect_domain_factor_range(arg0, arg1):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is union_map:
+                arg1 = union_map(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_intersect_domain_factor_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr))
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
     def intersect_params(arg0, arg1):
         try:
             if not arg0.__class__ is union_map:
@@ -6668,6 +6788,36 @@
             obj = union_map(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def intersect_range_factor_domain(arg0, arg1):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is union_map:
+                arg1 = union_map(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_intersect_range_factor_domain(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr))
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
+    def intersect_range_factor_range(arg0, arg1):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is union_map:
+                arg1 = union_map(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_intersect_range_factor_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr))
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
     def is_bijective(arg0):
         try:
             if not arg0.__class__ is union_map:
@@ -7133,12 +7283,20 @@
 isl.isl_union_map_intersect_domain_space.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_intersect_domain_union_set.restype = c_void_p
 isl.isl_union_map_intersect_domain_union_set.argtypes = [c_void_p, c_void_p]
+isl.isl_union_map_intersect_domain_factor_domain.restype = c_void_p
+isl.isl_union_map_intersect_domain_factor_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_union_map_intersect_domain_factor_range.restype = c_void_p
+isl.isl_union_map_intersect_domain_factor_range.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_intersect_params.restype = c_void_p
 isl.isl_union_map_intersect_params.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_intersect_range_space.restype = c_void_p
 isl.isl_union_map_intersect_range_space.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_intersect_range_union_set.restype = c_void_p
 isl.isl_union_map_intersect_range_union_set.argtypes = [c_void_p, c_void_p]
+isl.isl_union_map_intersect_range_factor_domain.restype = c_void_p
+isl.isl_union_map_intersect_range_factor_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_union_map_intersect_range_factor_range.restype = c_void_p
+isl.isl_union_map_intersect_range_factor_range.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_is_bijective.argtypes = [c_void_p]
 isl.isl_union_map_is_disjoint.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_is_empty.argtypes = [c_void_p]
@@ -7584,6 +7742,36 @@
         res = isl.isl_map_intersect_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def intersect_domain_factor_domain(arg0, arg1):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map:
+                arg1 = map(arg1)
+        except:
+            return union_map(arg0).intersect_domain_factor_domain(arg1)
+        ctx = arg0.ctx
+        res = isl.isl_map_intersect_domain_factor_domain(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
+    def intersect_domain_factor_range(arg0, arg1):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map:
+                arg1 = map(arg1)
+        except:
+            return union_map(arg0).intersect_domain_factor_range(arg1)
+        ctx = arg0.ctx
+        res = isl.isl_map_intersect_domain_factor_range(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
     def intersect_params(arg0, arg1):
         try:
             if not arg0.__class__ is map:
@@ -7614,6 +7802,36 @@
         res = isl.isl_map_intersect_range(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def intersect_range_factor_domain(arg0, arg1):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map:
+                arg1 = map(arg1)
+        except:
+            return union_map(arg0).intersect_range_factor_domain(arg1)
+        ctx = arg0.ctx
+        res = isl.isl_map_intersect_range_factor_domain(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
+    def intersect_range_factor_range(arg0, arg1):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map:
+                arg1 = map(arg1)
+        except:
+            return union_map(arg0).intersect_range_factor_range(arg1)
+        ctx = arg0.ctx
+        res = isl.isl_map_intersect_range_factor_range(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
     def is_bijective(arg0):
         try:
             if not arg0.__class__ is map:
@@ -7796,11 +8014,6 @@
             res = isl.isl_map_lower_bound_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr))
             obj = map(ctx=ctx, ptr=res)
             return obj
-        if len(args) == 2 and args[1].__class__ is multi_val:
-            ctx = args[0].ctx
-            res = isl.isl_map_lower_bound_multi_val(isl.isl_map_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr))
-            obj = map(ctx=ctx, ptr=res)
-            return obj
         raise Error
     def max_multi_pw_aff(arg0):
         try:
@@ -7861,6 +8074,21 @@
             obj = map(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def product(arg0, arg1):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map:
+                arg1 = map(arg1)
+        except:
+            return union_map(arg0).product(arg1)
+        ctx = arg0.ctx
+        res = isl.isl_map_product(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
     def project_out_all_params(arg0):
         try:
             if not arg0.__class__ is map:
@@ -8013,11 +8241,6 @@
             res = isl.isl_map_upper_bound_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr))
             obj = map(ctx=ctx, ptr=res)
             return obj
-        if len(args) == 2 and args[1].__class__ is multi_val:
-            ctx = args[0].ctx
-            res = isl.isl_map_upper_bound_multi_val(isl.isl_map_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr))
-            obj = map(ctx=ctx, ptr=res)
-            return obj
         raise Error
     def wrap(arg0):
         try:
@@ -8029,6 +8252,16 @@
         res = isl.isl_map_wrap(isl.isl_map_copy(arg0.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
+    def zip(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_zip(isl.isl_map_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
 
 isl.isl_map_from_basic_map.restype = c_void_p
 isl.isl_map_from_basic_map.argtypes = [c_void_p]
@@ -8089,10 +8322,18 @@
 isl.isl_map_intersect.argtypes = [c_void_p, c_void_p]
 isl.isl_map_intersect_domain.restype = c_void_p
 isl.isl_map_intersect_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_map_intersect_domain_factor_domain.restype = c_void_p
+isl.isl_map_intersect_domain_factor_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_map_intersect_domain_factor_range.restype = c_void_p
+isl.isl_map_intersect_domain_factor_range.argtypes = [c_void_p, c_void_p]
 isl.isl_map_intersect_params.restype = c_void_p
 isl.isl_map_intersect_params.argtypes = [c_void_p, c_void_p]
 isl.isl_map_intersect_range.restype = c_void_p
 isl.isl_map_intersect_range.argtypes = [c_void_p, c_void_p]
+isl.isl_map_intersect_range_factor_domain.restype = c_void_p
+isl.isl_map_intersect_range_factor_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_map_intersect_range_factor_range.restype = c_void_p
+isl.isl_map_intersect_range_factor_range.argtypes = [c_void_p, c_void_p]
 isl.isl_map_is_bijective.argtypes = [c_void_p]
 isl.isl_map_is_disjoint.argtypes = [c_void_p, c_void_p]
 isl.isl_map_is_empty.argtypes = [c_void_p]
@@ -8119,8 +8360,6 @@
 isl.isl_map_lexmin_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_map_lower_bound_multi_pw_aff.restype = c_void_p
 isl.isl_map_lower_bound_multi_pw_aff.argtypes = [c_void_p, c_void_p]
-isl.isl_map_lower_bound_multi_val.restype = c_void_p
-isl.isl_map_lower_bound_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_map_max_multi_pw_aff.restype = c_void_p
 isl.isl_map_max_multi_pw_aff.argtypes = [c_void_p]
 isl.isl_map_min_multi_pw_aff.restype = c_void_p
@@ -8137,6 +8376,8 @@
 isl.isl_map_preimage_range_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_map_preimage_range_pw_multi_aff.restype = c_void_p
 isl.isl_map_preimage_range_pw_multi_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_map_product.restype = c_void_p
+isl.isl_map_product.argtypes = [c_void_p, c_void_p]
 isl.isl_map_project_out_all_params.restype = c_void_p
 isl.isl_map_project_out_all_params.argtypes = [c_void_p]
 isl.isl_map_range.restype = c_void_p
@@ -8165,10 +8406,10 @@
 isl.isl_map_unshifted_simple_hull.argtypes = [c_void_p]
 isl.isl_map_upper_bound_multi_pw_aff.restype = c_void_p
 isl.isl_map_upper_bound_multi_pw_aff.argtypes = [c_void_p, c_void_p]
-isl.isl_map_upper_bound_multi_val.restype = c_void_p
-isl.isl_map_upper_bound_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_map_wrap.restype = c_void_p
 isl.isl_map_wrap.argtypes = [c_void_p]
+isl.isl_map_zip.restype = c_void_p
+isl.isl_map_zip.argtypes = [c_void_p]
 isl.isl_map_copy.restype = c_void_p
 isl.isl_map_copy.argtypes = [c_void_p]
 isl.isl_map_free.restype = c_void_p
@@ -9692,6 +9933,16 @@
         res = isl.isl_set_subtract(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
+    def translation(arg0):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_translation(isl.isl_set_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
     def unbind_params(arg0, arg1):
         try:
             if not arg0.__class__ is set:
@@ -9881,6 +10132,8 @@
 isl.isl_set_sample_point.argtypes = [c_void_p]
 isl.isl_set_subtract.restype = c_void_p
 isl.isl_set_subtract.argtypes = [c_void_p, c_void_p]
+isl.isl_set_translation.restype = c_void_p
+isl.isl_set_translation.argtypes = [c_void_p]
 isl.isl_set_unbind_params.restype = c_void_p
 isl.isl_set_unbind_params.argtypes = [c_void_p, c_void_p]
 isl.isl_set_unbind_params_insert_domain.restype = c_void_p
@@ -10794,6 +11047,17 @@
         return obj
     def get_space(arg0):
         return arg0.space()
+    def involves_nan(arg0):
+        try:
+            if not arg0.__class__ is multi_val:
+                arg0 = multi_val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_val_involves_nan(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def max(arg0, arg1):
         try:
             if not arg0.__class__ is multi_val:
@@ -10985,6 +11249,7 @@
 isl.isl_multi_val_get_list.argtypes = [c_void_p]
 isl.isl_multi_val_get_space.restype = c_void_p
 isl.isl_multi_val_get_space.argtypes = [c_void_p]
+isl.isl_multi_val_involves_nan.argtypes = [c_void_p]
 isl.isl_multi_val_max.restype = c_void_p
 isl.isl_multi_val_max.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_min.restype = c_void_p
@@ -11451,6 +11716,18 @@
         res = isl.isl_schedule_from_domain(isl.isl_union_set_copy(arg0.ptr))
         obj = schedule(ctx=ctx, ptr=res)
         return obj
+    def domain(arg0):
+        try:
+            if not arg0.__class__ is schedule:
+                arg0 = schedule(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_get_domain(arg0.ptr)
+        obj = union_set(ctx=ctx, ptr=res)
+        return obj
+    def get_domain(arg0):
+        return arg0.domain()
     def map(arg0):
         try:
             if not arg0.__class__ is schedule:
@@ -11487,6 +11764,8 @@
 isl.isl_schedule_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_schedule_from_domain.restype = c_void_p
 isl.isl_schedule_from_domain.argtypes = [c_void_p]
+isl.isl_schedule_get_domain.restype = c_void_p
+isl.isl_schedule_get_domain.argtypes = [c_void_p]
 isl.isl_schedule_get_map.restype = c_void_p
 isl.isl_schedule_get_map.argtypes = [c_void_p]
 isl.isl_schedule_get_root.restype = c_void_p
@@ -13269,6 +13548,16 @@
             obj = space(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def curry(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_curry(isl.isl_space_copy(arg0.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
     def domain(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13346,6 +13635,21 @@
         res = isl.isl_space_params(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def product(arg0, arg1):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is space:
+                arg1 = space(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_product(isl.isl_space_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
     def range(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13356,6 +13660,36 @@
         res = isl.isl_space_range(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def range_reverse(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_range_reverse(isl.isl_space_copy(arg0.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def reverse(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_reverse(isl.isl_space_copy(arg0.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def uncurry(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_uncurry(isl.isl_space_copy(arg0.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
     @staticmethod
     def unit():
         ctx = Context.getDefaultInstance()
@@ -13387,6 +13721,8 @@
 isl.isl_space_add_named_tuple_id_ui.argtypes = [c_void_p, c_void_p, c_int]
 isl.isl_space_add_unnamed_tuple_ui.restype = c_void_p
 isl.isl_space_add_unnamed_tuple_ui.argtypes = [c_void_p, c_int]
+isl.isl_space_curry.restype = c_void_p
+isl.isl_space_curry.argtypes = [c_void_p]
 isl.isl_space_domain.restype = c_void_p
 isl.isl_space_domain.argtypes = [c_void_p]
 isl.isl_space_flatten_domain.restype = c_void_p
@@ -13399,8 +13735,16 @@
 isl.isl_space_map_from_set.argtypes = [c_void_p]
 isl.isl_space_params.restype = c_void_p
 isl.isl_space_params.argtypes = [c_void_p]
+isl.isl_space_product.restype = c_void_p
+isl.isl_space_product.argtypes = [c_void_p, c_void_p]
 isl.isl_space_range.restype = c_void_p
 isl.isl_space_range.argtypes = [c_void_p]
+isl.isl_space_range_reverse.restype = c_void_p
+isl.isl_space_range_reverse.argtypes = [c_void_p]
+isl.isl_space_reverse.restype = c_void_p
+isl.isl_space_reverse.argtypes = [c_void_p]
+isl.isl_space_uncurry.restype = c_void_p
+isl.isl_space_uncurry.argtypes = [c_void_p]
 isl.isl_space_unit.restype = c_void_p
 isl.isl_space_unit.argtypes = [Context]
 isl.isl_space_unwrap.restype = c_void_p
diff --git a/lib/External/isl/interface/ltmain.sh b/lib/External/isl/interface/ltmain.sh
index a736cf9..0cb7f90 100644
--- a/lib/External/isl/interface/ltmain.sh
+++ b/lib/External/isl/interface/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-2"
+VERSION="2.4.6 Debian-2.4.6-14"
 package_revision=2.4.6
 
 
@@ -387,7 +387,7 @@
 # putting '$debug_cmd' at the start of all your functions, you can get
 # bash to show function call trace with:
 #
-#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+#    debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
 debug_cmd=${debug_cmd-":"}
 exit_cmd=:
 
@@ -1370,7 +1370,7 @@
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
+scriptversion=2015-10-07.11; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -1530,6 +1530,8 @@
 {
     $debug_cmd
 
+    _G_rc_run_hooks=false
+
     case " $hookable_fns " in
       *" $1 "*) ;;
       *) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -1538,16 +1540,16 @@
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
+      if eval $_G_hook '"$@"'; then
+        # store returned options list back into positional
+        # parameters for next 'cmd' execution.
+        eval _G_hook_result=\$${_G_hook}_result
+        eval set dummy "$_G_hook_result"; shift
+        _G_rc_run_hooks=:
+      fi
     done
 
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
+    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -1557,10 +1559,16 @@
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, you may remove/edit
+# any options that you action, and then pass back the remaining unprocessed
 # options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
+# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
+# hook's caller know that it should pay attention to
+# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
+# arguments are left untouched by the hook and therefore caller will ignore the
+# result variable.
+#
+# Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1570,9 +1578,11 @@
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
+#        # No change in '$@' (ignored completely by this hook).  There is
+#        # no need to do the equivalent (but slower) action:
+#        # func_quote_for_eval ${1+"$@"}
+#        # my_options_prep_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1581,25 +1591,37 @@
 #    {
 #        $debug_cmd
 #
+#        args_changed=false
+#
 #        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=: ;;
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
+#                         args_changed=:
 #                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@", we could need that later
+#                         # if $args_changed is true.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
+#        if $args_changed; then
+#          func_quote_for_eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_for_eval_result
+#        fi
+#
+#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1611,16 +1633,32 @@
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll alse need to manually amend $usage_message to reflect the extra
+# You'll also need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    _G_func_options_finish_exit=false
+    if func_run_hooks func_options ${1+"$@"}; then
+      func_options_finish_result=$func_run_hooks_result
+      _G_func_options_finish_exit=:
+    fi
+
+    $_G_func_options_finish_exit
+}
+
+
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1630,17 +1668,28 @@
 {
     $debug_cmd
 
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
+    _G_rc_options=false
 
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      if eval func_$my_func '${1+"$@"}'; then
+        eval _G_res_var='$'"func_${my_func}_result"
+        eval set dummy "$_G_res_var" ; shift
+        _G_rc_options=:
+      fi
+    done
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    # Save modified positional parameters for caller.  As a top-level
+    # options-parser function we always need to set the 'func_options_result'
+    # variable (regardless the $_G_rc_options value).
+    if $_G_rc_options; then
+      func_options_result=$_G_res_var
+    else
+      func_quote_for_eval ${1+"$@"}
+      func_options_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_options
 }
 
 
@@ -1649,9 +1698,9 @@
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
+# needs to propagate that back to rest of this script, then the complete
 # modified list must be put in 'func_run_hooks_result' before
-# returning.
+# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1661,10 +1710,14 @@
     opt_verbose=false
     opt_warning_types=
 
-    func_run_hooks func_options_prep ${1+"$@"}
+    _G_rc_options_prep=false
+    if func_run_hooks func_options_prep ${1+"$@"}; then
+      _G_rc_options_prep=:
+      # save modified positional parameters for caller
+      func_options_prep_result=$func_run_hooks_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    $_G_rc_options_prep
 }
 
 
@@ -1678,18 +1731,20 @@
 
     func_parse_options_result=
 
+    _G_rc_parse_options=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
-
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+      if func_run_hooks func_parse_options ${1+"$@"}; then
+        eval set dummy "$func_run_hooks_result"; shift
+        _G_rc_parse_options=:
+      fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -1704,7 +1759,10 @@
 		      ;;
 
         --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_rc_parse_options=:
+                        break
+                      fi
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1757,15 +1815,25 @@
                       shift
                       ;;
 
-        --)           break ;;
+        --)           _G_rc_parse_options=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
       esac
+
+      $_G_match_parse_options && _G_rc_parse_options=:
     done
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+
+    if $_G_rc_parse_options; then
+      # save modified positional parameters for caller
+      func_quote_for_eval ${1+"$@"}
+      func_parse_options_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_parse_options
 }
 
 
@@ -1778,16 +1846,21 @@
 {
     $debug_cmd
 
+    _G_rc_validate_options=false
+
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    func_run_hooks func_validate_options ${1+"$@"}
+    if func_run_hooks func_validate_options ${1+"$@"}; then
+      # save modified positional parameters for caller
+      func_validate_options_result=$func_run_hooks_result
+      _G_rc_validate_options=:
+    fi
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    $_G_rc_validate_options
 }
 
 
@@ -2068,7 +2141,7 @@
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-2
+       version:        $progname $scriptversion Debian-2.4.6-14
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
@@ -2270,6 +2343,8 @@
     nonopt=
     preserve_args=
 
+    _G_rc_lt_options_prep=:
+
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -2293,11 +2368,18 @@
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
+    *)
+      _G_rc_lt_options_prep=false
+      ;;
     esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
+    if $_G_rc_lt_options_prep; then
+      # Pass back the list of options.
+      func_quote_for_eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_lt_options_prep
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2309,9 +2391,12 @@
 {
     $debug_cmd
 
+    _G_rc_lt_parse_options=false
+
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
+      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -2386,15 +2471,22 @@
                         func_append preserve_args " $_G_opt"
                         ;;
 
-	# An option not handled by this hook function:
-        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
+        # An option not handled by this hook function:
+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
+                        _G_match_lt_parse_options=false
+                        break
+                        ;;
       esac
+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
+    if $_G_rc_lt_parse_options; then
+      # save modified positional parameters for caller
+      func_quote_for_eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_for_eval_result
+    fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
+    $_G_rc_lt_parse_options
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -7275,10 +7367,13 @@
       # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
       # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -fuse-ld=*           Linker select flags for GCC
+      # -static-*            direct GCC to link specific libraries statically
+      # -fcilkplus           Cilk Plus language extension features for C/C++
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*)
+      -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
         func_quote_for_eval "$arg"
 	arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
diff --git a/lib/External/isl/interface/missing b/lib/External/isl/interface/missing
index f62bbae..625aeb1 100644
--- a/lib/External/isl/interface/missing
+++ b/lib/External/isl/interface/missing
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2013-10-28.13; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -101,9 +101,9 @@
   exit $st
 fi
 
-perl_URL=http://www.perl.org/
-flex_URL=http://flex.sourceforge.net/
-gnu_software_URL=http://www.gnu.org/software
+perl_URL=https://www.perl.org/
+flex_URL=https://github.com/westes/flex
+gnu_software_URL=https://www.gnu.org/software
 
 program_details ()
 {
@@ -207,9 +207,9 @@
 exit $st
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/lib/External/isl/isl_aff.c b/lib/External/isl/isl_aff.c
index 831d220..b840a52 100644
--- a/lib/External/isl/isl_aff.c
+++ b/lib/External/isl/isl_aff.c
@@ -4,7 +4,7 @@
  * Copyright 2012-2014 Ecole Normale Superieure
  * Copyright 2014      INRIA Rocquencourt
  * Copyright 2016      Sven Verdoolaege
- * Copyright 2018      Cerebras Systems
+ * Copyright 2018,2020 Cerebras Systems
  *
  * Use of this software is governed by the MIT license
  *
@@ -196,6 +196,23 @@
 	return isl_aff_set_nan(aff);
 }
 
+/* Return an affine expression defined on the specified domain space
+ * that represents NaN.
+ */
+__isl_give isl_aff *isl_aff_nan_on_domain_space(__isl_take isl_space *space)
+{
+	return isl_aff_nan_on_domain(isl_local_space_from_space(space));
+}
+
+/* Return a piecewise affine expression defined on the specified domain space
+ * that represents NaN.
+ */
+__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space(
+	__isl_take isl_space *space)
+{
+	return isl_pw_aff_from_aff(isl_aff_nan_on_domain_space(space));
+}
+
 /* Return a piecewise affine expression defined on the specified domain
  * that represents NaN.
  */
@@ -901,25 +918,12 @@
 	return aff;
 }
 
-/* Add "v" to the constant term of "aff".
- *
- * A NaN is unaffected by this operation.
+/* Add "v" to the constant term of "aff",
+ * in case "aff" is a rational expression.
  */
-__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
+static __isl_give isl_aff *isl_aff_add_rat_constant_val(__isl_take isl_aff *aff,
 	__isl_take isl_val *v)
 {
-	if (!aff || !v)
-		goto error;
-
-	if (isl_aff_is_nan(aff) || isl_val_is_zero(v)) {
-		isl_val_free(v);
-		return aff;
-	}
-
-	if (!isl_val_is_rat(v))
-		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
-			"expecting rational value", goto error);
-
 	aff = isl_aff_cow(aff);
 	if (!aff)
 		goto error;
@@ -953,6 +957,58 @@
 	return NULL;
 }
 
+/* Return the first argument and free the second.
+ */
+static __isl_give isl_aff *pick_free(__isl_take isl_aff *aff,
+	__isl_take isl_val *v)
+{
+	isl_val_free(v);
+	return aff;
+}
+
+/* Replace the first argument by NaN and free the second argument.
+ */
+static __isl_give isl_aff *set_nan_free_val(__isl_take isl_aff *aff,
+	__isl_take isl_val *v)
+{
+	isl_val_free(v);
+	return isl_aff_set_nan(aff);
+}
+
+/* Add "v" to the constant term of "aff".
+ *
+ * A NaN is unaffected by this operation.
+ * Conversely, adding a NaN turns "aff" into a NaN.
+ */
+__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
+	__isl_take isl_val *v)
+{
+	isl_bool is_nan, is_zero, is_rat;
+
+	is_nan = isl_aff_is_nan(aff);
+	is_zero = isl_val_is_zero(v);
+	if (is_nan < 0 || is_zero < 0)
+		goto error;
+	if (is_nan || is_zero)
+		return pick_free(aff, v);
+
+	is_nan = isl_val_is_nan(v);
+	is_rat = isl_val_is_rat(v);
+	if (is_nan < 0 || is_rat < 0)
+		goto error;
+	if (is_nan)
+		return set_nan_free_val(aff, v);
+	if (!is_rat)
+		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
+			"expecting rational value or NaN", goto error);
+
+	return isl_aff_add_rat_constant_val(aff, v);
+error:
+	isl_aff_free(aff);
+	isl_val_free(v);
+	return NULL;
+}
+
 __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
 {
 	isl_int t;
@@ -4151,6 +4207,18 @@
 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
 }
 
+/* Create a piecewise multi expression that maps elements in the given space
+ * to themselves.
+ */
+__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space(
+	__isl_take isl_space *space)
+{
+	isl_multi_aff *ma;
+
+	ma = isl_multi_aff_identity_on_domain_space(space);
+	return isl_pw_multi_aff_from_multi_aff(ma);
+}
+
 /* Exploit the equalities in "eq" to simplify the affine expressions.
  */
 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
@@ -6432,6 +6500,23 @@
 #include <isl_multi_zero_templ.c>
 #include <isl_multi_unbind_params_templ.c>
 
+/* If "mpa" has an explicit domain, then intersect the domain of "map"
+ * with this explicit domain.
+ */
+__isl_give isl_map *isl_map_intersect_multi_pw_aff_explicit_domain(
+	__isl_take isl_map *map, __isl_keep isl_multi_pw_aff *mpa)
+{
+	isl_set *dom;
+
+	if (!isl_multi_pw_aff_has_explicit_domain(mpa))
+		return map;
+
+	dom = isl_multi_pw_aff_domain(isl_multi_pw_aff_copy(mpa));
+	map = isl_map_intersect_domain(map, dom);
+
+	return map;
+}
+
 /* Are all elements of "mpa" piecewise constants?
  */
 isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa)
@@ -7372,17 +7457,24 @@
 }
 
 /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
- * where the function values of "mpa1" lexicographically satisfies "base"
- * compared to that of "mpa2".  "space" is the space of the result.
+ * where the function values of "mpa1" lexicographically satisfies
+ * "strict_base"/"base" compared to that of "mpa2".
+ * "space" is the space of the result.
  * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
  *
- * "mpa1" lexicographically satisfies "base" compared to "mpa2"
- * if its i-th element satisfies "base" when compared to
- * the i-th element of "mpa2" while all previous elements are
+ * "mpa1" lexicographically satisfies "strict_base"/"base" compared to "mpa2"
+ * if, for some i, the i-th element of "mpa1" satisfies "strict_base"/"base"
+ * when compared to the i-th element of "mpa2" while all previous elements are
  * pairwise equal.
+ * In particular, if i corresponds to the final elements
+ * then they need to satisfy "base", while "strict_base" needs to be satisfied
+ * for other values of i.
+ * If "base" is a strict order, then "base" and "strict_base" are the same.
  */
 static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space(
 	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
+	__isl_give isl_map *(*strict_base)(__isl_take isl_pw_aff *pa1,
+		__isl_take isl_pw_aff *pa2),
 	__isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1,
 		__isl_take isl_pw_aff *pa2),
 	__isl_take isl_space *space)
@@ -7398,16 +7490,19 @@
 	rest = isl_map_universe(space);
 
 	for (i = 0; i < n; ++i) {
+		int last;
 		isl_pw_aff *pa1, *pa2;
 		isl_map *map;
 
+		last = i == n - 1;
+
 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
 		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
-		map = base(pa1, pa2);
+		map = last ? base(pa1, pa2) : strict_base(pa1, pa2);
 		map = isl_map_intersect(map, isl_map_copy(rest));
 		res = isl_map_union(res, map);
 
-		if (i == n - 1)
+		if (last)
 			continue;
 
 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
@@ -7421,19 +7516,27 @@
 }
 
 #undef ORDER
-#define ORDER	le
+#define ORDER		le
+#undef STRICT_ORDER
+#define STRICT_ORDER	lt
 #include "isl_aff_lex_templ.c"
 
 #undef ORDER
-#define ORDER	lt
+#define ORDER		lt
+#undef STRICT_ORDER
+#define STRICT_ORDER	lt
 #include "isl_aff_lex_templ.c"
 
 #undef ORDER
-#define ORDER	ge
+#define ORDER		ge
+#undef STRICT_ORDER
+#define STRICT_ORDER	gt
 #include "isl_aff_lex_templ.c"
 
 #undef ORDER
-#define ORDER	gt
+#define ORDER		gt
+#undef STRICT_ORDER
+#define STRICT_ORDER	gt
 #include "isl_aff_lex_templ.c"
 
 /* Compare two isl_affs.
@@ -7689,6 +7792,104 @@
 	return isl_union_pw_multi_aff_pullback_union_pw_multi_aff(upma2, upma1);
 }
 
+#undef TYPE
+#define TYPE isl_pw_multi_aff
+static
+#include "isl_copy_tuple_id_templ.c"
+
+/* Given a function "pma1" of the form A[B -> C] -> D and
+ * a function "pma2" of the form E -> B,
+ * replace the domain of the wrapped relation inside the domain of "pma1"
+ * by the preimage with respect to "pma2".
+ * In other words, plug in "pma2" in this nested domain.
+ * The result is of the form A[E -> C] -> D.
+ *
+ * In particular, extend E -> B to A[E -> C] -> A[B -> C] and
+ * plug that into "pma1".
+ */
+__isl_give isl_pw_multi_aff *
+isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
+	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
+{
+	isl_space *pma1_space, *pma2_space;
+	isl_space *space;
+	isl_pw_multi_aff *id;
+
+	pma1_space = isl_pw_multi_aff_peek_space(pma1);
+	pma2_space = isl_pw_multi_aff_peek_space(pma2);
+
+	if (isl_space_check_domain_is_wrapping(pma1_space) < 0)
+		goto error;
+	if (isl_space_check_wrapped_tuple_is_equal(pma1_space,
+			isl_dim_in, isl_dim_in, pma2_space, isl_dim_out) < 0)
+		goto error;
+
+	space = isl_space_domain(isl_space_copy(pma1_space));
+	space = isl_space_range(isl_space_unwrap(space));
+	id = isl_pw_multi_aff_identity_on_domain_space(space);
+	pma2 = isl_pw_multi_aff_product(pma2, id);
+
+	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_in,
+						pma1_space, isl_dim_in);
+	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_out,
+						pma1_space, isl_dim_in);
+
+	return isl_pw_multi_aff_pullback_pw_multi_aff(pma1, pma2);
+error:
+	isl_pw_multi_aff_free(pma1);
+	isl_pw_multi_aff_free(pma2);
+	return NULL;
+}
+
+/* If data->pma and "pma2" are such that
+ * data->pma is of the form A[B -> C] -> D and
+ * "pma2" is of the form E -> B,
+ * then replace the domain of the wrapped relation
+ * inside the domain of data->pma by the preimage with respect to "pma2" and
+ * add the result to data->res.
+ */
+static isl_stat preimage_domain_wrapped_domain_entry(
+	__isl_take isl_pw_multi_aff *pma2, void *user)
+{
+	struct isl_union_pw_multi_aff_bin_data *data = user;
+	isl_space *pma1_space, *pma2_space;
+	isl_bool match;
+
+	pma1_space = isl_pw_multi_aff_peek_space(data->pma);
+	pma2_space = isl_pw_multi_aff_peek_space(pma2);
+
+	match = isl_space_domain_is_wrapping(pma1_space);
+	if (match >= 0 && match)
+		match = isl_space_wrapped_tuple_is_equal(pma1_space, isl_dim_in,
+					isl_dim_in, pma2_space, isl_dim_out);
+	if (match < 0 || !match) {
+		isl_pw_multi_aff_free(pma2);
+		return match < 0 ? isl_stat_error : isl_stat_ok;
+	}
+
+	pma2 = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
+		isl_pw_multi_aff_copy(data->pma), pma2);
+
+	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
+
+	return isl_stat_non_null(data->res);
+}
+
+/* For each pair of functions A[B -> C] -> D in "upma1" and
+ * E -> B in "upma2",
+ * replace the domain of the wrapped relation inside the domain of the first
+ * by the preimage with respect to the second and collect the results.
+ * In other words, plug in the second function in this nested domain.
+ * The results are of the form A[E -> C] -> D.
+ */
+__isl_give isl_union_pw_multi_aff *
+isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(
+	__isl_take isl_union_pw_multi_aff *upma1,
+	__isl_take isl_union_pw_multi_aff *upma2)
+{
+	return bin_op(upma1, upma2, &preimage_domain_wrapped_domain_entry);
+}
+
 /* Check that the domain space of "upa" matches "space".
  *
  * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and
diff --git a/lib/External/isl/isl_aff_lex_templ.c b/lib/External/isl/isl_aff_lex_templ.c
index 428eb58..9fbab61 100644
--- a/lib/External/isl/isl_aff_lex_templ.c
+++ b/lib/External/isl/isl_aff_lex_templ.c
@@ -17,15 +17,19 @@
  * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
  *
  * "mpa1" is in the given lexicographic order compared to "mpa2"
- * if its i-th element is in that order compared to
+ * if, for some i, the i-th element of "mpa1" is in that order compared to
  * the i-th element of "mpa2" while all previous elements are
- * pairwise equal.
+ * pairwise equal, where the order needs to be strict (not-equal)
+ * if i corresponds to anything but the last element.
+ * The strict version of "ORDER" is defined by "STRICT_ORDER",
+ * which is the same if "ORDER" itself is strict.
  */
 static __isl_give isl_map *FN(FN(isl_multi_pw_aff_lex,ORDER),map_on_space)(
 	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
 	__isl_take isl_space *space)
 {
 	return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2,
+					&FN(FN(isl_pw_aff,STRICT_ORDER),map),
 					&FN(FN(isl_pw_aff,ORDER),map), space);
 }
 
diff --git a/lib/External/isl/isl_aff_private.h b/lib/External/isl/isl_aff_private.h
index a9a4487..8c94f04 100644
--- a/lib/External/isl/isl_aff_private.h
+++ b/lib/External/isl/isl_aff_private.h
@@ -200,6 +200,9 @@
 
 #undef EXPLICIT_DOMAIN
 
+__isl_give isl_map *isl_map_intersect_multi_pw_aff_explicit_domain(
+	__isl_take isl_map *map, __isl_keep isl_multi_pw_aff *mpa);
+
 #undef EL
 #define EL isl_union_pw_aff
 
diff --git a/lib/External/isl/isl_arg.c b/lib/External/isl/isl_arg.c
index 2494837..8a9e26d 100644
--- a/lib/External/isl/isl_arg.c
+++ b/lib/External/isl/isl_arg.c
@@ -17,6 +17,7 @@
 
 static struct isl_arg help_arg[] = {
 ISL_ARG_PHANTOM_BOOL('h', "help", NULL, "print this help, then exit")
+{ isl_arg_end }
 };
 
 static void set_default_choice(struct isl_arg *arg, void *opt)
diff --git a/lib/External/isl/isl_ast_codegen.c b/lib/External/isl/isl_ast_codegen.c
index 4215484..7f891a0 100644
--- a/lib/External/isl/isl_ast_codegen.c
+++ b/lib/External/isl/isl_ast_codegen.c
@@ -5187,6 +5187,32 @@
 	return list;
 }
 
+/* Check that the band partial schedule "partial" does not filter out
+ * any statement instances, as specified by the range of "executed".
+ */
+static isl_stat check_band_schedule_total_on_instances(
+	__isl_keep isl_multi_union_pw_aff *partial,
+	__isl_keep isl_union_map *executed)
+{
+	isl_bool subset;
+	isl_union_set *domain, *instances;
+
+	instances = isl_union_map_range(isl_union_map_copy(executed));
+	partial = isl_multi_union_pw_aff_copy(partial);
+	domain = isl_multi_union_pw_aff_domain(partial);
+	subset = isl_union_set_is_subset(instances, domain);
+	isl_union_set_free(domain);
+	isl_union_set_free(instances);
+
+	if (subset < 0)
+		return isl_stat_error;
+	if (!subset)
+		isl_die(isl_union_map_get_ctx(executed), isl_error_invalid,
+			"band node is not allowed to drop statement instances",
+			return isl_stat_error);
+	return isl_stat_ok;
+}
+
 /* Generate an AST that visits the elements in the domain of "executed"
  * in the relative order specified by the band node "node" and its descendants.
  *
@@ -5224,6 +5250,9 @@
 				isl_ast_build_get_space(build, 1));
 	space = isl_multi_union_pw_aff_get_space(extra);
 
+	if (check_band_schedule_total_on_instances(extra, executed) < 0)
+		executed = isl_union_map_free(executed);
+
 	extra_umap = isl_union_map_from_multi_union_pw_aff(extra);
 	extra_umap = isl_union_map_reverse(extra_umap);
 
diff --git a/lib/External/isl/isl_bernstein.c b/lib/External/isl/isl_bernstein.c
index 5c19a11..eddea83 100644
--- a/lib/External/isl/isl_bernstein.c
+++ b/lib/External/isl/isl_bernstein.c
@@ -99,11 +99,18 @@
  * which is the case if we select exactly one vertex (i.e., one of the
  * exponents in "k" is exactly "d") and if that vertex
  * is integral for all values of the parameters.
+ *
+ * If the degree "d" is zero, then there are no exponents.
+ * Since the polynomial is a constant expression in this case,
+ * the bound is necessarily tight.
  */
 static isl_bool is_tight(int *k, int n, int d, isl_cell *cell)
 {
 	int i;
 
+	if (d == 0)
+		return isl_bool_true;
+
 	for (i = 0; i < n; ++i) {
 		int v;
 		if (!k[i])
@@ -352,43 +359,34 @@
  * We compute the chamber decomposition of the parametric polytope "bset"
  * and then perform bernstein expansion on the parametric vertices
  * that are active on each chamber.
+ *
+ * If the polynomial does not depend on the set variables
+ * (and in particular if the number of set variables is zero)
+ * then the bound is equal to the polynomial and
+ * no actual bernstein expansion needs to be performed.
  */
 static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_base(
 	__isl_take isl_basic_set *bset,
 	__isl_take isl_qpolynomial *poly, struct bernstein_data *data,
 	isl_bool *tight)
 {
+	int degree;
 	isl_size nvar;
 	isl_space *space;
-	isl_pw_qpolynomial_fold *pwf;
 	isl_vertices *vertices;
 	isl_bool covers;
 
 	nvar = isl_basic_set_dim(bset, isl_dim_set);
 	if (nvar < 0)
 		bset = isl_basic_set_free(bset);
-	if (nvar == 0) {
-		isl_set *dom;
-		isl_qpolynomial_fold *fold;
+	if (nvar == 0)
+		return isl_qpolynomial_cst_bound(bset, poly, data->type, tight);
 
-		fold = isl_qpolynomial_fold_alloc(data->type, poly);
-		dom = isl_set_from_basic_set(bset);
-		if (tight)
-			*tight = isl_bool_true;
-		pwf = isl_pw_qpolynomial_fold_alloc(data->type, dom, fold);
-		return isl_pw_qpolynomial_fold_project_domain_on_params(pwf);
-	}
-
-	if (isl_qpolynomial_is_zero(poly)) {
-		isl_set *dom;
-		isl_qpolynomial_fold *fold;
-		fold = isl_qpolynomial_fold_alloc(data->type, poly);
-		dom = isl_set_from_basic_set(bset);
-		pwf = isl_pw_qpolynomial_fold_alloc(data->type, dom, fold);
-		if (tight)
-			*tight = isl_bool_true;
-		return isl_pw_qpolynomial_fold_project_domain_on_params(pwf);
-	}
+	degree = isl_qpolynomial_degree(poly);
+	if (degree < -1)
+		bset = isl_basic_set_free(bset);
+	if (degree <= 0)
+		return isl_qpolynomial_cst_bound(bset, poly, data->type, tight);
 
 	space = isl_basic_set_get_space(bset);
 	space = isl_space_params(space);
@@ -482,7 +480,7 @@
 		goto error;
 	if (f->n_group == 0) {
 		isl_factorizer_free(f);
-		return  bernstein_coefficients_base(bset, poly, data, tight);
+		return bernstein_coefficients_base(bset, poly, data, tight);
 	}
 
 	set = isl_set_from_basic_set(bset);
@@ -575,11 +573,9 @@
 		pwf = bernstein_coefficients_base(bset, poly, &data, tp);
 
 	if (tight)
-		bound->pwf_tight = isl_pw_qpolynomial_fold_fold(bound->pwf_tight, pwf);
+		return isl_bound_add_tight(bound, pwf);
 	else
-		bound->pwf = isl_pw_qpolynomial_fold_fold(bound->pwf, pwf);
-
-	return isl_stat_ok;
+		return isl_bound_add(bound, pwf);
 error:
 	isl_basic_set_free(bset);
 	isl_qpolynomial_free(poly);
diff --git a/lib/External/isl/isl_bound.c b/lib/External/isl/isl_bound.c
index e90ae96..64247ac 100644
--- a/lib/External/isl/isl_bound.c
+++ b/lib/External/isl/isl_bound.c
@@ -16,23 +16,91 @@
 #include <isl_polynomial_private.h>
 #include <isl_options_private.h>
 
+/* Given a polynomial "poly" that is constant in terms
+ * of the domain variables, construct a polynomial reduction
+ * of type "type" that is equal to "poly" on "bset",
+ * with the domain projected onto the parameters.
+ */
+__isl_give isl_pw_qpolynomial_fold *isl_qpolynomial_cst_bound(
+	__isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly,
+	enum isl_fold type, isl_bool *tight)
+{
+	isl_set *dom;
+	isl_qpolynomial_fold *fold;
+	isl_pw_qpolynomial_fold *pwf;
+
+	fold = isl_qpolynomial_fold_alloc(type, poly);
+	dom = isl_set_from_basic_set(bset);
+	if (tight)
+		*tight = isl_bool_true;
+	pwf = isl_pw_qpolynomial_fold_alloc(type, dom, fold);
+	return isl_pw_qpolynomial_fold_project_domain_on_params(pwf);
+}
+
+/* Add the bound "pwf", which is not known to be tight,
+ * to the output of "bound".
+ */
+isl_stat isl_bound_add(struct isl_bound *bound,
+	__isl_take isl_pw_qpolynomial_fold *pwf)
+{
+	bound->pwf = isl_pw_qpolynomial_fold_fold(bound->pwf, pwf);
+	return isl_stat_non_null(bound->pwf);
+}
+
+/* Add the bound "pwf", which is known to be tight,
+ * to the output of "bound".
+ */
+isl_stat isl_bound_add_tight(struct isl_bound *bound,
+	__isl_take isl_pw_qpolynomial_fold *pwf)
+{
+	bound->pwf_tight = isl_pw_qpolynomial_fold_fold(bound->pwf_tight, pwf);
+	return isl_stat_non_null(bound->pwf);
+}
+
+/* Given a polynomial "poly" that is constant in terms
+ * of the domain variables and the domain "bset",
+ * construct the corresponding polynomial reduction and
+ * add it to the tight bounds of "bound".
+ */
+static isl_stat add_constant_poly(__isl_take isl_basic_set *bset,
+	__isl_take isl_qpolynomial *poly, struct isl_bound *bound)
+{
+	isl_pw_qpolynomial_fold *pwf;
+
+	pwf = isl_qpolynomial_cst_bound(bset, poly, bound->type, NULL);
+	return isl_bound_add_tight(bound, pwf);
+}
+
 /* Compute a bound on the polynomial defined over the parametric polytope
  * using either range propagation or bernstein expansion and
  * store the result in bound->pwf and bound->pwf_tight.
  * Since bernstein expansion requires bounded domains, we apply
  * range propagation on unbounded domains.  Otherwise, we respect the choice
  * of the user.
+ *
+ * If the polynomial does not depend on the set variables
+ * then the bound is equal to the polynomial and
+ * it can be added to "bound" directly.
  */
 static isl_stat compressed_guarded_poly_bound(__isl_take isl_basic_set *bset,
 	__isl_take isl_qpolynomial *poly, void *user)
 {
 	struct isl_bound *bound = (struct isl_bound *)user;
+	isl_ctx *ctx;
 	int bounded;
+	int degree;
 
 	if (!bset || !poly)
 		goto error;
 
-	if (bset->ctx->opt->bound == ISL_BOUND_RANGE)
+	degree = isl_qpolynomial_degree(poly);
+	if (degree < -1)
+		goto error;
+	if (degree <= 0)
+		return add_constant_poly(bset, poly, bound);
+
+	ctx = isl_basic_set_get_ctx(bset);
+	if (ctx->opt->bound == ISL_BOUND_RANGE)
 		return isl_qpolynomial_bound_on_domain_range(bset, poly, bound);
 
 	bounded = isl_basic_set_is_bounded(bset);
@@ -94,9 +162,8 @@
 	bound->pwf_tight = isl_pw_qpolynomial_fold_morph_domain(
 						bound->pwf_tight, morph);
 
-	bound->pwf = isl_pw_qpolynomial_fold_fold(top_pwf, bound->pwf);
-	bound->pwf_tight = isl_pw_qpolynomial_fold_fold(top_pwf_tight,
-							bound->pwf_tight);
+	isl_bound_add(bound, top_pwf);
+	isl_bound_add_tight(bound, top_pwf_tight);
 
 	return r;
 error:
@@ -105,6 +172,24 @@
 	return isl_stat_error;
 }
 
+/* Update bound->pwf and bound->pwf_tight with a bound
+ * of type bound->type on the polynomial "poly" over the domain "bset".
+ *
+ * If the original problem had a wrapped relation in the domain,
+ * meaning that the bound should be computed over the range
+ * of this relation, then temporarily treat the domain dimensions
+ * of this wrapped relation as parameters, compute a bound
+ * in terms of these and the original parameters,
+ * turn the parameters back into set dimensions and
+ * add the results to bound->pwf and bound->pwf_tight.
+ *
+ * Note that even though "bset" is known to live in the same space
+ * as the domain of "poly", the names of the set dimensions
+ * may be different (or missing).  Make sure the naming is exactly
+ * the same before turning these dimensions into parameters
+ * to ensure that the spaces are still the same after
+ * this operation.
+ */
 static isl_stat guarded_poly_bound(__isl_take isl_basic_set *bset,
 	__isl_take isl_qpolynomial *poly, void *user)
 {
@@ -124,6 +209,9 @@
 	if (nparam < 0 || n_in < 0)
 		goto error;
 
+	space = isl_qpolynomial_get_domain_space(poly);
+	bset = isl_basic_set_reset_space(bset, space);
+
 	bset = isl_basic_set_move_dims(bset, isl_dim_param, nparam,
 					isl_dim_set, 0, n_in);
 	poly = isl_qpolynomial_move_dims(poly, isl_dim_param, nparam,
@@ -148,9 +236,8 @@
 	bound->pwf_tight = isl_pw_qpolynomial_fold_reset_space(bound->pwf_tight,
 						    isl_space_copy(bound->dim));
 
-	bound->pwf = isl_pw_qpolynomial_fold_fold(top_pwf, bound->pwf);
-	bound->pwf_tight = isl_pw_qpolynomial_fold_fold(top_pwf_tight,
-							bound->pwf_tight);
+	isl_bound_add(bound, top_pwf);
+	isl_bound_add_tight(bound, top_pwf_tight);
 
 	return r;
 error:
diff --git a/lib/External/isl/isl_bound.h b/lib/External/isl/isl_bound.h
index 1a9d390..13a5813 100644
--- a/lib/External/isl/isl_bound.h
+++ b/lib/External/isl/isl_bound.h
@@ -17,4 +17,13 @@
 	isl_pw_qpolynomial_fold *pwf_tight;
 };
 
+__isl_give isl_pw_qpolynomial_fold *isl_qpolynomial_cst_bound(
+	__isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly,
+	enum isl_fold type, isl_bool *tight);
+
+isl_stat isl_bound_add(struct isl_bound *bound,
+	__isl_take isl_pw_qpolynomial_fold *pwf);
+isl_stat isl_bound_add_tight(struct isl_bound *bound,
+	__isl_take isl_pw_qpolynomial_fold *pwf);
+
 #endif
diff --git a/lib/External/isl/isl_convex_hull.c b/lib/External/isl/isl_convex_hull.c
index 44e4ae7..a15092e 100644
--- a/lib/External/isl/isl_convex_hull.c
+++ b/lib/External/isl/isl_convex_hull.c
@@ -2618,6 +2618,7 @@
 
 	bmap1 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap1);
 	bmap2 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap2);
+	bmap1 = isl_basic_map_order_divs(bmap1);
 	bmap2 = isl_basic_map_align_divs(bmap2, bmap1);
 	bmap1 = isl_basic_map_align_divs(bmap1, bmap2);
 	bmap1 = isl_basic_map_sort_constraints(bmap1);
diff --git a/lib/External/isl/isl_copy_tuple_id_templ.c b/lib/External/isl/isl_copy_tuple_id_templ.c
new file mode 100644
index 0000000..5345ab3
--- /dev/null
+++ b/lib/External/isl/isl_copy_tuple_id_templ.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019      Cerebras Systems
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
+ */
+
+#define xFN(TYPE,NAME) TYPE ## _ ## NAME
+#define FN(TYPE,NAME) xFN(TYPE,NAME)
+
+/* Copy the identifier of tuple "src_type" in "src"
+ * to that of "dst_type" in "dst", if there is any such identifier.
+ */
+__isl_give TYPE *FN(TYPE,copy_tuple_id)(__isl_take TYPE *dst,
+	enum isl_dim_type dst_type, __isl_keep isl_space *src,
+	enum isl_dim_type src_type)
+{
+	isl_bool has_id;
+	isl_id *id;
+
+	has_id = isl_space_has_tuple_id(src, src_type);
+	if (has_id < 0)
+		return FN(TYPE,free)(dst);
+	if (!has_id)
+		return dst;
+
+	id = isl_space_get_tuple_id(src, src_type);
+	dst = FN(TYPE,set_tuple_id)(dst, dst_type, id);
+
+	return dst;
+}
diff --git a/lib/External/isl/isl_fold.c b/lib/External/isl/isl_fold.c
index aaa1b72..2d7f85c 100644
--- a/lib/External/isl/isl_fold.c
+++ b/lib/External/isl/isl_fold.c
@@ -41,30 +41,33 @@
 	isl_die(NULL, isl_error_internal, "unhandled isl_fold type", abort());
 }
 
+/* Construct a new reduction with the given type, domain space and
+ * list of polynomials.
+ */
 static __isl_give isl_qpolynomial_fold *qpolynomial_fold_alloc(
-	enum isl_fold type, __isl_take isl_space *space, int n)
+	enum isl_fold type, __isl_take isl_space *space,
+	__isl_take isl_qpolynomial_list *list)
 {
+	isl_ctx *ctx;
 	isl_qpolynomial_fold *fold;
 
-	if (!space)
+	if (type < 0 || !space || !list)
 		goto error;
 
-	isl_assert(space->ctx, n >= 0, goto error);
-	fold = isl_calloc(space->ctx, struct isl_qpolynomial_fold,
-			sizeof(struct isl_qpolynomial_fold) +
-			(n - 1) * sizeof(struct isl_qpolynomial *));
+	ctx = isl_space_get_ctx(space);
+	fold = isl_calloc_type(ctx, struct isl_qpolynomial_fold);
 	if (!fold)
 		goto error;
 
 	fold->ref = 1;
-	fold->size = n;
-	fold->n = 0;
 	fold->type = type;
 	fold->dim = space;
+	fold->list = list;
 
 	return fold;
 error:
 	isl_space_free(space);
+	isl_qpolynomial_list_free(list);
 	return NULL;
 }
 
@@ -73,10 +76,72 @@
 	return fold ? fold->dim->ctx : NULL;
 }
 
+/* Return the domain space of "fold".
+ */
+static __isl_keep isl_space *isl_qpolynomial_fold_peek_domain_space(
+	__isl_keep isl_qpolynomial_fold *fold)
+{
+	return fold ? fold->dim : NULL;
+}
+
 __isl_give isl_space *isl_qpolynomial_fold_get_domain_space(
 	__isl_keep isl_qpolynomial_fold *fold)
 {
-	return fold ? isl_space_copy(fold->dim) : NULL;
+	return isl_space_copy(isl_qpolynomial_fold_peek_domain_space(fold));
+}
+
+/* Return the space of the domain of "fold".
+ * This may be either a copy or the space itself
+ * if there is only one reference to "fold".
+ * This allows the space to be modified inplace
+ * if both the expression and its space have only a single reference.
+ * The caller is not allowed to modify "fold" between this call and
+ * a subsequent call to isl_qpolynomial_fold_restore_domain_space.
+ * The only exception is that isl_qpolynomial_fold_free can be called instead.
+ */
+static __isl_give isl_space *isl_qpolynomial_fold_take_domain_space(
+	__isl_keep isl_qpolynomial_fold *fold)
+{
+	isl_space *space;
+
+	if (!fold)
+		return NULL;
+	if (fold->ref != 1)
+		return isl_qpolynomial_fold_get_domain_space(fold);
+	space = fold->dim;
+	fold->dim = NULL;
+	return space;
+}
+
+/* Set the space of the domain of "fold" to "space",
+ * where the space of "fold" may be missing
+ * due to a preceding call to isl_qpolynomial_fold_take_domain_space.
+ * However, in this case, "fold" only has a single reference and
+ * then the call to isl_qpolynomial_fold_cow has no effect.
+ */
+static
+__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_restore_domain_space(
+	__isl_keep isl_qpolynomial_fold *fold, __isl_take isl_space *space)
+{
+	if (!fold || !space)
+		goto error;
+
+	if (fold->dim == space) {
+		isl_space_free(space);
+		return fold;
+	}
+
+	fold = isl_qpolynomial_fold_cow(fold);
+	if (!fold)
+		goto error;
+	isl_space_free(fold->dim);
+	fold->dim = space;
+
+	return fold;
+error:
+	isl_qpolynomial_fold_free(fold);
+	isl_space_free(space);
+	return NULL;
 }
 
 __isl_give isl_space *isl_qpolynomial_fold_get_space(
@@ -91,32 +156,107 @@
 	return space;
 }
 
-__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_domain_space(
-	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space)
+/* Return the list of polynomials in the reduction "fold".
+ */
+__isl_keep isl_qpolynomial_list *isl_qpolynomial_fold_peek_list(
+	__isl_keep isl_qpolynomial_fold *fold)
 {
-	int i;
+	return fold ? fold->list : NULL;
+}
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold || !space)
+/* Return a copy of the list of polynomials in the reduction "fold".
+ */
+static __isl_give isl_qpolynomial_list *isl_qpolynomial_fold_get_list(
+	__isl_keep isl_qpolynomial_fold *fold)
+{
+	return isl_qpolynomial_list_copy(isl_qpolynomial_fold_peek_list(fold));
+}
+
+/* Return the list of polynomials of "fold".
+ * This may be either a copy or the list itself
+ * if there is only one reference to "fold".
+ * This allows the list to be modified inplace
+ * if both the expression and its list have only a single reference.
+ * The caller is not allowed to modify "fold" between this call and
+ * a subsequent call to isl_qpolynomial_fold_restore_list.
+ * The only exception is that isl_qpolynomial_fold_free can be called instead.
+ */
+static __isl_give isl_qpolynomial_list *isl_qpolynomial_fold_take_list(
+	__isl_keep isl_qpolynomial_fold *fold)
+{
+	isl_qpolynomial_list *list;
+
+	if (!fold)
+		return NULL;
+	if (fold->ref != 1)
+		return isl_qpolynomial_fold_get_list(fold);
+	list = fold->list;
+	fold->list = NULL;
+	return list;
+}
+
+/* Set the space of the list of polynomials of "fold" to "space",
+ * where the list of polynomials of "fold" may be missing
+ * due to a preceding call to isl_qpolynomial_fold_take_list.
+ * However, in this case, "fold" only has a single reference and
+ * then the call to isl_qpolynomial_fold_cow has no effect.
+ */
+static __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_restore_list(
+	__isl_keep isl_qpolynomial_fold *fold,
+	__isl_take isl_qpolynomial_list *list)
+{
+	if (!fold || !list)
 		goto error;
 
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_reset_domain_space(fold->qp[i],
-							isl_space_copy(space));
-		if (!fold->qp[i])
-			goto error;
+	if (fold->list == list) {
+		isl_qpolynomial_list_free(list);
+		return fold;
 	}
 
-	isl_space_free(fold->dim);
-	fold->dim = space;
+	fold = isl_qpolynomial_fold_cow(fold);
+	if (!fold)
+		goto error;
+	isl_qpolynomial_list_free(fold->list);
+	fold->list = list;
 
 	return fold;
 error:
 	isl_qpolynomial_fold_free(fold);
-	isl_space_free(space);
+	isl_qpolynomial_list_free(list);
 	return NULL;
 }
 
+/* isl_qpolynomial_list_map callback that calls
+ * isl_qpolynomial_reset_domain_space on "qp".
+ */
+static __isl_give isl_qpolynomial *reset_domain_space(
+	__isl_take isl_qpolynomial *qp, void *user)
+{
+	isl_space *space = user;
+
+	return isl_qpolynomial_reset_domain_space(qp, isl_space_copy(space));
+}
+
+/* Replace the domain space of "fold" by "space".
+ *
+ * Replace the domain space itself and that of all polynomials
+ * in the list.
+ */
+__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_domain_space(
+	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space)
+{
+	isl_qpolynomial_list *list;
+
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &reset_domain_space, space);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
+
+	isl_space_free(isl_qpolynomial_fold_take_domain_space(fold));
+	fold = isl_qpolynomial_fold_restore_domain_space(fold, space);
+
+	return fold;
+}
+
 /* Reset the space of "fold".  This function is called from isl_pw_templ.c
  * and doesn't know if the space of an element object is represented
  * directly or through its domain.  It therefore passes along both.
@@ -129,49 +269,71 @@
 	return isl_qpolynomial_fold_reset_domain_space(fold, domain);
 }
 
-int isl_qpolynomial_fold_involves_dims(__isl_keep isl_qpolynomial_fold *fold,
-	enum isl_dim_type type, unsigned first, unsigned n)
+/* Internal data structure for isl_qpolynomial_fold_*_dims
+ * representing their arguments.
+ */
+struct isl_fold_dims_data {
+	enum isl_dim_type type;
+	unsigned first;
+	unsigned n;
+};
+
+/* isl_qpolynomial_list_every callback that checks whether "qp"
+ * does not involve any dimensions in the given range.
+ */
+static isl_bool not_involved(__isl_keep isl_qpolynomial *qp, void *user)
 {
-	int i;
+	struct isl_fold_dims_data *data = user;
+	isl_bool involves;
 
-	if (!fold)
-		return -1;
-	if (fold->n == 0 || n == 0)
-		return 0;
-
-	for (i = 0; i < fold->n; ++i) {
-		int involves = isl_qpolynomial_involves_dims(fold->qp[i],
-							    type, first, n);
-		if (involves < 0 || involves)
-			return involves;
-	}
-	return 0;
+	involves = isl_qpolynomial_involves_dims(qp, data->type,
+							data->first, data->n);
+	return isl_bool_not(involves);
 }
 
-__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_set_dim_name(
-	__isl_take isl_qpolynomial_fold *fold,
-	enum isl_dim_type type, unsigned pos, const char *s)
+/* Does "fold" involve any dimensions in the given range.
+ *
+ * It involves any of those dimensions if it is not the case
+ * that every polynomial in the reduction does not involve
+ * any of the dimensions.
+ */
+static isl_bool isl_qpolynomial_fold_involves_dims(
+	__isl_keep isl_qpolynomial_fold *fold,
+	enum isl_dim_type type, unsigned first, unsigned n)
 {
-	int i;
+	struct isl_fold_dims_data data = { type, first, n };
+	isl_qpolynomial_list *list;
+	isl_bool not;
 
-	fold = isl_qpolynomial_fold_cow(fold);
 	if (!fold)
-		return NULL;
-	fold->dim = isl_space_set_dim_name(fold->dim, type, pos, s);
-	if (!fold->dim)
-		goto error;
+		return isl_bool_error;
+	if (n == 0)
+		return isl_bool_false;
 
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_set_dim_name(fold->qp[i],
-							    type, pos, s);
-		if (!fold->qp[i])
-			goto error;
-	}
+	list = isl_qpolynomial_fold_peek_list(fold);
+	not = isl_qpolynomial_list_every(list, &not_involved, &data);
+	return isl_bool_not(not);
+}
 
-	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
+/* Internal data structure for isl_qpolynomial_fold_set_dim_name
+ * representing its arguments.
+ */
+struct isl_fold_set_dim_name_data {
+	enum isl_dim_type type;
+	unsigned pos;
+	const char *s;
+};
+
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_set_dim_name on "qp".
+ */
+static __isl_give isl_qpolynomial *set_dim_name(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	struct isl_fold_set_dim_name_data *data = user;
+
+	qp = isl_qpolynomial_set_dim_name(qp, data->type, data->pos, data->s);
+	return qp;
 }
 
 /* Given a dimension type for an isl_qpolynomial_fold,
@@ -184,12 +346,47 @@
 	return type;
 }
 
+__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_set_dim_name(
+	__isl_take isl_qpolynomial_fold *fold,
+	enum isl_dim_type type, unsigned pos, const char *s)
+{
+	struct isl_fold_set_dim_name_data data = { type, pos, s };
+	enum isl_dim_type set_type;
+	isl_space *space;
+	isl_qpolynomial_list *list;
+
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &set_dim_name, &data);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
+
+	set_type = domain_type(type);
+	space = isl_qpolynomial_fold_take_domain_space(fold);
+	space = isl_space_set_dim_name(space, set_type, pos, s);
+	fold = isl_qpolynomial_fold_restore_domain_space(fold, space);
+
+	return fold;
+}
+
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_drop_dims on "qp".
+ */
+static __isl_give isl_qpolynomial *drop_dims(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	struct isl_fold_dims_data *data = user;
+
+	qp = isl_qpolynomial_drop_dims(qp, data->type, data->first, data->n);
+	return qp;
+}
+
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_drop_dims(
 	__isl_take isl_qpolynomial_fold *fold,
 	enum isl_dim_type type, unsigned first, unsigned n)
 {
-	int i;
+	struct isl_fold_dims_data data = { type, first, n };
 	enum isl_dim_type set_type;
+	isl_space *space;
+	isl_qpolynomial_list *list;
 
 	if (!fold)
 		return NULL;
@@ -198,55 +395,53 @@
 
 	set_type = domain_type(type);
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		return NULL;
-	fold->dim = isl_space_drop_dims(fold->dim, set_type, first, n);
-	if (!fold->dim)
-		goto error;
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &drop_dims, &data);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_drop_dims(fold->qp[i],
-							    type, first, n);
-		if (!fold->qp[i])
-			goto error;
-	}
+	space = isl_qpolynomial_fold_take_domain_space(fold);
+	space = isl_space_drop_dims(space, set_type, first, n);
+	fold = isl_qpolynomial_fold_restore_domain_space(fold, space);
 
 	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
+}
+
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_insert_dims on "qp".
+ */
+static __isl_give isl_qpolynomial *insert_dims(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	struct isl_fold_dims_data *data = user;
+
+	qp = isl_qpolynomial_insert_dims(qp, data->type, data->first, data->n);
+	return qp;
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_insert_dims(
 	__isl_take isl_qpolynomial_fold *fold,
 	enum isl_dim_type type, unsigned first, unsigned n)
 {
-	int i;
+	struct isl_fold_dims_data data = { type, first, n };
+	enum isl_dim_type set_type;
+	isl_space *space;
+	isl_qpolynomial_list *list;
 
 	if (!fold)
 		return NULL;
 	if (n == 0 && !isl_space_is_named_or_nested(fold->dim, type))
 		return fold;
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		return NULL;
-	fold->dim = isl_space_insert_dims(fold->dim, type, first, n);
-	if (!fold->dim)
-		goto error;
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &insert_dims, &data);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_insert_dims(fold->qp[i],
-							    type, first, n);
-		if (!fold->qp[i])
-			goto error;
-	}
+	set_type = domain_type(type);
+	space = isl_qpolynomial_fold_take_domain_space(fold);
+	space = isl_space_insert_dims(space, set_type, first, n);
+	fold = isl_qpolynomial_fold_restore_domain_space(fold, space);
 
 	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
 }
 
 /* Determine the sign of the constant quasipolynomial "qp".
@@ -423,6 +618,101 @@
 	return sgn;
 }
 
+/* Check that "fold1" and "fold2" have the same type.
+ */
+static isl_stat isl_qpolynomial_fold_check_equal_type(
+	__isl_keep isl_qpolynomial_fold *fold1,
+	__isl_keep isl_qpolynomial_fold *fold2)
+{
+	enum isl_fold type1, type2;
+
+	type1 = isl_qpolynomial_fold_get_type(fold1);
+	type2 = isl_qpolynomial_fold_get_type(fold2);
+	if (type1 < 0 || type2 < 0)
+		return isl_stat_error;
+	if (type1 != type2)
+		isl_die(isl_qpolynomial_fold_get_ctx(fold1), isl_error_invalid,
+			"fold types don't match", return isl_stat_error);
+	return isl_stat_ok;
+}
+
+/* Check that "fold1" and "fold2" have the same (domain) space.
+ */
+static isl_stat isl_qpolynomial_fold_check_equal_space(
+	__isl_keep isl_qpolynomial_fold *fold1,
+	__isl_keep isl_qpolynomial_fold *fold2)
+{
+	isl_bool equal;
+	isl_space *space1, *space2;
+
+	space1 = isl_qpolynomial_fold_peek_domain_space(fold1);
+	space2 = isl_qpolynomial_fold_peek_domain_space(fold2);
+	equal = isl_space_is_equal(space1, space2);
+	if (equal < 0)
+		return isl_stat_error;
+	if (!equal)
+		isl_die(isl_qpolynomial_fold_get_ctx(fold1), isl_error_invalid,
+			"spaces don't match", return isl_stat_error);
+	return isl_stat_ok;
+}
+
+/* Combine "list1" and "list2" into a single list, eliminating
+ * those elements of one list that are already covered by the other
+ * list on "set".
+ *
+ * "better" is the sign that the difference qp1 - qp2 needs to have for qp1
+ * to be covered by qp2.
+ */
+static __isl_give isl_qpolynomial_list *merge_lists(__isl_keep isl_set *set,
+	__isl_take isl_qpolynomial_list *list1,
+	__isl_take isl_qpolynomial_list *list2, int better)
+{
+	int i, j;
+	isl_size n1, n2;
+
+	n1 = isl_qpolynomial_list_size(list1);
+	n2 = isl_qpolynomial_list_size(list2);
+	if (n1 < 0 || n2 < 0)
+		goto error;
+
+	for (i = n2 - 1; i >= 0; --i) {
+		for (j = n1 - 1; j >= 0; --j) {
+			isl_qpolynomial *qp1, *qp2, *d;
+			int sgn;
+			isl_bool equal;
+
+			qp1 = isl_qpolynomial_list_peek(list1, j);
+			qp2 = isl_qpolynomial_list_peek(list2, i);
+			equal = isl_qpolynomial_plain_is_equal(qp1, qp2);
+			if (equal < 0)
+				goto error;
+			if (equal)
+				break;
+			d = isl_qpolynomial_sub(
+				isl_qpolynomial_copy(qp1),
+				isl_qpolynomial_copy(qp2));
+			sgn = isl_qpolynomial_sign(set, d);
+			isl_qpolynomial_free(d);
+			if (sgn == 0)
+				continue;
+			if (sgn != better)
+				break;
+			list1 = isl_qpolynomial_list_drop(list1, j, 1);
+			n1--;
+		}
+		if (j < 0)
+			continue;
+		list2 = isl_qpolynomial_list_drop(list2, i, 1);
+		n2--;
+	}
+
+	return isl_qpolynomial_list_concat(list1, list2);
+error:
+	isl_qpolynomial_list_free(list1);
+	isl_qpolynomial_list_free(list2);
+	return NULL;
+}
+
 /* Combine "fold1" and "fold2" into a single reduction, eliminating
  * those elements of one reduction that are already covered by the other
  * reduction on "set".
@@ -436,17 +726,14 @@
 	__isl_take isl_qpolynomial_fold *fold1,
 	__isl_take isl_qpolynomial_fold *fold2)
 {
-	int i, j;
-	int n1;
-	struct isl_qpolynomial_fold *res = NULL;
+	isl_qpolynomial_list *list1;
+	isl_qpolynomial_list *list2;
 	int better;
 
-	if (!fold1 || !fold2)
+	if (isl_qpolynomial_fold_check_equal_type(fold1, fold2) < 0)
 		goto error;
-
-	isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error);
-	isl_assert(fold1->dim->ctx, isl_space_is_equal(fold1->dim, fold2->dim),
-			goto error);
+	if (isl_qpolynomial_fold_check_equal_space(fold1, fold2) < 0)
+		goto error;
 
 	better = fold1->type == isl_fold_max ? -1 : 1;
 
@@ -462,69 +749,35 @@
 		return fold1;
 	}
 
-	res = qpolynomial_fold_alloc(fold1->type, isl_space_copy(fold1->dim),
-					fold1->n + fold2->n);
-	if (!res)
-		goto error;
+	list1 = isl_qpolynomial_fold_take_list(fold1);
+	list2 = isl_qpolynomial_fold_take_list(fold2);
 
-	for (i = 0; i < fold1->n; ++i) {
-		res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
-		if (!res->qp[res->n])
-			goto error;
-		res->n++;
-	}
-	n1 = res->n;
+	list1 = merge_lists(set, list1, list2, better);
 
-	for (i = 0; i < fold2->n; ++i) {
-		for (j = n1 - 1; j >= 0; --j) {
-			isl_qpolynomial *d;
-			int sgn, equal;
-			equal = isl_qpolynomial_plain_is_equal(res->qp[j],
-								fold2->qp[i]);
-			if (equal < 0)
-				goto error;
-			if (equal)
-				break;
-			d = isl_qpolynomial_sub(
-				isl_qpolynomial_copy(res->qp[j]),
-				isl_qpolynomial_copy(fold2->qp[i]));
-			sgn = isl_qpolynomial_sign(set, d);
-			isl_qpolynomial_free(d);
-			if (sgn == 0)
-				continue;
-			if (sgn != better)
-				break;
-			isl_qpolynomial_free(res->qp[j]);
-			if (j != n1 - 1)
-				res->qp[j] = res->qp[n1 - 1];
-			n1--;
-			if (n1 != res->n - 1)
-				res->qp[n1] = res->qp[res->n - 1];
-			res->n--;
-		}
-		if (j >= 0)
-			continue;
-		res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
-		if (!res->qp[res->n])
-			goto error;
-		res->n++;
-	}
-
-	isl_qpolynomial_fold_free(fold1);
+	fold1 = isl_qpolynomial_fold_restore_list(fold1, list1);
 	isl_qpolynomial_fold_free(fold2);
 
-	return res;
+	return fold1;
 error:
-	isl_qpolynomial_fold_free(res);
 	isl_qpolynomial_fold_free(fold1);
 	isl_qpolynomial_fold_free(fold2);
 	return NULL;
 }
 
+/* isl_qpolynomial_list_map callback for adding "qp2" to "qp".
+ */
+static __isl_give isl_qpolynomial *add_qpolynomial(
+	__isl_take isl_qpolynomial *qp, void *user)
+{
+	isl_qpolynomial *qp2 = user;
+
+	return isl_qpolynomial_add(qp, isl_qpolynomial_copy(qp2));
+}
+
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_qpolynomial(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_qpolynomial *qp)
 {
-	int i;
+	isl_qpolynomial_list *list;
 
 	if (!fold || !qp)
 		goto error;
@@ -534,16 +787,9 @@
 		return fold;
 	}
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		goto error;
-
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_add(fold->qp[i],
-						isl_qpolynomial_copy(qp));
-		if (!fold->qp[i])
-			goto error;
-	}
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &add_qpolynomial, qp);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
 	isl_qpolynomial_free(qp);
 	return fold;
@@ -559,7 +805,10 @@
 	__isl_take isl_qpolynomial_fold *fold2)
 {
 	int i;
+	isl_size n1, n2;
 	isl_qpolynomial_fold *res = NULL;
+	isl_qpolynomial *qp;
+	isl_qpolynomial_list *list1, *list2;
 
 	if (!fold1 || !fold2)
 		goto error;
@@ -574,25 +823,32 @@
 		return fold1;
 	}
 
-	if (fold1->n == 1 && fold2->n != 1)
+	list1 = isl_qpolynomial_fold_peek_list(fold1);
+	list2 = isl_qpolynomial_fold_peek_list(fold2);
+	n1 = isl_qpolynomial_list_size(list1);
+	n2 = isl_qpolynomial_list_size(list2);
+	if (n1 < 0 || n2 < 0)
+		goto error;
+
+	if (n1 == 1 && n2 != 1)
 		return isl_qpolynomial_fold_add_on_domain(dom, fold2, fold1);
 
-	if (fold2->n == 1) {
-		res = isl_qpolynomial_fold_add_qpolynomial(fold1,
-					isl_qpolynomial_copy(fold2->qp[0]));
+	qp = isl_qpolynomial_list_get_at(list2, 0);
+	if (n2 == 1) {
+		res = isl_qpolynomial_fold_add_qpolynomial(fold1, qp);
 		isl_qpolynomial_fold_free(fold2);
 		return res;
 	}
 
 	res = isl_qpolynomial_fold_add_qpolynomial(
-				isl_qpolynomial_fold_copy(fold1),
-				isl_qpolynomial_copy(fold2->qp[0]));
+				isl_qpolynomial_fold_copy(fold1), qp);
 
-	for (i = 1; i < fold2->n; ++i) {
+	for (i = 1; i < n2; ++i) {
 		isl_qpolynomial_fold *res_i;
+
+		qp = isl_qpolynomial_list_get_at(list2, i);
 		res_i = isl_qpolynomial_fold_add_qpolynomial(
-					isl_qpolynomial_fold_copy(fold1),
-					isl_qpolynomial_copy(fold2->qp[i]));
+					isl_qpolynomial_fold_copy(fold1), qp);
 		res = isl_qpolynomial_fold_fold_on_domain(dom, res, res_i);
 	}
 
@@ -606,58 +862,53 @@
 	return NULL;
 }
 
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_substitute_equalities on "qp" and "eq".
+ */
+static __isl_give isl_qpolynomial *substitute_equalities(
+	__isl_take isl_qpolynomial *qp, void *user)
+{
+	isl_basic_set *eq = user;
+
+	eq = isl_basic_set_copy(eq);
+	return isl_qpolynomial_substitute_equalities(qp, eq);
+}
+
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute_equalities(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_basic_set *eq)
 {
-	int i;
+	isl_qpolynomial_list *list;
 
-	if (!fold || !eq)
-		goto error;
-
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		return NULL;
-
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_substitute_equalities(fold->qp[i],
-							isl_basic_set_copy(eq));
-		if (!fold->qp[i])
-			goto error;
-	}
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &substitute_equalities, eq);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
 	isl_basic_set_free(eq);
 	return fold;
-error:
-	isl_basic_set_free(eq);
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
+}
+
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_substitute_equalities on "qp" and "context".
+ */
+static __isl_give isl_qpolynomial *gist(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	isl_set *context = user;
+
+	return isl_qpolynomial_gist(qp, isl_set_copy(context));
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *context)
 {
-	int i;
+	isl_qpolynomial_list *list;
 
-	if (!fold || !context)
-		goto error;
-
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		return NULL;
-
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_gist(fold->qp[i],
-							isl_set_copy(context));
-		if (!fold->qp[i])
-			goto error;
-	}
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &gist, context);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
 	isl_set_free(context);
 	return fold;
-error:
-	isl_set_free(context);
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params(
@@ -715,32 +966,34 @@
 #include <isl_union_single.c>
 #include <isl_union_eval.c>
 
+/* Construct a new reduction of the given type and space
+ * with an empty list of polynomials.
+ */
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type,
 	__isl_take isl_space *space)
 {
-	return qpolynomial_fold_alloc(type, space, 0);
+	isl_ctx *ctx;
+	isl_qpolynomial_list *list;
+
+	if (!space)
+		return NULL;
+	ctx = isl_space_get_ctx(space);
+	list = isl_qpolynomial_list_alloc(ctx, 0);
+	return qpolynomial_fold_alloc(type, space, list);
 }
 
+/* Construct a new reduction of the given type and
+ * a single given polynomial.
+ */
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc(
 	enum isl_fold type, __isl_take isl_qpolynomial *qp)
 {
-	isl_qpolynomial_fold *fold;
+	isl_space *space;
+	isl_qpolynomial_list *list;
 
-	if (!qp)
-		return NULL;
-
-	fold = qpolynomial_fold_alloc(type, isl_space_copy(qp->dim), 1);
-	if (!fold)
-		goto error;
-
-	fold->qp[0] = qp;
-	fold->n++;
-
-	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	isl_qpolynomial_free(qp);
-	return NULL;
+	space = isl_qpolynomial_get_domain_space(qp);
+	list = isl_qpolynomial_list_from_qpolynomial(qp);
+	return qpolynomial_fold_alloc(type, space, list);
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy(
@@ -756,27 +1009,14 @@
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup(
 	__isl_keep isl_qpolynomial_fold *fold)
 {
-	int i;
-	isl_qpolynomial_fold *dup;
+	enum isl_fold type;
+	isl_space *space;
+	isl_qpolynomial_list *list;
 
-	if (!fold)
-		return NULL;
-	dup = qpolynomial_fold_alloc(fold->type,
-					isl_space_copy(fold->dim), fold->n);
-	if (!dup)
-		return NULL;
-	
-	dup->n = fold->n;
-	for (i = 0; i < fold->n; ++i) {
-		dup->qp[i] = isl_qpolynomial_copy(fold->qp[i]);
-		if (!dup->qp[i])
-			goto error;
-	}
-
-	return dup;
-error:
-	isl_qpolynomial_fold_free(dup);
-	return NULL;
+	type = isl_qpolynomial_fold_get_type(fold);
+	space = isl_qpolynomial_fold_get_domain_space(fold);
+	list = isl_qpolynomial_fold_get_list(fold);
+	return qpolynomial_fold_alloc(type, space, list);
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_cow(
@@ -794,15 +1034,12 @@
 __isl_null isl_qpolynomial_fold *isl_qpolynomial_fold_free(
 	__isl_take isl_qpolynomial_fold *fold)
 {
-	int i;
-
 	if (!fold)
 		return NULL;
 	if (--fold->ref > 0)
 		return NULL;
 
-	for (i = 0; i < fold->n; ++i)
-		isl_qpolynomial_free(fold->qp[i]);
+	isl_qpolynomial_list_free(fold->list);
 	isl_space_free(fold->dim);
 	free(fold);
 
@@ -811,36 +1048,45 @@
 
 isl_bool isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold)
 {
-	if (!fold)
+	isl_size n;
+	isl_qpolynomial_list *list;
+
+	list = isl_qpolynomial_fold_peek_list(fold);
+	n = isl_qpolynomial_list_size(list);
+	if (n < 0)
 		return isl_bool_error;
 
-	return isl_bool_ok(fold->n == 0);
+	return isl_bool_ok(n == 0);
 }
 
 /* Does "fold" represent max(NaN) or min(NaN)?
  */
 isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold)
 {
-	if (!fold)
+	isl_size n;
+	isl_qpolynomial *qp;
+	isl_qpolynomial_list *list;
+
+	list = isl_qpolynomial_fold_peek_list(fold);
+	n = isl_qpolynomial_list_size(list);
+	if (n < 0)
 		return isl_bool_error;
-	if (fold->n != 1)
+	if (n != 1)
 		return isl_bool_false;
-	return isl_qpolynomial_is_nan(fold->qp[0]);
+	qp = isl_qpolynomial_list_peek(list, 0);
+	return isl_qpolynomial_is_nan(qp);
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold(
 	__isl_take isl_qpolynomial_fold *fold1,
 	__isl_take isl_qpolynomial_fold *fold2)
 {
-	int i;
-	struct isl_qpolynomial_fold *res = NULL;
+	isl_qpolynomial_list *list1, *list2;
 
-	if (!fold1 || !fold2)
+	if (isl_qpolynomial_fold_check_equal_type(fold1, fold2) < 0)
 		goto error;
-
-	isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error);
-	isl_assert(fold1->dim->ctx, isl_space_is_equal(fold1->dim, fold2->dim),
-			goto error);
+	if (isl_qpolynomial_fold_check_equal_space(fold1, fold2) < 0)
+		goto error;
 
 	if (isl_qpolynomial_fold_is_empty(fold1)) {
 		isl_qpolynomial_fold_free(fold1);
@@ -852,31 +1098,14 @@
 		return fold1;
 	}
 
-	res = qpolynomial_fold_alloc(fold1->type, isl_space_copy(fold1->dim),
-					fold1->n + fold2->n);
-	if (!res)
-		goto error;
-
-	for (i = 0; i < fold1->n; ++i) {
-		res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
-		if (!res->qp[res->n])
-			goto error;
-		res->n++;
-	}
-
-	for (i = 0; i < fold2->n; ++i) {
-		res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
-		if (!res->qp[res->n])
-			goto error;
-		res->n++;
-	}
-
-	isl_qpolynomial_fold_free(fold1);
+	list1 = isl_qpolynomial_fold_take_list(fold1);
+	list2 = isl_qpolynomial_fold_take_list(fold2);
+	list1 = isl_qpolynomial_list_concat(list1, list2);
+	fold1 = isl_qpolynomial_fold_restore_list(fold1, list1);
 	isl_qpolynomial_fold_free(fold2);
 
-	return res;
+	return fold1;
 error:
-	isl_qpolynomial_fold_free(res);
 	isl_qpolynomial_fold_free(fold1);
 	isl_qpolynomial_fold_free(fold2);
 	return NULL;
@@ -1060,21 +1289,30 @@
 	__isl_keep isl_qpolynomial_fold *fold2)
 {
 	int i;
+	isl_size n1, n2;
+	isl_qpolynomial_list *list1, *list2;
 
 	if (fold1 == fold2)
 		return 0;
-	if (!fold1)
+	list1 = isl_qpolynomial_fold_peek_list(fold1);
+	list2 = isl_qpolynomial_fold_peek_list(fold2);
+	n1 = isl_qpolynomial_list_size(list1);
+	n2 = isl_qpolynomial_list_size(list2);
+	if (n1 < 0)
 		return -1;
-	if (!fold2)
+	if (n2 < 0)
 		return 1;
 
-	if (fold1->n != fold2->n)
-		return fold1->n - fold2->n;
+	if (n1 != n2)
+		return n1 - n2;
 
-	for (i = 0; i < fold1->n; ++i) {
+	for (i = 0; i < n1; ++i) {
 		int cmp;
+		isl_qpolynomial *qp1, *qp2;
 
-		cmp = isl_qpolynomial_plain_cmp(fold1->qp[i], fold2->qp[i]);
+		qp1 = isl_qpolynomial_list_peek(list1, i);
+		qp2 = isl_qpolynomial_list_peek(list2, i);
+		cmp = isl_qpolynomial_plain_cmp(qp1, qp2);
 		if (cmp != 0)
 			return cmp;
 	}
@@ -1082,32 +1320,73 @@
 	return 0;
 }
 
-int isl_qpolynomial_fold_plain_is_equal(__isl_keep isl_qpolynomial_fold *fold1,
-	__isl_keep isl_qpolynomial_fold *fold2)
+/* Are the lists "list1" and "list2", both consisting of "n" elements
+ * obviously equal to each other?
+ */
+static isl_bool isl_qpolynomial_list_plain_is_equal(unsigned n,
+	isl_qpolynomial_list *list1, isl_qpolynomial_list *list2)
 {
 	int i;
 
-	if (!fold1 || !fold2)
-		return -1;
+	for (i = 0; i < n; ++i) {
+		isl_bool eq;
+		isl_qpolynomial *qp1, *qp2;
 
-	if (fold1->n != fold2->n)
-		return 0;
-
-	/* We probably want to sort the qps first... */
-	for (i = 0; i < fold1->n; ++i) {
-		int eq = isl_qpolynomial_plain_is_equal(fold1->qp[i], fold2->qp[i]);
+		qp1 = isl_qpolynomial_list_peek(list1, i);
+		qp2 = isl_qpolynomial_list_peek(list2, i);
+		eq = isl_qpolynomial_plain_is_equal(qp1, qp2);
 		if (eq < 0 || !eq)
 			return eq;
 	}
 
-	return 1;
+	return isl_bool_true;
+}
+
+/* Wrapper around isl_qpolynomial_plain_cmp for use
+ * as a isl_qpolynomial_list_sort callback.
+ */
+static int qpolynomial_cmp(__isl_keep isl_qpolynomial *a,
+	__isl_keep isl_qpolynomial *b, void *user)
+{
+	return isl_qpolynomial_plain_cmp(a, b);
+}
+
+isl_bool isl_qpolynomial_fold_plain_is_equal(
+	__isl_keep isl_qpolynomial_fold *fold1,
+	__isl_keep isl_qpolynomial_fold *fold2)
+{
+	isl_bool equal;
+	isl_size n1, n2;
+	isl_qpolynomial_list *list1, *list2;
+
+	list1 = isl_qpolynomial_fold_peek_list(fold1);
+	list2 = isl_qpolynomial_fold_peek_list(fold2);
+	n1 = isl_qpolynomial_list_size(list1);
+	n2 = isl_qpolynomial_list_size(list2);
+	if (n1 < 0 || n2 < 0)
+		return isl_bool_error;
+
+	if (n1 != n2)
+		return isl_bool_false;
+
+	list1 = isl_qpolynomial_list_copy(list1);
+	list1 = isl_qpolynomial_list_sort(list1, &qpolynomial_cmp, NULL);
+	list2 = isl_qpolynomial_list_copy(list2);
+	list2 = isl_qpolynomial_list_sort(list2, &qpolynomial_cmp, NULL);
+	equal = isl_qpolynomial_list_plain_is_equal(n1, list1, list2);
+	isl_qpolynomial_list_free(list1);
+	isl_qpolynomial_list_free(list2);
+	return equal;
 }
 
 __isl_give isl_val *isl_qpolynomial_fold_eval(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt)
 {
+	isl_size n;
 	isl_ctx *ctx;
 	isl_val *v;
+	isl_qpolynomial *qp;
+	isl_qpolynomial_list *list;
 
 	if (!fold || !pnt)
 		goto error;
@@ -1117,17 +1396,23 @@
 		fold->type == isl_fold_max || fold->type == isl_fold_min,
 		goto error);
 
-	if (fold->n == 0)
+	list = isl_qpolynomial_fold_peek_list(fold);
+	n = isl_qpolynomial_list_size(list);
+	if (n < 0)
+		goto error;
+
+	if (n == 0)
 		v = isl_val_zero(ctx);
 	else {
 		int i;
-		v = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]),
-						isl_point_copy(pnt));
-		for (i = 1; i < fold->n; ++i) {
+
+		qp = isl_qpolynomial_list_get_at(list, 0);
+		v = isl_qpolynomial_eval(qp, isl_point_copy(pnt));
+		for (i = 1; i < n; ++i) {
 			isl_val *v_i;
-			v_i = isl_qpolynomial_eval(
-					    isl_qpolynomial_copy(fold->qp[i]),
-					    isl_point_copy(pnt));
+
+			qp = isl_qpolynomial_list_get_at(list, i);
+			v_i = isl_qpolynomial_eval(qp, isl_point_copy(pnt));
 			if (fold->type == isl_fold_max)
 				v = isl_val_max(v, v_i);
 			else
@@ -1149,8 +1434,17 @@
 	int i;
 	size_t n = 0;
 
-	for (i = 0; i < pwf->n; ++i)
-		n += pwf->p[i].fold->n;
+	for (i = 0; i < pwf->n; ++i) {
+		isl_size n_i;
+		isl_qpolynomial_list *list;
+
+		list = isl_qpolynomial_fold_peek_list(pwf->p[i].fold);
+		n_i = isl_qpolynomial_list_size(list);
+		if (n_i < 0)
+			return isl_size_error;
+
+		n += n_i;
+	}
 
 	return n;
 }
@@ -1159,24 +1453,30 @@
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *set, int max)
 {
 	int i;
+	isl_size n;
 	isl_val *opt;
+	isl_qpolynomial *qp;
+	isl_qpolynomial_list *list;
 
-	if (!set || !fold)
+	list = isl_qpolynomial_fold_peek_list(fold);
+	n = isl_qpolynomial_list_size(list);
+	if (!set || n < 0)
 		goto error;
 
-	if (fold->n == 0) {
+	if (n == 0) {
 		opt = isl_val_zero(isl_set_get_ctx(set));
 		isl_set_free(set);
 		isl_qpolynomial_fold_free(fold);
 		return opt;
 	}
 
-	opt = isl_qpolynomial_opt_on_domain(isl_qpolynomial_copy(fold->qp[0]),
-						isl_set_copy(set), max);
-	for (i = 1; i < fold->n; ++i) {
+	qp = isl_qpolynomial_list_get_at(list, 0);
+	opt = isl_qpolynomial_opt_on_domain(qp, isl_set_copy(set), max);
+	for (i = 1; i < n; ++i) {
 		isl_val *opt_i;
-		opt_i = isl_qpolynomial_opt_on_domain(
-				isl_qpolynomial_copy(fold->qp[i]),
+
+		qp = isl_qpolynomial_list_get_at(list, i);
+		opt_i = isl_qpolynomial_opt_on_domain(qp,
 				isl_set_copy(set), max);
 		if (max)
 			opt = isl_val_max(opt, opt_i);
@@ -1203,26 +1503,32 @@
 {
 	int i, j;
 	int covers;
+	isl_size n1, n2;
+	isl_qpolynomial_list *list1, *list2;
 
-	if (!set || !fold1 || !fold2)
+	list1 = isl_qpolynomial_fold_peek_list(fold1);
+	list2 = isl_qpolynomial_fold_peek_list(fold2);
+	n1 = isl_qpolynomial_list_size(list1);
+	n2 = isl_qpolynomial_list_size(list2);
+	if (!set || n1 < 0 || n2 < 0)
 		return isl_bool_error;
 
 	covers = fold1->type == isl_fold_max ? 1 : -1;
 
-	for (i = 0; i < fold2->n; ++i) {
-		for (j = 0; j < fold1->n; ++j) {
-			isl_qpolynomial *d;
+	for (i = 0; i < n2; ++i) {
+		for (j = 0; j < n1; ++j) {
+			isl_qpolynomial *qp1, *qp2, *d;
 			int sgn;
 
-			d = isl_qpolynomial_sub(
-				isl_qpolynomial_copy(fold1->qp[j]),
-				isl_qpolynomial_copy(fold2->qp[i]));
+			qp1 = isl_qpolynomial_list_get_at(list1, j);
+			qp2 = isl_qpolynomial_list_get_at(list2, i);
+			d = isl_qpolynomial_sub(qp1, qp2);
 			sgn = isl_qpolynomial_sign(set, d);
 			isl_qpolynomial_free(d);
 			if (sgn == covers)
 				break;
 		}
-		if (j >= fold1->n)
+		if (j >= n1)
 			return isl_bool_false;
 	}
 
@@ -1284,33 +1590,34 @@
 	return isl_bool_true;
 }
 
+/* isl_qpolynomial_list_map callback that calls
+ * isl_qpolynomial_morph_domain on "qp".
+ */
+static __isl_give isl_qpolynomial *morph_domain(
+	__isl_take isl_qpolynomial *qp, void *user)
+{
+	isl_morph *morph = user;
+
+	return isl_qpolynomial_morph_domain(qp, isl_morph_copy(morph));
+}
+
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_morph_domain(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_morph *morph)
 {
-	int i;
-	isl_ctx *ctx;
+	isl_space *space;
+	isl_qpolynomial_list *list;
 
-	if (!fold || !morph)
+	space = isl_qpolynomial_fold_peek_domain_space(fold);
+	if (isl_morph_check_applies(morph, space) < 0)
 		goto error;
 
-	ctx = fold->dim->ctx;
-	isl_assert(ctx, isl_space_is_equal(fold->dim, morph->dom->dim), goto error);
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &morph_domain, morph);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		goto error;
-
-	isl_space_free(fold->dim);
-	fold->dim = isl_space_copy(morph->ran->dim);
-	if (!fold->dim)
-		goto error;
-
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_morph_domain(fold->qp[i],
-						isl_morph_copy(morph));
-		if (!fold->qp[i])
-			goto error;
-	}
+	space = isl_morph_get_ran_space(morph);
+	isl_space_free(isl_qpolynomial_fold_take_domain_space(fold));
+	fold = isl_qpolynomial_fold_restore_domain_space(fold, space);
 
 	isl_morph_free(morph);
 
@@ -1346,10 +1653,21 @@
 	return upwf->type;
 }
 
+/* isl_qpolynomial_list_map callback that calls
+ * isl_qpolynomial_lift on "qp".
+ */
+static __isl_give isl_qpolynomial *lift(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	isl_space *space = user;
+
+	return isl_qpolynomial_lift(qp, isl_space_copy(space));
+}
+
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_lift(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space)
 {
-	int i;
+	isl_qpolynomial_list *list;
 
 	if (!fold || !space)
 		goto error;
@@ -1359,23 +1677,12 @@
 		return fold;
 	}
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		goto error;
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &lift, space);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
-	isl_space_free(fold->dim);
-	fold->dim = isl_space_copy(space);
-	if (!fold->dim)
-		goto error;
-
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_lift(fold->qp[i],
-						isl_space_copy(space));
-		if (!fold->qp[i])
-			goto error;
-	}
-
-	isl_space_free(space);
+	isl_space_free(isl_qpolynomial_fold_take_domain_space(fold));
+	fold = isl_qpolynomial_fold_restore_domain_space(fold, space);
 
 	return fold;
 error:
@@ -1388,16 +1695,34 @@
 	__isl_keep isl_qpolynomial_fold *fold,
 	isl_stat (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user)
 {
-	int i;
+	isl_qpolynomial_list *list;
 
-	if (!fold)
-		return isl_stat_error;
+	list = isl_qpolynomial_fold_peek_list(fold);
+	return isl_qpolynomial_list_foreach(list, fn, user);
+}
 
-	for (i = 0; i < fold->n; ++i)
-		if (fn(isl_qpolynomial_copy(fold->qp[i]), user) < 0)
-			return isl_stat_error;
+/* Internal data structure for isl_qpolynomial_fold_move_dims
+ * representing its arguments.
+ */
+struct isl_fold_move_dims_data {
+	enum isl_dim_type dst_type;
+	unsigned dst_pos;
+	enum isl_dim_type src_type;
+	unsigned src_pos;
+	unsigned n;
+};
 
-	return isl_stat_ok;
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_move_dims on "qp".
+ */
+static __isl_give isl_qpolynomial *move_dims(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	struct isl_fold_move_dims_data *data = user;
+
+	qp = isl_qpolynomial_move_dims(qp, data->dst_type, data->dst_pos,
+					data->src_type, data->src_pos, data->n);
+	return qp;
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims(
@@ -1405,8 +1730,11 @@
 	enum isl_dim_type dst_type, unsigned dst_pos,
 	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
 {
-	int i;
+	struct isl_fold_move_dims_data data =
+		{ dst_type, dst_pos, src_type, src_pos, n };
 	enum isl_dim_type set_src_type, set_dst_type;
+	isl_space *space;
+	isl_qpolynomial_list *list;
 
 	if (n == 0)
 		return fold;
@@ -1418,22 +1746,39 @@
 	set_src_type = domain_type(src_type);
 	set_dst_type = domain_type(dst_type);
 
-	fold->dim = isl_space_move_dims(fold->dim, set_dst_type, dst_pos,
-						set_src_type, src_pos, n);
-	if (!fold->dim)
-		goto error;
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &move_dims, &data);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_move_dims(fold->qp[i],
-				dst_type, dst_pos, src_type, src_pos, n);
-		if (!fold->qp[i])
-			goto error;
-	}
+	space = isl_qpolynomial_fold_take_domain_space(fold);
+	space = isl_space_move_dims(space, set_dst_type, dst_pos,
+						set_src_type, src_pos, n);
+	fold = isl_qpolynomial_fold_restore_domain_space(fold, space);
 
 	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
+}
+
+/* Internal data structure for isl_qpolynomial_fold_substitute
+ * representing its arguments.
+ */
+struct isl_fold_substitute {
+	enum isl_dim_type type;
+	unsigned first;
+	unsigned n;
+	isl_qpolynomial **subs;
+};
+
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_substitute on "qp".
+ */
+static __isl_give isl_qpolynomial *substitute(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	struct isl_fold_substitute *data = user;
+
+	qp = isl_qpolynomial_substitute(qp,
+				data->type, data->first, data->n, data->subs);
+	return qp;
 }
 
 /* For each 0 <= i < "n", replace variable "first" + i of type "type"
@@ -1444,26 +1789,17 @@
 	enum isl_dim_type type, unsigned first, unsigned n,
 	__isl_keep isl_qpolynomial **subs)
 {
-	int i;
+	struct isl_fold_substitute data = { type, first, n, subs };
+	isl_qpolynomial_list *list;
 
 	if (n == 0)
 		return fold;
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold)
-		return NULL;
-
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_substitute(fold->qp[i],
-				type, first, n, subs);
-		if (!fold->qp[i])
-			goto error;
-	}
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &substitute, &data);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
 	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
 }
 
 static isl_stat add_pwqp(__isl_take isl_pw_qpolynomial *pwqp, void *user)
@@ -1684,24 +2020,29 @@
 	return isl_union_map_apply_union_pw_qpolynomial_fold(uset, upwf, tight);
 }
 
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_realign_domain on "qp".
+ */
+static __isl_give isl_qpolynomial *realign_domain(
+	__isl_take isl_qpolynomial *qp, void *user)
+{
+	isl_reordering *r = user;
+
+	qp = isl_qpolynomial_realign_domain(qp, isl_reordering_copy(r));
+	return qp;
+}
+
 /* Reorder the dimension of "fold" according to the given reordering.
  */
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign_domain(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_reordering *r)
 {
-	int i;
 	isl_space *space;
+	isl_qpolynomial_list *list;
 
-	fold = isl_qpolynomial_fold_cow(fold);
-	if (!fold || !r)
-		goto error;
-
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_realign_domain(fold->qp[i],
-						    isl_reordering_copy(r));
-		if (!fold->qp[i])
-			goto error;
-	}
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &realign_domain, r);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
 	space = isl_reordering_get_space(r);
 	fold = isl_qpolynomial_fold_reset_domain_space(fold, space);
@@ -1709,16 +2050,24 @@
 	isl_reordering_free(r);
 
 	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	isl_reordering_free(r);
-	return NULL;
+}
+
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_mul_isl_int on "qp".
+ */
+static __isl_give isl_qpolynomial *mul_int(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	isl_int *v = user;
+
+	qp = isl_qpolynomial_mul_isl_int(qp, *v);
+	return qp;
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_mul_isl_int(
 	__isl_take isl_qpolynomial_fold *fold, isl_int v)
 {
-	int i;
+	isl_qpolynomial_list *list;
 
 	if (isl_int_is_one(v))
 		return fold;
@@ -1736,16 +2085,12 @@
 
 	if (isl_int_is_neg(v))
 		fold->type = isl_fold_type_negate(fold->type);
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_mul_isl_int(fold->qp[i], v);
-		if (!fold->qp[i])
-			goto error;
-	}
+
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &mul_int, &v);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
 	return fold;
-error:
-	isl_qpolynomial_fold_free(fold);
-	return NULL;
 }
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale(
@@ -1754,12 +2099,24 @@
 	return isl_qpolynomial_fold_mul_isl_int(fold, v);
 }
 
+/* isl_qpolynomial_list_map callback for calling
+ * isl_qpolynomial_scale_val on "qp".
+ */
+static __isl_give isl_qpolynomial *scale_val(__isl_take isl_qpolynomial *qp,
+	void *user)
+{
+	isl_val *v = user;
+
+	qp = isl_qpolynomial_scale_val(qp, isl_val_copy(v));
+	return qp;
+}
+
 /* Multiply "fold" by "v".
  */
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_val(
 	__isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v)
 {
-	int i;
+	isl_qpolynomial_list *list;
 
 	if (!fold || !v)
 		goto error;
@@ -1786,12 +2143,10 @@
 
 	if (isl_val_is_neg(v))
 		fold->type = isl_fold_type_negate(fold->type);
-	for (i = 0; i < fold->n; ++i) {
-		fold->qp[i] = isl_qpolynomial_scale_val(fold->qp[i],
-							isl_val_copy(v));
-		if (!fold->qp[i])
-			goto error;
-	}
+
+	list = isl_qpolynomial_fold_take_list(fold);
+	list = isl_qpolynomial_list_map(list, &scale_val, v);
+	fold = isl_qpolynomial_fold_restore_list(fold, list);
 
 	isl_val_free(v);
 	return fold;
diff --git a/lib/External/isl/isl_input.c b/lib/External/isl/isl_input.c
index 233742a..4ac2bdd 100644
--- a/lib/External/isl/isl_input.c
+++ b/lib/External/isl/isl_input.c
@@ -593,10 +593,7 @@
  */
 static __isl_give isl_pw_aff *nan_on_domain(__isl_keep isl_space *space)
 {
-	isl_local_space *ls;
-
-	ls = isl_local_space_from_space(isl_space_copy(space));
-	return isl_pw_aff_nan_on_domain(ls);
+	return isl_pw_aff_nan_on_domain_space(isl_space_copy(space));
 }
 
 static __isl_give isl_pw_aff *accept_affine(__isl_keep isl_stream *s,
@@ -2602,24 +2599,28 @@
 static struct isl_obj obj_read_poly_or_fold(__isl_keep isl_stream *s,
 	__isl_take isl_set *set, struct vars *v, int n)
 {
+	int min, max;
 	struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL };
 	isl_pw_qpolynomial *pwqp;
 	isl_pw_qpolynomial_fold *pwf = NULL;
+	enum isl_fold fold;
 
-	if (!isl_stream_eat_if_available(s, ISL_TOKEN_MAX))
+	max = isl_stream_eat_if_available(s, ISL_TOKEN_MAX);
+	min = !max && isl_stream_eat_if_available(s, ISL_TOKEN_MIN);
+	if (!min && !max)
 		return obj_read_poly(s, set, v, n);
+	fold = max ? isl_fold_max : isl_fold_min;
 
 	if (isl_stream_eat(s, '('))
 		goto error;
 
 	pwqp = read_term(s, set, v);
-	pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial(isl_fold_max, pwqp);
+	pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial(fold, pwqp);
 
 	while (isl_stream_eat_if_available(s, ',')) {
 		isl_pw_qpolynomial_fold *pwf_i;
 		pwqp = read_term(s, set, v);
-		pwf_i = isl_pw_qpolynomial_fold_from_pw_qpolynomial(isl_fold_max,
-									pwqp);
+		pwf_i = isl_pw_qpolynomial_fold_from_pw_qpolynomial(fold, pwqp);
 		pwf = isl_pw_qpolynomial_fold_fold(pwf, pwf_i);
 	}
 
@@ -3385,7 +3386,43 @@
 	return pwqp;
 }
 
-/* Is the next token an identifer not in "v"?
+/* Read an isl_pw_qpolynomial_fold from "s".
+ * First read a generic object and
+ * then check that it is an isl_pw_qpolynomial_fold.
+ */
+__isl_give isl_pw_qpolynomial_fold *isl_stream_read_pw_qpolynomial_fold(
+	__isl_keep isl_stream *s)
+{
+	struct isl_obj obj;
+
+	obj = obj_read(s);
+	if (obj.v && obj.type != isl_obj_pw_qpolynomial_fold)
+		isl_die(s->ctx, isl_error_invalid, "invalid input", goto error);
+
+	return obj.v;
+error:
+	obj.type->free(obj.v);
+	return NULL;
+}
+
+/* Read an isl_pw_qpolynomial_fold from "str".
+ */
+__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_read_from_str(
+	isl_ctx *ctx, const char *str)
+{
+	isl_pw_qpolynomial_fold *pwqp;
+	isl_stream *s;
+
+	s = isl_stream_new_str(ctx, str);
+	if (!s)
+		return NULL;
+	pwqp = isl_stream_read_pw_qpolynomial_fold(s);
+	isl_stream_free(s);
+
+	return pwqp;
+}
+
+/* Is the next token an identifier not in "v"?
  */
 static int next_is_fresh_ident(__isl_keep isl_stream *s, struct vars *v)
 {
diff --git a/lib/External/isl/isl_list_private.h b/lib/External/isl/isl_list_private.h
new file mode 100644
index 0000000..006b287
--- /dev/null
+++ b/lib/External/isl/isl_list_private.h
@@ -0,0 +1,10 @@
+#ifndef ISL_LIST_PRIVATE_H
+#define ISL_LIST_PRIVATE_H
+
+#include <isl/list.h>
+
+#define ISL_DECLARE_LIST_FN_PRIVATE(EL)					\
+__isl_keep isl_##EL *isl_##EL##_list_peek(				\
+	__isl_keep isl_##EL##_list *list, int index);
+
+#endif
diff --git a/lib/External/isl/isl_list_templ.c b/lib/External/isl/isl_list_templ.c
index f398ba9..03bea20 100644
--- a/lib/External/isl/isl_list_templ.c
+++ b/lib/External/isl/isl_list_templ.c
@@ -265,7 +265,7 @@
 
 /* Return the element at position "index" in "list".
  */
-static __isl_keep EL *FN(LIST(EL),peek)(__isl_keep LIST(EL) *list, int index)
+__isl_keep EL *FN(LIST(EL),peek)(__isl_keep LIST(EL) *list, int index)
 {
 	if (FN(LIST(EL),check_index)(list, index) < 0)
 		return NULL;
diff --git a/lib/External/isl/isl_local_space.c b/lib/External/isl/isl_local_space.c
index 0b4aa7c..1eebd44 100644
--- a/lib/External/isl/isl_local_space.c
+++ b/lib/External/isl/isl_local_space.c
@@ -37,7 +37,7 @@
 		return 0;
 
 	hash = isl_hash_init();
-	space_hash = isl_space_get_hash(ls->dim);
+	space_hash = isl_space_get_full_hash(isl_local_space_peek_space(ls));
 	isl_hash_hash(hash, space_hash);
 	div_hash = isl_mat_get_hash(ls->div);
 	isl_hash_hash(hash, div_hash);
@@ -163,14 +163,7 @@
 #define TYPE	isl_local_space
 
 #include "isl_type_has_equal_space_bin_templ.c"
-
-/* Is the space of "ls" equal to "space"?
- */
-isl_bool isl_local_space_has_space(__isl_keep isl_local_space *ls,
-	__isl_keep isl_space *space)
-{
-	return isl_space_is_equal(isl_local_space_peek_space(ls), space);
-}
+#include "isl_type_has_space_templ.c"
 
 /* Check that the space of "ls" is equal to "space".
  */
diff --git a/lib/External/isl/isl_map.c b/lib/External/isl/isl_map.c
index c818ebf..6b6f301 100644
--- a/lib/External/isl/isl_map.c
+++ b/lib/External/isl/isl_map.c
@@ -6864,6 +6864,18 @@
 	return set_from_map(isl_map_upper_bound_val(map, type, pos, value));
 }
 
+/* If "mv" has an explicit domain, then intersect the domain of "map"
+ * with this explicit domain.
+ *
+ * An isl_multi_val object never has an explicit domain,
+ * so simply return "map".
+ */
+static __isl_give isl_map *isl_map_intersect_multi_val_explicit_domain(
+	__isl_take isl_map *map, __isl_keep isl_multi_val *mv)
+{
+	return map;
+}
+
 #undef BASE
 #define BASE	val
 #include "isl_map_bound_templ.c"
@@ -6921,15 +6933,6 @@
 	return set_bound_multi_val(set, lower, &map_lower_bound_val);
 }
 
-/* Force the values of the output dimensions of "map"
- * to be no smaller than the corresponding values in "lower".
- */
-__isl_give isl_map *isl_map_lower_bound_multi_val(__isl_take isl_map *map,
-	__isl_take isl_multi_val *lower)
-{
-	return map_bound_multi_val(map, lower, &map_lower_bound_val);
-}
-
 /* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
  * setting a bound on the given output dimension.
  */
@@ -6948,15 +6951,6 @@
 	return set_bound_multi_val(set, upper, &map_upper_bound_val);
 }
 
-/* Force the values of the set dimensions of "set"
- * to be no greater than the corresponding values in "upper".
- */
-__isl_give isl_map *isl_map_upper_bound_multi_val(__isl_take isl_map *map,
-	__isl_take isl_multi_val *upper)
-{
-	return map_bound_multi_val(map, upper, &map_upper_bound_val);
-}
-
 /* Force the symbolic constant expression "bound"
  * to satisfy the relation "order" with respect to
  * the output variable at position "pos" of "map".
@@ -8287,6 +8281,11 @@
 	return NULL;
 }
 
+#undef TYPE
+#define TYPE isl_map
+static
+#include "isl_copy_tuple_id_templ.c"
+
 /* Data structure that specifies how isl_map_intersect_factor
  * should operate.
  *
@@ -8322,8 +8321,7 @@
 	__isl_take isl_map *map, __isl_take isl_map *factor,
 	struct isl_intersect_factor_control *control)
 {
-	isl_bool equal, has_id;
-	isl_id *id;
+	isl_bool equal;
 	isl_space *space;
 	isl_map *other, *product;
 
@@ -8336,19 +8334,12 @@
 	}
 
 	space = isl_map_get_space(map);
-	has_id = isl_space_has_tuple_id(space, control->preserve_type);
-	if (has_id < 0)
-		space = isl_space_free(space);
-	else if (has_id)
-		id = isl_space_get_tuple_id(space, control->preserve_type);
-
 	other = isl_map_universe(control->other_factor(space));
 	product = control->product(factor, other);
 
-	if (has_id >= 0 && has_id)
-		product = isl_map_set_tuple_id(product,
-						control->preserve_type, id);
-
+	space = isl_map_peek_space(map);
+	product = isl_map_copy_tuple_id(product, control->preserve_type,
+					space, control->preserve_type);
 	return map_intersect(map, product);
 error:
 	isl_map_free(map);
@@ -8373,6 +8364,21 @@
 }
 
 /* Given a map "map" in a space [A -> B] -> C and a map "factor"
+ * in the space A -> C, return the intersection.
+ */
+__isl_give isl_map *isl_map_intersect_domain_factor_domain(
+	__isl_take isl_map *map, __isl_take isl_map *factor)
+{
+	struct isl_intersect_factor_control control = {
+		.preserve_type = isl_dim_in,
+		.other_factor = isl_space_domain_factor_range,
+		.product = isl_map_domain_product,
+	};
+
+	return isl_map_intersect_factor(map, factor, &control);
+}
+
+/* Given a map "map" in a space [A -> B] -> C and a map "factor"
  * in the space B -> C, return the intersection.
  */
 __isl_give isl_map *isl_map_intersect_domain_factor_range(
@@ -8604,6 +8610,17 @@
 	return isl_space_tuple_is_equal(space1, type1, space2, type2);
 }
 
+/* Is the space of "obj" equal to "space", ignoring parameters?
+ */
+isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map,
+	__isl_keep isl_space *space)
+{
+	isl_space *map_space;
+
+	map_space = isl_map_peek_space(map);
+	return isl_space_has_equal_tuples(map_space, space);
+}
+
 /* Check that "map" is a transformation, i.e.,
  * that it relates elements from the same space.
  */
@@ -8707,6 +8724,20 @@
 					&isl_basic_map_deltas_map);
 }
 
+/* Return pairs of elements { x -> y } such that y - x is in "deltas".
+ */
+__isl_give isl_map *isl_set_translation(__isl_take isl_set *deltas)
+{
+	isl_space *space;
+	isl_map *map;
+
+	space = isl_space_map_from_set(isl_set_get_space(deltas));
+	map = isl_map_deltas_map(isl_map_universe(space));
+	map = isl_map_intersect_range(map, deltas);
+
+	return isl_set_unwrap(isl_map_domain(map));
+}
+
 __isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space)
 {
 	isl_size n_in, n_out;
@@ -9022,6 +9053,7 @@
 
 #include "isl_type_has_equal_space_bin_templ.c"
 #include "isl_type_check_equal_space_templ.c"
+#include "isl_type_has_space_templ.c"
 
 isl_bool isl_set_has_equal_space(__isl_keep isl_set *set1,
 	__isl_keep isl_set *set2)
@@ -9480,6 +9512,16 @@
 /* Align the divs of "dst" to those of "src", adding divs from "src"
  * if needed.  That is, make sure that the first src->n_div divs
  * of the result are equal to those of src.
+ * The integer division of "src" are assumed to be ordered.
+ *
+ * The integer divisions are swapped into the right position
+ * (possibly after adding them first).  This may result
+ * in the remaining integer divisions appearing in the wrong order,
+ * i.e., with some integer division appearing before
+ * some other integer division on which it depends.
+ * The integer divisions therefore need to be ordered.
+ * This will not affect the integer divisions aligned to those of "src",
+ * since "src" is assumed to have ordered integer divisions.
  *
  * The result is not finalized as by design it will have redundant
  * divs if any divs from "src" were copied.
@@ -9511,10 +9553,6 @@
 	if (v_div < 0)
 		return isl_basic_map_free(dst);
 
-	src = isl_basic_map_order_divs(isl_basic_map_copy(src));
-	if (!src)
-		return isl_basic_map_free(dst);
-
 	extended = 0;
 	dst_n_div = isl_basic_map_dim(dst, isl_dim_div);
 	if (dst_n_div < 0)
@@ -9528,32 +9566,27 @@
 				int extra = src->n_div - i;
 				dst = isl_basic_map_cow(dst);
 				if (!dst)
-					goto error;
+					return isl_basic_map_free(dst);
 				dst = isl_basic_map_extend(dst,
 						extra, 0, 2 * extra);
 				extended = 1;
 			}
 			j = isl_basic_map_alloc_div(dst);
 			if (j < 0)
-				goto error;
+				return isl_basic_map_free(dst);
 			isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i);
 			isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i);
 			dst_n_div++;
 			dst = isl_basic_map_add_div_constraints(dst, j);
 			if (!dst)
-				goto error;
+				return isl_basic_map_free(dst);
 		}
 		if (j != i)
 			dst = isl_basic_map_swap_div(dst, i, j);
 		if (!dst)
-			goto error;
+			return isl_basic_map_free(dst);
 	}
-	isl_basic_map_free(src);
-	return dst;
-error:
-	isl_basic_map_free(src);
-	isl_basic_map_free(dst);
-	return NULL;
+	return isl_basic_map_order_divs(dst);
 }
 
 __isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
@@ -9565,6 +9598,7 @@
 	if (map->n == 0)
 		return map;
 	map = isl_map_compute_divs(map);
+	map = isl_map_order_divs(map);
 	map = isl_map_cow(map);
 	if (!map)
 		return NULL;
@@ -9613,6 +9647,7 @@
 		isl_basic_map *bmap;
 
 		bmap = isl_basic_map_list_get_basic_map(list, i);
+		bmap = isl_basic_map_order_divs(bmap);
 		map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
 		isl_basic_map_free(bmap);
 	}
diff --git a/lib/External/isl/isl_map_bound_templ.c b/lib/External/isl/isl_map_bound_templ.c
index 116ab6f..7e1bcf2 100644
--- a/lib/External/isl/isl_map_bound_templ.c
+++ b/lib/External/isl/isl_map_bound_templ.c
@@ -25,6 +25,9 @@
 
 /* Apply "map_bound" to "map" with the corresponding value in "bound"
  * for each output dimension.
+ * If "bound" has an explicit domain (which implies that "bound"
+ * is zero-dimensional), then intersect the domain of "map"
+ * with this explicit domain instead.
  */
 static __isl_give isl_map *FN(map_bound_multi,BASE)(__isl_take isl_map *map,
 	__isl_take MULTI(BASE) *bound,
@@ -44,6 +47,7 @@
 		el = FN(MULTI(BASE),get_at)(bound, i);
 		map = map_bound(map, i, el);
 	}
+	map = FN(FN(isl_map_intersect_multi,BASE),explicit_domain)(map, bound);
 	FN(MULTI(BASE),free)(bound);
 	return map;
 error:
diff --git a/lib/External/isl/isl_map_private.h b/lib/External/isl/isl_map_private.h
index cb4c65a..5ddd3c8 100644
--- a/lib/External/isl/isl_map_private.h
+++ b/lib/External/isl/isl_map_private.h
@@ -562,6 +562,10 @@
 isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1,
 	enum isl_dim_type type1, __isl_keep isl_map *map2,
 	enum isl_dim_type type2);
+isl_bool isl_map_has_space(__isl_keep isl_map *map,
+	__isl_keep isl_space *space);
+isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map,
+	__isl_keep isl_space *space);
 
 isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap);
 isl_stat isl_map_check_transformation(__isl_keep isl_map *map);
diff --git a/lib/External/isl/isl_map_simplify.c b/lib/External/isl/isl_map_simplify.c
index 7ec4394..9759c0d 100644
--- a/lib/External/isl/isl_map_simplify.c
+++ b/lib/External/isl/isl_map_simplify.c
@@ -2149,6 +2149,7 @@
 		return bmap;
 	}
 
+	bmap = isl_basic_map_order_divs(bmap);
 	context = isl_basic_map_align_divs(context, bmap);
 	bmap = isl_basic_map_align_divs(bmap, context);
 
@@ -3284,6 +3285,7 @@
 
 	bmap = isl_basic_map_remove_redundancies(bmap);
 	context = isl_basic_map_remove_redundancies(context);
+	bmap = isl_basic_map_order_divs(bmap);
 	context = isl_basic_map_align_divs(context, bmap);
 
 	n_div = isl_basic_map_dim(context, isl_dim_div);
@@ -3520,6 +3522,7 @@
 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
 			"context has unknown divs", goto error);
 
+	context = isl_basic_map_order_divs(context);
 	bmap = isl_basic_map_align_divs(bmap, context);
 	bmap = isl_basic_map_gauss(bmap, NULL);
 	bmap = isl_basic_map_sort_constraints(bmap);
diff --git a/lib/External/isl/isl_mat.c b/lib/External/isl/isl_mat.c
index 93622b9..37468ee 100644
--- a/lib/External/isl/isl_mat.c
+++ b/lib/External/isl/isl_mat.c
@@ -64,12 +64,14 @@
 	mat->block = isl_blk_alloc(ctx, n_row * n_col);
 	if (isl_blk_is_error(mat->block))
 		goto error;
-	mat->row = isl_alloc_array(ctx, isl_int *, n_row);
+	mat->row = isl_calloc_array(ctx, isl_int *, n_row);
 	if (n_row && !mat->row)
 		goto error;
 
-	for (i = 0; i < n_row; ++i)
-		mat->row[i] = mat->block.data + i * n_col;
+	if (n_col != 0) {
+		for (i = 0; i < n_row; ++i)
+			mat->row[i] = mat->block.data + i * n_col;
+	}
 
 	mat->ctx = ctx;
 	isl_ctx_ref(ctx);
@@ -648,9 +650,6 @@
 		*Q = NULL;
 	if (!M)
 		goto error;
-	M = isl_mat_cow(M);
-	if (!M)
-		goto error;
 	if (U) {
 		*U = isl_mat_identity(M->ctx, M->n_col);
 		if (!*U)
@@ -662,6 +661,13 @@
 			goto error;
 	}
 
+	if (M->n_col == 0)
+		return M;
+
+	M = isl_mat_cow(M);
+	if (!M)
+		goto error;
+
 	col = 0;
 	isl_int_init(c);
 	for (row = 0; row < M->n_row; ++row) {
diff --git a/lib/External/isl/isl_morph.c b/lib/External/isl/isl_morph.c
index dd37516..f7b920b 100644
--- a/lib/External/isl/isl_morph.c
+++ b/lib/External/isl/isl_morph.c
@@ -18,6 +18,8 @@
 #include <isl_space_private.h>
 #include <isl_equalities.h>
 #include <isl_id_private.h>
+#include <isl_aff_private.h>
+#include <isl_vec_private.h>
 
 isl_ctx *isl_morph_get_ctx(__isl_keep isl_morph *morph)
 {
@@ -179,12 +181,46 @@
 
 /* Return the domain space of "morph".
  */
-__isl_give isl_space *isl_morph_get_dom_space(__isl_keep isl_morph *morph)
+static __isl_keep isl_space *isl_morph_peek_dom_space(
+	__isl_keep isl_morph *morph)
 {
 	if (!morph)
 		return NULL;
 
-	return isl_basic_set_get_space(morph->dom);
+	return isl_basic_set_peek_space(morph->dom);
+}
+
+/* Return a copy of the domain space of "morph".
+ */
+__isl_give isl_space *isl_morph_get_dom_space(__isl_keep isl_morph *morph)
+{
+	return isl_space_copy(isl_morph_peek_dom_space(morph));
+}
+
+/* Check that the match against "space" with result "match" was successful.
+ */
+static isl_stat check_space_match(__isl_keep isl_space *space, isl_bool match)
+{
+	if (match < 0)
+		return isl_stat_error;
+	if (!match)
+		isl_die(isl_space_get_ctx(space), isl_error_invalid,
+			"spaces don't match", return isl_stat_error);
+
+	return isl_stat_ok;
+}
+
+/* Check that "morph" can be applied to the "space".
+ */
+isl_stat isl_morph_check_applies(__isl_keep isl_morph *morph,
+	__isl_keep isl_space *space)
+{
+	isl_space *dom_space;
+	isl_bool applies;
+
+	dom_space = isl_morph_peek_dom_space(morph);
+	applies = isl_space_is_equal(dom_space, space);
+	return check_space_match(space, applies);
 }
 
 __isl_give isl_space *isl_morph_get_ran_space(__isl_keep isl_morph *morph)
@@ -573,191 +609,96 @@
 	return isl_morph_alloc(dom, ran, map, inv);
 }
 
-/* Add stride constraints to "bset" based on the inverse mapping
- * that was plugged in.  In particular, if morph maps x' to x,
- * the constraints of the original input
- *
- *	A x' + b >= 0
- *
- * have been rewritten to
- *
- *	A inv x + b >= 0
- *
- * However, this substitution may loose information on the integrality of x',
- * so we need to impose that
- *
- *	inv x
- *
- * is integral.  If inv = B/d, this means that we need to impose that
- *
- *	B x = 0		mod d
- *
- * or
- *
- *	exists alpha in Z^m: B x = d alpha
- *
- * This function is similar to add_strides in isl_affine_hull.c
+/* Construct an isl_multi_aff that corresponds
+ * to the affine transformation matrix "mat" and
+ * that lives in an anonymous space.
  */
-static __isl_give isl_basic_set *add_strides(__isl_take isl_basic_set *bset,
-	__isl_keep isl_morph *morph)
+static __isl_give isl_multi_aff *isl_multi_aff_from_aff_mat_anonymous(
+	__isl_take isl_mat *mat)
 {
-	int i, div, k;
-	isl_int gcd;
+	isl_size n_row, n_col;
+	isl_ctx *ctx;
+	isl_space *space;
 
-	if (isl_int_is_one(morph->inv->row[0][0]))
-		return bset;
+	ctx = isl_mat_get_ctx(mat);
+	n_row = isl_mat_rows(mat);
+	n_col = isl_mat_cols(mat);
+	if (n_row < 0 || n_col < 0)
+		space = NULL;
+	else
+		space = isl_space_alloc(ctx, 0, n_col - 1, n_row - 1);
 
-	isl_int_init(gcd);
-
-	for (i = 0; 1 + i < morph->inv->n_row; ++i) {
-		isl_seq_gcd(morph->inv->row[1 + i], morph->inv->n_col, &gcd);
-		if (isl_int_is_divisible_by(gcd, morph->inv->row[0][0]))
-			continue;
-		div = isl_basic_set_alloc_div(bset);
-		if (div < 0)
-			goto error;
-		isl_int_set_si(bset->div[div][0], 0);
-		k = isl_basic_set_alloc_equality(bset);
-		if (k < 0)
-			goto error;
-		isl_seq_cpy(bset->eq[k], morph->inv->row[1 + i],
-			    morph->inv->n_col);
-		isl_seq_clr(bset->eq[k] + morph->inv->n_col, bset->n_div);
-		isl_int_set(bset->eq[k][morph->inv->n_col + div],
-			    morph->inv->row[0][0]);
-	}
-
-	isl_int_clear(gcd);
-
-	return bset;
-error:
-	isl_int_clear(gcd);
-	isl_basic_set_free(bset);
-	return NULL;
+	return isl_multi_aff_from_aff_mat(space, mat);
 }
 
 /* Apply the morphism to the basic set.
- * We basically just compute the preimage of "bset" under the inverse mapping
- * in morph, add in stride constraints and intersect with the range
- * of the morphism.
+ * In particular, compute the preimage of "bset" under the inverse mapping
+ * in morph and intersect with the range of the morphism.
+ * Note that the mapping in morph applies to both parameters and set dimensions,
+ * so the parameters need to be treated as set dimensions during the call
+ * to isl_basic_set_preimage_multi_aff.
  */
 __isl_give isl_basic_set *isl_morph_basic_set(__isl_take isl_morph *morph,
 	__isl_take isl_basic_set *bset)
 {
-	isl_basic_set *res = NULL;
-	isl_mat *mat = NULL;
-	int i, k;
-	int max_stride;
+	isl_size n_param;
+	isl_space *space;
+	isl_multi_aff *ma;
 
 	if (!morph || isl_basic_set_check_equal_space(bset, morph->dom) < 0)
 		goto error;
-
-	max_stride = morph->inv->n_row - 1;
-	if (isl_int_is_one(morph->inv->row[0][0]))
-		max_stride = 0;
-	res = isl_basic_set_alloc_space(isl_space_copy(morph->ran->dim),
-		bset->n_div + max_stride, bset->n_eq + max_stride, bset->n_ineq);
-
-	for (i = 0; i < bset->n_div; ++i)
-		if (isl_basic_set_alloc_div(res) < 0)
-			goto error;
-
-	mat = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, bset->n_eq,
-					0, morph->inv->n_row);
-	mat = isl_mat_product(mat, isl_mat_copy(morph->inv));
-	if (!mat)
+	n_param = isl_basic_set_dim(morph->dom, isl_dim_param);
+	if (n_param < 0)
 		goto error;
-	for (i = 0; i < bset->n_eq; ++i) {
-		k = isl_basic_set_alloc_equality(res);
-		if (k < 0)
-			goto error;
-		isl_seq_cpy(res->eq[k], mat->row[i], mat->n_col);
-		isl_seq_scale(res->eq[k] + mat->n_col, bset->eq[i] + mat->n_col,
-				morph->inv->row[0][0], bset->n_div);
-	}
-	isl_mat_free(mat);
 
-	mat = isl_mat_sub_alloc6(bset->ctx, bset->ineq, 0, bset->n_ineq,
-					0, morph->inv->n_row);
-	mat = isl_mat_product(mat, isl_mat_copy(morph->inv));
-	if (!mat)
-		goto error;
-	for (i = 0; i < bset->n_ineq; ++i) {
-		k = isl_basic_set_alloc_inequality(res);
-		if (k < 0)
-			goto error;
-		isl_seq_cpy(res->ineq[k], mat->row[i], mat->n_col);
-		isl_seq_scale(res->ineq[k] + mat->n_col,
-				bset->ineq[i] + mat->n_col,
-				morph->inv->row[0][0], bset->n_div);
-	}
-	isl_mat_free(mat);
+	ma = isl_multi_aff_from_aff_mat_anonymous(isl_mat_copy(morph->inv));
 
-	mat = isl_mat_sub_alloc6(bset->ctx, bset->div, 0, bset->n_div,
-					1, morph->inv->n_row);
-	mat = isl_mat_product(mat, isl_mat_copy(morph->inv));
-	if (!mat)
-		goto error;
-	for (i = 0; i < bset->n_div; ++i) {
-		isl_int_mul(res->div[i][0],
-				morph->inv->row[0][0], bset->div[i][0]);
-		isl_seq_cpy(res->div[i] + 1, mat->row[i], mat->n_col);
-		isl_seq_scale(res->div[i] + 1 + mat->n_col,
-				bset->div[i] + 1 + mat->n_col,
-				morph->inv->row[0][0], bset->n_div);
-	}
-	isl_mat_free(mat);
-
-	res = add_strides(res, morph);
-
-	if (isl_basic_set_is_rational(bset))
-		res = isl_basic_set_set_rational(res);
-
-	res = isl_basic_set_simplify(res);
-	res = isl_basic_set_finalize(res);
-
-	res = isl_basic_set_intersect(res, isl_basic_set_copy(morph->ran));
+	bset = isl_basic_set_move_dims(bset, isl_dim_set, 0,
+					isl_dim_param, 0, n_param);
+	bset = isl_basic_set_preimage_multi_aff(bset, ma);
+	space = isl_basic_set_get_space(morph->ran);
+	bset = isl_basic_set_reset_space(bset, space);
+	bset = isl_basic_set_intersect(bset, isl_basic_set_copy(morph->ran));
 
 	isl_morph_free(morph);
-	isl_basic_set_free(bset);
-	return res;
+	return bset;
 error:
-	isl_mat_free(mat);
 	isl_morph_free(morph);
 	isl_basic_set_free(bset);
-	isl_basic_set_free(res);
 	return NULL;
 }
 
 /* Apply the morphism to the set.
+ * In particular, compute the preimage of "set" under the inverse mapping
+ * in morph and intersect with the range of the morphism.
+ * Note that the mapping in morph applies to both parameters and set dimensions,
+ * so the parameters need to be treated as set dimensions during the call
+ * to isl_set_preimage_multi_aff.
  */
 __isl_give isl_set *isl_morph_set(__isl_take isl_morph *morph,
 	__isl_take isl_set *set)
 {
-	int i;
+	isl_size n_param;
+	isl_space *space;
+	isl_multi_aff *ma;
+	isl_basic_set *ran;
 
 	if (!morph || isl_set_basic_set_check_equal_space(set, morph->dom) < 0)
 		goto error;
-
-	set = isl_set_cow(set);
-	if (!set)
+	n_param = isl_basic_set_dim(morph->dom, isl_dim_param);
+	if (n_param < 0)
 		goto error;
 
-	isl_space_free(set->dim);
-	set->dim = isl_space_copy(morph->ran->dim);
-	if (!set->dim)
-		goto error;
+	ma = isl_multi_aff_from_aff_mat_anonymous(isl_mat_copy(morph->inv));
 
-	for (i = 0; i < set->n; ++i) {
-		set->p[i] = isl_morph_basic_set(isl_morph_copy(morph), set->p[i]);
-		if (!set->p[i])
-			goto error;
-	}
+	set = isl_set_move_dims(set, isl_dim_set, 0, isl_dim_param, 0, n_param);
+	set = isl_set_preimage_multi_aff(set, ma);
+	space = isl_basic_set_get_space(morph->ran);
+	set = isl_set_reset_space(set, space);
+	ran = isl_basic_set_copy(morph->ran);
+	set = isl_set_intersect(set, isl_set_from_basic_set(ran));
 
 	isl_morph_free(morph);
-
-	ISL_F_CLR(set, ISL_SET_NORMALIZED);
-
 	return set;
 error:
 	isl_set_free(set);
diff --git a/lib/External/isl/isl_morph.h b/lib/External/isl/isl_morph.h
index ef8b876..004e148 100644
--- a/lib/External/isl/isl_morph.h
+++ b/lib/External/isl/isl_morph.h
@@ -45,6 +45,9 @@
 __isl_give isl_morph *isl_morph_identity(__isl_keep isl_basic_set *bset);
 __isl_null isl_morph *isl_morph_free(__isl_take isl_morph *morph);
 
+isl_stat isl_morph_check_applies(__isl_keep isl_morph *morph,
+	__isl_keep isl_space *space);
+
 __isl_give isl_space *isl_morph_get_dom_space(__isl_keep isl_morph *morph);
 __isl_give isl_space *isl_morph_get_ran_space(__isl_keep isl_morph *morph);
 __isl_give isl_multi_aff *isl_morph_get_var_multi_aff(
diff --git a/lib/External/isl/isl_opt_mpa_templ.c b/lib/External/isl/isl_opt_mpa_templ.c
index 84382d3..e424543 100644
--- a/lib/External/isl/isl_opt_mpa_templ.c
+++ b/lib/External/isl/isl_opt_mpa_templ.c
@@ -19,8 +19,8 @@
  * for a single dimension.
  *
  * If the resulting multi piecewise affine expression has
- * an explicit domain, then assign it the parameter domain of the input.
- * In other cases, the parameter domain is stored in the individual elements.
+ * an explicit domain, then assign it the (parameter) domain of the input.
+ * In other cases, the (parameter) domain is stored in the individual elements.
  */
 static __isl_give isl_multi_pw_aff *FN(BASE,opt_mpa)(__isl_take TYPE *obj,
 	__isl_give isl_pw_aff *(*opt)(__isl_take TYPE *obj, int pos))
@@ -42,8 +42,8 @@
 	if (isl_multi_pw_aff_has_explicit_domain(mpa)) {
 		isl_set *dom;
 
-		dom = FN(TYPE,params)(FN(TYPE,copy)(obj));
-		mpa = isl_multi_pw_aff_intersect_params(mpa, dom);
+		dom = FN(TYPE,domain)(FN(TYPE,copy)(obj));
+		mpa = isl_multi_pw_aff_intersect_domain(mpa, dom);
 	}
 	FN(TYPE,free)(obj);
 
diff --git a/lib/External/isl/isl_output.c b/lib/External/isl/isl_output.c
index ace3665..9839a52 100644
--- a/lib/External/isl/isl_output.c
+++ b/lib/External/isl/isl_output.c
@@ -1988,16 +1988,25 @@
 	__isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
 {
 	int i;
+	isl_qpolynomial_list *list;
+	isl_size n;
 
+	list = isl_qpolynomial_fold_peek_list(fold);
+	n = isl_qpolynomial_list_size(list);
+	if (n < 0)
+		return isl_printer_free(p);
 	if (fold->type == isl_fold_min)
 		p = isl_printer_print_str(p, "min");
 	else if (fold->type == isl_fold_max)
 		p = isl_printer_print_str(p, "max");
 	p = isl_printer_print_str(p, "(");
-	for (i = 0; i < fold->n; ++i) {
+	for (i = 0; i < n; ++i) {
+		isl_qpolynomial *qp;
+
 		if (i)
 			p = isl_printer_print_str(p, ", ");
-		p = print_qpolynomial(p, fold->qp[i]);
+		qp = isl_qpolynomial_list_peek(list, i);
+		p = print_qpolynomial(p, qp);
 	}
 	p = isl_printer_print_str(p, ")");
 	return p;
@@ -2337,17 +2346,26 @@
 	__isl_keep isl_qpolynomial_fold *fold)
 {
 	int i;
+	isl_qpolynomial_list *list;
+	isl_size n;
 
-	for (i = 0; i < fold->n - 1; ++i)
+	list = isl_qpolynomial_fold_peek_list(fold);
+	n = isl_qpolynomial_list_size(list);
+	if (n < 0)
+		return isl_printer_free(p);
+	for (i = 0; i < n - 1; ++i)
 		if (fold->type == isl_fold_min)
 			p = isl_printer_print_str(p, "min(");
 		else if (fold->type == isl_fold_max)
 			p = isl_printer_print_str(p, "max(");
 
-	for (i = 0; i < fold->n; ++i) {
+	for (i = 0; i < n; ++i) {
+		isl_qpolynomial *qp;
+
 		if (i)
 			p = isl_printer_print_str(p, ", ");
-		p = print_qpolynomial_c(p, space, fold->qp[i]);
+		qp = isl_qpolynomial_list_peek(list, i);
+		p = print_qpolynomial_c(p, space, qp);
 		if (i)
 			p = isl_printer_print_str(p, ")");
 	}
diff --git a/lib/External/isl/isl_polynomial.c b/lib/External/isl/isl_polynomial.c
index 5053000..5577e07 100644
--- a/lib/External/isl/isl_polynomial.c
+++ b/lib/External/isl/isl_polynomial.c
@@ -29,6 +29,11 @@
 #include <isl_config.h>
 
 #undef EL_BASE
+#define EL_BASE qpolynomial
+
+#include <isl_list_templ.c>
+
+#undef EL_BASE
 #define EL_BASE pw_qpolynomial
 
 #include <isl_list_templ.c>
@@ -4384,16 +4389,17 @@
 	int i;
 	int n_sub;
 	isl_ctx *ctx;
+	isl_space *space;
 	isl_poly **subs;
 	isl_mat *mat, *diag;
 
 	qp = isl_qpolynomial_cow(qp);
-	if (!qp || !morph)
+
+	space = isl_qpolynomial_peek_domain_space(qp);
+	if (isl_morph_check_applies(morph, space) < 0)
 		goto error;
 
-	ctx = qp->dim->ctx;
-	isl_assert(ctx, isl_space_is_equal(qp->dim, morph->dom->dim), goto error);
-
+	ctx = isl_qpolynomial_get_ctx(qp);
 	n_sub = morph->inv->n_row - 1;
 	if (morph->inv->n_row != morph->inv->n_col)
 		n_sub += qp->div->n_row;
diff --git a/lib/External/isl/isl_polynomial_private.h b/lib/External/isl/isl_polynomial_private.h
index 36831c0..acab078 100644
--- a/lib/External/isl/isl_polynomial_private.h
+++ b/lib/External/isl/isl_polynomial_private.h
@@ -5,6 +5,7 @@
 #include <isl_morph.h>
 #include <isl/polynomial.h>
 #include <isl_reordering.h>
+#include "isl_list_private.h"
 
 struct isl_poly {
 	int ref;
@@ -40,6 +41,11 @@
 	isl_poly *poly;
 };
 
+#undef EL
+#define EL isl_qpolynomial
+
+#include <isl_list_templ.h>
+
 struct isl_term {
 	int ref;
 
@@ -86,10 +92,7 @@
 	enum isl_fold type;
 	isl_space *dim;
 
-	int n;
-
-	size_t size;
-	struct isl_qpolynomial *qp[1];
+	isl_qpolynomial_list *list;
 };
 
 struct isl_pw_qpolynomial_fold_piece {
@@ -202,6 +205,9 @@
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup(
 	__isl_keep isl_qpolynomial_fold *fold);
 
+__isl_keep isl_qpolynomial_list *isl_qpolynomial_fold_peek_list(
+	__isl_keep isl_qpolynomial_fold *fold);
+
 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_cow(
 	__isl_take isl_pw_qpolynomial_fold *pwf);
 
@@ -289,3 +295,5 @@
 __isl_give isl_union_pw_qpolynomial_fold *
 isl_union_pw_qpolynomial_fold_mul_isl_int(
 	__isl_take isl_union_pw_qpolynomial_fold *upwf, isl_int v);
+
+ISL_DECLARE_LIST_FN_PRIVATE(qpolynomial)
diff --git a/lib/External/isl/isl_pw_templ.c b/lib/External/isl/isl_pw_templ.c
index 9521b11..3fa6faf 100644
--- a/lib/External/isl/isl_pw_templ.c
+++ b/lib/External/isl/isl_pw_templ.c
@@ -1434,14 +1434,29 @@
 	return pw->p[pos].set;
 }
 
+/* Return a copy of the cell at position "pos" in "pw".
+ */
+__isl_give isl_set *FN(PW,get_domain_at)(__isl_keep PW *pw, int pos)
+{
+	return isl_set_copy(FN(PW,peek_domain_at)(pw, pos));
+}
+
+/* Return the base expression associated to
+ * the cell at position "pos" in "pw".
+ */
+static __isl_keep EL *FN(PW,peek_base_at)(__isl_keep PW *pw, int pos)
+{
+	if (FN(PW,check_pos)(pw, pos) < 0)
+		return NULL;
+	return pw->p[pos].FIELD;
+}
+
 /* Return a copy of the base expression associated to
  * the cell at position "pos" in "pw".
  */
 __isl_give EL *FN(PW,get_base_at)(__isl_keep PW *pw, int pos)
 {
-	if (FN(PW,check_pos)(pw, pos) < 0)
-		return NULL;
-	return FN(EL,copy)(pw->p[pos].FIELD);
+	return FN(EL,copy)(FN(PW,peek_base_at)(pw, pos));
 }
 
 /* Return the base expression associated to
diff --git a/lib/External/isl/isl_pw_union_opt.c b/lib/External/isl/isl_pw_union_opt.c
index c10126a..d0fc38c 100644
--- a/lib/External/isl/isl_pw_union_opt.c
+++ b/lib/External/isl/isl_pw_union_opt.c
@@ -1,6 +1,7 @@
 /*
  * Copyright 2011      INRIA Saclay
  * Copyright 2012      Ecole Normale Superieure
+ * Copyright 2020      Cerebras Systems
  *
  * Use of this software is governed by the MIT license
  *
@@ -8,6 +9,7 @@
  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
  * 91893 Orsay, France
  * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
+ * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
  */
 
 #include <isl_pw_macro.h>
@@ -69,29 +71,173 @@
 	return isl_set_union(set_worse, set_out);
 }
 
-/* Given two piecewise expressions "pw1" and "pw2", replace their domains
- * by the sets in "list1" and "list2" and combine the results into
+/* Internal data structure used by isl_pw_*_union_opt_cmp
+ * that keeps track of a piecewise expression with updated cells.
+ * "pw" holds the original piecewise expression.
+ * "list" holds the updated cells.
+ */
+S(PW,union_opt_cmp_data) {
+	PW *pw;
+	isl_set_list *cell;
+};
+
+/* Free all memory allocated for "data".
+ */
+static void FN(PW,union_opt_cmp_data_clear)(S(PW,union_opt_cmp_data) *data)
+{
+	isl_set_list_free(data->cell);
+	FN(PW,free)(data->pw);
+}
+
+/* Given (potentially) updated cells "i" of data_i->pw and "j" of data_j->pw and
+ * a set "better" where the piece from data_j->pw is better
+ * than the piece from data_i->pw,
+ * (further) update the specified cells such that only the better elements
+ * remain on the (non-empty) intersection.
+ *
+ * Let C be the set "better".
+ * Let A be the cell data_i->cell[i] and B the cell data_j->cell[j].
+ *
+ * The elements in C need to be removed from A, except for those parts
+ * that lie outside of B.  That is,
+ *
+ *	A <- (A \setminus C) \cup ((A \cap C) \setminus B')
+ *
+ * Conversely, the elements in B need to be restricted to C, except
+ * for those parts that lie outside of A.  That is
+ *
+ *	B <- (B \cap C) \cup ((B \setminus C) \setminus A')
+ *
+ * Since all pairs of pieces are considered, the domains are updated
+ * several times.  A and B refer to these updated domains
+ * (kept track of in data_i->cell[i] and data_j->cell[j]), while A' and B' refer
+ * to the original domains of the pieces.  It is safe to use these
+ * original domains because the difference between, say, A' and A is
+ * the domains of pw2-pieces that have been removed before and
+ * those domains are disjoint from B.  A' is used instead of A
+ * because the continued updating of A may result in this domain
+ * getting broken up into more disjuncts.
+ */
+static isl_stat FN(PW,union_opt_cmp_split)(S(PW,union_opt_cmp_data) *data_i,
+	int i, S(PW,union_opt_cmp_data) *data_j, int j,
+	__isl_take isl_set *better)
+{
+	isl_set *set_i, *set_j;
+
+	set_i = isl_set_list_get_set(data_i->cell, i);
+	set_j = FN(PW,get_domain_at)(data_j->pw, j);
+	set_i = FN(PW,worse_or_out)(set_i, isl_set_copy(better), set_j);
+	data_i->cell = isl_set_list_set_set(data_i->cell, i, set_i);
+	set_i = FN(PW,get_domain_at)(data_i->pw, i);
+	set_j = isl_set_list_get_set(data_j->cell, j);
+	set_j = FN(PW,better_or_out)(set_j, better, set_i);
+	data_j->cell = isl_set_list_set_set(data_j->cell, j, set_j);
+
+	return isl_stat_ok;
+}
+
+/* Given (potentially) updated cells "i" of data_i->pw and "j" of data_j->pw and
+ * a function "cmp" that returns the set of elements where
+ * "el1" is "better" than "el2",
+ * (further) update the specified cells such that only the "better" elements
+ * remain on the (non-empty) intersection.
+ */
+static isl_stat FN(PW,union_opt_cmp_pair)(S(PW,union_opt_cmp_data) *data_i,
+	int i, S(PW,union_opt_cmp_data) *data_j, int j,
+	__isl_give isl_set *(*cmp)(__isl_take EL *el1, __isl_take EL *el2))
+{
+	isl_set *better;
+	EL *el_i, *el_j;
+
+	el_i = FN(PW,peek_base_at)(data_i->pw, i);
+	el_j = FN(PW,peek_base_at)(data_j->pw, j);
+	better = FN(PW,better)(el_j, el_i, cmp);
+	return FN(PW,union_opt_cmp_split)(data_i, i, data_j, j, better);
+}
+
+/* Given (potentially) updated cells "i" of data_i->pw and "j" of data_j->pw and
+ * a function "cmp" that returns the set of elements where
+ * "el1" is "better" than "el2",
+ * (further) update the specified cells such that only the "better" elements
+ * remain on the (non-empty) intersection.
+ *
+ * The base computation is performed by isl_pw_*_union_opt_cmp_pair,
+ * which splits the cells according to the set of elements
+ * where the piece from data_j->pw is better than the piece from data_i->pw.
+ *
+ * In some cases, there may be a subset of the intersection
+ * where both pieces have the same value and can therefore
+ * both be considered to be "better" than the other.
+ * This can result in unnecessary splitting on this subset.
+ * Avoid some of these cases by checking whether
+ * data_i->pw is always better than data_j->pw on the intersection.
+ * In particular, do this for the special case where this intersection
+ * is equal to the cell "j" and data_i->pw is better on its entire cell.
+ *
+ * Similarly, if data_i->pw is never better than data_j->pw,
+ * then no splitting will occur and there is no need to check
+ * where data_j->pw is better than data_i->pw.
+ */
+static isl_stat FN(PW,union_opt_cmp_two)(S(PW,union_opt_cmp_data) *data_i,
+	int i, S(PW,union_opt_cmp_data) *data_j, int j,
+	__isl_give isl_set *(*cmp)(__isl_take EL *el1, __isl_take EL *el2))
+{
+	isl_bool is_subset, is_empty;
+	isl_set *better, *set_i, *set_j;
+	EL *el_i, *el_j;
+
+	set_i = FN(PW,peek_domain_at)(data_i->pw, i);
+	set_j = FN(PW,peek_domain_at)(data_j->pw, j);
+	is_subset = isl_set_is_subset(set_j, set_i);
+	if (is_subset < 0)
+		return isl_stat_error;
+	if (!is_subset)
+		return FN(PW,union_opt_cmp_pair)(data_i, i, data_j, j, cmp);
+
+	el_i = FN(PW,peek_base_at)(data_i->pw, i);
+	el_j = FN(PW,peek_base_at)(data_j->pw, j);
+	better = FN(PW,better)(el_i, el_j, cmp);
+	is_empty = isl_set_is_empty(better);
+	if (is_empty >= 0 && is_empty)
+		return FN(PW,union_opt_cmp_split)(data_j, j, data_i, i, better);
+	is_subset = isl_set_is_subset(set_i, better);
+	if (is_subset >= 0 && is_subset)
+		return FN(PW,union_opt_cmp_split)(data_j, j, data_i, i, better);
+	isl_set_free(better);
+	if (is_empty < 0 || is_subset < 0)
+		return isl_stat_error;
+
+	return FN(PW,union_opt_cmp_pair)(data_i, i, data_j, j, cmp);
+}
+
+/* Given two piecewise expressions data1->pw and data2->pw, replace
+ * their domains
+ * by the sets in data1->cell and data2->cell and combine the results into
  * a single piecewise expression.
- * The pieces of "pw1" and "pw2" are assumed to have been sorted
+ * The pieces of data1->pw and data2->pw are assumed to have been sorted
  * according to the function value expressions.
  * The pieces of the result are also sorted in this way.
  *
- * Run through the pieces of "pw1" and "pw2" in order until they
- * have both been exhausted, picking the piece from "pw1" or "pw2"
+ * Run through the pieces of data1->pw and data2->pw in order until they
+ * have both been exhausted, picking the piece from data1->pw or data2->pw
  * depending on which should come first, together with the corresponding
- * domain from "list1" or "list2".  In cases where the next pieces
- * in both "pw1" and "pw2" have the same function value expression,
+ * domain from data1->cell or data2->cell.  In cases where the next pieces
+ * in both data1->pw and data2->pw have the same function value expression,
  * construct only a single piece in the result with as domain
- * the union of the domains in "list1" and "list2".
+ * the union of the domains in data1->cell and data2->cell.
  */
-static __isl_give PW *FN(PW,merge)(__isl_take PW *pw1, __isl_take PW *pw2,
-	__isl_take isl_set_list *list1, __isl_take isl_set_list *list2)
+static __isl_give PW *FN(PW,merge)(S(PW,union_opt_cmp_data) *data1,
+	S(PW,union_opt_cmp_data) *data2)
 {
 	int i, j;
 	PW *res;
+	PW *pw1 = data1->pw;
+	PW *pw2 = data2->pw;
+	isl_set_list *list1 = data1->cell;
+	isl_set_list *list2 = data2->cell;
 
 	if (!pw1 || !pw2)
-		goto error;
+		return NULL;
 
 	res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), pw1->n + pw2->n);
 
@@ -125,17 +271,7 @@
 		res = FN(PW,add_piece)(res, set, el);
 	}
 
-	isl_set_list_free(list1);
-	isl_set_list_free(list2);
-	FN(PW,free)(pw1);
-	FN(PW,free)(pw2);
 	return res;
-error:
-	isl_set_list_free(list1);
-	isl_set_list_free(list2);
-	FN(PW,free)(pw1);
-	FN(PW,free)(pw2);
-	return NULL;
 }
 
 /* Given a function "cmp" that returns the set of elements where
@@ -148,32 +284,9 @@
  * Run through all pairs of pieces in "pw1" and "pw2".
  * If the domains of these pieces intersect, then the intersection
  * needs to be distributed over the two pieces based on "cmp".
- * Let C be the set where the piece from "pw2" is better (according to "cmp")
- * than the piece from "pw1".  Let A be the domain of the piece from "pw1" and
- * B the domain of the piece from "pw2".
- *
- * The elements in C need to be removed from A, except for those parts
- * that lie outside of B.  That is,
- *
- *	A <- (A \setminus C) \cup ((A \cap C) \setminus B')
- *
- * Conversely, the elements in B need to be restricted to C, except
- * for those parts that lie outside of A.  That is
- *
- *	B <- (B \cap C) \cup ((B \setminus C) \setminus A')
- *
- * Since all pairs of pieces are considered, the domains are updated
- * several times.  A and B refer to these updated domains
- * (kept track of in "list1" and "list2"), while A' and B' refer
- * to the original domains of the pieces.  It is safe to use these
- * original domains because the difference between, say, A' and A is
- * the domains of pw2-pieces that have been removed before and
- * those domains are disjoint from B.  A' is used instead of A
- * because the continued updating of A may result in this domain
- * getting broken up into more disjuncts.
  *
  * After the updated domains have been computed, the result is constructed
- * from "pw1", "pw2", "list1" and "list2".  If there are any pieces
+ * from "pw1", "pw2", data[0].cell and data[1].cell.  If there are any pieces
  * in "pw1" and "pw2" with the same function value expression, then
  * they are combined into a single piece in the result.
  * In order to be able to do this efficiently, the pieces of "pw1" and
@@ -183,11 +296,11 @@
 	__isl_take PW *pw1, __isl_take PW *pw2,
 	__isl_give isl_set *(*cmp)(__isl_take EL *el1, __isl_take EL *el2))
 {
+	S(PW,union_opt_cmp_data) data[2] = { { pw1, NULL }, { pw2, NULL } };
 	int i, j;
+	isl_size n1, n2;
 	PW *res = NULL;
 	isl_ctx *ctx;
-	isl_set *set = NULL;
-	isl_set_list *list1 = NULL, *list2 = NULL;
 
 	if (!pw1 || !pw2)
 		goto error;
@@ -207,47 +320,40 @@
 		return pw1;
 	}
 
-	pw1 = FN(PW,sort)(pw1);
-	pw2 = FN(PW,sort)(pw2);
-	if (!pw1 || !pw2)
+	for (i = 0; i < 2; ++i) {
+		data[i].pw = FN(PW,sort)(data[i].pw);
+		data[i].cell = FN(PW,extract_domains)(data[i].pw);
+	}
+
+	n1 = FN(PW,n_piece)(data[0].pw);
+	n2 = FN(PW,n_piece)(data[1].pw);
+	if (n1 < 0 || n2 < 0)
 		goto error;
-
-	list1 = FN(PW,extract_domains)(pw1);
-	list2 = FN(PW,extract_domains)(pw2);
-
-	for (i = 0; i < pw1->n; ++i) {
-		for (j = 0; j < pw2->n; ++j) {
+	for (i = 0; i < n1; ++i) {
+		for (j = 0; j < n2; ++j) {
 			isl_bool disjoint;
-			isl_set *better, *set_i, *set_j;
+			isl_set *set_i, *set_j;
 
-			disjoint = isl_set_is_disjoint(pw1->p[i].set,
-							pw2->p[j].set);
+			set_i = FN(PW,peek_domain_at)(data[0].pw, i);
+			set_j = FN(PW,peek_domain_at)(data[1].pw, j);
+			disjoint = isl_set_is_disjoint(set_i, set_j);
 			if (disjoint < 0)
 				goto error;
 			if (disjoint)
 				continue;
-			better = FN(PW,better)(pw2->p[j].FIELD,
-						pw1->p[i].FIELD, cmp);
-			set_i = isl_set_list_get_set(list1, i);
-			set_j = isl_set_copy(pw2->p[j].set);
-			set_i = FN(PW,worse_or_out)(set_i,
-						isl_set_copy(better), set_j);
-			list1 = isl_set_list_set_set(list1, i, set_i);
-			set_i = isl_set_copy(pw1->p[i].set);
-			set_j = isl_set_list_get_set(list2, j);
-			set_j = FN(PW,better_or_out)(set_j, better, set_i);
-			list2 = isl_set_list_set_set(list2, j, set_j);
+			if (FN(PW,union_opt_cmp_two)(&data[0], i,
+							&data[1], j, cmp) < 0)
+				goto error;
 		}
 	}
 
-	res = FN(PW,merge)(pw1, pw2, list1, list2);
+	res = FN(PW,merge)(&data[0], &data[1]);
+	for (i = 0; i < 2; ++i)
+		FN(PW,union_opt_cmp_data_clear)(&data[i]);
 
 	return res;
 error:
-	isl_set_list_free(list1);
-	isl_set_list_free(list2);
-	FN(PW,free)(pw1);
-	FN(PW,free)(pw2);
-	isl_set_free(set);
+	for (i = 0; i < 2; ++i)
+		FN(PW,union_opt_cmp_data_clear)(&data[i]);
 	return FN(PW,free)(res);
 }
diff --git a/lib/External/isl/isl_seq.c b/lib/External/isl/isl_seq.c
index 8e6c84c..fb2100e 100644
--- a/lib/External/isl/isl_seq.c
+++ b/lib/External/isl/isl_seq.c
@@ -125,9 +125,12 @@
 	isl_int_clear(tmp);
 }
 
-/*
- * Let d = dst[pos] and s = src[pos]
- * dst is replaced by |s| dst - sgn(s)d src
+/* Eliminate element "pos" from "dst" using "src".
+ * In particular, let d = dst[pos] and s = src[pos], then
+ * dst is replaced by (|s| dst - sgn(s)d src)/gcd(s,d),
+ * such that dst[pos] is zero after the elimination.
+ * If "m" is not NULL, then *m is multiplied by |s|/gcd(s,d).
+ * That is, it is multiplied by the same factor as "dst".
  */
 void isl_seq_elim(isl_int *dst, isl_int *src, unsigned pos, unsigned len,
 		  isl_int *m)
diff --git a/lib/External/isl/isl_space.c b/lib/External/isl/isl_space.c
index 9e0cfb2..1aa0f60 100644
--- a/lib/External/isl/isl_space.c
+++ b/lib/External/isl/isl_space.c
@@ -122,6 +122,22 @@
 }
 
 /* Check that "space" is the space of a map
+ * where the domain is a wrapped map space.
+ */
+isl_stat isl_space_check_domain_is_wrapping(__isl_keep isl_space *space)
+{
+	isl_bool wrapping;
+
+	wrapping = isl_space_domain_is_wrapping(space);
+	if (wrapping < 0)
+		return isl_stat_error;
+	if (!wrapping)
+		isl_die(isl_space_get_ctx(space), isl_error_invalid,
+			"domain not a product", return isl_stat_error);
+	return isl_stat_ok;
+}
+
+/* Check that "space" is the space of a map
  * where the range is a wrapped map space.
  */
 isl_stat isl_space_check_range_is_wrapping(__isl_keep isl_space *space)
@@ -929,6 +945,20 @@
 					space2, isl_dim_out);
 }
 
+/* Check that a match involving "space" was successful.
+ * That is, check that "match" is equal to isl_bool_true.
+ */
+static isl_stat check_match(__isl_keep isl_space *space, isl_bool match)
+{
+	if (match < 0)
+		return isl_stat_error;
+	if (!match)
+		isl_die(isl_space_get_ctx(space), isl_error_invalid,
+			"incompatible spaces", return isl_stat_error);
+
+	return isl_stat_ok;
+}
+
 /* Check that the two spaces are the same,
  * apart from positions and names of parameters.
  */
@@ -938,13 +968,7 @@
 	isl_bool is_equal;
 
 	is_equal = isl_space_has_equal_tuples(space1, space2);
-	if (is_equal < 0)
-		return isl_stat_error;
-	if (!is_equal)
-		isl_die(isl_space_get_ctx(space1), isl_error_invalid,
-			"incompatible spaces", return isl_stat_error);
-
-	return isl_stat_ok;
+	return check_match(space1, is_equal);
 }
 
 /* Check if the tuple of type "type1" of "space1" is the same as
@@ -989,6 +1013,41 @@
 	return isl_bool_true;
 }
 
+/* Is the tuple "inner" within the wrapped relation inside tuple "outer"
+ * of "space1" equal to tuple "type2" of "space2"?
+ */
+isl_bool isl_space_wrapped_tuple_is_equal(__isl_keep isl_space *space1,
+	enum isl_dim_type outer, enum isl_dim_type inner,
+	__isl_keep isl_space *space2, enum isl_dim_type type2)
+{
+	int pos;
+	isl_space *nested;
+
+	if (!space1)
+		return isl_bool_error;
+	if (outer != isl_dim_in && outer != isl_dim_out)
+		isl_die(isl_space_get_ctx(space1), isl_error_invalid,
+			"only input, output and set tuples "
+			"can have nested relations", return isl_bool_error);
+	pos = outer - isl_dim_in;
+	nested = isl_space_peek_nested(space1, pos);
+	return isl_space_tuple_is_equal(nested, inner, space2, type2);
+}
+
+/* Check that the tuple "inner" within the wrapped relation inside tuple "outer"
+ * of "space1" is equal to tuple "type2" of "space2".
+ */
+isl_stat isl_space_check_wrapped_tuple_is_equal(__isl_keep isl_space *space1,
+	enum isl_dim_type outer, enum isl_dim_type inner,
+	__isl_keep isl_space *space2, enum isl_dim_type type2)
+{
+	isl_bool is_equal;
+
+	is_equal = isl_space_wrapped_tuple_is_equal(space1, outer, inner,
+							space2, type2);
+	return check_match(space1, is_equal);
+}
+
 static isl_bool match(__isl_keep isl_space *space1, enum isl_dim_type type1,
 	__isl_keep isl_space *space2, enum isl_dim_type type2)
 {
@@ -1525,11 +1584,8 @@
 	isl_space *nested;
 	isl_space *domain;
 
-	if (!space)
-		return NULL;
-	if (!isl_space_domain_is_wrapping(space))
-		isl_die(isl_space_get_ctx(space), isl_error_invalid,
-			"domain not a product", return isl_space_free(space));
+	if (isl_space_check_domain_is_wrapping(space) < 0)
+		return isl_space_free(space);
 
 	nested = space->nested[0];
 	domain = isl_space_copy(space);
@@ -1564,11 +1620,8 @@
 	isl_space *nested;
 	isl_space *range;
 
-	if (!space)
-		return NULL;
-	if (!isl_space_domain_is_wrapping(space))
-		isl_die(isl_space_get_ctx(space), isl_error_invalid,
-			"domain not a product", return isl_space_free(space));
+	if (isl_space_check_domain_is_wrapping(space) < 0)
+		return isl_space_free(space);
 
 	nested = space->nested[0];
 	range = isl_space_copy(space);
@@ -2424,13 +2477,7 @@
 	isl_bool is_equal;
 
 	is_equal = isl_space_has_domain_tuples(space1, space2);
-	if (is_equal < 0)
-		return isl_stat_error;
-	if (!is_equal)
-		isl_die(isl_space_get_ctx(space1), isl_error_invalid,
-			"incompatible spaces", return isl_stat_error);
-
-	return isl_stat_ok;
+	return check_match(space1, is_equal);
 }
 
 /* Check that the tuples of "space1" correspond to those
@@ -2581,6 +2628,8 @@
 
 /* Return a hash value that digests the tuples of "space",
  * i.e., that ignores the parameters.
+ * Changes in this function should be reflected
+ * in isl_space_get_tuple_domain_hash.
  */
 uint32_t isl_space_get_tuple_hash(__isl_keep isl_space *space)
 {
@@ -2595,7 +2644,9 @@
 	return hash;
 }
 
-uint32_t isl_space_get_hash(__isl_keep isl_space *space)
+/* Return the hash value of "space".
+ */
+uint32_t isl_space_get_full_hash(__isl_keep isl_space *space)
 {
 	uint32_t hash;
 
@@ -2609,11 +2660,11 @@
 	return hash;
 }
 
-/* Return the hash value of the domain of "space".
- * That is, isl_space_get_domain_hash(space) is equal to
- * isl_space_get_hash(isl_space_domain(space)).
+/* Return the hash value of the domain tuple of "space".
+ * That is, isl_space_get_tuple_domain_hash(space) is equal to
+ * isl_space_get_tuple_hash(isl_space_domain(space)).
  */
-uint32_t isl_space_get_domain_hash(__isl_keep isl_space *space)
+uint32_t isl_space_get_tuple_domain_hash(__isl_keep isl_space *space)
 {
 	uint32_t hash;
 
@@ -2621,7 +2672,6 @@
 		return 0;
 
 	hash = isl_hash_init();
-	hash = isl_hash_params(hash, space);
 	hash = isl_hash_tuples_domain(hash, space);
 
 	return hash;
diff --git a/lib/External/isl/isl_space_private.h b/lib/External/isl/isl_space_private.h
index 4e9ce6d..140749e 100644
--- a/lib/External/isl/isl_space_private.h
+++ b/lib/External/isl/isl_space_private.h
@@ -28,8 +28,8 @@
 	unsigned n_div);
 
 uint32_t isl_space_get_tuple_hash(__isl_keep isl_space *space);
-uint32_t isl_space_get_hash(__isl_keep isl_space *space);
-uint32_t isl_space_get_domain_hash(__isl_keep isl_space *space);
+uint32_t isl_space_get_tuple_domain_hash(__isl_keep isl_space *space);
+uint32_t isl_space_get_full_hash(__isl_keep isl_space *space);
 
 isl_bool isl_space_has_domain_tuples(__isl_keep isl_space *space1,
 	__isl_keep isl_space *space2);
@@ -43,6 +43,12 @@
 	__isl_keep isl_space *space2);
 isl_stat isl_space_check_domain_wrapped_domain_tuples(
 	__isl_keep isl_space *space1, __isl_keep isl_space *space2);
+isl_bool isl_space_wrapped_tuple_is_equal(__isl_keep isl_space *space1,
+	enum isl_dim_type outer, enum isl_dim_type inner,
+	__isl_keep isl_space *space2, enum isl_dim_type type2);
+isl_stat isl_space_check_wrapped_tuple_is_equal(__isl_keep isl_space *space1,
+	enum isl_dim_type outer, enum isl_dim_type inner,
+	__isl_keep isl_space *space2, enum isl_dim_type type2);
 
 isl_size isl_space_wrapped_dim(__isl_keep isl_space *space,
 	enum isl_dim_type outer, enum isl_dim_type inner);
@@ -66,6 +72,7 @@
 	enum isl_dim_type type);
 __isl_give isl_space *isl_space_flatten(__isl_take isl_space *space);
 
+isl_stat isl_space_check_domain_is_wrapping(__isl_keep isl_space *space);
 isl_stat isl_space_check_range_is_wrapping(__isl_keep isl_space *space);
 
 __isl_give isl_space *isl_space_replace_params(__isl_take isl_space *dst,
diff --git a/lib/External/isl/isl_tab.c b/lib/External/isl/isl_tab.c
index b6d0c37..4152735 100644
--- a/lib/External/isl/isl_tab.c
+++ b/lib/External/isl/isl_tab.c
@@ -1787,17 +1787,6 @@
 	return r;
 }
 
-/* Add a variable to the tableau and allocate a column for it.
- * Return the index into the variable array "var".
- */
-int isl_tab_allocate_var(struct isl_tab *tab)
-{
-	if (!tab)
-		return -1;
-
-	return isl_tab_insert_var(tab, tab->n_var);
-}
-
 /* Add a row to the tableau.  The row is given as an affine combination
  * of the original variables and needs to be expressed in terms of the
  * column variables.
@@ -3884,7 +3873,8 @@
 	if (n_div < 0)
 		return isl_stat_error;
 	off = tab->n_var - n_div;
-	if (isl_basic_map_drop_div(tab->bmap, pos - off) < 0)
+	tab->bmap = isl_basic_map_drop_div(tab->bmap, pos - off);
+	if (!tab->bmap)
 		return isl_stat_error;
 	if (tab->samples) {
 		tab->samples = isl_mat_drop_cols(tab->samples, 1 + pos, 1);
diff --git a/lib/External/isl/isl_tab.h b/lib/External/isl/isl_tab.h
index 49aefe3..b580245 100644
--- a/lib/External/isl/isl_tab.h
+++ b/lib/External/isl/isl_tab.h
@@ -299,7 +299,6 @@
 int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new) WARN_UNUSED;
 int isl_tab_allocate_con(struct isl_tab *tab) WARN_UNUSED;
 int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new) WARN_UNUSED;
-int isl_tab_allocate_var(struct isl_tab *tab) WARN_UNUSED;
 int isl_tab_insert_var(struct isl_tab *tab, int pos) WARN_UNUSED;
 int isl_tab_pivot(struct isl_tab *tab, int row, int col) WARN_UNUSED;
 int isl_tab_add_row(struct isl_tab *tab, isl_int *line) WARN_UNUSED;
diff --git a/lib/External/isl/isl_tab_pip.c b/lib/External/isl/isl_tab_pip.c
index 980acb9..b8659e0 100644
--- a/lib/External/isl/isl_tab_pip.c
+++ b/lib/External/isl/isl_tab_pip.c
@@ -4379,6 +4379,7 @@
 	}
 	other = bmap_n_div - common;
 	if (dom->n_div - common > 0) {
+		bmap = isl_basic_map_cow(bmap);
 		bmap = isl_basic_map_extend(bmap, dom->n_div - common, 0, 0);
 		if (!bmap)
 			return NULL;
diff --git a/lib/External/isl/isl_test.c b/lib/External/isl/isl_test.c
index aac63e4..d609442 100644
--- a/lib/External/isl/isl_test.c
+++ b/lib/External/isl/isl_test.c
@@ -1402,76 +1402,47 @@
 	return isl_stat_ok;
 }
 
-/* Pairs of maps and the corresponding expected results of
- * isl_map_plain_unshifted_simple_hull.
+/* Inputs for simple hull tests, consisting of
+ * the specific simple hull function, the input set and the expected result.
  */
 struct {
-	const char *map;
-	const char *hull;
-} plain_unshifted_simple_hull_tests[] = {
-	{ "{ [i] -> [j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }",
-	  "{ [i] -> [j] : i >= 1 }" },
-	{ "{ [n] -> [i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or "
-		"(j mod 4 = 2 and k mod 6 = n) }",
-	  "{ [n] -> [i,j,k] : j mod 4 = 2 }" },
-};
-
-/* Basic tests for isl_map_plain_unshifted_simple_hull.
- */
-static int test_plain_unshifted_simple_hull(isl_ctx *ctx)
-{
-	int i;
-	isl_map *map;
-	isl_basic_map *hull, *expected;
-	isl_bool equal;
-
-	for (i = 0; i < ARRAY_SIZE(plain_unshifted_simple_hull_tests); ++i) {
-		const char *str;
-		str = plain_unshifted_simple_hull_tests[i].map;
-		map = isl_map_read_from_str(ctx, str);
-		str = plain_unshifted_simple_hull_tests[i].hull;
-		expected = isl_basic_map_read_from_str(ctx, str);
-		hull = isl_map_plain_unshifted_simple_hull(map);
-		equal = isl_basic_map_is_equal(hull, expected);
-		isl_basic_map_free(hull);
-		isl_basic_map_free(expected);
-		if (equal < 0)
-			return -1;
-		if (!equal)
-			isl_die(ctx, isl_error_unknown, "unexpected hull",
-				return -1);
-	}
-
-	return 0;
-}
-
-/* Pairs of sets and the corresponding expected results of
- * isl_set_unshifted_simple_hull.
- */
-struct {
+	__isl_give isl_basic_set *(*fn)(__isl_take isl_set *set);
 	const char *set;
 	const char *hull;
-} unshifted_simple_hull_tests[] = {
-	{ "{ [0,x,y] : x <= -1; [1,x,y] : x <= y <= -x; [2,x,y] : x <= 1 }",
+} simple_hull_tests[] = {
+	{ &isl_set_plain_unshifted_simple_hull,
+	  "{ [i,j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }",
+	  "{ [i,j] : i >= 1 }" },
+	{ &isl_set_plain_unshifted_simple_hull,
+	  "{ [n,i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or "
+		"(j mod 4 = 2 and k mod 6 = n) }",
+	  "{ [n,i,j,k] : j mod 4 = 2 }" },
+	{ &isl_set_unshifted_simple_hull,
+	  "{ [0,x,y] : x <= -1; [1,x,y] : x <= y <= -x; [2,x,y] : x <= 1 }",
 	  "{ [t,x,y] : 0 <= t <= 2 and x <= 1 }" },
+	{ &isl_set_simple_hull,
+	  "{ [a, b] : b <= 0 and "
+			"2*floor((-2*floor((b)/2))/5) >= a - floor((b)/2); "
+	    "[a, b] : a mod 2 = 0 }",
+	  "{ [a, b] }" },
 };
 
-/* Basic tests for isl_set_unshifted_simple_hull.
+/* Basic tests for various simple hull functions.
  */
-static int test_unshifted_simple_hull(isl_ctx *ctx)
+static int test_various_simple_hull(isl_ctx *ctx)
 {
 	int i;
 	isl_set *set;
 	isl_basic_set *hull, *expected;
 	isl_bool equal;
 
-	for (i = 0; i < ARRAY_SIZE(unshifted_simple_hull_tests); ++i) {
+	for (i = 0; i < ARRAY_SIZE(simple_hull_tests); ++i) {
 		const char *str;
-		str = unshifted_simple_hull_tests[i].set;
+		str = simple_hull_tests[i].set;
 		set = isl_set_read_from_str(ctx, str);
-		str = unshifted_simple_hull_tests[i].hull;
+		str = simple_hull_tests[i].hull;
 		expected = isl_basic_set_read_from_str(ctx, str);
-		hull = isl_set_unshifted_simple_hull(set);
+		hull = simple_hull_tests[i].fn(set);
 		equal = isl_basic_set_is_equal(hull, expected);
 		isl_basic_set_free(hull);
 		isl_basic_set_free(expected);
@@ -1508,9 +1479,7 @@
 
 	if (test_plain_unshifted_simple_hull_special(ctx) < 0)
 		return -1;
-	if (test_plain_unshifted_simple_hull(ctx) < 0)
-		return -1;
-	if (test_unshifted_simple_hull(ctx) < 0)
+	if (test_various_simple_hull(ctx) < 0)
 		return -1;
 
 	return 0;
@@ -1683,33 +1652,6 @@
 	return 0;
 }
 
-void test_gist_case(struct isl_ctx *ctx, const char *name)
-{
-	char *filename;
-	FILE *input;
-	struct isl_basic_set *bset1, *bset2;
-
-	filename = get_filename(ctx, name, "polylib");
-	assert(filename);
-	input = fopen(filename, "r");
-	assert(input);
-
-	bset1 = isl_basic_set_read_from_file(ctx, input);
-	bset2 = isl_basic_set_read_from_file(ctx, input);
-
-	bset1 = isl_basic_set_gist(bset1, bset2);
-
-	bset2 = isl_basic_set_read_from_file(ctx, input);
-
-	assert(isl_basic_set_is_equal(bset1, bset2) == 1);
-
-	isl_basic_set_free(bset1);
-	isl_basic_set_free(bset2);
-	free(filename);
-
-	fclose(input);
-}
-
 /* Check that computing the gist of "map" with respect to "context"
  * does not make any copy of "map" get marked empty.
  * Earlier versions of isl would end up doing that.
@@ -1858,6 +1800,9 @@
 	const char *context;
 	const char *gist;
 } gist_tests[] = {
+	{ "{ [1, -1, 3] }",
+	  "{ [1, b, 2 - b] : -1 <= b <= 2 }",
+	  "{ [a, -1, c] }" },
 	{ "{ [a, b, c] : a <= 15 and a >= 1 }",
 	  "{ [a, b, c] : exists (e0 = floor((-1 + a)/16): a >= 1 and "
 			"c <= 30 and 32e0 >= -62 + 2a + 2b - c and b >= 0) }",
@@ -1982,8 +1927,6 @@
 	if (test_gist_fail(ctx) < 0)
 		return -1;
 
-	test_gist_case(ctx, "gist1");
-
 	str = "[p0, p2, p3, p5, p6, p10] -> { [] : "
 	    "exists (e0 = [(15 + p0 + 15p6 + 15p10)/16], e1 = [(p5)/8], "
 	    "e2 = [(p6)/128], e3 = [(8p2 - p5)/128], "
@@ -3177,6 +3120,53 @@
 	return 0;
 }
 
+/* Check that the result of isl_set_min_multi_pw_aff
+ * on the union of the sets with string descriptions "s1" and "s2"
+ * consists of a single expression (on a single cell).
+ */
+static isl_stat check_single_expr_min(isl_ctx *ctx, const char *s1,
+	const char *s2)
+{
+	isl_size n;
+	isl_set *set1, *set2;
+	isl_multi_pw_aff *mpa;
+	isl_pw_multi_aff *pma;
+
+	set1 = isl_set_read_from_str(ctx, s1);
+	set2 = isl_set_read_from_str(ctx, s2);
+	set1 = isl_set_union(set1, set2);
+	mpa = isl_set_min_multi_pw_aff(set1);
+	pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
+	n = isl_pw_multi_aff_n_piece(pma);
+	isl_pw_multi_aff_free(pma);
+
+	if (n < 0)
+		return isl_stat_error;
+	if (n != 1)
+		isl_die(ctx, isl_error_unknown, "expecting single expression",
+			return isl_stat_error);
+	return isl_stat_ok;
+}
+
+/* A specialized isl_set_min_multi_pw_aff test that checks
+ * that the minimum of 2N and 3N for N >= 0 is represented
+ * by a single expression, without splitting off the special case N = 0.
+ * Do this for both orderings.
+ */
+static int test_min_mpa(isl_ctx *ctx)
+{
+	const char *s1, *s2;
+
+	s1 = "[N=0:] -> { [1, 3N:] }";
+	s2 = "[N=0:] -> { [10, 2N:] }";
+	if (check_single_expr_min(ctx, s1, s2) < 0)
+		return -1;
+	if (check_single_expr_min(ctx, s2, s1) < 0)
+		return -1;
+
+	return 0;
+}
+
 struct {
 	const char *set;
 	const char *obj;
@@ -3870,67 +3860,88 @@
 	return 0;
 }
 
-/* Check that computing a bound of a non-zero polynomial over an unbounded
- * domain does not produce a rational value.
- * In particular, check that the upper bound is infinity.
+/* Inputs for basic isl_pw_qpolynomial_bound tests.
+ * "type" is the type of bound that should be computed.
+ * "poly" is a string representation of the input.
+ * "bound" is a string representation of the expected result.
+ * "tight" is set if the result is expected to be tight.
  */
-static int test_bound_unbounded_domain(isl_ctx *ctx)
+static struct {
+	int tight;
+	enum isl_fold type;
+	const char *poly;
+	const char *bound;
+} bound_tests[] = {
+	/* Check that computing a bound of a non-zero polynomial
+	 * over an unbounded domain does not produce a rational value.
+	 * In particular, check that the upper bound is infinity.
+	 */
+	{ 0, isl_fold_max, "{ [m, n] -> -m * n }", "{ max(infty) }" },
+	{ 1, isl_fold_max, "{ [[a, b, c, d] -> [e]] -> 0 }",
+	  "{ [a, b, c, d] -> max(0) }" },
+	{ 1, isl_fold_max, "{ [[x] -> [x]] -> 1 : exists a : x = 2 a }",
+	  "{ [x] -> max(1) : x mod 2 = 0 }" },
+	{ 1, isl_fold_min, "{ [x=5:10] -> (x + 2)^2 }", "{ min(49) }" },
+	{ 1, isl_fold_max, "{ [0:10] -> 1 }", "{ max(1) }" },
+	{ 1, isl_fold_max, "{ [[m] -> [0:m]] -> m^2 }",
+	  "{ [m] -> max(m^2) : m >= 0 }" },
+};
+
+/* Check that the bound computation can handle differences
+ * in domain dimension names of the input polynomial and its domain.
+ */
+static isl_stat test_bound_space(isl_ctx *ctx)
 {
 	const char *str;
-	isl_pw_qpolynomial *pwqp;
-	isl_pw_qpolynomial_fold *pwf, *pwf2;
-	isl_bool equal;
-
-	str = "{ [m,n] -> -m * n }";
-	pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
-	pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL);
-	str = "{ infty }";
-	pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
-	pwf2 = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL);
-	equal = isl_pw_qpolynomial_fold_plain_is_equal(pwf, pwf2);
-	isl_pw_qpolynomial_fold_free(pwf);
-	isl_pw_qpolynomial_fold_free(pwf2);
-
-	if (equal < 0)
-		return -1;
-	if (!equal)
-		isl_die(ctx, isl_error_unknown,
-			"expecting infinite polynomial bound", return -1);
-
-	return 0;
-}
-
-static int test_bound(isl_ctx *ctx)
-{
-	const char *str;
-	isl_size dim;
+	isl_set *set;
 	isl_pw_qpolynomial *pwqp;
 	isl_pw_qpolynomial_fold *pwf;
 
-	if (test_bound_unbounded_domain(ctx) < 0)
+	str = "{ [[c] -> [c]] }";
+	set = isl_set_read_from_str(ctx, str);
+	str = "{ [[a] -> [b]] -> 1 }";
+	pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
+	pwqp = isl_pw_qpolynomial_intersect_domain(pwqp, set);
+	pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL);
+	isl_pw_qpolynomial_fold_free(pwf);
+
+	return isl_stat_non_null(pwf);
+}
+
+/* Perform basic isl_pw_qpolynomial_bound tests.
+ */
+static int test_bound(isl_ctx *ctx)
+{
+	int i;
+
+	if (test_bound_space(ctx) < 0)
 		return -1;
 
-	str = "{ [[a, b, c, d] -> [e]] -> 0 }";
-	pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
-	pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL);
-	dim = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in);
-	isl_pw_qpolynomial_fold_free(pwf);
-	if (dim < 0)
-		return -1;
-	if (dim != 4)
-		isl_die(ctx, isl_error_unknown, "unexpected input dimension",
-			return -1);
+	for (i = 0; i < ARRAY_SIZE(bound_tests); ++i) {
+		const char *str;
+		enum isl_fold type;
+		isl_bool equal, tight;
+		isl_pw_qpolynomial *pwqp;
+		isl_pw_qpolynomial_fold *pwf1, *pwf2;
 
-	str = "{ [[x]->[x]] -> 1 : exists a : x = 2 a }";
-	pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
-	pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL);
-	dim = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in);
-	isl_pw_qpolynomial_fold_free(pwf);
-	if (dim < 0)
-		return -1;
-	if (dim != 1)
-		isl_die(ctx, isl_error_unknown, "unexpected input dimension",
-			return -1);
+		str = bound_tests[i].poly;
+		pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
+		type = bound_tests[i].type;
+		pwf1 = isl_pw_qpolynomial_bound(pwqp, type, &tight);
+		str = bound_tests[i].bound;
+		pwf2 = isl_pw_qpolynomial_fold_read_from_str(ctx, str);
+		equal = isl_pw_qpolynomial_fold_plain_is_equal(pwf1, pwf2);
+		isl_pw_qpolynomial_fold_free(pwf2);
+		isl_pw_qpolynomial_fold_free(pwf1);
+		if (equal < 0)
+			return -1;
+		if (!equal)
+			isl_die(ctx, isl_error_unknown,
+				"incorrect bound result", return -1);
+		if (bound_tests[i].tight && !tight)
+			isl_die(ctx, isl_error_unknown,
+				"bound unexpectedly not tight", return -1);
+	}
 
 	return 0;
 }
@@ -5600,6 +5611,26 @@
 	{ &isl_union_pw_multi_aff_union_add, "{ B[x] -> A[1] : x <= 0 }",
 	  "{ B[x] -> A[2] : x >= 0 }",
 	  "{ B[x] -> A[1] : x < 0; B[x] -> A[2] : x > 0; B[0] -> A[3] }" },
+	{
+  &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff,
+	  "{ B[x] -> C[x + 2] }",
+	  "{ D[y] -> B[2y] }",
+	  "{ }" },
+	{
+  &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff,
+	  "{ [A[x] -> B[x + 1]] -> C[x + 2] }",
+	  "{ D[y] -> B[2y] }",
+	  "{ }" },
+	{
+  &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff,
+	  "{ [A[x] -> B[x + 1]] -> C[x + 2]; B[x] -> C[x + 2] }",
+	  "{ D[y] -> A[2y] }",
+	  "{ [D[y] -> B[2y + 1]] -> C[2y + 2] }" },
+	{
+  &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff,
+	  "{ T[A[x] -> B[x + 1]] -> C[x + 2]; B[x] -> C[x + 2] }",
+	  "{ D[y] -> A[2y] }",
+	  "{ T[D[y] -> B[2y + 1]] -> C[2y + 2] }" },
 };
 
 /* Perform some basic tests of binary operations on
@@ -7938,6 +7969,18 @@
 	  "[n] -> { A[i] -> [] : 0 <= i <= n; B[] -> [] }",
 	  "[m] -> { A[i] -> [] : 0 <= i <= m; C[] -> [] }",
 	  "[m, n] -> { A[i] -> [] : 0 <= i <= n and i <= m }" },
+	{ &isl_union_map_intersect_domain_factor_domain,
+	  "{ [A[i] -> B[i + 1]] -> C[i + 2] }",
+	  "[N] -> { B[i] -> C[N] }",
+	  "{ }" },
+	{ &isl_union_map_intersect_domain_factor_domain,
+	  "{ [A[i] -> B[i + 1]] -> C[i + 2] }",
+	  "[N] -> { A[i] -> C[N] }",
+	  "[N] -> { [A[N - 2] -> B[N - 1]] -> C[N] }" },
+	{ &isl_union_map_intersect_domain_factor_domain,
+	  "{ T[A[i] -> B[i + 1]] -> C[i + 2] }",
+	  "[N] -> { A[i] -> C[N] }",
+	  "[N] -> { T[A[N - 2] -> B[N - 1]] -> C[N] }" },
 	{ &isl_union_map_intersect_domain_factor_range,
 	  "{ [A[i] -> B[i + 1]] -> C[i + 2] }",
 	  "[N] -> { B[i] -> C[N] }",
@@ -8160,11 +8203,21 @@
 	  "{ A[i,j] -> B[i',j'] }",
 	  "F[{ A[i,j] -> [i] : i > j; B[i,j] -> [i] }]",
 	  "{ A[i,j] -> B[i,j'] : i > j }" },
+	{ &isl_union_map_lex_le_at_multi_union_pw_aff,
+	  "{ A[i,j] -> B[i',j'] }",
+	  "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, "
+	    "{ A[i,j] -> [j]; B[i,j] -> [j] }]",
+	  "{ A[i,j] -> B[i',j'] : i,j <<= i',j' }" },
 	{ &isl_union_map_lex_lt_at_multi_union_pw_aff,
 	  "{ A[i,j] -> B[i',j'] }",
 	  "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, "
 	    "{ A[i,j] -> [j]; B[i,j] -> [j] }]",
 	  "{ A[i,j] -> B[i',j'] : i,j << i',j' }" },
+	{ &isl_union_map_lex_ge_at_multi_union_pw_aff,
+	  "{ A[i,j] -> B[i',j'] }",
+	  "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, "
+	    "{ A[i,j] -> [j]; B[i,j] -> [j] }]",
+	  "{ A[i,j] -> B[i',j'] : i,j >>= i',j' }" },
 	{ &isl_union_map_lex_gt_at_multi_union_pw_aff,
 	  "{ A[i,j] -> B[i',j'] }",
 	  "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, "
@@ -10006,6 +10059,48 @@
 	return isl_stat_ok;
 }
 
+/* String descriptions of boxes that
+ * are used for reconstructing box maps from their lower and upper bounds.
+ */
+static const char *multi_pw_aff_box_tests[] = {
+	"{ A[x, y] -> [] : x + y >= 0 }",
+	"[N] -> { A[x, y] -> [x] : x + y <= N }",
+	"[N] -> { A[x, y] -> [x : y] : x + y <= N }",
+};
+
+/* Check that map representations of boxes can be reconstructed
+ * from their lower and upper bounds.
+ */
+static isl_stat test_multi_pw_aff_box(isl_ctx *ctx)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(multi_pw_aff_box_tests); ++i) {
+		const char *str;
+		isl_bool equal;
+		isl_map *map, *box;
+		isl_multi_pw_aff *min, *max;
+
+		str = multi_pw_aff_box_tests[i];
+		map = isl_map_read_from_str(ctx, str);
+		min = isl_map_min_multi_pw_aff(isl_map_copy(map));
+		max = isl_map_max_multi_pw_aff(isl_map_copy(map));
+		box = isl_map_universe(isl_map_get_space(map));
+		box = isl_map_lower_bound_multi_pw_aff(box, min);
+		box = isl_map_upper_bound_multi_pw_aff(box, max);
+		equal = isl_map_is_equal(map, box);
+		isl_map_free(map);
+		isl_map_free(box);
+		if (equal < 0)
+			return isl_stat_error;
+		if (!equal)
+			isl_die(ctx, isl_error_unknown,
+				"unexpected result", return isl_stat_error);
+	}
+
+	return isl_stat_ok;
+}
+
 /* Perform some tests on multi piecewise affine expressions.
  */
 static int test_multi_pw_aff(isl_ctx *ctx)
@@ -10016,6 +10111,8 @@
 		return -1;
 	if (test_multi_pw_aff_3(ctx) < 0)
 		return -1;
+	if (test_multi_pw_aff_box(ctx) < 0)
+		return -1;
 	return 0;
 }
 
@@ -10560,7 +10657,7 @@
 }
 
 /* Check that the domain hash of a space is equal to the hash
- * of the domain of the space.
+ * of the domain of the space, both ignoring parameters.
  */
 static int test_domain_hash(isl_ctx *ctx)
 {
@@ -10571,9 +10668,9 @@
 	map = isl_map_read_from_str(ctx, "[n] -> { A[B[x] -> C[]] -> D[] }");
 	space = isl_map_get_space(map);
 	isl_map_free(map);
-	hash1 = isl_space_get_domain_hash(space);
+	hash1 = isl_space_get_tuple_domain_hash(space);
 	space = isl_space_domain(space);
-	hash2 = isl_space_get_hash(space);
+	hash2 = isl_space_get_tuple_hash(space);
 	isl_space_free(space);
 
 	if (!space)
@@ -10761,6 +10858,7 @@
 	{ "intersect", &test_intersect },
 	{ "lexmin", &test_lexmin },
 	{ "min", &test_min },
+	{ "set lower bounds", &test_min_mpa },
 	{ "gist", &test_gist },
 	{ "piecewise quasi-polynomials", &test_pwqp },
 	{ "lift", &test_lift },
diff --git a/lib/External/isl/isl_test_imath.c b/lib/External/isl/isl_test_imath.c
index fdb0777..2ac39ad 100644
--- a/lib/External/isl/isl_test_imath.c
+++ b/lib/External/isl/isl_test_imath.c
@@ -34,7 +34,6 @@
 	assert(MP_SMALL_MAX == LONG_MAX);
 
 	assert(sizeof(mp_usmall) == sizeof(unsigned long));
-	assert(MP_USMALL_MIN == ULONG_MIN);
 	assert(MP_USMALL_MAX == ULONG_MAX);
 
 	retval = mp_int_init_value(&val, 0);
diff --git a/lib/External/isl/isl_type_has_space_templ.c b/lib/External/isl/isl_type_has_space_templ.c
new file mode 100644
index 0000000..313b27a
--- /dev/null
+++ b/lib/External/isl/isl_type_has_space_templ.c
@@ -0,0 +1,18 @@
+/*
+ * 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
+ */
+
+#define xFN(TYPE,NAME) TYPE ## _ ## NAME
+#define FN(TYPE,NAME) xFN(TYPE,NAME)
+
+/* Is the space of "obj" equal to "space"?
+ */
+isl_bool FN(TYPE,has_space)(__isl_keep TYPE *obj, __isl_keep isl_space *space)
+{
+	return isl_space_is_equal(FN(TYPE,peek_space)(obj), space);
+}
diff --git a/lib/External/isl/isl_union_eval.c b/lib/External/isl/isl_union_eval.c
index 4ddaeef..050eb8a 100644
--- a/lib/External/isl/isl_union_eval.c
+++ b/lib/External/isl/isl_union_eval.c
@@ -24,53 +24,57 @@
 	return isl_val_nan(ctx);
 }
 
-/* Do the tuples of "space" correspond to those of the domain of "part"?
- * That is, is the domain space of "part" equal to "space", ignoring parameters?
+/* Internal data structure for isl_union_*_eval.
+ *
+ * "pnt" is the point in which the function is evaluated.
+ * "v" stores the result and is initialized to zero.
  */
-static isl_bool FN(UNION,has_domain_space_tuples)(const void *entry,
-	const void *val)
-{
-	PART *part = (PART *)entry;
-	isl_space *space = (isl_space *) val;
+S(UNION,eval_data) {
+	isl_point *pnt;
+	isl_val *v;
+};
 
-	return FN(PART,has_domain_space_tuples)(part, space);
+/* Update the evaluation in data->v based on the evaluation of "part".
+ *
+ * Only (at most) a single part on which this function is called
+ * is assumed to evaluate to anything other than zero.
+ * Since the value is initialized to zero, the evaluation of "part"
+ * can simply be added.
+ */
+static isl_stat FN(UNION,eval_entry)(__isl_take PART *part, void *user)
+{
+	S(UNION,eval_data) *data = user;
+	isl_val *v;
+
+	v = FN(PART,eval)(part, isl_point_copy(data->pnt));
+	data->v = isl_val_add(data->v, v);
+
+	return isl_stat_non_null(data->v);
 }
 
+/* Evaluate "u" in the point "pnt".
+ */
 __isl_give isl_val *FN(UNION,eval)(__isl_take UNION *u,
 	__isl_take isl_point *pnt)
 {
-	uint32_t hash;
-	struct isl_hash_table_entry *entry;
+	S(UNION,eval_data) data = { pnt };
 	isl_bool is_void;
 	isl_space *space;
-	isl_val *v;
 
-	if (!u || !pnt)
-		goto error;
 	is_void = isl_point_is_void(pnt);
 	if (is_void < 0)
 		goto error;
 	if (is_void)
 		return FN(UNION,eval_void)(u, pnt);
 
-	space = isl_space_copy(pnt->dim);
-	if (!space)
-		goto error;
-	hash = isl_space_get_hash(space);
-	entry = isl_hash_table_find(u->space->ctx, &u->table,
-				    hash, &FN(UNION,has_domain_space_tuples),
-				    space, 0);
-	isl_space_free(space);
-	if (!entry)
-		goto error;
-	if (entry == isl_hash_table_entry_none) {
-		v = isl_val_zero(isl_point_get_ctx(pnt));
-		isl_point_free(pnt);
-	} else {
-		v = FN(PART,eval)(FN(PART,copy)(entry->data), pnt);
-	}
+	data.v = isl_val_zero(isl_point_get_ctx(pnt));
+	space = isl_point_peek_space(pnt);
+	if (FN(UNION,foreach_on_domain)(u, space,
+					&FN(UNION,eval_entry), &data) < 0)
+		data.v = isl_val_free(data.v);
 	FN(UNION,free)(u);
-	return v;
+	isl_point_free(pnt);
+	return data.v;
 error:
 	FN(UNION,free)(u);
 	isl_point_free(pnt);
diff --git a/lib/External/isl/isl_union_map.c b/lib/External/isl/isl_union_map.c
index 4595d7b..bd93dcc 100644
--- a/lib/External/isl/isl_union_map.c
+++ b/lib/External/isl/isl_union_map.c
@@ -32,6 +32,13 @@
 #include <uset_from_umap.c>
 #include <set_list_from_map_list_inl.c>
 
+#undef TYPE
+#define TYPE	isl_union_map
+static
+#include "has_single_reference_templ.c"
+static
+#include "check_single_reference_templ.c"
+
 /* Return the number of parameters of "umap", where "type"
  * is required to be set to isl_dim_param.
  */
@@ -402,20 +409,58 @@
 	return isl_union_map_space_has_equal_params(uset_to_umap(uset), space);
 }
 
-static isl_bool has_space(const void *entry, const void *val)
+/* Is the space of the map at "entry" equal to "space", ignoring parameters?
+ */
+static isl_bool has_space_tuples(const void *entry, const void *val)
 {
 	isl_map *map = (isl_map *)entry;
 	isl_space *space = (isl_space *) val;
 
-	return isl_space_is_equal(map->dim, space);
+	return isl_map_has_space_tuples(map, space);
+}
+
+/* Find the entry in "umap" with space "space" (ignoring parameters),
+ * returning isl_hash_table_entry_none if no such entry appears in "umap" and
+ * NULL on error.
+ * If "reserve" is set, then an entry is created if it does
+ * not exist already.  Since this modifies the hash table in-place,
+ * this means "umap" must have a single reference when "reserve" is set.
+ */
+static struct isl_hash_table_entry *isl_union_map_find_entry(
+	__isl_keep isl_union_map *umap, __isl_keep isl_space *space,
+	int reserve)
+{
+	uint32_t hash;
+
+	if (!umap || !space)
+		return NULL;
+	if (reserve && isl_union_map_check_single_reference(umap) < 0)
+		return NULL;
+
+	hash = isl_space_get_tuple_hash(space);
+	return isl_hash_table_find(isl_union_map_get_ctx(umap), &umap->table,
+				    hash, &has_space_tuples, space, reserve);
+}
+
+/* Find the entry in "uset" with space "space" (ignoring parameters),
+ * returning isl_hash_table_entry_none if no such entry appears in "uset" and
+ * NULL on error.
+ * If "reserve" is set, then an entry is created if it does
+ * not exist already.  In this case, a NULL return indicates an error.
+ */
+struct isl_hash_table_entry *isl_union_set_find_entry(
+	__isl_keep isl_union_set *uset, __isl_keep isl_space *space,
+	int reserve)
+{
+	return isl_union_map_find_entry(uset_to_umap(uset), space, reserve);
 }
 
 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
 	__isl_take isl_map *map)
 {
-	uint32_t hash;
 	struct isl_hash_table_entry *entry;
 	isl_bool aligned;
+	isl_space *space;
 
 	if (!map || !umap)
 		goto error;
@@ -435,12 +480,8 @@
 
 	umap = isl_union_map_cow(umap);
 
-	if (!map || !umap)
-		goto error;
-
-	hash = isl_space_get_hash(map->dim);
-	entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
-				    &has_space, map->dim, 1);
+	space = isl_map_peek_space(map);
+	entry = isl_union_map_find_entry(umap, space, 1);
 	if (!entry)
 		goto error;
 
@@ -701,17 +742,9 @@
 __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
 	__isl_take isl_space *space)
 {
-	uint32_t hash;
 	struct isl_hash_table_entry *entry;
 
-	space = isl_space_drop_all_params(space);
-	space = isl_space_align_params(space, isl_union_map_get_space(umap));
-	if (!umap || !space)
-		goto error;
-
-	hash = isl_space_get_hash(space);
-	entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
-				    &has_space, space, 0);
+	entry = isl_union_map_find_entry(umap, space, 0);
 	if (!entry)
 		goto error;
 	if (entry == isl_hash_table_entry_none)
@@ -734,17 +767,11 @@
 isl_bool isl_union_map_contains(__isl_keep isl_union_map *umap,
 	__isl_keep isl_space *space)
 {
-	uint32_t hash;
 	struct isl_hash_table_entry *entry;
 
 	space = isl_space_drop_all_params(isl_space_copy(space));
 	space = isl_space_align_params(space, isl_union_map_get_space(umap));
-	if (!space)
-		return isl_bool_error;
-
-	hash = isl_space_get_hash(space);
-	entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
-				    &has_space, space, 0);
+	entry = isl_union_map_find_entry(umap, space, 0);
 	isl_space_free(space);
 	if (!entry)
 		return isl_bool_error;
@@ -903,7 +930,6 @@
 static __isl_keep isl_maybe_isl_map bin_try_get_match(
 	struct isl_union_map_gen_bin_data *data, __isl_keep isl_map *map)
 {
-	uint32_t hash;
 	struct isl_hash_table_entry *entry2;
 	isl_space *space;
 	isl_maybe_isl_map res = { isl_bool_error, NULL };
@@ -918,12 +944,7 @@
 	space = isl_map_get_space(map);
 	if (data->control->match_space != &identity)
 		space = data->control->match_space(space);
-	if (!space)
-		return res;
-	hash = isl_space_get_hash(space);
-	entry2 = isl_hash_table_find(isl_union_map_get_ctx(data->umap2),
-				     &data->umap2->table, hash,
-				     &has_space, space, 0);
+	entry2 = isl_union_map_find_entry(data->umap2, space, 0);
 	isl_space_free(space);
 	if (entry2)
 		res.valid = isl_bool_ok(entry2 != isl_hash_table_entry_none);
@@ -1119,14 +1140,13 @@
 static isl_stat match_bin_entry(void **entry, void *user)
 {
 	struct isl_union_map_match_bin_data *data = user;
-	uint32_t hash;
 	struct isl_hash_table_entry *entry2;
+	isl_space *space;
 	isl_map *map = *entry;
 	int empty;
 
-	hash = isl_space_get_hash(map->dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_space, map->dim, 0);
+	space = isl_map_peek_space(map);
+	entry2 = isl_union_map_find_entry(data->umap2, space, 0);
 	if (!entry2)
 		return isl_stat_error;
 	if (entry2 == isl_hash_table_entry_none)
@@ -1447,6 +1467,22 @@
 }
 
 /* Intersect each map in "umap" in a space [A -> B] -> C
+ * with the corresponding map in "factor" in the space A -> C and
+ * collect the results.
+ */
+__isl_give isl_union_map *isl_union_map_intersect_domain_factor_domain(
+	__isl_take isl_union_map *umap, __isl_take isl_union_map *factor)
+{
+	struct isl_bin_op_control control = {
+		.filter = &isl_map_domain_is_wrapping,
+		.match_space = &isl_space_domain_factor_domain,
+		.fn_map = &isl_map_intersect_domain_factor_domain,
+	};
+
+	return gen_bin_op(umap, factor, &control);
+}
+
+/* Intersect each map in "umap" in a space [A -> B] -> C
  * with the corresponding map in "factor" in the space B -> C and
  * collect the results.
  */
@@ -2484,13 +2520,12 @@
 static isl_stat is_subset_entry(void **entry, void *user)
 {
 	struct isl_union_map_is_subset_data *data = user;
-	uint32_t hash;
 	struct isl_hash_table_entry *entry2;
+	isl_space *space;
 	isl_map *map = *entry;
 
-	hash = isl_space_get_hash(map->dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_space, map->dim, 0);
+	space = isl_map_peek_space(map);
+	entry2 = isl_union_map_find_entry(data->umap2, space, 0);
 	if (!entry2)
 		return isl_stat_error;
 	if (entry2 == isl_hash_table_entry_none) {
@@ -2515,28 +2550,16 @@
 {
 	struct isl_union_map_is_subset_data data = { NULL, isl_bool_true };
 
-	umap1 = isl_union_map_copy(umap1);
-	umap2 = isl_union_map_copy(umap2);
-	umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
-	umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
-
 	if (!umap1 || !umap2)
-		goto error;
+		return isl_bool_error;
 
 	data.umap2 = umap2;
 	if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
 				   &is_subset_entry, &data) < 0 &&
 	    data.is_subset)
-		goto error;
-
-	isl_union_map_free(umap1);
-	isl_union_map_free(umap2);
+		return isl_bool_error;
 
 	return data.is_subset;
-error:
-	isl_union_map_free(umap1);
-	isl_union_map_free(umap2);
-	return isl_bool_error;
 }
 
 isl_bool isl_union_set_is_subset(__isl_keep isl_union_set *uset1,
@@ -2601,13 +2624,12 @@
 static isl_stat is_disjoint_entry(void **entry, void *user)
 {
 	struct isl_union_map_is_disjoint_data *data = user;
-	uint32_t hash;
 	struct isl_hash_table_entry *entry2;
+	isl_space *space;
 	isl_map *map = *entry;
 
-	hash = isl_space_get_hash(map->dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_space, map->dim, 0);
+	space = isl_map_peek_space(map);
+	entry2 = isl_union_map_find_entry(data->umap2, space, 0);
 	if (!entry2)
 		return isl_stat_error;
 	if (entry2 == isl_hash_table_entry_none)
@@ -4234,27 +4256,21 @@
 						&isl_multi_pw_aff_eq_map);
 }
 
-/* Return the subset of "umap" where the domain has a lexicographically
- * smaller "mupa" value than the range.
- */
-__isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff(
-	__isl_take isl_union_map *umap,
-	__isl_take isl_multi_union_pw_aff *mupa)
-{
-	return isl_union_map_order_at_multi_union_pw_aff(umap, mupa,
-						&isl_multi_pw_aff_lex_lt_map);
-}
+#undef ORDER
+#define ORDER		le
+#include "isl_union_map_lex_templ.c"
 
-/* Return the subset of "umap" where the domain has a lexicographically
- * greater "mupa" value than the range.
- */
-__isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff(
-	__isl_take isl_union_map *umap,
-	__isl_take isl_multi_union_pw_aff *mupa)
-{
-	return isl_union_map_order_at_multi_union_pw_aff(umap, mupa,
-						&isl_multi_pw_aff_lex_gt_map);
-}
+#undef ORDER
+#define ORDER		lt
+#include "isl_union_map_lex_templ.c"
+
+#undef ORDER
+#define ORDER		ge
+#include "isl_union_map_lex_templ.c"
+
+#undef ORDER
+#define ORDER		gt
+#include "isl_union_map_lex_templ.c"
 
 /* Return the union of the elements in the list "list".
  */
diff --git a/lib/External/isl/isl_union_map_lex_templ.c b/lib/External/isl/isl_union_map_lex_templ.c
new file mode 100644
index 0000000..b9df712
--- /dev/null
+++ b/lib/External/isl/isl_union_map_lex_templ.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014      INRIA Rocquencourt
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
+ * B.P. 105 - 78153 Le Chesnay, France
+ */
+
+#define xFN(TYPE,NAME) TYPE ## _ ## NAME
+#define FN(TYPE,NAME) xFN(TYPE,NAME)
+
+/* Return the subset of "umap" where the domain and the range
+ * have "mupa" values that lexicographically compare as "ORDER".
+ */
+__isl_give isl_union_map *FN(FN(isl_union_map_lex,ORDER),at_multi_union_pw_aff)(
+	__isl_take isl_union_map *umap,
+	__isl_take isl_multi_union_pw_aff *mupa)
+{
+	return isl_union_map_order_at_multi_union_pw_aff(umap, mupa,
+				&FN(FN(isl_multi_pw_aff_lex,ORDER),map));
+}
diff --git a/lib/External/isl/isl_union_map_private.h b/lib/External/isl/isl_union_map_private.h
index 2af6c2b..af52d9f 100644
--- a/lib/External/isl/isl_union_map_private.h
+++ b/lib/External/isl/isl_union_map_private.h
@@ -10,6 +10,10 @@
 	struct isl_hash_table	table;
 };
 
+struct isl_hash_table_entry *isl_union_set_find_entry(
+	__isl_keep isl_union_set *uset, __isl_keep isl_space *space,
+	int reserve);
+
 __isl_keep isl_space *isl_union_map_peek_space(__isl_keep isl_union_map *umap);
 __isl_keep isl_space *isl_union_set_peek_space(__isl_keep isl_union_set *uset);
 isl_bool isl_union_map_is_params(__isl_keep isl_union_map *umap);
diff --git a/lib/External/isl/isl_union_multi.c b/lib/External/isl/isl_union_multi.c
index f9bcc44..b630b18 100644
--- a/lib/External/isl/isl_union_multi.c
+++ b/lib/External/isl/isl_union_multi.c
@@ -18,7 +18,7 @@
 
 /* A group of expressions defined over the same domain space "domain_space".
  * The entries of "part_table" are the individual expressions,
- * keyed on the entire space of the expression.
+ * keyed on the entire space of the expression (ignoring parameters).
  *
  * Each UNION has its own groups, so there can only ever be a single
  * reference to each group.
@@ -30,7 +30,8 @@
 
 /* A union of expressions defined over different disjoint domains.
  * "space" describes the parameters.
- * The entries of "table" are keyed on the domain space of the entry and
+ * The entries of "table" are keyed on the domain space of the entry
+ * (ignoring parameters) and
  * contain groups of expressions that are defined over the same domain space.
  */
 struct UNION {
@@ -158,14 +159,16 @@
 	return NULL;
 }
 
-/* Is the space of "entry" equal to "space"?
+/* Is the space of "entry" equal to "space", ignoring parameters?
  */
-static isl_bool FN(UNION,has_space)(const void *entry, const void *val)
+static isl_bool FN(UNION,has_space_tuples)(const void *entry, const void *val)
 {
 	PART *part = (PART *) entry;
 	isl_space *space = (isl_space *) val;
+	isl_space *part_space;
 
-	return isl_space_is_equal(part->dim, space);
+	part_space = FN(PART,peek_space)(part);
+	return isl_space_has_equal_tuples(part_space, space);
 }
 
 /* Return a group equal to "group", but with a single reference.
@@ -221,15 +224,15 @@
 }
 
 /* Is the domain space of the group of expressions at "entry"
- * equal to that of "space"?
+ * equal to that of "space", ignoring parameters?
  */
-static isl_bool FN(UNION,group_has_same_domain_space)(const void *entry,
+static isl_bool FN(UNION,group_has_same_domain_space_tuples)(const void *entry,
 	const void *val)
 {
 	S(UNION,group) *group = (S(UNION,group) *) entry;
 	isl_space *space = (isl_space *) val;
 
-	return isl_space_is_domain_internal(group->domain_space, space);
+	return isl_space_has_domain_tuples(group->domain_space, space);
 }
 
 /* Return the entry, if any, in "u" that lives in "space".
@@ -254,9 +257,9 @@
 		return NULL;
 
 	ctx = FN(UNION,get_ctx)(u);
-	hash = isl_space_get_domain_hash(space);
+	hash = isl_space_get_tuple_domain_hash(space);
 	group_entry = isl_hash_table_find(ctx, &u->table, hash,
-			&FN(UNION,group_has_same_domain_space), space, reserve);
+		&FN(UNION,group_has_same_domain_space_tuples), space, reserve);
 	if (!group_entry || group_entry == isl_hash_table_entry_none)
 		return group_entry;
 	if (reserve && !group_entry->data) {
@@ -270,9 +273,9 @@
 	}
 	if (!group)
 		return NULL;
-	hash = isl_space_get_hash(space);
+	hash = isl_space_get_tuple_hash(space);
 	return isl_hash_table_find(ctx, &group->part_table, hash,
-				&FN(UNION,has_space), space, reserve);
+				&FN(UNION,has_space_tuples), space, reserve);
 }
 
 /* Remove "part_entry" from the hash table of "u".
@@ -297,9 +300,9 @@
 	part = part_entry->data;
 	ctx = FN(UNION,get_ctx)(u);
 	space = FN(PART,peek_space)(part);
-	hash = isl_space_get_domain_hash(space);
+	hash = isl_space_get_tuple_domain_hash(space);
 	group_entry = isl_hash_table_find(ctx, &u->table, hash,
-			    &FN(UNION,group_has_same_domain_space), space, 0);
+		    &FN(UNION,group_has_same_domain_space_tuples), space, 0);
 	if (!group_entry)
 		return FN(UNION,free)(u);
 	if (group_entry == isl_hash_table_entry_none)
@@ -383,9 +386,9 @@
 		return isl_stat_error;
 	ctx = FN(UNION,get_ctx)(u);
 	space = FN(PART,peek_space)(part);
-	hash = isl_space_get_domain_hash(space);
+	hash = isl_space_get_tuple_domain_hash(space);
 	group_entry = isl_hash_table_find(ctx, &u->table, hash,
-			    &FN(UNION,group_has_same_domain_space), space, 0);
+		    &FN(UNION,group_has_same_domain_space_tuples), space, 0);
 	if (!group_entry)
 		return isl_stat_error;
 	if (group_entry == isl_hash_table_entry_none)
diff --git a/lib/External/isl/isl_union_single.c b/lib/External/isl/isl_union_single.c
index 1ec7c45..e84706c 100644
--- a/lib/External/isl/isl_union_single.c
+++ b/lib/External/isl/isl_union_single.c
@@ -15,7 +15,8 @@
 
 /* A union of expressions defined over different domain spaces.
  * "space" describes the parameters.
- * The entries of "table" are keyed on the domain space of the entry.
+ * The entries of "table" are keyed on the domain space of the entry
+ * (ignoring parameters).
  */
 struct UNION {
 	int ref;
@@ -63,9 +64,10 @@
 				      &FN(UNION,call_on_copy), &data);
 }
 
-/* Is the domain space of "entry" equal to the domain of "space"?
+/* Is the domain space of "entry" equal to the domain of "space",
+ * ignoring parameters?
  */
-static isl_bool FN(UNION,has_same_domain_space)(const void *entry,
+static isl_bool FN(UNION,has_same_domain_space_tuples)(const void *entry,
 	const void *val)
 {
 	PART *part = (PART *)entry;
@@ -100,9 +102,9 @@
 		return NULL;
 
 	ctx = FN(UNION,get_ctx)(u);
-	hash = isl_space_get_domain_hash(space);
+	hash = isl_space_get_tuple_domain_hash(space);
 	entry = isl_hash_table_find(ctx, &u->table, hash,
-			&FN(UNION,has_same_domain_space), space, reserve);
+		&FN(UNION,has_same_domain_space_tuples), space, reserve);
 	if (!entry || entry == isl_hash_table_entry_none)
 		return entry;
 	if (reserve && !entry->data)
@@ -178,6 +180,47 @@
 	return isl_hash_table_foreach(ctx, &u->table, fn, user);
 }
 
+static isl_bool FN(PART,has_domain_space_tuples)(__isl_keep PART *part,
+	__isl_keep isl_space *space);
+
+/* Do the tuples of "space" correspond to those of the domain of "part"?
+ * That is, is the domain space of "part" equal to "space", ignoring parameters?
+ */
+static isl_bool FN(UNION,has_domain_space_tuples)(const void *entry,
+	const void *val)
+{
+	PART *part = (PART *)entry;
+	isl_space *space = (isl_space *) val;
+
+	return FN(PART,has_domain_space_tuples)(part, space);
+}
+
+/* Call "fn" on each part of "u" that has domain space "space".
+ *
+ * Since each entry is defined over a different domain space,
+ * simply look for an entry with the given domain space and
+ * call "fn" on the corresponding part if there is one.
+ */
+isl_stat FN(UNION,foreach_on_domain)(__isl_keep UNION *u,
+	__isl_keep isl_space *space,
+	isl_stat (*fn)(__isl_take PART *part, void *user), void *user)
+{
+	uint32_t hash;
+	struct isl_hash_table_entry *entry;
+
+	if (!u || !space)
+		return isl_stat_error;
+	hash = isl_space_get_tuple_hash(space);
+	entry = isl_hash_table_find(FN(UNION,get_ctx)(u), &u->table,
+				    hash, &FN(UNION,has_domain_space_tuples),
+				    space, 0);
+	if (!entry)
+		return isl_stat_error;
+	if (entry == isl_hash_table_entry_none)
+		return isl_stat_ok;
+	return fn(FN(PART,copy)(entry->data), user);
+}
+
 static isl_stat FN(UNION,free_u_entry)(void **entry, void *user)
 {
 	PART *part = *entry;
diff --git a/lib/External/isl/isl_union_templ.c b/lib/External/isl/isl_union_templ.c
index fcdc7f9..9439d9b 100644
--- a/lib/External/isl/isl_union_templ.c
+++ b/lib/External/isl/isl_union_templ.c
@@ -143,8 +143,6 @@
 {
 	struct isl_hash_table_entry *entry;
 
-	space = isl_space_replace_params(space, FN(UNION,peek_space)(u));
-
 	entry = FN(UNION,find_part_entry)(u, space, 0);
 	if (!entry)
 		goto error;
@@ -736,24 +734,15 @@
 	S(UNION,match_domain_control) *control;
 };
 
-static isl_bool FN(UNION,set_has_space)(const void *entry, const void *val)
-{
-	isl_set *set = (isl_set *)entry;
-	isl_space *space = (isl_space *)val;
-
-	return isl_space_is_equal(set->dim, space);
-}
-
 /* Find the set in data->uset that lives in the same space as the domain
- * of "part", apply data->fn to *entry and this set (if any), and add
- * the result to data->res.
+ * of "part" (ignoring parameters), apply data->fn to *entry and this set
+ * (if any), and add the result to data->res.
  */
 static isl_stat FN(UNION,match_domain_entry)(__isl_take PART *part, void *user)
 {
 	S(UNION,match_domain_data) *data = user;
-	uint32_t hash;
 	struct isl_hash_table_entry *entry2;
-	isl_space *space, *uset_space;
+	isl_space *space;
 
 	if (data->control->filter) {
 		isl_bool pass = data->control->filter(part);
@@ -763,14 +752,10 @@
 		}
 	}
 
-	uset_space = isl_union_set_peek_space(data->uset);
 	space = FN(PART,get_domain_space)(part);
 	if (data->control->match_space)
 		space = data->control->match_space(space);
-	space = isl_space_replace_params(space, uset_space);
-	hash = isl_space_get_hash(space);
-	entry2 = isl_hash_table_find(data->uset->dim->ctx, &data->uset->table,
-				     hash, &FN(UNION,set_has_space), space, 0);
+	entry2 = isl_union_set_find_entry(data->uset, space, 0);
 	isl_space_free(space);
 	if (!entry2 || entry2 == isl_hash_table_entry_none) {
 		FN(PART,free)(part);
diff --git a/lib/External/isl/ltmain.sh b/lib/External/isl/ltmain.sh
index a736cf9..0cb7f90 100644
--- a/lib/External/isl/ltmain.sh
+++ b/lib/External/isl/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-2"
+VERSION="2.4.6 Debian-2.4.6-14"
 package_revision=2.4.6
 
 
@@ -387,7 +387,7 @@
 # putting '$debug_cmd' at the start of all your functions, you can get
 # bash to show function call trace with:
 #
-#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+#    debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
 debug_cmd=${debug_cmd-":"}
 exit_cmd=:
 
@@ -1370,7 +1370,7 @@
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
+scriptversion=2015-10-07.11; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -1530,6 +1530,8 @@
 {
     $debug_cmd
 
+    _G_rc_run_hooks=false
+
     case " $hookable_fns " in
       *" $1 "*) ;;
       *) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -1538,16 +1540,16 @@
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
+      if eval $_G_hook '"$@"'; then
+        # store returned options list back into positional
+        # parameters for next 'cmd' execution.
+        eval _G_hook_result=\$${_G_hook}_result
+        eval set dummy "$_G_hook_result"; shift
+        _G_rc_run_hooks=:
+      fi
     done
 
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
+    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -1557,10 +1559,16 @@
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, you may remove/edit
+# any options that you action, and then pass back the remaining unprocessed
 # options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
+# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
+# hook's caller know that it should pay attention to
+# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
+# arguments are left untouched by the hook and therefore caller will ignore the
+# result variable.
+#
+# Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1570,9 +1578,11 @@
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
+#        # No change in '$@' (ignored completely by this hook).  There is
+#        # no need to do the equivalent (but slower) action:
+#        # func_quote_for_eval ${1+"$@"}
+#        # my_options_prep_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1581,25 +1591,37 @@
 #    {
 #        $debug_cmd
 #
+#        args_changed=false
+#
 #        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=: ;;
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
+#                         args_changed=:
 #                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@", we could need that later
+#                         # if $args_changed is true.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
+#        if $args_changed; then
+#          func_quote_for_eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_for_eval_result
+#        fi
+#
+#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1611,16 +1633,32 @@
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll alse need to manually amend $usage_message to reflect the extra
+# You'll also need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    _G_func_options_finish_exit=false
+    if func_run_hooks func_options ${1+"$@"}; then
+      func_options_finish_result=$func_run_hooks_result
+      _G_func_options_finish_exit=:
+    fi
+
+    $_G_func_options_finish_exit
+}
+
+
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1630,17 +1668,28 @@
 {
     $debug_cmd
 
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
+    _G_rc_options=false
 
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      if eval func_$my_func '${1+"$@"}'; then
+        eval _G_res_var='$'"func_${my_func}_result"
+        eval set dummy "$_G_res_var" ; shift
+        _G_rc_options=:
+      fi
+    done
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    # Save modified positional parameters for caller.  As a top-level
+    # options-parser function we always need to set the 'func_options_result'
+    # variable (regardless the $_G_rc_options value).
+    if $_G_rc_options; then
+      func_options_result=$_G_res_var
+    else
+      func_quote_for_eval ${1+"$@"}
+      func_options_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_options
 }
 
 
@@ -1649,9 +1698,9 @@
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
+# needs to propagate that back to rest of this script, then the complete
 # modified list must be put in 'func_run_hooks_result' before
-# returning.
+# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1661,10 +1710,14 @@
     opt_verbose=false
     opt_warning_types=
 
-    func_run_hooks func_options_prep ${1+"$@"}
+    _G_rc_options_prep=false
+    if func_run_hooks func_options_prep ${1+"$@"}; then
+      _G_rc_options_prep=:
+      # save modified positional parameters for caller
+      func_options_prep_result=$func_run_hooks_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    $_G_rc_options_prep
 }
 
 
@@ -1678,18 +1731,20 @@
 
     func_parse_options_result=
 
+    _G_rc_parse_options=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
-
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+      if func_run_hooks func_parse_options ${1+"$@"}; then
+        eval set dummy "$func_run_hooks_result"; shift
+        _G_rc_parse_options=:
+      fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -1704,7 +1759,10 @@
 		      ;;
 
         --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_rc_parse_options=:
+                        break
+                      fi
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1757,15 +1815,25 @@
                       shift
                       ;;
 
-        --)           break ;;
+        --)           _G_rc_parse_options=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
       esac
+
+      $_G_match_parse_options && _G_rc_parse_options=:
     done
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+
+    if $_G_rc_parse_options; then
+      # save modified positional parameters for caller
+      func_quote_for_eval ${1+"$@"}
+      func_parse_options_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_parse_options
 }
 
 
@@ -1778,16 +1846,21 @@
 {
     $debug_cmd
 
+    _G_rc_validate_options=false
+
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    func_run_hooks func_validate_options ${1+"$@"}
+    if func_run_hooks func_validate_options ${1+"$@"}; then
+      # save modified positional parameters for caller
+      func_validate_options_result=$func_run_hooks_result
+      _G_rc_validate_options=:
+    fi
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    $_G_rc_validate_options
 }
 
 
@@ -2068,7 +2141,7 @@
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-2
+       version:        $progname $scriptversion Debian-2.4.6-14
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
@@ -2270,6 +2343,8 @@
     nonopt=
     preserve_args=
 
+    _G_rc_lt_options_prep=:
+
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -2293,11 +2368,18 @@
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
+    *)
+      _G_rc_lt_options_prep=false
+      ;;
     esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
+    if $_G_rc_lt_options_prep; then
+      # Pass back the list of options.
+      func_quote_for_eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_lt_options_prep
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2309,9 +2391,12 @@
 {
     $debug_cmd
 
+    _G_rc_lt_parse_options=false
+
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
+      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -2386,15 +2471,22 @@
                         func_append preserve_args " $_G_opt"
                         ;;
 
-	# An option not handled by this hook function:
-        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
+        # An option not handled by this hook function:
+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
+                        _G_match_lt_parse_options=false
+                        break
+                        ;;
       esac
+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
+    if $_G_rc_lt_parse_options; then
+      # save modified positional parameters for caller
+      func_quote_for_eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_for_eval_result
+    fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
+    $_G_rc_lt_parse_options
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -7275,10 +7367,13 @@
       # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
       # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -fuse-ld=*           Linker select flags for GCC
+      # -static-*            direct GCC to link specific libraries statically
+      # -fcilkplus           Cilk Plus language extension features for C/C++
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*)
+      -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
         func_quote_for_eval "$arg"
 	arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
diff --git a/lib/External/isl/m4/libtool.m4 b/lib/External/isl/m4/libtool.m4
index ee80844..a6d21ae 100644
--- a/lib/External/isl/m4/libtool.m4
+++ b/lib/External/isl/m4/libtool.m4
@@ -1041,8 +1041,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
-      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
-      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
       echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
       $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
       cat > conftest.c << _LT_EOF
@@ -1492,7 +1492,7 @@
 m4_defun([_LT_PROG_AR],
 [AC_CHECK_TOOLS(AR, [ar], false)
 : ${AR=ar}
-: ${AR_FLAGS=cru}
+: ${AR_FLAGS=cr}
 _LT_DECL([], [AR], [1], [The archiver])
 _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
 
@@ -4063,7 +4063,8 @@
   if AC_TRY_EVAL(ac_compile); then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
 	mv -f "$nlist"T "$nlist"
@@ -4703,6 +4704,12 @@
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
+      # flang / f18. f95 an alias for gfortran or flang on Debian
+      flang* | f18* | f95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -6438,7 +6445,7 @@
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -6813,7 +6820,7 @@
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -6878,7 +6885,7 @@
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
 	    if test yes = "$GXX"; then
@@ -7217,7 +7224,7 @@
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
 	    else
 	      # FIXME: insert proper C++ library support
@@ -7301,7 +7308,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
@@ -7312,7 +7319,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 	      fi
 
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
diff --git a/lib/External/isl/missing b/lib/External/isl/missing
index f62bbae..625aeb1 100755
--- a/lib/External/isl/missing
+++ b/lib/External/isl/missing
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2013-10-28.13; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -101,9 +101,9 @@
   exit $st
 fi
 
-perl_URL=http://www.perl.org/
-flex_URL=http://flex.sourceforge.net/
-gnu_software_URL=http://www.gnu.org/software
+perl_URL=https://www.perl.org/
+flex_URL=https://github.com/westes/flex
+gnu_software_URL=https://www.gnu.org/software
 
 program_details ()
 {
@@ -207,9 +207,9 @@
 exit $st
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/lib/External/isl/py-compile b/lib/External/isl/py-compile
index 3693d96..9f8baf7 100644
--- a/lib/External/isl/py-compile
+++ b/lib/External/isl/py-compile
@@ -1,9 +1,9 @@
 #!/bin/sh
 # py-compile - Compile a Python program
 
-scriptversion=2016-01-11.22; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2000-2017 Free Software Foundation, Inc.
+# Copyright (C) 2000-2018 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -162,7 +162,7 @@
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
 # time-stamp-time-zone: "UTC0"
diff --git a/lib/External/isl/test-driver b/lib/External/isl/test-driver
index 8e575b0..b8521a4 100755
--- a/lib/External/isl/test-driver
+++ b/lib/External/isl/test-driver
@@ -1,9 +1,9 @@
 #! /bin/sh
 # test-driver - basic testsuite driver script.
 
-scriptversion=2013-07-13.22; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2018 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -140,9 +140,9 @@
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/lib/External/isl/test_inputs/codegen/cloog/classen.c b/lib/External/isl/test_inputs/codegen/cloog/classen.c
index 0201766..ec6daad 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/classen.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/classen.c
@@ -1,9 +1,9 @@
 if (m >= 1) {
   S1(0, 1, 1, 1);
   if (m >= 2) {
-    S2(0, 1, 1, 1, 1, 1, 2, 1);
-    S3(0, 1, 1, 2, 1, 1, 1, 2);
     S4(0, 1, 2, 2, 1, 1, 2, 2);
+    S3(0, 1, 1, 2, 1, 1, 1, 2);
+    S2(0, 1, 1, 1, 1, 1, 2, 1);
   }
   S8(0, 1);
   for (int c0 = 1; c0 < 2 * m - 1; c0 += 1) {
@@ -12,45 +12,45 @@
         S5(m - 2, 1, m - 1, 1, m - 1, 1, m, 1);
         S1(m - 1, 1, m, 1);
         S3(m - 1, 1, m, 2, m, 1, m, 2);
-      } else if (m >= c0 + 2) {
-        S5(c0 - 1, 1, c0, 1, c0, 1, c0 + 1, 1);
-        S1(c0, 1, c0 + 1, 1);
-        S2(c0, 1, c0 + 1, 1, c0 + 1, 1, c0 + 2, 1);
-        S4(c0, 1, c0 + 2, 2, c0 + 1, 1, c0 + 2, 2);
-        S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2);
-      } else {
+      } else if (c0 >= m) {
         S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2);
         S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2);
         S1(c0, -m + c0 + 2, m, -m + c0 + 2);
         S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3);
+      } else {
+        S5(c0 - 1, 1, c0, 1, c0, 1, c0 + 1, 1);
+        S1(c0, 1, c0 + 1, 1);
+        S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2);
+        S4(c0, 1, c0 + 2, 2, c0 + 1, 1, c0 + 2, 2);
+        S2(c0, 1, c0 + 1, 1, c0 + 1, 1, c0 + 2, 1);
       }
       for (int c1 = max(2, -m + c0 + 3); c1 <= min(m - 1, c0); c1 += 1) {
         S5(c0 - 1, c1, c0, c1, c0 - c1 + 1, c1, c0 - c1 + 2, c1);
-        S7(c0 - 1, c1 - 1, c0 + 1, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 3, c1);
         S6(c0 - 1, c1 - 1, c0, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 2, c1);
+        S7(c0 - 1, c1 - 1, c0 + 1, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 3, c1);
         S1(c0, c1, c0 - c1 + 2, c1);
-        S2(c0, c1, c0 + 1, c1, c0 - c1 + 2, c1, c0 - c1 + 3, c1);
-        S4(c0, c1, c0 + 2, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 3, c1 + 1);
         S3(c0, c1, c0 + 1, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 2, c1 + 1);
+        S4(c0, c1, c0 + 2, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 3, c1 + 1);
+        S2(c0, c1, c0 + 1, c1, c0 - c1 + 2, c1, c0 - c1 + 3, c1);
       }
       if (c0 + 1 == m) {
-        S7(m - 2, m - 1, m, m, 1, m - 1, 2, m);
         S6(m - 2, m - 1, m - 1, m, 1, m - 1, 1, m);
+        S7(m - 2, m - 1, m, m, 1, m - 1, 2, m);
         S1(m - 1, m, 1, m);
         S2(m - 1, m, m, m, 1, m, 2, m);
-      } else if (m >= c0 + 2) {
+      } else if (c0 >= m) {
+        S5(c0 - 1, m, c0, m, -m + c0 + 1, m, -m + c0 + 2, m);
+        S6(c0 - 1, m - 1, c0, m, -m + c0 + 2, m - 1, -m + c0 + 2, m);
+        S7(c0 - 1, m - 1, c0 + 1, m, -m + c0 + 2, m - 1, -m + c0 + 3, m);
+        S1(c0, m, -m + c0 + 2, m);
+        S2(c0, m, c0 + 1, m, -m + c0 + 2, m, -m + c0 + 3, m);
+      } else {
         S6(c0 - 1, c0, c0, c0 + 1, 1, c0, 1, c0 + 1);
         S7(c0 - 1, c0, c0 + 1, c0 + 1, 1, c0, 2, c0 + 1);
         S1(c0, c0 + 1, 1, c0 + 1);
-        S2(c0, c0 + 1, c0 + 1, c0 + 1, 1, c0 + 1, 2, c0 + 1);
-        S4(c0, c0 + 1, c0 + 2, c0 + 2, 1, c0 + 1, 2, c0 + 2);
         S3(c0, c0 + 1, c0 + 1, c0 + 2, 1, c0 + 1, 1, c0 + 2);
-      } else {
-        S5(c0 - 1, m, c0, m, -m + c0 + 1, m, -m + c0 + 2, m);
-        S7(c0 - 1, m - 1, c0 + 1, m, -m + c0 + 2, m - 1, -m + c0 + 3, m);
-        S6(c0 - 1, m - 1, c0, m, -m + c0 + 2, m - 1, -m + c0 + 2, m);
-        S1(c0, m, -m + c0 + 2, m);
-        S2(c0, m, c0 + 1, m, -m + c0 + 2, m, -m + c0 + 3, m);
+        S4(c0, c0 + 1, c0 + 2, c0 + 2, 1, c0 + 1, 2, c0 + 2);
+        S2(c0, c0 + 1, c0 + 1, c0 + 1, 1, c0 + 1, 2, c0 + 1);
       }
     } else {
       S5(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m);
diff --git a/lib/External/isl/test_inputs/codegen/cloog/dealII.c b/lib/External/isl/test_inputs/codegen/cloog/dealII.c
index 1283f67..2151d99 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/dealII.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/dealII.c
@@ -2,6 +2,8 @@
   S1(c0);
   S2(c0);
 }
+for (int c0 = T_2; c0 <= min(T_67 - 1, T_66); c0 += 1)
+  S2(c0);
 for (int c0 = max(0, T_66 + 1); c0 < min(T_2, T_67); c0 += 1)
   S1(c0);
 for (int c0 = T_67; c0 <= min(T_2 - 1, T_66); c0 += 1) {
@@ -10,7 +12,5 @@
 }
 for (int c0 = max(T_67, T_66 + 1); c0 < T_2; c0 += 1)
   S1(c0);
-for (int c0 = T_2; c0 <= min(T_67 - 1, T_66); c0 += 1)
-  S2(c0);
 if (T_2 == 0 && T_67 == 0)
   S1(0);
diff --git a/lib/External/isl/test_inputs/codegen/cloog/dot2.c b/lib/External/isl/test_inputs/codegen/cloog/dot2.c
index 18f4ec8..12faa6d 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/dot2.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/dot2.c
@@ -3,8 +3,8 @@
   for (int c1 = 1; c1 <= M; c1 += 1)
     S2(c0, c1);
 }
+for (int c0 = N + 1; c0 <= M; c0 += 1)
+  S1(c0);
 for (int c0 = M + 1; c0 <= N; c0 += 1)
   for (int c1 = 1; c1 <= M; c1 += 1)
     S2(c0, c1);
-for (int c0 = N + 1; c0 <= M; c0 += 1)
-  S1(c0);
diff --git a/lib/External/isl/test_inputs/codegen/cloog/faber.c b/lib/External/isl/test_inputs/codegen/cloog/faber.c
index 958e48c..a0ed89b 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/faber.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/faber.c
@@ -36,18 +36,16 @@
   for (int c1 = 1; c1 <= 18; c1 += 1) {
     for (int c2 = -8 * c1; c2 <= min(6, -8 * c1 + 24); c2 += 1)
       S3(c0, c1, c2);
-    if (c1 == 2) {
-      S3(c0, 2, 7);
-    } else if (c0 <= 34 && c1 == 1) {
+    if (c0 <= 34 && c1 == 1) {
       S3(c0, 1, 7);
+    } else if (c1 == 2) {
+      S3(c0, 2, 7);
     } else if (c0 >= 35 && c1 == 1) {
       S3(c0, 1, 7);
       S7(c0, 1, 7);
     }
     for (int c2 = 8; c2 <= min(-8 * c1 + 24, c1 - (6 * c0 + 77) / 77 + 12); c2 += 1)
       S3(c0, c1, c2);
-    for (int c2 = max(-8 * c1 + 25, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 + 12; c2 += 1)
-      S6(c0, c1, c2);
     if (c1 == 1) {
       for (int c2 = -((6 * c0 + 77) / 77) + 14; c2 <= 13; c2 += 1) {
         S3(c0, 1, c2);
@@ -56,6 +54,8 @@
       for (int c2 = 14; c2 <= 16; c2 += 1)
         S3(c0, 1, c2);
     }
+    for (int c2 = max(-8 * c1 + 25, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 + 12; c2 += 1)
+      S6(c0, c1, c2);
     for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 + 48; c2 += 1)
       S1(c0, c1, c2);
   }
@@ -77,14 +77,6 @@
     for (int c2 = -2 * c1 + 30; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1)
       S1(c0, c1, c2);
   }
-  for (int c1 = c0 / 14 - 5; c1 < 0; c1 += 1) {
-    if (7 * c1 + 114 >= 2 * c0)
-      S7(c0, c1, 6);
-    for (int c2 = max(8, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1)
-      S6(c0, c1, c2);
-    for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1)
-      S1(c0, c1, c2);
-  }
   if (c0 <= 148)
     for (int c1 = max(0, (c0 + 5) / 14 - 8); c1 < c0 / 14 - 5; c1 += 1) {
       if (c1 == 0)
@@ -95,6 +87,14 @@
   if (c0 >= 70 && c0 % 14 >= 9)
     for (int c2 = max((c0 + 5) / 14 + 18, -((3 * c0 + 14) / 14) + c0 / 14 + 44); c2 <= -((3 * c0 + 17) / 14) + c0 / 14 + 51; c2 += 1)
       S1(c0, c0 / 14 - 5, c2);
+  for (int c1 = c0 / 14 - 5; c1 < 0; c1 += 1) {
+    if (7 * c1 + 114 >= 2 * c0)
+      S7(c0, c1, 6);
+    for (int c2 = max(8, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1)
+      S6(c0, c1, c2);
+    for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1)
+      S1(c0, c1, c2);
+  }
   for (int c1 = max(0, (c0 + 5) / 14 - 5); c1 < c0 / 14 - 2; c1 += 1) {
     for (int c2 = max(c1, -2 * c1 + 6); c2 <= min(c1 + 5, -2 * c1 + 24); c2 += 1)
       S9(c0, c1, c2);
diff --git a/lib/External/isl/test_inputs/codegen/cloog/gesced.c b/lib/External/isl/test_inputs/codegen/cloog/gesced.c
index 06f94f6..2eb44ed 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/gesced.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/gesced.c
@@ -5,9 +5,9 @@
     S2(c1, -N + c0);
 for (int c0 = 2 * N + 1; c0 <= M + N; c0 += 1) {
   for (int c1 = 1; c1 <= N; c1 += 1)
-    S2(c1, -N + c0);
-  for (int c1 = 1; c1 <= N; c1 += 1)
     S3(c1, -2 * N + c0);
+  for (int c1 = 1; c1 <= N; c1 += 1)
+    S2(c1, -N + c0);
 }
 for (int c0 = M + N + 1; c0 <= M + 2 * N; c0 += 1)
   for (int c1 = 1; c1 <= N; c1 += 1)
diff --git a/lib/External/isl/test_inputs/codegen/cloog/gesced3.c b/lib/External/isl/test_inputs/codegen/cloog/gesced3.c
index 2419305..86e4a5e 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/gesced3.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/gesced3.c
@@ -1,8 +1,8 @@
 for (int c0 = M + 1; c0 <= 2 * M; c0 += 1)
   S1(-M + c0);
 for (int c0 = 2 * M + 1; c0 <= M + N; c0 += 1) {
-  S2(-2 * M + c0);
   S1(-M + c0);
+  S2(-2 * M + c0);
 }
 for (int c0 = M + N + 1; c0 <= 2 * M + N; c0 += 1)
   S2(-2 * M + c0);
diff --git a/lib/External/isl/test_inputs/codegen/cloog/mode.c b/lib/External/isl/test_inputs/codegen/cloog/mode.c
index 5596b26..bcfd318 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/mode.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/mode.c
@@ -3,8 +3,8 @@
     S1(c0, c1);
     S2(c0, c1);
   }
-  for (int c1 = c0 + 1; c1 <= N; c1 += 1)
-    S2(c0, c1);
   for (int c1 = max(0, N + 1); c1 <= c0; c1 += 1)
     S1(c0, c1);
+  for (int c1 = c0 + 1; c1 <= N; c1 += 1)
+    S2(c0, c1);
 }
diff --git a/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c b/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c
index 84f6a25..3de60e1 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c
@@ -1,18 +1,18 @@
 if (M >= 0 && N >= 0)
   for (int c0 = -4; c0 <= 3 * M + N; c0 += 1) {
-    if (c0 >= 3 * M) {
-      S2(M, -3 * M + c0);
-    } else if (3 * M >= c0 + 4 && (c0 + 1) % 3 == 0) {
+    if (3 * M >= c0 + 4 && (c0 + 1) % 3 == 0) {
       S1((c0 + 4) / 3, 0);
+    } else if (c0 >= 3 * M) {
+      S2(M, -3 * M + c0);
     }
     for (int c1 = max(-3 * M + c0 + 3, (c0 + 6) % 3); c1 <= min(N - 1, c0); c1 += 3) {
       S2((c0 - c1) / 3, c1);
       S1(((c0 - c1) / 3) + 1, c1 + 1);
     }
-    if (3 * M + N >= c0 + 3 && c0 >= N && (N - c0) % 3 == 0) {
-      S2((-N + c0) / 3, N);
-    } else if (N >= c0 + 4 && c0 >= -3) {
+    if (N >= c0 + 4 && c0 >= -3) {
       S1(0, c0 + 4);
+    } else if (3 * M + N >= c0 + 3 && c0 >= N && (N - c0) % 3 == 0) {
+      S2((-N + c0) / 3, N);
     }
     for (int c1 = max(-3 * M + c0, (c0 + 6) % 3); c1 <= min(N, c0); c1 += 3)
       S3((c0 - c1) / 3, c1);
diff --git a/lib/External/isl/test_inputs/codegen/cloog/test.c b/lib/External/isl/test_inputs/codegen/cloog/test.c
index 67485ca..1abafb0 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/test.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/test.c
@@ -4,12 +4,12 @@
 for (int c0 = 3; c0 <= N; c0 += 1) {
   for (int c1 = 1; c1 <= min(M, c0 - 1); c1 += 1)
     S1(c0, c1);
-  if (c0 >= M + 1) {
-    S2(c0, c0);
-  } else {
+  if (M >= c0) {
     S1(c0, c0);
     S2(c0, c0);
   }
   for (int c1 = c0 + 1; c1 <= M; c1 += 1)
     S1(c0, c1);
+  if (c0 >= M + 1)
+    S2(c0, c0);
 }
diff --git a/lib/External/isl/test_inputs/codegen/cloog/vivien.c b/lib/External/isl/test_inputs/codegen/cloog/vivien.c
index 98a64cb..a41c886 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/vivien.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/vivien.c
@@ -14,8 +14,8 @@
       }
     }
     for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) {
-      S6(-c1 + 2, c0 + c1 - 2);
       S4(-c1, c0 + c1);
+      S6(-c1 + 2, c0 + c1 - 2);
       for (int c2 = 1; c2 <= -c1; c2 += 1)
         S5(-c1 + 1, c0 + c1 - 1, c2);
     }
@@ -24,23 +24,22 @@
       for (int c2 = 1; c2 < -n + c0; c2 += 1)
         S5(-n + c0, n, c2);
     }
-    if (n >= 3 && c0 == n + 2) {
-      S1(n + 1);
-      S6(2, n);
+    if (c0 >= n + 3 && 2 * n >= c0 + 1)
+      S6(-n + c0, n);
+    if (c0 >= n + 3) {
+      S1(c0 - 1);
     } else {
-      if (c0 >= n + 3 && 2 * n >= c0 + 1)
-        S6(-n + c0, n);
-      if (c0 >= n + 3) {
+      if (n + 1 >= c0 && c0 <= 4) {
         S1(c0 - 1);
-      } else {
-        if (n + 1 >= c0 && c0 <= 4) {
-          S1(c0 - 1);
-        } else if (c0 >= 5 && n + 1 >= c0) {
-          S1(c0 - 1);
-          S6(2, c0 - 2);
-        }
-        if (n + 1 >= c0)
-          S6(1, c0 - 1);
+      } else if (c0 >= 5 && n + 1 >= c0) {
+        S1(c0 - 1);
+        S6(2, c0 - 2);
+      }
+      if (n + 1 >= c0) {
+        S6(1, c0 - 1);
+      } else if (n >= 3) {
+        S1(n + 1);
+        S6(2, n);
       }
     }
     if (n == 2 && c0 == 4)
@@ -67,8 +66,8 @@
         S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2);
     }
     for (int c1 = -c0 + c0 / 2 + 3; c1 <= n - c0; c1 += 1) {
-      S6(-c1 + 2, c0 + c1 - 2);
       S4(-c1, c0 + c1);
+      S6(-c1 + 2, c0 + c1 - 2);
       for (int c2 = 1; c2 <= -c1; c2 += 1)
         S5(-c1 + 1, c0 + c1 - 1, c2);
     }
diff --git a/lib/External/isl/test_inputs/codegen/cloog/vivien2.c b/lib/External/isl/test_inputs/codegen/cloog/vivien2.c
index b74f118..bfe1dc1 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/vivien2.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/vivien2.c
@@ -3,14 +3,19 @@
 for (int c0 = 2; c0 <= n + 29; c0 += 1) {
   if (c0 >= 3) {
     S4(c0 - c0 / 2 - 1, c0 / 2 + 1);
-    if (c0 >= 5 && 2 * n >= c0 + 3) {
+    if (c0 <= 4) {
+      S1(c0 - 1);
+    } else if (c0 + 2 >= 2 * n) {
+      for (int c2 = 1; c2 < -n + c0; c2 += 1)
+        S5(-n + c0, n, c2);
+    } else {
       S4(c0 - c0 / 2 - 2, c0 / 2 + 2);
       for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1)
         S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2);
     }
     for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) {
-      S6(-c1 + 2, c0 + c1 - 2);
       S4(-c1, c0 + c1);
+      S6(-c1 + 2, c0 + c1 - 2);
       for (int c2 = 1; c2 <= -c1; c2 += 1)
         S5(-c1 + 1, c0 + c1 - 1, c2);
     }
@@ -18,26 +23,19 @@
       S6(-n + c0 + 1, n - 1);
       for (int c2 = 1; c2 < -n + c0; c2 += 1)
         S5(-n + c0, n, c2);
-      if (c0 == n + 2) {
-        S1(n + 1);
-        S6(2, n);
-      }
-    } else if (c0 + 2 >= 2 * n) {
-      for (int c2 = 1; c2 < -n + c0; c2 += 1)
-        S5(-n + c0, n, c2);
     }
     if (c0 >= n + 3) {
       S6(-n + c0, n);
       S1(c0 - 1);
+    } else if (c0 == n + 2) {
+      S1(n + 1);
+      S6(2, n);
     } else {
-      if (c0 >= 5 && n + 1 >= c0) {
+      if (c0 >= 5) {
         S1(c0 - 1);
         S6(2, c0 - 2);
-      } else if (c0 <= 4) {
-        S1(c0 - 1);
       }
-      if (n + 1 >= c0)
-        S6(1, c0 - 1);
+      S6(1, c0 - 1);
     }
   } else {
     S1(1);
@@ -59,8 +57,8 @@
         S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2);
     }
     for (int c1 = -c0 + c0 / 2 + 3; c1 <= n - c0; c1 += 1) {
-      S6(-c1 + 2, c0 + c1 - 2);
       S4(-c1, c0 + c1);
+      S6(-c1 + 2, c0 + c1 - 2);
       for (int c2 = 1; c2 <= -c1; c2 += 1)
         S5(-c1 + 1, c0 + c1 - 1, c2);
     }
diff --git a/lib/External/isl/test_inputs/codegen/cloog/yosr.c b/lib/External/isl/test_inputs/codegen/cloog/yosr.c
index 711d44d..563701e 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/yosr.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/yosr.c
@@ -1,9 +1,9 @@
 for (int c0 = 1; c0 < n; c0 += 1) {
-  for (int c2 = c0 + 1; c2 <= n; c2 += 1)
-    S1(c0, c2);
   for (int c1 = 1; c1 < c0; c1 += 1)
     for (int c2 = c1 + 1; c2 <= n; c2 += 1)
       S2(c1, c2, c0);
+  for (int c2 = c0 + 1; c2 <= n; c2 += 1)
+    S1(c0, c2);
 }
 for (int c1 = 1; c1 < n; c1 += 1)
   for (int c2 = c1 + 1; c2 <= n; c2 += 1)
diff --git a/lib/External/isl/test_inputs/codegen/cloog/yosr2.c b/lib/External/isl/test_inputs/codegen/cloog/yosr2.c
index 449743d..a414b43 100644
--- a/lib/External/isl/test_inputs/codegen/cloog/yosr2.c
+++ b/lib/External/isl/test_inputs/codegen/cloog/yosr2.c
@@ -3,9 +3,9 @@
 for (int c0 = 2; c0 <= M; c0 += 1) {
   for (int c2 = 1; c2 < c0; c2 += 1)
     S1(c0, c2);
-  for (int c1 = 1; c1 < c0; c1 += 1)
-    S4(c1, c0);
   for (int c2 = c0 + 1; c2 <= M; c2 += 1)
     for (int c3 = 1; c3 < c0; c3 += 1)
       S3(c0, c2, c3);
+  for (int c1 = 1; c1 < c0; c1 += 1)
+    S4(c1, c0);
 }
diff --git a/lib/External/isl/test_inputs/codegen/correlation.c b/lib/External/isl/test_inputs/codegen/correlation.c
index 8285005..8a5bc75 100644
--- a/lib/External/isl/test_inputs/codegen/correlation.c
+++ b/lib/External/isl/test_inputs/codegen/correlation.c
@@ -1,45 +1,55 @@
 for (int c0 = 0; c0 < m; c0 += 32)
   for (int c1 = (n >= 32 && m >= c0 + 2) || (m == 1 && c0 == 0) ? 0 : 32 * n - 32 * floord(31 * n + 31, 32); c1 <= ((n <= 0 && c0 == 0) || (m == 1 && n >= 1 && c0 == 0) ? max(0, n - 1) : n); c1 += 32)
     for (int c2 = c0; c2 <= (m >= 2 && c0 + 31 >= m && n >= c1 && c1 + 31 >= n ? 2 * m - 3 : (m >= 2 * c0 + 63 && c1 <= -32 && n >= c1 && c1 + 31 >= n) || (m >= c0 + 32 && 2 * c0 + 62 >= m && n >= c1 && c1 + 31 >= n) || (n >= 0 && c0 >= 32 && m >= 2 * c0 + 63 && c1 == n) || (m >= 63 && n >= 32 && c0 == 0 && c1 == n) ? 2 * c0 + 61 : m - 1); c2 += 32) {
-      if (n >= c1 + 32 && c1 >= 0 && 2 * c0 >= c2 + 32) {
-        for (int c4 = 0; c4 <= 31; c4 += 1)
-          for (int c5 = max(0, c0 - c2 + 1); c5 <= min(31, m - c2 - 1); c5 += 1)
-            S_27(c0, c2 + c5, c1 + c4);
-      } else if (c0 >= 32 && c1 >= 0 && c2 >= 2 * c0) {
-        for (int c4 = 0; c4 <= min(31, n - c1 - 1); c4 += 1)
-          for (int c5 = 0; c5 <= min(31, m - c2 - 1); c5 += 1)
-            S_27(c0, c2 + c5, c1 + c4);
-      } else if (c0 == 0 && c1 >= 0) {
-        for (int c4 = 0; c4 <= min(31, n - c1 - 1); c4 += 1)
-          for (int c5 = 0; c5 <= min(31, m - c2 - 1); c5 += 1) {
-            if (c1 == 0 && c4 == 0)
-              S_14(c2 + c5);
-            S_19(c1 + c4, c2 + c5);
-            if (c2 + c5 >= 1)
-              S_27(0, c2 + c5, c1 + c4);
-          }
-      }
-      if (c1 >= 0) {
-        for (int c3 = 1; c3 <= min(31, (c2 / 2) - c0); c3 += 1)
-          for (int c4 = 0; c4 <= min(31, n - c1 - 1); c4 += 1)
-            for (int c5 = 0; c5 <= min(31, m - c2 - 1); c5 += 1)
-              S_27(c0 + c3, c2 + c5, c1 + c4);
-        if (n >= c1 + 32) {
-          for (int c3 = max(1, (c2 / 2) - c0 + 1); c3 <= min(min(31, m - c0 - 2), -c0 + c2 + 30); c3 += 1)
-            for (int c4 = 0; c4 <= 31; c4 += 1)
-              for (int c5 = max(0, c0 - c2 + c3 + 1); c5 <= min(31, m - c2 - 1); c5 += 1)
-                S_27(c0 + c3, c2 + c5, c1 + c4);
-        } else if (n <= 0 && c0 == 0 && c1 == 0) {
+      if (m >= 2) {
+        if (n <= 0 && c0 == 0 && c1 == 0)
           for (int c5 = 0; c5 <= min(31, m - c2 - 1); c5 += 1)
             S_14(c2 + c5);
+        if (n >= 0 && c1 == n) {
+          for (int c3 = max(0, (c2 / 2) - c0 + 1); c3 <= min(31, m - c0 - 2); c3 += 1)
+            for (int c5 = max(0, c0 - c2 + c3); c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1)
+              S_29(-c0 + c2 - c3 + c5, c0 + c3);
+        } else if (n >= c1 + 1 && c1 >= 0 && c1 + 31 >= n && c2 >= m) {
+          for (int c3 = max(0, (c2 / 2) - c0 + 1); c3 <= min(31, m - c0 - 2); c3 += 1)
+            for (int c5 = 0; c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1)
+              S_29(-c0 + c2 - c3 + c5, c0 + c3);
+        } else if (c1 <= -32 && n >= c1 && c1 + 31 >= n) {
+          for (int c3 = max(0, (c2 / 2) - c0 + 1); c3 <= min(31, m - c0 - 2); c3 += 1)
+            for (int c5 = max(0, c0 - c2 + c3); c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1)
+              S_29(-c0 + c2 - c3 + c5, c0 + c3);
+        } else if (n >= c1 + 1 && c1 >= 0 && m >= c2 + 1) {
+          for (int c3 = 0; c3 <= min(min(31, m - c0 - 2), -c0 + c2 + 30); c3 += 1) {
+            for (int c4 = 0; c4 <= min(31, n - c1 - 1); c4 += 1) {
+              if (c0 == 0 && c2 == 0 && c3 == 0) {
+                if (c1 == 0 && c4 == 0)
+                  S_14(0);
+                S_19(c1 + c4, 0);
+              }
+              for (int c5 = max(0, c0 - c2 + c3 + 1); c5 <= min(31, m - c2 - 1); c5 += 1) {
+                if (c0 == 0 && c1 == 0 && c3 == 0 && c4 == 0)
+                  S_14(c2 + c5);
+                if (c0 == 0 && c3 == 0)
+                  S_19(c1 + c4, c2 + c5);
+                S_27(c0 + c3, c2 + c5, c1 + c4);
+              }
+            }
+            if (c1 + 31 >= n)
+              for (int c5 = max(0, c0 - c2 + c3); c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1)
+                S_29(-c0 + c2 - c3 + c5, c0 + c3);
+          }
         }
+        if (c0 + 32 >= m && n >= c1 && c1 + 31 >= n) {
+          for (int c5 = max(0, m - c2 - 1); c5 <= min(31, 2 * m - c2 - 3); c5 += 1)
+            S_29(-m + c2 + c5 + 1, m - 1);
+        } else if (m >= c0 + 33 && n >= c1 + 1 && c1 >= 0 && c1 + 31 >= n && c2 == c0) {
+          S_29(0, c0 + 31);
+        }
+      } else if (c1 >= 32 && c2 == 0) {
+        for (int c4 = 0; c4 <= min(31, n - c1 - 1); c4 += 1)
+          S_19(c1 + c4, 0);
+      } else if (c1 == 0 && c2 == 0) {
+        S_14(0);
+        for (int c4 = 0; c4 <= min(31, n - 1); c4 += 1)
+          S_19(c4, 0);
       }
-      if (n >= c1 && c1 + 31 >= n)
-        for (int c3 = max(0, (c2 / 2) - c0 + 1); c3 <= min(31, m - c0 - 1); c3 += 1) {
-          for (int c4 = max(0, -c1); c4 < n - c1; c4 += 1)
-            for (int c5 = max(0, c0 - c2 + c3 + 1); c5 <= min(31, m - c2 - 1); c5 += 1)
-              S_27(c0 + c3, c2 + c5, c1 + c4);
-          for (int c5 = max(0, c0 - c2 + c3); c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1)
-            S_29(-c0 + c2 - c3 + c5, c0 + c3);
-        }
     }
diff --git a/lib/External/isl/test_inputs/codegen/empty.c b/lib/External/isl/test_inputs/codegen/empty.c
index 0205735..58f7b7b 100644
--- a/lib/External/isl/test_inputs/codegen/empty.c
+++ b/lib/External/isl/test_inputs/codegen/empty.c
@@ -1,6 +1,6 @@
 for (int c0 = 0; c0 <= 10; c0 += 1) {
   S0(c0);
-  S1(c0);
   if (c0 == 5)
     S2();
+  S1(c0);
 }
diff --git a/lib/External/isl/test_inputs/codegen/group.c b/lib/External/isl/test_inputs/codegen/group.c
index 9fad240..3e521e2 100644
--- a/lib/External/isl/test_inputs/codegen/group.c
+++ b/lib/External/isl/test_inputs/codegen/group.c
@@ -1,5 +1,5 @@
 if (N == 0) {
-  C();
   A();
+  C();
 }
 B();
diff --git a/lib/External/isl/test_inputs/codegen/omega/if_then-1.c b/lib/External/isl/test_inputs/codegen/omega/if_then-1.c
index 5e2cd82..18ca370 100644
--- a/lib/External/isl/test_inputs/codegen/omega/if_then-1.c
+++ b/lib/External/isl/test_inputs/codegen/omega/if_then-1.c
@@ -2,8 +2,8 @@
   if (n >= 2)
     s0(c0);
   for (int c1 = 1; c1 <= 100; c1 += 1) {
-    s2(c0, c1);
     if (n >= 2)
       s1(c0, c1);
+    s2(c0, c1);
   }
 }
diff --git a/lib/External/isl/test_inputs/codegen/omega/if_then-2.c b/lib/External/isl/test_inputs/codegen/omega/if_then-2.c
index b3f4a24..158b078 100644
--- a/lib/External/isl/test_inputs/codegen/omega/if_then-2.c
+++ b/lib/External/isl/test_inputs/codegen/omega/if_then-2.c
@@ -2,8 +2,8 @@
   if (n >= 2) {
     s0(c0);
     for (int c1 = 1; c1 <= 100; c1 += 1) {
-      s2(c0, c1);
       s1(c0, c1);
+      s2(c0, c1);
     }
   } else {
     for (int c1 = 1; c1 <= 100; c1 += 1)
diff --git a/lib/External/isl/test_inputs/codegen/omega/if_then-3.c b/lib/External/isl/test_inputs/codegen/omega/if_then-3.c
index 94dc201..bae078e 100644
--- a/lib/External/isl/test_inputs/codegen/omega/if_then-3.c
+++ b/lib/External/isl/test_inputs/codegen/omega/if_then-3.c
@@ -2,8 +2,8 @@
   for (int c0 = 1; c0 <= 100; c0 += 1) {
     s0(c0);
     for (int c1 = 1; c1 <= 100; c1 += 1) {
-      s2(c0, c1);
       s1(c0, c1);
+      s2(c0, c1);
     }
   }
 } else {
diff --git a/lib/External/isl/test_inputs/codegen/omega/iter9-0.c b/lib/External/isl/test_inputs/codegen/omega/iter9-0.c
index baedaa0..e0b957f 100644
--- a/lib/External/isl/test_inputs/codegen/omega/iter9-0.c
+++ b/lib/External/isl/test_inputs/codegen/omega/iter9-0.c
@@ -1,10 +1,10 @@
 for (int c0 = 1; c0 <= 15; c0 += 1) {
   if (((-exprVar1 + 15) % 8) + c0 <= 15) {
-    s1(c0);
-    s3(c0);
     s2(c0);
     s0(c0);
     s4(c0);
+    s3(c0);
+    s1(c0);
   }
   if (((-exprVar1 + 15) % 8) + c0 <= 15 || (exprVar1 - c0 + 1) % 8 == 0)
     s5(c0);
diff --git a/lib/External/isl/test_inputs/codegen/omega/m12-1.c b/lib/External/isl/test_inputs/codegen/omega/m12-1.c
index 68d3c36..ca1821f 100644
--- a/lib/External/isl/test_inputs/codegen/omega/m12-1.c
+++ b/lib/External/isl/test_inputs/codegen/omega/m12-1.c
@@ -4,8 +4,8 @@
     s1(1, c1, c2, 0);
   }
 for (int c1 = 1; c1 <= n; c1 += 1) {
-  s3(2, c1, 0, 0);
   s2(2, c1, 0, 0);
+  s3(2, c1, 0, 0);
 }
 for (int c1 = 1; c1 <= m; c1 += 1) {
   for (int c3 = 1; c3 <= n; c3 += 1) {
@@ -13,8 +13,8 @@
     s5(3, c1, 1, c3);
   }
   for (int c3 = 1; c3 <= n; c3 += 1) {
-    s7(3, c1, 2, c3);
     s6(3, c1, 2, c3);
+    s7(3, c1, 2, c3);
   }
 }
 for (int c1 = 1; c1 <= m; c1 += 1) {
diff --git a/lib/External/isl/test_inputs/codegen/omega/wak1-0.c b/lib/External/isl/test_inputs/codegen/omega/wak1-0.c
index e5a0253..49024c5 100644
--- a/lib/External/isl/test_inputs/codegen/omega/wak1-0.c
+++ b/lib/External/isl/test_inputs/codegen/omega/wak1-0.c
@@ -1,25 +1,25 @@
-for (int c0 = a3; c0 <= min(min(a1 - 1, b3), a2 - 1); c0 += 1)
-  s2(c0);
-for (int c0 = a1; c0 <= min(b1, a2 - 1); c0 += 1) {
+for (int c0 = a1; c0 <= min(min(b1, a3 - 1), a2 - 1); c0 += 1)
   s0(c0);
-  if (c0 >= a3 && b3 >= c0)
-    s2(c0);
-}
-for (int c0 = max(max(a1, b1 + 1), a3); c0 <= min(b3, a2 - 1); c0 += 1)
-  s2(c0);
-for (int c0 = a2; c0 <= b2; c0 += 1) {
+for (int c0 = a2; c0 <= min(a3 - 1, b2); c0 += 1) {
   if (c0 >= a1 && b1 >= c0)
     s0(c0);
   s1(c0);
-  if (c0 >= a3 && b3 >= c0)
-    s2(c0);
 }
-for (int c0 = max(max(a3, a2), b2 + 1); c0 <= min(a1 - 1, b3); c0 += 1)
-  s2(c0);
-for (int c0 = max(max(a1, a2), b2 + 1); c0 <= b1; c0 += 1) {
+for (int c0 = max(max(a1, a2), b2 + 1); c0 <= min(b1, a3 - 1); c0 += 1)
   s0(c0);
-  if (c0 >= a3 && b3 >= c0)
-    s2(c0);
-}
-for (int c0 = max(max(max(max(a1, b1 + 1), a3), a2), b2 + 1); c0 <= b3; c0 += 1)
+for (int c0 = a3; c0 <= b3; c0 += 1) {
+  if (c0 >= a1 && b1 >= c0)
+    s0(c0);
+  if (c0 >= a2 && b2 >= c0)
+    s1(c0);
   s2(c0);
+}
+for (int c0 = max(max(a1, a3), b3 + 1); c0 <= min(b1, a2 - 1); c0 += 1)
+  s0(c0);
+for (int c0 = max(max(a3, b3 + 1), a2); c0 <= b2; c0 += 1) {
+  if (c0 >= a1 && b1 >= c0)
+    s0(c0);
+  s1(c0);
+}
+for (int c0 = max(max(max(max(a1, a3), b3 + 1), a2), b2 + 1); c0 <= b1; c0 += 1)
+  s0(c0);
diff --git a/lib/External/isl/test_inputs/codegen/pldi2012/figure7_b.c b/lib/External/isl/test_inputs/codegen/pldi2012/figure7_b.c
index 5e2cd82..18ca370 100644
--- a/lib/External/isl/test_inputs/codegen/pldi2012/figure7_b.c
+++ b/lib/External/isl/test_inputs/codegen/pldi2012/figure7_b.c
@@ -2,8 +2,8 @@
   if (n >= 2)
     s0(c0);
   for (int c1 = 1; c1 <= 100; c1 += 1) {
-    s2(c0, c1);
     if (n >= 2)
       s1(c0, c1);
+    s2(c0, c1);
   }
 }
diff --git a/lib/External/isl/test_inputs/codegen/pldi2012/figure7_c.c b/lib/External/isl/test_inputs/codegen/pldi2012/figure7_c.c
index b3f4a24..158b078 100644
--- a/lib/External/isl/test_inputs/codegen/pldi2012/figure7_c.c
+++ b/lib/External/isl/test_inputs/codegen/pldi2012/figure7_c.c
@@ -2,8 +2,8 @@
   if (n >= 2) {
     s0(c0);
     for (int c1 = 1; c1 <= 100; c1 += 1) {
-      s2(c0, c1);
       s1(c0, c1);
+      s2(c0, c1);
     }
   } else {
     for (int c1 = 1; c1 <= 100; c1 += 1)
diff --git a/lib/External/isl/test_inputs/codegen/pldi2012/figure7_d.c b/lib/External/isl/test_inputs/codegen/pldi2012/figure7_d.c
index 94dc201..bae078e 100644
--- a/lib/External/isl/test_inputs/codegen/pldi2012/figure7_d.c
+++ b/lib/External/isl/test_inputs/codegen/pldi2012/figure7_d.c
@@ -2,8 +2,8 @@
   for (int c0 = 1; c0 <= 100; c0 += 1) {
     s0(c0);
     for (int c1 = 1; c1 <= 100; c1 += 1) {
-      s2(c0, c1);
       s1(c0, c1);
+      s2(c0, c1);
     }
   }
 } else {
diff --git a/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.in b/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.in
index 2effb0a..d375c4d 100644
--- a/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.in
+++ b/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.in
@@ -1,4 +1,4 @@
 [n] -> { s0[i] -> [i] : exists alpha: 1 <= i <= n and i = 4 alpha;
 	 s1[i] -> [i] : exists alpha: 1 <= i <= n and i = 4 alpha + 2 }
 [n] -> { : }
-[n] -> { }
+[n] -> { [*] -> separate[x] : x >= 0 }
diff --git a/lib/External/isl/test_inputs/codegen/shift2.c b/lib/External/isl/test_inputs/codegen/shift2.c
index 04831a0..9d07c27 100644
--- a/lib/External/isl/test_inputs/codegen/shift2.c
+++ b/lib/External/isl/test_inputs/codegen/shift2.c
@@ -1,53 +1,51 @@
 for (int c0 = 0; c0 <= 1; c0 += 1) {
-  for (int c1 = 0; c1 < length - 1; c1 += 32) {
-    for (int c2 = c1; c2 < length; c2 += 32) {
-      if (c1 == 0)
-        for (int c3 = 0; c3 <= min(length, 2 * c2 - 31); c3 += 32)
-          for (int c5 = 0; c5 <= min(31, length - c2 - 1); c5 += 1)
-            for (int c6 = max(0, -c3 + 1); c6 <= min(31, length - c3); c6 += 1)
-              S_0(c0, c2 + c5, c3 + c6 - 1);
-      for (int c3 = 2 * c2; c3 <= min(2 * length - 2, 2 * c2 + 62); c3 += 32)
-        for (int c4 = 0; c4 <= min(min(31, length - c1 - 2), (c3 / 2) - c1 + 14); c4 += 1) {
-          if (c1 == 0 && c2 == 0 && c4 == 0)
-            for (int c6 = max(0, -c3 + 1); c6 <= min(31, length - c3); c6 += 1)
-              S_0(c0, 0, c3 + c6 - 1);
-          if (c1 == 0 && c3 == 2 * c2 + 32 && c4 == 0)
-            for (int c5 = max(0, -c2 + 1); c5 <= 15; c5 += 1)
-              for (int c6 = 0; c6 <= min(31, length - 2 * c2 - 32); c6 += 1)
-                S_0(c0, c2 + c5, 2 * c2 + c6 + 31);
-          for (int c5 = max((c3 / 2) - c2, c1 - c2 + c4 + 1); c5 <= min(length - c2 - 1, (c3 / 2) - c2 + 15); c5 += 1) {
-            if (c1 == 0 && c4 == 0)
-              for (int c6 = max(0, -c3 + 1); c6 <= min(length - c3, 2 * c2 - c3 + 2 * c5 - 1); c6 += 1)
-                S_0(c0, c2 + c5, c3 + c6 - 1);
-            S_3(c0, c1 + c4, c2 + c5);
-            if (c1 == 0 && c4 == 0 && length >= 2 * c2 + 2 * c5)
-              S_0(c0, c2 + c5, 2 * c2 + 2 * c5 - 1);
-            if (c1 == 0 && c4 == 0)
-              for (int c6 = 2 * c2 - c3 + 2 * c5 + 1; c6 <= min(31, length - c3); c6 += 1)
-                S_0(c0, c2 + c5, c3 + c6 - 1);
-          }
-          if (c1 == 0 && c3 == 2 * c2 && c4 == 0)
-            for (int c5 = 16; c5 <= min(31, length - c2 - 1); c5 += 1)
-              for (int c6 = max(0, -2 * c2 + 1); c6 <= min(31, length - 2 * c2); c6 += 1)
-                S_0(c0, c2 + c5, 2 * c2 + c6 - 1);
-          if (c1 == 0 && c3 + 30 >= 2 * length && c4 == 0)
+  for (int c2 = 0; c2 <= length; c2 += 32) {
+    if (length >= c2 + 1) {
+      for (int c3 = 0; c3 <= length; c3 += 32) {
+        if (c2 == 0)
+          for (int c6 = max(0, -c3 + 1); c6 <= min(31, length - c3); c6 += 1)
+            S_0(c0, 0, c3 + c6 - 1);
+        for (int c5 = max(0, -c2 + 1); c5 <= min(31, (c3 / 2) - c2 - 1); c5 += 1)
+          for (int c6 = 0; c6 <= min(31, length - c3); c6 += 1)
+            S_0(c0, c2 + c5, c3 + c6 - 1);
+        for (int c5 = max(max(0, -c2 + 1), (c3 / 2) - c2); c5 <= min(min(31, length - c2 - 1), (c3 / 2) - c2 + 15); c5 += 1) {
+          for (int c6 = max(0, -c3 + 1); c6 <= min(length - c3, 2 * c2 - c3 + 2 * c5 - 1); c6 += 1)
+            S_0(c0, c2 + c5, c3 + c6 - 1);
+          S_3(c0, 0, c2 + c5);
+          if (length >= 2 * c2 + 2 * c5)
+            S_0(c0, c2 + c5, 2 * c2 + 2 * c5 - 1);
+          for (int c6 = 2 * c2 - c3 + 2 * c5 + 1; c6 <= min(31, length - c3); c6 += 1)
+            S_0(c0, c2 + c5, c3 + c6 - 1);
+        }
+        for (int c5 = max(0, (c3 / 2) - c2 + 16); c5 <= min(31, length - c2 - 1); c5 += 1)
+          for (int c6 = max(0, -c3 + 1); c6 <= min(31, length - c3); c6 += 1)
+            S_0(c0, c2 + c5, c3 + c6 - 1);
+        if (length <= 15 && c2 == 0 && c3 == 0)
+          S_4(c0);
+        if (c3 >= 2 * c2 && 2 * c2 + 32 >= c3)
+          for (int c4 = 1; c4 <= min(min(31, length - 2), (c3 / 2) + 14); c4 += 1)
+            for (int c5 = max((c3 / 2) - c2, -c2 + c4 + 1); c5 <= min(length - c2 - 1, (c3 / 2) - c2 + 15); c5 += 1)
+              S_3(c0, c4, c2 + c5);
+      }
+      for (int c3 = max(2 * c2, -(length % 32) + length + 32); c3 <= min(2 * length - 2, 2 * c2 + 62); c3 += 32)
+        for (int c4 = 0; c4 <= min(31, length - 2); c4 += 1) {
+          for (int c5 = max((c3 / 2) - c2, -c2 + c4 + 1); c5 <= min(length - c2 - 1, (c3 / 2) - c2 + 15); c5 += 1)
+            S_3(c0, c4, c2 + c5);
+          if (c3 + 30 >= 2 * length && c4 == 0)
             S_4(c0);
         }
-      if (c1 == 0) {
-        for (int c3 = 2 * c2 + 64; c3 <= length; c3 += 32)
-          for (int c5 = 0; c5 <= 31; c5 += 1)
-            for (int c6 = 0; c6 <= min(31, length - c3); c6 += 1)
-              S_0(c0, c2 + c5, c3 + c6 - 1);
-        if (c2 + 16 == length)
-          S_4(c0);
-      }
-    }
-    if (c1 == 0 && length % 32 == 0)
+      if (c2 + 16 == length)
+        S_4(c0);
+    } else if (length >= 32) {
       S_4(c0);
+    } else {
+      S_4(c0);
+    }
   }
-  if (length <= 1) {
-    if (length == 1)
-      S_0(c0, 0, 0);
-    S_4(c0);
-  }
+  for (int c1 = 32; c1 < length - 1; c1 += 32)
+    for (int c2 = c1; c2 < length; c2 += 32)
+      for (int c3 = c2; c3 <= min(length - 1, c2 + 31); c3 += 16)
+        for (int c4 = 0; c4 <= min(min(31, length - c1 - 2), -c1 + c3 + 14); c4 += 1)
+          for (int c5 = max(-c2 + c3, c1 - c2 + c4 + 1); c5 <= min(length - c2 - 1, -c2 + c3 + 15); c5 += 1)
+            S_3(c0, c1 + c4, c2 + c5);
 }
diff --git a/lib/External/isl/test_inputs/gist1.polylib b/lib/External/isl/test_inputs/gist1.polylib
deleted file mode 100644
index 802a4eb..0000000
--- a/lib/External/isl/test_inputs/gist1.polylib
+++ /dev/null
@@ -1,14 +0,0 @@
-4 5
-0 1 0 0 -1
-0 0 1 0 1
-0 0 0 1 -3
-1 0 0 0 1
-
-4 5
-0 1 0 0 -1
-0 0 1 1 -2
-1 0 0 1 0
-1 0 0 -1 3
-
-1 5
-0 0 1 0 1
diff --git a/test/DependenceInfo/computeout.ll b/test/DependenceInfo/computeout.ll
index 5f7fd37..69ee233 100644
--- a/test/DependenceInfo/computeout.ll
+++ b/test/DependenceInfo/computeout.ll
@@ -57,14 +57,14 @@
 ; VALUE-NEXT: WAR dependences:
 ; VALUE-NEXT:     {  }
 ; VALUE-NEXT: WAW dependences:
-; VALUE-NEXT:     { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+; VALUE-NEXT:     { Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9 }
 
 ; FUNC-VALUE:      RAW dependences:
 ; FUNC-VALUE-NEXT:     {  }
 ; FUNC-VALUE-NEXT: WAR dependences:
 ; FUNC-VALUE-NEXT:     {  }
 ; FUNC-VALUE-NEXT: WAW dependences:
-; FUNC-VALUE-NEXT:     { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; [Stmt_S2[i0] -> Stmt_S2_Write0[]] -> [Stmt_S3[i0] ->  Stmt_S3_Write0[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] ->  [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+; FUNC-VALUE-NEXT:     { Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S2[i0] -> Stmt_S2_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 10 <= i0 <= 99 }
 
 ; TIMEOUT:      RAW dependences:
 ; TIMEOUT-NEXT:     n/a
diff --git a/test/DependenceInfo/different_schedule_dimensions.ll b/test/DependenceInfo/different_schedule_dimensions.ll
index a9b818f..bcd84ce 100644
--- a/test/DependenceInfo/different_schedule_dimensions.ll
+++ b/test/DependenceInfo/different_schedule_dimensions.ll
@@ -15,7 +15,7 @@
 ; FUNC: RAW dependences:
 ; FUNC-NEXT:   { Stmt_bb9[0] -> Stmt_bb10[0]; [Stmt_bb9[0] -> Stmt_bb9_Write0[]] -> [Stmt_bb10[0] -> Stmt_bb10_Read0[]] }
 ; FUNC-NEXT: WAR dependences:
-; FUNC-NEXT:   { [Stmt_bb3[0] -> Stmt_bb3_Read0[]] -> [Stmt_bb10[0] -> Stmt_bb10_Write1[]]; Stmt_bb3[0] -> Stmt_bb10[0] }
+; FUNC-NEXT:   { Stmt_bb3[0] -> Stmt_bb10[0]; [Stmt_bb3[0] -> Stmt_bb3_Read0[]] -> [Stmt_bb10[0] -> Stmt_bb10_Write1[]] }
 ; FUNC-NEXT: WAW dependences:
 ; FUNC-NEXT:   { Stmt_bb3[0] -> Stmt_bb10[0]; [Stmt_bb3[0] -> Stmt_bb3_Write1[]] -> [Stmt_bb10[0] -> Stmt_bb10_Write1[]] }
 ; FUNC-NEXT: Reduction dependences:
diff --git a/test/DependenceInfo/fine_grain_dep_0.ll b/test/DependenceInfo/fine_grain_dep_0.ll
index 3624e83..57c97e6 100644
--- a/test/DependenceInfo/fine_grain_dep_0.ll
+++ b/test/DependenceInfo/fine_grain_dep_0.ll
@@ -3,7 +3,7 @@
 ; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-function-dependences -polly-dependences-analysis-type=value-based -polly-dependences-analysis-level=access-wise -analyze < %s | FileCheck %s --check-prefix=ACC
 ;
 ; REF:      RAW dependences:
-; REF-NEXT:     [N] -> { Stmt_for_body[i0] -> Stmt_for_body[6 + i0] : 0 <= i0 <= -13 + N; Stmt_for_body[i0] -> Stmt_for_body[4 + i0] : 0 <= i0 <= -11 + N; [Stmt_for_body[i0] -> MemRef_a[]] -> [Stmt_for_body[4 + i0] -> MemRef_a[]] : 0 <= i0 <= -11 + N; [Stmt_for_body[i0] -> MemRef_b[]] -> [Stmt_for_body[6 + i0] -> MemRef_b[]] : 0 <= i0 <= -13 + N }
+; REF-NEXT:     [N] -> { [Stmt_for_body[i0] -> MemRef_b[]] -> [Stmt_for_body[6 + i0] -> MemRef_b[]] : 0 <= i0 <= -13 + N; Stmt_for_body[i0] -> Stmt_for_body[6 + i0] : 0 <= i0 <= -13 + N; Stmt_for_body[i0] -> Stmt_for_body[4 + i0] : 0 <= i0 <= -11 + N; [Stmt_for_body[i0] -> MemRef_a[]] -> [Stmt_for_body[4 + i0] -> MemRef_a[]] : 0 <= i0 <= -11 + N }
 ; REF-NEXT: WAR dependences:
 ; REF-NEXT:     {  }
 ; REF-NEXT: WAW dependences:
@@ -12,7 +12,7 @@
 ; REF-NEXT:     {  }
 
 ; ACC:      RAW dependences:
-; ACC-NEXT:   [N] -> { Stmt_for_body[i0] -> Stmt_for_body[6 + i0] : 0 <= i0 <= -13 + N; Stmt_for_body[i0] -> Stmt_for_body[4 + i0] : 0 <= i0 <= -11 + N; [Stmt_for_body[i0] -> Stmt_for_body_Write1[]] -> [Stmt_for_body[4 + i0] -> Stmt_for_body_Read0[]] : 0 <= i0 <= -11 + N; [Stmt_for_body[i0] -> Stmt_for_body_Write3[]] -> [Stmt_for_body[6 + i0] -> Stmt_for_body_Read2[]] : 0 <= i0 <= -13 + N }
+; ACC-NEXT:   [N] -> { [Stmt_for_body[i0] -> Stmt_for_body_Write1[]] -> [Stmt_for_body[4 + i0] -> Stmt_for_body_Read0[]] : 0 <= i0 <= -11 + N; Stmt_for_body[i0] -> Stmt_for_body[6 + i0] : 0 <= i0 <= -13 + N; Stmt_for_body[i0] -> Stmt_for_body[4 + i0] : 0 <= i0 <= -11 + N; [Stmt_for_body[i0] -> Stmt_for_body_Write3[]] -> [Stmt_for_body[6 + i0] -> Stmt_for_body_Read2[]] : 0 <= i0 <= -13 + N }
 
 ; ACC-NEXT: WAR dependences:
 ; ACC-NEXT:   [N] -> {  }
diff --git a/test/DependenceInfo/generate_may_write_dependence_info.ll b/test/DependenceInfo/generate_may_write_dependence_info.ll
index 38274e2..8a8d493 100644
--- a/test/DependenceInfo/generate_may_write_dependence_info.ll
+++ b/test/DependenceInfo/generate_may_write_dependence_info.ll
@@ -56,11 +56,11 @@
   ret void
 }
 ; VALUE: RAW dependences:
-; VALUE-NEXT:   { Stmt_A_must_write_20[i0] -> Stmt_B_write_from_A[i0] : 0 <= i0 <= 2999; Stmt_compute_i_square__TO__B_write_from_A[i0] -> Stmt_B_write_from_A[i0] : 0 <= i0 <= 2999 }
+; VALUE-NEXT:   { Stmt_compute_i_square__TO__B_write_from_A[i0] -> Stmt_B_write_from_A[i0] : 0 <= i0 <= 2999; Stmt_A_must_write_20[i0] -> Stmt_B_write_from_A[i0] : 0 <= i0 <= 2999 }
 ; VALUE-NEXT: WAR dependences:
 ; VALUE-NEXT:   { Stmt_B_write_from_A[i0] -> Stmt_A_must_write_42[i0] : 0 <= i0 <= 2999 }
 ; VALUE-NEXT: WAW dependences:
-; VALUE-NEXT:   { Stmt_compute_i_square__TO__B_write_from_A[i0] -> Stmt_A_must_write_42[i0] : 0 <= i0 <= 2999; Stmt_A_must_write_20[i0] -> Stmt_A_must_write_42[i0] : 0 <= i0 <= 2999; Stmt_A_must_write_20[i0] -> Stmt_compute_i_square__TO__B_write_from_A[i0] : 0 <= i0 <= 2999 }
+; VALUE-NEXT:   { Stmt_A_must_write_20[i0] -> Stmt_compute_i_square__TO__B_write_from_A[i0] : 0 <= i0 <= 2999; Stmt_compute_i_square__TO__B_write_from_A[i0] -> Stmt_A_must_write_42[i0] : 0 <= i0 <= 2999; Stmt_A_must_write_20[i0] -> Stmt_A_must_write_42[i0] : 0 <= i0 <= 2999 }
 ; VALUE-NEXT: Reduction dependences:
 ; VALUE-NEXT:   {  }
 ; VALUE-NEXT: Transitive closure of reduction dependences:
diff --git a/test/DependenceInfo/may_writes_do_not_block_must_writes_for_war.ll b/test/DependenceInfo/may_writes_do_not_block_must_writes_for_war.ll
index 858743b..40de1c2 100644
--- a/test/DependenceInfo/may_writes_do_not_block_must_writes_for_war.ll
+++ b/test/DependenceInfo/may_writes_do_not_block_must_writes_for_war.ll
@@ -8,7 +8,7 @@
 ; (S0(Read) -> S2(Must-Write)).
 ;
 ; CHECK: WAR dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S2[i0] : 0 < i0 <= 2; Stmt_S0[i0] -> Stmt_if_end__TO__S2[i0] : 0 < i0 <= 2 }
+; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_if_end__TO__S2[i0] : 0 < i0 <= 2; Stmt_S0[i0] -> Stmt_S2[i0] : 0 < i0 <= 2 }
 ;
 ;
 ;    static const int N = 3000;
diff --git a/test/DependenceInfo/reduction_multiple_reductions.ll b/test/DependenceInfo/reduction_multiple_reductions.ll
index bc8aa3e..532cfb6 100644
--- a/test/DependenceInfo/reduction_multiple_reductions.ll
+++ b/test/DependenceInfo/reduction_multiple_reductions.ll
@@ -9,7 +9,7 @@
 ; CHECK-NEXT: WAW dependences:
 ; CHECK-NEXT:     {  }
 ; CHECK-NEXT: Reduction dependences:
-; CHECK-NEXT:     { Stmt_if_then[i0] -> Stmt_if_then[1 + i0] : 0 <= i0 <= 510; Stmt_if_else[i0] -> Stmt_if_else[1 + i0] : 512 <= i0 <= 1022 }
+; CHECK-NEXT:     { Stmt_if_else[i0] -> Stmt_if_else[1 + i0] : 512 <= i0 <= 1022; Stmt_if_then[i0] -> Stmt_if_then[1 + i0] : 0 <= i0 <= 510 }
 ;
 ; void f(int *restrict sum, int *restrict prod) {
 ;   for (int i = 0; i < 1024; i++)
diff --git a/test/DependenceInfo/reduction_multiple_reductions_2.ll b/test/DependenceInfo/reduction_multiple_reductions_2.ll
index 6da5d4a..89b9cab 100644
--- a/test/DependenceInfo/reduction_multiple_reductions_2.ll
+++ b/test/DependenceInfo/reduction_multiple_reductions_2.ll
@@ -10,11 +10,11 @@
 ;   Stmt_S1[i0, i1] -> Stmt_S2[i0, 0]
 ;
 ; CHECK:      RAW dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S2[i0, i1] -> Stmt_S3[i0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023; Stmt_S3[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 1022; Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022 }
+; CHECK-NEXT:     { Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_S2[i0, i1] -> Stmt_S3[i0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023; Stmt_S3[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 1022; Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023 }
 ; CHECK-NEXT: WAR dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S2[i0, i1] -> Stmt_S3[i0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023; Stmt_S3[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 1022; Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022 }
+; CHECK-NEXT:     { Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_S2[i0, i1] -> Stmt_S3[i0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023; Stmt_S3[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 1022; Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023 }
 ; CHECK-NEXT: WAW dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S2[i0, i1] -> Stmt_S3[i0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023; Stmt_S3[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 1022; Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022 }
+; CHECK-NEXT:     { Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023; Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_S2[i0, i1] -> Stmt_S3[i0] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023; Stmt_S3[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 1022; Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 1023 and 0 <= o1 <= 1023 }
 ; CHECK-NEXT: Reduction dependences:
 ; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S1[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_S2[i0, i1] -> Stmt_S2[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022 }
 ;
diff --git a/test/DependenceInfo/reduction_privatization_deps.ll b/test/DependenceInfo/reduction_privatization_deps.ll
index e51357a..a8de1ec 100644
--- a/test/DependenceInfo/reduction_privatization_deps.ll
+++ b/test/DependenceInfo/reduction_privatization_deps.ll
@@ -1,11 +1,11 @@
 ; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
 ;
 ; CHECK:      RAW dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and 0 <= o0 <= i0; Stmt_S1[i0, i1] -> Stmt_S2[-1 + i0 + i1] : 0 <= i0 <= 1023 and i1 >= 0 and -i0 < i1 <= 1024 - i0 and i1 <= 1023 }
+; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S2[-1 + i0 + i1] : 0 <= i0 <= 1023 and i1 >= 0 and -i0 < i1 <= 1024 - i0 and i1 <= 1023; Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and 0 <= o0 <= i0 }
 ; CHECK-NEXT: WAR dependences:
-; CHECK-NEXT:     { Stmt_S2[i0] -> Stmt_S2[1 + i0] : 0 <= i0 <= 1022; Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i0 >= 0 and 0 <= i1 <= 1023 - i0 }
+; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i0 >= 0 and 0 <= i1 <= 1023 - i0; Stmt_S2[i0] -> Stmt_S2[1 + i0] : 0 <= i0 <= 1022 }
 ; CHECK-NEXT: WAW dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and 0 <= o0 <= i0; Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i0 >= 0 and 0 <= i1 <= 1023 - i0 }
+; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i0 >= 0 and 0 <= i1 <= 1023 - i0; Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and 0 <= o0 <= i0 }
 ; CHECK-NEXT: Reduction dependences:
 ; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S1[1 + i0, -1 + i1] : 0 <= i0 <= 1022 and 0 < i1 <= 1023 }
 ;
diff --git a/test/DependenceInfo/reduction_privatization_deps_3.ll b/test/DependenceInfo/reduction_privatization_deps_3.ll
index 0cf6fc6..66b371b 100644
--- a/test/DependenceInfo/reduction_privatization_deps_3.ll
+++ b/test/DependenceInfo/reduction_privatization_deps_3.ll
@@ -1,11 +1,11 @@
 ; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
 ;
 ; CHECK:      RAW dependences:
-; CHECK-NEXT:     { Stmt_S2[i0, i1] -> Stmt_S3[o0] : i1 <= 1 - i0 and -i1 < o0 <= 1 and o0 <= 1 + i0 - i1; Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : 0 <= i0 <= 1 and i0 < o0 <= 98; Stmt_S1[i0] -> Stmt_S3[2 + i0] : 0 <= i0 <= 96 }
+; CHECK-NEXT:     { Stmt_S1[i0] -> Stmt_S3[2 + i0] : 0 <= i0 <= 96; Stmt_S2[i0, i1] -> Stmt_S3[o0] : i1 <= 1 - i0 and -i1 < o0 <= 1 and o0 <= 1 + i0 - i1; Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : 0 <= i0 <= 1 and i0 < o0 <= 98 }
 ; CHECK-NEXT: WAR dependences:
-; CHECK-NEXT:   { Stmt_S2[i0, i1] -> Stmt_S3[o0] : i1 <= 1 - i0 and -i1 < o0 <= 1 and o0 <= 1 + i0 - i1; Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : 0 <= i0 <= 1 and i0 < o0 <= 98; Stmt_S1[i0] -> Stmt_S3[2 + i0] : 0 <= i0 <= 96 }
+; CHECK-NEXT:     { Stmt_S1[i0] -> Stmt_S3[2 + i0] : 0 <= i0 <= 96; Stmt_S2[i0, i1] -> Stmt_S3[o0] : i1 <= 1 - i0 and -i1 < o0 <= 1 and o0 <= 1 + i0 - i1; Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : 0 <= i0 <= 1 and i0 < o0 <= 98 }
 ; CHECK-NEXT: WAW dependences:
-; CHECK-NEXT:     { Stmt_S2[i0, i1] -> Stmt_S3[o0] : i1 <= 1 - i0 and -i1 < o0 <= 1 and o0 <= 1 + i0 - i1; Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : 0 <= i0 <= 1 and i0 < o0 <= 98; Stmt_S1[i0] -> Stmt_S3[2 + i0] : 0 <= i0 <= 96 }
+; CHECK-NEXT:     { Stmt_S1[i0] -> Stmt_S3[2 + i0] : 0 <= i0 <= 96; Stmt_S2[i0, i1] -> Stmt_S3[o0] : i1 <= 1 - i0 and -i1 < o0 <= 1 and o0 <= 1 + i0 - i1; Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : 0 <= i0 <= 1 and i0 < o0 <= 98 }
 ; CHECK-NEXT: Reduction dependences:
 ; CHECK-NEXT:     { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : 0 <= i0 <= 97 and i1 >= 0 and 2 - i0 <= i1 <= 98 - i0; Stmt_S2[0, 0] -> Stmt_S2[1, 0] }
 ;
diff --git a/test/DependenceInfo/reduction_privatization_deps_4.ll b/test/DependenceInfo/reduction_privatization_deps_4.ll
index 68fbd08..a83bf23 100644
--- a/test/DependenceInfo/reduction_privatization_deps_4.ll
+++ b/test/DependenceInfo/reduction_privatization_deps_4.ll
@@ -1,11 +1,11 @@
 ; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
 ;
 ; CHECK:      RAW dependences:
-; CHECK-NEXT:     { Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i0 < i1 <= 98; Stmt_S1[i0] -> Stmt_S2[i0, i0] : 0 <= i0 <= 98; Stmt_S2[i0, i0] -> Stmt_S3[i0] : 0 <= i0 <= 98; Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and i0 < o0 <= 98 }
+; CHECK-NEXT:     { Stmt_S1[i0] -> Stmt_S2[i0, i0] : 0 <= i0 <= 98; Stmt_S2[i0, i0] -> Stmt_S3[i0] : 0 <= i0 <= 98; Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and i0 < o0 <= 98; Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i0 < i1 <= 98 }
 ; CHECK-NEXT: WAR dependences:
-; CHECK-NEXT:   { Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i0 < i1 <= 98; Stmt_S1[i0] -> Stmt_S2[i0, i0] : 0 <= i0 <= 98; Stmt_S2[i0, i0] -> Stmt_S3[i0] : 0 <= i0 <= 98; Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and i0 < o0 <= 98 }
+; CHECK-NEXT:     { Stmt_S1[i0] -> Stmt_S2[i0, i0] : 0 <= i0 <= 98; Stmt_S2[i0, i0] -> Stmt_S3[i0] : 0 <= i0 <= 98; Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and i0 < o0 <= 98; Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i0 < i1 <= 98 }
 ; CHECK-NEXT: WAW dependences:
-; CHECK-NEXT:     { Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i0 < i1 <= 98; Stmt_S1[i0] -> Stmt_S2[i0, i0] : 0 <= i0 <= 98; Stmt_S2[i0, i0] -> Stmt_S3[i0] : 0 <= i0 <= 98; Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and i0 < o0 <= 98 }
+; CHECK-NEXT:     { Stmt_S1[i0] -> Stmt_S2[i0, i0] : 0 <= i0 <= 98; Stmt_S2[i0, i0] -> Stmt_S3[i0] : 0 <= i0 <= 98; Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and i0 < o0 <= 98; Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i0 < i1 <= 98 }
 ; CHECK-NEXT: Reduction dependences:
 ; CHECK-NEXT:     { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : (i0 >= 0 and 2 + i0 <= i1 <= 99) or (i0 <= 97 and 0 <= i1 < i0) }
 ;
diff --git a/test/DependenceInfo/reduction_privatization_deps_5.ll b/test/DependenceInfo/reduction_privatization_deps_5.ll
index 9c002b4..d5f5e7b 100644
--- a/test/DependenceInfo/reduction_privatization_deps_5.ll
+++ b/test/DependenceInfo/reduction_privatization_deps_5.ll
@@ -1,11 +1,11 @@
 ; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
 ;
 ; CHECK:      RAW dependences:
-; CHECK-NEXT:     { Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : 0 <= i0 <= 97; Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : 0 <= i0 <= 98 }
+; CHECK-NEXT:     { Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : 0 <= i0 <= 98; Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : 0 <= i0 <= 97 }
 ; CHECK-NEXT: WAR dependences:
-; CHECK-NEXT:     { Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : 0 <= i0 <= 97; Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : 0 <= i0 <= 98 }
+; CHECK-NEXT:     { Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : 0 <= i0 <= 98; Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : 0 <= i0 <= 97 }
 ; CHECK-NEXT: WAW dependences:
-; CHECK-NEXT:     { Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : 0 <= i0 <= 97; Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : 0 <= i0 <= 98 }
+; CHECK-NEXT:     { Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : 0 <= i0 <= 98; Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : 0 <= i0 <= 97 }
 ; CHECK-NEXT: Reduction dependences:
 ; CHECK-NEXT:     { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : 0 <= i0 <= 97 and 0 < i1 <= 99 }
 ;
diff --git a/test/DependenceInfo/reduction_sequence.ll b/test/DependenceInfo/reduction_sequence.ll
index 05d8697..1df0b15 100644
--- a/test/DependenceInfo/reduction_sequence.ll
+++ b/test/DependenceInfo/reduction_sequence.ll
@@ -59,16 +59,16 @@
 ;    }
 
 ; CHECK: 	RAW dependences:
-; CHECK-NEXT: 		{ Stmt_bb150[1023, 1023] -> Stmt_bb162[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb150[i0, i1] -> Stmt_bb162[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb150[1023, 1023] -> Stmt_bb162[0, 0]; Stmt_bb174[1023, 1023] -> Stmt_bb186[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb174[i0, i1] -> Stmt_bb186[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb174[1023, 1023] -> Stmt_bb186[0, 0]; Stmt_bb102[1023, 1023] -> Stmt_bb114[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb102[i0, i1] -> Stmt_bb114[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb102[1023, 1023] -> Stmt_bb114[0, 0]; Stmt_bb42[1023, 1023] -> Stmt_bb54[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb42[i0, i1] -> Stmt_bb54[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb42[1023, 1023] -> Stmt_bb54[0, 0]; Stmt_bb54[1023, 1023] -> Stmt_bb66[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb54[i0, i1] -> Stmt_bb66[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb54[1023, 1023] -> Stmt_bb66[0, 0]; Stmt_bb31[1023, 1023] -> Stmt_bb42[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb31[i0, i1] -> Stmt_bb42[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb31[1023, 1023] -> Stmt_bb42[0, 0]; Stmt_bb162[1023, 1023] -> Stmt_bb174[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb162[i0, i1] -> Stmt_bb174[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb162[1023, 1023] -> Stmt_bb174[0, 0]; Stmt_bb126[1023, 1023] -> Stmt_bb138[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb126[i0, i1] -> Stmt_bb138[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb126[1023, 1023] -> Stmt_bb138[0, 0]; Stmt_bb90[1023, 1023] -> Stmt_bb102[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb90[i0, i1] -> Stmt_bb102[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb90[1023, 1023] -> Stmt_bb102[0, 0]; Stmt_bb138[1023, 1023] -> Stmt_bb150[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb138[i0, i1] -> Stmt_bb150[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb138[1023, 1023] -> Stmt_bb150[0, 0]; Stmt_bb66[1023, 1023] -> Stmt_bb78[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb66[i0, i1] -> Stmt_bb78[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb66[1023, 1023] -> Stmt_bb78[0, 0]; Stmt_bb78[1023, 1023] -> Stmt_bb90[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb78[i0, i1] -> Stmt_bb90[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb78[1023, 1023] -> Stmt_bb90[0, 0]; Stmt_bb114[1023, 1023] -> Stmt_bb126[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb114[i0, i1] -> Stmt_bb126[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb114[1023, 1023] -> Stmt_bb126[0, 0] }
+; CHECK-NEXT: 		{ Stmt_bb90[1023, 1023] -> Stmt_bb102[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb90[i0, i1] -> Stmt_bb102[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb90[1023, 1023] -> Stmt_bb102[0, 0]; Stmt_bb150[1023, 1023] -> Stmt_bb162[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb150[i0, i1] -> Stmt_bb162[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb150[1023, 1023] -> Stmt_bb162[0, 0]; Stmt_bb66[1023, 1023] -> Stmt_bb78[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb66[i0, i1] -> Stmt_bb78[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb66[1023, 1023] -> Stmt_bb78[0, 0]; Stmt_bb126[1023, 1023] -> Stmt_bb138[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb126[i0, i1] -> Stmt_bb138[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb126[1023, 1023] -> Stmt_bb138[0, 0]; Stmt_bb54[1023, 1023] -> Stmt_bb66[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb54[i0, i1] -> Stmt_bb66[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb54[1023, 1023] -> Stmt_bb66[0, 0]; Stmt_bb174[1023, 1023] -> Stmt_bb186[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb174[i0, i1] -> Stmt_bb186[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb174[1023, 1023] -> Stmt_bb186[0, 0]; Stmt_bb114[1023, 1023] -> Stmt_bb126[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb114[i0, i1] -> Stmt_bb126[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb114[1023, 1023] -> Stmt_bb126[0, 0]; Stmt_bb31[1023, 1023] -> Stmt_bb42[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb31[i0, i1] -> Stmt_bb42[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb31[1023, 1023] -> Stmt_bb42[0, 0]; Stmt_bb42[1023, 1023] -> Stmt_bb54[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb42[i0, i1] -> Stmt_bb54[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb42[1023, 1023] -> Stmt_bb54[0, 0]; Stmt_bb78[1023, 1023] -> Stmt_bb90[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb78[i0, i1] -> Stmt_bb90[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb78[1023, 1023] -> Stmt_bb90[0, 0]; Stmt_bb138[1023, 1023] -> Stmt_bb150[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb138[i0, i1] -> Stmt_bb150[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb138[1023, 1023] -> Stmt_bb150[0, 0]; Stmt_bb102[1023, 1023] -> Stmt_bb114[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb102[i0, i1] -> Stmt_bb114[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb102[1023, 1023] -> Stmt_bb114[0, 0]; Stmt_bb162[1023, 1023] -> Stmt_bb174[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb162[i0, i1] -> Stmt_bb174[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb162[1023, 1023] -> Stmt_bb174[0, 0] }
 ; CHECK-NEXT: 	WAR dependences:
-; CHECK-NEXT:     { Stmt_bb150[1023, 1023] -> Stmt_bb162[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb150[i0, i1] -> Stmt_bb162[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb150[1023, 1023] -> Stmt_bb162[0, 0]; Stmt_bb174[1023, 1023] -> Stmt_bb186[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb174[i0, i1] -> Stmt_bb186[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb174[1023, 1023] -> Stmt_bb186[0, 0]; Stmt_bb102[1023, 1023] -> Stmt_bb114[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb102[i0, i1] -> Stmt_bb114[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb102[1023, 1023] -> Stmt_bb114[0, 0]; Stmt_bb42[1023, 1023] -> Stmt_bb54[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb42[i0, i1] -> Stmt_bb54[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb42[1023, 1023] -> Stmt_bb54[0, 0]; Stmt_bb54[1023, 1023] -> Stmt_bb66[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb54[i0, i1] -> Stmt_bb66[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb54[1023, 1023] -> Stmt_bb66[0, 0]; Stmt_bb31[1023, 1023] -> Stmt_bb42[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb31[i0, i1] -> Stmt_bb42[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb31[1023, 1023] -> Stmt_bb42[0, 0]; Stmt_bb162[1023, 1023] -> Stmt_bb174[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb162[i0, i1] -> Stmt_bb174[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb162[1023, 1023] -> Stmt_bb174[0, 0]; Stmt_bb126[1023, 1023] -> Stmt_bb138[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb126[i0, i1] -> Stmt_bb138[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb126[1023, 1023] -> Stmt_bb138[0, 0]; Stmt_bb90[1023, 1023] -> Stmt_bb102[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb90[i0, i1] -> Stmt_bb102[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb90[1023, 1023] -> Stmt_bb102[0, 0]; Stmt_bb138[1023, 1023] -> Stmt_bb150[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb138[i0, i1] -> Stmt_bb150[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb138[1023, 1023] -> Stmt_bb150[0, 0]; Stmt_bb66[1023, 1023] -> Stmt_bb78[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb66[i0, i1] -> Stmt_bb78[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb66[1023, 1023] -> Stmt_bb78[0, 0]; Stmt_bb78[1023, 1023] -> Stmt_bb90[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb78[i0, i1] -> Stmt_bb90[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb78[1023, 1023] -> Stmt_bb90[0, 0]; Stmt_bb114[1023, 1023] -> Stmt_bb126[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb114[i0, i1] -> Stmt_bb126[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb114[1023, 1023] -> Stmt_bb126[0, 0] }
+; CHECK-NEXT:     { Stmt_bb90[1023, 1023] -> Stmt_bb102[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb90[i0, i1] -> Stmt_bb102[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb90[1023, 1023] -> Stmt_bb102[0, 0]; Stmt_bb150[1023, 1023] -> Stmt_bb162[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb150[i0, i1] -> Stmt_bb162[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb150[1023, 1023] -> Stmt_bb162[0, 0]; Stmt_bb66[1023, 1023] -> Stmt_bb78[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb66[i0, i1] -> Stmt_bb78[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb66[1023, 1023] -> Stmt_bb78[0, 0]; Stmt_bb126[1023, 1023] -> Stmt_bb138[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb126[i0, i1] -> Stmt_bb138[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb126[1023, 1023] -> Stmt_bb138[0, 0]; Stmt_bb54[1023, 1023] -> Stmt_bb66[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb54[i0, i1] -> Stmt_bb66[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb54[1023, 1023] -> Stmt_bb66[0, 0]; Stmt_bb174[1023, 1023] -> Stmt_bb186[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb174[i0, i1] -> Stmt_bb186[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb174[1023, 1023] -> Stmt_bb186[0, 0]; Stmt_bb114[1023, 1023] -> Stmt_bb126[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb114[i0, i1] -> Stmt_bb126[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb114[1023, 1023] -> Stmt_bb126[0, 0]; Stmt_bb31[1023, 1023] -> Stmt_bb42[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb31[i0, i1] -> Stmt_bb42[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb31[1023, 1023] -> Stmt_bb42[0, 0]; Stmt_bb42[1023, 1023] -> Stmt_bb54[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb42[i0, i1] -> Stmt_bb54[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb42[1023, 1023] -> Stmt_bb54[0, 0]; Stmt_bb78[1023, 1023] -> Stmt_bb90[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb78[i0, i1] -> Stmt_bb90[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb78[1023, 1023] -> Stmt_bb90[0, 0]; Stmt_bb138[1023, 1023] -> Stmt_bb150[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb138[i0, i1] -> Stmt_bb150[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb138[1023, 1023] -> Stmt_bb150[0, 0]; Stmt_bb102[1023, 1023] -> Stmt_bb114[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb102[i0, i1] -> Stmt_bb114[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb102[1023, 1023] -> Stmt_bb114[0, 0]; Stmt_bb162[1023, 1023] -> Stmt_bb174[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb162[i0, i1] -> Stmt_bb174[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb162[1023, 1023] -> Stmt_bb174[0, 0] }
 ; CHECK-NEXT: 	WAW dependences:
-; CHECK-NEXT: 		{ Stmt_bb150[1023, 1023] -> Stmt_bb162[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb150[i0, i1] -> Stmt_bb162[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb150[1023, 1023] -> Stmt_bb162[0, 0]; Stmt_bb174[1023, 1023] -> Stmt_bb186[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb174[i0, i1] -> Stmt_bb186[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb174[1023, 1023] -> Stmt_bb186[0, 0]; Stmt_bb102[1023, 1023] -> Stmt_bb114[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb102[i0, i1] -> Stmt_bb114[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb102[1023, 1023] -> Stmt_bb114[0, 0]; Stmt_bb42[1023, 1023] -> Stmt_bb54[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb42[i0, i1] -> Stmt_bb54[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb42[1023, 1023] -> Stmt_bb54[0, 0]; Stmt_bb54[1023, 1023] -> Stmt_bb66[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb54[i0, i1] -> Stmt_bb66[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb54[1023, 1023] -> Stmt_bb66[0, 0]; Stmt_bb31[1023, 1023] -> Stmt_bb42[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb31[i0, i1] -> Stmt_bb42[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb31[1023, 1023] -> Stmt_bb42[0, 0]; Stmt_bb162[1023, 1023] -> Stmt_bb174[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb162[i0, i1] -> Stmt_bb174[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb162[1023, 1023] -> Stmt_bb174[0, 0]; Stmt_bb126[1023, 1023] -> Stmt_bb138[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb126[i0, i1] -> Stmt_bb138[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb126[1023, 1023] -> Stmt_bb138[0, 0]; Stmt_bb90[1023, 1023] -> Stmt_bb102[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb90[i0, i1] -> Stmt_bb102[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb90[1023, 1023] -> Stmt_bb102[0, 0]; Stmt_bb138[1023, 1023] -> Stmt_bb150[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb138[i0, i1] -> Stmt_bb150[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb138[1023, 1023] -> Stmt_bb150[0, 0]; Stmt_bb66[1023, 1023] -> Stmt_bb78[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb66[i0, i1] -> Stmt_bb78[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb66[1023, 1023] -> Stmt_bb78[0, 0]; Stmt_bb78[1023, 1023] -> Stmt_bb90[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb78[i0, i1] -> Stmt_bb90[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb78[1023, 1023] -> Stmt_bb90[0, 0]; Stmt_bb114[1023, 1023] -> Stmt_bb126[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb114[i0, i1] -> Stmt_bb126[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb114[1023, 1023] -> Stmt_bb126[0, 0] }
+; CHECK-NEXT: 		{ Stmt_bb90[1023, 1023] -> Stmt_bb102[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb90[i0, i1] -> Stmt_bb102[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb90[1023, 1023] -> Stmt_bb102[0, 0]; Stmt_bb150[1023, 1023] -> Stmt_bb162[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb150[i0, i1] -> Stmt_bb162[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb150[1023, 1023] -> Stmt_bb162[0, 0]; Stmt_bb66[1023, 1023] -> Stmt_bb78[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb66[i0, i1] -> Stmt_bb78[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb66[1023, 1023] -> Stmt_bb78[0, 0]; Stmt_bb126[1023, 1023] -> Stmt_bb138[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb126[i0, i1] -> Stmt_bb138[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb126[1023, 1023] -> Stmt_bb138[0, 0]; Stmt_bb54[1023, 1023] -> Stmt_bb66[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb54[i0, i1] -> Stmt_bb66[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb54[1023, 1023] -> Stmt_bb66[0, 0]; Stmt_bb174[1023, 1023] -> Stmt_bb186[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb174[i0, i1] -> Stmt_bb186[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb174[1023, 1023] -> Stmt_bb186[0, 0]; Stmt_bb114[1023, 1023] -> Stmt_bb126[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb114[i0, i1] -> Stmt_bb126[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb114[1023, 1023] -> Stmt_bb126[0, 0]; Stmt_bb31[1023, 1023] -> Stmt_bb42[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb31[i0, i1] -> Stmt_bb42[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb31[1023, 1023] -> Stmt_bb42[0, 0]; Stmt_bb42[1023, 1023] -> Stmt_bb54[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb42[i0, i1] -> Stmt_bb54[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb42[1023, 1023] -> Stmt_bb54[0, 0]; Stmt_bb78[1023, 1023] -> Stmt_bb90[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb78[i0, i1] -> Stmt_bb90[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb78[1023, 1023] -> Stmt_bb90[0, 0]; Stmt_bb138[1023, 1023] -> Stmt_bb150[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb138[i0, i1] -> Stmt_bb150[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb138[1023, 1023] -> Stmt_bb150[0, 0]; Stmt_bb102[1023, 1023] -> Stmt_bb114[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb102[i0, i1] -> Stmt_bb114[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb102[1023, 1023] -> Stmt_bb114[0, 0]; Stmt_bb162[1023, 1023] -> Stmt_bb174[o0, o1] : o0 <= 1023 and o1 >= 0 and -1024o0 < o1 <= 1023; Stmt_bb162[i0, i1] -> Stmt_bb174[0, 0] : i0 >= 0 and 0 <= i1 <= 1048574 - 1024i0 and i1 <= 1023; Stmt_bb162[1023, 1023] -> Stmt_bb174[0, 0] }
 ; CHECK-NEXT: 	Reduction dependences:
-; CHECK-NEXT: 		{ Stmt_bb102[i0, i1] -> Stmt_bb102[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb102[i0, 1023] -> Stmt_bb102[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb90[i0, i1] -> Stmt_bb90[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb90[i0, 1023] -> Stmt_bb90[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb186[i0, i1] -> Stmt_bb186[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb186[i0, 1023] -> Stmt_bb186[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb66[i0, i1] -> Stmt_bb66[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb66[i0, 1023] -> Stmt_bb66[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb31[i0, i1] -> Stmt_bb31[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb31[i0, 1023] -> Stmt_bb31[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb138[i0, i1] -> Stmt_bb138[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb138[i0, 1023] -> Stmt_bb138[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb126[i0, i1] -> Stmt_bb126[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb126[i0, 1023] -> Stmt_bb126[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb42[i0, i1] -> Stmt_bb42[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb42[i0, 1023] -> Stmt_bb42[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb150[i0, i1] -> Stmt_bb150[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb150[i0, 1023] -> Stmt_bb150[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb78[i0, i1] -> Stmt_bb78[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb78[i0, 1023] -> Stmt_bb78[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb174[i0, i1] -> Stmt_bb174[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb174[i0, 1023] -> Stmt_bb174[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb114[i0, i1] -> Stmt_bb114[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb114[i0, 1023] -> Stmt_bb114[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb162[i0, i1] -> Stmt_bb162[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb162[i0, 1023] -> Stmt_bb162[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb54[i0, i1] -> Stmt_bb54[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb54[i0, 1023] -> Stmt_bb54[1 + i0, 0] : 0 <= i0 <= 1022 }
+; CHECK-NEXT: 		{ Stmt_bb162[i0, i1] -> Stmt_bb162[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb162[i0, 1023] -> Stmt_bb162[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb90[i0, i1] -> Stmt_bb90[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb90[i0, 1023] -> Stmt_bb90[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb150[i0, i1] -> Stmt_bb150[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb150[i0, 1023] -> Stmt_bb150[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb186[i0, i1] -> Stmt_bb186[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb186[i0, 1023] -> Stmt_bb186[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb66[i0, i1] -> Stmt_bb66[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb66[i0, 1023] -> Stmt_bb66[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb31[i0, i1] -> Stmt_bb31[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb31[i0, 1023] -> Stmt_bb31[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb102[i0, i1] -> Stmt_bb102[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb102[i0, 1023] -> Stmt_bb102[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb138[i0, i1] -> Stmt_bb138[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb138[i0, 1023] -> Stmt_bb138[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb54[i0, i1] -> Stmt_bb54[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb54[i0, 1023] -> Stmt_bb54[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb174[i0, i1] -> Stmt_bb174[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb174[i0, 1023] -> Stmt_bb174[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb78[i0, i1] -> Stmt_bb78[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb78[i0, 1023] -> Stmt_bb78[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb126[i0, i1] -> Stmt_bb126[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb126[i0, 1023] -> Stmt_bb126[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb114[i0, i1] -> Stmt_bb114[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb114[i0, 1023] -> Stmt_bb114[1 + i0, 0] : 0 <= i0 <= 1022; Stmt_bb42[i0, i1] -> Stmt_bb42[i0, 1 + i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1022; Stmt_bb42[i0, 1023] -> Stmt_bb42[1 + i0, 0] : 0 <= i0 <= 1022 }
 
 ; CHECK-NEXT: 	Transitive closure of reduction dependences:
-; CHECK-NEXT:  { Stmt_bb102[i0, i1] -> Stmt_bb102[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb90[i0, i1] -> Stmt_bb90[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb186[i0, i1] -> Stmt_bb186[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb66[i0, i1] -> Stmt_bb66[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb31[i0, i1] -> Stmt_bb31[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb138[i0, i1] -> Stmt_bb138[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb126[i0, i1] -> Stmt_bb126[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb42[i0, i1] -> Stmt_bb42[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb150[i0, i1] -> Stmt_bb150[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb78[i0, i1] -> Stmt_bb78[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb174[i0, i1] -> Stmt_bb174[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb114[i0, i1] -> Stmt_bb114[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb162[i0, i1] -> Stmt_bb162[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb54[i0, i1] -> Stmt_bb54[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)) }
+; CHECK-NEXT:  { Stmt_bb162[i0, i1] -> Stmt_bb162[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb90[i0, i1] -> Stmt_bb90[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb150[i0, i1] -> Stmt_bb150[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb186[i0, i1] -> Stmt_bb186[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb66[i0, i1] -> Stmt_bb66[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb31[i0, i1] -> Stmt_bb31[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb102[i0, i1] -> Stmt_bb102[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb138[i0, i1] -> Stmt_bb138[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb54[i0, i1] -> Stmt_bb54[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb174[i0, i1] -> Stmt_bb174[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb78[i0, i1] -> Stmt_bb78[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb126[i0, i1] -> Stmt_bb126[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb114[i0, i1] -> Stmt_bb114[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)); Stmt_bb42[i0, i1] -> Stmt_bb42[o0, o1] : 0 <= i1 <= 1023 and 0 <= o1 <= 1023 and ((i0 >= 0 and o0 <= 1023 and o1 > 1024i0 + i1 - 1024o0) or (i0 <= 1023 and o0 >= 0 and o1 < 1024i0 + i1 - 1024o0)) }
 
 ;
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/DependenceInfo/reduction_simple_privatization_deps_2.ll b/test/DependenceInfo/reduction_simple_privatization_deps_2.ll
index 215abc9..ed34187 100644
--- a/test/DependenceInfo/reduction_simple_privatization_deps_2.ll
+++ b/test/DependenceInfo/reduction_simple_privatization_deps_2.ll
@@ -1,11 +1,11 @@
 ; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
 ;
 ; CHECK:      RAW dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 99 and 0 <= o1 <= 99; Stmt_S2[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 98; Stmt_S1[i0, i1] -> Stmt_S2[i0] : 0 <= i0 <= 99 and 0 <= i1 <= 99 }
+; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S2[i0] : 0 <= i0 <= 99 and 0 <= i1 <= 99; Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 99 and 0 <= o1 <= 99; Stmt_S2[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 98 }
 ; CHECK-NEXT: WAR dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 99 and 0 <= o1 <= 99; Stmt_S2[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 98; Stmt_S1[i0, i1] -> Stmt_S2[i0] : 0 <= i0 <= 99 and 0 <= i1 <= 99 }
+; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S2[i0] : 0 <= i0 <= 99 and 0 <= i1 <= 99; Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 99 and 0 <= o1 <= 99; Stmt_S2[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 98 }
 ; CHECK-NEXT: WAW dependences:
-; CHECK-NEXT:     { Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 99 and 0 <= o1 <= 99; Stmt_S2[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 98; Stmt_S1[i0, i1] -> Stmt_S2[i0] : 0 <= i0 <= 99 and 0 <= i1 <= 99 }
+; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S2[i0] : 0 <= i0 <= 99 and 0 <= i1 <= 99; Stmt_S0[i0] -> Stmt_S1[i0, o1] : 0 <= i0 <= 99 and 0 <= o1 <= 99; Stmt_S2[i0] -> Stmt_S0[1 + i0] : 0 <= i0 <= 98 }
 ; CHECK-NEXT: Reduction dependences:
 ; CHECK-NEXT:     { Stmt_S1[i0, i1] -> Stmt_S1[i0, 1 + i1] : 0 <= i0 <= 99 and 0 <= i1 <= 98 }
 ;
diff --git a/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll b/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll
index 9ef1d74..73876b1 100644
--- a/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll
+++ b/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll
@@ -1,11 +1,11 @@
 ; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
 ;
 ; CHECK:      RAW dependences:
-; CHECK-NEXT:     [N] -> { Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and 0 <= o0 <= 1023; Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and 0 <= i0 <= 1023 }
+; CHECK-NEXT:     [N] -> { Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and 0 <= i0 <= 1023; Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and 0 <= o0 <= 1023 }
 ; CHECK-NEXT: WAR dependences:
 ; CHECK-NEXT:     [N] -> { Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and 0 <= i0 <= 1023 }
 ; CHECK-NEXT: WAW dependences:
-; CHECK-NEXT:     [N] -> { Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and 0 <= o0 <= 1023; Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and 0 <= i0 <= 1023 }
+; CHECK-NEXT:     [N] -> { Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and 0 <= i0 <= 1023; Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and 0 <= o0 <= 1023 }
 ; CHECK-NEXT: Reduction dependences:
 ; CHECK-NEXT:     [N] -> { Stmt_S1[i0] -> Stmt_S1[1 + i0] : N >= 11 and 0 <= i0 <= 1022 }
 ;
diff --git a/test/DependenceInfo/sequential_loops.ll b/test/DependenceInfo/sequential_loops.ll
index 5857e1d..de93148 100644
--- a/test/DependenceInfo/sequential_loops.ll
+++ b/test/DependenceInfo/sequential_loops.ll
@@ -8,7 +8,7 @@
 ; VALUE-NEXT:      WAR dependences:
 ; VALUE-NEXT:          {  }
 ; VALUE-NEXT:      WAW dependences:
-; VALUE-NEXT:          { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+; VALUE-NEXT:          { Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9 }
 ;
 ;VALUE_ACCESS-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'sequential_writes':
 ;VALUE_ACCESS-NEXT:        RAW dependences:
@@ -16,7 +16,7 @@
 ;VALUE_ACCESS-NEXT:        WAR dependences:
 ;VALUE_ACCESS-NEXT:                {  }
 ;VALUE_ACCESS-NEXT:        WAW dependences:
-;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; [Stmt_S2[i0] -> Stmt_S2_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S2[i0] -> Stmt_S2_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 10 <= i0 <= 99 }
 
 ;
 ; VALUE-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'read_after_writes':
@@ -29,12 +29,12 @@
 ;
 ;VALUE_ACCESS-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'read_after_writes':
 ;VALUE_ACCESS-NEXT:        RAW dependences:
-;VALUE_ACCESS-NEXT:                { [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Read0[]] : 10 <= i0 <= 99; [Stmt_S2[i0] -> Stmt_S2_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Read0[]] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; [Stmt_S2[i0] -> Stmt_S2_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Read0[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Read0[]] : 10 <= i0 <= 99 }
 
 ;VALUE_ACCESS-NEXT:        WAR dependences:
 ;VALUE_ACCESS-NEXT:                {  }
 ;VALUE_ACCESS-NEXT:        WAW dependences:
-;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9 }
+;VALUE_ACCESS-NEXT:                { [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9 }
 ;
 ; VALUE-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'write_after_read':
 ; VALUE-NEXT:      RAW dependences:
@@ -48,7 +48,7 @@
 ;VALUE_ACCESS-NEXT:         RAW dependences:
 ;VALUE_ACCESS-NEXT:                 {  }
 ;VALUE_ACCESS-NEXT:         WAR dependences:
-;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Read0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Read0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 10 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99 }
+;VALUE_ACCESS-NEXT:                { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 10 <= i0 <= 99; [Stmt_S1[i0] -> Stmt_S1_Read0[]] -> [Stmt_S2[i0] -> Stmt_S2_Write0[]] : 0 <= i0 <= 9; [Stmt_S1[i0] -> Stmt_S1_Read0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 10 <= i0 <= 99 }
 ;VALUE_ACCESS-NEXT:         WAW dependences:
 ;VALUE_ACCESS-NEXT:                { Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; [Stmt_S2[i0] -> Stmt_S2_Write0[]] -> [Stmt_S3[i0] -> Stmt_S3_Write0[]] : 0 <= i0 <= 9 }
 ;
@@ -62,7 +62,7 @@
 ;
 ;VALUE_ACCESS-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.2' in function 'parametric_offset':
 ;VALUE_ACCESS-NEXT:        RAW dependences:
-;VALUE_ACCESS-NEXT:                [p] -> { [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[-p + i0] -> Stmt_S2_Read0[]] : i0 >= p and 0 <= i0 <= 99 and i0 <= 9 + p; Stmt_S1[i0] -> Stmt_S2[-p + i0] : i0 >= p and 0 <= i0 <= 99 and i0 <= 9 + p }
+;VALUE_ACCESS-NEXT:                [p] -> { Stmt_S1[i0] -> Stmt_S2[-p + i0] : i0 >= p and 0 <= i0 <= 99 and i0 <= 9 + p; [Stmt_S1[i0] -> Stmt_S1_Write0[]] -> [Stmt_S2[-p + i0] -> Stmt_S2_Read0[]] : i0 >= p and 0 <= i0 <= 99 and i0 <= 9 + p }
 ;VALUE_ACCESS-NEXT:        WAR dependences:
 ;VALUE_ACCESS-NEXT:                [p] -> {  }
 ;VALUE_ACCESS-NEXT:        WAW dependences:
@@ -74,7 +74,7 @@
 ; MEMORY-NEXT:      WAR dependences:
 ; MEMORY-NEXT:          {  }
 ; MEMORY-NEXT:      WAW dependences:
-; MEMORY-NEXT:          { Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9; Stmt_S1[i0] -> Stmt_S3[i0] : 0 <= i0 <= 99 }
+; MEMORY-NEXT:          { Stmt_S1[i0] -> Stmt_S3[i0] : 0 <= i0 <= 99; Stmt_S1[i0] -> Stmt_S2[i0] : 0 <= i0 <= 9; Stmt_S2[i0] -> Stmt_S3[i0] : 0 <= i0 <= 9 }
 ;
 ; MEMORY-LABEL: Printing analysis 'Polly - Calculate dependences' for region: 'S1 => exit.3' in function 'read_after_writes':
 ; MEMORY-NEXT:      RAW dependences:
diff --git a/test/GPGPU/managed-pointers-preparation.ll b/test/GPGPU/managed-pointers-preparation.ll
index 4a22e48..f0a8971 100644
--- a/test/GPGPU/managed-pointers-preparation.ll
+++ b/test/GPGPU/managed-pointers-preparation.ll
@@ -17,7 +17,7 @@
 ; CHECK-NOT: @polly_launchKernel
 
 
-; CODE:  if (p_0_loaded_from___data_runcontrol_MOD_lmulti_layer == 0) {
+; CODE:  if (p_0_loaded_from___data_runcontrol_MOD_lmulti_layer == 1) {
 ; CODE-NEXT:    {
 ; CODE-NEXT:      dim3 k0_dimBlock;
 ; CODE-NEXT:      dim3 k0_dimGrid;
diff --git a/test/GPGPU/non-zero-array-offset.ll b/test/GPGPU/non-zero-array-offset.ll
index dcab25e..9ad68ae 100644
--- a/test/GPGPU/non-zero-array-offset.ll
+++ b/test/GPGPU/non-zero-array-offset.ll
@@ -12,14 +12,14 @@
 
 ; CODE:          dim3 k0_dimBlock(8);
 ; CODE-NEXT:     dim3 k0_dimGrid(1);
-; CODE-NEXT:     kernel0 <<<k0_dimGrid, k0_dimBlock>>> (dev_MemRef_A);
+; CODE-NEXT:     kernel0 <<<k0_dimGrid, k0_dimBlock>>> (dev_MemRef_B);
 ; CODE-NEXT:     cudaCheckKernel();
 ; CODE-NEXT:   }
 
 ; CODE:        {
 ; CODE-NEXT:     dim3 k1_dimBlock(8);
 ; CODE-NEXT:     dim3 k1_dimGrid(1);
-; CODE-NEXT:     kernel1 <<<k1_dimGrid, k1_dimBlock>>> (dev_MemRef_B);
+; CODE-NEXT:     kernel1 <<<k1_dimGrid, k1_dimBlock>>> (dev_MemRef_A);
 ; CODE-NEXT:     cudaCheckKernel();
 ; CODE-NEXT:   }
 
@@ -27,10 +27,10 @@
 ; CODE-NEXT:   cudaCheckReturn(cudaMemcpy(MemRef_A, dev_MemRef_A, (8) * sizeof(float), cudaMemcpyDeviceToHost));
 
 ; CODE: # kernel0
-; CODE-NEXT: Stmt_bb11(t0);
+; CODE-NEXT: Stmt_bb3(t0);
 
 ; CODE: # kernel1
-; CODE-NEXT: Stmt_bb3(t0);
+; CODE-NEXT: Stmt_bb11(t0);
 
 ; IR:       %p_dev_array_MemRef_B = call i8* @polly_allocateMemoryForDevice(i64 32)
 ; IR-NEXT:  %p_dev_array_MemRef_A = call i8* @polly_allocateMemoryForDevice(i64 32)
diff --git a/test/Isl/Ast/alias_checks_with_empty_context.ll b/test/Isl/Ast/alias_checks_with_empty_context.ll
index a05309d..1ce365c 100644
--- a/test/Isl/Ast/alias_checks_with_empty_context.ll
+++ b/test/Isl/Ast/alias_checks_with_empty_context.ll
@@ -56,7 +56,7 @@
   br label %bb1
 }
 
-; CHECK: if (1 && (&MemRef_global_1[1] <= &MemRef_tmp3[0] || &MemRef_tmp3[1] <= &MemRef_global_1[0]) && (&MemRef_tmp[1] <= &MemRef_tmp3[0] || &MemRef_tmp3[1] <= &MemRef_tmp[0]) && (&MemRef_tmp[1] <= &MemRef_global_1[0] || &MemRef_global_1[1] <= &MemRef_tmp[0]))
+; CHECK: if (1 && (&MemRef_tmp3[1] <= &MemRef_global_1[0] || &MemRef_global_1[1] <= &MemRef_tmp3[0]) && (&MemRef_tmp[1] <= &MemRef_global_1[0] || &MemRef_global_1[1] <= &MemRef_tmp[0]) && (&MemRef_tmp[1] <= &MemRef_tmp3[0] || &MemRef_tmp3[1] <= &MemRef_tmp[0]))
 
 ; CHECK:            for (int c0 = 0; c0 <= 64; c0 += 1) {
 ; CHECK-NEXT:         Stmt_bb7(c0);
diff --git a/test/Isl/CodeGen/empty_domain_in_context.ll b/test/Isl/CodeGen/empty_domain_in_context.ll
index 57b583d..c4d250a 100644
--- a/test/Isl/CodeGen/empty_domain_in_context.ll
+++ b/test/Isl/CodeGen/empty_domain_in_context.ll
@@ -81,6 +81,6 @@
 ; It is not important since this code will never be executed.
 
 ; CHECK:      polly.stmt.lor.end.us.peel:
-; CHECK-NEXT:   %tmp_p_scalar_1 = load i8, i8* @b
-; CHECK-NEXT:   store i8 %tmp_p_scalar_1, i8* %tmp3.phiops
+; CHECK-NEXT:   %tmp_p_scalar_2 = load i8, i8* @b
+; CHECK-NEXT:   store i8 %tmp_p_scalar_2, i8* %tmp3.phiops
 ; CHECK-NEXT:   br label %polly.merge
diff --git a/test/ScheduleOptimizer/focaltech_test_detail_threshold-7bc17e.ll b/test/ScheduleOptimizer/focaltech_test_detail_threshold-7bc17e.ll
index 2668386..34cc41d 100644
--- a/test/ScheduleOptimizer/focaltech_test_detail_threshold-7bc17e.ll
+++ b/test/ScheduleOptimizer/focaltech_test_detail_threshold-7bc17e.ll
@@ -61,22 +61,22 @@
 
 ; CHECK-LABEL: Printing analysis 'Polly - Optimize schedule of SCoP' for region: 'for.cond => cleanup' in function 'func':
 ; CHECK: Calculated schedule:
-; CHECK: domain: "[call15] -> { Stmt_for_body23[i0, i1] : 0 <= i0 <= 59 and 0 <= i1 <= 59; Stmt_for_body30[i0, i1] : 0 <= i0 <= 59 and 0 <= i1 <= 59 }"
+; CHECK: domain: "[call15] -> { Stmt_for_body30[i0, i1] : 0 <= i0 <= 59 and 0 <= i1 <= 59; Stmt_for_body23[i0, i1] : 0 <= i0 <= 59 and 0 <= i1 <= 59 }"
 ; CHECK: child:
 ; CHECK:   mark: "1st level tiling - Tiles"
 ; CHECK:   child:
-; CHECK:     schedule: "[call15] -> [{ Stmt_for_body23[i0, i1] -> [(floor((i0 + i1)/32))]; Stmt_for_body30[i0, i1] -> [(floor((call15 + i1)/32))] }, { Stmt_for_body23[i0, i1] -> [(floor((i0)/32))]; Stmt_for_body30[i0, i1] -> [(floor((i0)/32))] }]"
+; CHECK:     schedule: "[call15] -> [{ Stmt_for_body30[i0, i1] -> [(floor((i1)/32))]; Stmt_for_body23[i0, i1] -> [(floor((i1)/32))] }, { Stmt_for_body30[i0, i1] -> [(floor((i0)/32))]; Stmt_for_body23[i0, i1] -> [(floor((i0)/32))] }]"
 ; CHECK:     permutable: 1
 ; CHECK:     coincident: [ 1, 0 ]
 ; CHECK:     child:
 ; CHECK:       mark: "1st level tiling - Points"
 ; CHECK:       child:
-; CHECK:         schedule: "[call15] -> [{ Stmt_for_body23[i0, i1] -> [(floor((i0 + i1)/4) - 8*floor((i0 + i1)/32))]; Stmt_for_body30[i0, i1] -> [(floor((call15 + i1)/4) - 8*floor((call15 + i1)/32))] }]"
+; CHECK:         schedule: "[call15] -> [{ Stmt_for_body30[i0, i1] -> [(floor((i1)/4) - 8*floor((i1)/32))]; Stmt_for_body23[i0, i1] -> [(floor((i1)/4) - 8*floor((i1)/32))] }]"
 ; CHECK:         permutable: 1
 ; CHECK:         coincident: [ 1 ]
-; CHECK:         options: "[call15] -> { atomic[0]; isolate{{\[\[}}i0, i1] -> [i2]] : 0 <= i1 <= 1 and 0 <= i2 <= 7 and call15 - 32i0 <= 4i2 <= 56 + call15 - 32i0 and (call15 >= 120 or i2 < -8i0 + 8i1); isolate{{\[\[}}i0, 0] -> [i2]] : 0 <= i2 <= 7 and ((call15 >= 120 and -8i0 <= i2 <= 21 - 8i0) or (call15 >= 92 and i2 <= 28 - 8i0 and 4i2 >= call15 - 32i0) or (call15 <= 91 and -8i0 <= i2 <= 21 - 8i0) or (92 <= call15 <= 119 and -8i0 <= i2 <= 21 - 8i0) or (call15 <= 91 and 22 - 8i0 <= i2 <= 28 - 8i0 and 4i2 <= 56 + call15 - 32i0) or (call15 <= 119 and i2 >= 29 - 8i0 and call15 - 32i0 <= 4i2 <= 56 + call15 - 32i0)); isolate{{\[\[}}i0, 1] -> [i2]] : i2 >= 0 and 8 - 8i0 <= i2 <= 7 and ((call15 >= 120 and i2 <= 28 - 8i0) or (call15 <= 119 and i2 >= 29 - 8i0 and 4i2 <= 56 + call15 - 32i0) or (call15 <= 119 and i2 <= 28 - 8i0)) }"
+; CHECK:         options: "[call15] -> { atomic[0]; isolate{{\[\[}}i0, i1] -> [i2]] : i0 >= 0 and 0 <= i1 <= 1 and 0 <= i2 <= 14 - 8i0 and i2 <= 7 }"
 ; CHECK:         child:
-; CHECK:           schedule: "[call15] -> [{ Stmt_for_body23[i0, i1] -> [((i0) mod 32)]; Stmt_for_body30[i0, i1] -> [((i0) mod 32)] }]"
+; CHECK:           schedule: "[call15] -> [{ Stmt_for_body30[i0, i1] -> [((i0) mod 32)]; Stmt_for_body23[i0, i1] -> [((i0) mod 32)] }]"
 ; CHECK:           permutable: 1
 ; CHECK:           child:
 ; CHECK:             mark: "SIMD"
@@ -84,11 +84,11 @@
 ; CHECK:               sequence:
 ; CHECK:               - filter: "[call15] -> { Stmt_for_body23[i0, i1] }"
 ; CHECK:                 child:
-; CHECK:                   schedule: "[call15] -> [{ Stmt_for_body23[i0, i1] -> [((i0 + i1) mod 4)]; Stmt_for_body30[i0, i1] -> [((call15 + i1) mod 4)] }]"
+; CHECK:                   schedule: "[call15] -> [{ Stmt_for_body30[i0, i1] -> [((i1) mod 4)]; Stmt_for_body23[i0, i1] -> [((i1) mod 4)] }]"
 ; CHECK:                   permutable: 1
 ; CHECK:                   coincident: [ 1 ]
 ; CHECK:               - filter: "[call15] -> { Stmt_for_body30[i0, i1] }"
 ; CHECK:                 child:
-; CHECK:                   schedule: "[call15] -> [{ Stmt_for_body23[i0, i1] -> [((i0 + i1) mod 4)]; Stmt_for_body30[i0, i1] -> [((call15 + i1) mod 4)] }]"
+; CHECK:                   schedule: "[call15] -> [{ Stmt_for_body30[i0, i1] -> [((i1) mod 4)]; Stmt_for_body23[i0, i1] -> [((i1) mod 4)] }]"
 ; CHECK:                   permutable: 1
 ; CHECK:                   coincident: [ 1 ]