Problem 591

Best Approximations by Quadratic Integers — i128 fixed-point (96 fractional bits). Machin's formula for pi, Newton's method for sqrt, continued fraction best approximation.

Answer526007984625966
Output526007984625966
StatusPASS
Native helperno
Runtime30 ms
Peak memory4400 KB
Time complexityO(n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n)O(sqrt(n))
Space complexityO(n^2)O(1)
ApproachFlow solutionContinued fraction convergents
VerdictSuboptimal

Flow source

# Project Euler 591
# Best Approximations by Quadratic Integers — i128 fixed-point (96 fractional bits).
# Machin's formula for pi, Newton's method for sqrt, continued fraction best approximation.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
    function realloc(p: ptr<void>, n: i64) -> ptr<void>
    function printf(fmt: ptr<i8>, ...) -> i32
    function sqrt(x: f64) -> f64
    function floor(x: f64) -> f64
    function round(x: f64) -> f64
}

function one() -> i128 {
    return (1 as i128) << 96
}

function arctan_inv_scaled(x: i32) -> i128 {
    let mut sum: i128 = 0
    let mut xpow: i128 = x as i128
    let x2: i128 = (x as i128) * (x as i128)
    let mut k: i32 = 0
    while k < 60 {
        let denom: i128 = ((2 * k + 1) as i128) * xpow
        if denom > one() { break }
        let term: i128 = one() / denom
        if k % 2 == 0 {
            sum = sum + term
        } else {
            sum = sum - term
        }
        xpow = xpow * x2
        k = k + 1
    }
    return sum
}

function compute_pi_fp() -> i128 {
    return 16 * arctan_inv_scaled(5) - 4 * arctan_inv_scaled(239)
}

function floor_div(a: i128, b: i128) -> i128 {
    let q: i128 = a / b
    let r: i128 = a % b
    if r != 0 {
        if (a < 0 && b >= 0) || (a >= 0 && b < 0) {
            return q - 1
        }
    }
    return q
}

function isqrt_scaled(d: i32) -> i128 {
    let target: i128 = (d as i128) << 120
    let shift60: f64 = ((1 as i64) << 60) as f64
    let mut y: i128 = (sqrt(d as f64) * shift60) as i128
    let mut i: i32 = 0
    while i < 50 {
        let q: i128 = target / y
        let y_new: i128 = (y + q) / 2
        if y_new == y { break }
        y = y_new
        i = i + 1
    }
    let mut z: i128 = y << 36
    let mut two_sqrt_d: i32 = round(2.0 * sqrt(d as f64)) as i32
    if two_sqrt_d == 0 { two_sqrt_d = 1 }
    let mut iter: i32 = 0
    while iter < 40 {
        let hi: i128 = z >> 48
        let lo: i128 = z & (((1 as i128) << 48) - 1)
        let z2: i128 = hi * hi + ((2 * hi * lo) >> 48) + ((lo * lo) >> 96)
        let diff: i128 = z2 - (d as i128) * one()
        if diff == 0 { break }
        let mut corr: i128 = 0
        if diff >= 0 - ((1 as i128) << 30) && diff <= ((1 as i128) << 30) {
            corr = floor_div(diff * one(), (2 as i128) * z)
            if corr == 0 {
                if diff > 0 { corr = 1 } else { corr = 0 - 1 }
            }
        } else {
            corr = floor_div(diff, two_sqrt_d as i128)
        }
        if corr == 0 { break }
        z = z - corr
        iter = iter + 1
    }
    return z
}

function frac_mul(alpha_fp: i128, n: i64) -> i128 {
    let mask64: i128 = ((1 as i128) << 64) - 1
    let lo: i128 = alpha_fp & mask64
    let hi: i128 = (alpha_fp >> 64) & mask64
    let lo_n: i128 = lo * (n as i128)
    let hi_n: i128 = hi * (n as i128)
    let hi_n_mod: i128 = hi_n & (((1 as i128) << 32) - 1)
    let hi_part: i128 = hi_n_mod << 64
    return (lo_n + hi_part) & (one() - 1)
}

function compute_error_fp(sqrt_D_fp: i128, pi_fp: i128, b: i64) -> i128 {
    let mask64: i128 = ((1 as i128) << 64) - 1
    let lo_sqrt: i128 = sqrt_D_fp & mask64
    let hi_sqrt: i128 = (sqrt_D_fp >> 64) & mask64
    let lo_b: i128 = lo_sqrt * (b as i128)
    let hi_b: i128 = hi_sqrt * (b as i128)
    let hi_b_mod: i128 = hi_b & (((1 as i128) << 32) - 1)
    let hi_part: i128 = hi_b_mod << 64
    let val: i128 = lo_b - pi_fp + hi_part
    let mut frac_val: i128 = val % one()
    if frac_val < 0 { frac_val = frac_val + one() }
    if frac_val <= one() / 2 { return frac_val }
    return one() - frac_val
}

function is_square(n: i32) -> bool {
    let r: i32 = floor(sqrt(n as f64) + 0.5) as i32
    return r * r == n
}

function sqrt_cf_period(d: i32, a0_out: ptr<i32>, period: ptr<i32>, plen_out: ptr<i32>) -> i32 {
    let a0: i32 = floor(sqrt(d as f64)) as i32
    a0_out[0] = a0
    let mut m: i64 = 0
    let mut dd: i64 = 1
    let mut a: i64 = a0 as i64
    let mut n: i32 = 0
    while true {
        m = dd * a - m
        dd = ((d as i64) - m * m) / dd
        a = (a0 as i64 + m) / dd
        period[n] = a as i32
        n = n + 1
        if a == 2 * (a0 as i64) { break }
        if n > 10000 { return -1 }
    }
    plen_out[0] = n
    return 0
}

function ceil_div_i128(a0: i128, b0: i128) -> i128 {
    let mut a: i128 = a0
    let mut b: i128 = b0
    if b < 0 {
        a = 0 - a
        b = 0 - b
    }
    if a >= 0 { return (a + b - 1) / b }
    return 0 - ((0 - a) / b)
}

function best_b_positive(alpha_fp: i128, beta_fp: i128, B: i64, period: ptr<i32>, plen: i32) -> i64 {
    if B <= 0 { return 0 }
    let mut cap: i32 = 128
    let mut a: ptr<i32> = calloc(cap as i64, 4) as ptr<i32>
    let mut q: ptr<i64> = calloc(cap as i64, 8) as ptr<i64>
    let mut delta: ptr<i128> = calloc(cap as i64, 16) as ptr<i128>
    a[0] = 0
    q[0] = 1
    let mut q_minus1: i64 = 0
    delta[0] = alpha_fp
    let delta_minus1: i128 = one()
    let mut k: i32 = 1
    let mut extra: i32 = 6
    let mut len: i32 = 1
    while true {
        if k + 2 >= cap {
            let ncap: i32 = cap * 2
            a = realloc(a as ptr<void>, (ncap as i64) * 4) as ptr<i32>
            q = realloc(q as ptr<void>, (ncap as i64) * 8) as ptr<i64>
            delta = realloc(delta as ptr<void>, (ncap as i64) * 16) as ptr<i128>
            cap = ncap
        }
        let ak: i32 = period[(k - 1) % plen]
        a[k] = ak
        let qk: i64 = (ak as i64) * q[k - 1] + q_minus1
        q_minus1 = q[k - 1]
        q[k] = qk
        if k == 1 {
            delta[k] = 0 - (ak as i128) * delta[0] + delta_minus1
        } else {
            delta[k] = 0 - (ak as i128) * delta[k - 1] + delta[k - 2]
        }
        len = k + 1
        if qk > B {
            extra = extra - 1
            if extra <= 0 { break }
        }
        k = k + 1
        if k > 500 { break }
    }
    let max_i: i32 = len - 1
    let b_digits: ptr<i32> = calloc((max_i + 1) as i64, 4) as ptr<i32>
    let mut beta_rem: i128 = beta_fp
    let mut i: i32 = 1
    while i <= max_i {
        let d: i128 = delta[i - 1]
        if d == 0 {
            b_digits[i] = 0
        } else {
            let mut bi: i128 = ceil_div_i128(beta_rem, d)
            if bi > (a[i] as i128) { bi = a[i] as i128 }
            if bi < 0 { bi = 0 }
            b_digits[i] = bi as i32
            beta_rem = bi * d - beta_rem
        }
        i = i + 1
    }
    let prefix: ptr<i64> = calloc((max_i + 1) as i64, 8) as ptr<i64>
    let mut s: i64 = 0
    i = 1
    while i <= max_i {
        s = s + (b_digits[i] as i64) * q[i - 1]
        prefix[i] = s
        i = i + 1
    }
    let cand_r: ptr<i64> = calloc(200000, 8) as ptr<i64>
    let cand_l: ptr<i64> = calloc(200000, 8) as ptr<i64>
    let mut nr: i32 = 0
    let mut nl: i32 = 0
    cand_r[nr] = 0
    nr = nr + 1
    cand_l[nl] = 0
    nl = nl + 1
    let mut k2: i32 = 1
    while 2 * k2 < max_i + 1 {
        let ie: i32 = 2 * k2
        let io: i32 = 2 * k2 - 1
        if ie > max_i { break }
        let P: i64 = prefix[io]
        let st: i64 = q[io]
        let mut j: i32 = 0
        while j < b_digits[ie] {
            let n: i64 = P + (j as i64) * st
            if 0 <= n && n <= B {
                cand_r[nr] = n
                nr = nr + 1
            }
            j = j + 1
        }
        k2 = k2 + 1
    }
    k2 = 0
    while 2 * k2 + 1 <= max_i {
        let idx: i32 = 2 * k2
        let inn: i32 = idx + 1
        if inn > max_i { break }
        let P: i64 = prefix[idx]
        let st: i64 = q[idx]
        let mut j: i32 = 0
        while j < b_digits[inn] {
            let n: i64 = P + (j as i64) * st
            if 0 <= n && n <= B {
                cand_l[nl] = n
                nl = nl + 1
            }
            j = j + 1
        }
        k2 = k2 + 1
    }
    let mut best_r_gap: i128 = one()
    let mut best_l_gap: i128 = one()
    let mut best_r_n: i64 = 0
    let mut best_l_n: i64 = 0
    i = 0
    while i < nr {
        let n: i64 = cand_r[i]
        let x: i128 = frac_mul(alpha_fp, n)
        let mut gap: i128 = x - beta_fp
        if gap < 0 { gap = gap + one() }
        if gap < best_r_gap {
            best_r_gap = gap
            best_r_n = n
        }
        i = i + 1
    }
    i = 0
    while i < nl {
        let n: i64 = cand_l[i]
        let x: i128 = frac_mul(alpha_fp, n)
        let mut gap: i128 = beta_fp - x
        if gap < 0 { gap = gap + one() }
        if gap < best_l_gap {
            best_l_gap = gap
            best_l_n = n
        }
        i = i + 1
    }
    let ans: i64 = 0
    if best_r_gap < best_l_gap {
        ans = best_r_n
    } else {
        ans = best_l_n
    }
    free(delta as ptr<void>)
    free(a as ptr<void>)
    free(q as ptr<void>)
    free(b_digits as ptr<void>)
    free(prefix as ptr<void>)
    free(cand_r as ptr<void>)
    free(cand_l as ptr<void>)
    return ans
}

function bqa_pi_d(d: i32, n: i64, pi_fp: i128, beta_fp: i128) -> i64 {
    let a0_ptr: ptr<i32> = calloc(1, 4) as ptr<i32>
    let period: ptr<i32> = calloc(4096, 4) as ptr<i32>
    let plen_ptr: ptr<i32> = calloc(1, 4) as ptr<i32>
    sqrt_cf_period(d, a0_ptr, period, plen_ptr)
    let a0: i32 = a0_ptr[0]
    let plen: i32 = plen_ptr[0]
    let sqrt_D_fp: i128 = isqrt_scaled(d)
    let alpha_fp: i128 = sqrt_D_fp - ((a0 as i128) << 96)
    let sqrt_d: f64 = sqrt(d as f64)
    let pi_d: f64 = 3.14159265358979323846
    let mut Bpos: i64 = floor((pi_d + (n as f64)) / sqrt_d) as i64
    if Bpos < 0 { Bpos = 0 }
    if Bpos > n { Bpos = n }
    let mut Bneg: i64 = floor(((n as f64) - pi_d) / sqrt_d) as i64
    if Bneg < 0 { Bneg = 0 }
    if Bneg > n { Bneg = n }
    let b_pos: i64 = best_b_positive(alpha_fp, beta_fp, Bpos, period, plen)
    let one_m_beta: i128 = one() - beta_fp
    let t: i64 = best_b_positive(alpha_fp, one_m_beta, Bneg, period, plen)
    let b_neg: i64 = 0 - t
    let err1_fp: i128 = compute_error_fp(sqrt_D_fp, pi_fp, b_pos)
    let err2_fp: i128 = compute_error_fp(sqrt_D_fp, pi_fp, b_neg)
    let mut b_chosen: i64 = b_pos
    if err2_fp < err1_fp { b_chosen = b_neg }
    let a_real: f64 = pi_d - sqrt_d * (b_chosen as f64)
    let mut a_out: i64 = round(a_real) as i64
    if a_out > n { a_out = n }
    if a_out < 0 - n { a_out = 0 - n }
    free(a0_ptr as ptr<void>)
    free(period as ptr<void>)
    free(plen_ptr as ptr<void>)
    return a_out
}

function main() -> i32 {
    let pi_fp: i128 = compute_pi_fp()
    let beta_fp: i128 = pi_fp - ((3 as i128) << 96)
    let mut total: i64 = 0
    let n: i64 = 10000000000000
    let mut d: i32 = 2
    while d < 100 {
        if !is_square(d) {
            let a: i64 = bqa_pi_d(d, n, pi_fp, beta_fp)
            if a >= 0 {
                total = total + a
            } else {
                total = total + (0 - a)
            }
        }
        d = d + 1
    }
    printf("%lld\n", total)
    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; }

__int128 one(void);
__int128 arctan_inv_scaled_i32(int32_t x);
__int128 compute_pi_fp(void);
__int128 floor_div_i128_i128(__int128 a, __int128 b);
__int128 isqrt_scaled_i32(int32_t d);
__int128 frac_mul_i128_i64(__int128 alpha_fp, int64_t n);
__int128 compute_error_fp_i128_i128_i64(__int128 sqrt_D_fp, __int128 pi_fp, int64_t b);
bool is_square_i32(int32_t n);
int32_t sqrt_cf_period_i32_ptr_i32_ptr_i32_ptr_i32(int32_t d, int32_t* a0_out, int32_t* period, int32_t* plen_out);
__int128 ceil_div_i128_i128_i128(__int128 a0, __int128 b0);
int64_t best_b_positive_i128_i128_i64_ptr_i32_i32(__int128 alpha_fp, __int128 beta_fp, int64_t B, int32_t* period, int32_t plen);
int64_t bqa_pi_d_i32_i64_i128_i128(int32_t d, int64_t n, __int128 pi_fp, __int128 beta_fp);
int32_t main(void);








__int128 one(void) {
    return FLOW_CHECKED_SHL((((__int128)(1))), (96));
}

