Problem 931

Compute T(10^12) mod 715827883. Uses Min25-style prime counting/sum sieve and a closed-form summation. Pure Flow port of the native C solver.

Answer128856311
Output128856311
StatusPASS
Native helperno
Runtime3600 ms
Peak memory41168 KB
Time complexityO(n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n)O(1)
Space complexityO(n^2)O(1)
ApproachFlow solutionClosed-form formula
VerdictSuboptimal

Flow source

# Project Euler 931: Totient Graph
# Compute T(10^12) mod 715827883.
# Uses Min25-style prime counting/sum sieve and a closed-form summation.
# Pure Flow port of the native C solver.

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

const MOD: i64 = 715827883
const TARGET: i64 = 1000000000000

let mut g_v: i32 = 0
let mut g_primes: ptr<i32> = null as ptr<i32>
let mut g_num_primes: i32 = 0
let mut g_vals: ptr<i64> = null as ptr<i64>
let mut g_g_small: ptr<i64> = null as ptr<i64>
let mut g_h_small: ptr<i64> = null as ptr<i64>
let mut g_g_large: ptr<i64> = null as ptr<i64>
let mut g_h_large: ptr<i64> = null as ptr<i64>

function sieve_primes(limit: i32, count: ptr<i32>) -> ptr<i32> {
    if limit < 2 {
        count[0] = 0
        return null as ptr<i32>
    }
    if limit == 2 {
        let p: ptr<i32> = (malloc(4)) as ptr<i32>
        p[0] = 2
        count[0] = 1
        return p
    }

    let size: i32 = limit / 2 + 1
    let is_comp: ptr<i8> = (calloc((size as i64), 1)) as ptr<i8>
    let primes: ptr<i32> = (malloc(((size + 1) as i64) * 4)) as ptr<i32>
    let mut pc: i32 = 0
    primes[pc] = 2
    pc = pc + 1

    let r: i32 = (sqrt((limit as f64))) as i32
    let mut i: i32 = 1
    while i <= r / 2 {
        if is_comp[i] == 0 {
            let p: i32 = 2 * i + 1
            let start: i32 = (p * p) / 2
            let step: i32 = p
            let mut j: i32 = start
            while j < size {
                is_comp[j] = 1
                j = j + step
            }
        }
        i = i + 1
    }
    i = 1
    while i < size {
        if is_comp[i] == 0 {
            primes[pc] = 2 * i + 1
            pc = pc + 1
        }
        i = i + 1
    }

    free(is_comp as ptr<void>)
    count[0] = pc
    return primes
}

function tri(x: i64, mod: i64) -> i64 {
    let val: i128 = ((x as i128) * ((x + 1) as i128)) / 2
    return (val % (mod as i128)) as i64
}

function min25_init(n: i64, mod: i64) -> void {
    g_v = (sqrt((n as f64))) as i32
    let count_buf: ptr<i32> = (malloc(4)) as ptr<i32>
    g_primes = sieve_primes(g_v, count_buf)
    g_num_primes = count_buf[0]
    free(count_buf as ptr<void>)

    g_vals = (calloc((g_v + 1) as i64, 8)) as ptr<i64>
    g_g_small = (calloc((g_v + 1) as i64, 8)) as ptr<i64>
    g_h_small = (calloc((g_v + 1) as i64, 8)) as ptr<i64>
    g_g_large = (calloc((g_v + 1) as i64, 8)) as ptr<i64>
    g_h_large = (calloc((g_v + 1) as i64, 8)) as ptr<i64>

    # Initialize small
    let mut x: i32 = 0
    while x <= g_v {
        if x >= 2 {
            g_g_small[x] = (x - 1) as i64
            g_h_small[x] = ((((x as i128) * ((x + 1) as i128) / 2) - 1) % (mod as i128)) as i64
        } else {
            g_g_small[x] = 0
            g_h_small[x] = 0
        }
        x = x + 1
    }

    # Initialize large
    let mut i: i32 = 1
    while i <= g_v {
        let xx: i64 = n / (i as i64)
        g_vals[i] = xx
        if xx >= 2 {
            g_g_large[i] = xx - 1
            g_h_large[i] = ((((xx as i128) * ((xx + 1) as i128) / 2) - 1) % (mod as i128)) as i64
        } else {
            g_g_large[i] = 0
            g_h_large[i] = 0
        }
        i = i + 1
    }

    # Process primes
    let mut pi: i32 = 0
    while pi < g_num_primes {
        let p: i64 = g_primes[pi] as i64
        let p2: i64 = p * p
        if p2 > n { break }

        let g_p1: i64 = g_g_small[(p - 1) as i32]
        let h_p1: i64 = g_h_small[(p - 1) as i32]

        # Update large values, increasing i
        let mut i_max: i64 = n / p2
        if i_max > (g_v as i64) { i_max = g_v as i64 }

        let mut i2: i32 = 1
        while (i2 as i64) <= i_max {
            let y: i64 = g_vals[i2] / p
            let mut g_y: i64 = 0
            let mut h_y: i64 = 0
            if y <= (g_v as i64) {
                g_y = g_g_small[y as i32]
                h_y = g_h_small[y as i32]
            } else {
                let k: i32 = (n / y) as i32
                g_y = g_g_large[k]
                h_y = g_h_large[k]
            }

            g_g_large[i2] = g_g_large[i2] - (g_y - g_p1)

            let mut diff: i64 = h_y - h_p1
            if diff < 0 { diff = diff + mod }
            let hh: i128 = (p as i128) * (diff as i128) % (mod as i128)
            g_h_large[i2] = (g_h_large[i2] - (hh as i64)) % mod
            if g_h_large[i2] < 0 { g_h_large[i2] = g_h_large[i2] + mod }
            i2 = i2 + 1
        }

        # Update small values descending
        let mut xx2: i64 = g_v as i64
        while xx2 >= p2 {
            let y: i32 = (xx2 / p) as i32
            g_g_small[xx2 as i32] = g_g_small[xx2 as i32] - (g_g_small[y] - g_p1)

            let mut diff2: i64 = g_h_small[y] - h_p1
            if diff2 < 0 { diff2 = diff2 + mod }
            let hh2: i128 = (p as i128) * (diff2 as i128) % (mod as i128)
            g_h_small[xx2 as i32] = (g_h_small[xx2 as i32] - (hh2 as i64)) % mod
            if g_h_small[xx2 as i32] < 0 { g_h_small[xx2 as i32] = g_h_small[xx2 as i32] + mod }
            xx2 = xx2 - 1
        }
        pi = pi + 1
    }
}

function pi_func(x: i64) -> i64 {
    if x <= (g_v as i64) { return g_g_small[x as i32] }
    return g_g_large[(TARGET / x) as i32]
}

function psum(x: i64) -> i64 {
    if x <= (g_v as i64) { return g_h_small[x as i32] }
    return g_h_large[(TARGET / x) as i32]
}

function compute_T_mod(N: i64, mod: i64) -> i64 {
    if N <= 1 { return 0 }

    let sqrtN: i32 = (sqrt((N as f64))) as i32
    min25_init(N, mod)

    let mut total: i64 = 0

    # Part 1: primes p <= sqrt(N), all exponents e >= 1
    let mut pi: i32 = 0
    while pi < g_num_primes {
        let p: i64 = g_primes[pi] as i64
        if p * p > N { break }

        # e = 1
        let x1: i64 = N / p
        let x2: i64 = N / (p * p)
        let mut f: i64 = (tri(x1, mod) - (p % mod) * tri(x2, mod)) % mod
        if f < 0 { f = f + mod }
        total = (total + ((p - 2) % mod) * f) % mod

        # e >= 2
        let mut pe: i64 = p * p
        let mut p_pow: i64 = p
        while pe <= N {
            let xe: i64 = N / pe
            let xnext: i64 = N / (pe * p)
            let A: i64 = (p - 1) * p_pow - 1
            let mut f2: i64 = (tri(xe, mod) - (p % mod) * tri(xnext, mod)) % mod
            if f2 < 0 { f2 = f2 + mod }
            total = (total + (A % mod) * f2) % mod
            p_pow = p_pow * p
            pe = pe * p
        }
        pi = pi + 1
    }

    # Part 2: primes p > sqrt(N), only e=1. Group by q=floor(N/p)
    let mut q: i64 = 1
    while q < (sqrtN as i64) {
        let hi: i64 = N / q
        if hi <= (sqrtN as i64) { break }

        let mut lo: i64 = N / (q + 1) + 1
        if lo <= (sqrtN as i64) { lo = (sqrtN as i64) + 1 }
        if lo > hi {
            q = q + 1
            continue
        }

        let mut sum_p: i64 = (psum(hi) - psum(lo - 1)) % mod
        if sum_p < 0 { sum_p = sum_p + mod }
        let cnt_p: i64 = pi_func(hi) - pi_func(lo - 1)
        let mut term2: i64 = (sum_p - (2 * (cnt_p % mod)) % mod) % mod
        if term2 < 0 { term2 = term2 + mod }
        total = (total + tri(q, mod) * term2) % mod
        q = q + 1
    }

    total = total % mod
    if total < 0 { total = total + mod }

    free(g_vals as ptr<void>)
    free(g_g_small as ptr<void>)
    free(g_h_small as ptr<void>)
    free(g_g_large as ptr<void>)
    free(g_h_large as ptr<void>)
    free(g_primes as ptr<void>)

    return total
}

function main() -> i32 {
    let result: i64 = compute_T_mod(TARGET, MOD)
    printf("%lld\n", result)
    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; }

int32_t* sieve_primes_i32_ptr_i32(int32_t limit, int32_t* count);
int64_t tri_i64_i64(int64_t x, int64_t mod);
void min25_init_i64_i64(int64_t n, int64_t mod);
int64_t pi_func_i64(int64_t x);
int64_t psum_i64(int64_t x);
int64_t compute_T_mod_i64_i64(int64_t N, int64_t mod);
int32_t main(void);

static const int64_t MOD = 715827883;
static const int64_t TARGET = 1000000000000;

/* Module statics */
static int32_t g_v = 0;
static int32_t* g_primes = ((int32_t*)(NULL));
static int32_t g_num_primes = 0;
static int64_t* g_vals = ((int64_t*)(NULL));
static int64_t* g_g_small = ((int64_t*)(NULL));
static int64_t* g_h_small = ((int64_t*)(NULL));
static int64_t* g_g_large = ((int64_t*)(NULL));
static int64_t* g_h_large = ((int64_t*)(NULL));






