+ isl_vec_free(ineq);
+ return -1;
+}
+
+/* Check whether the div described by "div" is obviously non-negative.
+ * If we are using a big parameter, then we will encode the div
+ * as div' = M + div, which is always non-negative.
+ * Otherwise, we check whether div is a non-negative affine combination
+ * of non-negative variables.
+ */
+static int div_is_nonneg(struct isl_tab *tab, __isl_keep isl_vec *div)
+{
+ int i;
+
+ if (tab->M)
+ return 1;
+
+ if (isl_int_is_neg(div->el[1]))
+ return 0;
+
+ for (i = 0; i < tab->n_var; ++i) {
+ if (isl_int_is_neg(div->el[2 + i]))
+ return 0;
+ if (isl_int_is_zero(div->el[2 + i]))
+ continue;
+ if (!tab->var[i].is_nonneg)
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Add an extra div, prescribed by "div" to the tableau and
+ * the associated bmap (which is assumed to be non-NULL).
+ *
+ * If add_ineq is not NULL, then this function is used instead
+ * of isl_tab_add_ineq to add the div constraints.
+ * This complication is needed because the code in isl_tab_pip
+ * wants to perform some extra processing when an inequality
+ * is added to the tableau.
+ */
+int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div,
+ int (*add_ineq)(void *user, isl_int *), void *user)
+{
+ int r;
+ int k;
+ int nonneg;
+
+ if (!tab || !div)
+ return -1;
+
+ isl_assert(tab->mat->ctx, tab->bmap, return -1);
+
+ nonneg = div_is_nonneg(tab, div);
+
+ if (isl_tab_extend_cons(tab, 3) < 0)
+ return -1;
+ if (isl_tab_extend_vars(tab, 1) < 0)
+ return -1;
+ r = isl_tab_allocate_var(tab);
+ if (r < 0)
+ return -1;
+
+ if (nonneg)
+ tab->var[r].is_nonneg = 1;
+
+ tab->bmap = isl_basic_map_extend_space(tab->bmap,
+ isl_basic_map_get_space(tab->bmap), 1, 0, 2);
+ k = isl_basic_map_alloc_div(tab->bmap);
+ if (k < 0)
+ return -1;
+ isl_seq_cpy(tab->bmap->div[k], div->el, div->size);
+ if (isl_tab_push(tab, isl_tab_undo_bmap_div) < 0)
+ return -1;
+
+ if (add_div_constraints(tab, k, add_ineq, user) < 0)
+ return -1;
+
+ return r;