__int128 arctan_inv_scaled_i32(int32_t x) {
    __int128 sum = 0;
    __int128 xpow = ((__int128)(x));
    __int128 x2 = (((__int128)(x)) * ((__int128)(x)));
    int32_t k = 0;
    while (k < 60) {
        __int128 denom = (((__int128)(((2 * k) + 1))) * xpow);
        if (denom > one()) {
            break;
        }
        __int128 term = FLOW_CHECKED_DIV((one()), (denom));
        if (FLOW_CHECKED_MOD((k), (2)) == 0) {
            sum = (sum + term);
        } else {
            sum = (sum - term);
        }
        xpow = (xpow * x2);
        k = (k + 1);
    }
    return sum;
}

__int128 compute_pi_fp(void) {
    return ((16 * arctan_inv_scaled_i32(5)) - (4 * arctan_inv_scaled_i32(239)));
}

__int128 floor_div_i128_i128(__int128 a, __int128 b) {
    __int128 q = FLOW_CHECKED_DIV((a), (b));
    __int128 r = FLOW_CHECKED_MOD((a), (b));
    if (r != 0) {
        if (((a < 0 && b >= 0) || (a >= 0 && b < 0))) {
            return (q - 1);
        }
    }
    return q;
}

__int128 isqrt_scaled_i32(int32_t d) {
    __int128 target = FLOW_CHECKED_SHL((((__int128)(d))), (120));
    double shift60 = ((double)(FLOW_CHECKED_SHL((((int64_t)(1))), (60))));
    __int128 y = ((__int128)((sqrt(((double)(d))) * shift60)));
    int32_t i = 0;
    while (i < 50) {
        __int128 q = FLOW_CHECKED_DIV((target), (y));
        __int128 y_new = FLOW_CHECKED_DIV(((y + q)), (2));
        if (y_new == y) {
            break;
        }
        y = y_new;
        i = (i + 1);
    }
    __int128 z = FLOW_CHECKED_SHL((y), (36));
    int32_t two_sqrt_d = ((int32_t)(round((2.0 * sqrt(((double)(d)))))));
    if (two_sqrt_d == 0) {
        two_sqrt_d = 1;
    }
    int32_t iter = 0;
    while (iter < 40) {
        __int128 hi = FLOW_CHECKED_SHR((z), (48));
        __int128 lo = (z & (FLOW_CHECKED_SHL((((__int128)(1))), (48)) - 1));
        __int128 z2 = (((hi * hi) + FLOW_CHECKED_SHR((((2 * hi) * lo)), (48))) + FLOW_CHECKED_SHR(((lo * lo)), (96)));
        __int128 diff = (z2 - (((__int128)(d)) * one()));
        if (diff == 0) {
            break;
        }
        __int128 corr = 0;
        if ((diff >= (0 - FLOW_CHECKED_SHL((((__int128)(1))), (30))) && diff <= FLOW_CHECKED_SHL((((__int128)(1))), (30)))) {
            corr = floor_div_i128_i128((diff * one()), (((__int128)(2)) * z));
            if (corr == 0) {
                if (diff > 0) {
                    corr = 1;
                } else {
                    corr = (0 - 1);
                }
            }
        } else {
            corr = floor_div_i128_i128(diff, ((__int128)(two_sqrt_d)));
        }
        if (corr == 0) {
            break;
        }
        z = (z - corr);
        iter = (iter + 1);
    }
    return z;
}

__int128 frac_mul_i128_i64(__int128 alpha_fp, int64_t n) {
    __int128 mask64 = (FLOW_CHECKED_SHL((((__int128)(1))), (64)) - 1);
    __int128 lo = (alpha_fp & mask64);
    __int128 hi = (FLOW_CHECKED_SHR((alpha_fp), (64)) & mask64);
    __int128 lo_n = (lo * ((__int128)(n)));
    __int128 hi_n = (hi * ((__int128)(n)));
    __int128 hi_n_mod = (hi_n & (FLOW_CHECKED_SHL((((__int128)(1))), (32)) - 1));
    __int128 hi_part = FLOW_CHECKED_SHL((hi_n_mod), (64));
    return ((lo_n + hi_part) & (one() - 1));
}

__int128 compute_error_fp_i128_i128_i64(__int128 sqrt_D_fp, __int128 pi_fp, int64_t b) {
    __int128 mask64 = (FLOW_CHECKED_SHL((((__int128)(1))), (64)) - 1);
    __int128 lo_sqrt = (sqrt_D_fp & mask64);
    __int128 hi_sqrt = (FLOW_CHECKED_SHR((sqrt_D_fp), (64)) & mask64);
    __int128 lo_b = (lo_sqrt * ((__int128)(b)));
    __int128 hi_b = (hi_sqrt * ((__int128)(b)));
    __int128 hi_b_mod = (hi_b & (FLOW_CHECKED_SHL((((__int128)(1))), (32)) - 1));
    __int128 hi_part = FLOW_CHECKED_SHL((hi_b_mod), (64));
    __int128 val = ((lo_b - pi_fp) + hi_part);
    __int128 frac_val = FLOW_CHECKED_MOD((val), (one()));
    if (frac_val < 0) {
        frac_val = (frac_val + one());
    }
    if (frac_val <= FLOW_CHECKED_DIV((one()), (2))) {
        return frac_val;
    }
    return (one() - frac_val);
}

bool is_square_i32(int32_t n) {
    int32_t r = ((int32_t)(floor((sqrt(((double)(n))) + 0.5))));
    return (r * r) == n;
}

int32_t sqrt_cf_period_i32_ptr_i32_ptr_i32_ptr_i32(int32_t d, int32_t* a0_out, int32_t* period, int32_t* plen_out) {
    int32_t a0 = ((int32_t)(floor(sqrt(((double)(d))))));
    a0_out[0] = a0;
    int64_t m = 0;
    int64_t dd = 1;
    int64_t a = ((int64_t)(a0));
    int32_t n = 0;
    while (1) {
        m = ((dd * a) - m);
        dd = FLOW_CHECKED_DIV(((((int64_t)(d)) - (m * m))), (dd));
        a = FLOW_CHECKED_DIV(((((int64_t)(a0)) + m)), (dd));
        period[n] = ((int32_t)(a));
        n = (n + 1);
        if (a == (2 * ((int64_t)(a0)))) {
            break;
        }
        if (n > 10000) {
            return (-1);
        }
    }
    plen_out[0] = n;
    return 0;
}

__int128 ceil_div_i128_i128_i128(__int128 a0, __int128 b0) {
    __int128 a = a0;
    __int128 b = b0;
    if (b < 0) {
        a = (0 - a);
        b = (0 - b);
    }
    if (a >= 0) {
        return FLOW_CHECKED_DIV((((a + b) - 1)), (b));
    }
    return (0 - FLOW_CHECKED_DIV(((0 - a)), (b)));
}

int64_t best_b_positive_i128_i128_i64_ptr_i32_i32(__int128 alpha_fp, __int128 beta_fp, int64_t B, int32_t* period, int32_t plen) {
    if (B <= 0) {
        return 0;
    }
    int32_t cap = 128;
    int32_t* a = (int32_t*)(((int32_t*)(calloc(((int64_t)(cap)), 4))));
    int64_t* q = (int64_t*)(((int64_t*)(calloc(((int64_t)(cap)), 8))));
    __int128* delta = (__int128*)(((__int128*)(calloc(((int64_t)(cap)), 16))));
    a[0] = 0;
    q[0] = 1;
    int64_t q_minus1 = 0;
    delta[0] = alpha_fp;
    __int128 delta_minus1 = one();
    int32_t k = 1;
    int32_t extra = 6;
    int32_t len = 1;
    while (1) {
        if ((k + 2) >= cap) {
            int32_t ncap = (cap * 2);
            a = ((int32_t*)(realloc(((void*)(a)), (((int64_t)(ncap)) * 4))));
            q = ((int64_t*)(realloc(((void*)(q)), (((int64_t)(ncap)) * 8))));
            delta = ((__int128*)(realloc(((void*)(delta)), (((int64_t)(ncap)) * 16))));
            cap = ncap;
        }
        int32_t ak = period[FLOW_CHECKED_MOD(((k - 1)), (plen))];
        a[k] = ak;
        int64_t qk = ((((int64_t)(ak)) * q[(k - 1)]) + q_minus1);
        q_minus1 = q[(k - 1)];
        q[k] = qk;
        if (k == 1) {
            delta[k] = ((0 - (((__int128)(ak)) * delta[0])) + delta_minus1);
        } else {
            delta[k] = ((0 - (((__int128)(ak)) * delta[(k - 1)])) + delta[(k - 2)]);
        }
        len = (k + 1);
        if (qk > B) {
            extra = (extra - 1);
            if (extra <= 0) {
                break;
            }
        }
        k = (k + 1);
        if (k > 500) {
            break;
        }
    }
    int32_t max_i = (len - 1);
    int32_t* b_digits = (int32_t*)(((int32_t*)(calloc(((int64_t)((max_i + 1))), 4))));
    __int128 beta_rem = beta_fp;
    int32_t i = 1;
    while (i <= max_i) {
        __int128 d = delta[(i - 1)];
        if (d == 0) {
            b_digits[i] = 0;
        } else {
            __int128 bi = ceil_div_i128_i128_i128(beta_rem, d);
            if (bi > ((__int128)(a[i]))) {
                bi = ((__int128)(a[i]));
            }
            if (bi < 0) {
                bi = 0;
            }
            b_digits[i] = ((int32_t)(bi));
            beta_rem = ((bi * d) - beta_rem);
        }
        i = (i + 1);
    }
    int64_t* prefix = (int64_t*)(((int64_t*)(calloc(((int64_t)((max_i + 1))), 8))));
    int64_t s = 0;
    i = 1;
    while (i <= max_i) {
        s = (s + (((int64_t)(b_digits[i])) * q[(i - 1)]));
        prefix[i] = s;
        i = (i + 1);
    }
    int64_t* cand_r = (int64_t*)(((int64_t*)(calloc(200000, 8))));
    int64_t* cand_l = (int64_t*)(((int64_t*)(calloc(200000, 8))));
    int32_t nr = 0;
    int32_t nl = 0;
    cand_r[nr] = 0;
    nr = (nr + 1);
    cand_l[nl] = 0;
    nl = (nl + 1);
    int32_t k2 = 1;
    while ((2 * k2) < (max_i + 1)) {
        int32_t ie = (2 * k2);
        int32_t io = ((2 * k2) - 1);
        if (ie > max_i) {
            break;
        }
        int64_t P = prefix[io];
        int64_t st = q[io];
        int32_t j = 0;
        while (j < b_digits[ie]) {
            int64_t n = (P + (((int64_t)(j)) * st));
            if ((0 <= n && n <= B)) {
                cand_r[nr] = n;
                nr = (nr + 1);
            }
            j = (j + 1);
        }
        k2 = (k2 + 1);
    }
    k2 = 0;
    while (((2 * k2) + 1) <= max_i) {
        int32_t idx = (2 * k2);
        int32_t inn = (idx + 1);
        if (inn > max_i) {
            break;
        }
        int64_t P = prefix[idx];
        int64_t st = q[idx];
        int32_t j = 0;
        while (j < b_digits[inn]) {
            int64_t n = (P + (((int64_t)(j)) * st));
            if ((0 <= n && n <= B)) {
                cand_l[nl] = n;
                nl = (nl + 1);
            }
            j = (j + 1);
        }
        k2 = (k2 + 1);
    }
    __int128 best_r_gap = one();
    __int128 best_l_gap = one();
    int64_t best_r_n = 0;
    int64_t best_l_n = 0;
    i = 0;
    while (i < nr) {
        int64_t n = cand_r[i];
        __int128 x = frac_mul_i128_i64(alpha_fp, n);
        __int128 gap = (x - beta_fp);
        if (gap < 0) {
            gap = (gap + one());
        }
        if (gap < best_r_gap) {
            best_r_gap = gap;
            best_r_n = n;
        }
        i = (i + 1);
    }
    i = 0;
    while (i < nl) {
        int64_t n = cand_l[i];
        __int128 x = frac_mul_i128_i64(alpha_fp, n);
        __int128 gap = (beta_fp - x);
        if (gap < 0) {
            gap = (gap + one());
        }
        if (gap < best_l_gap) {
            best_l_gap = gap;
            best_l_n = n;
        }
        i = (i + 1);
    }
    int64_t ans = 0;
    if (best_r_gap < best_l_gap) {
        ans = best_r_n;
    } else {
        ans = best_l_n;
    }
    free(((void*)(delta)));
    free(((void*)(a)));
    free(((void*)(q)));
    free(((void*)(b_digits)));
    free(((void*)(prefix)));
    free(((void*)(cand_r)));
    free(((void*)(cand_l)));
    return ans;
}

int64_t bqa_pi_d_i32_i64_i128_i128(int32_t d, int64_t n, __int128 pi_fp, __int128 beta_fp) {
    int32_t* a0_ptr = (int32_t*)(((int32_t*)(calloc(1, 4))));
    int32_t* period = (int32_t*)(((int32_t*)(calloc(4096, 4))));
    int32_t* plen_ptr = (int32_t*)(((int32_t*)(calloc(1, 4))));
    sqrt_cf_period_i32_ptr_i32_ptr_i32_ptr_i32(d, a0_ptr, period, plen_ptr);
    int32_t a0 = a0_ptr[0];
    int32_t plen = plen_ptr[0];
    __int128 sqrt_D_fp = isqrt_scaled_i32(d);
    __int128 alpha_fp = (sqrt_D_fp - FLOW_CHECKED_SHL((((__int128)(a0))), (96)));
    double sqrt_d = sqrt(((double)(d)));
    double pi_d = 3.14159265358979323846;
    int64_t Bpos = ((int64_t)(floor(((pi_d + ((double)(n))) / sqrt_d))));
    if (Bpos < 0) {
        Bpos = 0;
    }
    if (Bpos > n) {
        Bpos = n;
    }
    int64_t Bneg = ((int64_t)(floor(((((double)(n)) - pi_d) / sqrt_d))));
    if (Bneg < 0) {
        Bneg = 0;
    }
    if (Bneg > n) {
        Bneg = n;
    }
    int64_t b_pos = best_b_positive_i128_i128_i64_ptr_i32_i32(alpha_fp, beta_fp, Bpos, period, plen);
    __int128 one_m_beta = (one() - beta_fp);
    int64_t t = best_b_positive_i128_i128_i64_ptr_i32_i32(alpha_fp, one_m_beta, Bneg, period, plen);
    int64_t b_neg = (0 - t);
    __int128 err1_fp = compute_error_fp_i128_i128_i64(sqrt_D_fp, pi_fp, b_pos);
    __int128 err2_fp = compute_error_fp_i128_i128_i64(sqrt_D_fp, pi_fp, b_neg);
    int64_t b_chosen = b_pos;
    if (err2_fp < err1_fp) {
        b_chosen = b_neg;
    }
    double a_real = (pi_d - (sqrt_d * ((double)(b_chosen))));
    int64_t a_out = ((int64_t)(round(a_real)));
    if (a_out > n) {
        a_out = n;
    }
    if (a_out < (0 - n)) {
        a_out = (0 - n);
    }
    free(((void*)(a0_ptr)));
    free(((void*)(period)));
    free(((void*)(plen_ptr)));
    return a_out;
}