int32_t* sieve_primes_i32_ptr_i32(int32_t limit, int32_t* count) {
    if (limit < 2) {
        count[0] = 0;
        return ((int32_t*)(NULL));
    }
    if (limit == 2) {
        int32_t* p = (int32_t*)(((int32_t*)(malloc(4))));
        p[0] = 2;
        count[0] = 1;
        return p;
    }
    int32_t size = (FLOW_CHECKED_DIV((limit), (2)) + 1);
    int8_t* is_comp = (int8_t*)(((int8_t*)(calloc(((int64_t)(size)), 1))));
    int32_t* primes = (int32_t*)(((int32_t*)(malloc((((int64_t)((size + 1))) * 4)))));
    int32_t pc = 0;
    primes[pc] = 2;
    pc = (pc + 1);
    int32_t r = ((int32_t)(sqrt(((double)(limit)))));
    int32_t i = 1;
    while (i <= FLOW_CHECKED_DIV((r), (2))) {
        if (is_comp[i] == 0) {
            int32_t p = ((2 * i) + 1);
            int32_t start = FLOW_CHECKED_DIV(((p * p)), (2));
            int32_t step = p;
            int32_t j = start;
            while (j < size) {
                is_comp[j] = 1;
                j = (j + step);
            }
        }
        i = (i + 1);
    }
    i = 1;
    while (i < size) {
        if (is_comp[i] == 0) {
            primes[pc] = ((2 * i) + 1);
            pc = (pc + 1);
        }
        i = (i + 1);
    }
    free(((void*)(is_comp)));
    count[0] = pc;
    return primes;
}

int64_t tri_i64_i64(int64_t x, int64_t mod) {
    __int128 val = FLOW_CHECKED_DIV(((((__int128)(x)) * ((__int128)((x + 1))))), (2));
    return ((int64_t)(FLOW_CHECKED_MOD((val), (((__int128)(mod))))));
}

void min25_init_i64_i64(int64_t n, int64_t mod) {
    g_v = ((int32_t)(sqrt(((double)(n)))));
    int32_t* count_buf = (int32_t*)(((int32_t*)(malloc(4))));
    g_primes = sieve_primes_i32_ptr_i32(g_v, count_buf);
    g_num_primes = count_buf[0];
    free(((void*)(count_buf)));
    g_vals = ((int64_t*)(calloc(((int64_t)((g_v + 1))), 8)));
    g_g_small = ((int64_t*)(calloc(((int64_t)((g_v + 1))), 8)));
    g_h_small = ((int64_t*)(calloc(((int64_t)((g_v + 1))), 8)));
    g_g_large = ((int64_t*)(calloc(((int64_t)((g_v + 1))), 8)));
    g_h_large = ((int64_t*)(calloc(((int64_t)((g_v + 1))), 8)));
    int32_t x = 0;
    while (x <= g_v) {
        if (x >= 2) {
            g_g_small[x] = ((int64_t)((x - 1)));
            g_h_small[x] = ((int64_t)(FLOW_CHECKED_MOD(((FLOW_CHECKED_DIV(((((__int128)(x)) * ((__int128)((x + 1))))), (2)) - 1)), (((__int128)(mod))))));
        } else {
            g_g_small[x] = 0;
            g_h_small[x] = 0;
        }
        x = (x + 1);
    }
    int32_t i = 1;
    while (i <= g_v) {
        int64_t xx = FLOW_CHECKED_DIV((n), (((int64_t)(i))));
        g_vals[i] = xx;
        if (xx >= 2) {
            g_g_large[i] = (xx - 1);
            g_h_large[i] = ((int64_t)(FLOW_CHECKED_MOD(((FLOW_CHECKED_DIV(((((__int128)(xx)) * ((__int128)((xx + 1))))), (2)) - 1)), (((__int128)(mod))))));
        } else {
            g_g_large[i] = 0;
            g_h_large[i] = 0;
        }
        i = (i + 1);
    }
    int32_t pi = 0;
    while (pi < g_num_primes) {
        int64_t p = ((int64_t)(g_primes[pi]));
        int64_t p2 = (p * p);
        if (p2 > n) {
            break;
        }
        int64_t g_p1 = g_g_small[((int32_t)((p - 1)))];
        int64_t h_p1 = g_h_small[((int32_t)((p - 1)))];
        int64_t i_max = FLOW_CHECKED_DIV((n), (p2));
        if (i_max > ((int64_t)(g_v))) {
            i_max = ((int64_t)(g_v));
        }
        int32_t i2 = 1;
        while (((int64_t)(i2)) <= i_max) {
            int64_t y = FLOW_CHECKED_DIV((g_vals[i2]), (p));
            int64_t g_y = 0;
            int64_t h_y = 0;
            if (y <= ((int64_t)(g_v))) {
                g_y = g_g_small[((int32_t)(y))];
                h_y = g_h_small[((int32_t)(y))];
            } else {
                int32_t k = ((int32_t)(FLOW_CHECKED_DIV((n), (y))));
                g_y = g_g_large[k];
                h_y = g_h_large[k];
            }
            g_g_large[i2] = (g_g_large[i2] - (g_y - g_p1));
            int64_t diff = (h_y - h_p1);
            if (diff < 0) {
                diff = (diff + mod);
            }
            __int128 hh = FLOW_CHECKED_MOD(((((__int128)(p)) * ((__int128)(diff)))), (((__int128)(mod))));
            g_h_large[i2] = FLOW_CHECKED_MOD(((g_h_large[i2] - ((int64_t)(hh)))), (mod));
            if (g_h_large[i2] < 0) {
                g_h_large[i2] = (g_h_large[i2] + mod);
            }
            i2 = (i2 + 1);
        }
        int64_t xx2 = ((int64_t)(g_v));
        while (xx2 >= p2) {
            int32_t y = ((int32_t)(FLOW_CHECKED_DIV((xx2), (p))));
            g_g_small[((int32_t)(xx2))] = (g_g_small[((int32_t)(xx2))] - (g_g_small[y] - g_p1));
            int64_t diff2 = (g_h_small[y] - h_p1);
            if (diff2 < 0) {
                diff2 = (diff2 + mod);
            }
            __int128 hh2 = FLOW_CHECKED_MOD(((((__int128)(p)) * ((__int128)(diff2)))), (((__int128)(mod))));
            g_h_small[((int32_t)(xx2))] = FLOW_CHECKED_MOD(((g_h_small[((int32_t)(xx2))] - ((int64_t)(hh2)))), (mod));
            if (g_h_small[((int32_t)(xx2))] < 0) {
                g_h_small[((int32_t)(xx2))] = (g_h_small[((int32_t)(xx2))] + mod);
            }
            xx2 = (xx2 - 1);
        }
        pi = (pi + 1);
    }
}

int64_t pi_func_i64(int64_t x) {
    if (x <= ((int64_t)(g_v))) {
        return g_g_small[((int32_t)(x))];
    }
    return g_g_large[((int32_t)(FLOW_CHECKED_DIV((TARGET), (x))))];
}

int64_t psum_i64(int64_t x) {
    if (x <= ((int64_t)(g_v))) {
        return g_h_small[((int32_t)(x))];
    }
    return g_h_large[((int32_t)(FLOW_CHECKED_DIV((TARGET), (x))))];
}

int64_t compute_T_mod_i64_i64(int64_t N, int64_t mod) {
    if (N <= 1) {
        return 0;
    }
    int32_t sqrtN = ((int32_t)(sqrt(((double)(N)))));
    min25_init_i64_i64(N, mod);
    int64_t total = 0;
    int32_t pi = 0;
    while (pi < g_num_primes) {
        int64_t p = ((int64_t)(g_primes[pi]));
        if ((p * p) > N) {
            break;
        }
        int64_t x1 = FLOW_CHECKED_DIV((N), (p));
        int64_t x2 = FLOW_CHECKED_DIV((N), ((p * p)));
        int64_t f = FLOW_CHECKED_MOD(((tri_i64_i64(x1, mod) - (FLOW_CHECKED_MOD((p), (mod)) * tri_i64_i64(x2, mod)))), (mod));
        if (f < 0) {
            f = (f + mod);
        }
        total = FLOW_CHECKED_MOD(((total + (FLOW_CHECKED_MOD(((p - 2)), (mod)) * f))), (mod));
        int64_t pe = (p * p);
        int64_t p_pow = p;
        while (pe <= N) {
            int64_t xe = FLOW_CHECKED_DIV((N), (pe));
            int64_t xnext = FLOW_CHECKED_DIV((N), ((pe * p)));
            int64_t A = (((p - 1) * p_pow) - 1);
            int64_t f2 = FLOW_CHECKED_MOD(((tri_i64_i64(xe, mod) - (FLOW_CHECKED_MOD((p), (mod)) * tri_i64_i64(xnext, mod)))), (mod));
            if (f2 < 0) {
                f2 = (f2 + mod);
            }
            total = FLOW_CHECKED_MOD(((total + (FLOW_CHECKED_MOD((A), (mod)) * f2))), (mod));
            p_pow = (p_pow * p);
            pe = (pe * p);
        }
        pi = (pi + 1);
    }
    int64_t q = 1;
    while (q < ((int64_t)(sqrtN))) {
        int64_t hi = FLOW_CHECKED_DIV((N), (q));
        if (hi <= ((int64_t)(sqrtN))) {
            break;
        }
        int64_t lo = (FLOW_CHECKED_DIV((N), ((q + 1))) + 1);
        if (lo <= ((int64_t)(sqrtN))) {
            lo = (((int64_t)(sqrtN)) + 1);
        }
        if (lo > hi) {
            q = (q + 1);
            continue;
        }
        int64_t sum_p = FLOW_CHECKED_MOD(((psum_i64(hi) - psum_i64((lo - 1)))), (mod));
        if (sum_p < 0) {
            sum_p = (sum_p + mod);
        }
        int64_t cnt_p = (pi_func_i64(hi) - pi_func_i64((lo - 1)));
        int64_t term2 = FLOW_CHECKED_MOD(((sum_p - FLOW_CHECKED_MOD(((2 * FLOW_CHECKED_MOD((cnt_p), (mod)))), (mod)))), (mod));
        if (term2 < 0) {
            term2 = (term2 + mod);
        }
        total = FLOW_CHECKED_MOD(((total + (tri_i64_i64(q, mod) * term2))), (mod));
        q = (q + 1);
    }
    total = FLOW_CHECKED_MOD((total), (mod));
    if (total < 0) {
        total = (total + mod);
    }
    free(((void*)(g_vals)));
    free(((void*)(g_g_small)));
    free(((void*)(g_h_small)));
    free(((void*)(g_g_large)));
    free(((void*)(g_h_large)));
    free(((void*)(g_primes)));
    return total;
}

