Problem 989
Fibonacci sum with nonprimitive pairs, mod 1e9+9. Tonelli-Shanks, Mobius sieve, and sliding window sums.
View problem on Project Euler
Performance comparison
| Metric | Our solution | Best known |
| Time complexity | O(n^2) | O(n log log n) |
| Space complexity | O(n^2) | O(n) |
| Approach | Flow solution | Mobius sieve |
| Verdict | Suboptimal |
Flow source
# Project Euler 989
# Fibonacci sum with nonprimitive pairs, mod 1e9+9.
# Tonelli-Shanks, Mobius sieve, and sliding window sums.
extern {
function calloc(n: i64, size: i64) -> ptr<void>
function free(p: ptr<void>) -> void
function memset(p: ptr<void>, c: i32, n: i64) -> ptr<void>
function sqrt(x: f64) -> f64
}
const MOD: i64 = 1000000009
const TARGET_LIMIT: i64 = 100000000000000
const SMALL_LIMIT: i64 = 8
# MOD < 2^30, so a*b < 2^60 fits in i64 (avoids slow i128 division).
function mulmod(a: i64, b: i64) -> i64 {
return (a * b) % MOD
}
function mod_pow(a0: i64, e0: i64) -> i64 {
let mut a: i64 = a0 % MOD
if a < 0 { a = a + MOD }
let mut r: i64 = 1
let mut e: i64 = e0
while e > 0 {
if (e & 1) != 0 { r = mulmod(r, a) }
a = mulmod(a, a)
e = e >> 1
}
return r
}
function tonelli_shanks(n0: i64, p: i64) -> i64 {
let n: i64 = n0 % p
if n == 0 { return 0 }
if mod_pow(n, (p - 1) / 2) != 1 { return -1 }
if p % 4 == 3 { return mod_pow(n, (p + 1) / 4) }
let mut q: i64 = p - 1
let mut s: i64 = 0
while q % 2 == 0 { q = q / 2; s = s + 1 }
let mut z: i64 = 2
while mod_pow(z, (p - 1) / 2) != p - 1 { z = z + 1 }
let mut m: i64 = s
let mut c: i64 = mod_pow(z, q)
let mut t: i64 = mod_pow(n, q)
let mut r: i64 = mod_pow(n, (q + 1) / 2)
while t != 1 {
let mut i: i64 = 1
let mut t2i: i64 = mulmod(t, t)
while t2i != 1 { t2i = mulmod(t2i, t2i); i = i + 1 }
let b: i64 = mod_pow(c, (1 as i64) << (m - i - 1))
r = mulmod(r, b)
c = mulmod(b, b)
t = mulmod(t, c)
m = i
}
return r
}
function isqrt_i64(n: i64) -> i64 {
if n <= 0 { return 0 }
let mut r: i64 = sqrt(n as f64) as i64
while r > 0 && r * r > n { r = r - 1 }
while (r + 1) * (r + 1) <= n { r = r + 1 }
return r
}
function mobius_sieve(limit: i64) -> ptr<i8> {
let mu: ptr<i8> = calloc(limit + 1, 1)
memset(mu, 1, limit + 1)
let is_prime: ptr<i8> = calloc(limit + 1, 1)
memset(is_prime, 1, limit + 1)
if limit >= 0 { is_prime[0] = 0 }
if limit >= 1 { is_prime[1] = 0 }
let mut p: i64 = 2
while p <= limit {
if is_prime[p] == 0 {
p = p + 1
continue
}
let mut mult: i64 = p
while mult <= limit {
mu[mult] = -mu[mult]
mult = mult + p
}
let square: i64 = p * p
if square <= limit {
let mut mult2: i64 = square
while mult2 <= limit {
mu[mult2] = 0
mult2 = mult2 + square
}
let mut mult3: i64 = square
while mult3 <= limit {
is_prime[mult3] = 0
mult3 = mult3 + p
}
}
let mut mult4: i64 = p + p
while mult4 <= limit {
is_prime[mult4] = 0
mult4 = mult4 + p
}
p = p + 1
}
free(is_prime as ptr<void>)
return mu
}
# Small nonprimitive terms: q = a^2 - ab - b^2, 0 < q <= 8
const MAX_SMALL: i32 = 16
function build_small_values(out: ptr<i32>) -> i32 {
let max_a: i32 = 2 * isqrt_i64(SMALL_LIMIT) + 2
let mut count: i32 = 0
let mut a: i32 = 2
while a <= max_a {
let mut b: i32 = 1
while b <= a / 2 {
let q: i32 = a * a - a * b - b * b
if q > 0 && q <= (SMALL_LIMIT as i32) {
out[count] = q
count = count + 1
}
b = b + 1
}
a = a + 1
}
# insertion sort
let mut i: i32 = 0
while i < count {
let mut j: i32 = i + 1
while j < count {
if out[j] < out[i] {
let t: i32 = out[i]
out[i] = out[j]
out[j] = t
}
j = j + 1
}
i = i + 1
}
return count
}
function eval_small_nonprimitive_pair(limit: i64, z1: i64, z2: i64,
sv: ptr<i32>, svc: i32,
out1: ptr<i64>, out2: ptr<i64>) -> void {
let mut total1: i64 = 0
let mut total2: i64 = 0
let mut power1: i64 = 1
let mut power2: i64 = 1
let mut exponent: i64 = 0
let mut idx: i32 = 0
while idx < svc {
let target: i64 = sv[idx] as i64
if target > limit { break }
while exponent < target {
power1 = mulmod(power1, z1)
power2 = mulmod(power2, z2)
exponent = exponent + 1
}
total1 = total1 + power1
if total1 >= MOD { total1 = total1 - MOD }
total2 = total2 + power2
if total2 >= MOD { total2 = total2 - MOD }
idx = idx + 1
}
out1[0] = total1
out2[0] = total2
}
function nonprimitive_pair(limit: i64, z1: i64, z1_inv: i64,
z2: i64, z2_inv: i64,
sv: ptr<i32>, svc: i32,
out1: ptr<i64>, out2: ptr<i64>) -> void {
if limit <= SMALL_LIMIT {
eval_small_nonprimitive_pair(limit, z1, z2, sv, svc, out1, out2)
return
}
let mut total1: i64 = 0
let mut total2: i64 = 0
let z1_sq: i64 = mulmod(z1, z1)
let z2_sq: i64 = mulmod(z2, z2)
let z1_inv_sq: i64 = mulmod(z1_inv, z1_inv)
let z2_inv_sq: i64 = mulmod(z2_inv, z2_inv)
let z1_inv_4: i64 = mulmod(z1_inv_sq, z1_inv_sq)
let z2_inv_4: i64 = mulmod(z2_inv_sq, z2_inv_sq)
let z1_inv_5: i64 = mulmod(z1_inv_4, z1_inv)
let z2_inv_5: i64 = mulmod(z2_inv_4, z2_inv)
let z1_inv_10: i64 = mulmod(z1_inv_5, z1_inv_5)
let z2_inv_10: i64 = mulmod(z2_inv_5, z2_inv_5)
let z1_inv_15: i64 = mulmod(z1_inv_10, z1_inv_5)
let z2_inv_15: i64 = mulmod(z2_inv_10, z2_inv_5)
# Even part: sliding window of z^(m^2)
let mut even_weight1: i64 = z1_inv_5
let mut even_weight2: i64 = z2_inv_5
let mut even_delta1: i64 = z1_inv_15
let mut even_delta2: i64 = z2_inv_15
let mut add_index: i64 = 0
let mut add_term1: i64 = 1
let mut add_term2: i64 = 1
let mut add_step1: i64 = z1
let mut add_step2: i64 = z2
let mut drop_index: i64 = 0
let mut drop_term1: i64 = 1
let mut drop_term2: i64 = 1
let mut drop_step1: i64 = z1
let mut drop_step2: i64 = z2
let mut window1: i64 = 0
let mut window2: i64 = 0
let mut t: i64 = 1
let mut lower: i64 = 3
let mut upper: i64 = 0
let mut rhs: i64 = limit + 5
while (upper + 1) * (upper + 1) <= rhs { upper = upper + 1 }
while lower <= upper {
while add_index <= upper {
window1 = window1 + add_term1
if window1 >= MOD { window1 = window1 - MOD }
window2 = window2 + add_term2
if window2 >= MOD { window2 = window2 - MOD }
add_term1 = mulmod(add_term1, add_step1)
add_step1 = mulmod(add_step1, z1_sq)
add_term2 = mulmod(add_term2, add_step2)
add_step2 = mulmod(add_step2, z2_sq)
add_index = add_index + 1
}
while drop_index < lower {
window1 = window1 - drop_term1
if window1 < 0 { window1 = window1 + MOD }
window2 = window2 - drop_term2
if window2 < 0 { window2 = window2 + MOD }
drop_term1 = mulmod(drop_term1, drop_step1)
drop_step1 = mulmod(drop_step1, z1_sq)
drop_term2 = mulmod(drop_term2, drop_step2)
drop_step2 = mulmod(drop_step2, z2_sq)
drop_index = drop_index + 1
}
total1 = (total1 + mulmod(window1, even_weight1)) % MOD
total2 = (total2 + mulmod(window2, even_weight2)) % MOD
even_weight1 = mulmod(even_weight1, even_delta1)
even_delta1 = mulmod(even_delta1, z1_inv_10)
even_weight2 = mulmod(even_weight2, even_delta2)
even_delta2 = mulmod(even_delta2, z2_inv_10)
rhs = rhs + 10 * t + 5
t = t + 1
lower = lower + 3
while (upper + 1) * (upper + 1) <= rhs { upper = upper + 1 }
}
# Odd part: sliding window of z^(m(m+1))
let mut odd_weight1: i64 = z1_inv
let mut odd_weight2: i64 = z2_inv
let mut odd_delta1: i64 = z1_inv_10
let mut odd_delta2: i64 = z2_inv_10
add_index = 0
add_term1 = 1
add_term2 = 1
add_step1 = z1_sq
add_step2 = z2_sq
drop_index = 0
drop_term1 = 1
drop_term2 = 1
drop_step1 = z1_sq
drop_step2 = z2_sq
window1 = 0
window2 = 0
t = 0
lower = 1
upper = 0
rhs = limit + 1
while (upper + 1) * (upper + 2) <= rhs { upper = upper + 1 }
while lower <= upper {
while add_index <= upper {
window1 = window1 + add_term1
if window1 >= MOD { window1 = window1 - MOD }
window2 = window2 + add_term2
if window2 >= MOD { window2 = window2 - MOD }
add_term1 = mulmod(add_term1, add_step1)
add_step1 = mulmod(add_step1, z1_sq)
add_term2 = mulmod(add_term2, add_step2)
add_step2 = mulmod(add_step2, z2_sq)
add_index = add_index + 1
}
while drop_index < lower {
window1 = window1 - drop_term1
if window1 < 0 { window1 = window1 + MOD }
window2 = window2 - drop_term2
if window2 < 0 { window2 = window2 + MOD }
drop_term1 = mulmod(drop_term1, drop_step1)
drop_step1 = mulmod(drop_step1, z1_sq)
drop_term2 = mulmod(drop_term2, drop_step2)
drop_step2 = mulmod(drop_step2, z2_sq)
drop_index = drop_index + 1
}
total1 = (total1 + mulmod(window1, odd_weight1)) % MOD
total2 = (total2 + mulmod(window2, odd_weight2)) % MOD
odd_weight1 = mulmod(odd_weight1, odd_delta1)
odd_delta1 = mulmod(odd_delta1, z1_inv_10)
odd_weight2 = mulmod(odd_weight2, odd_delta2)
odd_delta2 = mulmod(odd_delta2, z2_inv_10)
rhs = rhs + 10 * t + 10
t = t + 1
lower = lower + 3
while (upper + 1) * (upper + 2) <= rhs { upper = upper + 1 }
}
out1[0] = total1
out2[0] = total2
}
function main() -> i32 {
let sv: ptr<i32> = calloc(MAX_SMALL, 4)
let svc: i32 = build_small_values(sv)
let limit: i64 = TARGET_LIMIT
let root: i64 = isqrt_i64(limit)
let mu: ptr<i8> = mobius_sieve(root)
let sqrt5_mod: i64 = tonelli_shanks(5, MOD)
let inv_sqrt5_mod: i64 = mod_pow(sqrt5_mod, MOD - 2)
let inv2_mod: i64 = (MOD + 1) / 2
let phi_mod: i64 = mulmod((1 + sqrt5_mod) % MOD, inv2_mod)
let phi_inv_mod: i64 = mod_pow(phi_mod, MOD - 2)
let phi_sq_mod: i64 = mulmod(phi_mod, phi_mod)
let phi_inv_sq_mod: i64 = mulmod(phi_inv_mod, phi_inv_mod)
let mut p_phi: i64 = 0
let mut p_psi: i64 = 0
let mut phi_pow_g2: i64 = 1
let mut phi_inv_pow_g2: i64 = 1
let mut forward_step: i64 = phi_mod
let mut backward_step: i64 = phi_inv_mod
let mut g_square: i64 = 1
let np_phi: ptr<i64> = calloc(1, 8)
let np_psi: ptr<i64> = calloc(1, 8)
let mut g: i64 = 1
while g <= root {
phi_pow_g2 = mulmod(phi_pow_g2, forward_step)
forward_step = mulmod(forward_step, phi_sq_mod)
phi_inv_pow_g2 = mulmod(phi_inv_pow_g2, backward_step)
backward_step = mulmod(backward_step, phi_inv_sq_mod)
let mu_g: i8 = mu[g]
if mu_g != 0 {
let scaled_limit: i64 = limit / g_square
let psi_pow_g2: i64
let psi_inv_pow_g2: i64
if (g & 1) != 0 {
psi_pow_g2 = MOD - phi_inv_pow_g2
psi_inv_pow_g2 = MOD - phi_pow_g2
} else {
psi_pow_g2 = phi_inv_pow_g2
psi_inv_pow_g2 = phi_pow_g2
}
nonprimitive_pair(scaled_limit,
phi_pow_g2, phi_inv_pow_g2,
psi_pow_g2, psi_inv_pow_g2,
sv, svc, np_phi, np_psi)
if mu_g == 1 {
p_phi = p_phi + np_phi[0]
if p_phi >= MOD { p_phi = p_phi - MOD }
p_psi = p_psi + np_psi[0]
if p_psi >= MOD { p_psi = p_psi - MOD }
} else {
p_phi = p_phi - np_phi[0]
if p_phi < 0 { p_phi = p_phi + MOD }
p_psi = p_psi - np_psi[0]
if p_psi < 0 { p_psi = p_psi + MOD }
}
}
g_square = g_square + 2 * g + 1
g = g + 1
}
free(mu as ptr<void>)
free(sv as ptr<void>)
free(np_phi as ptr<void>)
free(np_psi as ptr<void>)
printf("%lld\n", mulmod((p_phi - p_psi + MOD) % MOD, inv_sqrt5_mod))
return 0
}
Generated C
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Flow runtime helpers */
typedef struct flow_temp_node { struct flow_temp_node* next; } flow_temp_node;
static flow_temp_node* flow_temp_head = NULL;
static int flow_temp_atexit_set = 0;
__attribute__((unused)) static void flow_temp_free_all(void) {
while (flow_temp_head) {
flow_temp_node* n = flow_temp_head;
flow_temp_head = n->next;
free(n);
}
}
__attribute__((unused)) static void* flow_temp_alloc(size_t nbytes) {
flow_temp_node* node = (flow_temp_node*)malloc(sizeof(flow_temp_node) + nbytes);
if (!node) return NULL;
node->next = flow_temp_head;
flow_temp_head = node;
if (!flow_temp_atexit_set) {
flow_temp_atexit_set = 1;
atexit(flow_temp_free_all);
}
return (void*)(node + 1);
}
#ifndef FLOW_DIAG
#define FLOW_DIAG(msg) fprintf(stderr, "%s", (msg))
#endif
#ifndef FLOW_LOG
#define FLOW_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
#ifndef FLOW_LOG_EMPTY
#define FLOW_LOG_EMPTY(fmt) printf(fmt)
#endif
static char* flow_strcat(const char* a, const char* b) {
size_t la = strlen(a ? a : ""), lb = strlen(b ? b : "");
char* r = (char*)flow_temp_alloc(la + lb + 1);
if (!r) return NULL;
if (la) memcpy(r, a, la);
if (lb) memcpy(r + la, b, lb);
r[la + lb] = '\0';
return r;
}
#define __flow_in_arr(arr, val) __extension__ ({ \
int _found = 0; \
size_t _n = sizeof(arr)/sizeof((arr)[0]); \
for (size_t _i = 0; _i < _n; _i++) { \
if ((arr)[_i] == (val)) { _found = 1; break; } \
} _found; })
/* Unified fault handler (MISRA #279) — override with -DFLOW_FAULT_HANDLER=fn */
#ifndef FLOW_FAULT_HANDLER
__attribute__((unused)) static inline void flow_fault_handler(const char* msg) {
fprintf(stderr, "flow: %s\n", msg ? msg : "fault");
abort();
#if defined(__GNUC__) || defined(__clang__)
__builtin_unreachable();
#endif
}
#else
#define flow_fault_handler FLOW_FAULT_HANDLER
#endif
#define flow_div_by_zero_handler() flow_fault_handler("division by zero")
#define flow_shift_ub_handler() flow_fault_handler("invalid shift (amount out of range or left-shift of negative)")
#ifndef FLOW_CHECKED_DIV
#define FLOW_CHECKED_DIV(L, R) (((R) != 0) ? ((L) / (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_MOD
#define FLOW_CHECKED_MOD(L, R) (((R) != 0) ? ((L) % (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHL
#define FLOW_CHECKED_SHL(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull)) && ((L) >= 0)) ? ((L) << (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHR
#define FLOW_CHECKED_SHR(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull))) ? ((L) >> (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#include <math.h>
void* _ui_state = NULL;
static inline float i32_to_f32(int32_t v) { return (float)v; }
/* Host stub for @gpu kernels (device codegen replaces this). */
static inline int32_t gpu_thread_id(void) { return 0; }
int64_t mulmod_i64_i64(int64_t a, int64_t b);
int64_t mod_pow_i64_i64(int64_t a0, int64_t e0);
int64_t tonelli_shanks_i64_i64(int64_t n0, int64_t p);
int64_t isqrt_i64_i64(int64_t n);
int8_t* mobius_sieve_i64(int64_t limit);
int32_t build_small_values_ptr_i32(int32_t* out);
void eval_small_nonprimitive_pair_i64_i64_i64_ptr_i32_i32_ptr_i64_ptr_i64(int64_t limit, int64_t z1, int64_t z2, int32_t* sv, int32_t svc, int64_t* out1, int64_t* out2);
void nonprimitive_pair_i64_i64_i64_i64_i64_ptr_i32_i32_ptr_i64_ptr_i64(int64_t limit, int64_t z1, int64_t z1_inv, int64_t z2, int64_t z2_inv, int32_t* sv, int32_t svc, int64_t* out1, int64_t* out2);
int32_t main(void);
static const int64_t MOD = 1000000009;
static const int64_t TARGET_LIMIT = 100000000000000;
static const int64_t SMALL_LIMIT = 8;
static const int32_t MAX_SMALL = 16;
int64_t mulmod_i64_i64(int64_t a, int64_t b) {
return FLOW_CHECKED_MOD(((a * b)), (MOD));
}
int64_t mod_pow_i64_i64(int64_t a0, int64_t e0) {
int64_t a = FLOW_CHECKED_MOD((a0), (MOD));
if (a < 0) {
a = (a + MOD);
}
int64_t r = 1;
int64_t e = e0;
while (e > 0) {
if ((e & 1) != 0) {
r = mulmod_i64_i64(r, a);
}
a = mulmod_i64_i64(a, a);
e = FLOW_CHECKED_SHR((e), (1));
}
return r;
}
int64_t tonelli_shanks_i64_i64(int64_t n0, int64_t p) {
int64_t n = FLOW_CHECKED_MOD((n0), (p));
if (n == 0) {
return 0;
}
if (mod_pow_i64_i64(n, FLOW_CHECKED_DIV(((p - 1)), (2))) != 1) {
return (-1);
}
if (FLOW_CHECKED_MOD((p), (4)) == 3) {
return mod_pow_i64_i64(n, FLOW_CHECKED_DIV(((p + 1)), (4)));
}
int64_t q = (p - 1);
int64_t s = 0;
while (FLOW_CHECKED_MOD((q), (2)) == 0) {
q = FLOW_CHECKED_DIV((q), (2));
s = (s + 1);
}
int64_t z = 2;
while (mod_pow_i64_i64(z, FLOW_CHECKED_DIV(((p - 1)), (2))) != (p - 1)) {
z = (z + 1);
}
int64_t m = s;
int64_t c = mod_pow_i64_i64(z, q);
int64_t t = mod_pow_i64_i64(n, q);
int64_t r = mod_pow_i64_i64(n, FLOW_CHECKED_DIV(((q + 1)), (2)));
while (t != 1) {
int64_t i = 1;
int64_t t2i = mulmod_i64_i64(t, t);
while (t2i != 1) {
t2i = mulmod_i64_i64(t2i, t2i);
i = (i + 1);
}
int64_t b = mod_pow_i64_i64(c, FLOW_CHECKED_SHL((((int64_t)(1))), (((m - i) - 1))));
r = mulmod_i64_i64(r, b);
c = mulmod_i64_i64(b, b);
t = mulmod_i64_i64(t, c);
m = i;
}
return r;
}
int64_t isqrt_i64_i64(int64_t n) {
if (n <= 0) {
return 0;
}
int64_t r = ((int64_t)(sqrt(((double)(n)))));
while ((r > 0 && (r * r) > n)) {
r = (r - 1);
}
while (((r + 1) * (r + 1)) <= n) {
r = (r + 1);
}
return r;
}
int8_t* mobius_sieve_i64(int64_t limit) {
int8_t* mu = (int8_t*)(calloc((limit + 1), 1));
memset(mu, 1, (limit + 1));
int8_t* is_prime = (int8_t*)(calloc((limit + 1), 1));
memset(is_prime, 1, (limit + 1));
if (limit >= 0) {
is_prime[0] = 0;
}
if (limit >= 1) {
is_prime[1] = 0;
}
int64_t p = 2;
while (p <= limit) {
if (is_prime[p] == 0) {
p = (p + 1);
continue;
}
int64_t mult = p;
while (mult <= limit) {
mu[mult] = (-mu[mult]);
mult = (mult + p);
}
int64_t square = (p * p);
if (square <= limit) {
int64_t mult2 = square;
while (mult2 <= limit) {
mu[mult2] = 0;
mult2 = (mult2 + square);
}
int64_t mult3 = square;
while (mult3 <= limit) {
is_prime[mult3] = 0;
mult3 = (mult3 + p);
}
}
int64_t mult4 = (p + p);
while (mult4 <= limit) {
is_prime[mult4] = 0;
mult4 = (mult4 + p);
}
p = (p + 1);
}
free(((void*)(is_prime)));
return mu;
}
int32_t build_small_values_ptr_i32(int32_t* out) {
int32_t max_a = ((2 * isqrt_i64_i64(SMALL_LIMIT)) + 2);
int32_t count = 0;
int32_t a = 2;
while (a <= max_a) {
int32_t b = 1;
while (b <= FLOW_CHECKED_DIV((a), (2))) {
int32_t q = (((a * a) - (a * b)) - (b * b));
if ((q > 0 && q <= ((int32_t)(SMALL_LIMIT)))) {
out[count] = q;
count = (count + 1);
}
b = (b + 1);
}
a = (a + 1);
}
int32_t i = 0;
while (i < count) {
int32_t j = (i + 1);
while (j < count) {
if (out[j] < out[i]) {
int32_t t = out[i];
out[i] = out[j];
out[j] = t;
}
j = (j + 1);
}
i = (i + 1);
}
return count;
}
void eval_small_nonprimitive_pair_i64_i64_i64_ptr_i32_i32_ptr_i64_ptr_i64(int64_t limit, int64_t z1, int64_t z2, int32_t* sv, int32_t svc, int64_t* out1, int64_t* out2) {
int64_t total1 = 0;
int64_t total2 = 0;
int64_t power1 = 1;
int64_t power2 = 1;
int64_t exponent = 0;
int32_t idx = 0;
while (idx < svc) {
int64_t target = ((int64_t)(sv[idx]));
if (target > limit) {
break;
}
while (exponent < target) {
power1 = mulmod_i64_i64(power1, z1);
power2 = mulmod_i64_i64(power2, z2);
exponent = (exponent + 1);
}
total1 = (total1 + power1);
if (total1 >= MOD) {
total1 = (total1 - MOD);
}
total2 = (total2 + power2);
if (total2 >= MOD) {
total2 = (total2 - MOD);
}
idx = (idx + 1);
}
out1[0] = total1;
out2[0] = total2;
}
void nonprimitive_pair_i64_i64_i64_i64_i64_ptr_i32_i32_ptr_i64_ptr_i64(int64_t limit, int64_t z1, int64_t z1_inv, int64_t z2, int64_t z2_inv, int32_t* sv, int32_t svc, int64_t* out1, int64_t* out2) {
if (limit <= SMALL_LIMIT) {
eval_small_nonprimitive_pair_i64_i64_i64_ptr_i32_i32_ptr_i64_ptr_i64(limit, z1, z2, sv, svc, out1, out2);
return;
}
int64_t total1 = 0;
int64_t total2 = 0;
int64_t z1_sq = mulmod_i64_i64(z1, z1);
int64_t z2_sq = mulmod_i64_i64(z2, z2);
int64_t z1_inv_sq = mulmod_i64_i64(z1_inv, z1_inv);
int64_t z2_inv_sq = mulmod_i64_i64(z2_inv, z2_inv);
int64_t z1_inv_4 = mulmod_i64_i64(z1_inv_sq, z1_inv_sq);
int64_t z2_inv_4 = mulmod_i64_i64(z2_inv_sq, z2_inv_sq);
int64_t z1_inv_5 = mulmod_i64_i64(z1_inv_4, z1_inv);
int64_t z2_inv_5 = mulmod_i64_i64(z2_inv_4, z2_inv);
int64_t z1_inv_10 = mulmod_i64_i64(z1_inv_5, z1_inv_5);
int64_t z2_inv_10 = mulmod_i64_i64(z2_inv_5, z2_inv_5);
int64_t z1_inv_15 = mulmod_i64_i64(z1_inv_10, z1_inv_5);
int64_t z2_inv_15 = mulmod_i64_i64(z2_inv_10, z2_inv_5);
int64_t even_weight1 = z1_inv_5;
int64_t even_weight2 = z2_inv_5;
int64_t even_delta1 = z1_inv_15;
int64_t even_delta2 = z2_inv_15;
int64_t add_index = 0;
int64_t add_term1 = 1;
int64_t add_term2 = 1;
int64_t add_step1 = z1;
int64_t add_step2 = z2;
int64_t drop_index = 0;
int64_t drop_term1 = 1;
int64_t drop_term2 = 1;
int64_t drop_step1 = z1;
int64_t drop_step2 = z2;
int64_t window1 = 0;
int64_t window2 = 0;
int64_t t = 1;
int64_t lower = 3;
int64_t upper = 0;
int64_t rhs = (limit + 5);
while (((upper + 1) * (upper + 1)) <= rhs) {
upper = (upper + 1);
}
while (lower <= upper) {
while (add_index <= upper) {
window1 = (window1 + add_term1);
if (window1 >= MOD) {
window1 = (window1 - MOD);
}
window2 = (window2 + add_term2);
if (window2 >= MOD) {
window2 = (window2 - MOD);
}
add_term1 = mulmod_i64_i64(add_term1, add_step1);
add_step1 = mulmod_i64_i64(add_step1, z1_sq);
add_term2 = mulmod_i64_i64(add_term2, add_step2);
add_step2 = mulmod_i64_i64(add_step2, z2_sq);
add_index = (add_index + 1);
}
while (drop_index < lower) {
window1 = (window1 - drop_term1);
if (window1 < 0) {
window1 = (window1 + MOD);
}
window2 = (window2 - drop_term2);
if (window2 < 0) {
window2 = (window2 + MOD);
}
drop_term1 = mulmod_i64_i64(drop_term1, drop_step1);
drop_step1 = mulmod_i64_i64(drop_step1, z1_sq);
drop_term2 = mulmod_i64_i64(drop_term2, drop_step2);
drop_step2 = mulmod_i64_i64(drop_step2, z2_sq);
drop_index = (drop_index + 1);
}
total1 = FLOW_CHECKED_MOD(((total1 + mulmod_i64_i64(window1, even_weight1))), (MOD));
total2 = FLOW_CHECKED_MOD(((total2 + mulmod_i64_i64(window2, even_weight2))), (MOD));
even_weight1 = mulmod_i64_i64(even_weight1, even_delta1);
even_delta1 = mulmod_i64_i64(even_delta1, z1_inv_10);
even_weight2 = mulmod_i64_i64(even_weight2, even_delta2);
even_delta2 = mulmod_i64_i64(even_delta2, z2_inv_10);
rhs = ((rhs + (10 * t)) + 5);
t = (t + 1);
lower = (lower + 3);
while (((upper + 1) * (upper + 1)) <= rhs) {
upper = (upper + 1);
}
}
int64_t odd_weight1 = z1_inv;
int64_t odd_weight2 = z2_inv;
int64_t odd_delta1 = z1_inv_10;
int64_t odd_delta2 = z2_inv_10;
add_index = 0;
add_term1 = 1;
add_term2 = 1;
add_step1 = z1_sq;
add_step2 = z2_sq;
drop_index = 0;
drop_term1 = 1;
drop_term2 = 1;
drop_step1 = z1_sq;
drop_step2 = z2_sq;
window1 = 0;
window2 = 0;
t = 0;
lower = 1;
upper = 0;
rhs = (limit + 1);
while (((upper + 1) * (upper + 2)) <= rhs) {
upper = (upper + 1);
}
while (lower <= upper) {
while (add_index <= upper) {
window1 = (window1 + add_term1);
if (window1 >= MOD) {
window1 = (window1 - MOD);
}
window2 = (window2 + add_term2);
if (window2 >= MOD) {
window2 = (window2 - MOD);
}
add_term1 = mulmod_i64_i64(add_term1, add_step1);
add_step1 = mulmod_i64_i64(add_step1, z1_sq);
add_term2 = mulmod_i64_i64(add_term2, add_step2);
add_step2 = mulmod_i64_i64(add_step2, z2_sq);
add_index = (add_index + 1);
}
while (drop_index < lower) {
window1 = (window1 - drop_term1);
if (window1 < 0) {
window1 = (window1 + MOD);
}
window2 = (window2 - drop_term2);
if (window2 < 0) {
window2 = (window2 + MOD);
}
drop_term1 = mulmod_i64_i64(drop_term1, drop_step1);
drop_step1 = mulmod_i64_i64(drop_step1, z1_sq);
drop_term2 = mulmod_i64_i64(drop_term2, drop_step2);
drop_step2 = mulmod_i64_i64(drop_step2, z2_sq);
drop_index = (drop_index + 1);
}
total1 = FLOW_CHECKED_MOD(((total1 + mulmod_i64_i64(window1, odd_weight1))), (MOD));
total2 = FLOW_CHECKED_MOD(((total2 + mulmod_i64_i64(window2, odd_weight2))), (MOD));
odd_weight1 = mulmod_i64_i64(odd_weight1, odd_delta1);
odd_delta1 = mulmod_i64_i64(odd_delta1, z1_inv_10);
odd_weight2 = mulmod_i64_i64(odd_weight2, odd_delta2);
odd_delta2 = mulmod_i64_i64(odd_delta2, z2_inv_10);
rhs = ((rhs + (10 * t)) + 10);
t = (t + 1);
lower = (lower + 3);
while (((upper + 1) * (upper + 2)) <= rhs) {
upper = (upper + 1);
}
}
out1[0] = total1;
out2[0] = total2;
}
int32_t main(void) {
int32_t* sv = (int32_t*)(calloc(MAX_SMALL, 4));
int32_t svc = build_small_values_ptr_i32(sv);
int64_t limit = TARGET_LIMIT;
int64_t root = isqrt_i64_i64(limit);
int8_t* mu = (int8_t*)(mobius_sieve_i64(root));
int64_t sqrt5_mod = tonelli_shanks_i64_i64(5, MOD);
int64_t inv_sqrt5_mod = mod_pow_i64_i64(sqrt5_mod, (MOD - 2));
int64_t inv2_mod = FLOW_CHECKED_DIV(((MOD + 1)), (2));
int64_t phi_mod = mulmod_i64_i64(FLOW_CHECKED_MOD(((1 + sqrt5_mod)), (MOD)), inv2_mod);
int64_t phi_inv_mod = mod_pow_i64_i64(phi_mod, (MOD - 2));
int64_t phi_sq_mod = mulmod_i64_i64(phi_mod, phi_mod);
int64_t phi_inv_sq_mod = mulmod_i64_i64(phi_inv_mod, phi_inv_mod);
int64_t p_phi = 0;
int64_t p_psi = 0;
int64_t phi_pow_g2 = 1;
int64_t phi_inv_pow_g2 = 1;
int64_t forward_step = phi_mod;
int64_t backward_step = phi_inv_mod;
int64_t g_square = 1;
int64_t* np_phi = (int64_t*)(calloc(1, 8));
int64_t* np_psi = (int64_t*)(calloc(1, 8));
int64_t g = 1;
while (g <= root) {
phi_pow_g2 = mulmod_i64_i64(phi_pow_g2, forward_step);
forward_step = mulmod_i64_i64(forward_step, phi_sq_mod);
phi_inv_pow_g2 = mulmod_i64_i64(phi_inv_pow_g2, backward_step);
backward_step = mulmod_i64_i64(backward_step, phi_inv_sq_mod);
int8_t mu_g = mu[g];
if (mu_g != 0) {
int64_t scaled_limit = FLOW_CHECKED_DIV((limit), (g_square));
int64_t psi_pow_g2;
int64_t psi_inv_pow_g2;
if ((g & 1) != 0) {
psi_pow_g2 = (MOD - phi_inv_pow_g2);
psi_inv_pow_g2 = (MOD - phi_pow_g2);
} else {
psi_pow_g2 = phi_inv_pow_g2;
psi_inv_pow_g2 = phi_pow_g2;
}
nonprimitive_pair_i64_i64_i64_i64_i64_ptr_i32_i32_ptr_i64_ptr_i64(scaled_limit, phi_pow_g2, phi_inv_pow_g2, psi_pow_g2, psi_inv_pow_g2, sv, svc, np_phi, np_psi);
if (mu_g == 1) {
p_phi = (p_phi + np_phi[0]);
if (p_phi >= MOD) {
p_phi = (p_phi - MOD);
}
p_psi = (p_psi + np_psi[0]);
if (p_psi >= MOD) {
p_psi = (p_psi - MOD);
}
} else {
p_phi = (p_phi - np_phi[0]);
if (p_phi < 0) {
p_phi = (p_phi + MOD);
}
p_psi = (p_psi - np_psi[0]);
if (p_psi < 0) {
p_psi = (p_psi + MOD);
}
}
}
g_square = ((g_square + (2 * g)) + 1);
g = (g + 1);
}
free(((void*)(mu)));
free(((void*)(sv)));
free(((void*)(np_phi)));
free(((void*)(np_psi)));
printf("%lld\n", mulmod_i64_i64(FLOW_CHECKED_MOD((((p_phi - p_psi) + MOD)), (MOD)), inv_sqrt5_mod));
return 0;
}
Generated MLIR
module {
llvm.func @printf(!llvm.ptr, ...) -> i32
llvm.mlir.global internal constant @str_0("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
func.func private @calloc(i64, i64) -> !llvm.ptr
func.func private @free(!llvm.ptr) -> ()
func.func private @memset(!llvm.ptr, i32, i64) -> !llvm.ptr
func.func private @sqrt(f64) -> f64
// Constant: MOD
llvm.mlir.global internal constant @MOD(1000000009 : i64) : i64
// Constant: TARGET_LIMIT
llvm.mlir.global internal constant @TARGET_LIMIT(100000000000000 : i64) : i64
// Constant: SMALL_LIMIT
llvm.mlir.global internal constant @SMALL_LIMIT(8 : i64) : i64
func.func @mulmod(%arg0: i64, %arg1: i64) -> i64 {
%0 = arith.muli %arg0, %arg1 : i64
%1 = llvm.mlir.addressof @MOD : !llvm.ptr
%2 = llvm.load %1 : !llvm.ptr -> i64
%3 = arith.remsi %0, %2 : i64
func.return %3 : i64
}
func.func @mod_pow(%arg0: i64, %arg1: i64) -> i64 {
%4 = llvm.mlir.addressof @MOD : !llvm.ptr
%5 = llvm.load %4 : !llvm.ptr -> i64
%6 = arith.remsi %arg0, %5 : i64
%7 = llvm.mlir.constant(1 : i64) : i64
%8 = llvm.alloca %7 x i64 : (i64) -> !llvm.ptr
llvm.store %6, %8 : i64, !llvm.ptr
%9 = llvm.load %8 : !llvm.ptr -> i64
%10 = arith.constant 0 : i32
%12 = arith.extsi %10 : i32 to i64
%11 = arith.cmpi slt, %9, %12 : i64
cf.cond_br %11, ^bb0, ^bb1
^bb0:
%13 = llvm.load %8 : !llvm.ptr -> i64
%14 = llvm.mlir.addressof @MOD : !llvm.ptr
%15 = llvm.load %14 : !llvm.ptr -> i64
%16 = arith.addi %13, %15 : i64
llvm.store %16, %8 : i64, !llvm.ptr
cf.br ^bb2
^bb1:
cf.br ^bb2
^bb2:
%17 = arith.constant 1 : i32
%18 = arith.extsi %17 : i32 to i64
%19 = llvm.mlir.constant(1 : i64) : i64
%20 = llvm.alloca %19 x i64 : (i64) -> !llvm.ptr
llvm.store %18, %20 : i64, !llvm.ptr
%21 = llvm.mlir.constant(1 : i64) : i64
%22 = llvm.alloca %21 x i64 : (i64) -> !llvm.ptr
llvm.store %arg1, %22 : i64, !llvm.ptr
cf.br ^bb3
^bb3:
%23 = llvm.load %22 : !llvm.ptr -> i64
%24 = arith.constant 0 : i32
%26 = arith.extsi %24 : i32 to i64
%25 = arith.cmpi sgt, %23, %26 : i64
cf.cond_br %25, ^bb4, ^bb5
^bb4:
%27 = llvm.load %22 : !llvm.ptr -> i64
%28 = arith.constant 1 : i32
%30 = arith.extsi %28 : i32 to i64
%29 = arith.andi %27, %30 : i64
%31 = arith.constant 0 : i32
%33 = arith.extsi %31 : i32 to i64
%32 = arith.cmpi ne, %29, %33 : i64
cf.cond_br %32, ^bb6, ^bb7
^bb6:
%35 = llvm.load %20 : !llvm.ptr -> i64
%36 = llvm.load %8 : !llvm.ptr -> i64
%34 = func.call @mulmod(%35, %36) : (i64, i64) -> i64
llvm.store %34, %20 : i64, !llvm.ptr
cf.br ^bb8
^bb7:
cf.br ^bb8
^bb8:
%38 = llvm.load %8 : !llvm.ptr -> i64
%39 = llvm.load %8 : !llvm.ptr -> i64
%37 = func.call @mulmod(%38, %39) : (i64, i64) -> i64
llvm.store %37, %8 : i64, !llvm.ptr
%40 = llvm.load %22 : !llvm.ptr -> i64
%41 = arith.constant 1 : i32
%43 = arith.extsi %41 : i32 to i64
%42 = arith.shrsi %40, %43 : i64
llvm.store %42, %22 : i64, !llvm.ptr
cf.br ^bb3
^bb5:
%44 = llvm.load %20 : !llvm.ptr -> i64
func.return %44 : i64
}
func.func @tonelli_shanks(%arg0: i64, %arg1: i64) -> i64 {
%45 = arith.remsi %arg0, %arg1 : i64
%46 = arith.constant 0 : i32
%48 = arith.extsi %46 : i32 to i64
%47 = arith.cmpi eq, %45, %48 : i64
cf.cond_br %47, ^bb9, ^bb10
^bb9:
%49 = arith.constant 0 : i32
%50 = arith.extsi %49 : i32 to i64
func.return %50 : i64
^bb10:
cf.br ^bb11
^bb11:
%52 = arith.constant 1 : i32
%54 = arith.extsi %52 : i32 to i64
%53 = arith.subi %arg1, %54 : i64
%55 = arith.constant 2 : i32
%57 = arith.extsi %55 : i32 to i64
%56 = arith.divsi %53, %57 : i64
%51 = func.call @mod_pow(%45, %56) : (i64, i64) -> i64
%58 = arith.constant 1 : i32
%60 = arith.extsi %58 : i32 to i64
%59 = arith.cmpi ne, %51, %60 : i64
cf.cond_br %59, ^bb12, ^bb13
^bb12:
%61 = arith.constant 1 : i32
%63 = arith.constant 0 : i32
%62 = arith.subi %63, %61 : i32
%64 = arith.extsi %62 : i32 to i64
func.return %64 : i64
^bb13:
cf.br ^bb14
^bb14:
%65 = arith.constant 4 : i32
%67 = arith.extsi %65 : i32 to i64
%66 = arith.remsi %arg1, %67 : i64
%68 = arith.constant 3 : i32
%70 = arith.extsi %68 : i32 to i64
%69 = arith.cmpi eq, %66, %70 : i64
cf.cond_br %69, ^bb15, ^bb16
^bb15:
%72 = arith.constant 1 : i32
%74 = arith.extsi %72 : i32 to i64
%73 = arith.addi %arg1, %74 : i64
%75 = arith.constant 4 : i32
%77 = arith.extsi %75 : i32 to i64
%76 = arith.divsi %73, %77 : i64
%71 = func.call @mod_pow(%45, %76) : (i64, i64) -> i64
func.return %71 : i64
^bb16:
cf.br ^bb17
^bb17:
%78 = arith.constant 1 : i32
%80 = arith.extsi %78 : i32 to i64
%79 = arith.subi %arg1, %80 : i64
%81 = llvm.mlir.constant(1 : i64) : i64
%82 = llvm.alloca %81 x i64 : (i64) -> !llvm.ptr
llvm.store %79, %82 : i64, !llvm.ptr
%83 = arith.constant 0 : i32
%84 = arith.extsi %83 : i32 to i64
%85 = llvm.mlir.constant(1 : i64) : i64
%86 = llvm.alloca %85 x i64 : (i64) -> !llvm.ptr
llvm.store %84, %86 : i64, !llvm.ptr
cf.br ^bb18
^bb18:
%87 = llvm.load %82 : !llvm.ptr -> i64
%88 = arith.constant 2 : i32
%90 = arith.extsi %88 : i32 to i64
%89 = arith.remsi %87, %90 : i64
%91 = arith.constant 0 : i32
%93 = arith.extsi %91 : i32 to i64
%92 = arith.cmpi eq, %89, %93 : i64
cf.cond_br %92, ^bb19, ^bb20
^bb19:
%94 = llvm.load %82 : !llvm.ptr -> i64
%95 = arith.constant 2 : i32
%97 = arith.extsi %95 : i32 to i64
%96 = arith.divsi %94, %97 : i64
llvm.store %96, %82 : i64, !llvm.ptr
%98 = llvm.load %86 : !llvm.ptr -> i64
%99 = arith.constant 1 : i32
%101 = arith.extsi %99 : i32 to i64
%100 = arith.addi %98, %101 : i64
llvm.store %100, %86 : i64, !llvm.ptr
cf.br ^bb18
^bb20:
%102 = arith.constant 2 : i32
%103 = arith.extsi %102 : i32 to i64
%104 = llvm.mlir.constant(1 : i64) : i64
%105 = llvm.alloca %104 x i64 : (i64) -> !llvm.ptr
llvm.store %103, %105 : i64, !llvm.ptr
cf.br ^bb21
^bb21:
%107 = llvm.load %105 : !llvm.ptr -> i64
%108 = arith.constant 1 : i32
%110 = arith.extsi %108 : i32 to i64
%109 = arith.subi %arg1, %110 : i64
%111 = arith.constant 2 : i32
%113 = arith.extsi %111 : i32 to i64
%112 = arith.divsi %109, %113 : i64
%106 = func.call @mod_pow(%107, %112) : (i64, i64) -> i64
%114 = arith.constant 1 : i32
%116 = arith.extsi %114 : i32 to i64
%115 = arith.subi %arg1, %116 : i64
%117 = arith.cmpi ne, %106, %115 : i64
cf.cond_br %117, ^bb22, ^bb23
^bb22:
%118 = llvm.load %105 : !llvm.ptr -> i64
%119 = arith.constant 1 : i32
%121 = arith.extsi %119 : i32 to i64
%120 = arith.addi %118, %121 : i64
llvm.store %120, %105 : i64, !llvm.ptr
cf.br ^bb21
^bb23:
%122 = llvm.load %86 : !llvm.ptr -> i64
%123 = llvm.mlir.constant(1 : i64) : i64
%124 = llvm.alloca %123 x i64 : (i64) -> !llvm.ptr
llvm.store %122, %124 : i64, !llvm.ptr
%126 = llvm.load %105 : !llvm.ptr -> i64
%127 = llvm.load %82 : !llvm.ptr -> i64
%125 = func.call @mod_pow(%126, %127) : (i64, i64) -> i64
%128 = llvm.mlir.constant(1 : i64) : i64
%129 = llvm.alloca %128 x i64 : (i64) -> !llvm.ptr
llvm.store %125, %129 : i64, !llvm.ptr
%131 = llvm.load %82 : !llvm.ptr -> i64
%130 = func.call @mod_pow(%45, %131) : (i64, i64) -> i64
%132 = llvm.mlir.constant(1 : i64) : i64
%133 = llvm.alloca %132 x i64 : (i64) -> !llvm.ptr
llvm.store %130, %133 : i64, !llvm.ptr
%135 = llvm.load %82 : !llvm.ptr -> i64
%136 = arith.constant 1 : i32
%138 = arith.extsi %136 : i32 to i64
%137 = arith.addi %135, %138 : i64
%139 = arith.constant 2 : i32
%141 = arith.extsi %139 : i32 to i64
%140 = arith.divsi %137, %141 : i64
%134 = func.call @mod_pow(%45, %140) : (i64, i64) -> i64
%142 = llvm.mlir.constant(1 : i64) : i64
%143 = llvm.alloca %142 x i64 : (i64) -> !llvm.ptr
llvm.store %134, %143 : i64, !llvm.ptr
cf.br ^bb24
^bb24:
%144 = llvm.load %133 : !llvm.ptr -> i64
%145 = arith.constant 1 : i32
%147 = arith.extsi %145 : i32 to i64
%146 = arith.cmpi ne, %144, %147 : i64
cf.cond_br %146, ^bb25, ^bb26
^bb25:
%148 = arith.constant 1 : i32
%149 = arith.extsi %148 : i32 to i64
%150 = llvm.mlir.constant(1 : i64) : i64
%151 = llvm.alloca %150 x i64 : (i64) -> !llvm.ptr
llvm.store %149, %151 : i64, !llvm.ptr
%153 = llvm.load %133 : !llvm.ptr -> i64
%154 = llvm.load %133 : !llvm.ptr -> i64
%152 = func.call @mulmod(%153, %154) : (i64, i64) -> i64
%155 = llvm.mlir.constant(1 : i64) : i64
%156 = llvm.alloca %155 x i64 : (i64) -> !llvm.ptr
llvm.store %152, %156 : i64, !llvm.ptr
cf.br ^bb27
^bb27:
%157 = llvm.load %156 : !llvm.ptr -> i64
%158 = arith.constant 1 : i32
%160 = arith.extsi %158 : i32 to i64
%159 = arith.cmpi ne, %157, %160 : i64
cf.cond_br %159, ^bb28, ^bb29
^bb28:
%162 = llvm.load %156 : !llvm.ptr -> i64
%163 = llvm.load %156 : !llvm.ptr -> i64
%161 = func.call @mulmod(%162, %163) : (i64, i64) -> i64
llvm.store %161, %156 : i64, !llvm.ptr
%164 = llvm.load %151 : !llvm.ptr -> i64
%165 = arith.constant 1 : i32
%167 = arith.extsi %165 : i32 to i64
%166 = arith.addi %164, %167 : i64
llvm.store %166, %151 : i64, !llvm.ptr
cf.br ^bb27
^bb29:
%169 = llvm.load %129 : !llvm.ptr -> i64
%170 = arith.constant 1 : i32
%171 = arith.extsi %170 : i32 to i64
%172 = llvm.load %124 : !llvm.ptr -> i64
%173 = llvm.load %151 : !llvm.ptr -> i64
%174 = arith.subi %172, %173 : i64
%175 = arith.constant 1 : i32
%177 = arith.extsi %175 : i32 to i64
%176 = arith.subi %174, %177 : i64
%178 = arith.shli %171, %176 : i64
%168 = func.call @mod_pow(%169, %178) : (i64, i64) -> i64
%180 = llvm.load %143 : !llvm.ptr -> i64
%179 = func.call @mulmod(%180, %168) : (i64, i64) -> i64
llvm.store %179, %143 : i64, !llvm.ptr
%181 = func.call @mulmod(%168, %168) : (i64, i64) -> i64
llvm.store %181, %129 : i64, !llvm.ptr
%183 = llvm.load %133 : !llvm.ptr -> i64
%184 = llvm.load %129 : !llvm.ptr -> i64
%182 = func.call @mulmod(%183, %184) : (i64, i64) -> i64
llvm.store %182, %133 : i64, !llvm.ptr
%185 = llvm.load %151 : !llvm.ptr -> i64
llvm.store %185, %124 : i64, !llvm.ptr
cf.br ^bb24
^bb26:
%186 = llvm.load %143 : !llvm.ptr -> i64
func.return %186 : i64
}
func.func @isqrt_i64(%arg0: i64) -> i64 {
%187 = arith.constant 0 : i32
%189 = arith.extsi %187 : i32 to i64
%188 = arith.cmpi sle, %arg0, %189 : i64
cf.cond_br %188, ^bb30, ^bb31
^bb30:
%190 = arith.constant 0 : i32
%191 = arith.extsi %190 : i32 to i64
func.return %191 : i64
^bb31:
cf.br ^bb32
^bb32:
%192 = arith.sitofp %arg0 : i64 to f64
%193 = math.sqrt %192 : f64
%194 = arith.fptosi %193 : f64 to i64
%195 = llvm.mlir.constant(1 : i64) : i64
%196 = llvm.alloca %195 x i64 : (i64) -> !llvm.ptr
llvm.store %194, %196 : i64, !llvm.ptr
cf.br ^bb33
^bb33:
%197 = llvm.load %196 : !llvm.ptr -> i64
%198 = arith.constant 0 : i32
%200 = arith.extsi %198 : i32 to i64
%199 = arith.cmpi sgt, %197, %200 : i64
%201 = scf.if %199 -> (i1) {
%202 = llvm.load %196 : !llvm.ptr -> i64
%203 = llvm.load %196 : !llvm.ptr -> i64
%204 = arith.muli %202, %203 : i64
%205 = arith.cmpi sgt, %204, %arg0 : i64
scf.yield %205 : i1
} else {
%206 = arith.constant false
scf.yield %206 : i1
}
cf.cond_br %201, ^bb34, ^bb35
^bb34:
%207 = llvm.load %196 : !llvm.ptr -> i64
%208 = arith.constant 1 : i32
%210 = arith.extsi %208 : i32 to i64
%209 = arith.subi %207, %210 : i64
llvm.store %209, %196 : i64, !llvm.ptr
cf.br ^bb33
^bb35:
cf.br ^bb36
^bb36:
%211 = llvm.load %196 : !llvm.ptr -> i64
%212 = arith.constant 1 : i32
%214 = arith.extsi %212 : i32 to i64
%213 = arith.addi %211, %214 : i64
%215 = llvm.load %196 : !llvm.ptr -> i64
%216 = arith.constant 1 : i32
%218 = arith.extsi %216 : i32 to i64
%217 = arith.addi %215, %218 : i64
%219 = arith.muli %213, %217 : i64
%220 = arith.cmpi sle, %219, %arg0 : i64
cf.cond_br %220, ^bb37, ^bb38
^bb37:
%221 = llvm.load %196 : !llvm.ptr -> i64
%222 = arith.constant 1 : i32
%224 = arith.extsi %222 : i32 to i64
%223 = arith.addi %221, %224 : i64
llvm.store %223, %196 : i64, !llvm.ptr
cf.br ^bb36
^bb38:
%225 = llvm.load %196 : !llvm.ptr -> i64
func.return %225 : i64
}
func.func @mobius_sieve(%arg0: i64) -> !llvm.ptr {
%227 = arith.constant 1 : i32
%229 = arith.extsi %227 : i32 to i64
%228 = arith.addi %arg0, %229 : i64
%230 = arith.constant 1 : i32
%231 = arith.extsi %230 : i32 to i64
%226 = func.call @calloc(%228, %231) : (i64, i64) -> !llvm.ptr
%233 = arith.constant 1 : i32
%234 = arith.constant 1 : i32
%236 = arith.extsi %234 : i32 to i64
%235 = arith.addi %arg0, %236 : i64
%232 = func.call @memset(%226, %233, %235) : (!llvm.ptr, i32, i64) -> !llvm.ptr
%238 = arith.constant 1 : i32
%240 = arith.extsi %238 : i32 to i64
%239 = arith.addi %arg0, %240 : i64
%241 = arith.constant 1 : i32
%242 = arith.extsi %241 : i32 to i64
%237 = func.call @calloc(%239, %242) : (i64, i64) -> !llvm.ptr
%244 = arith.constant 1 : i32
%245 = arith.constant 1 : i32
%247 = arith.extsi %245 : i32 to i64
%246 = arith.addi %arg0, %247 : i64
%243 = func.call @memset(%237, %244, %246) : (!llvm.ptr, i32, i64) -> !llvm.ptr
%248 = arith.constant 0 : i32
%250 = arith.extsi %248 : i32 to i64
%249 = arith.cmpi sge, %arg0, %250 : i64
cf.cond_br %249, ^bb39, ^bb40
^bb39:
%251 = arith.constant 0 : i32
%252 = arith.constant 0 : i32
%253 = arith.trunci %251 : i32 to i8
%254 = arith.extsi %252 : i32 to i64
%255 = llvm.getelementptr %237[%254] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %253, %255 : i8, !llvm.ptr
cf.br ^bb41
^bb40:
cf.br ^bb41
^bb41:
%256 = arith.constant 1 : i32
%258 = arith.extsi %256 : i32 to i64
%257 = arith.cmpi sge, %arg0, %258 : i64
cf.cond_br %257, ^bb42, ^bb43
^bb42:
%259 = arith.constant 0 : i32
%260 = arith.constant 1 : i32
%261 = arith.trunci %259 : i32 to i8
%262 = arith.extsi %260 : i32 to i64
%263 = llvm.getelementptr %237[%262] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %261, %263 : i8, !llvm.ptr
cf.br ^bb44
^bb43:
cf.br ^bb44
^bb44:
%264 = arith.constant 2 : i32
%265 = arith.extsi %264 : i32 to i64
%266 = llvm.mlir.constant(1 : i64) : i64
%267 = llvm.alloca %266 x i64 : (i64) -> !llvm.ptr
llvm.store %265, %267 : i64, !llvm.ptr
cf.br ^bb45
^bb45:
%268 = llvm.load %267 : !llvm.ptr -> i64
%269 = arith.cmpi sle, %268, %arg0 : i64
cf.cond_br %269, ^bb46, ^bb47
^bb46:
%271 = llvm.load %267 : !llvm.ptr -> i64
%272 = llvm.getelementptr %237[%271] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%270 = llvm.load %272 : !llvm.ptr -> i8
%273 = arith.constant 0 : i32
%275 = arith.extsi %270 : i8 to i32
%274 = arith.cmpi eq, %275, %273 : i32
cf.cond_br %274, ^bb48, ^bb49
^bb48:
%276 = llvm.load %267 : !llvm.ptr -> i64
%277 = arith.constant 1 : i32
%279 = arith.extsi %277 : i32 to i64
%278 = arith.addi %276, %279 : i64
llvm.store %278, %267 : i64, !llvm.ptr
cf.br ^bb45
^bb49:
cf.br ^bb50
^bb50:
%280 = llvm.load %267 : !llvm.ptr -> i64
%281 = llvm.mlir.constant(1 : i64) : i64
%282 = llvm.alloca %281 x i64 : (i64) -> !llvm.ptr
llvm.store %280, %282 : i64, !llvm.ptr
cf.br ^bb51
^bb51:
%283 = llvm.load %282 : !llvm.ptr -> i64
%284 = arith.cmpi sle, %283, %arg0 : i64
cf.cond_br %284, ^bb52, ^bb53
^bb52:
%286 = llvm.load %282 : !llvm.ptr -> i64
%287 = llvm.getelementptr %226[%286] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%285 = llvm.load %287 : !llvm.ptr -> i8
%289 = arith.constant 0 : i8
%288 = arith.subi %289, %285 : i8
%290 = llvm.load %282 : !llvm.ptr -> i64
%291 = llvm.getelementptr %226[%290] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %288, %291 : i8, !llvm.ptr
%292 = llvm.load %282 : !llvm.ptr -> i64
%293 = llvm.load %267 : !llvm.ptr -> i64
%294 = arith.addi %292, %293 : i64
llvm.store %294, %282 : i64, !llvm.ptr
cf.br ^bb51
^bb53:
%295 = llvm.load %267 : !llvm.ptr -> i64
%296 = llvm.load %267 : !llvm.ptr -> i64
%297 = arith.muli %295, %296 : i64
%298 = arith.cmpi sle, %297, %arg0 : i64
cf.cond_br %298, ^bb54, ^bb55
^bb54:
%299 = llvm.mlir.constant(1 : i64) : i64
%300 = llvm.alloca %299 x i64 : (i64) -> !llvm.ptr
llvm.store %297, %300 : i64, !llvm.ptr
cf.br ^bb57
^bb57:
%301 = llvm.load %300 : !llvm.ptr -> i64
%302 = arith.cmpi sle, %301, %arg0 : i64
cf.cond_br %302, ^bb58, ^bb59
^bb58:
%303 = arith.constant 0 : i32
%304 = llvm.load %300 : !llvm.ptr -> i64
%305 = arith.trunci %303 : i32 to i8
%306 = llvm.getelementptr %226[%304] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %305, %306 : i8, !llvm.ptr
%307 = llvm.load %300 : !llvm.ptr -> i64
%308 = arith.addi %307, %297 : i64
llvm.store %308, %300 : i64, !llvm.ptr
cf.br ^bb57
^bb59:
%309 = llvm.mlir.constant(1 : i64) : i64
%310 = llvm.alloca %309 x i64 : (i64) -> !llvm.ptr
llvm.store %297, %310 : i64, !llvm.ptr
cf.br ^bb60
^bb60:
%311 = llvm.load %310 : !llvm.ptr -> i64
%312 = arith.cmpi sle, %311, %arg0 : i64
cf.cond_br %312, ^bb61, ^bb62
^bb61:
%313 = arith.constant 0 : i32
%314 = llvm.load %310 : !llvm.ptr -> i64
%315 = arith.trunci %313 : i32 to i8
%316 = llvm.getelementptr %237[%314] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %315, %316 : i8, !llvm.ptr
%317 = llvm.load %310 : !llvm.ptr -> i64
%318 = llvm.load %267 : !llvm.ptr -> i64
%319 = arith.addi %317, %318 : i64
llvm.store %319, %310 : i64, !llvm.ptr
cf.br ^bb60
^bb62:
cf.br ^bb56
^bb55:
cf.br ^bb56
^bb56:
%320 = llvm.load %267 : !llvm.ptr -> i64
%321 = llvm.load %267 : !llvm.ptr -> i64
%322 = arith.addi %320, %321 : i64
%323 = llvm.mlir.constant(1 : i64) : i64
%324 = llvm.alloca %323 x i64 : (i64) -> !llvm.ptr
llvm.store %322, %324 : i64, !llvm.ptr
cf.br ^bb63
^bb63:
%325 = llvm.load %324 : !llvm.ptr -> i64
%326 = arith.cmpi sle, %325, %arg0 : i64
cf.cond_br %326, ^bb64, ^bb65
^bb64:
%327 = arith.constant 0 : i32
%328 = llvm.load %324 : !llvm.ptr -> i64
%329 = arith.trunci %327 : i32 to i8
%330 = llvm.getelementptr %237[%328] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %329, %330 : i8, !llvm.ptr
%331 = llvm.load %324 : !llvm.ptr -> i64
%332 = llvm.load %267 : !llvm.ptr -> i64
%333 = arith.addi %331, %332 : i64
llvm.store %333, %324 : i64, !llvm.ptr
cf.br ^bb63
^bb65:
%334 = llvm.load %267 : !llvm.ptr -> i64
%335 = arith.constant 1 : i32
%337 = arith.extsi %335 : i32 to i64
%336 = arith.addi %334, %337 : i64
llvm.store %336, %267 : i64, !llvm.ptr
cf.br ^bb45
^bb47:
func.call @free(%237) : (!llvm.ptr) -> ()
func.return %226 : !llvm.ptr
}
// Constant: MAX_SMALL
llvm.mlir.global internal constant @MAX_SMALL(16 : i32) : i32
func.func @build_small_values(%arg0: !llvm.ptr) -> i32 {
%339 = arith.constant 2 : i32
%341 = llvm.mlir.addressof @SMALL_LIMIT : !llvm.ptr
%342 = llvm.load %341 : !llvm.ptr -> i64
%340 = func.call @isqrt_i64(%342) : (i64) -> i64
%344 = arith.extsi %339 : i32 to i64
%343 = arith.muli %344, %340 : i64
%345 = arith.constant 2 : i32
%347 = arith.extsi %345 : i32 to i64
%346 = arith.addi %343, %347 : i64
%348 = arith.trunci %346 : i64 to i32
%349 = arith.constant 0 : i32
%350 = llvm.mlir.constant(1 : i64) : i64
%351 = llvm.alloca %350 x i32 : (i64) -> !llvm.ptr
llvm.store %349, %351 : i32, !llvm.ptr
%352 = arith.constant 2 : i32
%353 = llvm.mlir.constant(1 : i64) : i64
%354 = llvm.alloca %353 x i32 : (i64) -> !llvm.ptr
llvm.store %352, %354 : i32, !llvm.ptr
cf.br ^bb66
^bb66:
%355 = llvm.load %354 : !llvm.ptr -> i32
%356 = arith.cmpi sle, %355, %348 : i32
cf.cond_br %356, ^bb67, ^bb68
^bb67:
%357 = arith.constant 1 : i32
%358 = llvm.mlir.constant(1 : i64) : i64
%359 = llvm.alloca %358 x i32 : (i64) -> !llvm.ptr
llvm.store %357, %359 : i32, !llvm.ptr
cf.br ^bb69
^bb69:
%360 = llvm.load %359 : !llvm.ptr -> i32
%361 = llvm.load %354 : !llvm.ptr -> i32
%362 = arith.constant 2 : i32
%363 = arith.divsi %361, %362 : i32
%364 = arith.cmpi sle, %360, %363 : i32
cf.cond_br %364, ^bb70, ^bb71
^bb70:
%365 = llvm.load %354 : !llvm.ptr -> i32
%366 = llvm.load %354 : !llvm.ptr -> i32
%367 = arith.muli %365, %366 : i32
%368 = llvm.load %354 : !llvm.ptr -> i32
%369 = llvm.load %359 : !llvm.ptr -> i32
%370 = arith.muli %368, %369 : i32
%371 = arith.subi %367, %370 : i32
%372 = llvm.load %359 : !llvm.ptr -> i32
%373 = llvm.load %359 : !llvm.ptr -> i32
%374 = arith.muli %372, %373 : i32
%375 = arith.subi %371, %374 : i32
%376 = arith.constant 0 : i32
%377 = arith.cmpi sgt, %375, %376 : i32
%378 = scf.if %377 -> (i1) {
%379 = llvm.mlir.addressof @SMALL_LIMIT : !llvm.ptr
%380 = llvm.load %379 : !llvm.ptr -> i64
%381 = arith.trunci %380 : i64 to i32
%382 = arith.cmpi sle, %375, %381 : i32
scf.yield %382 : i1
} else {
%383 = arith.constant false
scf.yield %383 : i1
}
cf.cond_br %378, ^bb72, ^bb73
^bb72:
%384 = llvm.load %351 : !llvm.ptr -> i32
%385 = arith.extsi %384 : i32 to i64
%386 = llvm.getelementptr %arg0[%385] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %375, %386 : i32, !llvm.ptr
%387 = llvm.load %351 : !llvm.ptr -> i32
%388 = arith.constant 1 : i32
%389 = arith.addi %387, %388 : i32
llvm.store %389, %351 : i32, !llvm.ptr
cf.br ^bb74
^bb73:
cf.br ^bb74
^bb74:
%390 = llvm.load %359 : !llvm.ptr -> i32
%391 = arith.constant 1 : i32
%392 = arith.addi %390, %391 : i32
llvm.store %392, %359 : i32, !llvm.ptr
cf.br ^bb69
^bb71:
%393 = llvm.load %354 : !llvm.ptr -> i32
%394 = arith.constant 1 : i32
%395 = arith.addi %393, %394 : i32
llvm.store %395, %354 : i32, !llvm.ptr
cf.br ^bb66
^bb68:
%396 = arith.constant 0 : i32
%397 = llvm.mlir.constant(1 : i64) : i64
%398 = llvm.alloca %397 x i32 : (i64) -> !llvm.ptr
llvm.store %396, %398 : i32, !llvm.ptr
cf.br ^bb75
^bb75:
%399 = llvm.load %398 : !llvm.ptr -> i32
%400 = llvm.load %351 : !llvm.ptr -> i32
%401 = arith.cmpi slt, %399, %400 : i32
cf.cond_br %401, ^bb76, ^bb77
^bb76:
%402 = llvm.load %398 : !llvm.ptr -> i32
%403 = arith.constant 1 : i32
%404 = arith.addi %402, %403 : i32
%405 = llvm.mlir.constant(1 : i64) : i64
%406 = llvm.alloca %405 x i32 : (i64) -> !llvm.ptr
llvm.store %404, %406 : i32, !llvm.ptr
cf.br ^bb78
^bb78:
%407 = llvm.load %406 : !llvm.ptr -> i32
%408 = llvm.load %351 : !llvm.ptr -> i32
%409 = arith.cmpi slt, %407, %408 : i32
cf.cond_br %409, ^bb79, ^bb80
^bb79:
%411 = llvm.load %406 : !llvm.ptr -> i32
%412 = arith.extsi %411 : i32 to i64
%413 = llvm.getelementptr %arg0[%412] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%410 = llvm.load %413 : !llvm.ptr -> i32
%415 = llvm.load %398 : !llvm.ptr -> i32
%416 = arith.extsi %415 : i32 to i64
%417 = llvm.getelementptr %arg0[%416] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%414 = llvm.load %417 : !llvm.ptr -> i32
%418 = arith.cmpi slt, %410, %414 : i32
cf.cond_br %418, ^bb81, ^bb82
^bb81:
%420 = llvm.load %398 : !llvm.ptr -> i32
%421 = arith.extsi %420 : i32 to i64
%422 = llvm.getelementptr %arg0[%421] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%419 = llvm.load %422 : !llvm.ptr -> i32
%424 = llvm.load %406 : !llvm.ptr -> i32
%425 = arith.extsi %424 : i32 to i64
%426 = llvm.getelementptr %arg0[%425] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%423 = llvm.load %426 : !llvm.ptr -> i32
%427 = llvm.load %398 : !llvm.ptr -> i32
%428 = arith.extsi %427 : i32 to i64
%429 = llvm.getelementptr %arg0[%428] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %423, %429 : i32, !llvm.ptr
%430 = llvm.load %406 : !llvm.ptr -> i32
%431 = arith.extsi %430 : i32 to i64
%432 = llvm.getelementptr %arg0[%431] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %419, %432 : i32, !llvm.ptr
cf.br ^bb83
^bb82:
cf.br ^bb83
^bb83:
%433 = llvm.load %406 : !llvm.ptr -> i32
%434 = arith.constant 1 : i32
%435 = arith.addi %433, %434 : i32
llvm.store %435, %406 : i32, !llvm.ptr
cf.br ^bb78
^bb80:
%436 = llvm.load %398 : !llvm.ptr -> i32
%437 = arith.constant 1 : i32
%438 = arith.addi %436, %437 : i32
llvm.store %438, %398 : i32, !llvm.ptr
cf.br ^bb75
^bb77:
%439 = llvm.load %351 : !llvm.ptr -> i32
func.return %439 : i32
}
func.func @eval_small_nonprimitive_pair(%arg0: i64, %arg1: i64, %arg2: i64, %arg3: !llvm.ptr, %arg4: i32, %arg5: !llvm.ptr, %arg6: !llvm.ptr) -> () {
%440 = arith.constant 0 : i32
%441 = arith.extsi %440 : i32 to i64
%442 = llvm.mlir.constant(1 : i64) : i64
%443 = llvm.alloca %442 x i64 : (i64) -> !llvm.ptr
llvm.store %441, %443 : i64, !llvm.ptr
%444 = arith.constant 0 : i32
%445 = arith.extsi %444 : i32 to i64
%446 = llvm.mlir.constant(1 : i64) : i64
%447 = llvm.alloca %446 x i64 : (i64) -> !llvm.ptr
llvm.store %445, %447 : i64, !llvm.ptr
%448 = arith.constant 1 : i32
%449 = arith.extsi %448 : i32 to i64
%450 = llvm.mlir.constant(1 : i64) : i64
%451 = llvm.alloca %450 x i64 : (i64) -> !llvm.ptr
llvm.store %449, %451 : i64, !llvm.ptr
%452 = arith.constant 1 : i32
%453 = arith.extsi %452 : i32 to i64
%454 = llvm.mlir.constant(1 : i64) : i64
%455 = llvm.alloca %454 x i64 : (i64) -> !llvm.ptr
llvm.store %453, %455 : i64, !llvm.ptr
%456 = arith.constant 0 : i32
%457 = arith.extsi %456 : i32 to i64
%458 = llvm.mlir.constant(1 : i64) : i64
%459 = llvm.alloca %458 x i64 : (i64) -> !llvm.ptr
llvm.store %457, %459 : i64, !llvm.ptr
%460 = arith.constant 0 : i32
%461 = llvm.mlir.constant(1 : i64) : i64
%462 = llvm.alloca %461 x i32 : (i64) -> !llvm.ptr
llvm.store %460, %462 : i32, !llvm.ptr
cf.br ^bb84
^bb84:
%463 = llvm.load %462 : !llvm.ptr -> i32
%464 = arith.cmpi slt, %463, %arg4 : i32
cf.cond_br %464, ^bb85, ^bb86
^bb85:
%466 = llvm.load %462 : !llvm.ptr -> i32
%467 = arith.extsi %466 : i32 to i64
%468 = llvm.getelementptr %arg3[%467] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%465 = llvm.load %468 : !llvm.ptr -> i32
%469 = arith.extsi %465 : i32 to i64
%470 = arith.cmpi sgt, %469, %arg0 : i64
cf.cond_br %470, ^bb87, ^bb88
^bb87:
cf.br ^bb86
^bb88:
cf.br ^bb89
^bb89:
cf.br ^bb90
^bb90:
%471 = llvm.load %459 : !llvm.ptr -> i64
%472 = arith.cmpi slt, %471, %469 : i64
cf.cond_br %472, ^bb91, ^bb92
^bb91:
%474 = llvm.load %451 : !llvm.ptr -> i64
%473 = func.call @mulmod(%474, %arg1) : (i64, i64) -> i64
llvm.store %473, %451 : i64, !llvm.ptr
%476 = llvm.load %455 : !llvm.ptr -> i64
%475 = func.call @mulmod(%476, %arg2) : (i64, i64) -> i64
llvm.store %475, %455 : i64, !llvm.ptr
%477 = llvm.load %459 : !llvm.ptr -> i64
%478 = arith.constant 1 : i32
%480 = arith.extsi %478 : i32 to i64
%479 = arith.addi %477, %480 : i64
llvm.store %479, %459 : i64, !llvm.ptr
cf.br ^bb90
^bb92:
%481 = llvm.load %443 : !llvm.ptr -> i64
%482 = llvm.load %451 : !llvm.ptr -> i64
%483 = arith.addi %481, %482 : i64
llvm.store %483, %443 : i64, !llvm.ptr
%484 = llvm.load %443 : !llvm.ptr -> i64
%485 = llvm.mlir.addressof @MOD : !llvm.ptr
%486 = llvm.load %485 : !llvm.ptr -> i64
%487 = arith.cmpi sge, %484, %486 : i64
cf.cond_br %487, ^bb93, ^bb94
^bb93:
%488 = llvm.load %443 : !llvm.ptr -> i64
%489 = llvm.mlir.addressof @MOD : !llvm.ptr
%490 = llvm.load %489 : !llvm.ptr -> i64
%491 = arith.subi %488, %490 : i64
llvm.store %491, %443 : i64, !llvm.ptr
cf.br ^bb95
^bb94:
cf.br ^bb95
^bb95:
%492 = llvm.load %447 : !llvm.ptr -> i64
%493 = llvm.load %455 : !llvm.ptr -> i64
%494 = arith.addi %492, %493 : i64
llvm.store %494, %447 : i64, !llvm.ptr
%495 = llvm.load %447 : !llvm.ptr -> i64
%496 = llvm.mlir.addressof @MOD : !llvm.ptr
%497 = llvm.load %496 : !llvm.ptr -> i64
%498 = arith.cmpi sge, %495, %497 : i64
cf.cond_br %498, ^bb96, ^bb97
^bb96:
%499 = llvm.load %447 : !llvm.ptr -> i64
%500 = llvm.mlir.addressof @MOD : !llvm.ptr
%501 = llvm.load %500 : !llvm.ptr -> i64
%502 = arith.subi %499, %501 : i64
llvm.store %502, %447 : i64, !llvm.ptr
cf.br ^bb98
^bb97:
cf.br ^bb98
^bb98:
%503 = llvm.load %462 : !llvm.ptr -> i32
%504 = arith.constant 1 : i32
%505 = arith.addi %503, %504 : i32
llvm.store %505, %462 : i32, !llvm.ptr
cf.br ^bb84
^bb86:
%506 = llvm.load %443 : !llvm.ptr -> i64
%507 = arith.constant 0 : i32
%508 = arith.extsi %507 : i32 to i64
%509 = llvm.getelementptr %arg5[%508] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %506, %509 : i64, !llvm.ptr
%510 = llvm.load %447 : !llvm.ptr -> i64
%511 = arith.constant 0 : i32
%512 = arith.extsi %511 : i32 to i64
%513 = llvm.getelementptr %arg6[%512] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %510, %513 : i64, !llvm.ptr
func.return
}
func.func @nonprimitive_pair(%arg0: i64, %arg1: i64, %arg2: i64, %arg3: i64, %arg4: i64, %arg5: !llvm.ptr, %arg6: i32, %arg7: !llvm.ptr, %arg8: !llvm.ptr) -> () {
%514 = llvm.mlir.addressof @SMALL_LIMIT : !llvm.ptr
%515 = llvm.load %514 : !llvm.ptr -> i64
%516 = arith.cmpi sle, %arg0, %515 : i64
cf.cond_br %516, ^bb99, ^bb100
^bb99:
func.call @eval_small_nonprimitive_pair(%arg0, %arg1, %arg3, %arg5, %arg6, %arg7, %arg8) : (i64, i64, i64, !llvm.ptr, i32, !llvm.ptr, !llvm.ptr) -> ()
func.return
^bb100:
cf.br ^bb101
^bb101:
%518 = arith.constant 0 : i32
%519 = arith.extsi %518 : i32 to i64
%520 = llvm.mlir.constant(1 : i64) : i64
%521 = llvm.alloca %520 x i64 : (i64) -> !llvm.ptr
llvm.store %519, %521 : i64, !llvm.ptr
%522 = arith.constant 0 : i32
%523 = arith.extsi %522 : i32 to i64
%524 = llvm.mlir.constant(1 : i64) : i64
%525 = llvm.alloca %524 x i64 : (i64) -> !llvm.ptr
llvm.store %523, %525 : i64, !llvm.ptr
%526 = func.call @mulmod(%arg1, %arg1) : (i64, i64) -> i64
%527 = func.call @mulmod(%arg3, %arg3) : (i64, i64) -> i64
%528 = func.call @mulmod(%arg2, %arg2) : (i64, i64) -> i64
%529 = func.call @mulmod(%arg4, %arg4) : (i64, i64) -> i64
%530 = func.call @mulmod(%528, %528) : (i64, i64) -> i64
%531 = func.call @mulmod(%529, %529) : (i64, i64) -> i64
%532 = func.call @mulmod(%530, %arg2) : (i64, i64) -> i64
%533 = func.call @mulmod(%531, %arg4) : (i64, i64) -> i64
%534 = func.call @mulmod(%532, %532) : (i64, i64) -> i64
%535 = func.call @mulmod(%533, %533) : (i64, i64) -> i64
%536 = func.call @mulmod(%534, %532) : (i64, i64) -> i64
%537 = func.call @mulmod(%535, %533) : (i64, i64) -> i64
%538 = llvm.mlir.constant(1 : i64) : i64
%539 = llvm.alloca %538 x i64 : (i64) -> !llvm.ptr
llvm.store %532, %539 : i64, !llvm.ptr
%540 = llvm.mlir.constant(1 : i64) : i64
%541 = llvm.alloca %540 x i64 : (i64) -> !llvm.ptr
llvm.store %533, %541 : i64, !llvm.ptr
%542 = llvm.mlir.constant(1 : i64) : i64
%543 = llvm.alloca %542 x i64 : (i64) -> !llvm.ptr
llvm.store %536, %543 : i64, !llvm.ptr
%544 = llvm.mlir.constant(1 : i64) : i64
%545 = llvm.alloca %544 x i64 : (i64) -> !llvm.ptr
llvm.store %537, %545 : i64, !llvm.ptr
%546 = arith.constant 0 : i32
%547 = arith.extsi %546 : i32 to i64
%548 = llvm.mlir.constant(1 : i64) : i64
%549 = llvm.alloca %548 x i64 : (i64) -> !llvm.ptr
llvm.store %547, %549 : i64, !llvm.ptr
%550 = arith.constant 1 : i32
%551 = arith.extsi %550 : i32 to i64
%552 = llvm.mlir.constant(1 : i64) : i64
%553 = llvm.alloca %552 x i64 : (i64) -> !llvm.ptr
llvm.store %551, %553 : i64, !llvm.ptr
%554 = arith.constant 1 : i32
%555 = arith.extsi %554 : i32 to i64
%556 = llvm.mlir.constant(1 : i64) : i64
%557 = llvm.alloca %556 x i64 : (i64) -> !llvm.ptr
llvm.store %555, %557 : i64, !llvm.ptr
%558 = llvm.mlir.constant(1 : i64) : i64
%559 = llvm.alloca %558 x i64 : (i64) -> !llvm.ptr
llvm.store %arg1, %559 : i64, !llvm.ptr
%560 = llvm.mlir.constant(1 : i64) : i64
%561 = llvm.alloca %560 x i64 : (i64) -> !llvm.ptr
llvm.store %arg3, %561 : i64, !llvm.ptr
%562 = arith.constant 0 : i32
%563 = arith.extsi %562 : i32 to i64
%564 = llvm.mlir.constant(1 : i64) : i64
%565 = llvm.alloca %564 x i64 : (i64) -> !llvm.ptr
llvm.store %563, %565 : i64, !llvm.ptr
%566 = arith.constant 1 : i32
%567 = arith.extsi %566 : i32 to i64
%568 = llvm.mlir.constant(1 : i64) : i64
%569 = llvm.alloca %568 x i64 : (i64) -> !llvm.ptr
llvm.store %567, %569 : i64, !llvm.ptr
%570 = arith.constant 1 : i32
%571 = arith.extsi %570 : i32 to i64
%572 = llvm.mlir.constant(1 : i64) : i64
%573 = llvm.alloca %572 x i64 : (i64) -> !llvm.ptr
llvm.store %571, %573 : i64, !llvm.ptr
%574 = llvm.mlir.constant(1 : i64) : i64
%575 = llvm.alloca %574 x i64 : (i64) -> !llvm.ptr
llvm.store %arg1, %575 : i64, !llvm.ptr
%576 = llvm.mlir.constant(1 : i64) : i64
%577 = llvm.alloca %576 x i64 : (i64) -> !llvm.ptr
llvm.store %arg3, %577 : i64, !llvm.ptr
%578 = arith.constant 0 : i32
%579 = arith.extsi %578 : i32 to i64
%580 = llvm.mlir.constant(1 : i64) : i64
%581 = llvm.alloca %580 x i64 : (i64) -> !llvm.ptr
llvm.store %579, %581 : i64, !llvm.ptr
%582 = arith.constant 0 : i32
%583 = arith.extsi %582 : i32 to i64
%584 = llvm.mlir.constant(1 : i64) : i64
%585 = llvm.alloca %584 x i64 : (i64) -> !llvm.ptr
llvm.store %583, %585 : i64, !llvm.ptr
%586 = arith.constant 1 : i32
%587 = arith.extsi %586 : i32 to i64
%588 = llvm.mlir.constant(1 : i64) : i64
%589 = llvm.alloca %588 x i64 : (i64) -> !llvm.ptr
llvm.store %587, %589 : i64, !llvm.ptr
%590 = arith.constant 3 : i32
%591 = arith.extsi %590 : i32 to i64
%592 = llvm.mlir.constant(1 : i64) : i64
%593 = llvm.alloca %592 x i64 : (i64) -> !llvm.ptr
llvm.store %591, %593 : i64, !llvm.ptr
%594 = arith.constant 0 : i32
%595 = arith.extsi %594 : i32 to i64
%596 = llvm.mlir.constant(1 : i64) : i64
%597 = llvm.alloca %596 x i64 : (i64) -> !llvm.ptr
llvm.store %595, %597 : i64, !llvm.ptr
%598 = arith.constant 5 : i32
%600 = arith.extsi %598 : i32 to i64
%599 = arith.addi %arg0, %600 : i64
%601 = llvm.mlir.constant(1 : i64) : i64
%602 = llvm.alloca %601 x i64 : (i64) -> !llvm.ptr
llvm.store %599, %602 : i64, !llvm.ptr
cf.br ^bb102
^bb102:
%603 = llvm.load %597 : !llvm.ptr -> i64
%604 = arith.constant 1 : i32
%606 = arith.extsi %604 : i32 to i64
%605 = arith.addi %603, %606 : i64
%607 = llvm.load %597 : !llvm.ptr -> i64
%608 = arith.constant 1 : i32
%610 = arith.extsi %608 : i32 to i64
%609 = arith.addi %607, %610 : i64
%611 = arith.muli %605, %609 : i64
%612 = llvm.load %602 : !llvm.ptr -> i64
%613 = arith.cmpi sle, %611, %612 : i64
cf.cond_br %613, ^bb103, ^bb104
^bb103:
%614 = llvm.load %597 : !llvm.ptr -> i64
%615 = arith.constant 1 : i32
%617 = arith.extsi %615 : i32 to i64
%616 = arith.addi %614, %617 : i64
llvm.store %616, %597 : i64, !llvm.ptr
cf.br ^bb102
^bb104:
cf.br ^bb105
^bb105:
%618 = llvm.load %593 : !llvm.ptr -> i64
%619 = llvm.load %597 : !llvm.ptr -> i64
%620 = arith.cmpi sle, %618, %619 : i64
cf.cond_br %620, ^bb106, ^bb107
^bb106:
cf.br ^bb108
^bb108:
%621 = llvm.load %549 : !llvm.ptr -> i64
%622 = llvm.load %597 : !llvm.ptr -> i64
%623 = arith.cmpi sle, %621, %622 : i64
cf.cond_br %623, ^bb109, ^bb110
^bb109:
%624 = llvm.load %581 : !llvm.ptr -> i64
%625 = llvm.load %553 : !llvm.ptr -> i64
%626 = arith.addi %624, %625 : i64
llvm.store %626, %581 : i64, !llvm.ptr
%627 = llvm.load %581 : !llvm.ptr -> i64
%628 = llvm.mlir.addressof @MOD : !llvm.ptr
%629 = llvm.load %628 : !llvm.ptr -> i64
%630 = arith.cmpi sge, %627, %629 : i64
cf.cond_br %630, ^bb111, ^bb112
^bb111:
%631 = llvm.load %581 : !llvm.ptr -> i64
%632 = llvm.mlir.addressof @MOD : !llvm.ptr
%633 = llvm.load %632 : !llvm.ptr -> i64
%634 = arith.subi %631, %633 : i64
llvm.store %634, %581 : i64, !llvm.ptr
cf.br ^bb113
^bb112:
cf.br ^bb113
^bb113:
%635 = llvm.load %585 : !llvm.ptr -> i64
%636 = llvm.load %557 : !llvm.ptr -> i64
%637 = arith.addi %635, %636 : i64
llvm.store %637, %585 : i64, !llvm.ptr
%638 = llvm.load %585 : !llvm.ptr -> i64
%639 = llvm.mlir.addressof @MOD : !llvm.ptr
%640 = llvm.load %639 : !llvm.ptr -> i64
%641 = arith.cmpi sge, %638, %640 : i64
cf.cond_br %641, ^bb114, ^bb115
^bb114:
%642 = llvm.load %585 : !llvm.ptr -> i64
%643 = llvm.mlir.addressof @MOD : !llvm.ptr
%644 = llvm.load %643 : !llvm.ptr -> i64
%645 = arith.subi %642, %644 : i64
llvm.store %645, %585 : i64, !llvm.ptr
cf.br ^bb116
^bb115:
cf.br ^bb116
^bb116:
%647 = llvm.load %553 : !llvm.ptr -> i64
%648 = llvm.load %559 : !llvm.ptr -> i64
%646 = func.call @mulmod(%647, %648) : (i64, i64) -> i64
llvm.store %646, %553 : i64, !llvm.ptr
%650 = llvm.load %559 : !llvm.ptr -> i64
%649 = func.call @mulmod(%650, %526) : (i64, i64) -> i64
llvm.store %649, %559 : i64, !llvm.ptr
%652 = llvm.load %557 : !llvm.ptr -> i64
%653 = llvm.load %561 : !llvm.ptr -> i64
%651 = func.call @mulmod(%652, %653) : (i64, i64) -> i64
llvm.store %651, %557 : i64, !llvm.ptr
%655 = llvm.load %561 : !llvm.ptr -> i64
%654 = func.call @mulmod(%655, %527) : (i64, i64) -> i64
llvm.store %654, %561 : i64, !llvm.ptr
%656 = llvm.load %549 : !llvm.ptr -> i64
%657 = arith.constant 1 : i32
%659 = arith.extsi %657 : i32 to i64
%658 = arith.addi %656, %659 : i64
llvm.store %658, %549 : i64, !llvm.ptr
cf.br ^bb108
^bb110:
cf.br ^bb117
^bb117:
%660 = llvm.load %565 : !llvm.ptr -> i64
%661 = llvm.load %593 : !llvm.ptr -> i64
%662 = arith.cmpi slt, %660, %661 : i64
cf.cond_br %662, ^bb118, ^bb119
^bb118:
%663 = llvm.load %581 : !llvm.ptr -> i64
%664 = llvm.load %569 : !llvm.ptr -> i64
%665 = arith.subi %663, %664 : i64
llvm.store %665, %581 : i64, !llvm.ptr
%666 = llvm.load %581 : !llvm.ptr -> i64
%667 = arith.constant 0 : i32
%669 = arith.extsi %667 : i32 to i64
%668 = arith.cmpi slt, %666, %669 : i64
cf.cond_br %668, ^bb120, ^bb121
^bb120:
%670 = llvm.load %581 : !llvm.ptr -> i64
%671 = llvm.mlir.addressof @MOD : !llvm.ptr
%672 = llvm.load %671 : !llvm.ptr -> i64
%673 = arith.addi %670, %672 : i64
llvm.store %673, %581 : i64, !llvm.ptr
cf.br ^bb122
^bb121:
cf.br ^bb122
^bb122:
%674 = llvm.load %585 : !llvm.ptr -> i64
%675 = llvm.load %573 : !llvm.ptr -> i64
%676 = arith.subi %674, %675 : i64
llvm.store %676, %585 : i64, !llvm.ptr
%677 = llvm.load %585 : !llvm.ptr -> i64
%678 = arith.constant 0 : i32
%680 = arith.extsi %678 : i32 to i64
%679 = arith.cmpi slt, %677, %680 : i64
cf.cond_br %679, ^bb123, ^bb124
^bb123:
%681 = llvm.load %585 : !llvm.ptr -> i64
%682 = llvm.mlir.addressof @MOD : !llvm.ptr
%683 = llvm.load %682 : !llvm.ptr -> i64
%684 = arith.addi %681, %683 : i64
llvm.store %684, %585 : i64, !llvm.ptr
cf.br ^bb125
^bb124:
cf.br ^bb125
^bb125:
%686 = llvm.load %569 : !llvm.ptr -> i64
%687 = llvm.load %575 : !llvm.ptr -> i64
%685 = func.call @mulmod(%686, %687) : (i64, i64) -> i64
llvm.store %685, %569 : i64, !llvm.ptr
%689 = llvm.load %575 : !llvm.ptr -> i64
%688 = func.call @mulmod(%689, %526) : (i64, i64) -> i64
llvm.store %688, %575 : i64, !llvm.ptr
%691 = llvm.load %573 : !llvm.ptr -> i64
%692 = llvm.load %577 : !llvm.ptr -> i64
%690 = func.call @mulmod(%691, %692) : (i64, i64) -> i64
llvm.store %690, %573 : i64, !llvm.ptr
%694 = llvm.load %577 : !llvm.ptr -> i64
%693 = func.call @mulmod(%694, %527) : (i64, i64) -> i64
llvm.store %693, %577 : i64, !llvm.ptr
%695 = llvm.load %565 : !llvm.ptr -> i64
%696 = arith.constant 1 : i32
%698 = arith.extsi %696 : i32 to i64
%697 = arith.addi %695, %698 : i64
llvm.store %697, %565 : i64, !llvm.ptr
cf.br ^bb117
^bb119:
%699 = llvm.load %521 : !llvm.ptr -> i64
%701 = llvm.load %581 : !llvm.ptr -> i64
%702 = llvm.load %539 : !llvm.ptr -> i64
%700 = func.call @mulmod(%701, %702) : (i64, i64) -> i64
%703 = arith.addi %699, %700 : i64
%704 = llvm.mlir.addressof @MOD : !llvm.ptr
%705 = llvm.load %704 : !llvm.ptr -> i64
%706 = arith.remsi %703, %705 : i64
llvm.store %706, %521 : i64, !llvm.ptr
%707 = llvm.load %525 : !llvm.ptr -> i64
%709 = llvm.load %585 : !llvm.ptr -> i64
%710 = llvm.load %541 : !llvm.ptr -> i64
%708 = func.call @mulmod(%709, %710) : (i64, i64) -> i64
%711 = arith.addi %707, %708 : i64
%712 = llvm.mlir.addressof @MOD : !llvm.ptr
%713 = llvm.load %712 : !llvm.ptr -> i64
%714 = arith.remsi %711, %713 : i64
llvm.store %714, %525 : i64, !llvm.ptr
%716 = llvm.load %539 : !llvm.ptr -> i64
%717 = llvm.load %543 : !llvm.ptr -> i64
%715 = func.call @mulmod(%716, %717) : (i64, i64) -> i64
llvm.store %715, %539 : i64, !llvm.ptr
%719 = llvm.load %543 : !llvm.ptr -> i64
%718 = func.call @mulmod(%719, %534) : (i64, i64) -> i64
llvm.store %718, %543 : i64, !llvm.ptr
%721 = llvm.load %541 : !llvm.ptr -> i64
%722 = llvm.load %545 : !llvm.ptr -> i64
%720 = func.call @mulmod(%721, %722) : (i64, i64) -> i64
llvm.store %720, %541 : i64, !llvm.ptr
%724 = llvm.load %545 : !llvm.ptr -> i64
%723 = func.call @mulmod(%724, %535) : (i64, i64) -> i64
llvm.store %723, %545 : i64, !llvm.ptr
%725 = llvm.load %602 : !llvm.ptr -> i64
%726 = arith.constant 10 : i32
%727 = llvm.load %589 : !llvm.ptr -> i64
%729 = arith.extsi %726 : i32 to i64
%728 = arith.muli %729, %727 : i64
%730 = arith.addi %725, %728 : i64
%731 = arith.constant 5 : i32
%733 = arith.extsi %731 : i32 to i64
%732 = arith.addi %730, %733 : i64
llvm.store %732, %602 : i64, !llvm.ptr
%734 = llvm.load %589 : !llvm.ptr -> i64
%735 = arith.constant 1 : i32
%737 = arith.extsi %735 : i32 to i64
%736 = arith.addi %734, %737 : i64
llvm.store %736, %589 : i64, !llvm.ptr
%738 = llvm.load %593 : !llvm.ptr -> i64
%739 = arith.constant 3 : i32
%741 = arith.extsi %739 : i32 to i64
%740 = arith.addi %738, %741 : i64
llvm.store %740, %593 : i64, !llvm.ptr
cf.br ^bb126
^bb126:
%742 = llvm.load %597 : !llvm.ptr -> i64
%743 = arith.constant 1 : i32
%745 = arith.extsi %743 : i32 to i64
%744 = arith.addi %742, %745 : i64
%746 = llvm.load %597 : !llvm.ptr -> i64
%747 = arith.constant 1 : i32
%749 = arith.extsi %747 : i32 to i64
%748 = arith.addi %746, %749 : i64
%750 = arith.muli %744, %748 : i64
%751 = llvm.load %602 : !llvm.ptr -> i64
%752 = arith.cmpi sle, %750, %751 : i64
cf.cond_br %752, ^bb127, ^bb128
^bb127:
%753 = llvm.load %597 : !llvm.ptr -> i64
%754 = arith.constant 1 : i32
%756 = arith.extsi %754 : i32 to i64
%755 = arith.addi %753, %756 : i64
llvm.store %755, %597 : i64, !llvm.ptr
cf.br ^bb126
^bb128:
cf.br ^bb105
^bb107:
%757 = llvm.mlir.constant(1 : i64) : i64
%758 = llvm.alloca %757 x i64 : (i64) -> !llvm.ptr
llvm.store %arg2, %758 : i64, !llvm.ptr
%759 = llvm.mlir.constant(1 : i64) : i64
%760 = llvm.alloca %759 x i64 : (i64) -> !llvm.ptr
llvm.store %arg4, %760 : i64, !llvm.ptr
%761 = llvm.mlir.constant(1 : i64) : i64
%762 = llvm.alloca %761 x i64 : (i64) -> !llvm.ptr
llvm.store %534, %762 : i64, !llvm.ptr
%763 = llvm.mlir.constant(1 : i64) : i64
%764 = llvm.alloca %763 x i64 : (i64) -> !llvm.ptr
llvm.store %535, %764 : i64, !llvm.ptr
%765 = arith.constant 0 : i32
%766 = arith.extsi %765 : i32 to i64
llvm.store %766, %549 : i64, !llvm.ptr
%767 = arith.constant 1 : i32
%768 = arith.extsi %767 : i32 to i64
llvm.store %768, %553 : i64, !llvm.ptr
%769 = arith.constant 1 : i32
%770 = arith.extsi %769 : i32 to i64
llvm.store %770, %557 : i64, !llvm.ptr
llvm.store %526, %559 : i64, !llvm.ptr
llvm.store %527, %561 : i64, !llvm.ptr
%771 = arith.constant 0 : i32
%772 = arith.extsi %771 : i32 to i64
llvm.store %772, %565 : i64, !llvm.ptr
%773 = arith.constant 1 : i32
%774 = arith.extsi %773 : i32 to i64
llvm.store %774, %569 : i64, !llvm.ptr
%775 = arith.constant 1 : i32
%776 = arith.extsi %775 : i32 to i64
llvm.store %776, %573 : i64, !llvm.ptr
llvm.store %526, %575 : i64, !llvm.ptr
llvm.store %527, %577 : i64, !llvm.ptr
%777 = arith.constant 0 : i32
%778 = arith.extsi %777 : i32 to i64
llvm.store %778, %581 : i64, !llvm.ptr
%779 = arith.constant 0 : i32
%780 = arith.extsi %779 : i32 to i64
llvm.store %780, %585 : i64, !llvm.ptr
%781 = arith.constant 0 : i32
%782 = arith.extsi %781 : i32 to i64
llvm.store %782, %589 : i64, !llvm.ptr
%783 = arith.constant 1 : i32
%784 = arith.extsi %783 : i32 to i64
llvm.store %784, %593 : i64, !llvm.ptr
%785 = arith.constant 0 : i32
%786 = arith.extsi %785 : i32 to i64
llvm.store %786, %597 : i64, !llvm.ptr
%787 = arith.constant 1 : i32
%789 = arith.extsi %787 : i32 to i64
%788 = arith.addi %arg0, %789 : i64
llvm.store %788, %602 : i64, !llvm.ptr
cf.br ^bb129
^bb129:
%790 = llvm.load %597 : !llvm.ptr -> i64
%791 = arith.constant 1 : i32
%793 = arith.extsi %791 : i32 to i64
%792 = arith.addi %790, %793 : i64
%794 = llvm.load %597 : !llvm.ptr -> i64
%795 = arith.constant 2 : i32
%797 = arith.extsi %795 : i32 to i64
%796 = arith.addi %794, %797 : i64
%798 = arith.muli %792, %796 : i64
%799 = llvm.load %602 : !llvm.ptr -> i64
%800 = arith.cmpi sle, %798, %799 : i64
cf.cond_br %800, ^bb130, ^bb131
^bb130:
%801 = llvm.load %597 : !llvm.ptr -> i64
%802 = arith.constant 1 : i32
%804 = arith.extsi %802 : i32 to i64
%803 = arith.addi %801, %804 : i64
llvm.store %803, %597 : i64, !llvm.ptr
cf.br ^bb129
^bb131:
cf.br ^bb132
^bb132:
%805 = llvm.load %593 : !llvm.ptr -> i64
%806 = llvm.load %597 : !llvm.ptr -> i64
%807 = arith.cmpi sle, %805, %806 : i64
cf.cond_br %807, ^bb133, ^bb134
^bb133:
cf.br ^bb135
^bb135:
%808 = llvm.load %549 : !llvm.ptr -> i64
%809 = llvm.load %597 : !llvm.ptr -> i64
%810 = arith.cmpi sle, %808, %809 : i64
cf.cond_br %810, ^bb136, ^bb137
^bb136:
%811 = llvm.load %581 : !llvm.ptr -> i64
%812 = llvm.load %553 : !llvm.ptr -> i64
%813 = arith.addi %811, %812 : i64
llvm.store %813, %581 : i64, !llvm.ptr
%814 = llvm.load %581 : !llvm.ptr -> i64
%815 = llvm.mlir.addressof @MOD : !llvm.ptr
%816 = llvm.load %815 : !llvm.ptr -> i64
%817 = arith.cmpi sge, %814, %816 : i64
cf.cond_br %817, ^bb138, ^bb139
^bb138:
%818 = llvm.load %581 : !llvm.ptr -> i64
%819 = llvm.mlir.addressof @MOD : !llvm.ptr
%820 = llvm.load %819 : !llvm.ptr -> i64
%821 = arith.subi %818, %820 : i64
llvm.store %821, %581 : i64, !llvm.ptr
cf.br ^bb140
^bb139:
cf.br ^bb140
^bb140:
%822 = llvm.load %585 : !llvm.ptr -> i64
%823 = llvm.load %557 : !llvm.ptr -> i64
%824 = arith.addi %822, %823 : i64
llvm.store %824, %585 : i64, !llvm.ptr
%825 = llvm.load %585 : !llvm.ptr -> i64
%826 = llvm.mlir.addressof @MOD : !llvm.ptr
%827 = llvm.load %826 : !llvm.ptr -> i64
%828 = arith.cmpi sge, %825, %827 : i64
cf.cond_br %828, ^bb141, ^bb142
^bb141:
%829 = llvm.load %585 : !llvm.ptr -> i64
%830 = llvm.mlir.addressof @MOD : !llvm.ptr
%831 = llvm.load %830 : !llvm.ptr -> i64
%832 = arith.subi %829, %831 : i64
llvm.store %832, %585 : i64, !llvm.ptr
cf.br ^bb143
^bb142:
cf.br ^bb143
^bb143:
%834 = llvm.load %553 : !llvm.ptr -> i64
%835 = llvm.load %559 : !llvm.ptr -> i64
%833 = func.call @mulmod(%834, %835) : (i64, i64) -> i64
llvm.store %833, %553 : i64, !llvm.ptr
%837 = llvm.load %559 : !llvm.ptr -> i64
%836 = func.call @mulmod(%837, %526) : (i64, i64) -> i64
llvm.store %836, %559 : i64, !llvm.ptr
%839 = llvm.load %557 : !llvm.ptr -> i64
%840 = llvm.load %561 : !llvm.ptr -> i64
%838 = func.call @mulmod(%839, %840) : (i64, i64) -> i64
llvm.store %838, %557 : i64, !llvm.ptr
%842 = llvm.load %561 : !llvm.ptr -> i64
%841 = func.call @mulmod(%842, %527) : (i64, i64) -> i64
llvm.store %841, %561 : i64, !llvm.ptr
%843 = llvm.load %549 : !llvm.ptr -> i64
%844 = arith.constant 1 : i32
%846 = arith.extsi %844 : i32 to i64
%845 = arith.addi %843, %846 : i64
llvm.store %845, %549 : i64, !llvm.ptr
cf.br ^bb135
^bb137:
cf.br ^bb144
^bb144:
%847 = llvm.load %565 : !llvm.ptr -> i64
%848 = llvm.load %593 : !llvm.ptr -> i64
%849 = arith.cmpi slt, %847, %848 : i64
cf.cond_br %849, ^bb145, ^bb146
^bb145:
%850 = llvm.load %581 : !llvm.ptr -> i64
%851 = llvm.load %569 : !llvm.ptr -> i64
%852 = arith.subi %850, %851 : i64
llvm.store %852, %581 : i64, !llvm.ptr
%853 = llvm.load %581 : !llvm.ptr -> i64
%854 = arith.constant 0 : i32
%856 = arith.extsi %854 : i32 to i64
%855 = arith.cmpi slt, %853, %856 : i64
cf.cond_br %855, ^bb147, ^bb148
^bb147:
%857 = llvm.load %581 : !llvm.ptr -> i64
%858 = llvm.mlir.addressof @MOD : !llvm.ptr
%859 = llvm.load %858 : !llvm.ptr -> i64
%860 = arith.addi %857, %859 : i64
llvm.store %860, %581 : i64, !llvm.ptr
cf.br ^bb149
^bb148:
cf.br ^bb149
^bb149:
%861 = llvm.load %585 : !llvm.ptr -> i64
%862 = llvm.load %573 : !llvm.ptr -> i64
%863 = arith.subi %861, %862 : i64
llvm.store %863, %585 : i64, !llvm.ptr
%864 = llvm.load %585 : !llvm.ptr -> i64
%865 = arith.constant 0 : i32
%867 = arith.extsi %865 : i32 to i64
%866 = arith.cmpi slt, %864, %867 : i64
cf.cond_br %866, ^bb150, ^bb151
^bb150:
%868 = llvm.load %585 : !llvm.ptr -> i64
%869 = llvm.mlir.addressof @MOD : !llvm.ptr
%870 = llvm.load %869 : !llvm.ptr -> i64
%871 = arith.addi %868, %870 : i64
llvm.store %871, %585 : i64, !llvm.ptr
cf.br ^bb152
^bb151:
cf.br ^bb152
^bb152:
%873 = llvm.load %569 : !llvm.ptr -> i64
%874 = llvm.load %575 : !llvm.ptr -> i64
%872 = func.call @mulmod(%873, %874) : (i64, i64) -> i64
llvm.store %872, %569 : i64, !llvm.ptr
%876 = llvm.load %575 : !llvm.ptr -> i64
%875 = func.call @mulmod(%876, %526) : (i64, i64) -> i64
llvm.store %875, %575 : i64, !llvm.ptr
%878 = llvm.load %573 : !llvm.ptr -> i64
%879 = llvm.load %577 : !llvm.ptr -> i64
%877 = func.call @mulmod(%878, %879) : (i64, i64) -> i64
llvm.store %877, %573 : i64, !llvm.ptr
%881 = llvm.load %577 : !llvm.ptr -> i64
%880 = func.call @mulmod(%881, %527) : (i64, i64) -> i64
llvm.store %880, %577 : i64, !llvm.ptr
%882 = llvm.load %565 : !llvm.ptr -> i64
%883 = arith.constant 1 : i32
%885 = arith.extsi %883 : i32 to i64
%884 = arith.addi %882, %885 : i64
llvm.store %884, %565 : i64, !llvm.ptr
cf.br ^bb144
^bb146:
%886 = llvm.load %521 : !llvm.ptr -> i64
%888 = llvm.load %581 : !llvm.ptr -> i64
%889 = llvm.load %758 : !llvm.ptr -> i64
%887 = func.call @mulmod(%888, %889) : (i64, i64) -> i64
%890 = arith.addi %886, %887 : i64
%891 = llvm.mlir.addressof @MOD : !llvm.ptr
%892 = llvm.load %891 : !llvm.ptr -> i64
%893 = arith.remsi %890, %892 : i64
llvm.store %893, %521 : i64, !llvm.ptr
%894 = llvm.load %525 : !llvm.ptr -> i64
%896 = llvm.load %585 : !llvm.ptr -> i64
%897 = llvm.load %760 : !llvm.ptr -> i64
%895 = func.call @mulmod(%896, %897) : (i64, i64) -> i64
%898 = arith.addi %894, %895 : i64
%899 = llvm.mlir.addressof @MOD : !llvm.ptr
%900 = llvm.load %899 : !llvm.ptr -> i64
%901 = arith.remsi %898, %900 : i64
llvm.store %901, %525 : i64, !llvm.ptr
%903 = llvm.load %758 : !llvm.ptr -> i64
%904 = llvm.load %762 : !llvm.ptr -> i64
%902 = func.call @mulmod(%903, %904) : (i64, i64) -> i64
llvm.store %902, %758 : i64, !llvm.ptr
%906 = llvm.load %762 : !llvm.ptr -> i64
%905 = func.call @mulmod(%906, %534) : (i64, i64) -> i64
llvm.store %905, %762 : i64, !llvm.ptr
%908 = llvm.load %760 : !llvm.ptr -> i64
%909 = llvm.load %764 : !llvm.ptr -> i64
%907 = func.call @mulmod(%908, %909) : (i64, i64) -> i64
llvm.store %907, %760 : i64, !llvm.ptr
%911 = llvm.load %764 : !llvm.ptr -> i64
%910 = func.call @mulmod(%911, %535) : (i64, i64) -> i64
llvm.store %910, %764 : i64, !llvm.ptr
%912 = llvm.load %602 : !llvm.ptr -> i64
%913 = arith.constant 10 : i32
%914 = llvm.load %589 : !llvm.ptr -> i64
%916 = arith.extsi %913 : i32 to i64
%915 = arith.muli %916, %914 : i64
%917 = arith.addi %912, %915 : i64
%918 = arith.constant 10 : i32
%920 = arith.extsi %918 : i32 to i64
%919 = arith.addi %917, %920 : i64
llvm.store %919, %602 : i64, !llvm.ptr
%921 = llvm.load %589 : !llvm.ptr -> i64
%922 = arith.constant 1 : i32
%924 = arith.extsi %922 : i32 to i64
%923 = arith.addi %921, %924 : i64
llvm.store %923, %589 : i64, !llvm.ptr
%925 = llvm.load %593 : !llvm.ptr -> i64
%926 = arith.constant 3 : i32
%928 = arith.extsi %926 : i32 to i64
%927 = arith.addi %925, %928 : i64
llvm.store %927, %593 : i64, !llvm.ptr
cf.br ^bb153
^bb153:
%929 = llvm.load %597 : !llvm.ptr -> i64
%930 = arith.constant 1 : i32
%932 = arith.extsi %930 : i32 to i64
%931 = arith.addi %929, %932 : i64
%933 = llvm.load %597 : !llvm.ptr -> i64
%934 = arith.constant 2 : i32
%936 = arith.extsi %934 : i32 to i64
%935 = arith.addi %933, %936 : i64
%937 = arith.muli %931, %935 : i64
%938 = llvm.load %602 : !llvm.ptr -> i64
%939 = arith.cmpi sle, %937, %938 : i64
cf.cond_br %939, ^bb154, ^bb155
^bb154:
%940 = llvm.load %597 : !llvm.ptr -> i64
%941 = arith.constant 1 : i32
%943 = arith.extsi %941 : i32 to i64
%942 = arith.addi %940, %943 : i64
llvm.store %942, %597 : i64, !llvm.ptr
cf.br ^bb153
^bb155:
cf.br ^bb132
^bb134:
%944 = llvm.load %521 : !llvm.ptr -> i64
%945 = arith.constant 0 : i32
%946 = arith.extsi %945 : i32 to i64
%947 = llvm.getelementptr %arg7[%946] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %944, %947 : i64, !llvm.ptr
%948 = llvm.load %525 : !llvm.ptr -> i64
%949 = arith.constant 0 : i32
%950 = arith.extsi %949 : i32 to i64
%951 = llvm.getelementptr %arg8[%950] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %948, %951 : i64, !llvm.ptr
func.return
}
func.func @main() -> i32 {
%953 = llvm.mlir.addressof @MAX_SMALL : !llvm.ptr
%954 = llvm.load %953 : !llvm.ptr -> i32
%955 = arith.constant 4 : i32
%956 = arith.extsi %954 : i32 to i64
%957 = arith.extsi %955 : i32 to i64
%952 = func.call @calloc(%956, %957) : (i64, i64) -> !llvm.ptr
%958 = func.call @build_small_values(%952) : (!llvm.ptr) -> i32
%959 = llvm.mlir.addressof @TARGET_LIMIT : !llvm.ptr
%960 = llvm.load %959 : !llvm.ptr -> i64
%961 = func.call @isqrt_i64(%960) : (i64) -> i64
%962 = func.call @mobius_sieve(%961) : (i64) -> !llvm.ptr
%964 = arith.constant 5 : i32
%965 = llvm.mlir.addressof @MOD : !llvm.ptr
%966 = llvm.load %965 : !llvm.ptr -> i64
%967 = arith.extsi %964 : i32 to i64
%963 = func.call @tonelli_shanks(%967, %966) : (i64, i64) -> i64
%969 = llvm.mlir.addressof @MOD : !llvm.ptr
%970 = llvm.load %969 : !llvm.ptr -> i64
%971 = arith.constant 2 : i32
%973 = arith.extsi %971 : i32 to i64
%972 = arith.subi %970, %973 : i64
%968 = func.call @mod_pow(%963, %972) : (i64, i64) -> i64
%974 = llvm.mlir.addressof @MOD : !llvm.ptr
%975 = llvm.load %974 : !llvm.ptr -> i64
%976 = arith.constant 1 : i32
%978 = arith.extsi %976 : i32 to i64
%977 = arith.addi %975, %978 : i64
%979 = arith.constant 2 : i32
%981 = arith.extsi %979 : i32 to i64
%980 = arith.divsi %977, %981 : i64
%983 = arith.constant 1 : i32
%985 = arith.extsi %983 : i32 to i64
%984 = arith.addi %985, %963 : i64
%986 = llvm.mlir.addressof @MOD : !llvm.ptr
%987 = llvm.load %986 : !llvm.ptr -> i64
%988 = arith.remsi %984, %987 : i64
%982 = func.call @mulmod(%988, %980) : (i64, i64) -> i64
%990 = llvm.mlir.addressof @MOD : !llvm.ptr
%991 = llvm.load %990 : !llvm.ptr -> i64
%992 = arith.constant 2 : i32
%994 = arith.extsi %992 : i32 to i64
%993 = arith.subi %991, %994 : i64
%989 = func.call @mod_pow(%982, %993) : (i64, i64) -> i64
%995 = func.call @mulmod(%982, %982) : (i64, i64) -> i64
%996 = func.call @mulmod(%989, %989) : (i64, i64) -> i64
%997 = arith.constant 0 : i32
%998 = arith.extsi %997 : i32 to i64
%999 = llvm.mlir.constant(1 : i64) : i64
%1000 = llvm.alloca %999 x i64 : (i64) -> !llvm.ptr
llvm.store %998, %1000 : i64, !llvm.ptr
%1001 = arith.constant 0 : i32
%1002 = arith.extsi %1001 : i32 to i64
%1003 = llvm.mlir.constant(1 : i64) : i64
%1004 = llvm.alloca %1003 x i64 : (i64) -> !llvm.ptr
llvm.store %1002, %1004 : i64, !llvm.ptr
%1005 = arith.constant 1 : i32
%1006 = arith.extsi %1005 : i32 to i64
%1007 = llvm.mlir.constant(1 : i64) : i64
%1008 = llvm.alloca %1007 x i64 : (i64) -> !llvm.ptr
llvm.store %1006, %1008 : i64, !llvm.ptr
%1009 = arith.constant 1 : i32
%1010 = arith.extsi %1009 : i32 to i64
%1011 = llvm.mlir.constant(1 : i64) : i64
%1012 = llvm.alloca %1011 x i64 : (i64) -> !llvm.ptr
llvm.store %1010, %1012 : i64, !llvm.ptr
%1013 = llvm.mlir.constant(1 : i64) : i64
%1014 = llvm.alloca %1013 x i64 : (i64) -> !llvm.ptr
llvm.store %982, %1014 : i64, !llvm.ptr
%1015 = llvm.mlir.constant(1 : i64) : i64
%1016 = llvm.alloca %1015 x i64 : (i64) -> !llvm.ptr
llvm.store %989, %1016 : i64, !llvm.ptr
%1017 = arith.constant 1 : i32
%1018 = arith.extsi %1017 : i32 to i64
%1019 = llvm.mlir.constant(1 : i64) : i64
%1020 = llvm.alloca %1019 x i64 : (i64) -> !llvm.ptr
llvm.store %1018, %1020 : i64, !llvm.ptr
%1022 = arith.constant 1 : i32
%1023 = arith.constant 8 : i32
%1024 = arith.extsi %1022 : i32 to i64
%1025 = arith.extsi %1023 : i32 to i64
%1021 = func.call @calloc(%1024, %1025) : (i64, i64) -> !llvm.ptr
%1027 = arith.constant 1 : i32
%1028 = arith.constant 8 : i32
%1029 = arith.extsi %1027 : i32 to i64
%1030 = arith.extsi %1028 : i32 to i64
%1026 = func.call @calloc(%1029, %1030) : (i64, i64) -> !llvm.ptr
%1031 = arith.constant 1 : i32
%1032 = arith.extsi %1031 : i32 to i64
%1033 = llvm.mlir.constant(1 : i64) : i64
%1034 = llvm.alloca %1033 x i64 : (i64) -> !llvm.ptr
llvm.store %1032, %1034 : i64, !llvm.ptr
cf.br ^bb156
^bb156:
%1035 = llvm.load %1034 : !llvm.ptr -> i64
%1036 = arith.cmpi sle, %1035, %961 : i64
cf.cond_br %1036, ^bb157, ^bb158
^bb157:
%1038 = llvm.load %1008 : !llvm.ptr -> i64
%1039 = llvm.load %1014 : !llvm.ptr -> i64
%1037 = func.call @mulmod(%1038, %1039) : (i64, i64) -> i64
llvm.store %1037, %1008 : i64, !llvm.ptr
%1041 = llvm.load %1014 : !llvm.ptr -> i64
%1040 = func.call @mulmod(%1041, %995) : (i64, i64) -> i64
llvm.store %1040, %1014 : i64, !llvm.ptr
%1043 = llvm.load %1012 : !llvm.ptr -> i64
%1044 = llvm.load %1016 : !llvm.ptr -> i64
%1042 = func.call @mulmod(%1043, %1044) : (i64, i64) -> i64
llvm.store %1042, %1012 : i64, !llvm.ptr
%1046 = llvm.load %1016 : !llvm.ptr -> i64
%1045 = func.call @mulmod(%1046, %996) : (i64, i64) -> i64
llvm.store %1045, %1016 : i64, !llvm.ptr
%1048 = llvm.load %1034 : !llvm.ptr -> i64
%1049 = llvm.getelementptr %962[%1048] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%1047 = llvm.load %1049 : !llvm.ptr -> i8
%1050 = arith.constant 0 : i32
%1052 = arith.extsi %1047 : i8 to i32
%1051 = arith.cmpi ne, %1052, %1050 : i32
cf.cond_br %1051, ^bb159, ^bb160
^bb159:
%1053 = llvm.load %1020 : !llvm.ptr -> i64
%1054 = arith.divsi %960, %1053 : i64
%1055 = llvm.mlir.undef : i64
%1056 = llvm.mlir.undef : i64
%1057 = llvm.load %1034 : !llvm.ptr -> i64
%1058 = arith.constant 1 : i32
%1060 = arith.extsi %1058 : i32 to i64
%1059 = arith.andi %1057, %1060 : i64
%1061 = arith.constant 0 : i32
%1063 = arith.extsi %1061 : i32 to i64
%1062 = arith.cmpi ne, %1059, %1063 : i64
%1064, %1065 = scf.if %1062 -> (i64, i64) {
%1066 = llvm.mlir.addressof @MOD : !llvm.ptr
%1067 = llvm.load %1066 : !llvm.ptr -> i64
%1068 = llvm.load %1012 : !llvm.ptr -> i64
%1069 = arith.subi %1067, %1068 : i64
%1070 = llvm.mlir.addressof @MOD : !llvm.ptr
%1071 = llvm.load %1070 : !llvm.ptr -> i64
%1072 = llvm.load %1008 : !llvm.ptr -> i64
%1073 = arith.subi %1071, %1072 : i64
scf.yield %1069, %1073 : i64, i64
} else {
%1074 = llvm.load %1012 : !llvm.ptr -> i64
%1075 = llvm.load %1008 : !llvm.ptr -> i64
scf.yield %1074, %1075 : i64, i64
}
%1077 = llvm.load %1008 : !llvm.ptr -> i64
%1078 = llvm.load %1012 : !llvm.ptr -> i64
func.call @nonprimitive_pair(%1054, %1077, %1078, %1064, %1065, %952, %958, %1021, %1026) : (i64, i64, i64, i64, i64, !llvm.ptr, i32, !llvm.ptr, !llvm.ptr) -> ()
%1079 = arith.constant 1 : i32
%1081 = arith.extsi %1047 : i8 to i32
%1080 = arith.cmpi eq, %1081, %1079 : i32
cf.cond_br %1080, ^bb162, ^bb163
^bb162:
%1082 = llvm.load %1000 : !llvm.ptr -> i64
%1084 = arith.constant 0 : i32
%1085 = arith.extsi %1084 : i32 to i64
%1086 = llvm.getelementptr %1021[%1085] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%1083 = llvm.load %1086 : !llvm.ptr -> i64
%1087 = arith.addi %1082, %1083 : i64
llvm.store %1087, %1000 : i64, !llvm.ptr
%1088 = llvm.load %1000 : !llvm.ptr -> i64
%1089 = llvm.mlir.addressof @MOD : !llvm.ptr
%1090 = llvm.load %1089 : !llvm.ptr -> i64
%1091 = arith.cmpi sge, %1088, %1090 : i64
cf.cond_br %1091, ^bb165, ^bb166
^bb165:
%1092 = llvm.load %1000 : !llvm.ptr -> i64
%1093 = llvm.mlir.addressof @MOD : !llvm.ptr
%1094 = llvm.load %1093 : !llvm.ptr -> i64
%1095 = arith.subi %1092, %1094 : i64
llvm.store %1095, %1000 : i64, !llvm.ptr
cf.br ^bb167
^bb166:
cf.br ^bb167
^bb167:
%1096 = llvm.load %1004 : !llvm.ptr -> i64
%1098 = arith.constant 0 : i32
%1099 = arith.extsi %1098 : i32 to i64
%1100 = llvm.getelementptr %1026[%1099] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%1097 = llvm.load %1100 : !llvm.ptr -> i64
%1101 = arith.addi %1096, %1097 : i64
llvm.store %1101, %1004 : i64, !llvm.ptr
%1102 = llvm.load %1004 : !llvm.ptr -> i64
%1103 = llvm.mlir.addressof @MOD : !llvm.ptr
%1104 = llvm.load %1103 : !llvm.ptr -> i64
%1105 = arith.cmpi sge, %1102, %1104 : i64
cf.cond_br %1105, ^bb168, ^bb169
^bb168:
%1106 = llvm.load %1004 : !llvm.ptr -> i64
%1107 = llvm.mlir.addressof @MOD : !llvm.ptr
%1108 = llvm.load %1107 : !llvm.ptr -> i64
%1109 = arith.subi %1106, %1108 : i64
llvm.store %1109, %1004 : i64, !llvm.ptr
cf.br ^bb170
^bb169:
cf.br ^bb170
^bb170:
cf.br ^bb164
^bb163:
%1110 = llvm.load %1000 : !llvm.ptr -> i64
%1112 = arith.constant 0 : i32
%1113 = arith.extsi %1112 : i32 to i64
%1114 = llvm.getelementptr %1021[%1113] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%1111 = llvm.load %1114 : !llvm.ptr -> i64
%1115 = arith.subi %1110, %1111 : i64
llvm.store %1115, %1000 : i64, !llvm.ptr
%1116 = llvm.load %1000 : !llvm.ptr -> i64
%1117 = arith.constant 0 : i32
%1119 = arith.extsi %1117 : i32 to i64
%1118 = arith.cmpi slt, %1116, %1119 : i64
cf.cond_br %1118, ^bb171, ^bb172
^bb171:
%1120 = llvm.load %1000 : !llvm.ptr -> i64
%1121 = llvm.mlir.addressof @MOD : !llvm.ptr
%1122 = llvm.load %1121 : !llvm.ptr -> i64
%1123 = arith.addi %1120, %1122 : i64
llvm.store %1123, %1000 : i64, !llvm.ptr
cf.br ^bb173
^bb172:
cf.br ^bb173
^bb173:
%1124 = llvm.load %1004 : !llvm.ptr -> i64
%1126 = arith.constant 0 : i32
%1127 = arith.extsi %1126 : i32 to i64
%1128 = llvm.getelementptr %1026[%1127] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%1125 = llvm.load %1128 : !llvm.ptr -> i64
%1129 = arith.subi %1124, %1125 : i64
llvm.store %1129, %1004 : i64, !llvm.ptr
%1130 = llvm.load %1004 : !llvm.ptr -> i64
%1131 = arith.constant 0 : i32
%1133 = arith.extsi %1131 : i32 to i64
%1132 = arith.cmpi slt, %1130, %1133 : i64
cf.cond_br %1132, ^bb174, ^bb175
^bb174:
%1134 = llvm.load %1004 : !llvm.ptr -> i64
%1135 = llvm.mlir.addressof @MOD : !llvm.ptr
%1136 = llvm.load %1135 : !llvm.ptr -> i64
%1137 = arith.addi %1134, %1136 : i64
llvm.store %1137, %1004 : i64, !llvm.ptr
cf.br ^bb176
^bb175:
cf.br ^bb176
^bb176:
cf.br ^bb164
^bb164:
cf.br ^bb161
^bb160:
cf.br ^bb161
^bb161:
%1138 = llvm.load %1020 : !llvm.ptr -> i64
%1139 = arith.constant 2 : i32
%1140 = llvm.load %1034 : !llvm.ptr -> i64
%1142 = arith.extsi %1139 : i32 to i64
%1141 = arith.muli %1142, %1140 : i64
%1143 = arith.addi %1138, %1141 : i64
%1144 = arith.constant 1 : i32
%1146 = arith.extsi %1144 : i32 to i64
%1145 = arith.addi %1143, %1146 : i64
llvm.store %1145, %1020 : i64, !llvm.ptr
%1147 = llvm.load %1034 : !llvm.ptr -> i64
%1148 = arith.constant 1 : i32
%1150 = arith.extsi %1148 : i32 to i64
%1149 = arith.addi %1147, %1150 : i64
llvm.store %1149, %1034 : i64, !llvm.ptr
cf.br ^bb156
^bb158:
func.call @free(%962) : (!llvm.ptr) -> ()
func.call @free(%952) : (!llvm.ptr) -> ()
func.call @free(%1021) : (!llvm.ptr) -> ()
func.call @free(%1026) : (!llvm.ptr) -> ()
%1155 = llvm.mlir.addressof @str_0 : !llvm.ptr
%1157 = llvm.load %1000 : !llvm.ptr -> i64
%1158 = llvm.load %1004 : !llvm.ptr -> i64
%1159 = arith.subi %1157, %1158 : i64
%1160 = llvm.mlir.addressof @MOD : !llvm.ptr
%1161 = llvm.load %1160 : !llvm.ptr -> i64
%1162 = arith.addi %1159, %1161 : i64
%1163 = llvm.mlir.addressof @MOD : !llvm.ptr
%1164 = llvm.load %1163 : !llvm.ptr -> i64
%1165 = arith.remsi %1162, %1164 : i64
%1156 = func.call @mulmod(%1165, %968) : (i64, i64) -> i64
%1166 = llvm.call @printf(%1155, %1156) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
%1167 = arith.constant 0 : i32
func.return %1167 : i32
}
}