int32_t main(void) {
    __int128 pi_fp = compute_pi_fp();
    __int128 beta_fp = (pi_fp - FLOW_CHECKED_SHL((((__int128)(3))), (96)));
    int64_t total = 0;
    int64_t n = 10000000000000;
    int32_t d = 2;
    while (d < 100) {
        if ((!(is_square_i32(d)))) {
            int64_t a = bqa_pi_d_i32_i64_i128_i128(d, n, pi_fp, beta_fp);
            if (a >= 0) {
                total = (total + a);
            } else {
                total = (total + (0 - a));
            }
        }
        d = (d + 1);
    }
    printf("%lld\n", total);
    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 @realloc(!llvm.ptr, i64) -> !llvm.ptr

  func.func private @sqrt(f64) -> f64
  func.func private @floor(f64) -> f64
  func.func private @round(f64) -> f64
  func.func @one() -> i128 {
    %0 = arith.constant 1 : i32
    %1 = arith.extsi %0 : i32 to i128
    %2 = arith.constant 96 : i32
    %4 = arith.trunci %1 : i128 to i64
    %5 = arith.extsi %2 : i32 to i64
    %3 = arith.shli %4, %5 : i64
    %6 = arith.extsi %3 : i64 to i128
    func.return %6 : i128
  }
  func.func @arctan_inv_scaled(%arg0: i32) -> i128 {
    %7 = arith.constant 0 : i32
    %8 = arith.extsi %7 : i32 to i128
    %9 = llvm.mlir.constant(1 : i64) : i64
    %10 = llvm.alloca %9 x i128 : (i64) -> !llvm.ptr
    llvm.store %8, %10 : i128, !llvm.ptr
    %11 = arith.extsi %arg0 : i32 to i128
    %12 = llvm.mlir.constant(1 : i64) : i64
    %13 = llvm.alloca %12 x i128 : (i64) -> !llvm.ptr
    llvm.store %11, %13 : i128, !llvm.ptr
    %14 = arith.extsi %arg0 : i32 to i128
    %15 = arith.extsi %arg0 : i32 to i128
    %17 = arith.trunci %14 : i128 to i64
    %18 = arith.trunci %15 : i128 to i64
    %16 = arith.muli %17, %18 : i64
    %19 = arith.extsi %16 : i64 to i128
    %20 = arith.constant 0 : i32
    %21 = llvm.mlir.constant(1 : i64) : i64
    %22 = llvm.alloca %21 x i32 : (i64) -> !llvm.ptr
    llvm.store %20, %22 : i32, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %23 = llvm.load %22 : !llvm.ptr -> i32
    %24 = arith.constant 60 : i32
    %25 = arith.cmpi slt, %23, %24 : i32
    cf.cond_br %25, ^bb1, ^bb2
    ^bb1:
      %26 = arith.constant 2 : i32
      %27 = llvm.load %22 : !llvm.ptr -> i32
      %28 = arith.muli %26, %27 : i32
      %29 = arith.constant 1 : i32
      %30 = arith.addi %28, %29 : i32
      %31 = arith.extsi %30 : i32 to i128
      %32 = llvm.load %13 : !llvm.ptr -> i128
      %34 = arith.trunci %31 : i128 to i64
      %35 = arith.trunci %32 : i128 to i64
      %33 = arith.muli %34, %35 : i64
      %36 = arith.extsi %33 : i64 to i128
      %37 = func.call @one() : () -> i128
      %39 = arith.trunci %36 : i128 to i64
      %40 = arith.trunci %37 : i128 to i64
      %38 = arith.cmpi sgt, %39, %40 : i64
      cf.cond_br %38, ^bb3, ^bb4
      ^bb3:
        cf.br ^bb2
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %41 = func.call @one() : () -> i128
      %43 = arith.trunci %41 : i128 to i64
      %44 = arith.trunci %36 : i128 to i64
      %42 = arith.divsi %43, %44 : i64
      %45 = arith.extsi %42 : i64 to i128
      %46 = llvm.load %22 : !llvm.ptr -> i32
      %47 = arith.constant 2 : i32
      %48 = arith.remsi %46, %47 : i32
      %49 = arith.constant 0 : i32
      %50 = arith.cmpi eq, %48, %49 : i32
      cf.cond_br %50, ^bb6, ^bb7
      ^bb6:
        %51 = llvm.load %10 : !llvm.ptr -> i128
        %53 = arith.trunci %51 : i128 to i64
        %54 = arith.trunci %45 : i128 to i64
        %52 = arith.addi %53, %54 : i64
        %55 = arith.extsi %52 : i64 to i128
        llvm.store %55, %10 : i128, !llvm.ptr
        cf.br ^bb8
      ^bb7:
        %56 = llvm.load %10 : !llvm.ptr -> i128
        %58 = arith.trunci %56 : i128 to i64
        %59 = arith.trunci %45 : i128 to i64
        %57 = arith.subi %58, %59 : i64
        %60 = arith.extsi %57 : i64 to i128
        llvm.store %60, %10 : i128, !llvm.ptr
        cf.br ^bb8
      ^bb8:
      %61 = llvm.load %13 : !llvm.ptr -> i128
      %63 = arith.trunci %61 : i128 to i64
      %64 = arith.trunci %19 : i128 to i64
      %62 = arith.muli %63, %64 : i64
      %65 = arith.extsi %62 : i64 to i128
      llvm.store %65, %13 : i128, !llvm.ptr
      %66 = llvm.load %22 : !llvm.ptr -> i32
      %67 = arith.constant 1 : i32
      %68 = arith.addi %66, %67 : i32
      llvm.store %68, %22 : i32, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %69 = llvm.load %10 : !llvm.ptr -> i128
    func.return %69 : i128
  }
  func.func @compute_pi_fp() -> i128 {
    %70 = arith.constant 16 : i32
    %72 = arith.constant 5 : i32
    %71 = func.call @arctan_inv_scaled(%72) : (i32) -> i128
    %74 = arith.extsi %70 : i32 to i64
    %75 = arith.trunci %71 : i128 to i64
    %73 = arith.muli %74, %75 : i64
    %76 = arith.constant 4 : i32
    %78 = arith.constant 239 : i32
    %77 = func.call @arctan_inv_scaled(%78) : (i32) -> i128
    %80 = arith.extsi %76 : i32 to i64
    %81 = arith.trunci %77 : i128 to i64
    %79 = arith.muli %80, %81 : i64
    %82 = arith.subi %73, %79 : i64
    %83 = arith.extsi %82 : i64 to i128
    func.return %83 : i128
  }
  func.func @floor_div(%arg0: i128, %arg1: i128) -> i128 {
    %85 = arith.trunci %arg0 : i128 to i64
    %86 = arith.trunci %arg1 : i128 to i64
    %84 = arith.divsi %85, %86 : i64
    %87 = arith.extsi %84 : i64 to i128
    %89 = arith.trunci %arg0 : i128 to i64
    %90 = arith.trunci %arg1 : i128 to i64
    %88 = arith.remsi %89, %90 : i64
    %91 = arith.extsi %88 : i64 to i128
    %92 = arith.constant 0 : i32
    %94 = arith.trunci %91 : i128 to i64
    %95 = arith.extsi %92 : i32 to i64
    %93 = arith.cmpi ne, %94, %95 : i64
    cf.cond_br %93, ^bb9, ^bb10
    ^bb9:
      %96 = arith.constant 0 : i32
      %98 = arith.trunci %arg0 : i128 to i64
      %99 = arith.extsi %96 : i32 to i64
      %97 = arith.cmpi slt, %98, %99 : i64
      %100 = scf.if %97 -> (i1) {
        %101 = arith.constant 0 : i32
        %103 = arith.trunci %arg1 : i128 to i64
        %104 = arith.extsi %101 : i32 to i64
        %102 = arith.cmpi sge, %103, %104 : i64
        scf.yield %102 : i1
      } else {
        %105 = arith.constant false
        scf.yield %105 : i1
      }
      %106 = scf.if %100 -> (i1) {
        %107 = arith.constant true
        scf.yield %107 : i1
      } else {
        %108 = arith.constant 0 : i32
        %110 = arith.trunci %arg0 : i128 to i64
        %111 = arith.extsi %108 : i32 to i64
        %109 = arith.cmpi sge, %110, %111 : i64
        %112 = scf.if %109 -> (i1) {
          %113 = arith.constant 0 : i32
          %115 = arith.trunci %arg1 : i128 to i64
          %116 = arith.extsi %113 : i32 to i64
          %114 = arith.cmpi slt, %115, %116 : i64
          scf.yield %114 : i1
        } else {
          %117 = arith.constant false
          scf.yield %117 : i1
        }
        scf.yield %112 : i1
      }
      cf.cond_br %106, ^bb12, ^bb13
      ^bb12:
        %118 = arith.constant 1 : i32
        %120 = arith.trunci %87 : i128 to i64
        %121 = arith.extsi %118 : i32 to i64
        %119 = arith.subi %120, %121 : i64
        %122 = arith.extsi %119 : i64 to i128
        func.return %122 : i128
      ^bb13:
        cf.br ^bb14
      ^bb14:
      cf.br ^bb11
    ^bb10:
      cf.br ^bb11
    ^bb11:
    func.return %87 : i128
  }
  func.func @isqrt_scaled(%arg0: i32) -> i128 {
    %123 = arith.extsi %arg0 : i32 to i128
    %124 = arith.constant 120 : i32
    %126 = arith.trunci %123 : i128 to i64
    %127 = arith.extsi %124 : i32 to i64
    %125 = arith.shli %126, %127 : i64
    %128 = arith.extsi %125 : i64 to i128
    %129 = arith.constant 1 : i32
    %130 = arith.extsi %129 : i32 to i64
    %131 = arith.constant 60 : i32
    %133 = arith.extsi %131 : i32 to i64
    %132 = arith.shli %130, %133 : i64
    %134 = arith.sitofp %132 : i64 to f64
    %135 = arith.sitofp %arg0 : i32 to f64
    %136 = math.sqrt %135 : f64
    %137 = arith.mulf %136, %134 : f64
    %138 = arith.fptosi %137 : f64 to i128
    %139 = llvm.mlir.constant(1 : i64) : i64
    %140 = llvm.alloca %139 x i128 : (i64) -> !llvm.ptr
    llvm.store %138, %140 : i128, !llvm.ptr
    %141 = arith.constant 0 : i32
    %142 = llvm.mlir.constant(1 : i64) : i64
    %143 = llvm.alloca %142 x i32 : (i64) -> !llvm.ptr
    llvm.store %141, %143 : i32, !llvm.ptr
    cf.br ^bb15
    ^bb15:
    %144 = llvm.load %143 : !llvm.ptr -> i32
    %145 = arith.constant 50 : i32
    %146 = arith.cmpi slt, %144, %145 : i32
    cf.cond_br %146, ^bb16, ^bb17
    ^bb16:
      %147 = llvm.load %140 : !llvm.ptr -> i128
      %149 = arith.trunci %128 : i128 to i64
      %150 = arith.trunci %147 : i128 to i64
      %148 = arith.divsi %149, %150 : i64
      %151 = arith.extsi %148 : i64 to i128
      %152 = llvm.load %140 : !llvm.ptr -> i128
      %154 = arith.trunci %152 : i128 to i64
      %155 = arith.trunci %151 : i128 to i64
      %153 = arith.addi %154, %155 : i64
      %156 = arith.constant 2 : i32
      %158 = arith.extsi %156 : i32 to i64
      %157 = arith.divsi %153, %158 : i64
      %159 = arith.extsi %157 : i64 to i128
      %160 = llvm.load %140 : !llvm.ptr -> i128
      %162 = arith.trunci %159 : i128 to i64
      %163 = arith.trunci %160 : i128 to i64
      %161 = arith.cmpi eq, %162, %163 : i64
      cf.cond_br %161, ^bb18, ^bb19
      ^bb18:
        cf.br ^bb17
      ^bb19:
        cf.br ^bb20
      ^bb20:
      llvm.store %159, %140 : i128, !llvm.ptr
      %164 = llvm.load %143 : !llvm.ptr -> i32
      %165 = arith.constant 1 : i32
      %166 = arith.addi %164, %165 : i32
      llvm.store %166, %143 : i32, !llvm.ptr
      cf.br ^bb15
    ^bb17:
    %167 = llvm.load %140 : !llvm.ptr -> i128
    %168 = arith.constant 36 : i32
    %170 = arith.trunci %167 : i128 to i64
    %171 = arith.extsi %168 : i32 to i64
    %169 = arith.shli %170, %171 : i64
    %172 = arith.extsi %169 : i64 to i128
    %173 = llvm.mlir.constant(1 : i64) : i64
    %174 = llvm.alloca %173 x i128 : (i64) -> !llvm.ptr
    llvm.store %172, %174 : i128, !llvm.ptr
    %176 = arith.constant 2.0 : f32
    %177 = arith.sitofp %arg0 : i32 to f64
    %178 = math.sqrt %177 : f64
    %180 = arith.extf %176 : f32 to f64
    %179 = arith.mulf %180, %178 : f64
    %175 = func.call @round(%179) : (f64) -> f64
    %181 = arith.fptosi %175 : f64 to i32
    %182 = llvm.mlir.constant(1 : i64) : i64
    %183 = llvm.alloca %182 x i32 : (i64) -> !llvm.ptr
    llvm.store %181, %183 : i32, !llvm.ptr
    %184 = llvm.load %183 : !llvm.ptr -> i32
    %185 = arith.constant 0 : i32
    %186 = arith.cmpi eq, %184, %185 : i32
    cf.cond_br %186, ^bb21, ^bb22
    ^bb21:
      %187 = arith.constant 1 : i32
      llvm.store %187, %183 : i32, !llvm.ptr
      cf.br ^bb23
    ^bb22:
      cf.br ^bb23
    ^bb23:
    %188 = arith.constant 0 : i32
    %189 = llvm.mlir.constant(1 : i64) : i64
    %190 = llvm.alloca %189 x i32 : (i64) -> !llvm.ptr
    llvm.store %188, %190 : i32, !llvm.ptr
    cf.br ^bb24
    ^bb24:
    %191 = llvm.load %190 : !llvm.ptr -> i32
    %192 = arith.constant 40 : i32
    %193 = arith.cmpi slt, %191, %192 : i32
    cf.cond_br %193, ^bb25, ^bb26
    ^bb25:
      %194 = llvm.load %174 : !llvm.ptr -> i128
      %195 = arith.constant 48 : i32
      %197 = arith.trunci %194 : i128 to i64
      %198 = arith.extsi %195 : i32 to i64
      %196 = arith.shrsi %197, %198 : i64
      %199 = arith.extsi %196 : i64 to i128
      %200 = llvm.load %174 : !llvm.ptr -> i128
      %201 = arith.constant 1 : i32
      %202 = arith.extsi %201 : i32 to i128
      %203 = arith.constant 48 : i32
      %205 = arith.trunci %202 : i128 to i64
      %206 = arith.extsi %203 : i32 to i64
      %204 = arith.shli %205, %206 : i64
      %207 = arith.constant 1 : i32
      %209 = arith.extsi %207 : i32 to i64
      %208 = arith.subi %204, %209 : i64
      %211 = arith.trunci %200 : i128 to i64
      %210 = arith.andi %211, %208 : i64
      %212 = arith.extsi %210 : i64 to i128
      %214 = arith.trunci %199 : i128 to i64
      %215 = arith.trunci %199 : i128 to i64
      %213 = arith.muli %214, %215 : i64
      %216 = arith.constant 2 : i32
      %218 = arith.extsi %216 : i32 to i64
      %219 = arith.trunci %199 : i128 to i64
      %217 = arith.muli %218, %219 : i64
      %221 = arith.trunci %212 : i128 to i64
      %220 = arith.muli %217, %221 : i64
      %222 = arith.constant 48 : i32
      %224 = arith.extsi %222 : i32 to i64
      %223 = arith.shrsi %220, %224 : i64
      %225 = arith.addi %213, %223 : i64
      %227 = arith.trunci %212 : i128 to i64
      %228 = arith.trunci %212 : i128 to i64
      %226 = arith.muli %227, %228 : i64
      %229 = arith.constant 96 : i32
      %231 = arith.extsi %229 : i32 to i64
      %230 = arith.shrsi %226, %231 : i64
      %232 = arith.addi %225, %230 : i64
      %233 = arith.extsi %232 : i64 to i128
      %234 = arith.extsi %arg0 : i32 to i128
      %235 = func.call @one() : () -> i128
      %237 = arith.trunci %234 : i128 to i64
      %238 = arith.trunci %235 : i128 to i64
      %236 = arith.muli %237, %238 : i64
      %240 = arith.trunci %233 : i128 to i64
      %239 = arith.subi %240, %236 : i64
      %241 = arith.extsi %239 : i64 to i128
      %242 = arith.constant 0 : i32
      %244 = arith.trunci %241 : i128 to i64
      %245 = arith.extsi %242 : i32 to i64
      %243 = arith.cmpi eq, %244, %245 : i64
      cf.cond_br %243, ^bb27, ^bb28
      ^bb27:
        cf.br ^bb26
      ^bb28:
        cf.br ^bb29
      ^bb29:
      %246 = arith.constant 0 : i32
      %247 = arith.extsi %246 : i32 to i128
      %248 = llvm.mlir.constant(1 : i64) : i64
      %249 = llvm.alloca %248 x i128 : (i64) -> !llvm.ptr
      llvm.store %247, %249 : i128, !llvm.ptr
      %250 = arith.constant 0 : i32
      %251 = arith.constant 1 : i32
      %252 = arith.extsi %251 : i32 to i128
      %253 = arith.constant 30 : i32
      %255 = arith.trunci %252 : i128 to i64
      %256 = arith.extsi %253 : i32 to i64
      %254 = arith.shli %255, %256 : i64
      %258 = arith.extsi %250 : i32 to i64
      %257 = arith.subi %258, %254 : i64
      %260 = arith.trunci %241 : i128 to i64
      %259 = arith.cmpi sge, %260, %257 : i64
      %261 = scf.if %259 -> (i1) {
        %262 = arith.constant 1 : i32
        %263 = arith.extsi %262 : i32 to i128
        %264 = arith.constant 30 : i32
        %266 = arith.trunci %263 : i128 to i64
        %267 = arith.extsi %264 : i32 to i64
        %265 = arith.shli %266, %267 : i64
        %269 = arith.trunci %241 : i128 to i64
        %268 = arith.cmpi sle, %269, %265 : i64
        scf.yield %268 : i1
      } else {
        %270 = arith.constant false
        scf.yield %270 : i1
      }
      cf.cond_br %261, ^bb30, ^bb31
      ^bb30:
        %272 = func.call @one() : () -> i128
        %274 = arith.trunci %241 : i128 to i64
        %275 = arith.trunci %272 : i128 to i64
        %273 = arith.muli %274, %275 : i64
        %276 = arith.constant 2 : i32
        %277 = arith.extsi %276 : i32 to i128
        %278 = llvm.load %174 : !llvm.ptr -> i128
        %280 = arith.trunci %277 : i128 to i64
        %281 = arith.trunci %278 : i128 to i64
        %279 = arith.muli %280, %281 : i64
        %282 = arith.extsi %273 : i64 to i128
        %283 = arith.extsi %279 : i64 to i128
        %271 = func.call @floor_div(%282, %283) : (i128, i128) -> i128
        llvm.store %271, %249 : i128, !llvm.ptr
        %284 = llvm.load %249 : !llvm.ptr -> i128
        %285 = arith.constant 0 : i32
        %287 = arith.trunci %284 : i128 to i64
        %288 = arith.extsi %285 : i32 to i64
        %286 = arith.cmpi eq, %287, %288 : i64
        cf.cond_br %286, ^bb33, ^bb34
        ^bb33:
          %289 = arith.constant 0 : i32
          %291 = arith.trunci %241 : i128 to i64
          %292 = arith.extsi %289 : i32 to i64
          %290 = arith.cmpi sgt, %291, %292 : i64
          cf.cond_br %290, ^bb36, ^bb37
          ^bb36:
            %293 = arith.constant 1 : i32
            %294 = arith.extsi %293 : i32 to i128
            llvm.store %294, %249 : i128, !llvm.ptr
            cf.br ^bb38
          ^bb37:
            %295 = arith.constant 0 : i32
            %296 = arith.constant 1 : i32
            %297 = arith.subi %295, %296 : i32
            %298 = arith.extsi %297 : i32 to i128
            llvm.store %298, %249 : i128, !llvm.ptr
            cf.br ^bb38
          ^bb38:
          cf.br ^bb35
        ^bb34:
          cf.br ^bb35
        ^bb35:
        cf.br ^bb32
      ^bb31:
        %300 = llvm.load %183 : !llvm.ptr -> i32
        %301 = arith.extsi %300 : i32 to i128
        %299 = func.call @floor_div(%241, %301) : (i128, i128) -> i128
        llvm.store %299, %249 : i128, !llvm.ptr
        cf.br ^bb32
      ^bb32:
      %302 = llvm.load %249 : !llvm.ptr -> i128
      %303 = arith.constant 0 : i32
      %305 = arith.trunci %302 : i128 to i64
      %306 = arith.extsi %303 : i32 to i64
      %304 = arith.cmpi eq, %305, %306 : i64
      cf.cond_br %304, ^bb39, ^bb40
      ^bb39:
        cf.br ^bb26
      ^bb40:
        cf.br ^bb41
      ^bb41:
      %307 = llvm.load %174 : !llvm.ptr -> i128
      %308 = llvm.load %249 : !llvm.ptr -> i128
      %310 = arith.trunci %307 : i128 to i64
      %311 = arith.trunci %308 : i128 to i64
      %309 = arith.subi %310, %311 : i64
      %312 = arith.extsi %309 : i64 to i128
      llvm.store %312, %174 : i128, !llvm.ptr
      %313 = llvm.load %190 : !llvm.ptr -> i32
      %314 = arith.constant 1 : i32
      %315 = arith.addi %313, %314 : i32
      llvm.store %315, %190 : i32, !llvm.ptr
      cf.br ^bb24
    ^bb26:
    %316 = llvm.load %174 : !llvm.ptr -> i128
    func.return %316 : i128
  }
  func.func @frac_mul(%arg0: i128, %arg1: i64) -> i128 {
    %317 = arith.constant 1 : i32
    %318 = arith.extsi %317 : i32 to i128
    %319 = arith.constant 64 : i32
    %321 = arith.trunci %318 : i128 to i64
    %322 = arith.extsi %319 : i32 to i64
    %320 = arith.shli %321, %322 : i64
    %323 = arith.constant 1 : i32
    %325 = arith.extsi %323 : i32 to i64
    %324 = arith.subi %320, %325 : i64
    %326 = arith.extsi %324 : i64 to i128
    %328 = arith.trunci %arg0 : i128 to i64
    %329 = arith.trunci %326 : i128 to i64
    %327 = arith.andi %328, %329 : i64
    %330 = arith.extsi %327 : i64 to i128
    %331 = arith.constant 64 : i32
    %333 = arith.trunci %arg0 : i128 to i64
    %334 = arith.extsi %331 : i32 to i64
    %332 = arith.shrsi %333, %334 : i64
    %336 = arith.trunci %326 : i128 to i64
    %335 = arith.andi %332, %336 : i64
    %337 = arith.extsi %335 : i64 to i128
    %338 = arith.extsi %arg1 : i64 to i128
    %340 = arith.trunci %330 : i128 to i64
    %341 = arith.trunci %338 : i128 to i64
    %339 = arith.muli %340, %341 : i64
    %342 = arith.extsi %339 : i64 to i128
    %343 = arith.extsi %arg1 : i64 to i128
    %345 = arith.trunci %337 : i128 to i64
    %346 = arith.trunci %343 : i128 to i64
    %344 = arith.muli %345, %346 : i64
    %347 = arith.extsi %344 : i64 to i128
    %348 = arith.constant 1 : i32
    %349 = arith.extsi %348 : i32 to i128
    %350 = arith.constant 32 : i32
    %352 = arith.trunci %349 : i128 to i64
    %353 = arith.extsi %350 : i32 to i64
    %351 = arith.shli %352, %353 : i64
    %354 = arith.constant 1 : i32
    %356 = arith.extsi %354 : i32 to i64
    %355 = arith.subi %351, %356 : i64
    %358 = arith.trunci %347 : i128 to i64
    %357 = arith.andi %358, %355 : i64
    %359 = arith.extsi %357 : i64 to i128
    %360 = arith.constant 64 : i32
    %362 = arith.trunci %359 : i128 to i64
    %363 = arith.extsi %360 : i32 to i64
    %361 = arith.shli %362, %363 : i64
    %364 = arith.extsi %361 : i64 to i128
    %366 = arith.trunci %342 : i128 to i64
    %367 = arith.trunci %364 : i128 to i64
    %365 = arith.addi %366, %367 : i64
    %368 = func.call @one() : () -> i128
    %369 = arith.constant 1 : i32
    %371 = arith.trunci %368 : i128 to i64
    %372 = arith.extsi %369 : i32 to i64
    %370 = arith.subi %371, %372 : i64
    %373 = arith.andi %365, %370 : i64
    %374 = arith.extsi %373 : i64 to i128
    func.return %374 : i128
  }
  func.func @compute_error_fp(%arg0: i128, %arg1: i128, %arg2: i64) -> i128 {
    %375 = arith.constant 1 : i32
    %376 = arith.extsi %375 : i32 to i128
    %377 = arith.constant 64 : i32
    %379 = arith.trunci %376 : i128 to i64
    %380 = arith.extsi %377 : i32 to i64
    %378 = arith.shli %379, %380 : i64
    %381 = arith.constant 1 : i32
    %383 = arith.extsi %381 : i32 to i64
    %382 = arith.subi %378, %383 : i64
    %384 = arith.extsi %382 : i64 to i128
    %386 = arith.trunci %arg0 : i128 to i64
    %387 = arith.trunci %384 : i128 to i64
    %385 = arith.andi %386, %387 : i64
    %388 = arith.extsi %385 : i64 to i128
    %389 = arith.constant 64 : i32
    %391 = arith.trunci %arg0 : i128 to i64
    %392 = arith.extsi %389 : i32 to i64
    %390 = arith.shrsi %391, %392 : i64
    %394 = arith.trunci %384 : i128 to i64
    %393 = arith.andi %390, %394 : i64
    %395 = arith.extsi %393 : i64 to i128
    %396 = arith.extsi %arg2 : i64 to i128
    %398 = arith.trunci %388 : i128 to i64
    %399 = arith.trunci %396 : i128 to i64
    %397 = arith.muli %398, %399 : i64
    %400 = arith.extsi %397 : i64 to i128
    %401 = arith.extsi %arg2 : i64 to i128
    %403 = arith.trunci %395 : i128 to i64
    %404 = arith.trunci %401 : i128 to i64
    %402 = arith.muli %403, %404 : i64
    %405 = arith.extsi %402 : i64 to i128
    %406 = arith.constant 1 : i32
    %407 = arith.extsi %406 : i32 to i128
    %408 = arith.constant 32 : i32
    %410 = arith.trunci %407 : i128 to i64
    %411 = arith.extsi %408 : i32 to i64
    %409 = arith.shli %410, %411 : i64
    %412 = arith.constant 1 : i32
    %414 = arith.extsi %412 : i32 to i64
    %413 = arith.subi %409, %414 : i64
    %416 = arith.trunci %405 : i128 to i64
    %415 = arith.andi %416, %413 : i64
    %417 = arith.extsi %415 : i64 to i128
    %418 = arith.constant 64 : i32
    %420 = arith.trunci %417 : i128 to i64
    %421 = arith.extsi %418 : i32 to i64
    %419 = arith.shli %420, %421 : i64
    %422 = arith.extsi %419 : i64 to i128
    %424 = arith.trunci %400 : i128 to i64
    %425 = arith.trunci %arg1 : i128 to i64
    %423 = arith.subi %424, %425 : i64
    %427 = arith.trunci %422 : i128 to i64
    %426 = arith.addi %423, %427 : i64
    %428 = arith.extsi %426 : i64 to i128
    %429 = func.call @one() : () -> i128
    %431 = arith.trunci %428 : i128 to i64
    %432 = arith.trunci %429 : i128 to i64
    %430 = arith.remsi %431, %432 : i64
    %433 = arith.extsi %430 : i64 to i128
    %434 = llvm.mlir.constant(1 : i64) : i64
    %435 = llvm.alloca %434 x i128 : (i64) -> !llvm.ptr
    llvm.store %433, %435 : i128, !llvm.ptr
    %436 = llvm.load %435 : !llvm.ptr -> i128
    %437 = arith.constant 0 : i32
    %439 = arith.trunci %436 : i128 to i64
    %440 = arith.extsi %437 : i32 to i64
    %438 = arith.cmpi slt, %439, %440 : i64
    cf.cond_br %438, ^bb42, ^bb43
    ^bb42:
      %441 = llvm.load %435 : !llvm.ptr -> i128
      %442 = func.call @one() : () -> i128
      %444 = arith.trunci %441 : i128 to i64
      %445 = arith.trunci %442 : i128 to i64
      %443 = arith.addi %444, %445 : i64
      %446 = arith.extsi %443 : i64 to i128
      llvm.store %446, %435 : i128, !llvm.ptr
      cf.br ^bb44
    ^bb43:
      cf.br ^bb44
    ^bb44:
    %447 = llvm.load %435 : !llvm.ptr -> i128
    %448 = func.call @one() : () -> i128
    %449 = arith.constant 2 : i32
    %451 = arith.trunci %448 : i128 to i64
    %452 = arith.extsi %449 : i32 to i64
    %450 = arith.divsi %451, %452 : i64
    %454 = arith.trunci %447 : i128 to i64
    %453 = arith.cmpi sle, %454, %450 : i64
    cf.cond_br %453, ^bb45, ^bb46
    ^bb45:
      %455 = llvm.load %435 : !llvm.ptr -> i128
      func.return %455 : i128
    ^bb46:
      cf.br ^bb47
    ^bb47:
    %456 = func.call @one() : () -> i128
    %457 = llvm.load %435 : !llvm.ptr -> i128
    %459 = arith.trunci %456 : i128 to i64
    %460 = arith.trunci %457 : i128 to i64
    %458 = arith.subi %459, %460 : i64
    %461 = arith.extsi %458 : i64 to i128
    func.return %461 : i128
  }
  func.func @is_square(%arg0: i32) -> i1 {
    %463 = arith.sitofp %arg0 : i32 to f64
    %464 = math.sqrt %463 : f64
    %465 = arith.constant 0.5 : f32
    %467 = arith.extf %465 : f32 to f64
    %466 = arith.addf %464, %467 : f64
    %462 = func.call @floor(%466) : (f64) -> f64
    %468 = arith.fptosi %462 : f64 to i32
    %469 = arith.muli %468, %468 : i32
    %470 = arith.cmpi eq, %469, %arg0 : i32
    func.return %470 : i1
  }
  func.func @sqrt_cf_period(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr) -> i32 {
    %472 = arith.sitofp %arg0 : i32 to f64
    %473 = math.sqrt %472 : f64
    %471 = func.call @floor(%473) : (f64) -> f64
    %474 = arith.fptosi %471 : f64 to i32
    %475 = arith.constant 0 : i32
    %476 = arith.extsi %475 : i32 to i64
    %477 = llvm.getelementptr %arg1[%476] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %474, %477 : i32, !llvm.ptr
    %478 = arith.constant 0 : i32
    %479 = arith.extsi %478 : i32 to i64
    %480 = llvm.mlir.constant(1 : i64) : i64
    %481 = llvm.alloca %480 x i64 : (i64) -> !llvm.ptr
    llvm.store %479, %481 : i64, !llvm.ptr
    %482 = arith.constant 1 : i32
    %483 = arith.extsi %482 : i32 to i64
    %484 = llvm.mlir.constant(1 : i64) : i64
    %485 = llvm.alloca %484 x i64 : (i64) -> !llvm.ptr
    llvm.store %483, %485 : i64, !llvm.ptr
    %486 = arith.extsi %474 : i32 to i64
    %487 = llvm.mlir.constant(1 : i64) : i64
    %488 = llvm.alloca %487 x i64 : (i64) -> !llvm.ptr
    llvm.store %486, %488 : i64, !llvm.ptr
    %489 = arith.constant 0 : i32
    %490 = llvm.mlir.constant(1 : i64) : i64
    %491 = llvm.alloca %490 x i32 : (i64) -> !llvm.ptr
    llvm.store %489, %491 : i32, !llvm.ptr
    cf.br ^bb48
    ^bb48:
    %492 = arith.constant 1 : i1
    cf.cond_br %492, ^bb49, ^bb50
    ^bb49:
      %493 = llvm.load %485 : !llvm.ptr -> i64
      %494 = llvm.load %488 : !llvm.ptr -> i64
      %495 = arith.muli %493, %494 : i64
      %496 = llvm.load %481 : !llvm.ptr -> i64
      %497 = arith.subi %495, %496 : i64
      llvm.store %497, %481 : i64, !llvm.ptr
      %498 = arith.extsi %arg0 : i32 to i64
      %499 = llvm.load %481 : !llvm.ptr -> i64
      %500 = llvm.load %481 : !llvm.ptr -> i64
      %501 = arith.muli %499, %500 : i64
      %502 = arith.subi %498, %501 : i64
      %503 = llvm.load %485 : !llvm.ptr -> i64
      %504 = arith.divsi %502, %503 : i64
      llvm.store %504, %485 : i64, !llvm.ptr
      %505 = arith.extsi %474 : i32 to i64
      %506 = llvm.load %481 : !llvm.ptr -> i64
      %507 = arith.addi %505, %506 : i64
      %508 = llvm.load %485 : !llvm.ptr -> i64
      %509 = arith.divsi %507, %508 : i64
      llvm.store %509, %488 : i64, !llvm.ptr
      %510 = llvm.load %488 : !llvm.ptr -> i64
      %511 = arith.trunci %510 : i64 to i32
      %512 = llvm.load %491 : !llvm.ptr -> i32
      %513 = arith.extsi %512 : i32 to i64
      %514 = llvm.getelementptr %arg2[%513] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %511, %514 : i32, !llvm.ptr
      %515 = llvm.load %491 : !llvm.ptr -> i32
      %516 = arith.constant 1 : i32
      %517 = arith.addi %515, %516 : i32
      llvm.store %517, %491 : i32, !llvm.ptr
      %518 = llvm.load %488 : !llvm.ptr -> i64
      %519 = arith.constant 2 : i32
      %520 = arith.extsi %474 : i32 to i64
      %522 = arith.extsi %519 : i32 to i64
      %521 = arith.muli %522, %520 : i64
      %523 = arith.cmpi eq, %518, %521 : i64
      cf.cond_br %523, ^bb51, ^bb52
      ^bb51:
        cf.br ^bb50
      ^bb52:
        cf.br ^bb53
      ^bb53:
      %524 = llvm.load %491 : !llvm.ptr -> i32
      %525 = arith.constant 10000 : i32
      %526 = arith.cmpi sgt, %524, %525 : i32
      cf.cond_br %526, ^bb54, ^bb55
      ^bb54:
        %527 = arith.constant 1 : i32
        %529 = arith.constant 0 : i32
        %528 = arith.subi %529, %527 : i32
        func.return %528 : i32
      ^bb55:
        cf.br ^bb56
      ^bb56:
      cf.br ^bb48
    ^bb50:
    %530 = llvm.load %491 : !llvm.ptr -> i32
    %531 = arith.constant 0 : i32
    %532 = arith.extsi %531 : i32 to i64
    %533 = llvm.getelementptr %arg3[%532] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %530, %533 : i32, !llvm.ptr
    %534 = arith.constant 0 : i32
    func.return %534 : i32
  }
  func.func @ceil_div_i128(%arg0: i128, %arg1: i128) -> i128 {
    %535 = llvm.mlir.constant(1 : i64) : i64
    %536 = llvm.alloca %535 x i128 : (i64) -> !llvm.ptr
    llvm.store %arg0, %536 : i128, !llvm.ptr
    %537 = llvm.mlir.constant(1 : i64) : i64
    %538 = llvm.alloca %537 x i128 : (i64) -> !llvm.ptr
    llvm.store %arg1, %538 : i128, !llvm.ptr
    %539 = llvm.load %538 : !llvm.ptr -> i128
    %540 = arith.constant 0 : i32
    %542 = arith.trunci %539 : i128 to i64
    %543 = arith.extsi %540 : i32 to i64
    %541 = arith.cmpi slt, %542, %543 : i64
    cf.cond_br %541, ^bb57, ^bb58
    ^bb57:
      %544 = arith.constant 0 : i32
      %545 = llvm.load %536 : !llvm.ptr -> i128
      %547 = arith.extsi %544 : i32 to i64
      %548 = arith.trunci %545 : i128 to i64
      %546 = arith.subi %547, %548 : i64
      %549 = arith.extsi %546 : i64 to i128
      llvm.store %549, %536 : i128, !llvm.ptr
      %550 = arith.constant 0 : i32
      %551 = llvm.load %538 : !llvm.ptr -> i128
      %553 = arith.extsi %550 : i32 to i64
      %554 = arith.trunci %551 : i128 to i64
      %552 = arith.subi %553, %554 : i64
      %555 = arith.extsi %552 : i64 to i128
      llvm.store %555, %538 : i128, !llvm.ptr
      cf.br ^bb59
    ^bb58:
      cf.br ^bb59
    ^bb59:
    %556 = llvm.load %536 : !llvm.ptr -> i128
    %557 = arith.constant 0 : i32
    %559 = arith.trunci %556 : i128 to i64
    %560 = arith.extsi %557 : i32 to i64
    %558 = arith.cmpi sge, %559, %560 : i64
    cf.cond_br %558, ^bb60, ^bb61
    ^bb60:
      %561 = llvm.load %536 : !llvm.ptr -> i128
      %562 = llvm.load %538 : !llvm.ptr -> i128
      %564 = arith.trunci %561 : i128 to i64
      %565 = arith.trunci %562 : i128 to i64
      %563 = arith.addi %564, %565 : i64
      %566 = arith.constant 1 : i32
      %568 = arith.extsi %566 : i32 to i64
      %567 = arith.subi %563, %568 : i64
      %569 = llvm.load %538 : !llvm.ptr -> i128
      %571 = arith.trunci %569 : i128 to i64
      %570 = arith.divsi %567, %571 : i64
      %572 = arith.extsi %570 : i64 to i128
      func.return %572 : i128
    ^bb61:
      cf.br ^bb62
    ^bb62:
    %573 = arith.constant 0 : i32
    %574 = arith.constant 0 : i32
    %575 = llvm.load %536 : !llvm.ptr -> i128
    %577 = arith.extsi %574 : i32 to i64
    %578 = arith.trunci %575 : i128 to i64
    %576 = arith.subi %577, %578 : i64
    %579 = llvm.load %538 : !llvm.ptr -> i128
    %581 = arith.trunci %579 : i128 to i64
    %580 = arith.divsi %576, %581 : i64
    %583 = arith.extsi %573 : i32 to i64
    %582 = arith.subi %583, %580 : i64
    %584 = arith.extsi %582 : i64 to i128
    func.return %584 : i128
  }
  func.func @best_b_positive(%arg0: i128, %arg1: i128, %arg2: i64, %arg3: !llvm.ptr, %arg4: i32) -> i64 {
    %585 = arith.constant 0 : i32
    %587 = arith.extsi %585 : i32 to i64
    %586 = arith.cmpi sle, %arg2, %587 : i64
    cf.cond_br %586, ^bb63, ^bb64
    ^bb63:
      %588 = arith.constant 0 : i32
      %589 = arith.extsi %588 : i32 to i64
      func.return %589 : i64
    ^bb64:
      cf.br ^bb65
    ^bb65:
    %590 = arith.constant 128 : i32
    %591 = llvm.mlir.constant(1 : i64) : i64
    %592 = llvm.alloca %591 x i32 : (i64) -> !llvm.ptr
    llvm.store %590, %592 : i32, !llvm.ptr
    %594 = llvm.load %592 : !llvm.ptr -> i32
    %595 = arith.extsi %594 : i32 to i64
    %596 = arith.constant 4 : i32
    %597 = arith.extsi %596 : i32 to i64
    %593 = func.call @calloc(%595, %597) : (i64, i64) -> !llvm.ptr
    %598 = llvm.mlir.constant(1 : i64) : i64
    %599 = llvm.alloca %598 x !llvm.ptr : (i64) -> !llvm.ptr
    llvm.store %593, %599 : !llvm.ptr, !llvm.ptr
    %601 = llvm.load %592 : !llvm.ptr -> i32
    %602 = arith.extsi %601 : i32 to i64
    %603 = arith.constant 8 : i32
    %604 = arith.extsi %603 : i32 to i64
    %600 = func.call @calloc(%602, %604) : (i64, i64) -> !llvm.ptr
    %605 = llvm.mlir.constant(1 : i64) : i64
    %606 = llvm.alloca %605 x !llvm.ptr : (i64) -> !llvm.ptr
    llvm.store %600, %606 : !llvm.ptr, !llvm.ptr
    %608 = llvm.load %592 : !llvm.ptr -> i32
    %609 = arith.extsi %608 : i32 to i64
    %610 = arith.constant 16 : i32
    %611 = arith.extsi %610 : i32 to i64
    %607 = func.call @calloc(%609, %611) : (i64, i64) -> !llvm.ptr
    %612 = llvm.mlir.constant(1 : i64) : i64
    %613 = llvm.alloca %612 x !llvm.ptr : (i64) -> !llvm.ptr
    llvm.store %607, %613 : !llvm.ptr, !llvm.ptr
    %614 = arith.constant 0 : i32
    %615 = llvm.load %599 : !llvm.ptr -> !llvm.ptr
    %616 = arith.constant 0 : i32
    %617 = arith.extsi %616 : i32 to i64
    %618 = llvm.getelementptr %615[%617] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %614, %618 : i32, !llvm.ptr
    %619 = arith.constant 1 : i32
    %620 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
    %621 = arith.constant 0 : i32
    %622 = arith.extsi %619 : i32 to i64
    %623 = arith.extsi %621 : i32 to i64
    %624 = llvm.getelementptr %620[%623] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %622, %624 : i64, !llvm.ptr
    %625 = arith.constant 0 : i32
    %626 = arith.extsi %625 : i32 to i64
    %627 = llvm.mlir.constant(1 : i64) : i64
    %628 = llvm.alloca %627 x i64 : (i64) -> !llvm.ptr
    llvm.store %626, %628 : i64, !llvm.ptr
    %629 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
    %630 = arith.constant 0 : i32
    %631 = arith.extsi %630 : i32 to i64
    %632 = llvm.getelementptr %629[%631] : (!llvm.ptr, i64) -> !llvm.ptr, i128
    llvm.store %arg0, %632 : i128, !llvm.ptr
    %633 = func.call @one() : () -> i128
    %634 = arith.constant 1 : i32
    %635 = llvm.mlir.constant(1 : i64) : i64
    %636 = llvm.alloca %635 x i32 : (i64) -> !llvm.ptr
    llvm.store %634, %636 : i32, !llvm.ptr
    %637 = arith.constant 6 : i32
    %638 = llvm.mlir.constant(1 : i64) : i64
    %639 = llvm.alloca %638 x i32 : (i64) -> !llvm.ptr
    llvm.store %637, %639 : i32, !llvm.ptr
    %640 = arith.constant 1 : i32
    %641 = llvm.mlir.constant(1 : i64) : i64
    %642 = llvm.alloca %641 x i32 : (i64) -> !llvm.ptr
    llvm.store %640, %642 : i32, !llvm.ptr
    cf.br ^bb66
    ^bb66:
    %643 = arith.constant 1 : i1
    cf.cond_br %643, ^bb67, ^bb68
    ^bb67:
      %644 = llvm.load %636 : !llvm.ptr -> i32
      %645 = arith.constant 2 : i32
      %646 = arith.addi %644, %645 : i32
      %647 = llvm.load %592 : !llvm.ptr -> i32
      %648 = arith.cmpi sge, %646, %647 : i32
      cf.cond_br %648, ^bb69, ^bb70
      ^bb69:
        %649 = llvm.load %592 : !llvm.ptr -> i32
        %650 = arith.constant 2 : i32
        %651 = arith.muli %649, %650 : i32
        %653 = llvm.load %599 : !llvm.ptr -> !llvm.ptr
        %654 = arith.extsi %651 : i32 to i64
        %655 = arith.constant 4 : i32
        %657 = arith.extsi %655 : i32 to i64
        %656 = arith.muli %654, %657 : i64
        %652 = func.call @realloc(%653, %656) : (!llvm.ptr, i64) -> !llvm.ptr
        llvm.store %652, %599 : !llvm.ptr, !llvm.ptr
        %659 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
        %660 = arith.extsi %651 : i32 to i64
        %661 = arith.constant 8 : i32
        %663 = arith.extsi %661 : i32 to i64
        %662 = arith.muli %660, %663 : i64
        %658 = func.call @realloc(%659, %662) : (!llvm.ptr, i64) -> !llvm.ptr
        llvm.store %658, %606 : !llvm.ptr, !llvm.ptr
        %665 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
        %666 = arith.extsi %651 : i32 to i64
        %667 = arith.constant 16 : i32
        %669 = arith.extsi %667 : i32 to i64
        %668 = arith.muli %666, %669 : i64
        %664 = func.call @realloc(%665, %668) : (!llvm.ptr, i64) -> !llvm.ptr
        llvm.store %664, %613 : !llvm.ptr, !llvm.ptr
        llvm.store %651, %592 : i32, !llvm.ptr
        cf.br ^bb71
      ^bb70:
        cf.br ^bb71
      ^bb71:
      %671 = llvm.load %636 : !llvm.ptr -> i32
      %672 = arith.constant 1 : i32
      %673 = arith.subi %671, %672 : i32
      %674 = arith.remsi %673, %arg4 : i32
      %675 = arith.extsi %674 : i32 to i64
      %676 = llvm.getelementptr %arg3[%675] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %670 = llvm.load %676 : !llvm.ptr -> i32
      %677 = llvm.load %599 : !llvm.ptr -> !llvm.ptr
      %678 = llvm.load %636 : !llvm.ptr -> i32
      %679 = arith.extsi %678 : i32 to i64
      %680 = llvm.getelementptr %677[%679] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %670, %680 : i32, !llvm.ptr
      %681 = arith.extsi %670 : i32 to i64
      %683 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
      %684 = llvm.load %636 : !llvm.ptr -> i32
      %685 = arith.constant 1 : i32
      %686 = arith.subi %684, %685 : i32
      %687 = arith.extsi %686 : i32 to i64
      %688 = llvm.getelementptr %683[%687] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %682 = llvm.load %688 : !llvm.ptr -> i64
      %689 = arith.muli %681, %682 : i64
      %690 = llvm.load %628 : !llvm.ptr -> i64
      %691 = arith.addi %689, %690 : i64
      %693 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
      %694 = llvm.load %636 : !llvm.ptr -> i32
      %695 = arith.constant 1 : i32
      %696 = arith.subi %694, %695 : i32
      %697 = arith.extsi %696 : i32 to i64
      %698 = llvm.getelementptr %693[%697] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %692 = llvm.load %698 : !llvm.ptr -> i64
      llvm.store %692, %628 : i64, !llvm.ptr
      %699 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
      %700 = llvm.load %636 : !llvm.ptr -> i32
      %701 = arith.extsi %700 : i32 to i64
      %702 = llvm.getelementptr %699[%701] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %691, %702 : i64, !llvm.ptr
      %703 = llvm.load %636 : !llvm.ptr -> i32
      %704 = arith.constant 1 : i32
      %705 = arith.cmpi eq, %703, %704 : i32
      cf.cond_br %705, ^bb72, ^bb73
      ^bb72:
        %706 = arith.constant 0 : i32
        %707 = arith.extsi %670 : i32 to i128
        %709 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
        %710 = arith.constant 0 : i32
        %711 = arith.extsi %710 : i32 to i64
        %712 = llvm.getelementptr %709[%711] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        %708 = llvm.load %712 : !llvm.ptr -> i128
        %714 = arith.trunci %707 : i128 to i64
        %715 = arith.trunci %708 : i128 to i64
        %713 = arith.muli %714, %715 : i64
        %717 = arith.extsi %706 : i32 to i64
        %716 = arith.subi %717, %713 : i64
        %719 = arith.trunci %633 : i128 to i64
        %718 = arith.addi %716, %719 : i64
        %720 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
        %721 = llvm.load %636 : !llvm.ptr -> i32
        %722 = arith.extsi %718 : i64 to i128
        %723 = arith.extsi %721 : i32 to i64
        %724 = llvm.getelementptr %720[%723] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        llvm.store %722, %724 : i128, !llvm.ptr
        cf.br ^bb74
      ^bb73:
        %725 = arith.constant 0 : i32
        %726 = arith.extsi %670 : i32 to i128
        %728 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
        %729 = llvm.load %636 : !llvm.ptr -> i32
        %730 = arith.constant 1 : i32
        %731 = arith.subi %729, %730 : i32
        %732 = arith.extsi %731 : i32 to i64
        %733 = llvm.getelementptr %728[%732] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        %727 = llvm.load %733 : !llvm.ptr -> i128
        %735 = arith.trunci %726 : i128 to i64
        %736 = arith.trunci %727 : i128 to i64
        %734 = arith.muli %735, %736 : i64
        %738 = arith.extsi %725 : i32 to i64
        %737 = arith.subi %738, %734 : i64
        %740 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
        %741 = llvm.load %636 : !llvm.ptr -> i32
        %742 = arith.constant 2 : i32
        %743 = arith.subi %741, %742 : i32
        %744 = arith.extsi %743 : i32 to i64
        %745 = llvm.getelementptr %740[%744] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        %739 = llvm.load %745 : !llvm.ptr -> i128
        %747 = arith.trunci %739 : i128 to i64
        %746 = arith.addi %737, %747 : i64
        %748 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
        %749 = llvm.load %636 : !llvm.ptr -> i32
        %750 = arith.extsi %746 : i64 to i128
        %751 = arith.extsi %749 : i32 to i64
        %752 = llvm.getelementptr %748[%751] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        llvm.store %750, %752 : i128, !llvm.ptr
        cf.br ^bb74
      ^bb74:
      %753 = llvm.load %636 : !llvm.ptr -> i32
      %754 = arith.constant 1 : i32
      %755 = arith.addi %753, %754 : i32
      llvm.store %755, %642 : i32, !llvm.ptr
      %756 = arith.cmpi sgt, %691, %arg2 : i64
      cf.cond_br %756, ^bb75, ^bb76
      ^bb75:
        %757 = llvm.load %639 : !llvm.ptr -> i32
        %758 = arith.constant 1 : i32
        %759 = arith.subi %757, %758 : i32
        llvm.store %759, %639 : i32, !llvm.ptr
        %760 = llvm.load %639 : !llvm.ptr -> i32
        %761 = arith.constant 0 : i32
        %762 = arith.cmpi sle, %760, %761 : i32
        cf.cond_br %762, ^bb78, ^bb79
        ^bb78:
          cf.br ^bb68
        ^bb79:
          cf.br ^bb80
        ^bb80:
        cf.br ^bb77
      ^bb76:
        cf.br ^bb77
      ^bb77:
      %763 = llvm.load %636 : !llvm.ptr -> i32
      %764 = arith.constant 1 : i32
      %765 = arith.addi %763, %764 : i32
      llvm.store %765, %636 : i32, !llvm.ptr
      %766 = llvm.load %636 : !llvm.ptr -> i32
      %767 = arith.constant 500 : i32
      %768 = arith.cmpi sgt, %766, %767 : i32
      cf.cond_br %768, ^bb81, ^bb82
      ^bb81:
        cf.br ^bb68
      ^bb82:
        cf.br ^bb83
      ^bb83:
      cf.br ^bb66
    ^bb68:
    %769 = llvm.load %642 : !llvm.ptr -> i32
    %770 = arith.constant 1 : i32
    %771 = arith.subi %769, %770 : i32
    %773 = arith.constant 1 : i32
    %774 = arith.addi %771, %773 : i32
    %775 = arith.extsi %774 : i32 to i64
    %776 = arith.constant 4 : i32
    %777 = arith.extsi %776 : i32 to i64
    %772 = func.call @calloc(%775, %777) : (i64, i64) -> !llvm.ptr
    %778 = llvm.mlir.constant(1 : i64) : i64
    %779 = llvm.alloca %778 x i128 : (i64) -> !llvm.ptr
    llvm.store %arg1, %779 : i128, !llvm.ptr
    %780 = arith.constant 1 : i32
    %781 = llvm.mlir.constant(1 : i64) : i64
    %782 = llvm.alloca %781 x i32 : (i64) -> !llvm.ptr
    llvm.store %780, %782 : i32, !llvm.ptr
    cf.br ^bb84
    ^bb84:
    %783 = llvm.load %782 : !llvm.ptr -> i32
    %784 = arith.cmpi sle, %783, %771 : i32
    cf.cond_br %784, ^bb85, ^bb86
    ^bb85:
      %786 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
      %787 = llvm.load %782 : !llvm.ptr -> i32
      %788 = arith.constant 1 : i32
      %789 = arith.subi %787, %788 : i32
      %790 = arith.extsi %789 : i32 to i64
      %791 = llvm.getelementptr %786[%790] : (!llvm.ptr, i64) -> !llvm.ptr, i128
      %785 = llvm.load %791 : !llvm.ptr -> i128
      %792 = arith.constant 0 : i32
      %794 = arith.trunci %785 : i128 to i64
      %795 = arith.extsi %792 : i32 to i64
      %793 = arith.cmpi eq, %794, %795 : i64
      cf.cond_br %793, ^bb87, ^bb88
      ^bb87:
        %796 = arith.constant 0 : i32
        %797 = llvm.load %782 : !llvm.ptr -> i32
        %798 = arith.extsi %797 : i32 to i64
        %799 = llvm.getelementptr %772[%798] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %796, %799 : i32, !llvm.ptr
        cf.br ^bb89
      ^bb88:
        %801 = llvm.load %779 : !llvm.ptr -> i128
        %800 = func.call @ceil_div_i128(%801, %785) : (i128, i128) -> i128
        %802 = llvm.mlir.constant(1 : i64) : i64
        %803 = llvm.alloca %802 x i128 : (i64) -> !llvm.ptr
        llvm.store %800, %803 : i128, !llvm.ptr
        %804 = llvm.load %803 : !llvm.ptr -> i128
        %806 = llvm.load %599 : !llvm.ptr -> !llvm.ptr
        %807 = llvm.load %782 : !llvm.ptr -> i32
        %808 = arith.extsi %807 : i32 to i64
        %809 = llvm.getelementptr %806[%808] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %805 = llvm.load %809 : !llvm.ptr -> i32
        %810 = arith.extsi %805 : i32 to i128
        %812 = arith.trunci %804 : i128 to i64
        %813 = arith.trunci %810 : i128 to i64
        %811 = arith.cmpi sgt, %812, %813 : i64
        cf.cond_br %811, ^bb90, ^bb91
        ^bb90:
          %815 = llvm.load %599 : !llvm.ptr -> !llvm.ptr
          %816 = llvm.load %782 : !llvm.ptr -> i32
          %817 = arith.extsi %816 : i32 to i64
          %818 = llvm.getelementptr %815[%817] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %814 = llvm.load %818 : !llvm.ptr -> i32
          %819 = arith.extsi %814 : i32 to i128
          llvm.store %819, %803 : i128, !llvm.ptr
          cf.br ^bb92
        ^bb91:
          cf.br ^bb92
        ^bb92:
        %820 = llvm.load %803 : !llvm.ptr -> i128
        %821 = arith.constant 0 : i32
        %823 = arith.trunci %820 : i128 to i64
        %824 = arith.extsi %821 : i32 to i64
        %822 = arith.cmpi slt, %823, %824 : i64
        cf.cond_br %822, ^bb93, ^bb94
        ^bb93:
          %825 = arith.constant 0 : i32
          %826 = arith.extsi %825 : i32 to i128
          llvm.store %826, %803 : i128, !llvm.ptr
          cf.br ^bb95
        ^bb94:
          cf.br ^bb95
        ^bb95:
        %827 = llvm.load %803 : !llvm.ptr -> i128
        %828 = arith.trunci %827 : i128 to i32
        %829 = llvm.load %782 : !llvm.ptr -> i32
        %830 = arith.extsi %829 : i32 to i64
        %831 = llvm.getelementptr %772[%830] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %828, %831 : i32, !llvm.ptr
        %832 = llvm.load %803 : !llvm.ptr -> i128
        %834 = arith.trunci %832 : i128 to i64
        %835 = arith.trunci %785 : i128 to i64
        %833 = arith.muli %834, %835 : i64
        %836 = llvm.load %779 : !llvm.ptr -> i128
        %838 = arith.trunci %836 : i128 to i64
        %837 = arith.subi %833, %838 : i64
        %839 = arith.extsi %837 : i64 to i128
        llvm.store %839, %779 : i128, !llvm.ptr
        cf.br ^bb89
      ^bb89:
      %840 = llvm.load %782 : !llvm.ptr -> i32
      %841 = arith.constant 1 : i32
      %842 = arith.addi %840, %841 : i32
      llvm.store %842, %782 : i32, !llvm.ptr
      cf.br ^bb84
    ^bb86:
    %844 = arith.constant 1 : i32
    %845 = arith.addi %771, %844 : i32
    %846 = arith.extsi %845 : i32 to i64
    %847 = arith.constant 8 : i32
    %848 = arith.extsi %847 : i32 to i64
    %843 = func.call @calloc(%846, %848) : (i64, i64) -> !llvm.ptr
    %849 = arith.constant 0 : i32
    %850 = arith.extsi %849 : i32 to i64
    %851 = llvm.mlir.constant(1 : i64) : i64
    %852 = llvm.alloca %851 x i64 : (i64) -> !llvm.ptr
    llvm.store %850, %852 : i64, !llvm.ptr
    %853 = arith.constant 1 : i32
    llvm.store %853, %782 : i32, !llvm.ptr
    cf.br ^bb96
    ^bb96:
    %854 = llvm.load %782 : !llvm.ptr -> i32
    %855 = arith.cmpi sle, %854, %771 : i32
    cf.cond_br %855, ^bb97, ^bb98
    ^bb97:
      %856 = llvm.load %852 : !llvm.ptr -> i64
      %858 = llvm.load %782 : !llvm.ptr -> i32
      %859 = arith.extsi %858 : i32 to i64
      %860 = llvm.getelementptr %772[%859] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %857 = llvm.load %860 : !llvm.ptr -> i32
      %861 = arith.extsi %857 : i32 to i64
      %863 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
      %864 = llvm.load %782 : !llvm.ptr -> i32
      %865 = arith.constant 1 : i32
      %866 = arith.subi %864, %865 : i32
      %867 = arith.extsi %866 : i32 to i64
      %868 = llvm.getelementptr %863[%867] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %862 = llvm.load %868 : !llvm.ptr -> i64
      %869 = arith.muli %861, %862 : i64
      %870 = arith.addi %856, %869 : i64
      llvm.store %870, %852 : i64, !llvm.ptr
      %871 = llvm.load %852 : !llvm.ptr -> i64
      %872 = llvm.load %782 : !llvm.ptr -> i32
      %873 = arith.extsi %872 : i32 to i64
      %874 = llvm.getelementptr %843[%873] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %871, %874 : i64, !llvm.ptr
      %875 = llvm.load %782 : !llvm.ptr -> i32
      %876 = arith.constant 1 : i32
      %877 = arith.addi %875, %876 : i32
      llvm.store %877, %782 : i32, !llvm.ptr
      cf.br ^bb96
    ^bb98:
    %879 = arith.constant 200000 : i32
    %880 = arith.constant 8 : i32
    %881 = arith.extsi %879 : i32 to i64
    %882 = arith.extsi %880 : i32 to i64
    %878 = func.call @calloc(%881, %882) : (i64, i64) -> !llvm.ptr
    %884 = arith.constant 200000 : i32
    %885 = arith.constant 8 : i32
    %886 = arith.extsi %884 : i32 to i64
    %887 = arith.extsi %885 : i32 to i64
    %883 = func.call @calloc(%886, %887) : (i64, i64) -> !llvm.ptr
    %888 = arith.constant 0 : i32
    %889 = llvm.mlir.constant(1 : i64) : i64
    %890 = llvm.alloca %889 x i32 : (i64) -> !llvm.ptr
    llvm.store %888, %890 : i32, !llvm.ptr
    %891 = arith.constant 0 : i32
    %892 = llvm.mlir.constant(1 : i64) : i64
    %893 = llvm.alloca %892 x i32 : (i64) -> !llvm.ptr
    llvm.store %891, %893 : i32, !llvm.ptr
    %894 = arith.constant 0 : i32
    %895 = llvm.load %890 : !llvm.ptr -> i32
    %896 = arith.extsi %894 : i32 to i64
    %897 = arith.extsi %895 : i32 to i64
    %898 = llvm.getelementptr %878[%897] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %896, %898 : i64, !llvm.ptr
    %899 = llvm.load %890 : !llvm.ptr -> i32
    %900 = arith.constant 1 : i32
    %901 = arith.addi %899, %900 : i32
    llvm.store %901, %890 : i32, !llvm.ptr
    %902 = arith.constant 0 : i32
    %903 = llvm.load %893 : !llvm.ptr -> i32
    %904 = arith.extsi %902 : i32 to i64
    %905 = arith.extsi %903 : i32 to i64
    %906 = llvm.getelementptr %883[%905] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %904, %906 : i64, !llvm.ptr
    %907 = llvm.load %893 : !llvm.ptr -> i32
    %908 = arith.constant 1 : i32
    %909 = arith.addi %907, %908 : i32
    llvm.store %909, %893 : i32, !llvm.ptr
    %910 = arith.constant 1 : i32
    %911 = llvm.mlir.constant(1 : i64) : i64
    %912 = llvm.alloca %911 x i32 : (i64) -> !llvm.ptr
    llvm.store %910, %912 : i32, !llvm.ptr
    cf.br ^bb99
    ^bb99:
    %913 = arith.constant 2 : i32
    %914 = llvm.load %912 : !llvm.ptr -> i32
    %915 = arith.muli %913, %914 : i32
    %916 = arith.constant 1 : i32
    %917 = arith.addi %771, %916 : i32
    %918 = arith.cmpi slt, %915, %917 : i32
    cf.cond_br %918, ^bb100, ^bb101
    ^bb100:
      %919 = arith.constant 2 : i32
      %920 = llvm.load %912 : !llvm.ptr -> i32
      %921 = arith.muli %919, %920 : i32
      %922 = arith.constant 2 : i32
      %923 = llvm.load %912 : !llvm.ptr -> i32
      %924 = arith.muli %922, %923 : i32
      %925 = arith.constant 1 : i32
      %926 = arith.subi %924, %925 : i32
      %927 = arith.cmpi sgt, %921, %771 : i32
      cf.cond_br %927, ^bb102, ^bb103
      ^bb102:
        cf.br ^bb101
      ^bb103:
        cf.br ^bb104
      ^bb104:
      %929 = arith.extsi %926 : i32 to i64
      %930 = llvm.getelementptr %843[%929] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %928 = llvm.load %930 : !llvm.ptr -> i64
      %932 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
      %933 = arith.extsi %926 : i32 to i64
      %934 = llvm.getelementptr %932[%933] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %931 = llvm.load %934 : !llvm.ptr -> i64
      %935 = arith.constant 0 : i32
      %936 = llvm.mlir.constant(1 : i64) : i64
      %937 = llvm.alloca %936 x i32 : (i64) -> !llvm.ptr
      llvm.store %935, %937 : i32, !llvm.ptr
      cf.br ^bb105
      ^bb105:
      %938 = llvm.load %937 : !llvm.ptr -> i32
      %940 = arith.extsi %921 : i32 to i64
      %941 = llvm.getelementptr %772[%940] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %939 = llvm.load %941 : !llvm.ptr -> i32
      %942 = arith.cmpi slt, %938, %939 : i32
      cf.cond_br %942, ^bb106, ^bb107
      ^bb106:
        %943 = llvm.load %937 : !llvm.ptr -> i32
        %944 = arith.extsi %943 : i32 to i64
        %945 = arith.muli %944, %931 : i64
        %946 = arith.addi %928, %945 : i64
        %947 = arith.constant 0 : i32
        %949 = arith.extsi %947 : i32 to i64
        %948 = arith.cmpi sle, %949, %946 : i64
        %950 = scf.if %948 -> (i1) {
          %951 = arith.cmpi sle, %946, %arg2 : i64
          scf.yield %951 : i1
        } else {
          %952 = arith.constant false
          scf.yield %952 : i1
        }
        cf.cond_br %950, ^bb108, ^bb109
        ^bb108:
          %953 = llvm.load %890 : !llvm.ptr -> i32
          %954 = arith.extsi %953 : i32 to i64
          %955 = llvm.getelementptr %878[%954] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %946, %955 : i64, !llvm.ptr
          %956 = llvm.load %890 : !llvm.ptr -> i32
          %957 = arith.constant 1 : i32
          %958 = arith.addi %956, %957 : i32
          llvm.store %958, %890 : i32, !llvm.ptr
          cf.br ^bb110
        ^bb109:
          cf.br ^bb110
        ^bb110:
        %959 = llvm.load %937 : !llvm.ptr -> i32
        %960 = arith.constant 1 : i32
        %961 = arith.addi %959, %960 : i32
        llvm.store %961, %937 : i32, !llvm.ptr
        cf.br ^bb105
      ^bb107:
      %962 = llvm.load %912 : !llvm.ptr -> i32
      %963 = arith.constant 1 : i32
      %964 = arith.addi %962, %963 : i32
      llvm.store %964, %912 : i32, !llvm.ptr
      cf.br ^bb99
    ^bb101:
    %965 = arith.constant 0 : i32
    llvm.store %965, %912 : i32, !llvm.ptr
    cf.br ^bb111
    ^bb111:
    %966 = arith.constant 2 : i32
    %967 = llvm.load %912 : !llvm.ptr -> i32
    %968 = arith.muli %966, %967 : i32
    %969 = arith.constant 1 : i32
    %970 = arith.addi %968, %969 : i32
    %971 = arith.cmpi sle, %970, %771 : i32
    cf.cond_br %971, ^bb112, ^bb113
    ^bb112:
      %972 = arith.constant 2 : i32
      %973 = llvm.load %912 : !llvm.ptr -> i32
      %974 = arith.muli %972, %973 : i32
      %975 = arith.constant 1 : i32
      %976 = arith.addi %974, %975 : i32
      %977 = arith.cmpi sgt, %976, %771 : i32
      cf.cond_br %977, ^bb114, ^bb115
      ^bb114:
        cf.br ^bb113
      ^bb115:
        cf.br ^bb116
      ^bb116:
      %979 = arith.extsi %974 : i32 to i64
      %980 = llvm.getelementptr %843[%979] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %978 = llvm.load %980 : !llvm.ptr -> i64
      %982 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
      %983 = arith.extsi %974 : i32 to i64
      %984 = llvm.getelementptr %982[%983] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %981 = llvm.load %984 : !llvm.ptr -> i64
      %985 = arith.constant 0 : i32
      %986 = llvm.mlir.constant(1 : i64) : i64
      %987 = llvm.alloca %986 x i32 : (i64) -> !llvm.ptr
      llvm.store %985, %987 : i32, !llvm.ptr
      cf.br ^bb117
      ^bb117:
      %988 = llvm.load %987 : !llvm.ptr -> i32
      %990 = arith.extsi %976 : i32 to i64
      %991 = llvm.getelementptr %772[%990] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %989 = llvm.load %991 : !llvm.ptr -> i32
      %992 = arith.cmpi slt, %988, %989 : i32
      cf.cond_br %992, ^bb118, ^bb119
      ^bb118:
        %993 = llvm.load %987 : !llvm.ptr -> i32
        %994 = arith.extsi %993 : i32 to i64
        %995 = arith.muli %994, %981 : i64
        %996 = arith.addi %978, %995 : i64
        %997 = arith.constant 0 : i32
        %999 = arith.extsi %997 : i32 to i64
        %998 = arith.cmpi sle, %999, %996 : i64
        %1000 = scf.if %998 -> (i1) {
          %1001 = arith.cmpi sle, %996, %arg2 : i64
          scf.yield %1001 : i1
        } else {
          %1002 = arith.constant false
          scf.yield %1002 : i1
        }
        cf.cond_br %1000, ^bb120, ^bb121
        ^bb120:
          %1003 = llvm.load %893 : !llvm.ptr -> i32
          %1004 = arith.extsi %1003 : i32 to i64
          %1005 = llvm.getelementptr %883[%1004] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %996, %1005 : i64, !llvm.ptr
          %1006 = llvm.load %893 : !llvm.ptr -> i32
          %1007 = arith.constant 1 : i32
          %1008 = arith.addi %1006, %1007 : i32
          llvm.store %1008, %893 : i32, !llvm.ptr
          cf.br ^bb122
        ^bb121:
          cf.br ^bb122
        ^bb122:
        %1009 = llvm.load %987 : !llvm.ptr -> i32
        %1010 = arith.constant 1 : i32
        %1011 = arith.addi %1009, %1010 : i32
        llvm.store %1011, %987 : i32, !llvm.ptr
        cf.br ^bb117
      ^bb119:
      %1012 = llvm.load %912 : !llvm.ptr -> i32
      %1013 = arith.constant 1 : i32
      %1014 = arith.addi %1012, %1013 : i32
      llvm.store %1014, %912 : i32, !llvm.ptr
      cf.br ^bb111
    ^bb113:
    %1015 = func.call @one() : () -> i128
    %1016 = llvm.mlir.constant(1 : i64) : i64
    %1017 = llvm.alloca %1016 x i128 : (i64) -> !llvm.ptr
    llvm.store %1015, %1017 : i128, !llvm.ptr
    %1018 = func.call @one() : () -> i128
    %1019 = llvm.mlir.constant(1 : i64) : i64
    %1020 = llvm.alloca %1019 x i128 : (i64) -> !llvm.ptr
    llvm.store %1018, %1020 : i128, !llvm.ptr
    %1021 = arith.constant 0 : i32
    %1022 = arith.extsi %1021 : i32 to i64
    %1023 = llvm.mlir.constant(1 : i64) : i64
    %1024 = llvm.alloca %1023 x i64 : (i64) -> !llvm.ptr
    llvm.store %1022, %1024 : i64, !llvm.ptr
    %1025 = arith.constant 0 : i32
    %1026 = arith.extsi %1025 : i32 to i64
    %1027 = llvm.mlir.constant(1 : i64) : i64
    %1028 = llvm.alloca %1027 x i64 : (i64) -> !llvm.ptr
    llvm.store %1026, %1028 : i64, !llvm.ptr
    %1029 = arith.constant 0 : i32
    llvm.store %1029, %782 : i32, !llvm.ptr
    cf.br ^bb123
    ^bb123:
    %1030 = llvm.load %782 : !llvm.ptr -> i32
    %1031 = llvm.load %890 : !llvm.ptr -> i32
    %1032 = arith.cmpi slt, %1030, %1031 : i32
    cf.cond_br %1032, ^bb124, ^bb125
    ^bb124:
      %1034 = llvm.load %782 : !llvm.ptr -> i32
      %1035 = arith.extsi %1034 : i32 to i64
      %1036 = llvm.getelementptr %878[%1035] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1033 = llvm.load %1036 : !llvm.ptr -> i64
      %1037 = func.call @frac_mul(%arg0, %1033) : (i128, i64) -> i128
      %1039 = arith.trunci %1037 : i128 to i64
      %1040 = arith.trunci %arg1 : i128 to i64
      %1038 = arith.subi %1039, %1040 : i64
      %1041 = arith.extsi %1038 : i64 to i128
      %1042 = llvm.mlir.constant(1 : i64) : i64
      %1043 = llvm.alloca %1042 x i128 : (i64) -> !llvm.ptr
      llvm.store %1041, %1043 : i128, !llvm.ptr
      %1044 = llvm.load %1043 : !llvm.ptr -> i128
      %1045 = arith.constant 0 : i32
      %1047 = arith.trunci %1044 : i128 to i64
      %1048 = arith.extsi %1045 : i32 to i64
      %1046 = arith.cmpi slt, %1047, %1048 : i64
      cf.cond_br %1046, ^bb126, ^bb127
      ^bb126:
        %1049 = llvm.load %1043 : !llvm.ptr -> i128
        %1050 = func.call @one() : () -> i128
        %1052 = arith.trunci %1049 : i128 to i64
        %1053 = arith.trunci %1050 : i128 to i64
        %1051 = arith.addi %1052, %1053 : i64
        %1054 = arith.extsi %1051 : i64 to i128
        llvm.store %1054, %1043 : i128, !llvm.ptr
        cf.br ^bb128
      ^bb127:
        cf.br ^bb128
      ^bb128:
      %1055 = llvm.load %1043 : !llvm.ptr -> i128
      %1056 = llvm.load %1017 : !llvm.ptr -> i128
      %1058 = arith.trunci %1055 : i128 to i64
      %1059 = arith.trunci %1056 : i128 to i64
      %1057 = arith.cmpi slt, %1058, %1059 : i64
      cf.cond_br %1057, ^bb129, ^bb130
      ^bb129:
        %1060 = llvm.load %1043 : !llvm.ptr -> i128
        llvm.store %1060, %1017 : i128, !llvm.ptr
        llvm.store %1033, %1024 : i64, !llvm.ptr
        cf.br ^bb131
      ^bb130:
        cf.br ^bb131
      ^bb131:
      %1061 = llvm.load %782 : !llvm.ptr -> i32
      %1062 = arith.constant 1 : i32
      %1063 = arith.addi %1061, %1062 : i32
      llvm.store %1063, %782 : i32, !llvm.ptr
      cf.br ^bb123
    ^bb125:
    %1064 = arith.constant 0 : i32
    llvm.store %1064, %782 : i32, !llvm.ptr
    cf.br ^bb132
    ^bb132:
    %1065 = llvm.load %782 : !llvm.ptr -> i32
    %1066 = llvm.load %893 : !llvm.ptr -> i32
    %1067 = arith.cmpi slt, %1065, %1066 : i32
    cf.cond_br %1067, ^bb133, ^bb134
    ^bb133:
      %1069 = llvm.load %782 : !llvm.ptr -> i32
      %1070 = arith.extsi %1069 : i32 to i64
      %1071 = llvm.getelementptr %883[%1070] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1068 = llvm.load %1071 : !llvm.ptr -> i64
      %1072 = func.call @frac_mul(%arg0, %1068) : (i128, i64) -> i128
      %1074 = arith.trunci %arg1 : i128 to i64
      %1075 = arith.trunci %1072 : i128 to i64
      %1073 = arith.subi %1074, %1075 : i64
      %1076 = arith.extsi %1073 : i64 to i128
      %1077 = llvm.mlir.constant(1 : i64) : i64
      %1078 = llvm.alloca %1077 x i128 : (i64) -> !llvm.ptr
      llvm.store %1076, %1078 : i128, !llvm.ptr
      %1079 = llvm.load %1078 : !llvm.ptr -> i128
      %1080 = arith.constant 0 : i32
      %1082 = arith.trunci %1079 : i128 to i64
      %1083 = arith.extsi %1080 : i32 to i64
      %1081 = arith.cmpi slt, %1082, %1083 : i64
      cf.cond_br %1081, ^bb135, ^bb136
      ^bb135:
        %1084 = llvm.load %1078 : !llvm.ptr -> i128
        %1085 = func.call @one() : () -> i128
        %1087 = arith.trunci %1084 : i128 to i64
        %1088 = arith.trunci %1085 : i128 to i64
        %1086 = arith.addi %1087, %1088 : i64
        %1089 = arith.extsi %1086 : i64 to i128
        llvm.store %1089, %1078 : i128, !llvm.ptr
        cf.br ^bb137
      ^bb136:
        cf.br ^bb137
      ^bb137:
      %1090 = llvm.load %1078 : !llvm.ptr -> i128
      %1091 = llvm.load %1020 : !llvm.ptr -> i128
      %1093 = arith.trunci %1090 : i128 to i64
      %1094 = arith.trunci %1091 : i128 to i64
      %1092 = arith.cmpi slt, %1093, %1094 : i64
      cf.cond_br %1092, ^bb138, ^bb139
      ^bb138:
        %1095 = llvm.load %1078 : !llvm.ptr -> i128
        llvm.store %1095, %1020 : i128, !llvm.ptr
        llvm.store %1068, %1028 : i64, !llvm.ptr
        cf.br ^bb140
      ^bb139:
        cf.br ^bb140
      ^bb140:
      %1096 = llvm.load %782 : !llvm.ptr -> i32
      %1097 = arith.constant 1 : i32
      %1098 = arith.addi %1096, %1097 : i32
      llvm.store %1098, %782 : i32, !llvm.ptr
      cf.br ^bb132
    ^bb134:
    %1099 = arith.constant 0 : i32
    %1100 = arith.extsi %1099 : i32 to i64
    %1101 = llvm.load %1017 : !llvm.ptr -> i128
    %1102 = llvm.load %1020 : !llvm.ptr -> i128
    %1104 = arith.trunci %1101 : i128 to i64
    %1105 = arith.trunci %1102 : i128 to i64
    %1103 = arith.cmpi slt, %1104, %1105 : i64
    %1106 = scf.if %1103 -> (i64) {
      %1107 = llvm.load %1024 : !llvm.ptr -> i64
      scf.yield %1107 : i64
    } else {
      %1108 = llvm.load %1028 : !llvm.ptr -> i64
      scf.yield %1108 : i64
    }
    %1110 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1110) : (!llvm.ptr) -> ()
    %1112 = llvm.load %599 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1112) : (!llvm.ptr) -> ()
    %1114 = llvm.load %606 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1114) : (!llvm.ptr) -> ()
    func.call @free(%772) : (!llvm.ptr) -> ()
    func.call @free(%843) : (!llvm.ptr) -> ()
    func.call @free(%878) : (!llvm.ptr) -> ()
    func.call @free(%883) : (!llvm.ptr) -> ()
    func.return %1106 : i64
  }
  func.func @bqa_pi_d(%arg0: i32, %arg1: i64, %arg2: i128, %arg3: i128) -> i64 {
    %1120 = arith.constant 1 : i32
    %1121 = arith.constant 4 : i32
    %1122 = arith.extsi %1120 : i32 to i64
    %1123 = arith.extsi %1121 : i32 to i64
    %1119 = func.call @calloc(%1122, %1123) : (i64, i64) -> !llvm.ptr
    %1125 = arith.constant 4096 : i32
    %1126 = arith.constant 4 : i32
    %1127 = arith.extsi %1125 : i32 to i64
    %1128 = arith.extsi %1126 : i32 to i64
    %1124 = func.call @calloc(%1127, %1128) : (i64, i64) -> !llvm.ptr
    %1130 = arith.constant 1 : i32
    %1131 = arith.constant 4 : i32
    %1132 = arith.extsi %1130 : i32 to i64
    %1133 = arith.extsi %1131 : i32 to i64
    %1129 = func.call @calloc(%1132, %1133) : (i64, i64) -> !llvm.ptr
    %1134 = func.call @sqrt_cf_period(%arg0, %1119, %1124, %1129) : (i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
    %1136 = arith.constant 0 : i32
    %1137 = arith.extsi %1136 : i32 to i64
    %1138 = llvm.getelementptr %1119[%1137] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %1135 = llvm.load %1138 : !llvm.ptr -> i32
    %1140 = arith.constant 0 : i32
    %1141 = arith.extsi %1140 : i32 to i64
    %1142 = llvm.getelementptr %1129[%1141] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %1139 = llvm.load %1142 : !llvm.ptr -> i32
    %1143 = func.call @isqrt_scaled(%arg0) : (i32) -> i128
    %1144 = arith.extsi %1135 : i32 to i128
    %1145 = arith.constant 96 : i32
    %1147 = arith.trunci %1144 : i128 to i64
    %1148 = arith.extsi %1145 : i32 to i64
    %1146 = arith.shli %1147, %1148 : i64
    %1150 = arith.trunci %1143 : i128 to i64
    %1149 = arith.subi %1150, %1146 : i64
    %1151 = arith.extsi %1149 : i64 to i128
    %1152 = arith.sitofp %arg0 : i32 to f64
    %1153 = math.sqrt %1152 : f64
    %1154 = arith.constant 3.14159265358979323846 : f32
    %1155 = arith.extf %1154 : f32 to f64
    %1157 = arith.sitofp %arg1 : i64 to f64
    %1158 = arith.addf %1155, %1157 : f64
    %1159 = arith.divf %1158, %1153 : f64
    %1156 = func.call @floor(%1159) : (f64) -> f64
    %1160 = arith.fptosi %1156 : f64 to i64
    %1161 = llvm.mlir.constant(1 : i64) : i64
    %1162 = llvm.alloca %1161 x i64 : (i64) -> !llvm.ptr
    llvm.store %1160, %1162 : i64, !llvm.ptr
    %1163 = llvm.load %1162 : !llvm.ptr -> i64
    %1164 = arith.constant 0 : i32
    %1166 = arith.extsi %1164 : i32 to i64
    %1165 = arith.cmpi slt, %1163, %1166 : i64
    cf.cond_br %1165, ^bb141, ^bb142
    ^bb141:
      %1167 = arith.constant 0 : i32
      %1168 = arith.extsi %1167 : i32 to i64
      llvm.store %1168, %1162 : i64, !llvm.ptr
      cf.br ^bb143
    ^bb142:
      cf.br ^bb143
    ^bb143:
    %1169 = llvm.load %1162 : !llvm.ptr -> i64
    %1170 = arith.cmpi sgt, %1169, %arg1 : i64
    cf.cond_br %1170, ^bb144, ^bb145
    ^bb144:
      llvm.store %arg1, %1162 : i64, !llvm.ptr
      cf.br ^bb146
    ^bb145:
      cf.br ^bb146
    ^bb146:
    %1172 = arith.sitofp %arg1 : i64 to f64
    %1173 = arith.subf %1172, %1155 : f64
    %1174 = arith.divf %1173, %1153 : f64
    %1171 = func.call @floor(%1174) : (f64) -> f64
    %1175 = arith.fptosi %1171 : f64 to i64
    %1176 = llvm.mlir.constant(1 : i64) : i64
    %1177 = llvm.alloca %1176 x i64 : (i64) -> !llvm.ptr
    llvm.store %1175, %1177 : i64, !llvm.ptr
    %1178 = llvm.load %1177 : !llvm.ptr -> i64
    %1179 = arith.constant 0 : i32
    %1181 = arith.extsi %1179 : i32 to i64
    %1180 = arith.cmpi slt, %1178, %1181 : i64
    cf.cond_br %1180, ^bb147, ^bb148
    ^bb147:
      %1182 = arith.constant 0 : i32
      %1183 = arith.extsi %1182 : i32 to i64
      llvm.store %1183, %1177 : i64, !llvm.ptr
      cf.br ^bb149
    ^bb148:
      cf.br ^bb149
    ^bb149:
    %1184 = llvm.load %1177 : !llvm.ptr -> i64
    %1185 = arith.cmpi sgt, %1184, %arg1 : i64
    cf.cond_br %1185, ^bb150, ^bb151
    ^bb150:
      llvm.store %arg1, %1177 : i64, !llvm.ptr
      cf.br ^bb152
    ^bb151:
      cf.br ^bb152
    ^bb152:
    %1187 = llvm.load %1162 : !llvm.ptr -> i64
    %1186 = func.call @best_b_positive(%1151, %arg3, %1187, %1124, %1139) : (i128, i128, i64, !llvm.ptr, i32) -> i64
    %1188 = func.call @one() : () -> i128
    %1190 = arith.trunci %1188 : i128 to i64
    %1191 = arith.trunci %arg3 : i128 to i64
    %1189 = arith.subi %1190, %1191 : i64
    %1192 = arith.extsi %1189 : i64 to i128
    %1194 = llvm.load %1177 : !llvm.ptr -> i64
    %1193 = func.call @best_b_positive(%1151, %1192, %1194, %1124, %1139) : (i128, i128, i64, !llvm.ptr, i32) -> i64
    %1195 = arith.constant 0 : i32
    %1197 = arith.extsi %1195 : i32 to i64
    %1196 = arith.subi %1197, %1193 : i64
    %1198 = func.call @compute_error_fp(%1143, %arg2, %1186) : (i128, i128, i64) -> i128
    %1199 = func.call @compute_error_fp(%1143, %arg2, %1196) : (i128, i128, i64) -> i128
    %1200 = llvm.mlir.constant(1 : i64) : i64
    %1201 = llvm.alloca %1200 x i64 : (i64) -> !llvm.ptr
    llvm.store %1186, %1201 : i64, !llvm.ptr
    %1203 = arith.trunci %1199 : i128 to i64
    %1204 = arith.trunci %1198 : i128 to i64
    %1202 = arith.cmpi slt, %1203, %1204 : i64
    cf.cond_br %1202, ^bb153, ^bb154
    ^bb153:
      llvm.store %1196, %1201 : i64, !llvm.ptr
      cf.br ^bb155
    ^bb154:
      cf.br ^bb155
    ^bb155:
    %1205 = llvm.load %1201 : !llvm.ptr -> i64
    %1206 = arith.sitofp %1205 : i64 to f64
    %1207 = arith.mulf %1153, %1206 : f64
    %1208 = arith.subf %1155, %1207 : f64
    %1209 = func.call @round(%1208) : (f64) -> f64
    %1210 = arith.fptosi %1209 : f64 to i64
    %1211 = llvm.mlir.constant(1 : i64) : i64
    %1212 = llvm.alloca %1211 x i64 : (i64) -> !llvm.ptr
    llvm.store %1210, %1212 : i64, !llvm.ptr
    %1213 = llvm.load %1212 : !llvm.ptr -> i64
    %1214 = arith.cmpi sgt, %1213, %arg1 : i64
    cf.cond_br %1214, ^bb156, ^bb157
    ^bb156:
      llvm.store %arg1, %1212 : i64, !llvm.ptr
      cf.br ^bb158
    ^bb157:
      cf.br ^bb158
    ^bb158:
    %1215 = llvm.load %1212 : !llvm.ptr -> i64
    %1216 = arith.constant 0 : i32
    %1218 = arith.extsi %1216 : i32 to i64
    %1217 = arith.subi %1218, %arg1 : i64
    %1219 = arith.cmpi slt, %1215, %1217 : i64
    cf.cond_br %1219, ^bb159, ^bb160
    ^bb159:
      %1220 = arith.constant 0 : i32
      %1222 = arith.extsi %1220 : i32 to i64
      %1221 = arith.subi %1222, %arg1 : i64
      llvm.store %1221, %1212 : i64, !llvm.ptr
      cf.br ^bb161
    ^bb160:
      cf.br ^bb161
    ^bb161:
    func.call @free(%1119) : (!llvm.ptr) -> ()
    func.call @free(%1124) : (!llvm.ptr) -> ()
    func.call @free(%1129) : (!llvm.ptr) -> ()
    %1226 = llvm.load %1212 : !llvm.ptr -> i64
    func.return %1226 : i64
  }
  func.func @main() -> i32 {
    %1227 = func.call @compute_pi_fp() : () -> i128
    %1228 = arith.constant 3 : i32
    %1229 = arith.extsi %1228 : i32 to i128
    %1230 = arith.constant 96 : i32
    %1232 = arith.trunci %1229 : i128 to i64
    %1233 = arith.extsi %1230 : i32 to i64
    %1231 = arith.shli %1232, %1233 : i64
    %1235 = arith.trunci %1227 : i128 to i64
    %1234 = arith.subi %1235, %1231 : i64
    %1236 = arith.extsi %1234 : i64 to i128
    %1237 = arith.constant 0 : i32
    %1238 = arith.extsi %1237 : i32 to i64
    %1239 = llvm.mlir.constant(1 : i64) : i64
    %1240 = llvm.alloca %1239 x i64 : (i64) -> !llvm.ptr
    llvm.store %1238, %1240 : i64, !llvm.ptr
    %1241 = arith.constant 9995705032704 : i32
    %1242 = arith.extsi %1241 : i32 to i64
    %1243 = arith.constant 2 : i32
    %1244 = llvm.mlir.constant(1 : i64) : i64
    %1245 = llvm.alloca %1244 x i32 : (i64) -> !llvm.ptr
    llvm.store %1243, %1245 : i32, !llvm.ptr
    cf.br ^bb162
    ^bb162:
    %1246 = llvm.load %1245 : !llvm.ptr -> i32
    %1247 = arith.constant 100 : i32
    %1248 = arith.cmpi slt, %1246, %1247 : i32
    cf.cond_br %1248, ^bb163, ^bb164
    ^bb163:
      %1250 = llvm.load %1245 : !llvm.ptr -> i32
      %1249 = func.call @is_square(%1250) : (i32) -> i1
      %1252 = arith.constant 1 : i1
      %1251 = arith.xori %1249, %1252 : i1
      cf.cond_br %1251, ^bb165, ^bb166
      ^bb165:
        %1255 = llvm.load %1245 : !llvm.ptr -> i32
        %1254 = func.call @bqa_pi_d(%1255, %1242, %1227, %1236) : (i32, i64, i128, i128) -> i64
        %1256 = arith.constant 0 : i32
        %1258 = arith.extsi %1256 : i32 to i64
        %1257 = arith.cmpi sge, %1254, %1258 : i64
        cf.cond_br %1257, ^bb168, ^bb169
        ^bb168:
          %1259 = llvm.load %1240 : !llvm.ptr -> i64
          %1260 = arith.addi %1259, %1254 : i64
          llvm.store %1260, %1240 : i64, !llvm.ptr
          cf.br ^bb170
        ^bb169:
          %1261 = llvm.load %1240 : !llvm.ptr -> i64
          %1262 = arith.constant 0 : i32
          %1264 = arith.extsi %1262 : i32 to i64
          %1263 = arith.subi %1264, %1254 : i64
          %1265 = arith.addi %1261, %1263 : i64
          llvm.store %1265, %1240 : i64, !llvm.ptr
          cf.br ^bb170
        ^bb170:
        cf.br ^bb167
      ^bb166:
        cf.br ^bb167
      ^bb167:
      %1266 = llvm.load %1245 : !llvm.ptr -> i32
      %1267 = arith.constant 1 : i32
      %1268 = arith.addi %1266, %1267 : i32
      llvm.store %1268, %1245 : i32, !llvm.ptr
      cf.br ^bb162
    ^bb164:
    %1269 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %1270 = llvm.load %1240 : !llvm.ptr -> i64
    %1271 = llvm.call @printf(%1269, %1270) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %1272 = arith.constant 0 : i32
    func.return %1272 : i32
  }
}