Bug Summary

File:polly/lib/External/isl/isl_int_sioimath.h
Warning:line 973, column 17
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_val.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0=. -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-08-28-193554-24367-1 -x c /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c

/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c

1/*
2 * Copyright 2013 Ecole Normale Superieure
3 *
4 * Use of this software is governed by the MIT license
5 *
6 * Written by Sven Verdoolaege,
7 * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
8 */
9
10#include <isl_int.h>
11#include <isl_ctx_private.h>
12#include <isl_val_private.h>
13
14#undef EL_BASEval
15#define EL_BASEval val
16
17#include <isl_list_templ.c>
18#include <isl_list_read_templ.c>
19
20/* Allocate an isl_val object with indeterminate value.
21 */
22__isl_give isl_val *isl_val_alloc(isl_ctx *ctx)
23{
24 isl_val *v;
25
26 v = isl_alloc_type(ctx, struct isl_val)((struct isl_val *)isl_malloc_or_die(ctx, sizeof(struct isl_val
)))
;
27 if (!v)
28 return NULL((void*)0);
29
30 v->ctx = ctx;
31 isl_ctx_ref(ctx);
32 v->ref = 1;
33 isl_int_init(v->n)isl_sioimath_init((v->n));
34 isl_int_init(v->d)isl_sioimath_init((v->d));
35
36 return v;
37}
38
39/* Return a reference to an isl_val representing zero.
40 */
41__isl_give isl_val *isl_val_zero(isl_ctx *ctx)
42{
43 return isl_val_int_from_si(ctx, 0);
44}
45
46/* Return a reference to an isl_val representing one.
47 */
48__isl_give isl_val *isl_val_one(isl_ctx *ctx)
49{
50 return isl_val_int_from_si(ctx, 1);
51}
52
53/* Return a reference to an isl_val representing negative one.
54 */
55__isl_give isl_val *isl_val_negone(isl_ctx *ctx)
56{
57 return isl_val_int_from_si(ctx, -1);
58}
59
60/* Return a reference to an isl_val representing NaN.
61 */
62__isl_give isl_val *isl_val_nan(isl_ctx *ctx)
63{
64 isl_val *v;
65
66 v = isl_val_alloc(ctx);
67 if (!v)
68 return NULL((void*)0);
69
70 isl_int_set_si(v->n, 0)isl_sioimath_set_si((v->n), 0);
71 isl_int_set_si(v->d, 0)isl_sioimath_set_si((v->d), 0);
72
73 return v;
74}
75
76/* Change "v" into a NaN.
77 */
78__isl_give isl_val *isl_val_set_nan(__isl_take isl_val *v)
79{
80 if (!v)
81 return NULL((void*)0);
82 if (isl_val_is_nan(v))
83 return v;
84 v = isl_val_cow(v);
85 if (!v)
86 return NULL((void*)0);
87
88 isl_int_set_si(v->n, 0)isl_sioimath_set_si((v->n), 0);
89 isl_int_set_si(v->d, 0)isl_sioimath_set_si((v->d), 0);
90
91 return v;
92}
93
94/* Return a reference to an isl_val representing +infinity.
95 */
96__isl_give isl_val *isl_val_infty(isl_ctx *ctx)
97{
98 isl_val *v;
99
100 v = isl_val_alloc(ctx);
101 if (!v)
102 return NULL((void*)0);
103
104 isl_int_set_si(v->n, 1)isl_sioimath_set_si((v->n), 1);
105 isl_int_set_si(v->d, 0)isl_sioimath_set_si((v->d), 0);
106
107 return v;
108}
109
110/* Return a reference to an isl_val representing -infinity.
111 */
112__isl_give isl_val *isl_val_neginfty(isl_ctx *ctx)
113{
114 isl_val *v;
115
116 v = isl_val_alloc(ctx);
117 if (!v)
118 return NULL((void*)0);
119
120 isl_int_set_si(v->n, -1)isl_sioimath_set_si((v->n), -1);
121 isl_int_set_si(v->d, 0)isl_sioimath_set_si((v->d), 0);
122
123 return v;
124}
125
126/* Return a reference to an isl_val representing the integer "i".
127 */
128__isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, long i)
129{
130 isl_val *v;
131
132 v = isl_val_alloc(ctx);
133 if (!v)
134 return NULL((void*)0);
135
136 isl_int_set_si(v->n, i)isl_sioimath_set_si((v->n), i);
137 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
138
139 return v;
140}
141
142/* Change the value of "v" to be equal to the integer "i".
143 */
144__isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, long i)
145{
146 if (!v)
147 return NULL((void*)0);
148 if (isl_val_is_int(v) && isl_int_cmp_si(v->n, i)isl_sioimath_cmp_si(*(v->n), i) == 0)
149 return v;
150 v = isl_val_cow(v);
151 if (!v)
152 return NULL((void*)0);
153
154 isl_int_set_si(v->n, i)isl_sioimath_set_si((v->n), i);
155 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
156
157 return v;
158}
159
160/* Change the value of "v" to be equal to zero.
161 */
162__isl_give isl_val *isl_val_set_zero(__isl_take isl_val *v)
163{
164 return isl_val_set_si(v, 0);
165}
166
167/* Return a reference to an isl_val representing the unsigned integer "u".
168 */
169__isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, unsigned long u)
170{
171 isl_val *v;
172
173 v = isl_val_alloc(ctx);
174 if (!v)
175 return NULL((void*)0);
176
177 isl_int_set_ui(v->n, u)isl_sioimath_set_ui((v->n), u);
178 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
179
180 return v;
181}
182
183/* Return a reference to an isl_val representing the integer "n".
184 */
185__isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n)
186{
187 isl_val *v;
188
189 v = isl_val_alloc(ctx);
190 if (!v)
191 return NULL((void*)0);
192
193 isl_int_set(v->n, n)isl_sioimath_set((v->n), *(n));
194 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
195
196 return v;
197}
198
199/* Return a reference to an isl_val representing the rational value "n"/"d".
200 * Normalizing the isl_val (if needed) is left to the caller.
201 */
202__isl_give isl_val *isl_val_rat_from_isl_int(isl_ctx *ctx,
203 isl_int n, isl_int d)
204{
205 isl_val *v;
206
207 v = isl_val_alloc(ctx);
208 if (!v)
209 return NULL((void*)0);
210
211 isl_int_set(v->n, n)isl_sioimath_set((v->n), *(n));
212 isl_int_set(v->d, d)isl_sioimath_set((v->d), *(d));
213
214 return v;
215}
216
217/* Return a new reference to "v".
218 */
219__isl_give isl_val *isl_val_copy(__isl_keep isl_val *v)
220{
221 if (!v)
222 return NULL((void*)0);
223
224 v->ref++;
225 return v;
226}
227
228/* Return a fresh copy of "val".
229 */
230__isl_give isl_val *isl_val_dup(__isl_keep isl_val *val)
231{
232 isl_val *dup;
233
234 if (!val)
235 return NULL((void*)0);
236
237 dup = isl_val_alloc(isl_val_get_ctx(val));
238 if (!dup)
239 return NULL((void*)0);
240
241 isl_int_set(dup->n, val->n)isl_sioimath_set((dup->n), *(val->n));
242 isl_int_set(dup->d, val->d)isl_sioimath_set((dup->d), *(val->d));
243
244 return dup;
245}
246
247/* Return an isl_val that is equal to "val" and that has only
248 * a single reference.
249 */
250__isl_give isl_val *isl_val_cow(__isl_take isl_val *val)
251{
252 if (!val)
253 return NULL((void*)0);
254
255 if (val->ref == 1)
256 return val;
257 val->ref--;
258 return isl_val_dup(val);
259}
260
261/* Free "v" and return NULL.
262 */
263__isl_null isl_val *isl_val_free(__isl_take isl_val *v)
264{
265 if (!v)
266 return NULL((void*)0);
267
268 if (--v->ref > 0)
269 return NULL((void*)0);
270
271 isl_ctx_deref(v->ctx);
272 isl_int_clear(v->n)isl_sioimath_clear((v->n));
273 isl_int_clear(v->d)isl_sioimath_clear((v->d));
274 free(v);
275 return NULL((void*)0);
276}
277
278/* Extract the numerator of a rational value "v" as an integer.
279 *
280 * If "v" is not a rational value, then the result is undefined.
281 */
282long isl_val_get_num_si(__isl_keep isl_val *v)
283{
284 if (!v)
285 return 0;
286 if (!isl_val_is_rat(v))
287 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 288); return 0; } while (0)
288 "expecting rational value", return 0)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 288); return 0; } while (0)
;
289 if (!isl_int_fits_slong(v->n)isl_sioimath_fits_slong(*(v->n)))
290 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "numerator too large"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 291); return 0; } while (0)
291 "numerator too large", return 0)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "numerator too large"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 291); return 0; } while (0)
;
292 return isl_int_get_si(v->n)isl_sioimath_get_si(*(v->n));
293}
294
295/* Extract the numerator of a rational value "v" as an isl_int.
296 *
297 * If "v" is not a rational value, then the result is undefined.
298 */
299isl_stat isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n)
300{
301 if (!v)
302 return isl_stat_error;
303 if (!isl_val_is_rat(v))
304 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 305); return isl_stat_error; } while (0)
305 "expecting rational value", return isl_stat_error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 305); return isl_stat_error; } while (0)
;
306 isl_int_set(*n, v->n)isl_sioimath_set((*n), *(v->n));
307 return isl_stat_ok;
308}
309
310/* Extract the denominator of a rational value "v" as an integer.
311 *
312 * If "v" is not a rational value, then the result is undefined.
313 */
314long isl_val_get_den_si(__isl_keep isl_val *v)
315{
316 if (!v)
317 return 0;
318 if (!isl_val_is_rat(v))
319 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 320); return 0; } while (0)
320 "expecting rational value", return 0)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 320); return 0; } while (0)
;
321 if (!isl_int_fits_slong(v->d)isl_sioimath_fits_slong(*(v->d)))
322 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "denominator too large"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 323); return 0; } while (0)
323 "denominator too large", return 0)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "denominator too large"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 323); return 0; } while (0)
;
324 return isl_int_get_si(v->d)isl_sioimath_get_si(*(v->d));
325}
326
327/* Extract the denominator of a rational value "v" as an isl_val.
328 *
329 * If "v" is not a rational value, then the result is undefined.
330 */
331__isl_give isl_val *isl_val_get_den_val(__isl_keep isl_val *v)
332{
333 if (!v)
334 return NULL((void*)0);
335 if (!isl_val_is_rat(v))
336 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 337); return ((void*)0); } while (0)
337 "expecting rational value", return NULL)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 337); return ((void*)0); } while (0)
;
338 return isl_val_int_from_isl_int(isl_val_get_ctx(v), v->d);
339}
340
341/* Return an approximation of "v" as a double.
342 */
343double isl_val_get_d(__isl_keep isl_val *v)
344{
345 if (!v)
346 return 0;
347 if (!isl_val_is_rat(v))
348 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 349); return 0; } while (0)
349 "expecting rational value", return 0)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational value"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 349); return 0; } while (0)
;
350 return isl_int_get_d(v->n)isl_sioimath_get_d(*(v->n)) / isl_int_get_d(v->d)isl_sioimath_get_d(*(v->d));
351}
352
353/* Return the isl_ctx to which "val" belongs.
354 */
355isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val)
356{
357 return val ? val->ctx : NULL((void*)0);
358}
359
360/* Return a hash value that digests "val".
361 */
362uint32_t isl_val_get_hash(__isl_keep isl_val *val)
363{
364 uint32_t hash;
365
366 if (!val)
367 return 0;
368
369 hash = isl_hash_init()(2166136261u);
370 hash = isl_int_hash(val->n, hash)isl_sioimath_hash(*(val->n), hash);
371 hash = isl_int_hash(val->d, hash)isl_sioimath_hash(*(val->d), hash);
372
373 return hash;
374}
375
376/* Normalize "v".
377 *
378 * In particular, make sure that the denominator of a rational value
379 * is positive and the numerator and denominator do not have any
380 * common divisors.
381 *
382 * This function should not be called by an external user
383 * since it will only be given normalized values.
384 */
385__isl_give isl_val *isl_val_normalize(__isl_take isl_val *v)
386{
387 isl_ctx *ctx;
388
389 if (!v)
390 return NULL((void*)0);
391 if (isl_val_is_int(v))
392 return v;
393 if (!isl_val_is_rat(v))
394 return v;
395 if (isl_int_is_neg(v->d)(isl_sioimath_sgn(*(v->d)) < 0)) {
396 isl_int_neg(v->d, v->d)isl_sioimath_neg((v->d), *(v->d));
397 isl_int_neg(v->n, v->n)isl_sioimath_neg((v->n), *(v->n));
398 }
399 ctx = isl_val_get_ctx(v);
400 isl_int_gcd(ctx->normalize_gcd, v->n, v->d)isl_sioimath_gcd((ctx->normalize_gcd), *(v->n), *(v->
d))
;
401 if (isl_int_is_one(ctx->normalize_gcd)(isl_sioimath_cmp_si(*(ctx->normalize_gcd), 1) == 0))
402 return v;
403 isl_int_divexact(v->n, v->n, ctx->normalize_gcd)isl_sioimath_tdiv_q((v->n), *(v->n), *(ctx->normalize_gcd
))
;
404 isl_int_divexact(v->d, v->d, ctx->normalize_gcd)isl_sioimath_tdiv_q((v->d), *(v->d), *(ctx->normalize_gcd
))
;
405 return v;
406}
407
408/* Return the opposite of "v".
409 */
410__isl_give isl_val *isl_val_neg(__isl_take isl_val *v)
411{
412 if (!v)
413 return NULL((void*)0);
414 if (isl_val_is_nan(v))
415 return v;
416 if (isl_val_is_zero(v))
417 return v;
418
419 v = isl_val_cow(v);
420 if (!v)
421 return NULL((void*)0);
422 isl_int_neg(v->n, v->n)isl_sioimath_neg((v->n), *(v->n));
423
424 return v;
425}
426
427/* Return the inverse of "v".
428 */
429__isl_give isl_val *isl_val_inv(__isl_take isl_val *v)
430{
431 if (!v)
432 return NULL((void*)0);
433 if (isl_val_is_nan(v))
434 return v;
435 if (isl_val_is_zero(v)) {
436 isl_ctx *ctx = isl_val_get_ctx(v);
437 isl_val_free(v);
438 return isl_val_nan(ctx);
439 }
440 if (isl_val_is_infty(v) || isl_val_is_neginfty(v)) {
441 isl_ctx *ctx = isl_val_get_ctx(v);
442 isl_val_free(v);
443 return isl_val_zero(ctx);
444 }
445
446 v = isl_val_cow(v);
447 if (!v)
448 return NULL((void*)0);
449 isl_int_swap(v->n, v->d)isl_sioimath_swap((v->n), (v->d));
450
451 return isl_val_normalize(v);
452}
453
454/* Return the absolute value of "v".
455 */
456__isl_give isl_val *isl_val_abs(__isl_take isl_val *v)
457{
458 if (!v)
459 return NULL((void*)0);
460 if (isl_val_is_nan(v))
461 return v;
462 if (isl_val_is_nonneg(v))
463 return v;
464 return isl_val_neg(v);
465}
466
467/* Return the "floor" (greatest integer part) of "v".
468 * That is, return the result of rounding towards -infinity.
469 */
470__isl_give isl_val *isl_val_floor(__isl_take isl_val *v)
471{
472 if (!v)
1
Assuming 'v' is non-null
2
Taking false branch
473 return NULL((void*)0);
474 if (isl_val_is_int(v))
3
Assuming the condition is false
4
Taking false branch
475 return v;
476 if (!isl_val_is_rat(v))
5
Assuming the condition is false
6
Taking false branch
477 return v;
478
479 v = isl_val_cow(v);
480 if (!v
6.1
'v' is non-null
6.1
'v' is non-null
)
7
Taking false branch
481 return NULL((void*)0);
482 isl_int_fdiv_q(v->n, v->n, v->d)isl_sioimath_fdiv_q((v->n), *(v->n), *(v->d));
8
Calling 'isl_sioimath_fdiv_q'
483 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
484
485 return v;
486}
487
488/* Return the "ceiling" of "v".
489 * That is, return the result of rounding towards +infinity.
490 */
491__isl_give isl_val *isl_val_ceil(__isl_take isl_val *v)
492{
493 if (!v)
494 return NULL((void*)0);
495 if (isl_val_is_int(v))
496 return v;
497 if (!isl_val_is_rat(v))
498 return v;
499
500 v = isl_val_cow(v);
501 if (!v)
502 return NULL((void*)0);
503 isl_int_cdiv_q(v->n, v->n, v->d)isl_sioimath_cdiv_q((v->n), *(v->n), *(v->d));
504 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
505
506 return v;
507}
508
509/* Truncate "v".
510 * That is, return the result of rounding towards zero.
511 */
512__isl_give isl_val *isl_val_trunc(__isl_take isl_val *v)
513{
514 if (!v)
515 return NULL((void*)0);
516 if (isl_val_is_int(v))
517 return v;
518 if (!isl_val_is_rat(v))
519 return v;
520
521 v = isl_val_cow(v);
522 if (!v)
523 return NULL((void*)0);
524 isl_int_tdiv_q(v->n, v->n, v->d)isl_sioimath_tdiv_q((v->n), *(v->n), *(v->d));
525 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
526
527 return v;
528}
529
530/* Return 2^v, where v is an integer (that is not too large).
531 */
532__isl_give isl_val *isl_val_pow2(__isl_take isl_val *v)
533{
534 unsigned long exp;
535 int neg;
536
537 v = isl_val_cow(v);
538 if (!v)
539 return NULL((void*)0);
540 if (!isl_val_is_int(v))
541 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "can only compute integer powers"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 543); return isl_val_free(v); } while (0)
542 "can only compute integer powers",do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "can only compute integer powers"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 543); return isl_val_free(v); } while (0)
543 return isl_val_free(v))do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "can only compute integer powers"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 543); return isl_val_free(v); } while (0)
;
544 neg = isl_val_is_neg(v);
545 if (neg)
546 isl_int_neg(v->n, v->n)isl_sioimath_neg((v->n), *(v->n));
547 if (!isl_int_fits_ulong(v->n)isl_sioimath_fits_ulong(*(v->n)))
548 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "exponent too large"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 549); return isl_val_free(v); } while (0)
549 "exponent too large", return isl_val_free(v))do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "exponent too large"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 549); return isl_val_free(v); } while (0)
;
550 exp = isl_int_get_ui(v->n)isl_sioimath_get_ui(*(v->n));
551 if (neg) {
552 isl_int_mul_2exp(v->d, v->d, exp)isl_sioimath_mul_2exp((v->d), *(v->d), exp);
553 isl_int_set_si(v->n, 1)isl_sioimath_set_si((v->n), 1);
554 } else {
555 isl_int_mul_2exp(v->n, v->d, exp)isl_sioimath_mul_2exp((v->n), *(v->d), exp);
556 }
557
558 return v;
559}
560
561/* This is an alternative name for the function above.
562 */
563__isl_give isl_val *isl_val_2exp(__isl_take isl_val *v)
564{
565 return isl_val_pow2(v);
566}
567
568/* Return the minimum of "v1" and "v2".
569 */
570__isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2)
571{
572 if (!v1 || !v2)
573 goto error;
574
575 if (isl_val_is_nan(v1)) {
576 isl_val_free(v2);
577 return v1;
578 }
579 if (isl_val_is_nan(v2)) {
580 isl_val_free(v1);
581 return v2;
582 }
583 if (isl_val_le(v1, v2)) {
584 isl_val_free(v2);
585 return v1;
586 } else {
587 isl_val_free(v1);
588 return v2;
589 }
590error:
591 isl_val_free(v1);
592 isl_val_free(v2);
593 return NULL((void*)0);
594}
595
596/* Return the maximum of "v1" and "v2".
597 */
598__isl_give isl_val *isl_val_max(__isl_take isl_val *v1, __isl_take isl_val *v2)
599{
600 if (!v1 || !v2)
601 goto error;
602
603 if (isl_val_is_nan(v1)) {
604 isl_val_free(v2);
605 return v1;
606 }
607 if (isl_val_is_nan(v2)) {
608 isl_val_free(v1);
609 return v2;
610 }
611 if (isl_val_ge(v1, v2)) {
612 isl_val_free(v2);
613 return v1;
614 } else {
615 isl_val_free(v1);
616 return v2;
617 }
618error:
619 isl_val_free(v1);
620 isl_val_free(v2);
621 return NULL((void*)0);
622}
623
624/* Return the sum of "v1" and "v2".
625 */
626__isl_give isl_val *isl_val_add(__isl_take isl_val *v1, __isl_take isl_val *v2)
627{
628 if (!v1 || !v2)
629 goto error;
630 if (isl_val_is_nan(v1)) {
631 isl_val_free(v2);
632 return v1;
633 }
634 if (isl_val_is_nan(v2)) {
635 isl_val_free(v1);
636 return v2;
637 }
638 if ((isl_val_is_infty(v1) && isl_val_is_neginfty(v2)) ||
639 (isl_val_is_neginfty(v1) && isl_val_is_infty(v2))) {
640 isl_val_free(v2);
641 return isl_val_set_nan(v1);
642 }
643 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
644 isl_val_free(v2);
645 return v1;
646 }
647 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
648 isl_val_free(v1);
649 return v2;
650 }
651 if (isl_val_is_zero(v1)) {
652 isl_val_free(v1);
653 return v2;
654 }
655 if (isl_val_is_zero(v2)) {
656 isl_val_free(v2);
657 return v1;
658 }
659
660 v1 = isl_val_cow(v1);
661 if (!v1)
662 goto error;
663 if (isl_val_is_int(v1) && isl_val_is_int(v2))
664 isl_int_add(v1->n, v1->n, v2->n)isl_sioimath_add((v1->n), *(v1->n), *(v2->n));
665 else {
666 if (isl_int_eq(v1->d, v2->d)(isl_sioimath_cmp(*(v1->d), *(v2->d)) == 0))
667 isl_int_add(v1->n, v1->n, v2->n)isl_sioimath_add((v1->n), *(v1->n), *(v2->n));
668 else {
669 isl_int_mul(v1->n, v1->n, v2->d)isl_sioimath_mul((v1->n), *(v1->n), *(v2->d));
670 isl_int_addmul(v1->n, v2->n, v1->d)isl_sioimath_addmul((v1->n), *(v2->n), *(v1->d));
671 isl_int_mul(v1->d, v1->d, v2->d)isl_sioimath_mul((v1->d), *(v1->d), *(v2->d));
672 }
673 v1 = isl_val_normalize(v1);
674 }
675 isl_val_free(v2);
676 return v1;
677error:
678 isl_val_free(v1);
679 isl_val_free(v2);
680 return NULL((void*)0);
681}
682
683/* Return the sum of "v1" and "v2".
684 */
685__isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, unsigned long v2)
686{
687 if (!v1)
688 return NULL((void*)0);
689 if (!isl_val_is_rat(v1))
690 return v1;
691 if (v2 == 0)
692 return v1;
693 v1 = isl_val_cow(v1);
694 if (!v1)
695 return NULL((void*)0);
696
697 isl_int_addmul_ui(v1->n, v1->d, v2)isl_sioimath_addmul_ui((v1->n), *(v1->d), v2);
698
699 return v1;
700}
701
702/* Subtract "v2" from "v1".
703 */
704__isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, __isl_take isl_val *v2)
705{
706 if (!v1 || !v2)
707 goto error;
708 if (isl_val_is_nan(v1)) {
709 isl_val_free(v2);
710 return v1;
711 }
712 if (isl_val_is_nan(v2)) {
713 isl_val_free(v1);
714 return v2;
715 }
716 if ((isl_val_is_infty(v1) && isl_val_is_infty(v2)) ||
717 (isl_val_is_neginfty(v1) && isl_val_is_neginfty(v2))) {
718 isl_val_free(v2);
719 return isl_val_set_nan(v1);
720 }
721 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
722 isl_val_free(v2);
723 return v1;
724 }
725 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
726 isl_val_free(v1);
727 return isl_val_neg(v2);
728 }
729 if (isl_val_is_zero(v2)) {
730 isl_val_free(v2);
731 return v1;
732 }
733 if (isl_val_is_zero(v1)) {
734 isl_val_free(v1);
735 return isl_val_neg(v2);
736 }
737
738 v1 = isl_val_cow(v1);
739 if (!v1)
740 goto error;
741 if (isl_val_is_int(v1) && isl_val_is_int(v2))
742 isl_int_sub(v1->n, v1->n, v2->n)isl_sioimath_sub((v1->n), *(v1->n), *(v2->n));
743 else {
744 if (isl_int_eq(v1->d, v2->d)(isl_sioimath_cmp(*(v1->d), *(v2->d)) == 0))
745 isl_int_sub(v1->n, v1->n, v2->n)isl_sioimath_sub((v1->n), *(v1->n), *(v2->n));
746 else {
747 isl_int_mul(v1->n, v1->n, v2->d)isl_sioimath_mul((v1->n), *(v1->n), *(v2->d));
748 isl_int_submul(v1->n, v2->n, v1->d)isl_sioimath_submul((v1->n), *(v2->n), *(v1->d));
749 isl_int_mul(v1->d, v1->d, v2->d)isl_sioimath_mul((v1->d), *(v1->d), *(v2->d));
750 }
751 v1 = isl_val_normalize(v1);
752 }
753 isl_val_free(v2);
754 return v1;
755error:
756 isl_val_free(v1);
757 isl_val_free(v2);
758 return NULL((void*)0);
759}
760
761/* Subtract "v2" from "v1".
762 */
763__isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, unsigned long v2)
764{
765 if (!v1)
766 return NULL((void*)0);
767 if (!isl_val_is_rat(v1))
768 return v1;
769 if (v2 == 0)
770 return v1;
771 v1 = isl_val_cow(v1);
772 if (!v1)
773 return NULL((void*)0);
774
775 isl_int_submul_ui(v1->n, v1->d, v2)isl_sioimath_submul_ui((v1->n), *(v1->d), v2);
776
777 return v1;
778}
779
780/* Return the product of "v1" and "v2".
781 */
782__isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, __isl_take isl_val *v2)
783{
784 if (!v1 || !v2)
785 goto error;
786 if (isl_val_is_nan(v1)) {
787 isl_val_free(v2);
788 return v1;
789 }
790 if (isl_val_is_nan(v2)) {
791 isl_val_free(v1);
792 return v2;
793 }
794 if ((!isl_val_is_rat(v1) && isl_val_is_zero(v2)) ||
795 (isl_val_is_zero(v1) && !isl_val_is_rat(v2))) {
796 isl_val_free(v2);
797 return isl_val_set_nan(v1);
798 }
799 if (isl_val_is_zero(v1)) {
800 isl_val_free(v2);
801 return v1;
802 }
803 if (isl_val_is_zero(v2)) {
804 isl_val_free(v1);
805 return v2;
806 }
807 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
808 if (isl_val_is_neg(v2))
809 v1 = isl_val_neg(v1);
810 isl_val_free(v2);
811 return v1;
812 }
813 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
814 if (isl_val_is_neg(v1))
815 v2 = isl_val_neg(v2);
816 isl_val_free(v1);
817 return v2;
818 }
819
820 v1 = isl_val_cow(v1);
821 if (!v1)
822 goto error;
823 if (isl_val_is_int(v1) && isl_val_is_int(v2))
824 isl_int_mul(v1->n, v1->n, v2->n)isl_sioimath_mul((v1->n), *(v1->n), *(v2->n));
825 else {
826 isl_int_mul(v1->n, v1->n, v2->n)isl_sioimath_mul((v1->n), *(v1->n), *(v2->n));
827 isl_int_mul(v1->d, v1->d, v2->d)isl_sioimath_mul((v1->d), *(v1->d), *(v2->d));
828 v1 = isl_val_normalize(v1);
829 }
830 isl_val_free(v2);
831 return v1;
832error:
833 isl_val_free(v1);
834 isl_val_free(v2);
835 return NULL((void*)0);
836}
837
838/* Return the product of "v1" and "v2".
839 *
840 * This is a private copy of isl_val_mul for use in the generic
841 * isl_multi_*_scale_val instantiated for isl_val.
842 */
843__isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1,
844 __isl_take isl_val *v2)
845{
846 return isl_val_mul(v1, v2);
847}
848
849/* Return the product of "v1" and "v2".
850 */
851__isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, unsigned long v2)
852{
853 if (!v1)
854 return NULL((void*)0);
855 if (isl_val_is_nan(v1))
856 return v1;
857 if (!isl_val_is_rat(v1)) {
858 if (v2 == 0)
859 v1 = isl_val_set_nan(v1);
860 return v1;
861 }
862 if (v2 == 1)
863 return v1;
864 v1 = isl_val_cow(v1);
865 if (!v1)
866 return NULL((void*)0);
867
868 isl_int_mul_ui(v1->n, v1->n, v2)isl_sioimath_mul_ui((v1->n), *(v1->n), v2);
869
870 return isl_val_normalize(v1);
871}
872
873/* Divide "v1" by "v2".
874 */
875__isl_give isl_val *isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2)
876{
877 if (!v1 || !v2)
878 goto error;
879 if (isl_val_is_nan(v1)) {
880 isl_val_free(v2);
881 return v1;
882 }
883 if (isl_val_is_nan(v2)) {
884 isl_val_free(v1);
885 return v2;
886 }
887 if (isl_val_is_zero(v2) ||
888 (!isl_val_is_rat(v1) && !isl_val_is_rat(v2))) {
889 isl_val_free(v2);
890 return isl_val_set_nan(v1);
891 }
892 if (isl_val_is_zero(v1)) {
893 isl_val_free(v2);
894 return v1;
895 }
896 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
897 if (isl_val_is_neg(v2))
898 v1 = isl_val_neg(v1);
899 isl_val_free(v2);
900 return v1;
901 }
902 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
903 isl_val_free(v2);
904 return isl_val_set_zero(v1);
905 }
906
907 v1 = isl_val_cow(v1);
908 if (!v1)
909 goto error;
910 if (isl_val_is_int(v2)) {
911 isl_int_mul(v1->d, v1->d, v2->n)isl_sioimath_mul((v1->d), *(v1->d), *(v2->n));
912 v1 = isl_val_normalize(v1);
913 } else {
914 isl_int_mul(v1->d, v1->d, v2->n)isl_sioimath_mul((v1->d), *(v1->d), *(v2->n));
915 isl_int_mul(v1->n, v1->n, v2->d)isl_sioimath_mul((v1->n), *(v1->n), *(v2->d));
916 v1 = isl_val_normalize(v1);
917 }
918 isl_val_free(v2);
919 return v1;
920error:
921 isl_val_free(v1);
922 isl_val_free(v2);
923 return NULL((void*)0);
924}
925
926/* Divide "v1" by "v2".
927 */
928__isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, unsigned long v2)
929{
930 if (!v1)
931 return NULL((void*)0);
932 if (isl_val_is_nan(v1))
933 return v1;
934 if (v2 == 0)
935 return isl_val_set_nan(v1);
936 if (v2 == 1)
937 return v1;
938 if (isl_val_is_zero(v1))
939 return v1;
940 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1))
941 return v1;
942 v1 = isl_val_cow(v1);
943 if (!v1)
944 return NULL((void*)0);
945
946 isl_int_mul_ui(v1->d, v1->d, v2)isl_sioimath_mul_ui((v1->d), *(v1->d), v2);
947
948 return isl_val_normalize(v1);
949}
950
951/* Divide "v1" by "v2".
952 *
953 * This is a private copy of isl_val_div for use in the generic
954 * isl_multi_*_scale_down_val instantiated for isl_val.
955 */
956__isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1,
957 __isl_take isl_val *v2)
958{
959 return isl_val_div(v1, v2);
960}
961
962/* Given two integer values "v1" and "v2", check if "v1" is divisible by "v2".
963 */
964isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
965{
966 if (!v1 || !v2)
967 return isl_bool_error;
968
969 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
970 isl_die(isl_val_get_ctx(v1), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v1), isl_error_invalid,
"expecting two integers", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 971); return isl_bool_error; } while (0)
971 "expecting two integers", return isl_bool_error)do { isl_handle_error(isl_val_get_ctx(v1), isl_error_invalid,
"expecting two integers", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 971); return isl_bool_error; } while (0)
;
972
973 return isl_bool_ok(isl_int_is_divisible_by(v1->n, v2->n)isl_sioimath_is_divisible_by(*(v1->n), *(v2->n)));
974}
975
976/* Given two integer values "v1" and "v2", return the residue of "v1"
977 * modulo "v2".
978 */
979__isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2)
980{
981 if (!v1 || !v2)
982 goto error;
983 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
984 isl_die(isl_val_get_ctx(v1), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v1), isl_error_invalid,
"expecting two integers", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 985); goto error; } while (0)
985 "expecting two integers", goto error)do { isl_handle_error(isl_val_get_ctx(v1), isl_error_invalid,
"expecting two integers", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 985); goto error; } while (0)
;
986 if (isl_val_is_nonneg(v1) && isl_val_lt(v1, v2)) {
987 isl_val_free(v2);
988 return v1;
989 }
990 v1 = isl_val_cow(v1);
991 if (!v1)
992 goto error;
993 isl_int_fdiv_r(v1->n, v1->n, v2->n)isl_sioimath_fdiv_r((v1->n), *(v1->n), *(v2->n));
994 isl_val_free(v2);
995 return v1;
996error:
997 isl_val_free(v1);
998 isl_val_free(v2);
999 return NULL((void*)0);
1000}
1001
1002/* Given two integer values "v1" and "v2", return the residue of "v1"
1003 * modulo "v2".
1004 *
1005 * This is a private copy of isl_val_mod for use in the generic
1006 * isl_multi_*_mod_multi_val instantiated for isl_val.
1007 */
1008__isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1,
1009 __isl_take isl_val *v2)
1010{
1011 return isl_val_mod(v1, v2);
1012}
1013
1014/* Given two integer values, return their greatest common divisor.
1015 */
1016__isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2)
1017{
1018 if (!v1 || !v2)
1019 goto error;
1020 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
1021 isl_die(isl_val_get_ctx(v1), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v1), isl_error_invalid,
"expecting two integers", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 1022); goto error; } while (0)
1022 "expecting two integers", goto error)do { isl_handle_error(isl_val_get_ctx(v1), isl_error_invalid,
"expecting two integers", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 1022); goto error; } while (0)
;
1023 if (isl_val_eq(v1, v2)) {
1024 isl_val_free(v2);
1025 return v1;
1026 }
1027 if (isl_val_is_one(v1)) {
1028 isl_val_free(v2);
1029 return v1;
1030 }
1031 if (isl_val_is_one(v2)) {
1032 isl_val_free(v1);
1033 return v2;
1034 }
1035 v1 = isl_val_cow(v1);
1036 if (!v1)
1037 goto error;
1038 isl_int_gcd(v1->n, v1->n, v2->n)isl_sioimath_gcd((v1->n), *(v1->n), *(v2->n));
1039 isl_val_free(v2);
1040 return v1;
1041error:
1042 isl_val_free(v1);
1043 isl_val_free(v2);
1044 return NULL((void*)0);
1045}
1046
1047/* Compute x, y and g such that g = gcd(a,b) and a*x+b*y = g.
1048 */
1049static void isl_int_gcdext(isl_int *g, isl_int *x, isl_int *y,
1050 isl_int a, isl_int b)
1051{
1052 isl_int d, tmp;
1053 isl_int a_copy, b_copy;
1054
1055 isl_int_init(a_copy)isl_sioimath_init((a_copy));
1056 isl_int_init(b_copy)isl_sioimath_init((b_copy));
1057 isl_int_init(d)isl_sioimath_init((d));
1058 isl_int_init(tmp)isl_sioimath_init((tmp));
1059 isl_int_set(a_copy, a)isl_sioimath_set((a_copy), *(a));
1060 isl_int_set(b_copy, b)isl_sioimath_set((b_copy), *(b));
1061 isl_int_abs(*g, a_copy)isl_sioimath_abs((*g), *(a_copy));
1062 isl_int_abs(d, b_copy)isl_sioimath_abs((d), *(b_copy));
1063 isl_int_set_si(*x, 1)isl_sioimath_set_si((*x), 1);
1064 isl_int_set_si(*y, 0)isl_sioimath_set_si((*y), 0);
1065 while (isl_int_is_pos(d)(isl_sioimath_sgn(*(d)) > 0)) {
1066 isl_int_fdiv_q(tmp, *g, d)isl_sioimath_fdiv_q((tmp), *(*g), *(d));
1067 isl_int_submul(*x, tmp, *y)isl_sioimath_submul((*x), *(tmp), *(*y));
1068 isl_int_submul(*g, tmp, d)isl_sioimath_submul((*g), *(tmp), *(d));
1069 isl_int_swap(*g, d)isl_sioimath_swap((*g), (d));
1070 isl_int_swap(*x, *y)isl_sioimath_swap((*x), (*y));
1071 }
1072 if (isl_int_is_zero(a_copy)(isl_sioimath_sgn(*(a_copy)) == 0))
1073 isl_int_set_si(*x, 0)isl_sioimath_set_si((*x), 0);
1074 else if (isl_int_is_neg(a_copy)(isl_sioimath_sgn(*(a_copy)) < 0))
1075 isl_int_neg(*x, *x)isl_sioimath_neg((*x), *(*x));
1076 if (isl_int_is_zero(b_copy)(isl_sioimath_sgn(*(b_copy)) == 0))
1077 isl_int_set_si(*y, 0)isl_sioimath_set_si((*y), 0);
1078 else {
1079 isl_int_mul(tmp, a_copy, *x)isl_sioimath_mul((tmp), *(a_copy), *(*x));
1080 isl_int_sub(tmp, *g, tmp)isl_sioimath_sub((tmp), *(*g), *(tmp));
1081 isl_int_divexact(*y, tmp, b_copy)isl_sioimath_tdiv_q((*y), *(tmp), *(b_copy));
1082 }
1083 isl_int_clear(d)isl_sioimath_clear((d));
1084 isl_int_clear(tmp)isl_sioimath_clear((tmp));
1085 isl_int_clear(a_copy)isl_sioimath_clear((a_copy));
1086 isl_int_clear(b_copy)isl_sioimath_clear((b_copy));
1087}
1088
1089/* Given two integer values v1 and v2, return their greatest common divisor g,
1090 * as well as two integers x and y such that x * v1 + y * v2 = g.
1091 */
1092__isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1,
1093 __isl_take isl_val *v2, __isl_give isl_val **x, __isl_give isl_val **y)
1094{
1095 isl_ctx *ctx;
1096 isl_val *a = NULL((void*)0), *b = NULL((void*)0);
1097
1098 if (!x && !y)
1099 return isl_val_gcd(v1, v2);
1100
1101 if (!v1 || !v2)
1102 goto error;
1103
1104 ctx = isl_val_get_ctx(v1);
1105 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
1106 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "expecting two integers"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 1107); goto error; } while (0)
1107 "expecting two integers", goto error)do { isl_handle_error(ctx, isl_error_invalid, "expecting two integers"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_val.c"
, 1107); goto error; } while (0)
;
1108
1109 v1 = isl_val_cow(v1);
1110 a = isl_val_alloc(ctx);
1111 b = isl_val_alloc(ctx);
1112 if (!v1 || !a || !b)
1113 goto error;
1114 isl_int_gcdext(&v1->n, &a->n, &b->n, v1->n, v2->n);
1115 if (x) {
1116 isl_int_set_si(a->d, 1)isl_sioimath_set_si((a->d), 1);
1117 *x = a;
1118 } else
1119 isl_val_free(a);
1120 if (y) {
1121 isl_int_set_si(b->d, 1)isl_sioimath_set_si((b->d), 1);
1122 *y = b;
1123 } else
1124 isl_val_free(b);
1125 isl_val_free(v2);
1126 return v1;
1127error:
1128 isl_val_free(v1);
1129 isl_val_free(v2);
1130 isl_val_free(a);
1131 isl_val_free(b);
1132 if (x)
1133 *x = NULL((void*)0);
1134 if (y)
1135 *y = NULL((void*)0);
1136 return NULL((void*)0);
1137}
1138
1139/* Does "v" represent an integer value?
1140 */
1141isl_bool isl_val_is_int(__isl_keep isl_val *v)
1142{
1143 if (!v)
1144 return isl_bool_error;
1145
1146 return isl_bool_ok(isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0));
1147}
1148
1149/* Does "v" represent a rational value?
1150 */
1151isl_bool isl_val_is_rat(__isl_keep isl_val *v)
1152{
1153 if (!v)
1154 return isl_bool_error;
1155
1156 return isl_bool_ok(!isl_int_is_zero(v->d)(isl_sioimath_sgn(*(v->d)) == 0));
1157}
1158
1159/* Does "v" represent NaN?
1160 */
1161isl_bool isl_val_is_nan(__isl_keep isl_val *v)
1162{
1163 if (!v)
1164 return isl_bool_error;
1165
1166 return isl_bool_ok(isl_int_is_zero(v->n)(isl_sioimath_sgn(*(v->n)) == 0) && isl_int_is_zero(v->d)(isl_sioimath_sgn(*(v->d)) == 0));
1167}
1168
1169/* Does "v" represent +infinity?
1170 */
1171isl_bool isl_val_is_infty(__isl_keep isl_val *v)
1172{
1173 if (!v)
1174 return isl_bool_error;
1175
1176 return isl_bool_ok(isl_int_is_pos(v->n)(isl_sioimath_sgn(*(v->n)) > 0) && isl_int_is_zero(v->d)(isl_sioimath_sgn(*(v->d)) == 0));
1177}
1178
1179/* Does "v" represent -infinity?
1180 */
1181isl_bool isl_val_is_neginfty(__isl_keep isl_val *v)
1182{
1183 if (!v)
1184 return isl_bool_error;
1185
1186 return isl_bool_ok(isl_int_is_neg(v->n)(isl_sioimath_sgn(*(v->n)) < 0) && isl_int_is_zero(v->d)(isl_sioimath_sgn(*(v->d)) == 0));
1187}
1188
1189/* Does "v" represent the integer zero?
1190 */
1191isl_bool isl_val_is_zero(__isl_keep isl_val *v)
1192{
1193 if (!v)
1194 return isl_bool_error;
1195
1196 return isl_bool_ok(isl_int_is_zero(v->n)(isl_sioimath_sgn(*(v->n)) == 0) && !isl_int_is_zero(v->d)(isl_sioimath_sgn(*(v->d)) == 0));
1197}
1198
1199/* Does "v" represent the integer one?
1200 */
1201isl_bool isl_val_is_one(__isl_keep isl_val *v)
1202{
1203 if (!v)
1204 return isl_bool_error;
1205
1206 if (isl_val_is_nan(v))
1207 return isl_bool_false;
1208
1209 return isl_bool_ok(isl_int_eq(v->n, v->d)(isl_sioimath_cmp(*(v->n), *(v->d)) == 0));
1210}
1211
1212/* Does "v" represent the integer negative one?
1213 */
1214isl_bool isl_val_is_negone(__isl_keep isl_val *v)
1215{
1216 if (!v)
1217 return isl_bool_error;
1218
1219 return isl_bool_ok(isl_int_is_neg(v->n)(isl_sioimath_sgn(*(v->n)) < 0) && isl_int_abs_eq(v->n, v->d)(isl_sioimath_abs_cmp(*(v->n), *(v->d)) == 0));
1220}
1221
1222/* Is "v" (strictly) positive?
1223 */
1224isl_bool isl_val_is_pos(__isl_keep isl_val *v)
1225{
1226 if (!v)
1227 return isl_bool_error;
1228
1229 return isl_bool_ok(isl_int_is_pos(v->n)(isl_sioimath_sgn(*(v->n)) > 0));
1230}
1231
1232/* Is "v" (strictly) negative?
1233 */
1234isl_bool isl_val_is_neg(__isl_keep isl_val *v)
1235{
1236 if (!v)
1237 return isl_bool_error;
1238
1239 return isl_bool_ok(isl_int_is_neg(v->n)(isl_sioimath_sgn(*(v->n)) < 0));
1240}
1241
1242/* Is "v" non-negative?
1243 */
1244isl_bool isl_val_is_nonneg(__isl_keep isl_val *v)
1245{
1246 if (!v)
1247 return isl_bool_error;
1248
1249 if (isl_val_is_nan(v))
1250 return isl_bool_false;
1251
1252 return isl_bool_ok(isl_int_is_nonneg(v->n)(isl_sioimath_sgn(*(v->n)) >= 0));
1253}
1254
1255/* Is "v" non-positive?
1256 */
1257isl_bool isl_val_is_nonpos(__isl_keep isl_val *v)
1258{
1259 if (!v)
1260 return isl_bool_error;
1261
1262 if (isl_val_is_nan(v))
1263 return isl_bool_false;
1264
1265 return isl_bool_ok(isl_int_is_nonpos(v->n)(isl_sioimath_sgn(*(v->n)) <= 0));
1266}
1267
1268/* Return the sign of "v".
1269 *
1270 * The sign of NaN is undefined.
1271 */
1272int isl_val_sgn(__isl_keep isl_val *v)
1273{
1274 if (!v)
1275 return 0;
1276 if (isl_val_is_zero(v))
1277 return 0;
1278 if (isl_val_is_pos(v))
1279 return 1;
1280 return -1;
1281}
1282
1283/* Is "v1" (strictly) less than "v2"?
1284 */
1285isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1286{
1287 isl_int t;
1288 isl_bool lt;
1289
1290 if (!v1 || !v2)
1291 return isl_bool_error;
1292 if (isl_val_is_int(v1) && isl_val_is_int(v2))
1293 return isl_bool_ok(isl_int_lt(v1->n, v2->n)(isl_sioimath_cmp(*(v1->n), *(v2->n)) < 0));
1294 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1295 return isl_bool_false;
1296 if (isl_val_eq(v1, v2))
1297 return isl_bool_false;
1298 if (isl_val_is_infty(v2))
1299 return isl_bool_true;
1300 if (isl_val_is_infty(v1))
1301 return isl_bool_false;
1302 if (isl_val_is_neginfty(v1))
1303 return isl_bool_true;
1304 if (isl_val_is_neginfty(v2))
1305 return isl_bool_false;
1306
1307 isl_int_init(t)isl_sioimath_init((t));
1308 isl_int_mul(t, v1->n, v2->d)isl_sioimath_mul((t), *(v1->n), *(v2->d));
1309 isl_int_submul(t, v2->n, v1->d)isl_sioimath_submul((t), *(v2->n), *(v1->d));
1310 lt = isl_bool_ok(isl_int_is_neg(t)(isl_sioimath_sgn(*(t)) < 0));
1311 isl_int_clear(t)isl_sioimath_clear((t));
1312
1313 return lt;
1314}
1315
1316/* Is "v1" (strictly) greater than "v2"?
1317 */
1318isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1319{
1320 return isl_val_lt(v2, v1);
1321}
1322
1323/* Is "v" (strictly) greater than "i"?
1324 */
1325isl_bool isl_val_gt_si(__isl_keep isl_val *v, long i)
1326{
1327 isl_val *vi;
1328 isl_bool res;
1329
1330 if (!v)
1331 return isl_bool_error;
1332 if (isl_val_is_int(v))
1333 return isl_bool_ok(isl_int_cmp_si(v->n, i)isl_sioimath_cmp_si(*(v->n), i) > 0);
1334 if (isl_val_is_nan(v))
1335 return isl_bool_false;
1336 if (isl_val_is_infty(v))
1337 return isl_bool_true;
1338 if (isl_val_is_neginfty(v))
1339 return isl_bool_false;
1340
1341 vi = isl_val_int_from_si(isl_val_get_ctx(v), i);
1342 res = isl_bool_ok(isl_val_gt(v, vi));
1343 isl_val_free(vi);
1344
1345 return res;
1346}
1347
1348/* Is "v1" less than or equal to "v2"?
1349 */
1350isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1351{
1352 isl_int t;
1353 isl_bool le;
1354
1355 if (!v1 || !v2)
1356 return isl_bool_error;
1357 if (isl_val_is_int(v1) && isl_val_is_int(v2))
1358 return isl_bool_ok(isl_int_le(v1->n, v2->n)(isl_sioimath_cmp(*(v1->n), *(v2->n)) <= 0));
1359 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1360 return isl_bool_false;
1361 if (isl_val_eq(v1, v2))
1362 return isl_bool_true;
1363 if (isl_val_is_infty(v2))
1364 return isl_bool_true;
1365 if (isl_val_is_infty(v1))
1366 return isl_bool_false;
1367 if (isl_val_is_neginfty(v1))
1368 return isl_bool_true;
1369 if (isl_val_is_neginfty(v2))
1370 return isl_bool_false;
1371
1372 isl_int_init(t)isl_sioimath_init((t));
1373 isl_int_mul(t, v1->n, v2->d)isl_sioimath_mul((t), *(v1->n), *(v2->d));
1374 isl_int_submul(t, v2->n, v1->d)isl_sioimath_submul((t), *(v2->n), *(v1->d));
1375 le = isl_bool_ok(isl_int_is_nonpos(t)(isl_sioimath_sgn(*(t)) <= 0));
1376 isl_int_clear(t)isl_sioimath_clear((t));
1377
1378 return le;
1379}
1380
1381/* Is "v1" greater than or equal to "v2"?
1382 */
1383isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1384{
1385 return isl_val_le(v2, v1);
1386}
1387
1388/* How does "v" compare to "i"?
1389 *
1390 * Return 1 if v is greater, -1 if v is smaller and 0 if v is equal to i.
1391 *
1392 * If v is NaN (or NULL), then the result is undefined.
1393 */
1394int isl_val_cmp_si(__isl_keep isl_val *v, long i)
1395{
1396 isl_int t;
1397 int cmp;
1398
1399 if (!v)
1400 return 0;
1401 if (isl_val_is_int(v))
1402 return isl_int_cmp_si(v->n, i)isl_sioimath_cmp_si(*(v->n), i);
1403 if (isl_val_is_nan(v))
1404 return 0;
1405 if (isl_val_is_infty(v))
1406 return 1;
1407 if (isl_val_is_neginfty(v))
1408 return -1;
1409
1410 isl_int_init(t)isl_sioimath_init((t));
1411 isl_int_mul_si(t, v->d, i)isl_sioimath_mul_si((t), *(v->d), i);
1412 isl_int_sub(t, v->n, t)isl_sioimath_sub((t), *(v->n), *(t));
1413 cmp = isl_int_sgn(t)isl_sioimath_sgn(*(t));
1414 isl_int_clear(t)isl_sioimath_clear((t));
1415
1416 return cmp;
1417}
1418
1419/* Is "v1" equal to "v2"?
1420 */
1421isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1422{
1423 if (!v1 || !v2)
1424 return isl_bool_error;
1425 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1426 return isl_bool_false;
1427
1428 return isl_bool_ok(isl_int_eq(v1->n, v2->n)(isl_sioimath_cmp(*(v1->n), *(v2->n)) == 0) &&
1429 isl_int_eq(v1->d, v2->d)(isl_sioimath_cmp(*(v1->d), *(v2->d)) == 0));
1430}
1431
1432/* Is "v" equal to "i"?
1433 */
1434isl_bool isl_val_eq_si(__isl_keep isl_val *v, long i)
1435{
1436 if (!v)
1437 return isl_bool_error;
1438 if (!isl_val_is_int(v))
1439 return isl_bool_false;
1440 return isl_bool_ok(isl_int_cmp_si(v->n, i)isl_sioimath_cmp_si(*(v->n), i) == 0);
1441}
1442
1443/* Is "v1" equal to "v2" in absolute value?
1444 */
1445isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1446{
1447 if (!v1 || !v2)
1448 return isl_bool_error;
1449 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1450 return isl_bool_false;
1451
1452 return isl_bool_ok(isl_int_abs_eq(v1->n, v2->n)(isl_sioimath_abs_cmp(*(v1->n), *(v2->n)) == 0) &&
1453 isl_int_eq(v1->d, v2->d)(isl_sioimath_cmp(*(v1->d), *(v2->d)) == 0));
1454}
1455
1456/* Is "v1" different from "v2"?
1457 */
1458isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1459{
1460 if (!v1 || !v2)
1461 return isl_bool_error;
1462 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1463 return isl_bool_false;
1464
1465 return isl_bool_ok(isl_int_ne(v1->n, v2->n)(isl_sioimath_cmp(*(v1->n), *(v2->n)) != 0) ||
1466 isl_int_ne(v1->d, v2->d)(isl_sioimath_cmp(*(v1->d), *(v2->d)) != 0));
1467}
1468
1469/* Print a textual representation of "v" onto "p".
1470 */
1471__isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p,
1472 __isl_keep isl_val *v)
1473{
1474 int neg;
1475
1476 if (!p || !v)
1477 return isl_printer_free(p);
1478
1479 neg = isl_int_is_neg(v->n)(isl_sioimath_sgn(*(v->n)) < 0);
1480 if (neg) {
1481 p = isl_printer_print_str(p, "-");
1482 isl_int_neg(v->n, v->n)isl_sioimath_neg((v->n), *(v->n));
1483 }
1484 if (isl_int_is_zero(v->d)(isl_sioimath_sgn(*(v->d)) == 0)) {
1485 int sgn = isl_int_sgn(v->n)isl_sioimath_sgn(*(v->n));
1486 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1487 sgn == 0 ? "NaN" : "infty");
1488 } else
1489 p = isl_printer_print_isl_int(p, v->n);
1490 if (neg)
1491 isl_int_neg(v->n, v->n)isl_sioimath_neg((v->n), *(v->n));
1492 if (!isl_int_is_zero(v->d)(isl_sioimath_sgn(*(v->d)) == 0) && !isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) {
1493 p = isl_printer_print_str(p, "/");
1494 p = isl_printer_print_isl_int(p, v->d);
1495 }
1496
1497 return p;
1498}
1499
1500/* Is "val1" (obviously) equal to "val2"?
1501 *
1502 * This is a private copy of isl_val_eq for use in the generic
1503 * isl_multi_*_plain_is_equal instantiated for isl_val.
1504 */
1505isl_bool isl_val_plain_is_equal(__isl_keep isl_val *val1,
1506 __isl_keep isl_val *val2)
1507{
1508 return isl_val_eq(val1, val2);
1509}
1510
1511/* Does "v" have any non-zero coefficients
1512 * for any dimension in the given range?
1513 *
1514 * This function is only meant to be used in the generic isl_multi_*
1515 * functions which have to deal with base objects that have an associated
1516 * space. Since an isl_val does not have any coefficients, this function
1517 * always returns isl_bool_false.
1518 */
1519isl_bool isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type,
1520 unsigned first, unsigned n)
1521{
1522 if (!v)
1523 return isl_bool_error;
1524
1525 return isl_bool_false;
1526}
1527
1528/* Insert "n" dimensions of type "type" at position "first".
1529 *
1530 * This function is only meant to be used in the generic isl_multi_*
1531 * functions which have to deal with base objects that have an associated
1532 * space. Since an isl_val does not have an associated space, this function
1533 * does not do anything.
1534 */
1535__isl_give isl_val *isl_val_insert_dims(__isl_take isl_val *v,
1536 enum isl_dim_type type, unsigned first, unsigned n)
1537{
1538 return v;
1539}
1540
1541/* Change the name of the dimension of type "type" at position "pos" to "s".
1542 *
1543 * This function is only meant to be used in the generic isl_multi_*
1544 * functions which have to deal with base objects that have an associated
1545 * space. Since an isl_val does not have an associated space, this function
1546 * does not do anything.
1547 */
1548__isl_give isl_val *isl_val_set_dim_name(__isl_take isl_val *v,
1549 enum isl_dim_type type, unsigned pos, const char *s)
1550{
1551 return v;
1552}
1553
1554/* Return an isl_val that is zero on "ls".
1555 *
1556 * This function is only meant to be used in the generic isl_multi_*
1557 * functions which have to deal with base objects that have an associated
1558 * space. Since an isl_val does not have an associated space, this function
1559 * simply returns a zero isl_val in the same context as "ls".
1560 */
1561__isl_give isl_val *isl_val_zero_on_domain(__isl_take isl_local_space *ls)
1562{
1563 isl_ctx *ctx;
1564
1565 if (!ls)
1566 return NULL((void*)0);
1567 ctx = isl_local_space_get_ctx(ls);
1568 isl_local_space_free(ls);
1569 return isl_val_zero(ctx);
1570}
1571
1572#define isl_val_involves_nanisl_val_is_nan isl_val_is_nan
1573
1574#undef BASEval
1575#define BASEval val
1576
1577#include <isl_multi_no_domain_templ.c>
1578#include <isl_multi_no_explicit_domain.c>
1579#include <isl_multi_templ.c>
1580#include <isl_multi_arith_templ.c>
1581#include <isl_multi_dim_id_templ.c>
1582#include <isl_multi_dims.c>
1583#include <isl_multi_min_max_templ.c>
1584#include <isl_multi_nan_templ.c>
1585#include <isl_multi_product_templ.c>
1586#include <isl_multi_splice_templ.c>
1587#include <isl_multi_tuple_id_templ.c>
1588#include <isl_multi_zero_templ.c>
1589
1590/* Does "mv" consist of only zeros?
1591 */
1592isl_bool isl_multi_val_is_zero(__isl_keep isl_multi_val *mv)
1593{
1594 return isl_multi_val_every(mv, &isl_val_is_zero);
1595}
1596
1597/* Apply "fn" to each of the elements of "mv" with as second argument "v".
1598 */
1599static __isl_give isl_multi_val *isl_multi_val_fn_val(
1600 __isl_take isl_multi_val *mv,
1601 __isl_give isl_val *(*fn)(__isl_take isl_val *v1,
1602 __isl_take isl_val *v2),
1603 __isl_take isl_val *v)
1604{
1605 int i;
1606
1607 mv = isl_multi_val_cow(mv);
1608 if (!mv || !v)
1609 goto error;
1610
1611 for (i = 0; i < mv->n; ++i) {
1612 mv->u.p[i] = fn(mv->u.p[i], isl_val_copy(v));
1613 if (!mv->u.p[i])
1614 goto error;
1615 }
1616
1617 isl_val_free(v);
1618 return mv;
1619error:
1620 isl_val_free(v);
1621 isl_multi_val_free(mv);
1622 return NULL((void*)0);
1623}
1624
1625/* Add "v" to each of the elements of "mv".
1626 */
1627__isl_give isl_multi_val *isl_multi_val_add_val(__isl_take isl_multi_val *mv,
1628 __isl_take isl_val *v)
1629{
1630 if (!v)
1631 return isl_multi_val_free(mv);
1632 if (isl_val_is_zero(v)) {
1633 isl_val_free(v);
1634 return mv;
1635 }
1636 return isl_multi_val_fn_val(mv, &isl_val_add, v);
1637}
1638
1639/* Reduce the elements of "mv" modulo "v".
1640 */
1641__isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv,
1642 __isl_take isl_val *v)
1643{
1644 return isl_multi_val_fn_val(mv, &isl_val_mod, v);
1645}