int32_t main(void) {
    int64_t result = compute_T_mod_i64_i64(TARGET, MOD);
    printf("%lld\n", result);
    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 @malloc(i64) -> !llvm.ptr
  func.func private @sqrt(f64) -> f64

  // Constant: MOD
  llvm.mlir.global internal constant @MOD(715827883 : i64) : i64
  // Constant: TARGET
  llvm.mlir.global internal constant @TARGET(1000000000000 : i64) : i64
  // Module static: g_v
  llvm.mlir.global internal @g_v(0 : i32) : i32
  // Module static: g_primes
  llvm.mlir.global internal @g_primes() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: g_num_primes
  llvm.mlir.global internal @g_num_primes(0 : i32) : i32
  // Module static: g_vals
  llvm.mlir.global internal @g_vals() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: g_g_small
  llvm.mlir.global internal @g_g_small() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  // Module static: g_h_small
  llvm.mlir.global internal @g_h_small() {addr_space = 0 : i32} : !llvm.ptr {
    %3 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3 : !llvm.ptr
  }
  // Module static: g_g_large
  llvm.mlir.global internal @g_g_large() {addr_space = 0 : i32} : !llvm.ptr {
    %4 = llvm.mlir.zero : !llvm.ptr
    llvm.return %4 : !llvm.ptr
  }
  // Module static: g_h_large
  llvm.mlir.global internal @g_h_large() {addr_space = 0 : i32} : !llvm.ptr {
    %5 = llvm.mlir.zero : !llvm.ptr
    llvm.return %5 : !llvm.ptr
  }
  func.func @sieve_primes(%arg0: i32, %arg1: !llvm.ptr) -> !llvm.ptr {
    %6 = arith.constant 2 : i32
    %7 = arith.cmpi slt, %arg0, %6 : i32
    cf.cond_br %7, ^bb0, ^bb1
    ^bb0:
      %8 = arith.constant 0 : i32
      %9 = arith.constant 0 : i32
      %10 = arith.extsi %9 : i32 to i64
      %11 = llvm.getelementptr %arg1[%10] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %8, %11 : i32, !llvm.ptr
      %12 = llvm.mlir.zero : !llvm.ptr
      func.return %12 : !llvm.ptr
    ^bb1:
      cf.br ^bb2
    ^bb2:
    %13 = arith.constant 2 : i32
    %14 = arith.cmpi eq, %arg0, %13 : i32
    cf.cond_br %14, ^bb3, ^bb4
    ^bb3:
      %16 = arith.constant 4 : i32
      %17 = arith.extsi %16 : i32 to i64
      %15 = func.call @malloc(%17) : (i64) -> !llvm.ptr
      %18 = arith.constant 2 : i32
      %19 = arith.constant 0 : i32
      %20 = arith.extsi %19 : i32 to i64
      %21 = llvm.getelementptr %15[%20] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %18, %21 : i32, !llvm.ptr
      %22 = arith.constant 1 : i32
      %23 = arith.constant 0 : i32
      %24 = arith.extsi %23 : i32 to i64
      %25 = llvm.getelementptr %arg1[%24] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %22, %25 : i32, !llvm.ptr
      func.return %15 : !llvm.ptr
    ^bb4:
      cf.br ^bb5
    ^bb5:
    %26 = arith.constant 2 : i32
    %27 = arith.divsi %arg0, %26 : i32
    %28 = arith.constant 1 : i32
    %29 = arith.addi %27, %28 : i32
    %31 = arith.extsi %29 : i32 to i64
    %32 = arith.constant 1 : i32
    %33 = arith.extsi %32 : i32 to i64
    %30 = func.call @calloc(%31, %33) : (i64, i64) -> !llvm.ptr
    %35 = arith.constant 1 : i32
    %36 = arith.addi %29, %35 : i32
    %37 = arith.extsi %36 : i32 to i64
    %38 = arith.constant 4 : i32
    %40 = arith.extsi %38 : i32 to i64
    %39 = arith.muli %37, %40 : i64
    %34 = func.call @malloc(%39) : (i64) -> !llvm.ptr
    %41 = arith.constant 0 : i32
    %42 = llvm.mlir.constant(1 : i64) : i64
    %43 = llvm.alloca %42 x i32 : (i64) -> !llvm.ptr
    llvm.store %41, %43 : i32, !llvm.ptr
    %44 = arith.constant 2 : i32
    %45 = llvm.load %43 : !llvm.ptr -> i32
    %46 = arith.extsi %45 : i32 to i64
    %47 = llvm.getelementptr %34[%46] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %44, %47 : i32, !llvm.ptr
    %48 = llvm.load %43 : !llvm.ptr -> i32
    %49 = arith.constant 1 : i32
    %50 = arith.addi %48, %49 : i32
    llvm.store %50, %43 : i32, !llvm.ptr
    %51 = arith.sitofp %arg0 : i32 to f64
    %52 = math.sqrt %51 : f64
    %53 = arith.fptosi %52 : f64 to i32
    %54 = arith.constant 1 : i32
    %55 = llvm.mlir.constant(1 : i64) : i64
    %56 = llvm.alloca %55 x i32 : (i64) -> !llvm.ptr
    llvm.store %54, %56 : i32, !llvm.ptr
    cf.br ^bb6
    ^bb6:
    %57 = llvm.load %56 : !llvm.ptr -> i32
    %58 = arith.constant 2 : i32
    %59 = arith.divsi %53, %58 : i32
    %60 = arith.cmpi sle, %57, %59 : i32
    cf.cond_br %60, ^bb7, ^bb8
    ^bb7:
      %62 = llvm.load %56 : !llvm.ptr -> i32
      %63 = arith.extsi %62 : i32 to i64
      %64 = llvm.getelementptr %30[%63] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %61 = llvm.load %64 : !llvm.ptr -> i8
      %65 = arith.constant 0 : i32
      %67 = arith.extsi %61 : i8 to i32
      %66 = arith.cmpi eq, %67, %65 : i32
      cf.cond_br %66, ^bb9, ^bb10
      ^bb9:
        %68 = arith.constant 2 : i32
        %69 = llvm.load %56 : !llvm.ptr -> i32
        %70 = arith.muli %68, %69 : i32
        %71 = arith.constant 1 : i32
        %72 = arith.addi %70, %71 : i32
        %73 = arith.muli %72, %72 : i32
        %74 = arith.constant 2 : i32
        %75 = arith.divsi %73, %74 : i32
        %76 = llvm.mlir.constant(1 : i64) : i64
        %77 = llvm.alloca %76 x i32 : (i64) -> !llvm.ptr
        llvm.store %75, %77 : i32, !llvm.ptr
        cf.br ^bb12
        ^bb12:
        %78 = llvm.load %77 : !llvm.ptr -> i32
        %79 = arith.cmpi slt, %78, %29 : i32
        cf.cond_br %79, ^bb13, ^bb14
        ^bb13:
          %80 = arith.constant 1 : i32
          %81 = llvm.load %77 : !llvm.ptr -> i32
          %82 = arith.trunci %80 : i32 to i8
          %83 = arith.extsi %81 : i32 to i64
          %84 = llvm.getelementptr %30[%83] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %82, %84 : i8, !llvm.ptr
          %85 = llvm.load %77 : !llvm.ptr -> i32
          %86 = arith.addi %85, %72 : i32
          llvm.store %86, %77 : i32, !llvm.ptr
          cf.br ^bb12
        ^bb14:
        cf.br ^bb11
      ^bb10:
        cf.br ^bb11
      ^bb11:
      %87 = llvm.load %56 : !llvm.ptr -> i32
      %88 = arith.constant 1 : i32
      %89 = arith.addi %87, %88 : i32
      llvm.store %89, %56 : i32, !llvm.ptr
      cf.br ^bb6
    ^bb8:
    %90 = arith.constant 1 : i32
    llvm.store %90, %56 : i32, !llvm.ptr
    cf.br ^bb15
    ^bb15:
    %91 = llvm.load %56 : !llvm.ptr -> i32
    %92 = arith.cmpi slt, %91, %29 : i32
    cf.cond_br %92, ^bb16, ^bb17
    ^bb16:
      %94 = llvm.load %56 : !llvm.ptr -> i32
      %95 = arith.extsi %94 : i32 to i64
      %96 = llvm.getelementptr %30[%95] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %93 = llvm.load %96 : !llvm.ptr -> i8
      %97 = arith.constant 0 : i32
      %99 = arith.extsi %93 : i8 to i32
      %98 = arith.cmpi eq, %99, %97 : i32
      cf.cond_br %98, ^bb18, ^bb19
      ^bb18:
        %100 = arith.constant 2 : i32
        %101 = llvm.load %56 : !llvm.ptr -> i32
        %102 = arith.muli %100, %101 : i32
        %103 = arith.constant 1 : i32
        %104 = arith.addi %102, %103 : i32
        %105 = llvm.load %43 : !llvm.ptr -> i32
        %106 = arith.extsi %105 : i32 to i64
        %107 = llvm.getelementptr %34[%106] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %104, %107 : i32, !llvm.ptr
        %108 = llvm.load %43 : !llvm.ptr -> i32
        %109 = arith.constant 1 : i32
        %110 = arith.addi %108, %109 : i32
        llvm.store %110, %43 : i32, !llvm.ptr
        cf.br ^bb20
      ^bb19:
        cf.br ^bb20
      ^bb20:
      %111 = llvm.load %56 : !llvm.ptr -> i32
      %112 = arith.constant 1 : i32
      %113 = arith.addi %111, %112 : i32
      llvm.store %113, %56 : i32, !llvm.ptr
      cf.br ^bb15
    ^bb17:
    func.call @free(%30) : (!llvm.ptr) -> ()
    %115 = llvm.load %43 : !llvm.ptr -> i32
    %116 = arith.constant 0 : i32
    %117 = arith.extsi %116 : i32 to i64
    %118 = llvm.getelementptr %arg1[%117] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %115, %118 : i32, !llvm.ptr
    func.return %34 : !llvm.ptr
  }
  func.func @tri(%arg0: i64, %arg1: i64) -> i64 {
    %119 = arith.extsi %arg0 : i64 to i128
    %120 = arith.constant 1 : i32
    %122 = arith.extsi %120 : i32 to i64
    %121 = arith.addi %arg0, %122 : i64
    %123 = arith.extsi %121 : i64 to i128
    %125 = arith.trunci %119 : i128 to i64
    %126 = arith.trunci %123 : i128 to i64
    %124 = arith.muli %125, %126 : i64
    %127 = arith.constant 2 : i32
    %129 = arith.extsi %127 : i32 to i64
    %128 = arith.divsi %124, %129 : i64
    %130 = arith.extsi %128 : i64 to i128
    %131 = arith.extsi %arg1 : i64 to i128
    %133 = arith.trunci %130 : i128 to i64
    %134 = arith.trunci %131 : i128 to i64
    %132 = arith.remsi %133, %134 : i64
    func.return %132 : i64
  }
  func.func @min25_init(%arg0: i64, %arg1: i64) -> () {
    %135 = arith.sitofp %arg0 : i64 to f64
    %136 = math.sqrt %135 : f64
    %137 = arith.fptosi %136 : f64 to i32
    %138 = llvm.mlir.addressof @g_v : !llvm.ptr
    llvm.store %137, %138 : i32, !llvm.ptr
    %140 = arith.constant 4 : i32
    %141 = arith.extsi %140 : i32 to i64
    %139 = func.call @malloc(%141) : (i64) -> !llvm.ptr
    %143 = llvm.mlir.addressof @g_v : !llvm.ptr
    %144 = llvm.load %143 : !llvm.ptr -> i32
    %142 = func.call @sieve_primes(%144, %139) : (i32, !llvm.ptr) -> !llvm.ptr
    %145 = llvm.mlir.addressof @g_primes : !llvm.ptr
    llvm.store %142, %145 : !llvm.ptr, !llvm.ptr
    %147 = arith.constant 0 : i32
    %148 = arith.extsi %147 : i32 to i64
    %149 = llvm.getelementptr %139[%148] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %146 = llvm.load %149 : !llvm.ptr -> i32
    %150 = llvm.mlir.addressof @g_num_primes : !llvm.ptr
    llvm.store %146, %150 : i32, !llvm.ptr
    func.call @free(%139) : (!llvm.ptr) -> ()
    %153 = llvm.mlir.addressof @g_v : !llvm.ptr
    %154 = llvm.load %153 : !llvm.ptr -> i32
    %155 = arith.constant 1 : i32
    %156 = arith.addi %154, %155 : i32
    %157 = arith.extsi %156 : i32 to i64
    %158 = arith.constant 8 : i32
    %159 = arith.extsi %158 : i32 to i64
    %152 = func.call @calloc(%157, %159) : (i64, i64) -> !llvm.ptr
    %160 = llvm.mlir.addressof @g_vals : !llvm.ptr
    llvm.store %152, %160 : !llvm.ptr, !llvm.ptr
    %162 = llvm.mlir.addressof @g_v : !llvm.ptr
    %163 = llvm.load %162 : !llvm.ptr -> i32
    %164 = arith.constant 1 : i32
    %165 = arith.addi %163, %164 : i32
    %166 = arith.extsi %165 : i32 to i64
    %167 = arith.constant 8 : i32
    %168 = arith.extsi %167 : i32 to i64
    %161 = func.call @calloc(%166, %168) : (i64, i64) -> !llvm.ptr
    %169 = llvm.mlir.addressof @g_g_small : !llvm.ptr
    llvm.store %161, %169 : !llvm.ptr, !llvm.ptr
    %171 = llvm.mlir.addressof @g_v : !llvm.ptr
    %172 = llvm.load %171 : !llvm.ptr -> i32
    %173 = arith.constant 1 : i32
    %174 = arith.addi %172, %173 : i32
    %175 = arith.extsi %174 : i32 to i64
    %176 = arith.constant 8 : i32
    %177 = arith.extsi %176 : i32 to i64
    %170 = func.call @calloc(%175, %177) : (i64, i64) -> !llvm.ptr
    %178 = llvm.mlir.addressof @g_h_small : !llvm.ptr
    llvm.store %170, %178 : !llvm.ptr, !llvm.ptr
    %180 = llvm.mlir.addressof @g_v : !llvm.ptr
    %181 = llvm.load %180 : !llvm.ptr -> i32
    %182 = arith.constant 1 : i32
    %183 = arith.addi %181, %182 : i32
    %184 = arith.extsi %183 : i32 to i64
    %185 = arith.constant 8 : i32
    %186 = arith.extsi %185 : i32 to i64
    %179 = func.call @calloc(%184, %186) : (i64, i64) -> !llvm.ptr
    %187 = llvm.mlir.addressof @g_g_large : !llvm.ptr
    llvm.store %179, %187 : !llvm.ptr, !llvm.ptr
    %189 = llvm.mlir.addressof @g_v : !llvm.ptr
    %190 = llvm.load %189 : !llvm.ptr -> i32
    %191 = arith.constant 1 : i32
    %192 = arith.addi %190, %191 : i32
    %193 = arith.extsi %192 : i32 to i64
    %194 = arith.constant 8 : i32
    %195 = arith.extsi %194 : i32 to i64
    %188 = func.call @calloc(%193, %195) : (i64, i64) -> !llvm.ptr
    %196 = llvm.mlir.addressof @g_h_large : !llvm.ptr
    llvm.store %188, %196 : !llvm.ptr, !llvm.ptr
    %197 = arith.constant 0 : i32
    %198 = llvm.mlir.constant(1 : i64) : i64
    %199 = llvm.alloca %198 x i32 : (i64) -> !llvm.ptr
    llvm.store %197, %199 : i32, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %200 = llvm.load %199 : !llvm.ptr -> i32
    %201 = llvm.mlir.addressof @g_v : !llvm.ptr
    %202 = llvm.load %201 : !llvm.ptr -> i32
    %203 = arith.cmpi sle, %200, %202 : i32
    cf.cond_br %203, ^bb22, ^bb23
    ^bb22:
      %204 = llvm.load %199 : !llvm.ptr -> i32
      %205 = arith.constant 2 : i32
      %206 = arith.cmpi sge, %204, %205 : i32
      cf.cond_br %206, ^bb24, ^bb25
      ^bb24:
        %207 = llvm.load %199 : !llvm.ptr -> i32
        %208 = arith.constant 1 : i32
        %209 = arith.subi %207, %208 : i32
        %210 = arith.extsi %209 : i32 to i64
        %211 = llvm.mlir.addressof @g_g_small : !llvm.ptr
        %212 = llvm.load %211 : !llvm.ptr -> !llvm.ptr
        %213 = llvm.load %199 : !llvm.ptr -> i32
        %214 = arith.extsi %213 : i32 to i64
        %215 = llvm.getelementptr %212[%214] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %210, %215 : i64, !llvm.ptr
        %216 = llvm.load %199 : !llvm.ptr -> i32
        %217 = arith.extsi %216 : i32 to i128
        %218 = llvm.load %199 : !llvm.ptr -> i32
        %219 = arith.constant 1 : i32
        %220 = arith.addi %218, %219 : i32
        %221 = arith.extsi %220 : i32 to i128
        %223 = arith.trunci %217 : i128 to i64
        %224 = arith.trunci %221 : i128 to i64
        %222 = arith.muli %223, %224 : i64
        %225 = arith.constant 2 : i32
        %227 = arith.extsi %225 : i32 to i64
        %226 = arith.divsi %222, %227 : i64
        %228 = arith.constant 1 : i32
        %230 = arith.extsi %228 : i32 to i64
        %229 = arith.subi %226, %230 : i64
        %231 = arith.extsi %arg1 : i64 to i128
        %233 = arith.trunci %231 : i128 to i64
        %232 = arith.remsi %229, %233 : i64
        %234 = llvm.mlir.addressof @g_h_small : !llvm.ptr
        %235 = llvm.load %234 : !llvm.ptr -> !llvm.ptr
        %236 = llvm.load %199 : !llvm.ptr -> i32
        %237 = arith.extsi %236 : i32 to i64
        %238 = llvm.getelementptr %235[%237] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %232, %238 : i64, !llvm.ptr
        cf.br ^bb26
      ^bb25:
        %239 = arith.constant 0 : i32
        %240 = llvm.mlir.addressof @g_g_small : !llvm.ptr
        %241 = llvm.load %240 : !llvm.ptr -> !llvm.ptr
        %242 = llvm.load %199 : !llvm.ptr -> i32
        %243 = arith.extsi %239 : i32 to i64
        %244 = arith.extsi %242 : i32 to i64
        %245 = llvm.getelementptr %241[%244] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %243, %245 : i64, !llvm.ptr
        %246 = arith.constant 0 : i32
        %247 = llvm.mlir.addressof @g_h_small : !llvm.ptr
        %248 = llvm.load %247 : !llvm.ptr -> !llvm.ptr
        %249 = llvm.load %199 : !llvm.ptr -> i32
        %250 = arith.extsi %246 : i32 to i64
        %251 = arith.extsi %249 : i32 to i64
        %252 = llvm.getelementptr %248[%251] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %250, %252 : i64, !llvm.ptr
        cf.br ^bb26
      ^bb26:
      %253 = llvm.load %199 : !llvm.ptr -> i32
      %254 = arith.constant 1 : i32
      %255 = arith.addi %253, %254 : i32
      llvm.store %255, %199 : i32, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    %256 = arith.constant 1 : i32
    %257 = llvm.mlir.constant(1 : i64) : i64
    %258 = llvm.alloca %257 x i32 : (i64) -> !llvm.ptr
    llvm.store %256, %258 : i32, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %259 = llvm.load %258 : !llvm.ptr -> i32
    %260 = llvm.mlir.addressof @g_v : !llvm.ptr
    %261 = llvm.load %260 : !llvm.ptr -> i32
    %262 = arith.cmpi sle, %259, %261 : i32
    cf.cond_br %262, ^bb28, ^bb29
    ^bb28:
      %263 = llvm.load %258 : !llvm.ptr -> i32
      %264 = arith.extsi %263 : i32 to i64
      %265 = arith.divsi %arg0, %264 : i64
      %266 = llvm.mlir.addressof @g_vals : !llvm.ptr
      %267 = llvm.load %266 : !llvm.ptr -> !llvm.ptr
      %268 = llvm.load %258 : !llvm.ptr -> i32
      %269 = arith.extsi %268 : i32 to i64
      %270 = llvm.getelementptr %267[%269] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %265, %270 : i64, !llvm.ptr
      %271 = arith.constant 2 : i32
      %273 = arith.extsi %271 : i32 to i64
      %272 = arith.cmpi sge, %265, %273 : i64
      cf.cond_br %272, ^bb30, ^bb31
      ^bb30:
        %274 = arith.constant 1 : i32
        %276 = arith.extsi %274 : i32 to i64
        %275 = arith.subi %265, %276 : i64
        %277 = llvm.mlir.addressof @g_g_large : !llvm.ptr
        %278 = llvm.load %277 : !llvm.ptr -> !llvm.ptr
        %279 = llvm.load %258 : !llvm.ptr -> i32
        %280 = arith.extsi %279 : i32 to i64
        %281 = llvm.getelementptr %278[%280] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %275, %281 : i64, !llvm.ptr
        %282 = arith.extsi %265 : i64 to i128
        %283 = arith.constant 1 : i32
        %285 = arith.extsi %283 : i32 to i64
        %284 = arith.addi %265, %285 : i64
        %286 = arith.extsi %284 : i64 to i128
        %288 = arith.trunci %282 : i128 to i64
        %289 = arith.trunci %286 : i128 to i64
        %287 = arith.muli %288, %289 : i64
        %290 = arith.constant 2 : i32
        %292 = arith.extsi %290 : i32 to i64
        %291 = arith.divsi %287, %292 : i64
        %293 = arith.constant 1 : i32
        %295 = arith.extsi %293 : i32 to i64
        %294 = arith.subi %291, %295 : i64
        %296 = arith.extsi %arg1 : i64 to i128
        %298 = arith.trunci %296 : i128 to i64
        %297 = arith.remsi %294, %298 : i64
        %299 = llvm.mlir.addressof @g_h_large : !llvm.ptr
        %300 = llvm.load %299 : !llvm.ptr -> !llvm.ptr
        %301 = llvm.load %258 : !llvm.ptr -> i32
        %302 = arith.extsi %301 : i32 to i64
        %303 = llvm.getelementptr %300[%302] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %297, %303 : i64, !llvm.ptr
        cf.br ^bb32
      ^bb31:
        %304 = arith.constant 0 : i32
        %305 = llvm.mlir.addressof @g_g_large : !llvm.ptr
        %306 = llvm.load %305 : !llvm.ptr -> !llvm.ptr
        %307 = llvm.load %258 : !llvm.ptr -> i32
        %308 = arith.extsi %304 : i32 to i64
        %309 = arith.extsi %307 : i32 to i64
        %310 = llvm.getelementptr %306[%309] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %308, %310 : i64, !llvm.ptr
        %311 = arith.constant 0 : i32
        %312 = llvm.mlir.addressof @g_h_large : !llvm.ptr
        %313 = llvm.load %312 : !llvm.ptr -> !llvm.ptr
        %314 = llvm.load %258 : !llvm.ptr -> i32
        %315 = arith.extsi %311 : i32 to i64
        %316 = arith.extsi %314 : i32 to i64
        %317 = llvm.getelementptr %313[%316] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %315, %317 : i64, !llvm.ptr
        cf.br ^bb32
      ^bb32:
      %318 = llvm.load %258 : !llvm.ptr -> i32
      %319 = arith.constant 1 : i32
      %320 = arith.addi %318, %319 : i32
      llvm.store %320, %258 : i32, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %321 = arith.constant 0 : i32
    %322 = llvm.mlir.constant(1 : i64) : i64
    %323 = llvm.alloca %322 x i32 : (i64) -> !llvm.ptr
    llvm.store %321, %323 : i32, !llvm.ptr
    cf.br ^bb33
    ^bb33:
    %324 = llvm.load %323 : !llvm.ptr -> i32
    %325 = llvm.mlir.addressof @g_num_primes : !llvm.ptr
    %326 = llvm.load %325 : !llvm.ptr -> i32
    %327 = arith.cmpi slt, %324, %326 : i32
    cf.cond_br %327, ^bb34, ^bb35
    ^bb34:
      %329 = llvm.mlir.addressof @g_primes : !llvm.ptr
      %330 = llvm.load %329 : !llvm.ptr -> !llvm.ptr
      %331 = llvm.load %323 : !llvm.ptr -> i32
      %332 = arith.extsi %331 : i32 to i64
      %333 = llvm.getelementptr %330[%332] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %328 = llvm.load %333 : !llvm.ptr -> i32
      %334 = arith.extsi %328 : i32 to i64
      %335 = arith.muli %334, %334 : i64
      %336 = arith.cmpi sgt, %335, %arg0 : i64
      cf.cond_br %336, ^bb36, ^bb37
      ^bb36:
        cf.br ^bb35
      ^bb37:
        cf.br ^bb38
      ^bb38:
      %338 = llvm.mlir.addressof @g_g_small : !llvm.ptr
      %339 = llvm.load %338 : !llvm.ptr -> !llvm.ptr
      %340 = arith.constant 1 : i32
      %342 = arith.extsi %340 : i32 to i64
      %341 = arith.subi %334, %342 : i64
      %343 = arith.trunci %341 : i64 to i32
      %344 = arith.extsi %343 : i32 to i64
      %345 = llvm.getelementptr %339[%344] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %337 = llvm.load %345 : !llvm.ptr -> i64
      %347 = llvm.mlir.addressof @g_h_small : !llvm.ptr
      %348 = llvm.load %347 : !llvm.ptr -> !llvm.ptr
      %349 = arith.constant 1 : i32
      %351 = arith.extsi %349 : i32 to i64
      %350 = arith.subi %334, %351 : i64
      %352 = arith.trunci %350 : i64 to i32
      %353 = arith.extsi %352 : i32 to i64
      %354 = llvm.getelementptr %348[%353] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %346 = llvm.load %354 : !llvm.ptr -> i64
      %355 = arith.divsi %arg0, %335 : i64
      %356 = llvm.mlir.constant(1 : i64) : i64
      %357 = llvm.alloca %356 x i64 : (i64) -> !llvm.ptr
      llvm.store %355, %357 : i64, !llvm.ptr
      %358 = llvm.load %357 : !llvm.ptr -> i64
      %359 = llvm.mlir.addressof @g_v : !llvm.ptr
      %360 = llvm.load %359 : !llvm.ptr -> i32
      %361 = arith.extsi %360 : i32 to i64
      %362 = arith.cmpi sgt, %358, %361 : i64
      cf.cond_br %362, ^bb39, ^bb40
      ^bb39:
        %363 = llvm.mlir.addressof @g_v : !llvm.ptr
        %364 = llvm.load %363 : !llvm.ptr -> i32
        %365 = arith.extsi %364 : i32 to i64
        llvm.store %365, %357 : i64, !llvm.ptr
        cf.br ^bb41
      ^bb40:
        cf.br ^bb41
      ^bb41:
      %366 = arith.constant 1 : i32
      %367 = llvm.mlir.constant(1 : i64) : i64
      %368 = llvm.alloca %367 x i32 : (i64) -> !llvm.ptr
      llvm.store %366, %368 : i32, !llvm.ptr
      cf.br ^bb42
      ^bb42:
      %369 = llvm.load %368 : !llvm.ptr -> i32
      %370 = arith.extsi %369 : i32 to i64
      %371 = llvm.load %357 : !llvm.ptr -> i64
      %372 = arith.cmpi sle, %370, %371 : i64
      cf.cond_br %372, ^bb43, ^bb44
      ^bb43:
        %374 = llvm.mlir.addressof @g_vals : !llvm.ptr
        %375 = llvm.load %374 : !llvm.ptr -> !llvm.ptr
        %376 = llvm.load %368 : !llvm.ptr -> i32
        %377 = arith.extsi %376 : i32 to i64
        %378 = llvm.getelementptr %375[%377] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %373 = llvm.load %378 : !llvm.ptr -> i64
        %379 = arith.divsi %373, %334 : i64
        %380 = arith.constant 0 : i32
        %381 = arith.extsi %380 : i32 to i64
        %382 = llvm.mlir.constant(1 : i64) : i64
        %383 = llvm.alloca %382 x i64 : (i64) -> !llvm.ptr
        llvm.store %381, %383 : i64, !llvm.ptr
        %384 = arith.constant 0 : i32
        %385 = arith.extsi %384 : i32 to i64
        %386 = llvm.mlir.constant(1 : i64) : i64
        %387 = llvm.alloca %386 x i64 : (i64) -> !llvm.ptr
        llvm.store %385, %387 : i64, !llvm.ptr
        %388 = llvm.mlir.addressof @g_v : !llvm.ptr
        %389 = llvm.load %388 : !llvm.ptr -> i32
        %390 = arith.extsi %389 : i32 to i64
        %391 = arith.cmpi sle, %379, %390 : i64
        cf.cond_br %391, ^bb45, ^bb46
        ^bb45:
          %393 = llvm.mlir.addressof @g_g_small : !llvm.ptr
          %394 = llvm.load %393 : !llvm.ptr -> !llvm.ptr
          %395 = arith.trunci %379 : i64 to i32
          %396 = arith.extsi %395 : i32 to i64
          %397 = llvm.getelementptr %394[%396] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %392 = llvm.load %397 : !llvm.ptr -> i64
          llvm.store %392, %383 : i64, !llvm.ptr
          %399 = llvm.mlir.addressof @g_h_small : !llvm.ptr
          %400 = llvm.load %399 : !llvm.ptr -> !llvm.ptr
          %401 = arith.trunci %379 : i64 to i32
          %402 = arith.extsi %401 : i32 to i64
          %403 = llvm.getelementptr %400[%402] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %398 = llvm.load %403 : !llvm.ptr -> i64
          llvm.store %398, %387 : i64, !llvm.ptr
          cf.br ^bb47
        ^bb46:
          %404 = arith.divsi %arg0, %379 : i64
          %405 = arith.trunci %404 : i64 to i32
          %407 = llvm.mlir.addressof @g_g_large : !llvm.ptr
          %408 = llvm.load %407 : !llvm.ptr -> !llvm.ptr
          %409 = arith.extsi %405 : i32 to i64
          %410 = llvm.getelementptr %408[%409] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %406 = llvm.load %410 : !llvm.ptr -> i64
          llvm.store %406, %383 : i64, !llvm.ptr
          %412 = llvm.mlir.addressof @g_h_large : !llvm.ptr
          %413 = llvm.load %412 : !llvm.ptr -> !llvm.ptr
          %414 = arith.extsi %405 : i32 to i64
          %415 = llvm.getelementptr %413[%414] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %411 = llvm.load %415 : !llvm.ptr -> i64
          llvm.store %411, %387 : i64, !llvm.ptr
          cf.br ^bb47
        ^bb47:
        %417 = llvm.mlir.addressof @g_g_large : !llvm.ptr
        %418 = llvm.load %417 : !llvm.ptr -> !llvm.ptr
        %419 = llvm.load %368 : !llvm.ptr -> i32
        %420 = arith.extsi %419 : i32 to i64
        %421 = llvm.getelementptr %418[%420] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %416 = llvm.load %421 : !llvm.ptr -> i64
        %422 = llvm.load %383 : !llvm.ptr -> i64
        %423 = arith.subi %422, %337 : i64
        %424 = arith.subi %416, %423 : i64
        %425 = llvm.mlir.addressof @g_g_large : !llvm.ptr
        %426 = llvm.load %425 : !llvm.ptr -> !llvm.ptr
        %427 = llvm.load %368 : !llvm.ptr -> i32
        %428 = arith.extsi %427 : i32 to i64
        %429 = llvm.getelementptr %426[%428] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %424, %429 : i64, !llvm.ptr
        %430 = llvm.load %387 : !llvm.ptr -> i64
        %431 = arith.subi %430, %346 : i64
        %432 = llvm.mlir.constant(1 : i64) : i64
        %433 = llvm.alloca %432 x i64 : (i64) -> !llvm.ptr
        llvm.store %431, %433 : i64, !llvm.ptr
        %434 = llvm.load %433 : !llvm.ptr -> i64
        %435 = arith.constant 0 : i32
        %437 = arith.extsi %435 : i32 to i64
        %436 = arith.cmpi slt, %434, %437 : i64
        cf.cond_br %436, ^bb48, ^bb49
        ^bb48:
          %438 = llvm.load %433 : !llvm.ptr -> i64
          %439 = arith.addi %438, %arg1 : i64
          llvm.store %439, %433 : i64, !llvm.ptr
          cf.br ^bb50
        ^bb49:
          cf.br ^bb50
        ^bb50:
        %440 = arith.extsi %334 : i64 to i128
        %441 = llvm.load %433 : !llvm.ptr -> i64
        %442 = arith.extsi %441 : i64 to i128
        %444 = arith.trunci %440 : i128 to i64
        %445 = arith.trunci %442 : i128 to i64
        %443 = arith.muli %444, %445 : i64
        %446 = arith.extsi %arg1 : i64 to i128
        %448 = arith.trunci %446 : i128 to i64
        %447 = arith.remsi %443, %448 : i64
        %449 = arith.extsi %447 : i64 to i128
        %451 = llvm.mlir.addressof @g_h_large : !llvm.ptr
        %452 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
        %453 = llvm.load %368 : !llvm.ptr -> i32
        %454 = arith.extsi %453 : i32 to i64
        %455 = llvm.getelementptr %452[%454] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %450 = llvm.load %455 : !llvm.ptr -> i64
        %456 = arith.trunci %449 : i128 to i64
        %457 = arith.subi %450, %456 : i64
        %458 = arith.remsi %457, %arg1 : i64
        %459 = llvm.mlir.addressof @g_h_large : !llvm.ptr
        %460 = llvm.load %459 : !llvm.ptr -> !llvm.ptr
        %461 = llvm.load %368 : !llvm.ptr -> i32
        %462 = arith.extsi %461 : i32 to i64
        %463 = llvm.getelementptr %460[%462] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %458, %463 : i64, !llvm.ptr
        %465 = llvm.mlir.addressof @g_h_large : !llvm.ptr
        %466 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
        %467 = llvm.load %368 : !llvm.ptr -> i32
        %468 = arith.extsi %467 : i32 to i64
        %469 = llvm.getelementptr %466[%468] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %464 = llvm.load %469 : !llvm.ptr -> i64
        %470 = arith.constant 0 : i32
        %472 = arith.extsi %470 : i32 to i64
        %471 = arith.cmpi slt, %464, %472 : i64
        cf.cond_br %471, ^bb51, ^bb52
        ^bb51:
          %474 = llvm.mlir.addressof @g_h_large : !llvm.ptr
          %475 = llvm.load %474 : !llvm.ptr -> !llvm.ptr
          %476 = llvm.load %368 : !llvm.ptr -> i32
          %477 = arith.extsi %476 : i32 to i64
          %478 = llvm.getelementptr %475[%477] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %473 = llvm.load %478 : !llvm.ptr -> i64
          %479 = arith.addi %473, %arg1 : i64
          %480 = llvm.mlir.addressof @g_h_large : !llvm.ptr
          %481 = llvm.load %480 : !llvm.ptr -> !llvm.ptr
          %482 = llvm.load %368 : !llvm.ptr -> i32
          %483 = arith.extsi %482 : i32 to i64
          %484 = llvm.getelementptr %481[%483] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %479, %484 : i64, !llvm.ptr
          cf.br ^bb53
        ^bb52:
          cf.br ^bb53
        ^bb53:
        %485 = llvm.load %368 : !llvm.ptr -> i32
        %486 = arith.constant 1 : i32
        %487 = arith.addi %485, %486 : i32
        llvm.store %487, %368 : i32, !llvm.ptr
        cf.br ^bb42
      ^bb44:
      %488 = llvm.mlir.addressof @g_v : !llvm.ptr
      %489 = llvm.load %488 : !llvm.ptr -> i32
      %490 = arith.extsi %489 : i32 to i64
      %491 = llvm.mlir.constant(1 : i64) : i64
      %492 = llvm.alloca %491 x i64 : (i64) -> !llvm.ptr
      llvm.store %490, %492 : i64, !llvm.ptr
      cf.br ^bb54
      ^bb54:
      %493 = llvm.load %492 : !llvm.ptr -> i64
      %494 = arith.cmpi sge, %493, %335 : i64
      cf.cond_br %494, ^bb55, ^bb56
      ^bb55:
        %495 = llvm.load %492 : !llvm.ptr -> i64
        %496 = arith.divsi %495, %334 : i64
        %497 = arith.trunci %496 : i64 to i32
        %499 = llvm.mlir.addressof @g_g_small : !llvm.ptr
        %500 = llvm.load %499 : !llvm.ptr -> !llvm.ptr
        %501 = llvm.load %492 : !llvm.ptr -> i64
        %502 = arith.trunci %501 : i64 to i32
        %503 = arith.extsi %502 : i32 to i64
        %504 = llvm.getelementptr %500[%503] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %498 = llvm.load %504 : !llvm.ptr -> i64
        %506 = llvm.mlir.addressof @g_g_small : !llvm.ptr
        %507 = llvm.load %506 : !llvm.ptr -> !llvm.ptr
        %508 = arith.extsi %497 : i32 to i64
        %509 = llvm.getelementptr %507[%508] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %505 = llvm.load %509 : !llvm.ptr -> i64
        %510 = arith.subi %505, %337 : i64
        %511 = arith.subi %498, %510 : i64
        %512 = llvm.mlir.addressof @g_g_small : !llvm.ptr
        %513 = llvm.load %512 : !llvm.ptr -> !llvm.ptr
        %514 = llvm.load %492 : !llvm.ptr -> i64
        %515 = arith.trunci %514 : i64 to i32
        %516 = arith.extsi %515 : i32 to i64
        %517 = llvm.getelementptr %513[%516] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %511, %517 : i64, !llvm.ptr
        %519 = llvm.mlir.addressof @g_h_small : !llvm.ptr
        %520 = llvm.load %519 : !llvm.ptr -> !llvm.ptr
        %521 = arith.extsi %497 : i32 to i64
        %522 = llvm.getelementptr %520[%521] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %518 = llvm.load %522 : !llvm.ptr -> i64
        %523 = arith.subi %518, %346 : i64
        %524 = llvm.mlir.constant(1 : i64) : i64
        %525 = llvm.alloca %524 x i64 : (i64) -> !llvm.ptr
        llvm.store %523, %525 : i64, !llvm.ptr
        %526 = llvm.load %525 : !llvm.ptr -> i64
        %527 = arith.constant 0 : i32
        %529 = arith.extsi %527 : i32 to i64
        %528 = arith.cmpi slt, %526, %529 : i64
        cf.cond_br %528, ^bb57, ^bb58
        ^bb57:
          %530 = llvm.load %525 : !llvm.ptr -> i64
          %531 = arith.addi %530, %arg1 : i64
          llvm.store %531, %525 : i64, !llvm.ptr
          cf.br ^bb59
        ^bb58:
          cf.br ^bb59
        ^bb59:
        %532 = arith.extsi %334 : i64 to i128
        %533 = llvm.load %525 : !llvm.ptr -> i64
        %534 = arith.extsi %533 : i64 to i128
        %536 = arith.trunci %532 : i128 to i64
        %537 = arith.trunci %534 : i128 to i64
        %535 = arith.muli %536, %537 : i64
        %538 = arith.extsi %arg1 : i64 to i128
        %540 = arith.trunci %538 : i128 to i64
        %539 = arith.remsi %535, %540 : i64
        %541 = arith.extsi %539 : i64 to i128
        %543 = llvm.mlir.addressof @g_h_small : !llvm.ptr
        %544 = llvm.load %543 : !llvm.ptr -> !llvm.ptr
        %545 = llvm.load %492 : !llvm.ptr -> i64
        %546 = arith.trunci %545 : i64 to i32
        %547 = arith.extsi %546 : i32 to i64
        %548 = llvm.getelementptr %544[%547] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %542 = llvm.load %548 : !llvm.ptr -> i64
        %549 = arith.trunci %541 : i128 to i64
        %550 = arith.subi %542, %549 : i64
        %551 = arith.remsi %550, %arg1 : i64
        %552 = llvm.mlir.addressof @g_h_small : !llvm.ptr
        %553 = llvm.load %552 : !llvm.ptr -> !llvm.ptr
        %554 = llvm.load %492 : !llvm.ptr -> i64
        %555 = arith.trunci %554 : i64 to i32
        %556 = arith.extsi %555 : i32 to i64
        %557 = llvm.getelementptr %553[%556] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %551, %557 : i64, !llvm.ptr
        %559 = llvm.mlir.addressof @g_h_small : !llvm.ptr
        %560 = llvm.load %559 : !llvm.ptr -> !llvm.ptr
        %561 = llvm.load %492 : !llvm.ptr -> i64
        %562 = arith.trunci %561 : i64 to i32
        %563 = arith.extsi %562 : i32 to i64
        %564 = llvm.getelementptr %560[%563] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %558 = llvm.load %564 : !llvm.ptr -> i64
        %565 = arith.constant 0 : i32
        %567 = arith.extsi %565 : i32 to i64
        %566 = arith.cmpi slt, %558, %567 : i64
        cf.cond_br %566, ^bb60, ^bb61
        ^bb60:
          %569 = llvm.mlir.addressof @g_h_small : !llvm.ptr
          %570 = llvm.load %569 : !llvm.ptr -> !llvm.ptr
          %571 = llvm.load %492 : !llvm.ptr -> i64
          %572 = arith.trunci %571 : i64 to i32
          %573 = arith.extsi %572 : i32 to i64
          %574 = llvm.getelementptr %570[%573] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %568 = llvm.load %574 : !llvm.ptr -> i64
          %575 = arith.addi %568, %arg1 : i64
          %576 = llvm.mlir.addressof @g_h_small : !llvm.ptr
          %577 = llvm.load %576 : !llvm.ptr -> !llvm.ptr
          %578 = llvm.load %492 : !llvm.ptr -> i64
          %579 = arith.trunci %578 : i64 to i32
          %580 = arith.extsi %579 : i32 to i64
          %581 = llvm.getelementptr %577[%580] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %575, %581 : i64, !llvm.ptr
          cf.br ^bb62
        ^bb61:
          cf.br ^bb62
        ^bb62:
        %582 = llvm.load %492 : !llvm.ptr -> i64
        %583 = arith.constant 1 : i32
        %585 = arith.extsi %583 : i32 to i64
        %584 = arith.subi %582, %585 : i64
        llvm.store %584, %492 : i64, !llvm.ptr
        cf.br ^bb54
      ^bb56:
      %586 = llvm.load %323 : !llvm.ptr -> i32
      %587 = arith.constant 1 : i32
      %588 = arith.addi %586, %587 : i32
      llvm.store %588, %323 : i32, !llvm.ptr
      cf.br ^bb33
    ^bb35:
    func.return
  }
  func.func @pi_func(%arg0: i64) -> i64 {
    %589 = llvm.mlir.addressof @g_v : !llvm.ptr
    %590 = llvm.load %589 : !llvm.ptr -> i32
    %591 = arith.extsi %590 : i32 to i64
    %592 = arith.cmpi sle, %arg0, %591 : i64
    cf.cond_br %592, ^bb63, ^bb64
    ^bb63:
      %594 = llvm.mlir.addressof @g_g_small : !llvm.ptr
      %595 = llvm.load %594 : !llvm.ptr -> !llvm.ptr
      %596 = arith.trunci %arg0 : i64 to i32
      %597 = arith.extsi %596 : i32 to i64
      %598 = llvm.getelementptr %595[%597] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %593 = llvm.load %598 : !llvm.ptr -> i64
      func.return %593 : i64
    ^bb64:
      cf.br ^bb65
    ^bb65:
    %600 = llvm.mlir.addressof @g_g_large : !llvm.ptr
    %601 = llvm.load %600 : !llvm.ptr -> !llvm.ptr
    %602 = llvm.mlir.addressof @TARGET : !llvm.ptr
    %603 = llvm.load %602 : !llvm.ptr -> i64
    %604 = arith.divsi %603, %arg0 : i64
    %605 = arith.trunci %604 : i64 to i32
    %606 = arith.extsi %605 : i32 to i64
    %607 = llvm.getelementptr %601[%606] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %599 = llvm.load %607 : !llvm.ptr -> i64
    func.return %599 : i64
  }
  func.func @psum(%arg0: i64) -> i64 {
    %608 = llvm.mlir.addressof @g_v : !llvm.ptr
    %609 = llvm.load %608 : !llvm.ptr -> i32
    %610 = arith.extsi %609 : i32 to i64
    %611 = arith.cmpi sle, %arg0, %610 : i64
    cf.cond_br %611, ^bb66, ^bb67
    ^bb66:
      %613 = llvm.mlir.addressof @g_h_small : !llvm.ptr
      %614 = llvm.load %613 : !llvm.ptr -> !llvm.ptr
      %615 = arith.trunci %arg0 : i64 to i32
      %616 = arith.extsi %615 : i32 to i64
      %617 = llvm.getelementptr %614[%616] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %612 = llvm.load %617 : !llvm.ptr -> i64
      func.return %612 : i64
    ^bb67:
      cf.br ^bb68
    ^bb68:
    %619 = llvm.mlir.addressof @g_h_large : !llvm.ptr
    %620 = llvm.load %619 : !llvm.ptr -> !llvm.ptr
    %621 = llvm.mlir.addressof @TARGET : !llvm.ptr
    %622 = llvm.load %621 : !llvm.ptr -> i64
    %623 = arith.divsi %622, %arg0 : i64
    %624 = arith.trunci %623 : i64 to i32
    %625 = arith.extsi %624 : i32 to i64
    %626 = llvm.getelementptr %620[%625] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %618 = llvm.load %626 : !llvm.ptr -> i64
    func.return %618 : i64
  }
  func.func @compute_T_mod(%arg0: i64, %arg1: i64) -> i64 {
    %627 = arith.constant 1 : i32
    %629 = arith.extsi %627 : i32 to i64
    %628 = arith.cmpi sle, %arg0, %629 : i64
    cf.cond_br %628, ^bb69, ^bb70
    ^bb69:
      %630 = arith.constant 0 : i32
      %631 = arith.extsi %630 : i32 to i64
      func.return %631 : i64
    ^bb70:
      cf.br ^bb71
    ^bb71:
    %632 = arith.sitofp %arg0 : i64 to f64
    %633 = math.sqrt %632 : f64
    %634 = arith.fptosi %633 : f64 to i32
    func.call @min25_init(%arg0, %arg1) : (i64, i64) -> ()
    %636 = arith.constant 0 : i32
    %637 = arith.extsi %636 : i32 to i64
    %638 = llvm.mlir.constant(1 : i64) : i64
    %639 = llvm.alloca %638 x i64 : (i64) -> !llvm.ptr
    llvm.store %637, %639 : i64, !llvm.ptr
    %640 = arith.constant 0 : 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 ^bb72
    ^bb72:
    %643 = llvm.load %642 : !llvm.ptr -> i32
    %644 = llvm.mlir.addressof @g_num_primes : !llvm.ptr
    %645 = llvm.load %644 : !llvm.ptr -> i32
    %646 = arith.cmpi slt, %643, %645 : i32
    cf.cond_br %646, ^bb73, ^bb74
    ^bb73:
      %648 = llvm.mlir.addressof @g_primes : !llvm.ptr
      %649 = llvm.load %648 : !llvm.ptr -> !llvm.ptr
      %650 = llvm.load %642 : !llvm.ptr -> i32
      %651 = arith.extsi %650 : i32 to i64
      %652 = llvm.getelementptr %649[%651] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %647 = llvm.load %652 : !llvm.ptr -> i32
      %653 = arith.extsi %647 : i32 to i64
      %654 = arith.muli %653, %653 : i64
      %655 = arith.cmpi sgt, %654, %arg0 : i64
      cf.cond_br %655, ^bb75, ^bb76
      ^bb75:
        cf.br ^bb74
      ^bb76:
        cf.br ^bb77
      ^bb77:
      %656 = arith.divsi %arg0, %653 : i64
      %657 = arith.muli %653, %653 : i64
      %658 = arith.divsi %arg0, %657 : i64
      %659 = func.call @tri(%656, %arg1) : (i64, i64) -> i64
      %660 = arith.remsi %653, %arg1 : i64
      %661 = func.call @tri(%658, %arg1) : (i64, i64) -> i64
      %662 = arith.muli %660, %661 : i64
      %663 = arith.subi %659, %662 : i64
      %664 = arith.remsi %663, %arg1 : i64
      %665 = llvm.mlir.constant(1 : i64) : i64
      %666 = llvm.alloca %665 x i64 : (i64) -> !llvm.ptr
      llvm.store %664, %666 : i64, !llvm.ptr
      %667 = llvm.load %666 : !llvm.ptr -> i64
      %668 = arith.constant 0 : i32
      %670 = arith.extsi %668 : i32 to i64
      %669 = arith.cmpi slt, %667, %670 : i64
      cf.cond_br %669, ^bb78, ^bb79
      ^bb78:
        %671 = llvm.load %666 : !llvm.ptr -> i64
        %672 = arith.addi %671, %arg1 : i64
        llvm.store %672, %666 : i64, !llvm.ptr
        cf.br ^bb80
      ^bb79:
        cf.br ^bb80
      ^bb80:
      %673 = llvm.load %639 : !llvm.ptr -> i64
      %674 = arith.constant 2 : i32
      %676 = arith.extsi %674 : i32 to i64
      %675 = arith.subi %653, %676 : i64
      %677 = arith.remsi %675, %arg1 : i64
      %678 = llvm.load %666 : !llvm.ptr -> i64
      %679 = arith.muli %677, %678 : i64
      %680 = arith.addi %673, %679 : i64
      %681 = arith.remsi %680, %arg1 : i64
      llvm.store %681, %639 : i64, !llvm.ptr
      %682 = arith.muli %653, %653 : i64
      %683 = llvm.mlir.constant(1 : i64) : i64
      %684 = llvm.alloca %683 x i64 : (i64) -> !llvm.ptr
      llvm.store %682, %684 : i64, !llvm.ptr
      %685 = llvm.mlir.constant(1 : i64) : i64
      %686 = llvm.alloca %685 x i64 : (i64) -> !llvm.ptr
      llvm.store %653, %686 : i64, !llvm.ptr
      cf.br ^bb81
      ^bb81:
      %687 = llvm.load %684 : !llvm.ptr -> i64
      %688 = arith.cmpi sle, %687, %arg0 : i64
      cf.cond_br %688, ^bb82, ^bb83
      ^bb82:
        %689 = llvm.load %684 : !llvm.ptr -> i64
        %690 = arith.divsi %arg0, %689 : i64
        %691 = llvm.load %684 : !llvm.ptr -> i64
        %692 = arith.muli %691, %653 : i64
        %693 = arith.divsi %arg0, %692 : i64
        %694 = arith.constant 1 : i32
        %696 = arith.extsi %694 : i32 to i64
        %695 = arith.subi %653, %696 : i64
        %697 = llvm.load %686 : !llvm.ptr -> i64
        %698 = arith.muli %695, %697 : i64
        %699 = arith.constant 1 : i32
        %701 = arith.extsi %699 : i32 to i64
        %700 = arith.subi %698, %701 : i64
        %702 = func.call @tri(%690, %arg1) : (i64, i64) -> i64
        %703 = arith.remsi %653, %arg1 : i64
        %704 = func.call @tri(%693, %arg1) : (i64, i64) -> i64
        %705 = arith.muli %703, %704 : i64
        %706 = arith.subi %702, %705 : i64
        %707 = arith.remsi %706, %arg1 : i64
        %708 = llvm.mlir.constant(1 : i64) : i64
        %709 = llvm.alloca %708 x i64 : (i64) -> !llvm.ptr
        llvm.store %707, %709 : i64, !llvm.ptr
        %710 = llvm.load %709 : !llvm.ptr -> i64
        %711 = arith.constant 0 : i32
        %713 = arith.extsi %711 : i32 to i64
        %712 = arith.cmpi slt, %710, %713 : i64
        cf.cond_br %712, ^bb84, ^bb85
        ^bb84:
          %714 = llvm.load %709 : !llvm.ptr -> i64
          %715 = arith.addi %714, %arg1 : i64
          llvm.store %715, %709 : i64, !llvm.ptr
          cf.br ^bb86
        ^bb85:
          cf.br ^bb86
        ^bb86:
        %716 = llvm.load %639 : !llvm.ptr -> i64
        %717 = arith.remsi %700, %arg1 : i64
        %718 = llvm.load %709 : !llvm.ptr -> i64
        %719 = arith.muli %717, %718 : i64
        %720 = arith.addi %716, %719 : i64
        %721 = arith.remsi %720, %arg1 : i64
        llvm.store %721, %639 : i64, !llvm.ptr
        %722 = llvm.load %686 : !llvm.ptr -> i64
        %723 = arith.muli %722, %653 : i64
        llvm.store %723, %686 : i64, !llvm.ptr
        %724 = llvm.load %684 : !llvm.ptr -> i64
        %725 = arith.muli %724, %653 : i64
        llvm.store %725, %684 : i64, !llvm.ptr
        cf.br ^bb81
      ^bb83:
      %726 = llvm.load %642 : !llvm.ptr -> i32
      %727 = arith.constant 1 : i32
      %728 = arith.addi %726, %727 : i32
      llvm.store %728, %642 : i32, !llvm.ptr
      cf.br ^bb72
    ^bb74:
    %729 = arith.constant 1 : i32
    %730 = arith.extsi %729 : i32 to i64
    %731 = llvm.mlir.constant(1 : i64) : i64
    %732 = llvm.alloca %731 x i64 : (i64) -> !llvm.ptr
    llvm.store %730, %732 : i64, !llvm.ptr
    cf.br ^bb87
    ^bb87:
    %733 = llvm.load %732 : !llvm.ptr -> i64
    %734 = arith.extsi %634 : i32 to i64
    %735 = arith.cmpi slt, %733, %734 : i64
    cf.cond_br %735, ^bb88, ^bb89
    ^bb88:
      %736 = llvm.load %732 : !llvm.ptr -> i64
      %737 = arith.divsi %arg0, %736 : i64
      %738 = arith.extsi %634 : i32 to i64
      %739 = arith.cmpi sle, %737, %738 : i64
      cf.cond_br %739, ^bb90, ^bb91
      ^bb90:
        cf.br ^bb89
      ^bb91:
        cf.br ^bb92
      ^bb92:
      %740 = llvm.load %732 : !llvm.ptr -> i64
      %741 = arith.constant 1 : i32
      %743 = arith.extsi %741 : i32 to i64
      %742 = arith.addi %740, %743 : i64
      %744 = arith.divsi %arg0, %742 : i64
      %745 = arith.constant 1 : i32
      %747 = arith.extsi %745 : i32 to i64
      %746 = arith.addi %744, %747 : i64
      %748 = llvm.mlir.constant(1 : i64) : i64
      %749 = llvm.alloca %748 x i64 : (i64) -> !llvm.ptr
      llvm.store %746, %749 : i64, !llvm.ptr
      %750 = llvm.load %749 : !llvm.ptr -> i64
      %751 = arith.extsi %634 : i32 to i64
      %752 = arith.cmpi sle, %750, %751 : i64
      cf.cond_br %752, ^bb93, ^bb94
      ^bb93:
        %753 = arith.extsi %634 : i32 to i64
        %754 = arith.constant 1 : i32
        %756 = arith.extsi %754 : i32 to i64
        %755 = arith.addi %753, %756 : i64
        llvm.store %755, %749 : i64, !llvm.ptr
        cf.br ^bb95
      ^bb94:
        cf.br ^bb95
      ^bb95:
      %757 = llvm.load %749 : !llvm.ptr -> i64
      %758 = arith.cmpi sgt, %757, %737 : i64
      cf.cond_br %758, ^bb96, ^bb97
      ^bb96:
        %759 = llvm.load %732 : !llvm.ptr -> i64
        %760 = arith.constant 1 : i32
        %762 = arith.extsi %760 : i32 to i64
        %761 = arith.addi %759, %762 : i64
        llvm.store %761, %732 : i64, !llvm.ptr
        cf.br ^bb87
      ^bb97:
        cf.br ^bb98
      ^bb98:
      %763 = func.call @psum(%737) : (i64) -> i64
      %765 = llvm.load %749 : !llvm.ptr -> i64
      %766 = arith.constant 1 : i32
      %768 = arith.extsi %766 : i32 to i64
      %767 = arith.subi %765, %768 : i64
      %764 = func.call @psum(%767) : (i64) -> i64
      %769 = arith.subi %763, %764 : i64
      %770 = arith.remsi %769, %arg1 : i64
      %771 = llvm.mlir.constant(1 : i64) : i64
      %772 = llvm.alloca %771 x i64 : (i64) -> !llvm.ptr
      llvm.store %770, %772 : i64, !llvm.ptr
      %773 = llvm.load %772 : !llvm.ptr -> i64
      %774 = arith.constant 0 : i32
      %776 = arith.extsi %774 : i32 to i64
      %775 = arith.cmpi slt, %773, %776 : i64
      cf.cond_br %775, ^bb99, ^bb100
      ^bb99:
        %777 = llvm.load %772 : !llvm.ptr -> i64
        %778 = arith.addi %777, %arg1 : i64
        llvm.store %778, %772 : i64, !llvm.ptr
        cf.br ^bb101
      ^bb100:
        cf.br ^bb101
      ^bb101:
      %779 = func.call @pi_func(%737) : (i64) -> i64
      %781 = llvm.load %749 : !llvm.ptr -> i64
      %782 = arith.constant 1 : i32
      %784 = arith.extsi %782 : i32 to i64
      %783 = arith.subi %781, %784 : i64
      %780 = func.call @pi_func(%783) : (i64) -> i64
      %785 = arith.subi %779, %780 : i64
      %786 = llvm.load %772 : !llvm.ptr -> i64
      %787 = arith.constant 2 : i32
      %788 = arith.remsi %785, %arg1 : i64
      %790 = arith.extsi %787 : i32 to i64
      %789 = arith.muli %790, %788 : i64
      %791 = arith.remsi %789, %arg1 : i64
      %792 = arith.subi %786, %791 : i64
      %793 = arith.remsi %792, %arg1 : i64
      %794 = llvm.mlir.constant(1 : i64) : i64
      %795 = llvm.alloca %794 x i64 : (i64) -> !llvm.ptr
      llvm.store %793, %795 : i64, !llvm.ptr
      %796 = llvm.load %795 : !llvm.ptr -> i64
      %797 = arith.constant 0 : i32
      %799 = arith.extsi %797 : i32 to i64
      %798 = arith.cmpi slt, %796, %799 : i64
      cf.cond_br %798, ^bb102, ^bb103
      ^bb102:
        %800 = llvm.load %795 : !llvm.ptr -> i64
        %801 = arith.addi %800, %arg1 : i64
        llvm.store %801, %795 : i64, !llvm.ptr
        cf.br ^bb104
      ^bb103:
        cf.br ^bb104
      ^bb104:
      %802 = llvm.load %639 : !llvm.ptr -> i64
      %804 = llvm.load %732 : !llvm.ptr -> i64
      %803 = func.call @tri(%804, %arg1) : (i64, i64) -> i64
      %805 = llvm.load %795 : !llvm.ptr -> i64
      %806 = arith.muli %803, %805 : i64
      %807 = arith.addi %802, %806 : i64
      %808 = arith.remsi %807, %arg1 : i64
      llvm.store %808, %639 : i64, !llvm.ptr
      %809 = llvm.load %732 : !llvm.ptr -> i64
      %810 = arith.constant 1 : i32
      %812 = arith.extsi %810 : i32 to i64
      %811 = arith.addi %809, %812 : i64
      llvm.store %811, %732 : i64, !llvm.ptr
      cf.br ^bb87
    ^bb89:
    %813 = llvm.load %639 : !llvm.ptr -> i64
    %814 = arith.remsi %813, %arg1 : i64
    llvm.store %814, %639 : i64, !llvm.ptr
    %815 = llvm.load %639 : !llvm.ptr -> i64
    %816 = arith.constant 0 : i32
    %818 = arith.extsi %816 : i32 to i64
    %817 = arith.cmpi slt, %815, %818 : i64
    cf.cond_br %817, ^bb105, ^bb106
    ^bb105:
      %819 = llvm.load %639 : !llvm.ptr -> i64
      %820 = arith.addi %819, %arg1 : i64
      llvm.store %820, %639 : i64, !llvm.ptr
      cf.br ^bb107
    ^bb106:
      cf.br ^bb107
    ^bb107:
    %822 = llvm.mlir.addressof @g_vals : !llvm.ptr
    %823 = llvm.load %822 : !llvm.ptr -> !llvm.ptr
    func.call @free(%823) : (!llvm.ptr) -> ()
    %825 = llvm.mlir.addressof @g_g_small : !llvm.ptr
    %826 = llvm.load %825 : !llvm.ptr -> !llvm.ptr
    func.call @free(%826) : (!llvm.ptr) -> ()
    %828 = llvm.mlir.addressof @g_h_small : !llvm.ptr
    %829 = llvm.load %828 : !llvm.ptr -> !llvm.ptr
    func.call @free(%829) : (!llvm.ptr) -> ()
    %831 = llvm.mlir.addressof @g_g_large : !llvm.ptr
    %832 = llvm.load %831 : !llvm.ptr -> !llvm.ptr
    func.call @free(%832) : (!llvm.ptr) -> ()
    %834 = llvm.mlir.addressof @g_h_large : !llvm.ptr
    %835 = llvm.load %834 : !llvm.ptr -> !llvm.ptr
    func.call @free(%835) : (!llvm.ptr) -> ()
    %837 = llvm.mlir.addressof @g_primes : !llvm.ptr
    %838 = llvm.load %837 : !llvm.ptr -> !llvm.ptr
    func.call @free(%838) : (!llvm.ptr) -> ()
    %839 = llvm.load %639 : !llvm.ptr -> i64
    func.return %839 : i64
  }
  func.func @main() -> i32 {
    %841 = llvm.mlir.addressof @TARGET : !llvm.ptr
    %842 = llvm.load %841 : !llvm.ptr -> i64
    %843 = llvm.mlir.addressof @MOD : !llvm.ptr
    %844 = llvm.load %843 : !llvm.ptr -> i64
    %840 = func.call @compute_T_mod(%842, %844) : (i64, i64) -> i64
    %845 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %846 = llvm.call @printf(%845, %840) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %847 = arith.constant 0 : i32
    func.return %847 : i32
  }
}