/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_int_sioimath.h

1/*
2 * Copyright 2015 INRIA Paris-Rocquencourt
3 *
4 * Use of this software is governed by the MIT license
5 *
6 * Written by Michael Kruse, INRIA Paris-Rocquencourt,
7 * Domaine de Voluceau, Rocquenqourt, B.P. 105,
8 * 78153 Le Chesnay Cedex France
9 */
10#ifndef ISL_INT_SIOIMATH_H
11#define ISL_INT_SIOIMATH_H
12
13#include <inttypes.h>
14#include <limits.h>
15#include <stdint.h>
16#include <stdlib.h>
17
18#include <isl_imath.h>
19#include <isl/hash.h>
20
21#define ARRAY_SIZE(array)(sizeof(array)/sizeof(*array)) (sizeof(array)/sizeof(*array))
22
23/* Visual Studio before VS2015 does not support the inline keyword when
24 * compiling in C mode because it was introduced in C99 which it does not
25 * officially support. Instead, it has a proprietary extension using __inline.
26 */
27#if defined(_MSC_VER) && (_MSC_VER < 1900)
28#define inline __inline
29#endif
30
31/* The type to represent integers optimized for small values. It is either a
32 * pointer to an mp_int ( = mpz_t*; big representation) or an int32_t (small
33 * represenation) with a discriminator at the least significant bit. In big
34 * representation it will be always zero because of heap alignment. It is set
35 * to 1 for small representation and use the 32 most significant bits for the
36 * int32_t.
37 *
38 * Structure on 64 bit machines, with 8-byte aligment (3 bits):
39 *
40 * Big representation:
41 * MSB LSB
42 * |------------------------------------------------------------000
43 * | mpz_t* |
44 * | != NULL |
45 *
46 * Small representation:
47 * MSB 32 LSB
48 * |------------------------------|00000000000000000000000000000001
49 * | int32_t |
50 * | 2147483647 ... -2147483647 |
51 * ^
52 * |
53 * discriminator bit
54 *
55 * On 32 bit machines isl_sioimath type is blown up to 8 bytes, i.e.
56 * isl_sioimath is guaranteed to be at least 8 bytes. This is to ensure the
57 * int32_t can be hidden in that type without data loss. In the future we might
58 * optimize this to use 31 hidden bits in a 32 bit pointer. We may also use 63
59 * bits on 64 bit machines, but this comes with the cost of additional overflow
60 * checks because there is no standardized 128 bit integer we could expand to.
61 *
62 * We use native integer types and avoid union structures to avoid assumptions
63 * on the machine's endianness.
64 *
65 * This implementation makes the following assumptions:
66 * - long can represent any int32_t
67 * - mp_small is signed long
68 * - mp_usmall is unsigned long
69 * - adresses returned by malloc are aligned to 2-byte boundaries (leastmost
70 * bit is zero)
71 */
72#if UINT64_MAX(18446744073709551615UL) > UINTPTR_MAX(18446744073709551615UL)
73typedef uint64_t isl_sioimath;
74#else
75typedef uintptr_t isl_sioimath;
76#endif
77
78/* The negation of the smallest possible number in int32_t, INT32_MIN
79 * (0x80000000u, -2147483648), cannot be represented in an int32_t, therefore
80 * every operation that may produce this value needs to special-case it.
81 * The operations are:
82 * abs(INT32_MIN)
83 * -INT32_MIN (negation)
84 * -1 * INT32_MIN (multiplication)
85 * INT32_MIN/-1 (any division: divexact, fdiv, cdiv, tdiv)
86 * To avoid checking these cases, we exclude INT32_MIN from small
87 * representation.
88 */
89#define ISL_SIOIMATH_SMALL_MIN(-(2147483647)) (-INT32_MAX(2147483647))
90
91/* Largest possible number in small representation */
92#define ISL_SIOIMATH_SMALL_MAX(2147483647) INT32_MAX(2147483647)
93
94/* Used for function parameters the function modifies. */
95typedef isl_sioimath *isl_sioimath_ptr;
96
97/* Used for function parameters that are read-only. */
98typedef isl_sioimath isl_sioimath_src;
99
100/* Return whether the argument is stored in small representation.
101 */
102inline int isl_sioimath_is_small(isl_sioimath val)
103{
104 return val & 0x00000001;
16
Returning the value 1, which participates in a condition later
105}
106
107/* Return whether the argument is stored in big representation.
108 */
109inline int isl_sioimath_is_big(isl_sioimath val)
110{
111 return !isl_sioimath_is_small(val);
112}
113
114/* Get the number of an isl_int in small representation. Result is undefined if
115 * val is not stored in that format.
116 */
117inline int32_t isl_sioimath_get_small(isl_sioimath val)
118{
119 return val >> 32;
12
Returning zero
120}
121
122/* Get the number of an in isl_int in big representation. Result is undefined if
123 * val is not stored in that format.
124 */
125inline mp_int isl_sioimath_get_big(isl_sioimath val)
126{
127 return (mp_int)(uintptr_t) val;
128}
129
130/* Return 1 if val is stored in small representation and store its value to
131 * small. We rely on the compiler to optimize the isl_sioimath_get_small such
132 * that the shift is moved into the branch that executes in case of small
133 * representation. If there is no such branch, then a single shift is still
134 * cheaper than introducing branching code.
135 */
136inline int isl_sioimath_decode_small(isl_sioimath val, int32_t *small)
137{
138 *small = isl_sioimath_get_small(val);
11
Calling 'isl_sioimath_get_small'
13
Returning from 'isl_sioimath_get_small'
14
The value 0 is assigned to 'rhssmall'
139 return isl_sioimath_is_small(val);
15
Calling 'isl_sioimath_is_small'
17
Returning from 'isl_sioimath_is_small'
18
Returning the value 1, which participates in a condition later
140}
141
142/* Return 1 if val is stored in big representation and store its value to big.
143 */
144inline int isl_sioimath_decode_big(isl_sioimath val, mp_int *big)
145{
146 *big = isl_sioimath_get_big(val);
147 return isl_sioimath_is_big(val);
148}
149
150/* Encode a small representation into an isl_int.
151 */
152inline isl_sioimath isl_sioimath_encode_small(int32_t val)
153{
154 return ((isl_sioimath) val) << 32 | 0x00000001;
155}
156
157/* Encode a big representation.
158 */
159inline isl_sioimath isl_sioimath_encode_big(mp_int val)
160{
161 return (isl_sioimath)(uintptr_t) val;
162}
163
164/* A common situation is to call an IMath function with at least one argument
165 * that is currently in small representation or an integer parameter, i.e. a big
166 * representation of the same number is required. Promoting the original
167 * argument comes with multiple problems, such as modifying a read-only
168 * argument, the responsibility of deallocation and the execution cost. Instead,
169 * we make a copy by 'faking' the IMath internal structure.
170 *
171 * We reserve the maximum number of required digits on the stack to avoid heap
172 * allocations.
173 *
174 * mp_digit can be uint32_t or uint16_t. This code must work for little and big
175 * endian digits. The structure for an uint64_t argument and 32-bit mp_digits is
176 * sketched below.
177 *
178 * |----------------------------|
179 * uint64_t
180 *
181 * |-------------||-------------|
182 * mp_digit mp_digit
183 * digits[1] digits[0]
184 * Most sig digit Least sig digit
185 */
186typedef struct {
187 mpz_t big;
188 mp_digit digits[(sizeof(uintmax_t) + sizeof(mp_digit) - 1) /
189 sizeof(mp_digit)];
190} isl_sioimath_scratchspace_t;
191
192/* Convert a native integer to IMath's digit representation. A native integer
193 * might be big- or little endian, but IMath always stores the least significant
194 * digit in the lowest array indices. memcpy therefore is not possible.
195 *
196 * We also have to consider that long and mp_digit can be of different sizes,
197 * depending on the compiler (LP64, LLP64) and IMath's USE_64BIT_WORDS. This
198 * macro should work for all of them.
199 *
200 * "used" is set to the number of written digits. It must be minimal (IMath
201 * checks zeroness using the used field), but always at least one. Also note
202 * that the result of num>>(sizeof(num)*CHAR_BIT) is undefined.
203 */
204#define ISL_SIOIMATH_TO_DIGITS(num, digits, used)do { int i = 0; do { (digits)[i] = ((num) >> (sizeof(mp_digit
) * 8 * i)); i += 1; if (i >= (sizeof(num) + sizeof(mp_digit
) - 1) / sizeof(mp_digit)) break; if (((num) >> (sizeof
(mp_digit) * 8 * i)) == 0) break; } while (1); (used) = i; } while
(0)
\
205 do { \
206 int i = 0; \
207 do { \
208 (digits)[i] = \
209 ((num) >> (sizeof(mp_digit) * CHAR_BIT8 * i)); \
210 i += 1; \
211 if (i >= (sizeof(num) + sizeof(mp_digit) - 1) / \
212 sizeof(mp_digit)) \
213 break; \
214 if (((num) >> (sizeof(mp_digit) * CHAR_BIT8 * i)) == 0) \
215 break; \
216 } while (1); \
217 (used) = i; \
218 } while (0)
219
220inline void isl_siomath_uint32_to_digits(uint32_t num, mp_digit *digits,
221 mp_size *used)
222{
223 ISL_SIOIMATH_TO_DIGITS(num, digits, *used)do { int i = 0; do { (digits)[i] = ((num) >> (sizeof(mp_digit
) * 8 * i)); i += 1; if (i >= (sizeof(num) + sizeof(mp_digit
) - 1) / sizeof(mp_digit)) break; if (((num) >> (sizeof
(mp_digit) * 8 * i)) == 0) break; } while (1); (*used) = i; }
while (0)
;
224}
225
226inline void isl_siomath_ulong_to_digits(unsigned long num, mp_digit *digits,
227 mp_size *used)
228{
229 ISL_SIOIMATH_TO_DIGITS(num, digits, *used)do { int i = 0; do { (digits)[i] = ((num) >> (sizeof(mp_digit
) * 8 * i)); i += 1; if (i >= (sizeof(num) + sizeof(mp_digit
) - 1) / sizeof(mp_digit)) break; if (((num) >> (sizeof
(mp_digit) * 8 * i)) == 0) break; } while (1); (*used) = i; }
while (0)
;
230}
231
232inline void isl_siomath_uint64_to_digits(uint64_t num, mp_digit *digits,
233 mp_size *used)
234{
235 ISL_SIOIMATH_TO_DIGITS(num, digits, *used)do { int i = 0; do { (digits)[i] = ((num) >> (sizeof(mp_digit
) * 8 * i)); i += 1; if (i >= (sizeof(num) + sizeof(mp_digit
) - 1) / sizeof(mp_digit)) break; if (((num) >> (sizeof
(mp_digit) * 8 * i)) == 0) break; } while (1); (*used) = i; }
while (0)
;
236}
237
238/* Get the IMath representation of an isl_int without modifying it.
239 * For the case it is not in big representation yet, pass some scratch space we
240 * can use to store the big representation in.
241 * In order to avoid requiring init and free on the scratch space, we directly
242 * modify the internal representation.
243 *
244 * The name derives from its indented use: getting the big representation of an
245 * input (src) argument.
246 */
247inline mp_int isl_sioimath_bigarg_src(isl_sioimath arg,
248 isl_sioimath_scratchspace_t *scratch)
249{
250 mp_int big;
251 int32_t small;
252 uint32_t num;
253
254 if (isl_sioimath_decode_big(arg, &big))
255 return big;
256
257 small = isl_sioimath_get_small(arg);
258 scratch->big.digits = scratch->digits;
259 scratch->big.alloc = ARRAY_SIZE(scratch->digits)(sizeof(scratch->digits)/sizeof(*scratch->digits));
260 if (small >= 0) {
261 scratch->big.sign = MP_ZPOS;
262 num = small;
263 } else {
264 scratch->big.sign = MP_NEG;
265 num = -small;
266 }
267
268 isl_siomath_uint32_to_digits(num, scratch->digits, &scratch->big.used);
269 return &scratch->big;
270}
271
272/* Create a temporary IMath mp_int for a signed long.
273 */
274inline mp_int isl_sioimath_siarg_src(signed long arg,
275 isl_sioimath_scratchspace_t *scratch)
276{
277 unsigned long num;
278
279 scratch->big.digits = scratch->digits;
280 scratch->big.alloc = ARRAY_SIZE(scratch->digits)(sizeof(scratch->digits)/sizeof(*scratch->digits));
281 if (arg >= 0) {
282 scratch->big.sign = MP_ZPOS;
283 num = arg;
284 } else {
285 scratch->big.sign = MP_NEG;
286 num = (arg == LONG_MIN(-9223372036854775807L -1L)) ? ((unsigned long) LONG_MAX9223372036854775807L) + 1 : -arg;
287 }
288
289 isl_siomath_ulong_to_digits(num, scratch->digits, &scratch->big.used);
290 return &scratch->big;
291}
292
293/* Create a temporary IMath mp_int for an int64_t.
294 */
295inline mp_int isl_sioimath_si64arg_src(int64_t arg,
296 isl_sioimath_scratchspace_t *scratch)
297{
298 uint64_t num;
299
300 scratch->big.digits = scratch->digits;
301 scratch->big.alloc = ARRAY_SIZE(scratch->digits)(sizeof(scratch->digits)/sizeof(*scratch->digits));
302 if (arg >= 0) {
303 scratch->big.sign = MP_ZPOS;
304 num = arg;
305 } else {
306 scratch->big.sign = MP_NEG;
307 num = (arg == INT64_MIN(-9223372036854775807L -1)) ? ((uint64_t) INT64_MAX(9223372036854775807L)) + 1 : -arg;
308 }
309
310 isl_siomath_uint64_to_digits(num, scratch->digits, &scratch->big.used);
311 return &scratch->big;
312}
313
314/* Create a temporary IMath mp_int for an unsigned long.
315 */
316inline mp_int isl_sioimath_uiarg_src(unsigned long arg,
317 isl_sioimath_scratchspace_t *scratch)
318{
319 scratch->big.digits = scratch->digits;
320 scratch->big.alloc = ARRAY_SIZE(scratch->digits)(sizeof(scratch->digits)/sizeof(*scratch->digits));
321 scratch->big.sign = MP_ZPOS;
322
323 isl_siomath_ulong_to_digits(arg, scratch->digits, &scratch->big.used);
324 return &scratch->big;
325}
326
327/* Ensure big representation. Does not preserve the current number.
328 * Callers may use the fact that the value _is_ preserved if the presentation
329 * was big before.
330 */
331inline mp_int isl_sioimath_reinit_big(isl_sioimath_ptr ptr)
332{
333 if (isl_sioimath_is_small(*ptr))
334 *ptr = isl_sioimath_encode_big(mp_int_alloc());
335 return isl_sioimath_get_big(*ptr);
336}
337
338/* Set ptr to a number in small representation.
339 */
340inline void isl_sioimath_set_small(isl_sioimath_ptr ptr, int32_t val)
341{
342 if (isl_sioimath_is_big(*ptr))
343 mp_int_free(isl_sioimath_get_big(*ptr));
344 *ptr = isl_sioimath_encode_small(val);
345}
346
347/* Set ptr to val, choosing small representation if possible.
348 */
349inline void isl_sioimath_set_int32(isl_sioimath_ptr ptr, int32_t val)
350{
351 if (ISL_SIOIMATH_SMALL_MIN(-(2147483647)) <= val && val <= ISL_SIOIMATH_SMALL_MAX(2147483647)) {
352 isl_sioimath_set_small(ptr, val);
353 return;
354 }
355
356 mp_int_init_value(isl_sioimath_reinit_big(ptr), val);
357}
358
359/* Assign an int64_t number using small representation if possible.
360 */
361inline void isl_sioimath_set_int64(isl_sioimath_ptr ptr, int64_t val)
362{
363 if (ISL_SIOIMATH_SMALL_MIN(-(2147483647)) <= val && val <= ISL_SIOIMATH_SMALL_MAX(2147483647)) {
364 isl_sioimath_set_small(ptr, val);
365 return;
366 }
367
368 isl_sioimath_scratchspace_t scratch;
369 mp_int_copy(isl_sioimath_si64arg_src(val, &scratch),
370 isl_sioimath_reinit_big(ptr));
371}
372
373/* Convert to big representation while preserving the current number.
374 */
375inline void isl_sioimath_promote(isl_sioimath_ptr dst)
376{
377 int32_t small;
378
379 if (isl_sioimath_is_big(*dst))
380 return;
381
382 small = isl_sioimath_get_small(*dst);
383 mp_int_set_value(isl_sioimath_reinit_big(dst), small);
384}
385
386/* Convert to small representation while preserving the current number. Does
387 * nothing if dst doesn't fit small representation.
388 */
389inline void isl_sioimath_try_demote(isl_sioimath_ptr dst)
390{
391 mp_small small;
392
393 if (isl_sioimath_is_small(*dst))
394 return;
395
396 if (mp_int_to_int(isl_sioimath_get_big(*dst), &small) != MP_OK)
397 return;
398
399 if (ISL_SIOIMATH_SMALL_MIN(-(2147483647)) <= small && small <= ISL_SIOIMATH_SMALL_MAX(2147483647))
400 isl_sioimath_set_small(dst, small);
401}
402
403/* Initialize an isl_int. The implicit value is 0 in small representation.
404 */
405inline void isl_sioimath_init(isl_sioimath_ptr dst)
406{
407 *dst = isl_sioimath_encode_small(0);
408}
409
410/* Free the resources taken by an isl_int.
411 */
412inline void isl_sioimath_clear(isl_sioimath_ptr dst)
413{
414 if (isl_sioimath_is_small(*dst))
415 return;
416
417 mp_int_free(isl_sioimath_get_big(*dst));
418}
419
420/* Copy the value of one isl_int to another.
421 */
422inline void isl_sioimath_set(isl_sioimath_ptr dst, isl_sioimath_src val)
423{
424 if (isl_sioimath_is_small(val)) {
425 isl_sioimath_set_small(dst, isl_sioimath_get_small(val));
426 return;
427 }
428
429 mp_int_copy(isl_sioimath_get_big(val), isl_sioimath_reinit_big(dst));
430}
431
432/* Store a signed long into an isl_int.
433 */
434inline void isl_sioimath_set_si(isl_sioimath_ptr dst, long val)
435{
436 if (ISL_SIOIMATH_SMALL_MIN(-(2147483647)) <= val && val <= ISL_SIOIMATH_SMALL_MAX(2147483647)) {
437 isl_sioimath_set_small(dst, val);
438 return;
439 }
440
441 mp_int_set_value(isl_sioimath_reinit_big(dst), val);
442}
443
444/* Store an unsigned long into an isl_int.
445 */
446inline void isl_sioimath_set_ui(isl_sioimath_ptr dst, unsigned long val)
447{
448 if (val <= ISL_SIOIMATH_SMALL_MAX(2147483647)) {
449 isl_sioimath_set_small(dst, val);
450 return;
451 }
452
453 mp_int_set_uvalue(isl_sioimath_reinit_big(dst), val);
454}
455
456/* Return whether a number can be represented by a signed long.
457 */
458inline int isl_sioimath_fits_slong(isl_sioimath_src val)
459{
460 mp_small dummy;
461
462 if (isl_sioimath_is_small(val))
463 return 1;
464
465 return mp_int_to_int(isl_sioimath_get_big(val), &dummy) == MP_OK;
466}
467
468/* Return a number as signed long. Result is undefined if the number cannot be
469 * represented as long.
470 */
471inline long isl_sioimath_get_si(isl_sioimath_src val)
472{
473 mp_small result;
474
475 if (isl_sioimath_is_small(val))
476 return isl_sioimath_get_small(val);
477
478 mp_int_to_int(isl_sioimath_get_big(val), &result);
479 return result;
480}
481
482/* Return whether a number can be represented as unsigned long.
483 */
484inline int isl_sioimath_fits_ulong(isl_sioimath_src val)
485{
486 mp_usmall dummy;
487
488 if (isl_sioimath_is_small(val))
489 return isl_sioimath_get_small(val) >= 0;
490
491 return mp_int_to_uint(isl_sioimath_get_big(val), &dummy) == MP_OK;
492}
493
494/* Return a number as unsigned long. Result is undefined if the number cannot be
495 * represented as unsigned long.
496 */
497inline unsigned long isl_sioimath_get_ui(isl_sioimath_src val)
498{
499 mp_usmall result;
500
501 if (isl_sioimath_is_small(val))
502 return isl_sioimath_get_small(val);
503
504 mp_int_to_uint(isl_sioimath_get_big(val), &result);
505 return result;
506}
507
508/* Return a number as floating point value.
509 */
510inline double isl_sioimath_get_d(isl_sioimath_src val)
511{
512 mp_int big;
513 double result = 0;
514 int i;
515
516 if (isl_sioimath_is_small(val))
517 return isl_sioimath_get_small(val);
518
519 big = isl_sioimath_get_big(val);
520 for (i = 0; i < big->used; ++i)
521 result = result * (double) ((uintmax_t) MP_DIGIT_MAX((4294967295U) * 1UL) + 1) +
522 (double) big->digits[i];
523
524 if (big->sign == MP_NEG)
525 result = -result;
526
527 return result;
528}
529
530/* Format a number as decimal string.
531 *
532 * The largest possible string from small representation is 12 characters
533 * ("-2147483647").
534 */
535inline char *isl_sioimath_get_str(isl_sioimath_src val)
536{
537 char *result;
538
539 if (isl_sioimath_is_small(val)) {
540 result = malloc(12);
541 snprintf(result, 12, "%" PRIi32"i", isl_sioimath_get_small(val));
542 return result;
543 }
544
545 return impz_get_str(NULL((void*)0), 10, isl_sioimath_get_big(val));
546}
547
548/* Return the absolute value.
549 */
550inline void isl_sioimath_abs(isl_sioimath_ptr dst, isl_sioimath_src arg)
551{
552 if (isl_sioimath_is_small(arg)) {
553 isl_sioimath_set_small(dst, labs(isl_sioimath_get_small(arg)));
554 return;
555 }
556
557 mp_int_abs(isl_sioimath_get_big(arg), isl_sioimath_reinit_big(dst));
558}
559
560/* Return the negation of a number.
561 */
562inline void isl_sioimath_neg(isl_sioimath_ptr dst, isl_sioimath_src arg)
563{
564 if (isl_sioimath_is_small(arg)) {
565 isl_sioimath_set_small(dst, -isl_sioimath_get_small(arg));
566 return;
567 }
568
569 mp_int_neg(isl_sioimath_get_big(arg), isl_sioimath_reinit_big(dst));
570}
571
572/* Swap two isl_ints.
573 *
574 * isl_sioimath can be copied bytewise; nothing depends on its address. It can
575 * also be stored in a CPU register.
576 */
577inline void isl_sioimath_swap(isl_sioimath_ptr lhs, isl_sioimath_ptr rhs)
578{
579 isl_sioimath tmp = *lhs;
580 *lhs = *rhs;
581 *rhs = tmp;
582}
583
584/* Add an unsigned long to the number.
585 *
586 * On LP64 unsigned long exceeds the range of an int64_t, therefore we check in
587 * advance whether small representation possibly overflows.
588 */
589inline void isl_sioimath_add_ui(isl_sioimath_ptr dst, isl_sioimath lhs,
590 unsigned long rhs)
591{
592 int32_t smalllhs;
593 isl_sioimath_scratchspace_t lhsscratch;
594
595 if (isl_sioimath_decode_small(lhs, &smalllhs) &&
596 (rhs <= (uint64_t) INT64_MAX(9223372036854775807L) - (uint64_t) ISL_SIOIMATH_SMALL_MAX(2147483647))) {
597 isl_sioimath_set_int64(dst, (int64_t) smalllhs + rhs);
598 return;
599 }
600
601 impz_add_ui(isl_sioimath_reinit_big(dst),
602 isl_sioimath_bigarg_src(lhs, &lhsscratch), rhs);
603 isl_sioimath_try_demote(dst);
604}
605
606/* Subtract an unsigned long.
607 *
608 * On LP64 unsigned long exceeds the range of an int64_t. If
609 * ISL_SIOIMATH_SMALL_MIN-rhs>=INT64_MIN we can do the calculation using int64_t
610 * without risking an overflow.
611 */
612inline void isl_sioimath_sub_ui(isl_sioimath_ptr dst, isl_sioimath lhs,
613 unsigned long rhs)
614{
615 int32_t smalllhs;
616 isl_sioimath_scratchspace_t lhsscratch;
617
618 if (isl_sioimath_decode_small(lhs, &smalllhs) &&
619 (rhs < (uint64_t) INT64_MIN(-9223372036854775807L -1) - (uint64_t) ISL_SIOIMATH_SMALL_MIN(-(2147483647)))) {
620 isl_sioimath_set_int64(dst, (int64_t) smalllhs - rhs);
621 return;
622 }
623
624 impz_sub_ui(isl_sioimath_reinit_big(dst),
625 isl_sioimath_bigarg_src(lhs, &lhsscratch), rhs);
626 isl_sioimath_try_demote(dst);
627}
628
629/* Sum of two isl_ints.
630 */
631inline void isl_sioimath_add(isl_sioimath_ptr dst, isl_sioimath_src lhs,
632 isl_sioimath_src rhs)
633{
634 isl_sioimath_scratchspace_t scratchlhs, scratchrhs;
635 int32_t smalllhs, smallrhs;
636
637 if (isl_sioimath_decode_small(lhs, &smalllhs) &&
638 isl_sioimath_decode_small(rhs, &smallrhs)) {
639 isl_sioimath_set_int64(
640 dst, (int64_t) smalllhs + (int64_t) smallrhs);
641 return;
642 }
643
644 mp_int_add(isl_sioimath_bigarg_src(lhs, &scratchlhs),
645 isl_sioimath_bigarg_src(rhs, &scratchrhs),
646 isl_sioimath_reinit_big(dst));
647 isl_sioimath_try_demote(dst);
648}
649
650/* Subtract two isl_ints.
651 */
652inline void isl_sioimath_sub(isl_sioimath_ptr dst, isl_sioimath_src lhs,
653 isl_sioimath_src rhs)
654{
655 isl_sioimath_scratchspace_t scratchlhs, scratchrhs;
656 int32_t smalllhs, smallrhs;
657
658 if (isl_sioimath_decode_small(lhs, &smalllhs) &&
659 isl_sioimath_decode_small(rhs, &smallrhs)) {
660 isl_sioimath_set_int64(
661 dst, (int64_t) smalllhs - (int64_t) smallrhs);
662 return;
663 }
664
665 mp_int_sub(isl_sioimath_bigarg_src(lhs, &scratchlhs),
666 isl_sioimath_bigarg_src(rhs, &scratchrhs),
667 isl_sioimath_reinit_big(dst));
668 isl_sioimath_try_demote(dst);
669}
670
671/* Multiply two isl_ints.
672 */
673inline void isl_sioimath_mul(isl_sioimath_ptr dst, isl_sioimath_src lhs,
674 isl_sioimath_src rhs)
675{
676 isl_sioimath_scratchspace_t scratchlhs, scratchrhs;
677 int32_t smalllhs, smallrhs;
678
679 if (isl_sioimath_decode_small(lhs, &smalllhs) &&
680 isl_sioimath_decode_small(rhs, &smallrhs)) {
681 isl_sioimath_set_int64(
682 dst, (int64_t) smalllhs * (int64_t) smallrhs);
683 return;
684 }
685
686 mp_int_mul(isl_sioimath_bigarg_src(lhs, &scratchlhs),
687 isl_sioimath_bigarg_src(rhs, &scratchrhs),
688 isl_sioimath_reinit_big(dst));
689 isl_sioimath_try_demote(dst);
690}
691
692/* Shift lhs by rhs bits to the left and store the result in dst. Effectively,
693 * this operation computes 'lhs * 2^rhs'.
694 */
695inline void isl_sioimath_mul_2exp(isl_sioimath_ptr dst, isl_sioimath lhs,
696 unsigned long rhs)
697{
698 isl_sioimath_scratchspace_t scratchlhs;
699 int32_t smalllhs;
700
701 if (isl_sioimath_decode_small(lhs, &smalllhs) && (rhs <= 32ul)) {
702 isl_sioimath_set_int64(dst, ((int64_t) smalllhs) << rhs);
703 return;
704 }
705
706 mp_int_mul_pow2(isl_sioimath_bigarg_src(lhs, &scratchlhs), rhs,
707 isl_sioimath_reinit_big(dst));
708}
709
710/* Multiply an isl_int and a signed long.
711 */
712inline void isl_sioimath_mul_si(isl_sioimath_ptr dst, isl_sioimath lhs,
713 signed long rhs)
714{
715 isl_sioimath_scratchspace_t scratchlhs, scratchrhs;
716 int32_t smalllhs;
717
718 if (isl_sioimath_decode_small(lhs, &smalllhs) && (rhs > LONG_MIN(-9223372036854775807L -1L)) &&
719 (labs(rhs) <= UINT32_MAX(4294967295U))) {
720 isl_sioimath_set_int64(dst, (int64_t) smalllhs * (int64_t) rhs);
721 return;
722 }
723
724 mp_int_mul(isl_sioimath_bigarg_src(lhs, &scratchlhs),
725 isl_sioimath_siarg_src(rhs, &scratchrhs),
726 isl_sioimath_reinit_big(dst));
727 isl_sioimath_try_demote(dst);
728}
729
730/* Multiply an isl_int and an unsigned long.
731 */
732inline void isl_sioimath_mul_ui(isl_sioimath_ptr dst, isl_sioimath lhs,
733 unsigned long rhs)
734{
735 isl_sioimath_scratchspace_t scratchlhs, scratchrhs;
736 int32_t smalllhs;
737
738 if (isl_sioimath_decode_small(lhs, &smalllhs) && (rhs <= UINT32_MAX(4294967295U))) {
739 isl_sioimath_set_int64(dst, (int64_t) smalllhs * (int64_t) rhs);
740 return;
741 }
742
743 mp_int_mul(isl_sioimath_bigarg_src(lhs, &scratchlhs),
744 isl_sioimath_uiarg_src(rhs, &scratchrhs),
745 isl_sioimath_reinit_big(dst));
746 isl_sioimath_try_demote(dst);
747}
748
749/* Compute the power of an isl_int to an unsigned long.
750 * Always let IMath do it; the result is unlikely to be small except in some
751 * special cases.
752 * Note: 0^0 == 1
753 */
754inline void isl_sioimath_pow_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
755 unsigned long rhs)
756{
757 isl_sioimath_scratchspace_t scratchlhs, scratchrhs;
758 int32_t smalllhs;
759
760 switch (rhs) {
761 case 0:
762 isl_sioimath_set_small(dst, 1);
763 return;
764 case 1:
765 isl_sioimath_set(dst, lhs);
766 return;
767 case 2:
768 isl_sioimath_mul(dst, lhs, lhs);
769 return;
770 }
771
772 if (isl_sioimath_decode_small(lhs, &smalllhs)) {
773 switch (smalllhs) {
774 case 0:
775 isl_sioimath_set_small(dst, 0);
776 return;
777 case 1:
778 isl_sioimath_set_small(dst, 1);
779 return;
780 case 2:
781 isl_sioimath_set_small(dst, 1);
782 isl_sioimath_mul_2exp(dst, *dst, rhs);
783 return;
784 default:
785 if ((MP_SMALL_MIN(-9223372036854775807L -1L) <= rhs) && (rhs <= MP_SMALL_MAX9223372036854775807L)) {
786 mp_int_expt_value(smalllhs, rhs,
787 isl_sioimath_reinit_big(dst));
788 isl_sioimath_try_demote(dst);
789 return;
790 }
791 }
792 }
793
794 mp_int_expt_full(isl_sioimath_bigarg_src(lhs, &scratchlhs),
795 isl_sioimath_uiarg_src(rhs, &scratchrhs),
796 isl_sioimath_reinit_big(dst));
797 isl_sioimath_try_demote(dst);
798}
799
800/* Fused multiply-add.
801 */
802inline void isl_sioimath_addmul(isl_sioimath_ptr dst, isl_sioimath_src lhs,
803 isl_sioimath_src rhs)
804{
805 isl_sioimath tmp;
806 isl_sioimath_init(&tmp);
807 isl_sioimath_mul(&tmp, lhs, rhs);
808 isl_sioimath_add(dst, *dst, tmp);
809 isl_sioimath_clear(&tmp);
810}
811
812/* Fused multiply-add with an unsigned long.
813 */
814inline void isl_sioimath_addmul_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
815 unsigned long rhs)
816{
817 isl_sioimath tmp;
818 isl_sioimath_init(&tmp);
819 isl_sioimath_mul_ui(&tmp, lhs, rhs);
820 isl_sioimath_add(dst, *dst, tmp);
821 isl_sioimath_clear(&tmp);
822}
823
824/* Fused multiply-subtract.
825 */
826inline void isl_sioimath_submul(isl_sioimath_ptr dst, isl_sioimath_src lhs,
827 isl_sioimath_src rhs)
828{
829 isl_sioimath tmp;
830 isl_sioimath_init(&tmp);
831 isl_sioimath_mul(&tmp, lhs, rhs);
832 isl_sioimath_sub(dst, *dst, tmp);
833 isl_sioimath_clear(&tmp);
834}
835
836/* Fused multiply-add with an unsigned long.
837 */
838inline void isl_sioimath_submul_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
839 unsigned long rhs)
840{
841 isl_sioimath tmp;
842 isl_sioimath_init(&tmp);
843 isl_sioimath_mul_ui(&tmp, lhs, rhs);
844 isl_sioimath_sub(dst, *dst, tmp);
845 isl_sioimath_clear(&tmp);
846}
847
848void isl_sioimath_gcd(isl_sioimath_ptr dst, isl_sioimath_src lhs,
849 isl_sioimath_src rhs);
850void isl_sioimath_lcm(isl_sioimath_ptr dst, isl_sioimath_src lhs,
851 isl_sioimath_src rhs);
852
853/* Divide lhs by rhs, rounding to zero (Truncate).
854 */
855inline void isl_sioimath_tdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs,
856 isl_sioimath_src rhs)
857{
858 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
859 int32_t lhssmall, rhssmall;
860
861 if (isl_sioimath_decode_small(lhs, &lhssmall) &&
862 isl_sioimath_decode_small(rhs, &rhssmall)) {
863 isl_sioimath_set_small(dst, lhssmall / rhssmall);
864 return;
865 }
866
867 mp_int_div(isl_sioimath_bigarg_src(lhs, &lhsscratch),
868 isl_sioimath_bigarg_src(rhs, &rhsscratch),
869 isl_sioimath_reinit_big(dst), NULL((void*)0));
870 isl_sioimath_try_demote(dst);
871 return;
872}
873
874/* Divide lhs by an unsigned long rhs, rounding to zero (Truncate).
875 */
876inline void isl_sioimath_tdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
877 unsigned long rhs)
878{
879 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
880 int32_t lhssmall;
881
882 if (isl_sioimath_is_small(lhs) && (rhs <= (unsigned long) INT32_MAX(2147483647))) {
883 lhssmall = isl_sioimath_get_small(lhs);
884 isl_sioimath_set_small(dst, lhssmall / (int32_t) rhs);
885 return;
886 }
887
888 if (rhs <= MP_SMALL_MAX9223372036854775807L) {
889 mp_int_div_value(isl_sioimath_bigarg_src(lhs, &lhsscratch), rhs,
890 isl_sioimath_reinit_big(dst), NULL((void*)0));
891 isl_sioimath_try_demote(dst);
892 return;
893 }
894
895 mp_int_div(isl_sioimath_bigarg_src(lhs, &lhsscratch),
896 isl_sioimath_uiarg_src(rhs, &rhsscratch),
897 isl_sioimath_reinit_big(dst), NULL((void*)0));
898 isl_sioimath_try_demote(dst);
899}
900
901/* Divide lhs by rhs, rounding to positive infinity (Ceil).
902 */
903inline void isl_sioimath_cdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs,
904 isl_sioimath_src rhs)
905{
906 int32_t lhssmall, rhssmall;
907 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
908 int32_t q;
909
910 if (isl_sioimath_decode_small(lhs, &lhssmall) &&
911 isl_sioimath_decode_small(rhs, &rhssmall)) {
912 if ((lhssmall >= 0) && (rhssmall >= 0))
913 q = ((int64_t) lhssmall + (int64_t) rhssmall - 1) /
914 rhssmall;
915 else if ((lhssmall < 0) && (rhssmall < 0))
916 q = ((int64_t) lhssmall + (int64_t) rhssmall + 1) /
917 rhssmall;
918 else
919 q = lhssmall / rhssmall;
920 isl_sioimath_set_small(dst, q);
921 return;
922 }
923
924 impz_cdiv_q(isl_sioimath_reinit_big(dst),
925 isl_sioimath_bigarg_src(lhs, &lhsscratch),
926 isl_sioimath_bigarg_src(rhs, &rhsscratch));
927 isl_sioimath_try_demote(dst);
928}
929
930/* Compute the division of lhs by a rhs of type unsigned long, rounding towards
931 * positive infinity (Ceil).
932 */
933inline void isl_sioimath_cdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
934 unsigned long rhs)
935{
936 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
937 int32_t lhssmall, q;
938
939 if (isl_sioimath_decode_small(lhs, &lhssmall) && (rhs <= INT32_MAX(2147483647))) {
940 if (lhssmall >= 0)
941 q = ((int64_t) lhssmall + ((int64_t) rhs - 1)) /
942 (int64_t) rhs;
943 else
944 q = lhssmall / (int32_t) rhs;
945 isl_sioimath_set_small(dst, q);
946 return;
947 }
948
949 impz_cdiv_q(isl_sioimath_reinit_big(dst),
950 isl_sioimath_bigarg_src(lhs, &lhsscratch),
951 isl_sioimath_uiarg_src(rhs, &rhsscratch));
952 isl_sioimath_try_demote(dst);
953}
954
955/* Divide lhs by rhs, rounding to negative infinity (Floor).
956 */
957inline void isl_sioimath_fdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs,
958 isl_sioimath_src rhs)
959{
960 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
961 int32_t lhssmall, rhssmall;
962 int32_t q;
963
964 if (isl_sioimath_decode_small(lhs, &lhssmall) &&
9
Assuming the condition is true
965 isl_sioimath_decode_small(rhs, &rhssmall)) {
10
Calling 'isl_sioimath_decode_small'
19
Returning from 'isl_sioimath_decode_small'
966 if ((lhssmall
19.1
'lhssmall' is >= 0
19.1
'lhssmall' is >= 0
< 0) && (rhssmall >= 0))
967 q = ((int64_t) lhssmall - ((int64_t) rhssmall - 1)) /
968 rhssmall;
969 else if ((lhssmall
19.2
'lhssmall' is >= 0
19.2
'lhssmall' is >= 0
>= 0) && (rhssmall
19.3
'rhssmall' is >= 0
19.3
'rhssmall' is >= 0
< 0))
20
Taking false branch
970 q = ((int64_t) lhssmall - ((int64_t) rhssmall + 1)) /
971 rhssmall;
972 else
973 q = lhssmall / rhssmall;
21
Division by zero
974 isl_sioimath_set_small(dst, q);
975 return;
976 }
977
978 impz_fdiv_q(isl_sioimath_reinit_big(dst),
979 isl_sioimath_bigarg_src(lhs, &lhsscratch),
980 isl_sioimath_bigarg_src(rhs, &rhsscratch));
981 isl_sioimath_try_demote(dst);
982}
983
984/* Compute the division of lhs by a rhs of type unsigned long, rounding towards
985 * negative infinity (Floor).
986 */
987inline void isl_sioimath_fdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
988 unsigned long rhs)
989{
990 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
991 int32_t lhssmall, q;
992
993 if (isl_sioimath_decode_small(lhs, &lhssmall) && (rhs <= INT32_MAX(2147483647))) {
994 if (lhssmall >= 0)
995 q = (uint32_t) lhssmall / rhs;
996 else
997 q = ((int64_t) lhssmall - ((int64_t) rhs - 1)) /
998 (int64_t) rhs;
999 isl_sioimath_set_small(dst, q);
1000 return;
1001 }
1002
1003 impz_fdiv_q(isl_sioimath_reinit_big(dst),
1004 isl_sioimath_bigarg_src(lhs, &lhsscratch),
1005 isl_sioimath_uiarg_src(rhs, &rhsscratch));
1006 isl_sioimath_try_demote(dst);
1007}
1008
1009/* Get the remainder of: lhs divided by rhs rounded towards negative infinite
1010 * (Floor).
1011 */
1012inline void isl_sioimath_fdiv_r(isl_sioimath_ptr dst, isl_sioimath_src lhs,
1013 isl_sioimath_src rhs)
1014{
1015 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
1016 int64_t lhssmall, rhssmall;
1017 int32_t r;
1018
1019 if (isl_sioimath_is_small(lhs) && isl_sioimath_is_small(rhs)) {
1020 lhssmall = isl_sioimath_get_small(lhs);
1021 rhssmall = isl_sioimath_get_small(rhs);
1022 r = (rhssmall + lhssmall % rhssmall) % rhssmall;
1023 isl_sioimath_set_small(dst, r);
1024 return;
1025 }
1026
1027 impz_fdiv_r(isl_sioimath_reinit_big(dst),
1028 isl_sioimath_bigarg_src(lhs, &lhsscratch),
1029 isl_sioimath_bigarg_src(rhs, &rhsscratch));
1030 isl_sioimath_try_demote(dst);
1031}
1032
1033void isl_sioimath_read(isl_sioimath_ptr dst, const char *str);
1034
1035/* Return:
1036 * +1 for a positive number
1037 * -1 for a negative number
1038 * 0 if the number is zero
1039 */
1040inline int isl_sioimath_sgn(isl_sioimath_src arg)
1041{
1042 int32_t small;
1043
1044 if (isl_sioimath_decode_small(arg, &small))
1045 return (small > 0) - (small < 0);
1046
1047 return mp_int_compare_zero(isl_sioimath_get_big(arg));
1048}
1049
1050/* Return:
1051 * +1 if lhs > rhs
1052 * -1 if lhs < rhs
1053 * 0 if lhs = rhs
1054 */
1055inline int isl_sioimath_cmp(isl_sioimath_src lhs, isl_sioimath_src rhs)
1056{
1057 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
1058 int32_t lhssmall, rhssmall;
1059
1060 if (isl_sioimath_decode_small(lhs, &lhssmall) &&
1061 isl_sioimath_decode_small(rhs, &rhssmall))
1062 return (lhssmall > rhssmall) - (lhssmall < rhssmall);
1063
1064 if (isl_sioimath_decode_small(rhs, &rhssmall))
1065 return mp_int_compare_value(
1066 isl_sioimath_bigarg_src(lhs, &lhsscratch), rhssmall);
1067
1068 if (isl_sioimath_decode_small(lhs, &lhssmall))
1069 return -mp_int_compare_value(
1070 isl_sioimath_bigarg_src(rhs, &rhsscratch), lhssmall);
1071
1072 return mp_int_compare(
1073 isl_sioimath_get_big(lhs), isl_sioimath_get_big(rhs));
1074}
1075
1076/* As isl_sioimath_cmp, but with signed long rhs.
1077 */
1078inline int isl_sioimath_cmp_si(isl_sioimath_src lhs, signed long rhs)
1079{
1080 int32_t lhssmall;
1081
1082 if (isl_sioimath_decode_small(lhs, &lhssmall))
1083 return (lhssmall > rhs) - (lhssmall < rhs);
1084
1085 return mp_int_compare_value(isl_sioimath_get_big(lhs), rhs);
1086}
1087
1088/* Return:
1089 * +1 if |lhs| > |rhs|
1090 * -1 if |lhs| < |rhs|
1091 * 0 if |lhs| = |rhs|
1092 */
1093inline int isl_sioimath_abs_cmp(isl_sioimath_src lhs, isl_sioimath_src rhs)
1094{
1095 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
1096 int32_t lhssmall, rhssmall;
1097
1098 if (isl_sioimath_decode_small(lhs, &lhssmall) &&
1099 isl_sioimath_decode_small(rhs, &rhssmall)) {
1100 lhssmall = labs(lhssmall);
1101 rhssmall = labs(rhssmall);
1102 return (lhssmall > rhssmall) - (lhssmall < rhssmall);
1103 }
1104
1105 return mp_int_compare_unsigned(
1106 isl_sioimath_bigarg_src(lhs, &lhsscratch),
1107 isl_sioimath_bigarg_src(rhs, &rhsscratch));
1108}
1109
1110/* Return whether lhs is divisible by rhs.
1111 * In particular, can rhs be multiplied by some integer to result in lhs?
1112 * If rhs is zero, then this means lhs has to be zero too.
1113 */
1114inline int isl_sioimath_is_divisible_by(isl_sioimath_src lhs,
1115 isl_sioimath_src rhs)
1116{
1117 isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
1118 int32_t lhssmall, rhssmall;
1119 mpz_t rem;
1120 int cmp;
1121
1122 if (isl_sioimath_sgn(rhs) == 0)
1123 return isl_sioimath_sgn(lhs) == 0;
1124
1125 if (isl_sioimath_decode_small(lhs, &lhssmall) &&
1126 isl_sioimath_decode_small(rhs, &rhssmall))
1127 return lhssmall % rhssmall == 0;
1128
1129 if (isl_sioimath_decode_small(rhs, &rhssmall))
1130 return mp_int_divisible_value(
1131 isl_sioimath_bigarg_src(lhs, &lhsscratch), rhssmall);
1132
1133 mp_int_init(&rem);
1134 mp_int_div(isl_sioimath_bigarg_src(lhs, &lhsscratch),
1135 isl_sioimath_bigarg_src(rhs, &rhsscratch), NULL((void*)0), &rem);
1136 cmp = mp_int_compare_zero(&rem);
1137 mp_int_clear(&rem);
1138 return cmp == 0;
1139}
1140
1141/* Return a hash code of an isl_sioimath.
1142 * The hash code for a number in small and big representation must be identical
1143 * on the same machine because small representation if not obligatory if fits.
1144 */
1145inline uint32_t isl_sioimath_hash(isl_sioimath_src arg, uint32_t hash)
1146{
1147 int32_t small;
1148 int i;
1149 uint32_t num;
1150 mp_digit digits[(sizeof(uint32_t) + sizeof(mp_digit) - 1) /
1151 sizeof(mp_digit)];
1152 mp_size used;
1153 const unsigned char *digitdata = (const unsigned char *) &digits;
1154
1155 if (isl_sioimath_decode_small(arg, &small)) {
1156 if (small < 0)
1157 isl_hash_byte(hash, 0xFF)do { hash *= 16777619; hash ^= 0xFF; } while(0);
1158 num = labs(small);
1159
1160 isl_siomath_uint32_to_digits(num, digits, &used);
1161 for (i = 0; i < used * sizeof(mp_digit); i += 1)
1162 isl_hash_byte(hash, digitdata[i])do { hash *= 16777619; hash ^= digitdata[i]; } while(0);
1163 return hash;
1164 }
1165
1166 return isl_imath_hash(isl_sioimath_get_big(arg), hash);
1167}
1168
1169/* Return the number of digits in a number of the given base or more, i.e. the
1170 * string length without sign and null terminator.
1171 *
1172 * Current implementation for small representation returns the maximal number
1173 * of binary digits in that representation, which can be much larger than the
1174 * smallest possible solution.
1175 */
1176inline size_t isl_sioimath_sizeinbase(isl_sioimath_src arg, int base)
1177{
1178 int32_t small;
1179
1180 if (isl_sioimath_decode_small(arg, &small))
1181 return sizeof(int32_t) * CHAR_BIT8 - 1;
1182
1183 return impz_sizeinbase(isl_sioimath_get_big(arg), base);
1184}
1185
1186void isl_sioimath_print(FILE *out, isl_sioimath_src i, int width);
1187void isl_sioimath_dump(isl_sioimath_src arg);
1188
1189typedef isl_sioimath isl_int[1];
1190#define isl_int_init(i)isl_sioimath_init((i)) isl_sioimath_init((i))
1191#define isl_int_clear(i)isl_sioimath_clear((i)) isl_sioimath_clear((i))
1192
1193#define isl_int_set(r, i)isl_sioimath_set((r), *(i)) isl_sioimath_set((r), *(i))
1194#define isl_int_set_si(r, i)isl_sioimath_set_si((r), i) isl_sioimath_set_si((r), i)
1195#define isl_int_set_ui(r, i)isl_sioimath_set_ui((r), i) isl_sioimath_set_ui((r), i)
1196#define isl_int_fits_slong(r)isl_sioimath_fits_slong(*(r)) isl_sioimath_fits_slong(*(r))
1197#define isl_int_get_si(r)isl_sioimath_get_si(*(r)) isl_sioimath_get_si(*(r))
1198#define isl_int_fits_ulong(r)isl_sioimath_fits_ulong(*(r)) isl_sioimath_fits_ulong(*(r))
1199#define isl_int_get_ui(r)isl_sioimath_get_ui(*(r)) isl_sioimath_get_ui(*(r))
1200#define isl_int_get_d(r)isl_sioimath_get_d(*(r)) isl_sioimath_get_d(*(r))
1201#define isl_int_get_str(r)isl_sioimath_get_str(*(r)) isl_sioimath_get_str(*(r))
1202#define isl_int_abs(r, i)isl_sioimath_abs((r), *(i)) isl_sioimath_abs((r), *(i))
1203#define isl_int_neg(r, i)isl_sioimath_neg((r), *(i)) isl_sioimath_neg((r), *(i))
1204#define isl_int_swap(i, j)isl_sioimath_swap((i), (j)) isl_sioimath_swap((i), (j))
1205#define isl_int_swap_or_set(i, j)isl_sioimath_swap((i), (j)) isl_sioimath_swap((i), (j))
1206#define isl_int_add_ui(r, i, j)isl_sioimath_add_ui((r), *(i), j) isl_sioimath_add_ui((r), *(i), j)
1207#define isl_int_sub_ui(r, i, j)isl_sioimath_sub_ui((r), *(i), j) isl_sioimath_sub_ui((r), *(i), j)
1208
1209#define isl_int_add(r, i, j)isl_sioimath_add((r), *(i), *(j)) isl_sioimath_add((r), *(i), *(j))
1210#define isl_int_sub(r, i, j)isl_sioimath_sub((r), *(i), *(j)) isl_sioimath_sub((r), *(i), *(j))
1211#define isl_int_mul(r, i, j)isl_sioimath_mul((r), *(i), *(j)) isl_sioimath_mul((r), *(i), *(j))
1212#define isl_int_mul_2exp(r, i, j)isl_sioimath_mul_2exp((r), *(i), j) isl_sioimath_mul_2exp((r), *(i), j)
1213#define isl_int_mul_si(r, i, j)isl_sioimath_mul_si((r), *(i), j) isl_sioimath_mul_si((r), *(i), j)
1214#define isl_int_mul_ui(r, i, j)isl_sioimath_mul_ui((r), *(i), j) isl_sioimath_mul_ui((r), *(i), j)
1215#define isl_int_pow_ui(r, i, j)isl_sioimath_pow_ui((r), *(i), j) isl_sioimath_pow_ui((r), *(i), j)
1216#define isl_int_addmul(r, i, j)isl_sioimath_addmul((r), *(i), *(j)) isl_sioimath_addmul((r), *(i), *(j))
1217#define isl_int_addmul_ui(r, i, j)isl_sioimath_addmul_ui((r), *(i), j) isl_sioimath_addmul_ui((r), *(i), j)
1218#define isl_int_submul(r, i, j)isl_sioimath_submul((r), *(i), *(j)) isl_sioimath_submul((r), *(i), *(j))
1219#define isl_int_submul_ui(r, i, j)isl_sioimath_submul_ui((r), *(i), j) isl_sioimath_submul_ui((r), *(i), j)
1220
1221#define isl_int_gcd(r, i, j)isl_sioimath_gcd((r), *(i), *(j)) isl_sioimath_gcd((r), *(i), *(j))
1222#define isl_int_lcm(r, i, j)isl_sioimath_lcm((r), *(i), *(j)) isl_sioimath_lcm((r), *(i), *(j))
1223#define isl_int_divexact(r, i, j)isl_sioimath_tdiv_q((r), *(i), *(j)) isl_sioimath_tdiv_q((r), *(i), *(j))
1224#define isl_int_divexact_ui(r, i, j)isl_sioimath_tdiv_q_ui((r), *(i), j) isl_sioimath_tdiv_q_ui((r), *(i), j)
1225#define isl_int_tdiv_q(r, i, j)isl_sioimath_tdiv_q((r), *(i), *(j)) isl_sioimath_tdiv_q((r), *(i), *(j))
1226#define isl_int_cdiv_q(r, i, j)isl_sioimath_cdiv_q((r), *(i), *(j)) isl_sioimath_cdiv_q((r), *(i), *(j))
1227#define isl_int_cdiv_q_ui(r, i, j)isl_sioimath_cdiv_q_ui((r), *(i), j) isl_sioimath_cdiv_q_ui((r), *(i), j)
1228#define isl_int_fdiv_q(r, i, j)isl_sioimath_fdiv_q((r), *(i), *(j)) isl_sioimath_fdiv_q((r), *(i), *(j))
1229#define isl_int_fdiv_r(r, i, j)isl_sioimath_fdiv_r((r), *(i), *(j)) isl_sioimath_fdiv_r((r), *(i), *(j))
1230#define isl_int_fdiv_q_ui(r, i, j)isl_sioimath_fdiv_q_ui((r), *(i), j) isl_sioimath_fdiv_q_ui((r), *(i), j)
1231
1232#define isl_int_read(r, s)isl_sioimath_read((r), s) isl_sioimath_read((r), s)
1233#define isl_int_sgn(i)isl_sioimath_sgn(*(i)) isl_sioimath_sgn(*(i))
1234#define isl_int_cmp(i, j)isl_sioimath_cmp(*(i), *(j)) isl_sioimath_cmp(*(i), *(j))
1235#define isl_int_cmp_si(i, si)isl_sioimath_cmp_si(*(i), si) isl_sioimath_cmp_si(*(i), si)
1236#define isl_int_eq(i, j)(isl_sioimath_cmp(*(i), *(j)) == 0) (isl_sioimath_cmp(*(i), *(j)) == 0)
1237#define isl_int_ne(i, j)(isl_sioimath_cmp(*(i), *(j)) != 0) (isl_sioimath_cmp(*(i), *(j)) != 0)
1238#define isl_int_lt(i, j)(isl_sioimath_cmp(*(i), *(j)) < 0) (isl_sioimath_cmp(*(i), *(j)) < 0)
1239#define isl_int_le(i, j)(isl_sioimath_cmp(*(i), *(j)) <= 0) (isl_sioimath_cmp(*(i), *(j)) <= 0)
1240#define isl_int_gt(i, j)(isl_sioimath_cmp(*(i), *(j)) > 0) (isl_sioimath_cmp(*(i), *(j)) > 0)
1241#define isl_int_ge(i, j)(isl_sioimath_cmp(*(i), *(j)) >= 0) (isl_sioimath_cmp(*(i), *(j)) >= 0)
1242#define isl_int_abs_cmp(i, j)isl_sioimath_abs_cmp(*(i), *(j)) isl_sioimath_abs_cmp(*(i), *(j))
1243#define isl_int_abs_eq(i, j)(isl_sioimath_abs_cmp(*(i), *(j)) == 0) (isl_sioimath_abs_cmp(*(i), *(j)) == 0)
1244#define isl_int_abs_ne(i, j)(isl_sioimath_abs_cmp(*(i), *(j)) != 0) (isl_sioimath_abs_cmp(*(i), *(j)) != 0)
1245#define isl_int_abs_lt(i, j)(isl_sioimath_abs_cmp(*(i), *(j)) < 0) (isl_sioimath_abs_cmp(*(i), *(j)) < 0)
1246#define isl_int_abs_gt(i, j)(isl_sioimath_abs_cmp(*(i), *(j)) > 0) (isl_sioimath_abs_cmp(*(i), *(j)) > 0)
1247#define isl_int_abs_ge(i, j)(isl_sioimath_abs_cmp(*(i), *(j)) >= 0) (isl_sioimath_abs_cmp(*(i), *(j)) >= 0)
1248#define isl_int_is_divisible_by(i, j)isl_sioimath_is_divisible_by(*(i), *(j)) isl_sioimath_is_divisible_by(*(i), *(j))
1249
1250#define isl_int_hash(v, h)isl_sioimath_hash(*(v), h) isl_sioimath_hash(*(v), h)
1251#define isl_int_free_str(s)free(s) free(s)
1252#define isl_int_print(out, i, width)isl_sioimath_print(out, *(i), width) isl_sioimath_print(out, *(i), width)
1253
1254#endif /* ISL_INT_SIOIMATH_H */