Problem 946

Ported from native C to pure Flow. Sum of first 10^8 CF coefficients of beta = (2*alpha+3)/(3*alpha+2). Uses FST with binary lifting for fast processing of long runs of 1s.

Answer585787007
Output585787007
StatusPASS
Native helperno
Runtime0 ms
Peak memory2560 KB
Time complexityO(n^2) (estimated)
Space complexityO(1) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n log log n)
Space complexityO(1)O(n)
ApproachFlow solutionSieve or enumeration
VerdictSuboptimal

Flow source

# Project Euler 946: Continued Fraction Fraction
# Ported from native C to pure Flow.
# Sum of first 10^8 CF coefficients of beta = (2*alpha+3)/(3*alpha+2).
# Uses FST with binary lifting for fast processing of long runs of 1s.

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
}

const STATE_HT_SIZE: i64 = 4096
const STATE_HT_MASK: i64 = 4095
const MAX_POW: i64 = 25

struct State {
    A: i64,
    B: i64,
    C: i64,
    D: i64
}

# State storage
let mut st_A: ptr<i64> = null
let mut st_B: ptr<i64> = null
let mut st_C: ptr<i64> = null
let mut st_D: ptr<i64> = null
let mut st_ids: ptr<i32> = null
let mut n_states: i64 = 0

# Transition tables
let mut next1_arr: ptr<i32> = null
let mut next2_arr: ptr<i32> = null
let mut cnt1_arr: ptr<i64> = null
let mut sum1_arr: ptr<i64> = null
let mut cnt2_arr: ptr<i64> = null
let mut sum2_arr: ptr<i64> = null

# Binary lifting tables (flat: MAX_POW * STATE_HT_SIZE)
let mut pow_next_arr: ptr<i32> = null
let mut pow_cnt_arr: ptr<i64> = null
let mut pow_sum_arr: ptr<i64> = null

# Output from step_transition
let mut g_outs: ptr<i64> = null
let mut g_n_outs: i64 = 0

# Prime generator state
let mut primes_arr: ptr<i64> = null
let mut n_primes: i64 = 0
let mut next_cand: i64 = 0

# Alpha cursor state
let mut alpha_stage: i64 = 0
let mut alpha_ones_left: i64 = 0

# Output from consume_ones_with_limit
let mut g_new_state: i64 = 0
let mut g_consumed: i64 = 0
let mut g_emitted_c: i64 = 0
let mut g_emitted_s: i64 = 0

function floor_div(n0: i64, d0: i64) -> i64 {
    let mut n: i64 = n0
    let mut d: i64 = d0
    if d < 0 {
        n = 0 - n
        d = 0 - d
    }
    if n >= 0 {
        return n / d
    }
    return 0 - ((0 - n + d - 1) / d)
}

function normalize(s: State) -> State {
    let mut r: State = s
    if r.C < 0 && r.C + r.D < 0 {
        r.A = 0 - r.A
        r.B = 0 - r.B
        r.C = 0 - r.C
        r.D = 0 - r.D
    }
    return r
}

function step_transition(s0: State, inp: i64) -> State {
    g_n_outs = 0
    let mut s: State = normalize(s0)

    # Consume input: multiply by [[inp, 1], [1, 0]]
    let newA: i64 = s.A * inp + s.B
    let newB: i64 = s.A
    let newC: i64 = s.C * inp + s.D
    let newD: i64 = s.C
    s.A = newA
    s.B = newB
    s.C = newC
    s.D = newD

    while true {
        s = normalize(s)
        let denom_inf: i64 = s.C
        let denom_1: i64 = s.C + s.D
        if denom_inf != 0 && denom_1 != 0 {
            let inf_pos: bool = denom_inf > 0
            let one_pos: bool = denom_1 > 0
            if inf_pos == one_pos {
                let q_inf: i64 = floor_div(s.A, denom_inf)
                let q_1: i64 = floor_div(s.A + s.B, denom_1)
                if q_inf == q_1 {
                    let q: i64 = q_inf
                    g_outs[g_n_outs] = q
                    g_n_outs = g_n_outs + 1
                    # Extract: y' = 1/(y - q)
                    let oA: i64 = s.C
                    let oB: i64 = s.D
                    let oC: i64 = s.A - q * s.C
                    let oD: i64 = s.B - q * s.D
                    s.A = oA
                    s.B = oB
                    s.C = oC
                    s.D = oD
                } else {
                    break
                }
            } else {
                break
            }
        } else {
            break
        }
    }
    return s
}

function state_hash(s: State) -> i64 {
    let h: i64 = s.A * 31 + s.B * 37 + s.C * 41 + s.D * 43
    return h & STATE_HT_MASK
}

function state_find(s: State) -> i64 {
    let h: i64 = state_hash(s)
    let mut i: i64 = 0
    while i < STATE_HT_SIZE {
        let idx: i64 = (h + i) & STATE_HT_MASK
        if st_ids[idx] == -1 {
            return -1
        }
        let sid: i64 = st_ids[idx] as i64
        if st_A[sid] == s.A && st_B[sid] == s.B && st_C[sid] == s.C && st_D[sid] == s.D {
            return sid
        }
        i = i + 1
    }
    return -1
}

function state_insert(s: State) -> i64 {
    let id: i64 = n_states
    st_A[id] = s.A
    st_B[id] = s.B
    st_C[id] = s.C
    st_D[id] = s.D
    let h: i64 = state_hash(s)
    let mut i: i64 = 0
    while i < STATE_HT_SIZE {
        let idx: i64 = (h + i) & STATE_HT_MASK
        if st_ids[idx] == -1 {
            st_ids[idx] = id as i32
            n_states = n_states + 1
            return id
        }
        i = i + 1
    }
    return -1
}

function clzll(n: i64) -> i64 {
    if n <= 0 {
        return 64
    }
    let mut count: i64 = 0
    let mut v: i64 = n
    while v > 0 {
        v = v >> 1
        count = count + 1
    }
    return 64 - count
}

function isqrt_i64(n: i64) -> i64 {
    if n < 2 {
        return n
    }
    let mut r: i64 = (sqrt(n as f64)) as i64
    while r > 0 && r * r > n {
        r = r - 1
    }
    while (r + 1) * (r + 1) <= n {
        r = r + 1
    }
    return r
}

function next_prime() -> i64 {
    if n_primes == 0 {
        primes_arr[0] = 2
        n_primes = 1
        next_cand = 3
        return 2
    }
    let mut n: i64 = next_cand
    while true {
        let r: i64 = isqrt_i64(n)
        let mut is_p: bool = true
        let mut i: i64 = 0
        while i < n_primes {
            let p: i64 = primes_arr[i]
            if p > r {
                break
            }
            if n % p == 0 {
                is_p = false
                break
            }
            i = i + 1
        }
        if is_p {
            primes_arr[n_primes] = n
            n_primes = n_primes + 1
            next_cand = n + 2
            return n
        }
        n = n + 2
    }
    return 0
}

function alpha_init() -> void {
    alpha_stage = 0
    alpha_ones_left = 0
}

function alpha_next() -> i64 {
    if alpha_stage == 0 {
        alpha_stage = 1
        alpha_ones_left = next_prime()
        return 2
    }
    if alpha_stage == 1 {
        alpha_ones_left = alpha_ones_left - 1
        if alpha_ones_left == 0 {
            alpha_stage = 2
        }
        return 1
    }
    # stage 2
    alpha_stage = 1
    alpha_ones_left = next_prime()
    return 2
}

function alpha_can_skip_ones() -> bool {
    return alpha_stage == 1 && alpha_ones_left > 0
}

function alpha_skip_ones(k: i64) -> void {
    alpha_ones_left = alpha_ones_left - k
    if alpha_ones_left == 0 {
        alpha_stage = 2
    }
}

function prepare_tables() -> void {
    # Initialize hash table to -1
    let mut i: i64 = 0
    while i < STATE_HT_SIZE {
        st_ids[i] = -1
        i = i + 1
    }
    n_states = 0

    let init_state: State = State { A: 2, B: 3, C: 3, D: 2 }
    let init_id: i64 = state_insert(init_state)

    # BFS to collect reachable states
    let queue: ptr<i32> = malloc(STATE_HT_SIZE * 4) as ptr<i32>
    let mut qhead: i64 = 0
    let mut qtail: i64 = 0
    queue[qtail] = init_id as i32
    qtail = qtail + 1

    while qhead < qtail {
        let sid: i64 = queue[qhead] as i64
        qhead = qhead + 1
        let st: State = State { A: st_A[sid], B: st_B[sid], C: st_C[sid], D: st_D[sid] }
        let mut inp: i64 = 1
        while inp <= 2 {
            let nst: State = step_transition(st, inp)
            let nid: i64 = state_find(nst)
            if nid == -1 {
                let nid2: i64 = state_insert(nst)
                queue[qtail] = nid2 as i32
                qtail = qtail + 1
            }
            inp = inp + 1
        }
    }
    free(queue as ptr<void>)

    # Base transitions
    let mut sid: i64 = 0
    while sid < n_states {
        let st: State = State { A: st_A[sid], B: st_B[sid], C: st_C[sid], D: st_D[sid] }

        let nst1: State = step_transition(st, 1)
        next1_arr[sid] = state_find(nst1) as i32
        cnt1_arr[sid] = g_n_outs
        let mut s1: i64 = 0
        let mut j: i64 = 0
        while j < g_n_outs {
            s1 = s1 + g_outs[j]
            j = j + 1
        }
        sum1_arr[sid] = s1

        let nst2: State = step_transition(st, 2)
        next2_arr[sid] = state_find(nst2) as i32
        cnt2_arr[sid] = g_n_outs
        let mut s2: i64 = 0
        j = 0
        while j < g_n_outs {
            s2 = s2 + g_outs[j]
            j = j + 1
        }
        sum2_arr[sid] = s2

        sid = sid + 1
    }

    # Binary lifting for repeated 1s
    sid = 0
    while sid < n_states {
        pow_next_arr[sid] = next1_arr[sid]
        pow_cnt_arr[sid] = cnt1_arr[sid]
        pow_sum_arr[sid] = sum1_arr[sid]
        sid = sid + 1
   
    }
    let mut k: i64 = 1
    while k < MAX_POW {
        sid = 0
        while sid < n_states {
            let mid: i64 = pow_next_arr[(k - 1) * STATE_HT_SIZE + sid] as i64
            pow_next_arr[k * STATE_HT_SIZE + sid] = pow_next_arr[(k - 1) * STATE_HT_SIZE + mid]
            pow_cnt_arr[k * STATE_HT_SIZE + sid] = pow_cnt_arr[(k - 1) * STATE_HT_SIZE + sid] + pow_cnt_arr[(k - 1) * STATE_HT_SIZE + mid]
            pow_sum_arr[k * STATE_HT_SIZE + sid] = pow_sum_arr[(k - 1) * STATE_HT_SIZE + sid] + pow_sum_arr[(k - 1) * STATE_HT_SIZE + mid]
            sid = sid + 1
        }
        k = k + 1
    }
}

function consume_ones_with_limit(state_id: i64, max_ones: i64, out_limit: i64) -> void {
    g_consumed = 0
    g_emitted_c = 0
    g_emitted_s = 0
    g_new_state = state_id

    if max_ones <= 0 || out_limit <= 0 {
        return
    }

    let mut sid: i64 = state_id
    let mut cons: i64 = 0
    let mut ec: i64 = 0
    let mut es: i64 = 0
    let mut remaining: i64 = out_limit

    let mut bit: i64 = 63 - clzll(max_ones)
    while bit >= 0 {
        let step: i64 = 1 << bit
        if cons + step <= max_ones {
            let c: i64 = pow_cnt_arr[bit * STATE_HT_SIZE + sid]
            if c <= remaining {
                remaining = remaining - c
                cons = cons + step
                ec = ec + c
                es = es + pow_sum_arr[bit * STATE_HT_SIZE + sid]
                sid = pow_next_arr[bit * STATE_HT_SIZE + sid] as i64
            }
        }
        bit = bit - 1
    }

    g_new_state = sid
    g_consumed = cons
    g_emitted_c = ec
    g_emitted_s = es
}

function main() -> i32 {
    # Allocate all arrays
    st_A = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    st_B = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    st_C = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    st_D = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    st_ids = malloc(STATE_HT_SIZE * 4) as ptr<i32>
    next1_arr = malloc(STATE_HT_SIZE * 4) as ptr<i32>
    next2_arr = malloc(STATE_HT_SIZE * 4) as ptr<i32>
    cnt1_arr = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    sum1_arr = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    cnt2_arr = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    sum2_arr = malloc(STATE_HT_SIZE * 8) as ptr<i64>
    pow_next_arr = malloc(MAX_POW * STATE_HT_SIZE * 4) as ptr<i32>
    pow_cnt_arr = malloc(MAX_POW * STATE_HT_SIZE * 8) as ptr<i64>
    pow_sum_arr = malloc(MAX_POW * STATE_HT_SIZE * 8) as ptr<i64>
    g_outs = malloc(16 * 8) as ptr<i64>
    primes_arr = malloc(20000 * 8) as ptr<i64>

    prepare_tables()

    let n: i64 = 100000000

    alpha_init()

    let mut state_id: i64 = 0
    let mut total_sum: i64 = 0
    let mut total_cnt: i64 = 0
    let cutoff: i64 = 2000
    let mut safe_target: i64 = n - cutoff
    if safe_target < 0 {
        safe_target = 0
    }

    # Fast path: skip long runs of 1s
    while total_cnt < safe_target {
        if alpha_can_skip_ones() {
            let remaining_allowed: i64 = safe_target - total_cnt
            let max_ones: i64 = alpha_ones_left
            consume_ones_with_limit(state_id, max_ones, remaining_allowed)
            if g_consumed == 0 {
                break
            }
            alpha_skip_ones(g_consumed)
            total_cnt = total_cnt + g_emitted_c
            total_sum = total_sum + g_emitted_s
            state_id = g_new_state
            if g_consumed < max_ones {
                break
            }
        } else {
            let c: i64 = cnt2_arr[state_id]
            if total_cnt + c > safe_target {
                break
            }
            total_sum = total_sum + sum2_arr[state_id]
            total_cnt = total_cnt + c
            state_id = next2_arr[state_id] as i64
            alpha_next()
        }
    }

    # Finish digit by digit
    while total_cnt < n {
        let a: i64 = alpha_next()
        let st: State = State { A: st_A[state_id], B: st_B[state_id], C: st_C[state_id], D: st_D[state_id] }
        let nst: State = step_transition(st, a)
        state_id = state_find(nst)
        let mut j: i64 = 0
        while j < g_n_outs {
            if total_cnt >= n {
                break
            }
            total_sum = total_sum + g_outs[j]
            total_cnt = total_cnt + 1
            j = j + 1
        }
    }

    printf("%lld\n", total_sum)

    free(st_A as ptr<void>)
    free(st_B as ptr<void>)
    free(st_C as ptr<void>)
    free(st_D as ptr<void>)
    free(st_ids as ptr<void>)
    free(next1_arr as ptr<void>)
    free(next2_arr as ptr<void>)
    free(cnt1_arr as ptr<void>)
    free(sum1_arr as ptr<void>)
    free(cnt2_arr as ptr<void>)
    free(sum2_arr as ptr<void>)
    free(pow_next_arr as ptr<void>)
    free(pow_cnt_arr as ptr<void>)
    free(pow_sum_arr as ptr<void>)
    free(g_outs as ptr<void>)
    free(primes_arr as ptr<void>)
    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; }

typedef struct State State;

struct State {
    int64_t A;
    int64_t B;
    int64_t C;
    int64_t D;
};

int64_t floor_div_i64_i64(int64_t n0, int64_t d0);
State normalize_State(State s);
State step_transition_State_i64(State s0, int64_t inp);
int64_t state_hash_State(State s);
int64_t state_find_State(State s);
int64_t state_insert_State(State s);
int64_t clzll_i64(int64_t n);
int64_t isqrt_i64_i64(int64_t n);
int64_t next_prime(void);
void alpha_init(void);
int64_t alpha_next(void);
bool alpha_can_skip_ones(void);
void alpha_skip_ones_i64(int64_t k);
void prepare_tables(void);
void consume_ones_with_limit_i64_i64_i64(int64_t state_id, int64_t max_ones, int64_t out_limit);
int32_t main(void);

static const int64_t STATE_HT_SIZE = 4096;
static const int64_t STATE_HT_MASK = 4095;
static const int64_t MAX_POW = 25;

/* Module statics */
static int64_t* st_A = NULL;
static int64_t* st_B = NULL;
static int64_t* st_C = NULL;
static int64_t* st_D = NULL;
static int32_t* st_ids = NULL;
static int64_t n_states = 0;
static int32_t* next1_arr = NULL;
static int32_t* next2_arr = NULL;
static int64_t* cnt1_arr = NULL;
static int64_t* sum1_arr = NULL;
static int64_t* cnt2_arr = NULL;
static int64_t* sum2_arr = NULL;
static int32_t* pow_next_arr = NULL;
static int64_t* pow_cnt_arr = NULL;
static int64_t* pow_sum_arr = NULL;
static int64_t* g_outs = NULL;
static int64_t g_n_outs = 0;
static int64_t* primes_arr = NULL;
static int64_t n_primes = 0;
static int64_t next_cand = 0;
static int64_t alpha_stage = 0;
static int64_t alpha_ones_left = 0;
static int64_t g_new_state = 0;
static int64_t g_consumed = 0;
static int64_t g_emitted_c = 0;
static int64_t g_emitted_s = 0;





int64_t floor_div_i64_i64(int64_t n0, int64_t d0) {
    int64_t n = n0;
    int64_t d = d0;
    if (d < 0) {
        n = (0 - n);
        d = (0 - d);
    }
    if (n >= 0) {
        return FLOW_CHECKED_DIV((n), (d));
    }
    return (0 - FLOW_CHECKED_DIV(((((0 - n) + d) - 1)), (d)));
}

State normalize_State(State s) {
    State r = s;
    if ((r.C < 0 && (r.C + r.D) < 0)) {
        r.A = (0 - r.A);
        r.B = (0 - r.B);
        r.C = (0 - r.C);
        r.D = (0 - r.D);
    }
    return r;
}

State step_transition_State_i64(State s0, int64_t inp) {
    g_n_outs = 0;
    State s = normalize_State(s0);
    int64_t newA = ((s.A * inp) + s.B);
    int64_t newB = s.A;
    int64_t newC = ((s.C * inp) + s.D);
    int64_t newD = s.C;
    s.A = newA;
    s.B = newB;
    s.C = newC;
    s.D = newD;
    while (1) {
        s = normalize_State(s);
        int64_t denom_inf = s.C;
        int64_t denom_1 = (s.C + s.D);
        if ((denom_inf != 0 && denom_1 != 0)) {
            bool inf_pos = denom_inf > 0;
            bool one_pos = denom_1 > 0;
            if (inf_pos == one_pos) {
                int64_t q_inf = floor_div_i64_i64(s.A, denom_inf);
                int64_t q_1 = floor_div_i64_i64((s.A + s.B), denom_1);
                if (q_inf == q_1) {
                    int64_t q = q_inf;
                    g_outs[g_n_outs] = q;
                    g_n_outs = (g_n_outs + 1);
                    int64_t oA = s.C;
                    int64_t oB = s.D;
                    int64_t oC = (s.A - (q * s.C));
                    int64_t oD = (s.B - (q * s.D));
                    s.A = oA;
                    s.B = oB;
                    s.C = oC;
                    s.D = oD;
                } else {
                    break;
                }
            } else {
                break;
            }
        } else {
            break;
        }
    }
    return s;
}

int64_t state_hash_State(State s) {
    int64_t h = ((((s.A * 31) + (s.B * 37)) + (s.C * 41)) + (s.D * 43));
    return (h & STATE_HT_MASK);
}

int64_t state_find_State(State s) {
    int64_t h = state_hash_State(s);
    int64_t i = 0;
    while (i < STATE_HT_SIZE) {
        int64_t idx = ((h + i) & STATE_HT_MASK);
        if (st_ids[idx] == (-1)) {
            return (-1);
        }
        int64_t sid = ((int64_t)(st_ids[idx]));
        if ((((st_A[sid] == s.A && st_B[sid] == s.B) && st_C[sid] == s.C) && st_D[sid] == s.D)) {
            return sid;
        }
        i = (i + 1);
    }
    return (-1);
}

int64_t state_insert_State(State s) {
    int64_t id = n_states;
    st_A[id] = s.A;
    st_B[id] = s.B;
    st_C[id] = s.C;
    st_D[id] = s.D;
    int64_t h = state_hash_State(s);
    int64_t i = 0;
    while (i < STATE_HT_SIZE) {
        int64_t idx = ((h + i) & STATE_HT_MASK);
        if (st_ids[idx] == (-1)) {
            st_ids[idx] = ((int32_t)(id));
            n_states = (n_states + 1);
            return id;
        }
        i = (i + 1);
    }
    return (-1);
}

int64_t clzll_i64(int64_t n) {
    if (n <= 0) {
        return 64;
    }
    int64_t count = 0;
    int64_t v = n;
    while (v > 0) {
        v = FLOW_CHECKED_SHR((v), (1));
        count = (count + 1);
    }
    return (64 - count);
}

int64_t isqrt_i64_i64(int64_t n) {
    if (n < 2) {
        return n;
    }
    int64_t r = ((int64_t)(sqrt(((double)(n)))));
    while ((r > 0 && (r * r) > n)) {
        r = (r - 1);
    }
    while (((r + 1) * (r + 1)) <= n) {
        r = (r + 1);
    }
    return r;
}

int64_t next_prime(void) {
    if (n_primes == 0) {
        primes_arr[0] = 2;
        n_primes = 1;
        next_cand = 3;
        return 2;
    }
    int64_t n = next_cand;
    while (1) {
        int64_t r = isqrt_i64_i64(n);
        bool is_p = 1;
        int64_t i = 0;
        while (i < n_primes) {
            int64_t p = primes_arr[i];
            if (p > r) {
                break;
            }
            if (FLOW_CHECKED_MOD((n), (p)) == 0) {
                is_p = 0;
                break;
            }
            i = (i + 1);
        }
        if (is_p) {
            primes_arr[n_primes] = n;
            n_primes = (n_primes + 1);
            next_cand = (n + 2);
            return n;
        }
        n = (n + 2);
    }
    return 0;
}

void alpha_init(void) {
    alpha_stage = 0;
    alpha_ones_left = 0;
}

int64_t alpha_next(void) {
    if (alpha_stage == 0) {
        alpha_stage = 1;
        alpha_ones_left = next_prime();
        return 2;
    }
    if (alpha_stage == 1) {
        alpha_ones_left = (alpha_ones_left - 1);
        if (alpha_ones_left == 0) {
            alpha_stage = 2;
        }
        return 1;
    }
    alpha_stage = 1;
    alpha_ones_left = next_prime();
    return 2;
}

bool alpha_can_skip_ones(void) {
    return (alpha_stage == 1 && alpha_ones_left > 0);
}

void alpha_skip_ones_i64(int64_t k) {
    alpha_ones_left = (alpha_ones_left - k);
    if (alpha_ones_left == 0) {
        alpha_stage = 2;
    }
}

void prepare_tables(void) {
    int64_t i = 0;
    while (i < STATE_HT_SIZE) {
        st_ids[i] = (-1);
        i = (i + 1);
    }
    n_states = 0;
    State init_state = (State){ .A = 2, .B = 3, .C = 3, .D = 2 };
    int64_t init_id = state_insert_State(init_state);
    int32_t* queue = (int32_t*)(((int32_t*)(malloc((STATE_HT_SIZE * 4)))));
    int64_t qhead = 0;
    int64_t qtail = 0;
    queue[qtail] = ((int32_t)(init_id));
    qtail = (qtail + 1);
    while (qhead < qtail) {
        int64_t sid = ((int64_t)(queue[qhead]));
        qhead = (qhead + 1);
        State st = (State){ .A = st_A[sid], .B = st_B[sid], .C = st_C[sid], .D = st_D[sid] };
        int64_t inp = 1;
        while (inp <= 2) {
            State nst = step_transition_State_i64(st, inp);
            int64_t nid = state_find_State(nst);
            if (nid == (-1)) {
                int64_t nid2 = state_insert_State(nst);
                queue[qtail] = ((int32_t)(nid2));
                qtail = (qtail + 1);
            }
            inp = (inp + 1);
        }
    }
    free(((void*)(queue)));
    int64_t sid = 0;
    while (sid < n_states) {
        State st = (State){ .A = st_A[sid], .B = st_B[sid], .C = st_C[sid], .D = st_D[sid] };
        State nst1 = step_transition_State_i64(st, 1);
        next1_arr[sid] = ((int32_t)(state_find_State(nst1)));
        cnt1_arr[sid] = g_n_outs;
        int64_t s1 = 0;
        int64_t j = 0;
        while (j < g_n_outs) {
            s1 = (s1 + g_outs[j]);
            j = (j + 1);
        }
        sum1_arr[sid] = s1;
        State nst2 = step_transition_State_i64(st, 2);
        next2_arr[sid] = ((int32_t)(state_find_State(nst2)));
        cnt2_arr[sid] = g_n_outs;
        int64_t s2 = 0;
        j = 0;
        while (j < g_n_outs) {
            s2 = (s2 + g_outs[j]);
            j = (j + 1);
        }
        sum2_arr[sid] = s2;
        sid = (sid + 1);
    }
    sid = 0;
    while (sid < n_states) {
        pow_next_arr[sid] = next1_arr[sid];
        pow_cnt_arr[sid] = cnt1_arr[sid];
        pow_sum_arr[sid] = sum1_arr[sid];
        sid = (sid + 1);
    }
    int64_t k = 1;
    while (k < MAX_POW) {
        sid = 0;
        while (sid < n_states) {
            int64_t mid = ((int64_t)(pow_next_arr[(((k - 1) * STATE_HT_SIZE) + sid)]));
            pow_next_arr[((k * STATE_HT_SIZE) + sid)] = pow_next_arr[(((k - 1) * STATE_HT_SIZE) + mid)];
            pow_cnt_arr[((k * STATE_HT_SIZE) + sid)] = (pow_cnt_arr[(((k - 1) * STATE_HT_SIZE) + sid)] + pow_cnt_arr[(((k - 1) * STATE_HT_SIZE) + mid)]);
            pow_sum_arr[((k * STATE_HT_SIZE) + sid)] = (pow_sum_arr[(((k - 1) * STATE_HT_SIZE) + sid)] + pow_sum_arr[(((k - 1) * STATE_HT_SIZE) + mid)]);
            sid = (sid + 1);
        }
        k = (k + 1);
    }
}

void consume_ones_with_limit_i64_i64_i64(int64_t state_id, int64_t max_ones, int64_t out_limit) {
    g_consumed = 0;
    g_emitted_c = 0;
    g_emitted_s = 0;
    g_new_state = state_id;
    if ((max_ones <= 0 || out_limit <= 0)) {
        return;
    }
    int64_t sid = state_id;
    int64_t cons = 0;
    int64_t ec = 0;
    int64_t es = 0;
    int64_t remaining = out_limit;
    int64_t bit = (63 - clzll_i64(max_ones));
    while (bit >= 0) {
        int64_t step = FLOW_CHECKED_SHL((1), (bit));
        if ((cons + step) <= max_ones) {
            int64_t c = pow_cnt_arr[((bit * STATE_HT_SIZE) + sid)];
            if (c <= remaining) {
                remaining = (remaining - c);
                cons = (cons + step);
                ec = (ec + c);
                es = (es + pow_sum_arr[((bit * STATE_HT_SIZE) + sid)]);
                sid = ((int64_t)(pow_next_arr[((bit * STATE_HT_SIZE) + sid)]));
            }
        }
        bit = (bit - 1);
    }
    g_new_state = sid;
    g_consumed = cons;
    g_emitted_c = ec;
    g_emitted_s = es;
}

int32_t main(void) {
    st_A = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    st_B = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    st_C = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    st_D = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    st_ids = ((int32_t*)(malloc((STATE_HT_SIZE * 4))));
    next1_arr = ((int32_t*)(malloc((STATE_HT_SIZE * 4))));
    next2_arr = ((int32_t*)(malloc((STATE_HT_SIZE * 4))));
    cnt1_arr = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    sum1_arr = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    cnt2_arr = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    sum2_arr = ((int64_t*)(malloc((STATE_HT_SIZE * 8))));
    pow_next_arr = ((int32_t*)(malloc(((MAX_POW * STATE_HT_SIZE) * 4))));
    pow_cnt_arr = ((int64_t*)(malloc(((MAX_POW * STATE_HT_SIZE) * 8))));
    pow_sum_arr = ((int64_t*)(malloc(((MAX_POW * STATE_HT_SIZE) * 8))));
    g_outs = ((int64_t*)(malloc((16 * 8))));
    primes_arr = ((int64_t*)(malloc((20000 * 8))));
    prepare_tables();
    int64_t n = 100000000;
    alpha_init();
    int64_t state_id = 0;
    int64_t total_sum = 0;
    int64_t total_cnt = 0;
    int64_t cutoff = 2000;
    int64_t safe_target = (n - cutoff);
    if (safe_target < 0) {
        safe_target = 0;
    }
    while (total_cnt < safe_target) {
        if (alpha_can_skip_ones()) {
            int64_t remaining_allowed = (safe_target - total_cnt);
            int64_t max_ones = alpha_ones_left;
            consume_ones_with_limit_i64_i64_i64(state_id, max_ones, remaining_allowed);
            if (g_consumed == 0) {
                break;
            }
            alpha_skip_ones_i64(g_consumed);
            total_cnt = (total_cnt + g_emitted_c);
            total_sum = (total_sum + g_emitted_s);
            state_id = g_new_state;
            if (g_consumed < max_ones) {
                break;
            }
        } else {
            int64_t c = cnt2_arr[state_id];
            if ((total_cnt + c) > safe_target) {
                break;
            }
            total_sum = (total_sum + sum2_arr[state_id]);
            total_cnt = (total_cnt + c);
            state_id = ((int64_t)(next2_arr[state_id]));
            alpha_next();
        }
    }
    while (total_cnt < n) {
        int64_t a = alpha_next();
        State st = (State){ .A = st_A[state_id], .B = st_B[state_id], .C = st_C[state_id], .D = st_D[state_id] };
        State nst = step_transition_State_i64(st, a);
        state_id = state_find_State(nst);
        int64_t j = 0;
        while (j < g_n_outs) {
            if (total_cnt >= n) {
                break;
            }
            total_sum = (total_sum + g_outs[j]);
            total_cnt = (total_cnt + 1);
            j = (j + 1);
        }
    }
    printf("%lld\n", total_sum);
    free(((void*)(st_A)));
    free(((void*)(st_B)));
    free(((void*)(st_C)));
    free(((void*)(st_D)));
    free(((void*)(st_ids)));
    free(((void*)(next1_arr)));
    free(((void*)(next2_arr)));
    free(((void*)(cnt1_arr)));
    free(((void*)(sum1_arr)));
    free(((void*)(cnt2_arr)));
    free(((void*)(sum2_arr)));
    free(((void*)(pow_next_arr)));
    free(((void*)(pow_cnt_arr)));
    free(((void*)(pow_sum_arr)));
    free(((void*)(g_outs)));
    free(((void*)(primes_arr)));
    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: STATE_HT_SIZE
  llvm.mlir.global internal constant @STATE_HT_SIZE(4096 : i64) : i64
  // Constant: STATE_HT_MASK
  llvm.mlir.global internal constant @STATE_HT_MASK(4095 : i64) : i64
  // Constant: MAX_POW
  llvm.mlir.global internal constant @MAX_POW(25 : i64) : i64
  // Struct: State
  // Fields:
  //   A: i64
  //   B: i64
  //   C: i64
  //   D: i64
  // Module static: st_A
  llvm.mlir.global internal @st_A() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: st_B
  llvm.mlir.global internal @st_B() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: st_C
  llvm.mlir.global internal @st_C() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  // Module static: st_D
  llvm.mlir.global internal @st_D() {addr_space = 0 : i32} : !llvm.ptr {
    %3 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3 : !llvm.ptr
  }
  // Module static: st_ids
  llvm.mlir.global internal @st_ids() {addr_space = 0 : i32} : !llvm.ptr {
    %4 = llvm.mlir.zero : !llvm.ptr
    llvm.return %4 : !llvm.ptr
  }
  // Module static: n_states
  llvm.mlir.global internal @n_states(0 : i64) : i64
  // Module static: next1_arr
  llvm.mlir.global internal @next1_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %5 = llvm.mlir.zero : !llvm.ptr
    llvm.return %5 : !llvm.ptr
  }
  // Module static: next2_arr
  llvm.mlir.global internal @next2_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %6 = llvm.mlir.zero : !llvm.ptr
    llvm.return %6 : !llvm.ptr
  }
  // Module static: cnt1_arr
  llvm.mlir.global internal @cnt1_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %7 = llvm.mlir.zero : !llvm.ptr
    llvm.return %7 : !llvm.ptr
  }
  // Module static: sum1_arr
  llvm.mlir.global internal @sum1_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %8 = llvm.mlir.zero : !llvm.ptr
    llvm.return %8 : !llvm.ptr
  }
  // Module static: cnt2_arr
  llvm.mlir.global internal @cnt2_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %9 = llvm.mlir.zero : !llvm.ptr
    llvm.return %9 : !llvm.ptr
  }
  // Module static: sum2_arr
  llvm.mlir.global internal @sum2_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %10 = llvm.mlir.zero : !llvm.ptr
    llvm.return %10 : !llvm.ptr
  }
  // Module static: pow_next_arr
  llvm.mlir.global internal @pow_next_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %11 = llvm.mlir.zero : !llvm.ptr
    llvm.return %11 : !llvm.ptr
  }
  // Module static: pow_cnt_arr
  llvm.mlir.global internal @pow_cnt_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %12 = llvm.mlir.zero : !llvm.ptr
    llvm.return %12 : !llvm.ptr
  }
  // Module static: pow_sum_arr
  llvm.mlir.global internal @pow_sum_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %13 = llvm.mlir.zero : !llvm.ptr
    llvm.return %13 : !llvm.ptr
  }
  // Module static: g_outs
  llvm.mlir.global internal @g_outs() {addr_space = 0 : i32} : !llvm.ptr {
    %14 = llvm.mlir.zero : !llvm.ptr
    llvm.return %14 : !llvm.ptr
  }
  // Module static: g_n_outs
  llvm.mlir.global internal @g_n_outs(0 : i64) : i64
  // Module static: primes_arr
  llvm.mlir.global internal @primes_arr() {addr_space = 0 : i32} : !llvm.ptr {
    %15 = llvm.mlir.zero : !llvm.ptr
    llvm.return %15 : !llvm.ptr
  }
  // Module static: n_primes
  llvm.mlir.global internal @n_primes(0 : i64) : i64
  // Module static: next_cand
  llvm.mlir.global internal @next_cand(0 : i64) : i64
  // Module static: alpha_stage
  llvm.mlir.global internal @alpha_stage(0 : i64) : i64
  // Module static: alpha_ones_left
  llvm.mlir.global internal @alpha_ones_left(0 : i64) : i64
  // Module static: g_new_state
  llvm.mlir.global internal @g_new_state(0 : i64) : i64
  // Module static: g_consumed
  llvm.mlir.global internal @g_consumed(0 : i64) : i64
  // Module static: g_emitted_c
  llvm.mlir.global internal @g_emitted_c(0 : i64) : i64
  // Module static: g_emitted_s
  llvm.mlir.global internal @g_emitted_s(0 : i64) : i64
  func.func @floor_div(%arg0: i64, %arg1: i64) -> i64 {
    %16 = llvm.mlir.constant(1 : i64) : i64
    %17 = llvm.alloca %16 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %17 : i64, !llvm.ptr
    %18 = llvm.mlir.constant(1 : i64) : i64
    %19 = llvm.alloca %18 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %19 : i64, !llvm.ptr
    %20 = llvm.load %19 : !llvm.ptr -> i64
    %21 = arith.constant 0 : i32
    %23 = arith.extsi %21 : i32 to i64
    %22 = arith.cmpi slt, %20, %23 : i64
    cf.cond_br %22, ^bb0, ^bb1
    ^bb0:
      %24 = arith.constant 0 : i32
      %25 = llvm.load %17 : !llvm.ptr -> i64
      %27 = arith.extsi %24 : i32 to i64
      %26 = arith.subi %27, %25 : i64
      llvm.store %26, %17 : i64, !llvm.ptr
      %28 = arith.constant 0 : i32
      %29 = llvm.load %19 : !llvm.ptr -> i64
      %31 = arith.extsi %28 : i32 to i64
      %30 = arith.subi %31, %29 : i64
      llvm.store %30, %19 : i64, !llvm.ptr
      cf.br ^bb2
    ^bb1:
      cf.br ^bb2
    ^bb2:
    %32 = llvm.load %17 : !llvm.ptr -> i64
    %33 = arith.constant 0 : i32
    %35 = arith.extsi %33 : i32 to i64
    %34 = arith.cmpi sge, %32, %35 : i64
    cf.cond_br %34, ^bb3, ^bb4
    ^bb3:
      %36 = llvm.load %17 : !llvm.ptr -> i64
      %37 = llvm.load %19 : !llvm.ptr -> i64
      %38 = arith.divsi %36, %37 : i64
      func.return %38 : i64
    ^bb4:
      cf.br ^bb5
    ^bb5:
    %39 = arith.constant 0 : i32
    %40 = arith.constant 0 : i32
    %41 = llvm.load %17 : !llvm.ptr -> i64
    %43 = arith.extsi %40 : i32 to i64
    %42 = arith.subi %43, %41 : i64
    %44 = llvm.load %19 : !llvm.ptr -> i64
    %45 = arith.addi %42, %44 : i64
    %46 = arith.constant 1 : i32
    %48 = arith.extsi %46 : i32 to i64
    %47 = arith.subi %45, %48 : i64
    %49 = llvm.load %19 : !llvm.ptr -> i64
    %50 = arith.divsi %47, %49 : i64
    %52 = arith.extsi %39 : i32 to i64
    %51 = arith.subi %52, %50 : i64
    func.return %51 : i64
  }
  func.func @normalize(%arg0: !llvm.struct<(i64, i64, i64, i64)>) -> !llvm.struct<(i64, i64, i64, i64)> {
    %53 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %54 = llvm.extractvalue %arg0[0] : !llvm.struct<(i64, i64, i64, i64)>
    %55 = llvm.insertvalue %54, %53[0] : !llvm.struct<(i64, i64, i64, i64)>
    %56 = llvm.extractvalue %arg0[1] : !llvm.struct<(i64, i64, i64, i64)>
    %57 = llvm.insertvalue %56, %55[1] : !llvm.struct<(i64, i64, i64, i64)>
    %58 = llvm.extractvalue %arg0[2] : !llvm.struct<(i64, i64, i64, i64)>
    %59 = llvm.insertvalue %58, %57[2] : !llvm.struct<(i64, i64, i64, i64)>
    %60 = llvm.extractvalue %arg0[3] : !llvm.struct<(i64, i64, i64, i64)>
    %61 = llvm.insertvalue %60, %59[3] : !llvm.struct<(i64, i64, i64, i64)>
    %62 = llvm.mlir.constant(1 : i64) : i64
    %63 = llvm.alloca %62 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %61, %63 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %64 = llvm.load %63 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %65 = llvm.mlir.constant(1 : i64) : i64
    %66 = llvm.alloca %65 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %64, %66 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %67 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %68 = llvm.getelementptr %66[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %69 = llvm.load %68 : !llvm.ptr -> i64
    %70 = arith.constant 0 : i32
    %72 = arith.extsi %70 : i32 to i64
    %71 = arith.cmpi slt, %69, %72 : i64
    %73 = scf.if %71 -> (i1) {
      %74 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %75 = llvm.getelementptr %66[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %76 = llvm.load %75 : !llvm.ptr -> i64
      %77 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %78 = llvm.getelementptr %66[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %79 = llvm.load %78 : !llvm.ptr -> i64
      %80 = arith.addi %76, %79 : i64
      %81 = arith.constant 0 : i32
      %83 = arith.extsi %81 : i32 to i64
      %82 = arith.cmpi slt, %80, %83 : i64
      scf.yield %82 : i1
    } else {
      %84 = arith.constant false
      scf.yield %84 : i1
    }
    cf.cond_br %73, ^bb6, ^bb7
    ^bb6:
      %85 = arith.constant 0 : i32
      %86 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %87 = llvm.getelementptr %66[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %88 = llvm.load %87 : !llvm.ptr -> i64
      %90 = arith.extsi %85 : i32 to i64
      %89 = arith.subi %90, %88 : i64
      %91 = llvm.getelementptr %66[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %89, %91 : i64, !llvm.ptr
      %92 = arith.constant 0 : i32
      %93 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %94 = llvm.getelementptr %66[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %95 = llvm.load %94 : !llvm.ptr -> i64
      %97 = arith.extsi %92 : i32 to i64
      %96 = arith.subi %97, %95 : i64
      %98 = llvm.getelementptr %66[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %96, %98 : i64, !llvm.ptr
      %99 = arith.constant 0 : i32
      %100 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %101 = llvm.getelementptr %66[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %102 = llvm.load %101 : !llvm.ptr -> i64
      %104 = arith.extsi %99 : i32 to i64
      %103 = arith.subi %104, %102 : i64
      %105 = llvm.getelementptr %66[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %103, %105 : i64, !llvm.ptr
      %106 = arith.constant 0 : i32
      %107 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %108 = llvm.getelementptr %66[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %109 = llvm.load %108 : !llvm.ptr -> i64
      %111 = arith.extsi %106 : i32 to i64
      %110 = arith.subi %111, %109 : i64
      %112 = llvm.getelementptr %66[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %110, %112 : i64, !llvm.ptr
      cf.br ^bb8
    ^bb7:
      cf.br ^bb8
    ^bb8:
    %113 = llvm.load %66 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %114 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %115 = llvm.extractvalue %113[0] : !llvm.struct<(i64, i64, i64, i64)>
    %116 = llvm.insertvalue %115, %114[0] : !llvm.struct<(i64, i64, i64, i64)>
    %117 = llvm.extractvalue %113[1] : !llvm.struct<(i64, i64, i64, i64)>
    %118 = llvm.insertvalue %117, %116[1] : !llvm.struct<(i64, i64, i64, i64)>
    %119 = llvm.extractvalue %113[2] : !llvm.struct<(i64, i64, i64, i64)>
    %120 = llvm.insertvalue %119, %118[2] : !llvm.struct<(i64, i64, i64, i64)>
    %121 = llvm.extractvalue %113[3] : !llvm.struct<(i64, i64, i64, i64)>
    %122 = llvm.insertvalue %121, %120[3] : !llvm.struct<(i64, i64, i64, i64)>
    %123 = llvm.mlir.constant(1 : i64) : i64
    %124 = llvm.alloca %123 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %122, %124 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %125 = llvm.load %124 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    func.return %125 : !llvm.struct<(i64, i64, i64, i64)>
  }
  func.func @step_transition(%arg0: !llvm.struct<(i64, i64, i64, i64)>, %arg1: i64) -> !llvm.struct<(i64, i64, i64, i64)> {
    %126 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %127 = llvm.extractvalue %arg0[0] : !llvm.struct<(i64, i64, i64, i64)>
    %128 = llvm.insertvalue %127, %126[0] : !llvm.struct<(i64, i64, i64, i64)>
    %129 = llvm.extractvalue %arg0[1] : !llvm.struct<(i64, i64, i64, i64)>
    %130 = llvm.insertvalue %129, %128[1] : !llvm.struct<(i64, i64, i64, i64)>
    %131 = llvm.extractvalue %arg0[2] : !llvm.struct<(i64, i64, i64, i64)>
    %132 = llvm.insertvalue %131, %130[2] : !llvm.struct<(i64, i64, i64, i64)>
    %133 = llvm.extractvalue %arg0[3] : !llvm.struct<(i64, i64, i64, i64)>
    %134 = llvm.insertvalue %133, %132[3] : !llvm.struct<(i64, i64, i64, i64)>
    %135 = llvm.mlir.constant(1 : i64) : i64
    %136 = llvm.alloca %135 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %134, %136 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %137 = arith.constant 0 : i32
    %138 = arith.extsi %137 : i32 to i64
    %139 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
    llvm.store %138, %139 : i64, !llvm.ptr
    %141 = llvm.load %136 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %142 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %143 = llvm.extractvalue %141[0] : !llvm.struct<(i64, i64, i64, i64)>
    %144 = llvm.insertvalue %143, %142[0] : !llvm.struct<(i64, i64, i64, i64)>
    %145 = llvm.extractvalue %141[1] : !llvm.struct<(i64, i64, i64, i64)>
    %146 = llvm.insertvalue %145, %144[1] : !llvm.struct<(i64, i64, i64, i64)>
    %147 = llvm.extractvalue %141[2] : !llvm.struct<(i64, i64, i64, i64)>
    %148 = llvm.insertvalue %147, %146[2] : !llvm.struct<(i64, i64, i64, i64)>
    %149 = llvm.extractvalue %141[3] : !llvm.struct<(i64, i64, i64, i64)>
    %150 = llvm.insertvalue %149, %148[3] : !llvm.struct<(i64, i64, i64, i64)>
    %140 = func.call @normalize(%150) : (!llvm.struct<(i64, i64, i64, i64)>) -> !llvm.struct<(i64, i64, i64, i64)>
    %151 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %152 = llvm.extractvalue %140[0] : !llvm.struct<(i64, i64, i64, i64)>
    %153 = llvm.insertvalue %152, %151[0] : !llvm.struct<(i64, i64, i64, i64)>
    %154 = llvm.extractvalue %140[1] : !llvm.struct<(i64, i64, i64, i64)>
    %155 = llvm.insertvalue %154, %153[1] : !llvm.struct<(i64, i64, i64, i64)>
    %156 = llvm.extractvalue %140[2] : !llvm.struct<(i64, i64, i64, i64)>
    %157 = llvm.insertvalue %156, %155[2] : !llvm.struct<(i64, i64, i64, i64)>
    %158 = llvm.extractvalue %140[3] : !llvm.struct<(i64, i64, i64, i64)>
    %159 = llvm.insertvalue %158, %157[3] : !llvm.struct<(i64, i64, i64, i64)>
    %160 = llvm.mlir.constant(1 : i64) : i64
    %161 = llvm.alloca %160 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %159, %161 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %162 = llvm.load %161 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %163 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %164 = llvm.extractvalue %150[0] : !llvm.struct<(i64, i64, i64, i64)>
    %165 = llvm.insertvalue %164, %163[0] : !llvm.struct<(i64, i64, i64, i64)>
    %166 = llvm.extractvalue %150[1] : !llvm.struct<(i64, i64, i64, i64)>
    %167 = llvm.insertvalue %166, %165[1] : !llvm.struct<(i64, i64, i64, i64)>
    %168 = llvm.extractvalue %150[2] : !llvm.struct<(i64, i64, i64, i64)>
    %169 = llvm.insertvalue %168, %167[2] : !llvm.struct<(i64, i64, i64, i64)>
    %170 = llvm.extractvalue %150[3] : !llvm.struct<(i64, i64, i64, i64)>
    %171 = llvm.insertvalue %170, %169[3] : !llvm.struct<(i64, i64, i64, i64)>
    %172 = llvm.mlir.constant(1 : i64) : i64
    %173 = llvm.alloca %172 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %171, %173 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %174 = llvm.load %173 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    llvm.store %174, %136 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %175 = llvm.mlir.constant(1 : i64) : i64
    %176 = llvm.alloca %175 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %162, %176 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %177 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %178 = llvm.getelementptr %176[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %179 = llvm.load %178 : !llvm.ptr -> i64
    %180 = arith.muli %179, %arg1 : i64
    %181 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %182 = llvm.getelementptr %176[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %183 = llvm.load %182 : !llvm.ptr -> i64
    %184 = arith.addi %180, %183 : i64
    %185 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %186 = llvm.getelementptr %176[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %187 = llvm.load %186 : !llvm.ptr -> i64
    %188 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %189 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %190 = llvm.load %189 : !llvm.ptr -> i64
    %191 = arith.muli %190, %arg1 : i64
    %192 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %193 = llvm.getelementptr %176[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %194 = llvm.load %193 : !llvm.ptr -> i64
    %195 = arith.addi %191, %194 : i64
    %196 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %197 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %198 = llvm.load %197 : !llvm.ptr -> i64
    %199 = llvm.getelementptr %176[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    llvm.store %184, %199 : i64, !llvm.ptr
    %200 = llvm.getelementptr %176[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    llvm.store %187, %200 : i64, !llvm.ptr
    %201 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    llvm.store %195, %201 : i64, !llvm.ptr
    %202 = llvm.getelementptr %176[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    llvm.store %198, %202 : i64, !llvm.ptr
    cf.br ^bb9
    ^bb9:
    %203 = arith.constant 1 : i1
    cf.cond_br %203, ^bb10, ^bb11
    ^bb10:
      %205 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %206 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %207 = llvm.extractvalue %205[0] : !llvm.struct<(i64, i64, i64, i64)>
      %208 = llvm.insertvalue %207, %206[0] : !llvm.struct<(i64, i64, i64, i64)>
      %209 = llvm.extractvalue %205[1] : !llvm.struct<(i64, i64, i64, i64)>
      %210 = llvm.insertvalue %209, %208[1] : !llvm.struct<(i64, i64, i64, i64)>
      %211 = llvm.extractvalue %205[2] : !llvm.struct<(i64, i64, i64, i64)>
      %212 = llvm.insertvalue %211, %210[2] : !llvm.struct<(i64, i64, i64, i64)>
      %213 = llvm.extractvalue %205[3] : !llvm.struct<(i64, i64, i64, i64)>
      %214 = llvm.insertvalue %213, %212[3] : !llvm.struct<(i64, i64, i64, i64)>
      %204 = func.call @normalize(%214) : (!llvm.struct<(i64, i64, i64, i64)>) -> !llvm.struct<(i64, i64, i64, i64)>
      %215 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %216 = llvm.extractvalue %204[0] : !llvm.struct<(i64, i64, i64, i64)>
      %217 = llvm.insertvalue %216, %215[0] : !llvm.struct<(i64, i64, i64, i64)>
      %218 = llvm.extractvalue %204[1] : !llvm.struct<(i64, i64, i64, i64)>
      %219 = llvm.insertvalue %218, %217[1] : !llvm.struct<(i64, i64, i64, i64)>
      %220 = llvm.extractvalue %204[2] : !llvm.struct<(i64, i64, i64, i64)>
      %221 = llvm.insertvalue %220, %219[2] : !llvm.struct<(i64, i64, i64, i64)>
      %222 = llvm.extractvalue %204[3] : !llvm.struct<(i64, i64, i64, i64)>
      %223 = llvm.insertvalue %222, %221[3] : !llvm.struct<(i64, i64, i64, i64)>
      %224 = llvm.mlir.constant(1 : i64) : i64
      %225 = llvm.alloca %224 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %223, %225 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %226 = llvm.load %225 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %227 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %228 = llvm.extractvalue %214[0] : !llvm.struct<(i64, i64, i64, i64)>
      %229 = llvm.insertvalue %228, %227[0] : !llvm.struct<(i64, i64, i64, i64)>
      %230 = llvm.extractvalue %214[1] : !llvm.struct<(i64, i64, i64, i64)>
      %231 = llvm.insertvalue %230, %229[1] : !llvm.struct<(i64, i64, i64, i64)>
      %232 = llvm.extractvalue %214[2] : !llvm.struct<(i64, i64, i64, i64)>
      %233 = llvm.insertvalue %232, %231[2] : !llvm.struct<(i64, i64, i64, i64)>
      %234 = llvm.extractvalue %214[3] : !llvm.struct<(i64, i64, i64, i64)>
      %235 = llvm.insertvalue %234, %233[3] : !llvm.struct<(i64, i64, i64, i64)>
      %236 = llvm.mlir.constant(1 : i64) : i64
      %237 = llvm.alloca %236 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %235, %237 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %238 = llvm.load %237 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %238, %176 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      llvm.store %226, %176 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %239 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %240 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %241 = llvm.load %240 : !llvm.ptr -> i64
      %242 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %243 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %244 = llvm.load %243 : !llvm.ptr -> i64
      %245 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %246 = llvm.getelementptr %176[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %247 = llvm.load %246 : !llvm.ptr -> i64
      %248 = arith.addi %244, %247 : i64
      %249 = arith.constant 0 : i32
      %251 = arith.extsi %249 : i32 to i64
      %250 = arith.cmpi ne, %241, %251 : i64
      %252 = scf.if %250 -> (i1) {
        %253 = arith.constant 0 : i32
        %255 = arith.extsi %253 : i32 to i64
        %254 = arith.cmpi ne, %248, %255 : i64
        scf.yield %254 : i1
      } else {
        %256 = arith.constant false
        scf.yield %256 : i1
      }
      cf.cond_br %252, ^bb12, ^bb13
      ^bb12:
        %257 = arith.constant 0 : i32
        %259 = arith.extsi %257 : i32 to i64
        %258 = arith.cmpi sgt, %241, %259 : i64
        %260 = arith.constant 0 : i32
        %262 = arith.extsi %260 : i32 to i64
        %261 = arith.cmpi sgt, %248, %262 : i64
        %263 = arith.cmpi eq, %258, %261 : i1
        cf.cond_br %263, ^bb15, ^bb16
        ^bb15:
          %265 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
          %266 = llvm.getelementptr %176[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
          %267 = llvm.load %266 : !llvm.ptr -> i64
          %264 = func.call @floor_div(%267, %241) : (i64, i64) -> i64
          %269 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
          %270 = llvm.getelementptr %176[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
          %271 = llvm.load %270 : !llvm.ptr -> i64
          %272 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
          %273 = llvm.getelementptr %176[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
          %274 = llvm.load %273 : !llvm.ptr -> i64
          %275 = arith.addi %271, %274 : i64
          %268 = func.call @floor_div(%275, %248) : (i64, i64) -> i64
          %276 = arith.cmpi eq, %264, %268 : i64
          cf.cond_br %276, ^bb18, ^bb19
          ^bb18:
            %277 = llvm.mlir.addressof @g_outs : !llvm.ptr
            %278 = llvm.load %277 : !llvm.ptr -> !llvm.ptr
            %279 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
            %280 = llvm.load %279 : !llvm.ptr -> i64
            %281 = llvm.getelementptr %278[%280] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %264, %281 : i64, !llvm.ptr
            %282 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
            %283 = llvm.load %282 : !llvm.ptr -> i64
            %284 = arith.constant 1 : i32
            %286 = arith.extsi %284 : i32 to i64
            %285 = arith.addi %283, %286 : i64
            %287 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
            llvm.store %285, %287 : i64, !llvm.ptr
            %288 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
            %289 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            %290 = llvm.load %289 : !llvm.ptr -> i64
            %291 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
            %292 = llvm.getelementptr %176[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            %293 = llvm.load %292 : !llvm.ptr -> i64
            %294 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
            %295 = llvm.getelementptr %176[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            %296 = llvm.load %295 : !llvm.ptr -> i64
            %297 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
            %298 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            %299 = llvm.load %298 : !llvm.ptr -> i64
            %300 = arith.muli %264, %299 : i64
            %301 = arith.subi %296, %300 : i64
            %302 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
            %303 = llvm.getelementptr %176[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            %304 = llvm.load %303 : !llvm.ptr -> i64
            %305 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
            %306 = llvm.getelementptr %176[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            %307 = llvm.load %306 : !llvm.ptr -> i64
            %308 = arith.muli %264, %307 : i64
            %309 = arith.subi %304, %308 : i64
            %310 = llvm.getelementptr %176[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            llvm.store %290, %310 : i64, !llvm.ptr
            %311 = llvm.getelementptr %176[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            llvm.store %293, %311 : i64, !llvm.ptr
            %312 = llvm.getelementptr %176[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            llvm.store %301, %312 : i64, !llvm.ptr
            %313 = llvm.getelementptr %176[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
            llvm.store %309, %313 : i64, !llvm.ptr
            cf.br ^bb20
          ^bb19:
            cf.br ^bb11
          ^bb20:
          cf.br ^bb17
        ^bb16:
          cf.br ^bb11
        ^bb17:
        cf.br ^bb14
      ^bb13:
        cf.br ^bb11
      ^bb14:
      cf.br ^bb9
    ^bb11:
    %314 = llvm.load %176 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %315 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %316 = llvm.extractvalue %314[0] : !llvm.struct<(i64, i64, i64, i64)>
    %317 = llvm.insertvalue %316, %315[0] : !llvm.struct<(i64, i64, i64, i64)>
    %318 = llvm.extractvalue %314[1] : !llvm.struct<(i64, i64, i64, i64)>
    %319 = llvm.insertvalue %318, %317[1] : !llvm.struct<(i64, i64, i64, i64)>
    %320 = llvm.extractvalue %314[2] : !llvm.struct<(i64, i64, i64, i64)>
    %321 = llvm.insertvalue %320, %319[2] : !llvm.struct<(i64, i64, i64, i64)>
    %322 = llvm.extractvalue %314[3] : !llvm.struct<(i64, i64, i64, i64)>
    %323 = llvm.insertvalue %322, %321[3] : !llvm.struct<(i64, i64, i64, i64)>
    %324 = llvm.mlir.constant(1 : i64) : i64
    %325 = llvm.alloca %324 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %323, %325 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %326 = llvm.load %325 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    func.return %326 : !llvm.struct<(i64, i64, i64, i64)>
  }
  func.func @state_hash(%arg0: !llvm.struct<(i64, i64, i64, i64)>) -> i64 {
    %327 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %328 = llvm.extractvalue %arg0[0] : !llvm.struct<(i64, i64, i64, i64)>
    %329 = llvm.insertvalue %328, %327[0] : !llvm.struct<(i64, i64, i64, i64)>
    %330 = llvm.extractvalue %arg0[1] : !llvm.struct<(i64, i64, i64, i64)>
    %331 = llvm.insertvalue %330, %329[1] : !llvm.struct<(i64, i64, i64, i64)>
    %332 = llvm.extractvalue %arg0[2] : !llvm.struct<(i64, i64, i64, i64)>
    %333 = llvm.insertvalue %332, %331[2] : !llvm.struct<(i64, i64, i64, i64)>
    %334 = llvm.extractvalue %arg0[3] : !llvm.struct<(i64, i64, i64, i64)>
    %335 = llvm.insertvalue %334, %333[3] : !llvm.struct<(i64, i64, i64, i64)>
    %336 = llvm.mlir.constant(1 : i64) : i64
    %337 = llvm.alloca %336 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %335, %337 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %338 = llvm.load %337 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %339 = llvm.getelementptr %337[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %340 = llvm.load %339 : !llvm.ptr -> i64
    %341 = arith.constant 31 : i32
    %343 = arith.extsi %341 : i32 to i64
    %342 = arith.muli %340, %343 : i64
    %344 = llvm.load %337 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %345 = llvm.getelementptr %337[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %346 = llvm.load %345 : !llvm.ptr -> i64
    %347 = arith.constant 37 : i32
    %349 = arith.extsi %347 : i32 to i64
    %348 = arith.muli %346, %349 : i64
    %350 = arith.addi %342, %348 : i64
    %351 = llvm.load %337 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %352 = llvm.getelementptr %337[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %353 = llvm.load %352 : !llvm.ptr -> i64
    %354 = arith.constant 41 : i32
    %356 = arith.extsi %354 : i32 to i64
    %355 = arith.muli %353, %356 : i64
    %357 = arith.addi %350, %355 : i64
    %358 = llvm.load %337 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %359 = llvm.getelementptr %337[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %360 = llvm.load %359 : !llvm.ptr -> i64
    %361 = arith.constant 43 : i32
    %363 = arith.extsi %361 : i32 to i64
    %362 = arith.muli %360, %363 : i64
    %364 = arith.addi %357, %362 : i64
    %365 = llvm.mlir.addressof @STATE_HT_MASK : !llvm.ptr
    %366 = llvm.load %365 : !llvm.ptr -> i64
    %367 = arith.andi %364, %366 : i64
    func.return %367 : i64
  }
  func.func @state_find(%arg0: !llvm.struct<(i64, i64, i64, i64)>) -> i64 {
    %368 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %369 = llvm.extractvalue %arg0[0] : !llvm.struct<(i64, i64, i64, i64)>
    %370 = llvm.insertvalue %369, %368[0] : !llvm.struct<(i64, i64, i64, i64)>
    %371 = llvm.extractvalue %arg0[1] : !llvm.struct<(i64, i64, i64, i64)>
    %372 = llvm.insertvalue %371, %370[1] : !llvm.struct<(i64, i64, i64, i64)>
    %373 = llvm.extractvalue %arg0[2] : !llvm.struct<(i64, i64, i64, i64)>
    %374 = llvm.insertvalue %373, %372[2] : !llvm.struct<(i64, i64, i64, i64)>
    %375 = llvm.extractvalue %arg0[3] : !llvm.struct<(i64, i64, i64, i64)>
    %376 = llvm.insertvalue %375, %374[3] : !llvm.struct<(i64, i64, i64, i64)>
    %377 = llvm.mlir.constant(1 : i64) : i64
    %378 = llvm.alloca %377 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %376, %378 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %380 = llvm.load %378 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %379 = func.call @state_hash(%380) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
    %381 = arith.constant 0 : i32
    %382 = arith.extsi %381 : i32 to i64
    %383 = llvm.mlir.constant(1 : i64) : i64
    %384 = llvm.alloca %383 x i64 : (i64) -> !llvm.ptr
    llvm.store %382, %384 : i64, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %385 = llvm.load %384 : !llvm.ptr -> i64
    %386 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %387 = llvm.load %386 : !llvm.ptr -> i64
    %388 = arith.cmpi slt, %385, %387 : i64
    cf.cond_br %388, ^bb22, ^bb23
    ^bb22:
      %389 = llvm.load %384 : !llvm.ptr -> i64
      %390 = arith.addi %379, %389 : i64
      %391 = llvm.mlir.addressof @STATE_HT_MASK : !llvm.ptr
      %392 = llvm.load %391 : !llvm.ptr -> i64
      %393 = arith.andi %390, %392 : i64
      %395 = llvm.mlir.addressof @st_ids : !llvm.ptr
      %396 = llvm.load %395 : !llvm.ptr -> !llvm.ptr
      %397 = llvm.getelementptr %396[%393] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %394 = llvm.load %397 : !llvm.ptr -> i32
      %398 = arith.constant 1 : i32
      %400 = arith.constant 0 : i32
      %399 = arith.subi %400, %398 : i32
      %401 = arith.cmpi eq, %394, %399 : i32
      cf.cond_br %401, ^bb24, ^bb25
      ^bb24:
        %402 = arith.constant 1 : i32
        %404 = arith.constant 0 : i32
        %403 = arith.subi %404, %402 : i32
        %405 = arith.extsi %403 : i32 to i64
        func.return %405 : i64
      ^bb25:
        cf.br ^bb26
      ^bb26:
      %407 = llvm.mlir.addressof @st_ids : !llvm.ptr
      %408 = llvm.load %407 : !llvm.ptr -> !llvm.ptr
      %409 = llvm.getelementptr %408[%393] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %406 = llvm.load %409 : !llvm.ptr -> i32
      %410 = arith.extsi %406 : i32 to i64
      %412 = llvm.mlir.addressof @st_A : !llvm.ptr
      %413 = llvm.load %412 : !llvm.ptr -> !llvm.ptr
      %414 = llvm.getelementptr %413[%410] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %411 = llvm.load %414 : !llvm.ptr -> i64
      %415 = llvm.load %378 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %416 = llvm.getelementptr %378[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
      %417 = llvm.load %416 : !llvm.ptr -> i64
      %418 = arith.cmpi eq, %411, %417 : i64
      %419 = scf.if %418 -> (i1) {
        %421 = llvm.mlir.addressof @st_B : !llvm.ptr
        %422 = llvm.load %421 : !llvm.ptr -> !llvm.ptr
        %423 = llvm.getelementptr %422[%410] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %420 = llvm.load %423 : !llvm.ptr -> i64
        %424 = llvm.load %378 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
        %425 = llvm.getelementptr %378[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
        %426 = llvm.load %425 : !llvm.ptr -> i64
        %427 = arith.cmpi eq, %420, %426 : i64
        scf.yield %427 : i1
      } else {
        %428 = arith.constant false
        scf.yield %428 : i1
      }
      %429 = scf.if %419 -> (i1) {
        %431 = llvm.mlir.addressof @st_C : !llvm.ptr
        %432 = llvm.load %431 : !llvm.ptr -> !llvm.ptr
        %433 = llvm.getelementptr %432[%410] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %430 = llvm.load %433 : !llvm.ptr -> i64
        %434 = llvm.load %378 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
        %435 = llvm.getelementptr %378[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
        %436 = llvm.load %435 : !llvm.ptr -> i64
        %437 = arith.cmpi eq, %430, %436 : i64
        scf.yield %437 : i1
      } else {
        %438 = arith.constant false
        scf.yield %438 : i1
      }
      %439 = scf.if %429 -> (i1) {
        %441 = llvm.mlir.addressof @st_D : !llvm.ptr
        %442 = llvm.load %441 : !llvm.ptr -> !llvm.ptr
        %443 = llvm.getelementptr %442[%410] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %440 = llvm.load %443 : !llvm.ptr -> i64
        %444 = llvm.load %378 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
        %445 = llvm.getelementptr %378[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
        %446 = llvm.load %445 : !llvm.ptr -> i64
        %447 = arith.cmpi eq, %440, %446 : i64
        scf.yield %447 : i1
      } else {
        %448 = arith.constant false
        scf.yield %448 : i1
      }
      cf.cond_br %439, ^bb27, ^bb28
      ^bb27:
        func.return %410 : i64
      ^bb28:
        cf.br ^bb29
      ^bb29:
      %449 = llvm.load %384 : !llvm.ptr -> i64
      %450 = arith.constant 1 : i32
      %452 = arith.extsi %450 : i32 to i64
      %451 = arith.addi %449, %452 : i64
      llvm.store %451, %384 : i64, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    %453 = arith.constant 1 : i32
    %455 = arith.constant 0 : i32
    %454 = arith.subi %455, %453 : i32
    %456 = arith.extsi %454 : i32 to i64
    func.return %456 : i64
  }
  func.func @state_insert(%arg0: !llvm.struct<(i64, i64, i64, i64)>) -> i64 {
    %457 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %458 = llvm.extractvalue %arg0[0] : !llvm.struct<(i64, i64, i64, i64)>
    %459 = llvm.insertvalue %458, %457[0] : !llvm.struct<(i64, i64, i64, i64)>
    %460 = llvm.extractvalue %arg0[1] : !llvm.struct<(i64, i64, i64, i64)>
    %461 = llvm.insertvalue %460, %459[1] : !llvm.struct<(i64, i64, i64, i64)>
    %462 = llvm.extractvalue %arg0[2] : !llvm.struct<(i64, i64, i64, i64)>
    %463 = llvm.insertvalue %462, %461[2] : !llvm.struct<(i64, i64, i64, i64)>
    %464 = llvm.extractvalue %arg0[3] : !llvm.struct<(i64, i64, i64, i64)>
    %465 = llvm.insertvalue %464, %463[3] : !llvm.struct<(i64, i64, i64, i64)>
    %466 = llvm.mlir.constant(1 : i64) : i64
    %467 = llvm.alloca %466 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %465, %467 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %468 = llvm.mlir.addressof @n_states : !llvm.ptr
    %469 = llvm.load %468 : !llvm.ptr -> i64
    %470 = llvm.load %467 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %471 = llvm.getelementptr %467[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %472 = llvm.load %471 : !llvm.ptr -> i64
    %473 = llvm.mlir.addressof @st_A : !llvm.ptr
    %474 = llvm.load %473 : !llvm.ptr -> !llvm.ptr
    %475 = llvm.getelementptr %474[%469] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %472, %475 : i64, !llvm.ptr
    %476 = llvm.load %467 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %477 = llvm.getelementptr %467[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %478 = llvm.load %477 : !llvm.ptr -> i64
    %479 = llvm.mlir.addressof @st_B : !llvm.ptr
    %480 = llvm.load %479 : !llvm.ptr -> !llvm.ptr
    %481 = llvm.getelementptr %480[%469] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %478, %481 : i64, !llvm.ptr
    %482 = llvm.load %467 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %483 = llvm.getelementptr %467[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %484 = llvm.load %483 : !llvm.ptr -> i64
    %485 = llvm.mlir.addressof @st_C : !llvm.ptr
    %486 = llvm.load %485 : !llvm.ptr -> !llvm.ptr
    %487 = llvm.getelementptr %486[%469] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %484, %487 : i64, !llvm.ptr
    %488 = llvm.load %467 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %489 = llvm.getelementptr %467[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, i64, i64, i64)>
    %490 = llvm.load %489 : !llvm.ptr -> i64
    %491 = llvm.mlir.addressof @st_D : !llvm.ptr
    %492 = llvm.load %491 : !llvm.ptr -> !llvm.ptr
    %493 = llvm.getelementptr %492[%469] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %490, %493 : i64, !llvm.ptr
    %495 = llvm.load %467 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %494 = func.call @state_hash(%495) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
    %496 = arith.constant 0 : i32
    %497 = arith.extsi %496 : i32 to i64
    %498 = llvm.mlir.constant(1 : i64) : i64
    %499 = llvm.alloca %498 x i64 : (i64) -> !llvm.ptr
    llvm.store %497, %499 : i64, !llvm.ptr
    cf.br ^bb30
    ^bb30:
    %500 = llvm.load %499 : !llvm.ptr -> i64
    %501 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %502 = llvm.load %501 : !llvm.ptr -> i64
    %503 = arith.cmpi slt, %500, %502 : i64
    cf.cond_br %503, ^bb31, ^bb32
    ^bb31:
      %504 = llvm.load %499 : !llvm.ptr -> i64
      %505 = arith.addi %494, %504 : i64
      %506 = llvm.mlir.addressof @STATE_HT_MASK : !llvm.ptr
      %507 = llvm.load %506 : !llvm.ptr -> i64
      %508 = arith.andi %505, %507 : i64
      %510 = llvm.mlir.addressof @st_ids : !llvm.ptr
      %511 = llvm.load %510 : !llvm.ptr -> !llvm.ptr
      %512 = llvm.getelementptr %511[%508] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %509 = llvm.load %512 : !llvm.ptr -> i32
      %513 = arith.constant 1 : i32
      %515 = arith.constant 0 : i32
      %514 = arith.subi %515, %513 : i32
      %516 = arith.cmpi eq, %509, %514 : i32
      cf.cond_br %516, ^bb33, ^bb34
      ^bb33:
        %517 = arith.trunci %469 : i64 to i32
        %518 = llvm.mlir.addressof @st_ids : !llvm.ptr
        %519 = llvm.load %518 : !llvm.ptr -> !llvm.ptr
        %520 = llvm.getelementptr %519[%508] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %517, %520 : i32, !llvm.ptr
        %521 = llvm.mlir.addressof @n_states : !llvm.ptr
        %522 = llvm.load %521 : !llvm.ptr -> i64
        %523 = arith.constant 1 : i32
        %525 = arith.extsi %523 : i32 to i64
        %524 = arith.addi %522, %525 : i64
        %526 = llvm.mlir.addressof @n_states : !llvm.ptr
        llvm.store %524, %526 : i64, !llvm.ptr
        func.return %469 : i64
      ^bb34:
        cf.br ^bb35
      ^bb35:
      %527 = llvm.load %499 : !llvm.ptr -> i64
      %528 = arith.constant 1 : i32
      %530 = arith.extsi %528 : i32 to i64
      %529 = arith.addi %527, %530 : i64
      llvm.store %529, %499 : i64, !llvm.ptr
      cf.br ^bb30
    ^bb32:
    %531 = arith.constant 1 : i32
    %533 = arith.constant 0 : i32
    %532 = arith.subi %533, %531 : i32
    %534 = arith.extsi %532 : i32 to i64
    func.return %534 : i64
  }
  func.func @clzll(%arg0: i64) -> i64 {
    %535 = arith.constant 0 : i32
    %537 = arith.extsi %535 : i32 to i64
    %536 = arith.cmpi sle, %arg0, %537 : i64
    cf.cond_br %536, ^bb36, ^bb37
    ^bb36:
      %538 = arith.constant 64 : i32
      %539 = arith.extsi %538 : i32 to i64
      func.return %539 : i64
    ^bb37:
      cf.br ^bb38
    ^bb38:
    %540 = arith.constant 0 : i32
    %541 = arith.extsi %540 : i32 to i64
    %542 = llvm.mlir.constant(1 : i64) : i64
    %543 = llvm.alloca %542 x i64 : (i64) -> !llvm.ptr
    llvm.store %541, %543 : i64, !llvm.ptr
    %544 = llvm.mlir.constant(1 : i64) : i64
    %545 = llvm.alloca %544 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %545 : i64, !llvm.ptr
    cf.br ^bb39
    ^bb39:
    %546 = llvm.load %545 : !llvm.ptr -> i64
    %547 = arith.constant 0 : i32
    %549 = arith.extsi %547 : i32 to i64
    %548 = arith.cmpi sgt, %546, %549 : i64
    cf.cond_br %548, ^bb40, ^bb41
    ^bb40:
      %550 = llvm.load %545 : !llvm.ptr -> i64
      %551 = arith.constant 1 : i32
      %553 = arith.extsi %551 : i32 to i64
      %552 = arith.shrsi %550, %553 : i64
      llvm.store %552, %545 : i64, !llvm.ptr
      %554 = llvm.load %543 : !llvm.ptr -> i64
      %555 = arith.constant 1 : i32
      %557 = arith.extsi %555 : i32 to i64
      %556 = arith.addi %554, %557 : i64
      llvm.store %556, %543 : i64, !llvm.ptr
      cf.br ^bb39
    ^bb41:
    %558 = arith.constant 64 : i32
    %559 = llvm.load %543 : !llvm.ptr -> i64
    %561 = arith.extsi %558 : i32 to i64
    %560 = arith.subi %561, %559 : i64
    func.return %560 : i64
  }
  func.func @isqrt_i64(%arg0: i64) -> i64 {
    %562 = arith.constant 2 : i32
    %564 = arith.extsi %562 : i32 to i64
    %563 = arith.cmpi slt, %arg0, %564 : i64
    cf.cond_br %563, ^bb42, ^bb43
    ^bb42:
      func.return %arg0 : i64
    ^bb43:
      cf.br ^bb44
    ^bb44:
    %565 = arith.sitofp %arg0 : i64 to f64
    %566 = math.sqrt %565 : f64
    %567 = arith.fptosi %566 : f64 to i64
    %568 = llvm.mlir.constant(1 : i64) : i64
    %569 = llvm.alloca %568 x i64 : (i64) -> !llvm.ptr
    llvm.store %567, %569 : i64, !llvm.ptr
    cf.br ^bb45
    ^bb45:
    %570 = llvm.load %569 : !llvm.ptr -> i64
    %571 = arith.constant 0 : i32
    %573 = arith.extsi %571 : i32 to i64
    %572 = arith.cmpi sgt, %570, %573 : i64
    %574 = scf.if %572 -> (i1) {
      %575 = llvm.load %569 : !llvm.ptr -> i64
      %576 = llvm.load %569 : !llvm.ptr -> i64
      %577 = arith.muli %575, %576 : i64
      %578 = arith.cmpi sgt, %577, %arg0 : i64
      scf.yield %578 : i1
    } else {
      %579 = arith.constant false
      scf.yield %579 : i1
    }
    cf.cond_br %574, ^bb46, ^bb47
    ^bb46:
      %580 = llvm.load %569 : !llvm.ptr -> i64
      %581 = arith.constant 1 : i32
      %583 = arith.extsi %581 : i32 to i64
      %582 = arith.subi %580, %583 : i64
      llvm.store %582, %569 : i64, !llvm.ptr
      cf.br ^bb45
    ^bb47:
    cf.br ^bb48
    ^bb48:
    %584 = llvm.load %569 : !llvm.ptr -> i64
    %585 = arith.constant 1 : i32
    %587 = arith.extsi %585 : i32 to i64
    %586 = arith.addi %584, %587 : i64
    %588 = llvm.load %569 : !llvm.ptr -> i64
    %589 = arith.constant 1 : i32
    %591 = arith.extsi %589 : i32 to i64
    %590 = arith.addi %588, %591 : i64
    %592 = arith.muli %586, %590 : i64
    %593 = arith.cmpi sle, %592, %arg0 : i64
    cf.cond_br %593, ^bb49, ^bb50
    ^bb49:
      %594 = llvm.load %569 : !llvm.ptr -> i64
      %595 = arith.constant 1 : i32
      %597 = arith.extsi %595 : i32 to i64
      %596 = arith.addi %594, %597 : i64
      llvm.store %596, %569 : i64, !llvm.ptr
      cf.br ^bb48
    ^bb50:
    %598 = llvm.load %569 : !llvm.ptr -> i64
    func.return %598 : i64
  }
  func.func @next_prime() -> i64 {
    %599 = llvm.mlir.addressof @n_primes : !llvm.ptr
    %600 = llvm.load %599 : !llvm.ptr -> i64
    %601 = arith.constant 0 : i32
    %603 = arith.extsi %601 : i32 to i64
    %602 = arith.cmpi eq, %600, %603 : i64
    cf.cond_br %602, ^bb51, ^bb52
    ^bb51:
      %604 = arith.constant 2 : i32
      %605 = llvm.mlir.addressof @primes_arr : !llvm.ptr
      %606 = llvm.load %605 : !llvm.ptr -> !llvm.ptr
      %607 = arith.constant 0 : i32
      %608 = arith.extsi %604 : i32 to i64
      %609 = arith.extsi %607 : i32 to i64
      %610 = llvm.getelementptr %606[%609] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %608, %610 : i64, !llvm.ptr
      %611 = arith.constant 1 : i32
      %612 = arith.extsi %611 : i32 to i64
      %613 = llvm.mlir.addressof @n_primes : !llvm.ptr
      llvm.store %612, %613 : i64, !llvm.ptr
      %614 = arith.constant 3 : i32
      %615 = arith.extsi %614 : i32 to i64
      %616 = llvm.mlir.addressof @next_cand : !llvm.ptr
      llvm.store %615, %616 : i64, !llvm.ptr
      %617 = arith.constant 2 : i32
      %618 = arith.extsi %617 : i32 to i64
      func.return %618 : i64
    ^bb52:
      cf.br ^bb53
    ^bb53:
    %619 = llvm.mlir.addressof @next_cand : !llvm.ptr
    %620 = llvm.load %619 : !llvm.ptr -> i64
    %621 = llvm.mlir.constant(1 : i64) : i64
    %622 = llvm.alloca %621 x i64 : (i64) -> !llvm.ptr
    llvm.store %620, %622 : i64, !llvm.ptr
    cf.br ^bb54
    ^bb54:
    %623 = arith.constant 1 : i1
    cf.cond_br %623, ^bb55, ^bb56
    ^bb55:
      %625 = llvm.load %622 : !llvm.ptr -> i64
      %624 = func.call @isqrt_i64(%625) : (i64) -> i64
      %626 = arith.constant 1 : i1
      %627 = llvm.mlir.constant(1 : i64) : i64
      %628 = llvm.alloca %627 x i1 : (i64) -> !llvm.ptr
      llvm.store %626, %628 : i1, !llvm.ptr
      %629 = arith.constant 0 : i32
      %630 = arith.extsi %629 : i32 to i64
      %631 = llvm.mlir.constant(1 : i64) : i64
      %632 = llvm.alloca %631 x i64 : (i64) -> !llvm.ptr
      llvm.store %630, %632 : i64, !llvm.ptr
      cf.br ^bb57
      ^bb57:
      %633 = llvm.load %632 : !llvm.ptr -> i64
      %634 = llvm.mlir.addressof @n_primes : !llvm.ptr
      %635 = llvm.load %634 : !llvm.ptr -> i64
      %636 = arith.cmpi slt, %633, %635 : i64
      cf.cond_br %636, ^bb58, ^bb59
      ^bb58:
        %638 = llvm.mlir.addressof @primes_arr : !llvm.ptr
        %639 = llvm.load %638 : !llvm.ptr -> !llvm.ptr
        %640 = llvm.load %632 : !llvm.ptr -> i64
        %641 = llvm.getelementptr %639[%640] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %637 = llvm.load %641 : !llvm.ptr -> i64
        %642 = arith.cmpi sgt, %637, %624 : i64
        cf.cond_br %642, ^bb60, ^bb61
        ^bb60:
          cf.br ^bb59
        ^bb61:
          cf.br ^bb62
        ^bb62:
        %643 = llvm.load %622 : !llvm.ptr -> i64
        %644 = arith.remsi %643, %637 : i64
        %645 = arith.constant 0 : i32
        %647 = arith.extsi %645 : i32 to i64
        %646 = arith.cmpi eq, %644, %647 : i64
        cf.cond_br %646, ^bb63, ^bb64
        ^bb63:
          %648 = arith.constant 0 : i1
          llvm.store %648, %628 : i1, !llvm.ptr
          cf.br ^bb59
        ^bb64:
          cf.br ^bb65
        ^bb65:
        %649 = llvm.load %632 : !llvm.ptr -> i64
        %650 = arith.constant 1 : i32
        %652 = arith.extsi %650 : i32 to i64
        %651 = arith.addi %649, %652 : i64
        llvm.store %651, %632 : i64, !llvm.ptr
        cf.br ^bb57
      ^bb59:
      %653 = llvm.load %628 : !llvm.ptr -> i1
      cf.cond_br %653, ^bb66, ^bb67
      ^bb66:
        %654 = llvm.load %622 : !llvm.ptr -> i64
        %655 = llvm.mlir.addressof @primes_arr : !llvm.ptr
        %656 = llvm.load %655 : !llvm.ptr -> !llvm.ptr
        %657 = llvm.mlir.addressof @n_primes : !llvm.ptr
        %658 = llvm.load %657 : !llvm.ptr -> i64
        %659 = llvm.getelementptr %656[%658] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %654, %659 : i64, !llvm.ptr
        %660 = llvm.mlir.addressof @n_primes : !llvm.ptr
        %661 = llvm.load %660 : !llvm.ptr -> i64
        %662 = arith.constant 1 : i32
        %664 = arith.extsi %662 : i32 to i64
        %663 = arith.addi %661, %664 : i64
        %665 = llvm.mlir.addressof @n_primes : !llvm.ptr
        llvm.store %663, %665 : i64, !llvm.ptr
        %666 = llvm.load %622 : !llvm.ptr -> i64
        %667 = arith.constant 2 : i32
        %669 = arith.extsi %667 : i32 to i64
        %668 = arith.addi %666, %669 : i64
        %670 = llvm.mlir.addressof @next_cand : !llvm.ptr
        llvm.store %668, %670 : i64, !llvm.ptr
        %671 = llvm.load %622 : !llvm.ptr -> i64
        func.return %671 : i64
      ^bb67:
        cf.br ^bb68
      ^bb68:
      %672 = llvm.load %622 : !llvm.ptr -> i64
      %673 = arith.constant 2 : i32
      %675 = arith.extsi %673 : i32 to i64
      %674 = arith.addi %672, %675 : i64
      llvm.store %674, %622 : i64, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    %676 = arith.constant 0 : i32
    %677 = arith.extsi %676 : i32 to i64
    func.return %677 : i64
  }
  func.func @alpha_init() -> () {
    %678 = arith.constant 0 : i32
    %679 = arith.extsi %678 : i32 to i64
    %680 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
    llvm.store %679, %680 : i64, !llvm.ptr
    %681 = arith.constant 0 : i32
    %682 = arith.extsi %681 : i32 to i64
    %683 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
    llvm.store %682, %683 : i64, !llvm.ptr
    func.return
  }
  func.func @alpha_next() -> i64 {
    %684 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
    %685 = llvm.load %684 : !llvm.ptr -> i64
    %686 = arith.constant 0 : i32
    %688 = arith.extsi %686 : i32 to i64
    %687 = arith.cmpi eq, %685, %688 : i64
    cf.cond_br %687, ^bb69, ^bb70
    ^bb69:
      %689 = arith.constant 1 : i32
      %690 = arith.extsi %689 : i32 to i64
      %691 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
      llvm.store %690, %691 : i64, !llvm.ptr
      %692 = func.call @next_prime() : () -> i64
      %693 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
      llvm.store %692, %693 : i64, !llvm.ptr
      %694 = arith.constant 2 : i32
      %695 = arith.extsi %694 : i32 to i64
      func.return %695 : i64
    ^bb70:
      cf.br ^bb71
    ^bb71:
    %696 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
    %697 = llvm.load %696 : !llvm.ptr -> i64
    %698 = arith.constant 1 : i32
    %700 = arith.extsi %698 : i32 to i64
    %699 = arith.cmpi eq, %697, %700 : i64
    cf.cond_br %699, ^bb72, ^bb73
    ^bb72:
      %701 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
      %702 = llvm.load %701 : !llvm.ptr -> i64
      %703 = arith.constant 1 : i32
      %705 = arith.extsi %703 : i32 to i64
      %704 = arith.subi %702, %705 : i64
      %706 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
      llvm.store %704, %706 : i64, !llvm.ptr
      %707 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
      %708 = llvm.load %707 : !llvm.ptr -> i64
      %709 = arith.constant 0 : i32
      %711 = arith.extsi %709 : i32 to i64
      %710 = arith.cmpi eq, %708, %711 : i64
      cf.cond_br %710, ^bb75, ^bb76
      ^bb75:
        %712 = arith.constant 2 : i32
        %713 = arith.extsi %712 : i32 to i64
        %714 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
        llvm.store %713, %714 : i64, !llvm.ptr
        cf.br ^bb77
      ^bb76:
        cf.br ^bb77
      ^bb77:
      %715 = arith.constant 1 : i32
      %716 = arith.extsi %715 : i32 to i64
      func.return %716 : i64
    ^bb73:
      cf.br ^bb74
    ^bb74:
    %717 = arith.constant 1 : i32
    %718 = arith.extsi %717 : i32 to i64
    %719 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
    llvm.store %718, %719 : i64, !llvm.ptr
    %720 = func.call @next_prime() : () -> i64
    %721 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
    llvm.store %720, %721 : i64, !llvm.ptr
    %722 = arith.constant 2 : i32
    %723 = arith.extsi %722 : i32 to i64
    func.return %723 : i64
  }
  func.func @alpha_can_skip_ones() -> i1 {
    %724 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
    %725 = llvm.load %724 : !llvm.ptr -> i64
    %726 = arith.constant 1 : i32
    %728 = arith.extsi %726 : i32 to i64
    %727 = arith.cmpi eq, %725, %728 : i64
    %729 = scf.if %727 -> (i1) {
      %730 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
      %731 = llvm.load %730 : !llvm.ptr -> i64
      %732 = arith.constant 0 : i32
      %734 = arith.extsi %732 : i32 to i64
      %733 = arith.cmpi sgt, %731, %734 : i64
      scf.yield %733 : i1
    } else {
      %735 = arith.constant false
      scf.yield %735 : i1
    }
    func.return %729 : i1
  }
  func.func @alpha_skip_ones(%arg0: i64) -> () {
    %736 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
    %737 = llvm.load %736 : !llvm.ptr -> i64
    %738 = arith.subi %737, %arg0 : i64
    %739 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
    llvm.store %738, %739 : i64, !llvm.ptr
    %740 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
    %741 = llvm.load %740 : !llvm.ptr -> i64
    %742 = arith.constant 0 : i32
    %744 = arith.extsi %742 : i32 to i64
    %743 = arith.cmpi eq, %741, %744 : i64
    cf.cond_br %743, ^bb78, ^bb79
    ^bb78:
      %745 = arith.constant 2 : i32
      %746 = arith.extsi %745 : i32 to i64
      %747 = llvm.mlir.addressof @alpha_stage : !llvm.ptr
      llvm.store %746, %747 : i64, !llvm.ptr
      cf.br ^bb80
    ^bb79:
      cf.br ^bb80
    ^bb80:
    func.return
  }
  func.func @prepare_tables() -> () {
    %748 = arith.constant 0 : i32
    %749 = arith.extsi %748 : i32 to i64
    %750 = llvm.mlir.constant(1 : i64) : i64
    %751 = llvm.alloca %750 x i64 : (i64) -> !llvm.ptr
    llvm.store %749, %751 : i64, !llvm.ptr
    cf.br ^bb81
    ^bb81:
    %752 = llvm.load %751 : !llvm.ptr -> i64
    %753 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %754 = llvm.load %753 : !llvm.ptr -> i64
    %755 = arith.cmpi slt, %752, %754 : i64
    cf.cond_br %755, ^bb82, ^bb83
    ^bb82:
      %756 = arith.constant 1 : i32
      %758 = arith.constant 0 : i32
      %757 = arith.subi %758, %756 : i32
      %759 = llvm.mlir.addressof @st_ids : !llvm.ptr
      %760 = llvm.load %759 : !llvm.ptr -> !llvm.ptr
      %761 = llvm.load %751 : !llvm.ptr -> i64
      %762 = llvm.getelementptr %760[%761] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %757, %762 : i32, !llvm.ptr
      %763 = llvm.load %751 : !llvm.ptr -> i64
      %764 = arith.constant 1 : i32
      %766 = arith.extsi %764 : i32 to i64
      %765 = arith.addi %763, %766 : i64
      llvm.store %765, %751 : i64, !llvm.ptr
      cf.br ^bb81
    ^bb83:
    %767 = arith.constant 0 : i32
    %768 = arith.extsi %767 : i32 to i64
    %769 = llvm.mlir.addressof @n_states : !llvm.ptr
    llvm.store %768, %769 : i64, !llvm.ptr
    %770 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
    %771 = arith.constant 2 : i32
    %772 = arith.extsi %771 : i32 to i64
    %773 = llvm.insertvalue %772, %770[0] : !llvm.struct<(i64, i64, i64, i64)>
    %774 = arith.constant 3 : i32
    %775 = arith.extsi %774 : i32 to i64
    %776 = llvm.insertvalue %775, %773[1] : !llvm.struct<(i64, i64, i64, i64)>
    %777 = arith.constant 3 : i32
    %778 = arith.extsi %777 : i32 to i64
    %779 = llvm.insertvalue %778, %776[2] : !llvm.struct<(i64, i64, i64, i64)>
    %780 = arith.constant 2 : i32
    %781 = arith.extsi %780 : i32 to i64
    %782 = llvm.insertvalue %781, %779[3] : !llvm.struct<(i64, i64, i64, i64)>
    %783 = llvm.mlir.constant(1 : i64) : i64
    %784 = llvm.alloca %783 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
    llvm.store %782, %784 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
    %786 = llvm.load %784 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
    %785 = func.call @state_insert(%786) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
    %788 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %789 = llvm.load %788 : !llvm.ptr -> i64
    %790 = arith.constant 4 : i32
    %792 = arith.extsi %790 : i32 to i64
    %791 = arith.muli %789, %792 : i64
    %787 = func.call @malloc(%791) : (i64) -> !llvm.ptr
    %793 = arith.constant 0 : i32
    %794 = arith.extsi %793 : i32 to i64
    %795 = llvm.mlir.constant(1 : i64) : i64
    %796 = llvm.alloca %795 x i64 : (i64) -> !llvm.ptr
    llvm.store %794, %796 : i64, !llvm.ptr
    %797 = arith.constant 0 : i32
    %798 = arith.extsi %797 : i32 to i64
    %799 = llvm.mlir.constant(1 : i64) : i64
    %800 = llvm.alloca %799 x i64 : (i64) -> !llvm.ptr
    llvm.store %798, %800 : i64, !llvm.ptr
    %801 = arith.trunci %785 : i64 to i32
    %802 = llvm.load %800 : !llvm.ptr -> i64
    %803 = llvm.getelementptr %787[%802] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %801, %803 : i32, !llvm.ptr
    %804 = llvm.load %800 : !llvm.ptr -> i64
    %805 = arith.constant 1 : i32
    %807 = arith.extsi %805 : i32 to i64
    %806 = arith.addi %804, %807 : i64
    llvm.store %806, %800 : i64, !llvm.ptr
    cf.br ^bb84
    ^bb84:
    %808 = llvm.load %796 : !llvm.ptr -> i64
    %809 = llvm.load %800 : !llvm.ptr -> i64
    %810 = arith.cmpi slt, %808, %809 : i64
    cf.cond_br %810, ^bb85, ^bb86
    ^bb85:
      %812 = llvm.load %796 : !llvm.ptr -> i64
      %813 = llvm.getelementptr %787[%812] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %811 = llvm.load %813 : !llvm.ptr -> i32
      %814 = arith.extsi %811 : i32 to i64
      %815 = llvm.load %796 : !llvm.ptr -> i64
      %816 = arith.constant 1 : i32
      %818 = arith.extsi %816 : i32 to i64
      %817 = arith.addi %815, %818 : i64
      llvm.store %817, %796 : i64, !llvm.ptr
      %819 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %821 = llvm.mlir.addressof @st_A : !llvm.ptr
      %822 = llvm.load %821 : !llvm.ptr -> !llvm.ptr
      %823 = llvm.getelementptr %822[%814] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %820 = llvm.load %823 : !llvm.ptr -> i64
      %824 = llvm.insertvalue %820, %819[0] : !llvm.struct<(i64, i64, i64, i64)>
      %826 = llvm.mlir.addressof @st_B : !llvm.ptr
      %827 = llvm.load %826 : !llvm.ptr -> !llvm.ptr
      %828 = llvm.getelementptr %827[%814] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %825 = llvm.load %828 : !llvm.ptr -> i64
      %829 = llvm.insertvalue %825, %824[1] : !llvm.struct<(i64, i64, i64, i64)>
      %831 = llvm.mlir.addressof @st_C : !llvm.ptr
      %832 = llvm.load %831 : !llvm.ptr -> !llvm.ptr
      %833 = llvm.getelementptr %832[%814] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %830 = llvm.load %833 : !llvm.ptr -> i64
      %834 = llvm.insertvalue %830, %829[2] : !llvm.struct<(i64, i64, i64, i64)>
      %836 = llvm.mlir.addressof @st_D : !llvm.ptr
      %837 = llvm.load %836 : !llvm.ptr -> !llvm.ptr
      %838 = llvm.getelementptr %837[%814] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %835 = llvm.load %838 : !llvm.ptr -> i64
      %839 = llvm.insertvalue %835, %834[3] : !llvm.struct<(i64, i64, i64, i64)>
      %840 = llvm.mlir.constant(1 : i64) : i64
      %841 = llvm.alloca %840 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %839, %841 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %842 = arith.constant 1 : i32
      %843 = arith.extsi %842 : i32 to i64
      %844 = llvm.mlir.constant(1 : i64) : i64
      %845 = llvm.alloca %844 x i64 : (i64) -> !llvm.ptr
      llvm.store %843, %845 : i64, !llvm.ptr
      cf.br ^bb87
      ^bb87:
      %846 = llvm.load %845 : !llvm.ptr -> i64
      %847 = arith.constant 2 : i32
      %849 = arith.extsi %847 : i32 to i64
      %848 = arith.cmpi sle, %846, %849 : i64
      cf.cond_br %848, ^bb88, ^bb89
      ^bb88:
        %851 = llvm.load %845 : !llvm.ptr -> i64
        %852 = llvm.load %841 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
        %853 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
        %854 = llvm.extractvalue %852[0] : !llvm.struct<(i64, i64, i64, i64)>
        %855 = llvm.insertvalue %854, %853[0] : !llvm.struct<(i64, i64, i64, i64)>
        %856 = llvm.extractvalue %852[1] : !llvm.struct<(i64, i64, i64, i64)>
        %857 = llvm.insertvalue %856, %855[1] : !llvm.struct<(i64, i64, i64, i64)>
        %858 = llvm.extractvalue %852[2] : !llvm.struct<(i64, i64, i64, i64)>
        %859 = llvm.insertvalue %858, %857[2] : !llvm.struct<(i64, i64, i64, i64)>
        %860 = llvm.extractvalue %852[3] : !llvm.struct<(i64, i64, i64, i64)>
        %861 = llvm.insertvalue %860, %859[3] : !llvm.struct<(i64, i64, i64, i64)>
        %850 = func.call @step_transition(%861, %851) : (!llvm.struct<(i64, i64, i64, i64)>, i64) -> !llvm.struct<(i64, i64, i64, i64)>
        %862 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
        %863 = llvm.extractvalue %850[0] : !llvm.struct<(i64, i64, i64, i64)>
        %864 = llvm.insertvalue %863, %862[0] : !llvm.struct<(i64, i64, i64, i64)>
        %865 = llvm.extractvalue %850[1] : !llvm.struct<(i64, i64, i64, i64)>
        %866 = llvm.insertvalue %865, %864[1] : !llvm.struct<(i64, i64, i64, i64)>
        %867 = llvm.extractvalue %850[2] : !llvm.struct<(i64, i64, i64, i64)>
        %868 = llvm.insertvalue %867, %866[2] : !llvm.struct<(i64, i64, i64, i64)>
        %869 = llvm.extractvalue %850[3] : !llvm.struct<(i64, i64, i64, i64)>
        %870 = llvm.insertvalue %869, %868[3] : !llvm.struct<(i64, i64, i64, i64)>
        %871 = llvm.mlir.constant(1 : i64) : i64
        %872 = llvm.alloca %871 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
        llvm.store %870, %872 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
        %873 = llvm.load %872 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
        %874 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
        %875 = llvm.extractvalue %861[0] : !llvm.struct<(i64, i64, i64, i64)>
        %876 = llvm.insertvalue %875, %874[0] : !llvm.struct<(i64, i64, i64, i64)>
        %877 = llvm.extractvalue %861[1] : !llvm.struct<(i64, i64, i64, i64)>
        %878 = llvm.insertvalue %877, %876[1] : !llvm.struct<(i64, i64, i64, i64)>
        %879 = llvm.extractvalue %861[2] : !llvm.struct<(i64, i64, i64, i64)>
        %880 = llvm.insertvalue %879, %878[2] : !llvm.struct<(i64, i64, i64, i64)>
        %881 = llvm.extractvalue %861[3] : !llvm.struct<(i64, i64, i64, i64)>
        %882 = llvm.insertvalue %881, %880[3] : !llvm.struct<(i64, i64, i64, i64)>
        %883 = llvm.mlir.constant(1 : i64) : i64
        %884 = llvm.alloca %883 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
        llvm.store %882, %884 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
        %885 = llvm.load %884 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
        llvm.store %885, %841 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
        %886 = llvm.mlir.constant(1 : i64) : i64
        %887 = llvm.alloca %886 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
        llvm.store %873, %887 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
        %889 = llvm.load %887 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
        %888 = func.call @state_find(%889) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
        %890 = arith.constant 1 : i32
        %892 = arith.constant 0 : i32
        %891 = arith.subi %892, %890 : i32
        %894 = arith.extsi %891 : i32 to i64
        %893 = arith.cmpi eq, %888, %894 : i64
        cf.cond_br %893, ^bb90, ^bb91
        ^bb90:
          %896 = llvm.load %887 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
          %895 = func.call @state_insert(%896) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
          %897 = arith.trunci %895 : i64 to i32
          %898 = llvm.load %800 : !llvm.ptr -> i64
          %899 = llvm.getelementptr %787[%898] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %897, %899 : i32, !llvm.ptr
          %900 = llvm.load %800 : !llvm.ptr -> i64
          %901 = arith.constant 1 : i32
          %903 = arith.extsi %901 : i32 to i64
          %902 = arith.addi %900, %903 : i64
          llvm.store %902, %800 : i64, !llvm.ptr
          cf.br ^bb92
        ^bb91:
          cf.br ^bb92
        ^bb92:
        %904 = llvm.load %845 : !llvm.ptr -> i64
        %905 = arith.constant 1 : i32
        %907 = arith.extsi %905 : i32 to i64
        %906 = arith.addi %904, %907 : i64
        llvm.store %906, %845 : i64, !llvm.ptr
        cf.br ^bb87
      ^bb89:
      cf.br ^bb84
    ^bb86:
    func.call @free(%787) : (!llvm.ptr) -> ()
    %909 = arith.constant 0 : i32
    %910 = arith.extsi %909 : i32 to i64
    %911 = llvm.mlir.constant(1 : i64) : i64
    %912 = llvm.alloca %911 x i64 : (i64) -> !llvm.ptr
    llvm.store %910, %912 : i64, !llvm.ptr
    cf.br ^bb93
    ^bb93:
    %913 = llvm.load %912 : !llvm.ptr -> i64
    %914 = llvm.mlir.addressof @n_states : !llvm.ptr
    %915 = llvm.load %914 : !llvm.ptr -> i64
    %916 = arith.cmpi slt, %913, %915 : i64
    cf.cond_br %916, ^bb94, ^bb95
    ^bb94:
      %917 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %919 = llvm.mlir.addressof @st_A : !llvm.ptr
      %920 = llvm.load %919 : !llvm.ptr -> !llvm.ptr
      %921 = llvm.load %912 : !llvm.ptr -> i64
      %922 = llvm.getelementptr %920[%921] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %918 = llvm.load %922 : !llvm.ptr -> i64
      %923 = llvm.insertvalue %918, %917[0] : !llvm.struct<(i64, i64, i64, i64)>
      %925 = llvm.mlir.addressof @st_B : !llvm.ptr
      %926 = llvm.load %925 : !llvm.ptr -> !llvm.ptr
      %927 = llvm.load %912 : !llvm.ptr -> i64
      %928 = llvm.getelementptr %926[%927] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %924 = llvm.load %928 : !llvm.ptr -> i64
      %929 = llvm.insertvalue %924, %923[1] : !llvm.struct<(i64, i64, i64, i64)>
      %931 = llvm.mlir.addressof @st_C : !llvm.ptr
      %932 = llvm.load %931 : !llvm.ptr -> !llvm.ptr
      %933 = llvm.load %912 : !llvm.ptr -> i64
      %934 = llvm.getelementptr %932[%933] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %930 = llvm.load %934 : !llvm.ptr -> i64
      %935 = llvm.insertvalue %930, %929[2] : !llvm.struct<(i64, i64, i64, i64)>
      %937 = llvm.mlir.addressof @st_D : !llvm.ptr
      %938 = llvm.load %937 : !llvm.ptr -> !llvm.ptr
      %939 = llvm.load %912 : !llvm.ptr -> i64
      %940 = llvm.getelementptr %938[%939] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %936 = llvm.load %940 : !llvm.ptr -> i64
      %941 = llvm.insertvalue %936, %935[3] : !llvm.struct<(i64, i64, i64, i64)>
      %942 = llvm.mlir.constant(1 : i64) : i64
      %943 = llvm.alloca %942 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %941, %943 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %945 = arith.constant 1 : i32
      %946 = llvm.load %943 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %947 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %948 = llvm.extractvalue %946[0] : !llvm.struct<(i64, i64, i64, i64)>
      %949 = llvm.insertvalue %948, %947[0] : !llvm.struct<(i64, i64, i64, i64)>
      %950 = llvm.extractvalue %946[1] : !llvm.struct<(i64, i64, i64, i64)>
      %951 = llvm.insertvalue %950, %949[1] : !llvm.struct<(i64, i64, i64, i64)>
      %952 = llvm.extractvalue %946[2] : !llvm.struct<(i64, i64, i64, i64)>
      %953 = llvm.insertvalue %952, %951[2] : !llvm.struct<(i64, i64, i64, i64)>
      %954 = llvm.extractvalue %946[3] : !llvm.struct<(i64, i64, i64, i64)>
      %955 = llvm.insertvalue %954, %953[3] : !llvm.struct<(i64, i64, i64, i64)>
      %956 = arith.extsi %945 : i32 to i64
      %944 = func.call @step_transition(%955, %956) : (!llvm.struct<(i64, i64, i64, i64)>, i64) -> !llvm.struct<(i64, i64, i64, i64)>
      %957 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %958 = llvm.extractvalue %944[0] : !llvm.struct<(i64, i64, i64, i64)>
      %959 = llvm.insertvalue %958, %957[0] : !llvm.struct<(i64, i64, i64, i64)>
      %960 = llvm.extractvalue %944[1] : !llvm.struct<(i64, i64, i64, i64)>
      %961 = llvm.insertvalue %960, %959[1] : !llvm.struct<(i64, i64, i64, i64)>
      %962 = llvm.extractvalue %944[2] : !llvm.struct<(i64, i64, i64, i64)>
      %963 = llvm.insertvalue %962, %961[2] : !llvm.struct<(i64, i64, i64, i64)>
      %964 = llvm.extractvalue %944[3] : !llvm.struct<(i64, i64, i64, i64)>
      %965 = llvm.insertvalue %964, %963[3] : !llvm.struct<(i64, i64, i64, i64)>
      %966 = llvm.mlir.constant(1 : i64) : i64
      %967 = llvm.alloca %966 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %965, %967 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %968 = llvm.load %967 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %969 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %970 = llvm.extractvalue %955[0] : !llvm.struct<(i64, i64, i64, i64)>
      %971 = llvm.insertvalue %970, %969[0] : !llvm.struct<(i64, i64, i64, i64)>
      %972 = llvm.extractvalue %955[1] : !llvm.struct<(i64, i64, i64, i64)>
      %973 = llvm.insertvalue %972, %971[1] : !llvm.struct<(i64, i64, i64, i64)>
      %974 = llvm.extractvalue %955[2] : !llvm.struct<(i64, i64, i64, i64)>
      %975 = llvm.insertvalue %974, %973[2] : !llvm.struct<(i64, i64, i64, i64)>
      %976 = llvm.extractvalue %955[3] : !llvm.struct<(i64, i64, i64, i64)>
      %977 = llvm.insertvalue %976, %975[3] : !llvm.struct<(i64, i64, i64, i64)>
      %978 = llvm.mlir.constant(1 : i64) : i64
      %979 = llvm.alloca %978 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %977, %979 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %980 = llvm.load %979 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %980, %943 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %981 = llvm.mlir.constant(1 : i64) : i64
      %982 = llvm.alloca %981 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %968, %982 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %984 = llvm.load %982 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %983 = func.call @state_find(%984) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
      %985 = arith.trunci %983 : i64 to i32
      %986 = llvm.mlir.addressof @next1_arr : !llvm.ptr
      %987 = llvm.load %986 : !llvm.ptr -> !llvm.ptr
      %988 = llvm.load %912 : !llvm.ptr -> i64
      %989 = llvm.getelementptr %987[%988] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %985, %989 : i32, !llvm.ptr
      %990 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
      %991 = llvm.load %990 : !llvm.ptr -> i64
      %992 = llvm.mlir.addressof @cnt1_arr : !llvm.ptr
      %993 = llvm.load %992 : !llvm.ptr -> !llvm.ptr
      %994 = llvm.load %912 : !llvm.ptr -> i64
      %995 = llvm.getelementptr %993[%994] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %991, %995 : i64, !llvm.ptr
      %996 = arith.constant 0 : i32
      %997 = arith.extsi %996 : i32 to i64
      %998 = llvm.mlir.constant(1 : i64) : i64
      %999 = llvm.alloca %998 x i64 : (i64) -> !llvm.ptr
      llvm.store %997, %999 : i64, !llvm.ptr
      %1000 = arith.constant 0 : i32
      %1001 = arith.extsi %1000 : i32 to i64
      %1002 = llvm.mlir.constant(1 : i64) : i64
      %1003 = llvm.alloca %1002 x i64 : (i64) -> !llvm.ptr
      llvm.store %1001, %1003 : i64, !llvm.ptr
      cf.br ^bb96
      ^bb96:
      %1004 = llvm.load %1003 : !llvm.ptr -> i64
      %1005 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
      %1006 = llvm.load %1005 : !llvm.ptr -> i64
      %1007 = arith.cmpi slt, %1004, %1006 : i64
      cf.cond_br %1007, ^bb97, ^bb98
      ^bb97:
        %1008 = llvm.load %999 : !llvm.ptr -> i64
        %1010 = llvm.mlir.addressof @g_outs : !llvm.ptr
        %1011 = llvm.load %1010 : !llvm.ptr -> !llvm.ptr
        %1012 = llvm.load %1003 : !llvm.ptr -> i64
        %1013 = llvm.getelementptr %1011[%1012] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1009 = llvm.load %1013 : !llvm.ptr -> i64
        %1014 = arith.addi %1008, %1009 : i64
        llvm.store %1014, %999 : i64, !llvm.ptr
        %1015 = llvm.load %1003 : !llvm.ptr -> i64
        %1016 = arith.constant 1 : i32
        %1018 = arith.extsi %1016 : i32 to i64
        %1017 = arith.addi %1015, %1018 : i64
        llvm.store %1017, %1003 : i64, !llvm.ptr
        cf.br ^bb96
      ^bb98:
      %1019 = llvm.load %999 : !llvm.ptr -> i64
      %1020 = llvm.mlir.addressof @sum1_arr : !llvm.ptr
      %1021 = llvm.load %1020 : !llvm.ptr -> !llvm.ptr
      %1022 = llvm.load %912 : !llvm.ptr -> i64
      %1023 = llvm.getelementptr %1021[%1022] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1019, %1023 : i64, !llvm.ptr
      %1025 = arith.constant 2 : i32
      %1026 = llvm.load %943 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %1027 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %1028 = llvm.extractvalue %1026[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1029 = llvm.insertvalue %1028, %1027[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1030 = llvm.extractvalue %1026[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1031 = llvm.insertvalue %1030, %1029[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1032 = llvm.extractvalue %1026[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1033 = llvm.insertvalue %1032, %1031[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1034 = llvm.extractvalue %1026[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1035 = llvm.insertvalue %1034, %1033[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1036 = arith.extsi %1025 : i32 to i64
      %1024 = func.call @step_transition(%1035, %1036) : (!llvm.struct<(i64, i64, i64, i64)>, i64) -> !llvm.struct<(i64, i64, i64, i64)>
      %1037 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %1038 = llvm.extractvalue %1024[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1039 = llvm.insertvalue %1038, %1037[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1040 = llvm.extractvalue %1024[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1041 = llvm.insertvalue %1040, %1039[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1042 = llvm.extractvalue %1024[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1043 = llvm.insertvalue %1042, %1041[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1044 = llvm.extractvalue %1024[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1045 = llvm.insertvalue %1044, %1043[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1046 = llvm.mlir.constant(1 : i64) : i64
      %1047 = llvm.alloca %1046 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %1045, %1047 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1048 = llvm.load %1047 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %1049 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %1050 = llvm.extractvalue %1035[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1051 = llvm.insertvalue %1050, %1049[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1052 = llvm.extractvalue %1035[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1053 = llvm.insertvalue %1052, %1051[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1054 = llvm.extractvalue %1035[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1055 = llvm.insertvalue %1054, %1053[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1056 = llvm.extractvalue %1035[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1057 = llvm.insertvalue %1056, %1055[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1058 = llvm.mlir.constant(1 : i64) : i64
      %1059 = llvm.alloca %1058 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %1057, %1059 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1060 = llvm.load %1059 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %1060, %943 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1061 = llvm.mlir.constant(1 : i64) : i64
      %1062 = llvm.alloca %1061 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %1048, %1062 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1064 = llvm.load %1062 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %1063 = func.call @state_find(%1064) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
      %1065 = arith.trunci %1063 : i64 to i32
      %1066 = llvm.mlir.addressof @next2_arr : !llvm.ptr
      %1067 = llvm.load %1066 : !llvm.ptr -> !llvm.ptr
      %1068 = llvm.load %912 : !llvm.ptr -> i64
      %1069 = llvm.getelementptr %1067[%1068] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1065, %1069 : i32, !llvm.ptr
      %1070 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
      %1071 = llvm.load %1070 : !llvm.ptr -> i64
      %1072 = llvm.mlir.addressof @cnt2_arr : !llvm.ptr
      %1073 = llvm.load %1072 : !llvm.ptr -> !llvm.ptr
      %1074 = llvm.load %912 : !llvm.ptr -> i64
      %1075 = llvm.getelementptr %1073[%1074] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1071, %1075 : i64, !llvm.ptr
      %1076 = arith.constant 0 : i32
      %1077 = arith.extsi %1076 : i32 to i64
      %1078 = llvm.mlir.constant(1 : i64) : i64
      %1079 = llvm.alloca %1078 x i64 : (i64) -> !llvm.ptr
      llvm.store %1077, %1079 : i64, !llvm.ptr
      %1080 = arith.constant 0 : i32
      %1081 = arith.extsi %1080 : i32 to i64
      llvm.store %1081, %1003 : i64, !llvm.ptr
      cf.br ^bb99
      ^bb99:
      %1082 = llvm.load %1003 : !llvm.ptr -> i64
      %1083 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
      %1084 = llvm.load %1083 : !llvm.ptr -> i64
      %1085 = arith.cmpi slt, %1082, %1084 : i64
      cf.cond_br %1085, ^bb100, ^bb101
      ^bb100:
        %1086 = llvm.load %1079 : !llvm.ptr -> i64
        %1088 = llvm.mlir.addressof @g_outs : !llvm.ptr
        %1089 = llvm.load %1088 : !llvm.ptr -> !llvm.ptr
        %1090 = llvm.load %1003 : !llvm.ptr -> i64
        %1091 = llvm.getelementptr %1089[%1090] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1087 = llvm.load %1091 : !llvm.ptr -> i64
        %1092 = arith.addi %1086, %1087 : i64
        llvm.store %1092, %1079 : i64, !llvm.ptr
        %1093 = llvm.load %1003 : !llvm.ptr -> i64
        %1094 = arith.constant 1 : i32
        %1096 = arith.extsi %1094 : i32 to i64
        %1095 = arith.addi %1093, %1096 : i64
        llvm.store %1095, %1003 : i64, !llvm.ptr
        cf.br ^bb99
      ^bb101:
      %1097 = llvm.load %1079 : !llvm.ptr -> i64
      %1098 = llvm.mlir.addressof @sum2_arr : !llvm.ptr
      %1099 = llvm.load %1098 : !llvm.ptr -> !llvm.ptr
      %1100 = llvm.load %912 : !llvm.ptr -> i64
      %1101 = llvm.getelementptr %1099[%1100] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1097, %1101 : i64, !llvm.ptr
      %1102 = llvm.load %912 : !llvm.ptr -> i64
      %1103 = arith.constant 1 : i32
      %1105 = arith.extsi %1103 : i32 to i64
      %1104 = arith.addi %1102, %1105 : i64
      llvm.store %1104, %912 : i64, !llvm.ptr
      cf.br ^bb93
    ^bb95:
    %1106 = arith.constant 0 : i32
    %1107 = arith.extsi %1106 : i32 to i64
    llvm.store %1107, %912 : i64, !llvm.ptr
    cf.br ^bb102
    ^bb102:
    %1108 = llvm.load %912 : !llvm.ptr -> i64
    %1109 = llvm.mlir.addressof @n_states : !llvm.ptr
    %1110 = llvm.load %1109 : !llvm.ptr -> i64
    %1111 = arith.cmpi slt, %1108, %1110 : i64
    cf.cond_br %1111, ^bb103, ^bb104
    ^bb103:
      %1113 = llvm.mlir.addressof @next1_arr : !llvm.ptr
      %1114 = llvm.load %1113 : !llvm.ptr -> !llvm.ptr
      %1115 = llvm.load %912 : !llvm.ptr -> i64
      %1116 = llvm.getelementptr %1114[%1115] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1112 = llvm.load %1116 : !llvm.ptr -> i32
      %1117 = llvm.mlir.addressof @pow_next_arr : !llvm.ptr
      %1118 = llvm.load %1117 : !llvm.ptr -> !llvm.ptr
      %1119 = llvm.load %912 : !llvm.ptr -> i64
      %1120 = llvm.getelementptr %1118[%1119] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1112, %1120 : i32, !llvm.ptr
      %1122 = llvm.mlir.addressof @cnt1_arr : !llvm.ptr
      %1123 = llvm.load %1122 : !llvm.ptr -> !llvm.ptr
      %1124 = llvm.load %912 : !llvm.ptr -> i64
      %1125 = llvm.getelementptr %1123[%1124] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1121 = llvm.load %1125 : !llvm.ptr -> i64
      %1126 = llvm.mlir.addressof @pow_cnt_arr : !llvm.ptr
      %1127 = llvm.load %1126 : !llvm.ptr -> !llvm.ptr
      %1128 = llvm.load %912 : !llvm.ptr -> i64
      %1129 = llvm.getelementptr %1127[%1128] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1121, %1129 : i64, !llvm.ptr
      %1131 = llvm.mlir.addressof @sum1_arr : !llvm.ptr
      %1132 = llvm.load %1131 : !llvm.ptr -> !llvm.ptr
      %1133 = llvm.load %912 : !llvm.ptr -> i64
      %1134 = llvm.getelementptr %1132[%1133] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1130 = llvm.load %1134 : !llvm.ptr -> i64
      %1135 = llvm.mlir.addressof @pow_sum_arr : !llvm.ptr
      %1136 = llvm.load %1135 : !llvm.ptr -> !llvm.ptr
      %1137 = llvm.load %912 : !llvm.ptr -> i64
      %1138 = llvm.getelementptr %1136[%1137] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1130, %1138 : i64, !llvm.ptr
      %1139 = llvm.load %912 : !llvm.ptr -> i64
      %1140 = arith.constant 1 : i32
      %1142 = arith.extsi %1140 : i32 to i64
      %1141 = arith.addi %1139, %1142 : i64
      llvm.store %1141, %912 : i64, !llvm.ptr
      cf.br ^bb102
    ^bb104:
    %1143 = arith.constant 1 : i32
    %1144 = arith.extsi %1143 : i32 to i64
    %1145 = llvm.mlir.constant(1 : i64) : i64
    %1146 = llvm.alloca %1145 x i64 : (i64) -> !llvm.ptr
    llvm.store %1144, %1146 : i64, !llvm.ptr
    cf.br ^bb105
    ^bb105:
    %1147 = llvm.load %1146 : !llvm.ptr -> i64
    %1148 = llvm.mlir.addressof @MAX_POW : !llvm.ptr
    %1149 = llvm.load %1148 : !llvm.ptr -> i64
    %1150 = arith.cmpi slt, %1147, %1149 : i64
    cf.cond_br %1150, ^bb106, ^bb107
    ^bb106:
      %1151 = arith.constant 0 : i32
      %1152 = arith.extsi %1151 : i32 to i64
      llvm.store %1152, %912 : i64, !llvm.ptr
      cf.br ^bb108
      ^bb108:
      %1153 = llvm.load %912 : !llvm.ptr -> i64
      %1154 = llvm.mlir.addressof @n_states : !llvm.ptr
      %1155 = llvm.load %1154 : !llvm.ptr -> i64
      %1156 = arith.cmpi slt, %1153, %1155 : i64
      cf.cond_br %1156, ^bb109, ^bb110
      ^bb109:
        %1158 = llvm.mlir.addressof @pow_next_arr : !llvm.ptr
        %1159 = llvm.load %1158 : !llvm.ptr -> !llvm.ptr
        %1160 = llvm.load %1146 : !llvm.ptr -> i64
        %1161 = arith.constant 1 : i32
        %1163 = arith.extsi %1161 : i32 to i64
        %1162 = arith.subi %1160, %1163 : i64
        %1164 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1165 = llvm.load %1164 : !llvm.ptr -> i64
        %1166 = arith.muli %1162, %1165 : i64
        %1167 = llvm.load %912 : !llvm.ptr -> i64
        %1168 = arith.addi %1166, %1167 : i64
        %1169 = llvm.getelementptr %1159[%1168] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1157 = llvm.load %1169 : !llvm.ptr -> i32
        %1170 = arith.extsi %1157 : i32 to i64
        %1172 = llvm.mlir.addressof @pow_next_arr : !llvm.ptr
        %1173 = llvm.load %1172 : !llvm.ptr -> !llvm.ptr
        %1174 = llvm.load %1146 : !llvm.ptr -> i64
        %1175 = arith.constant 1 : i32
        %1177 = arith.extsi %1175 : i32 to i64
        %1176 = arith.subi %1174, %1177 : i64
        %1178 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1179 = llvm.load %1178 : !llvm.ptr -> i64
        %1180 = arith.muli %1176, %1179 : i64
        %1181 = arith.addi %1180, %1170 : i64
        %1182 = llvm.getelementptr %1173[%1181] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1171 = llvm.load %1182 : !llvm.ptr -> i32
        %1183 = llvm.mlir.addressof @pow_next_arr : !llvm.ptr
        %1184 = llvm.load %1183 : !llvm.ptr -> !llvm.ptr
        %1185 = llvm.load %1146 : !llvm.ptr -> i64
        %1186 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1187 = llvm.load %1186 : !llvm.ptr -> i64
        %1188 = arith.muli %1185, %1187 : i64
        %1189 = llvm.load %912 : !llvm.ptr -> i64
        %1190 = arith.addi %1188, %1189 : i64
        %1191 = llvm.getelementptr %1184[%1190] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1171, %1191 : i32, !llvm.ptr
        %1193 = llvm.mlir.addressof @pow_cnt_arr : !llvm.ptr
        %1194 = llvm.load %1193 : !llvm.ptr -> !llvm.ptr
        %1195 = llvm.load %1146 : !llvm.ptr -> i64
        %1196 = arith.constant 1 : i32
        %1198 = arith.extsi %1196 : i32 to i64
        %1197 = arith.subi %1195, %1198 : i64
        %1199 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1200 = llvm.load %1199 : !llvm.ptr -> i64
        %1201 = arith.muli %1197, %1200 : i64
        %1202 = llvm.load %912 : !llvm.ptr -> i64
        %1203 = arith.addi %1201, %1202 : i64
        %1204 = llvm.getelementptr %1194[%1203] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1192 = llvm.load %1204 : !llvm.ptr -> i64
        %1206 = llvm.mlir.addressof @pow_cnt_arr : !llvm.ptr
        %1207 = llvm.load %1206 : !llvm.ptr -> !llvm.ptr
        %1208 = llvm.load %1146 : !llvm.ptr -> i64
        %1209 = arith.constant 1 : i32
        %1211 = arith.extsi %1209 : i32 to i64
        %1210 = arith.subi %1208, %1211 : i64
        %1212 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1213 = llvm.load %1212 : !llvm.ptr -> i64
        %1214 = arith.muli %1210, %1213 : i64
        %1215 = arith.addi %1214, %1170 : i64
        %1216 = llvm.getelementptr %1207[%1215] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1205 = llvm.load %1216 : !llvm.ptr -> i64
        %1217 = arith.addi %1192, %1205 : i64
        %1218 = llvm.mlir.addressof @pow_cnt_arr : !llvm.ptr
        %1219 = llvm.load %1218 : !llvm.ptr -> !llvm.ptr
        %1220 = llvm.load %1146 : !llvm.ptr -> i64
        %1221 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1222 = llvm.load %1221 : !llvm.ptr -> i64
        %1223 = arith.muli %1220, %1222 : i64
        %1224 = llvm.load %912 : !llvm.ptr -> i64
        %1225 = arith.addi %1223, %1224 : i64
        %1226 = llvm.getelementptr %1219[%1225] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %1217, %1226 : i64, !llvm.ptr
        %1228 = llvm.mlir.addressof @pow_sum_arr : !llvm.ptr
        %1229 = llvm.load %1228 : !llvm.ptr -> !llvm.ptr
        %1230 = llvm.load %1146 : !llvm.ptr -> i64
        %1231 = arith.constant 1 : i32
        %1233 = arith.extsi %1231 : i32 to i64
        %1232 = arith.subi %1230, %1233 : i64
        %1234 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1235 = llvm.load %1234 : !llvm.ptr -> i64
        %1236 = arith.muli %1232, %1235 : i64
        %1237 = llvm.load %912 : !llvm.ptr -> i64
        %1238 = arith.addi %1236, %1237 : i64
        %1239 = llvm.getelementptr %1229[%1238] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1227 = llvm.load %1239 : !llvm.ptr -> i64
        %1241 = llvm.mlir.addressof @pow_sum_arr : !llvm.ptr
        %1242 = llvm.load %1241 : !llvm.ptr -> !llvm.ptr
        %1243 = llvm.load %1146 : !llvm.ptr -> i64
        %1244 = arith.constant 1 : i32
        %1246 = arith.extsi %1244 : i32 to i64
        %1245 = arith.subi %1243, %1246 : i64
        %1247 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1248 = llvm.load %1247 : !llvm.ptr -> i64
        %1249 = arith.muli %1245, %1248 : i64
        %1250 = arith.addi %1249, %1170 : i64
        %1251 = llvm.getelementptr %1242[%1250] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1240 = llvm.load %1251 : !llvm.ptr -> i64
        %1252 = arith.addi %1227, %1240 : i64
        %1253 = llvm.mlir.addressof @pow_sum_arr : !llvm.ptr
        %1254 = llvm.load %1253 : !llvm.ptr -> !llvm.ptr
        %1255 = llvm.load %1146 : !llvm.ptr -> i64
        %1256 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1257 = llvm.load %1256 : !llvm.ptr -> i64
        %1258 = arith.muli %1255, %1257 : i64
        %1259 = llvm.load %912 : !llvm.ptr -> i64
        %1260 = arith.addi %1258, %1259 : i64
        %1261 = llvm.getelementptr %1254[%1260] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %1252, %1261 : i64, !llvm.ptr
        %1262 = llvm.load %912 : !llvm.ptr -> i64
        %1263 = arith.constant 1 : i32
        %1265 = arith.extsi %1263 : i32 to i64
        %1264 = arith.addi %1262, %1265 : i64
        llvm.store %1264, %912 : i64, !llvm.ptr
        cf.br ^bb108
      ^bb110:
      %1266 = llvm.load %1146 : !llvm.ptr -> i64
      %1267 = arith.constant 1 : i32
      %1269 = arith.extsi %1267 : i32 to i64
      %1268 = arith.addi %1266, %1269 : i64
      llvm.store %1268, %1146 : i64, !llvm.ptr
      cf.br ^bb105
    ^bb107:
    func.return
  }
  func.func @consume_ones_with_limit(%arg0: i64, %arg1: i64, %arg2: i64) -> () {
    %1270 = arith.constant 0 : i32
    %1271 = arith.extsi %1270 : i32 to i64
    %1272 = llvm.mlir.addressof @g_consumed : !llvm.ptr
    llvm.store %1271, %1272 : i64, !llvm.ptr
    %1273 = arith.constant 0 : i32
    %1274 = arith.extsi %1273 : i32 to i64
    %1275 = llvm.mlir.addressof @g_emitted_c : !llvm.ptr
    llvm.store %1274, %1275 : i64, !llvm.ptr
    %1276 = arith.constant 0 : i32
    %1277 = arith.extsi %1276 : i32 to i64
    %1278 = llvm.mlir.addressof @g_emitted_s : !llvm.ptr
    llvm.store %1277, %1278 : i64, !llvm.ptr
    %1279 = llvm.mlir.addressof @g_new_state : !llvm.ptr
    llvm.store %arg0, %1279 : i64, !llvm.ptr
    %1280 = arith.constant 0 : i32
    %1282 = arith.extsi %1280 : i32 to i64
    %1281 = arith.cmpi sle, %arg1, %1282 : i64
    %1283 = scf.if %1281 -> (i1) {
      %1284 = arith.constant true
      scf.yield %1284 : i1
    } else {
      %1285 = arith.constant 0 : i32
      %1287 = arith.extsi %1285 : i32 to i64
      %1286 = arith.cmpi sle, %arg2, %1287 : i64
      scf.yield %1286 : i1
    }
    cf.cond_br %1283, ^bb111, ^bb112
    ^bb111:
      func.return
    ^bb112:
      cf.br ^bb113
    ^bb113:
    %1288 = llvm.mlir.constant(1 : i64) : i64
    %1289 = llvm.alloca %1288 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %1289 : i64, !llvm.ptr
    %1290 = arith.constant 0 : i32
    %1291 = arith.extsi %1290 : i32 to i64
    %1292 = llvm.mlir.constant(1 : i64) : i64
    %1293 = llvm.alloca %1292 x i64 : (i64) -> !llvm.ptr
    llvm.store %1291, %1293 : i64, !llvm.ptr
    %1294 = arith.constant 0 : i32
    %1295 = arith.extsi %1294 : i32 to i64
    %1296 = llvm.mlir.constant(1 : i64) : i64
    %1297 = llvm.alloca %1296 x i64 : (i64) -> !llvm.ptr
    llvm.store %1295, %1297 : i64, !llvm.ptr
    %1298 = arith.constant 0 : i32
    %1299 = arith.extsi %1298 : i32 to i64
    %1300 = llvm.mlir.constant(1 : i64) : i64
    %1301 = llvm.alloca %1300 x i64 : (i64) -> !llvm.ptr
    llvm.store %1299, %1301 : i64, !llvm.ptr
    %1302 = llvm.mlir.constant(1 : i64) : i64
    %1303 = llvm.alloca %1302 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg2, %1303 : i64, !llvm.ptr
    %1304 = arith.constant 63 : i32
    %1305 = func.call @clzll(%arg1) : (i64) -> i64
    %1307 = arith.extsi %1304 : i32 to i64
    %1306 = arith.subi %1307, %1305 : i64
    %1308 = llvm.mlir.constant(1 : i64) : i64
    %1309 = llvm.alloca %1308 x i64 : (i64) -> !llvm.ptr
    llvm.store %1306, %1309 : i64, !llvm.ptr
    cf.br ^bb114
    ^bb114:
    %1310 = llvm.load %1309 : !llvm.ptr -> i64
    %1311 = arith.constant 0 : i32
    %1313 = arith.extsi %1311 : i32 to i64
    %1312 = arith.cmpi sge, %1310, %1313 : i64
    cf.cond_br %1312, ^bb115, ^bb116
    ^bb115:
      %1314 = arith.constant 1 : i32
      %1315 = llvm.load %1309 : !llvm.ptr -> i64
      %1317 = arith.extsi %1314 : i32 to i64
      %1316 = arith.shli %1317, %1315 : i64
      %1318 = llvm.load %1293 : !llvm.ptr -> i64
      %1319 = arith.addi %1318, %1316 : i64
      %1320 = arith.cmpi sle, %1319, %arg1 : i64
      cf.cond_br %1320, ^bb117, ^bb118
      ^bb117:
        %1322 = llvm.mlir.addressof @pow_cnt_arr : !llvm.ptr
        %1323 = llvm.load %1322 : !llvm.ptr -> !llvm.ptr
        %1324 = llvm.load %1309 : !llvm.ptr -> i64
        %1325 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
        %1326 = llvm.load %1325 : !llvm.ptr -> i64
        %1327 = arith.muli %1324, %1326 : i64
        %1328 = llvm.load %1289 : !llvm.ptr -> i64
        %1329 = arith.addi %1327, %1328 : i64
        %1330 = llvm.getelementptr %1323[%1329] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1321 = llvm.load %1330 : !llvm.ptr -> i64
        %1331 = llvm.load %1303 : !llvm.ptr -> i64
        %1332 = arith.cmpi sle, %1321, %1331 : i64
        cf.cond_br %1332, ^bb120, ^bb121
        ^bb120:
          %1333 = llvm.load %1303 : !llvm.ptr -> i64
          %1334 = arith.subi %1333, %1321 : i64
          llvm.store %1334, %1303 : i64, !llvm.ptr
          %1335 = llvm.load %1293 : !llvm.ptr -> i64
          %1336 = arith.addi %1335, %1316 : i64
          llvm.store %1336, %1293 : i64, !llvm.ptr
          %1337 = llvm.load %1297 : !llvm.ptr -> i64
          %1338 = arith.addi %1337, %1321 : i64
          llvm.store %1338, %1297 : i64, !llvm.ptr
          %1339 = llvm.load %1301 : !llvm.ptr -> i64
          %1341 = llvm.mlir.addressof @pow_sum_arr : !llvm.ptr
          %1342 = llvm.load %1341 : !llvm.ptr -> !llvm.ptr
          %1343 = llvm.load %1309 : !llvm.ptr -> i64
          %1344 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
          %1345 = llvm.load %1344 : !llvm.ptr -> i64
          %1346 = arith.muli %1343, %1345 : i64
          %1347 = llvm.load %1289 : !llvm.ptr -> i64
          %1348 = arith.addi %1346, %1347 : i64
          %1349 = llvm.getelementptr %1342[%1348] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %1340 = llvm.load %1349 : !llvm.ptr -> i64
          %1350 = arith.addi %1339, %1340 : i64
          llvm.store %1350, %1301 : i64, !llvm.ptr
          %1352 = llvm.mlir.addressof @pow_next_arr : !llvm.ptr
          %1353 = llvm.load %1352 : !llvm.ptr -> !llvm.ptr
          %1354 = llvm.load %1309 : !llvm.ptr -> i64
          %1355 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
          %1356 = llvm.load %1355 : !llvm.ptr -> i64
          %1357 = arith.muli %1354, %1356 : i64
          %1358 = llvm.load %1289 : !llvm.ptr -> i64
          %1359 = arith.addi %1357, %1358 : i64
          %1360 = llvm.getelementptr %1353[%1359] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1351 = llvm.load %1360 : !llvm.ptr -> i32
          %1361 = arith.extsi %1351 : i32 to i64
          llvm.store %1361, %1289 : i64, !llvm.ptr
          cf.br ^bb122
        ^bb121:
          cf.br ^bb122
        ^bb122:
        cf.br ^bb119
      ^bb118:
        cf.br ^bb119
      ^bb119:
      %1362 = llvm.load %1309 : !llvm.ptr -> i64
      %1363 = arith.constant 1 : i32
      %1365 = arith.extsi %1363 : i32 to i64
      %1364 = arith.subi %1362, %1365 : i64
      llvm.store %1364, %1309 : i64, !llvm.ptr
      cf.br ^bb114
    ^bb116:
    %1366 = llvm.load %1289 : !llvm.ptr -> i64
    %1367 = llvm.mlir.addressof @g_new_state : !llvm.ptr
    llvm.store %1366, %1367 : i64, !llvm.ptr
    %1368 = llvm.load %1293 : !llvm.ptr -> i64
    %1369 = llvm.mlir.addressof @g_consumed : !llvm.ptr
    llvm.store %1368, %1369 : i64, !llvm.ptr
    %1370 = llvm.load %1297 : !llvm.ptr -> i64
    %1371 = llvm.mlir.addressof @g_emitted_c : !llvm.ptr
    llvm.store %1370, %1371 : i64, !llvm.ptr
    %1372 = llvm.load %1301 : !llvm.ptr -> i64
    %1373 = llvm.mlir.addressof @g_emitted_s : !llvm.ptr
    llvm.store %1372, %1373 : i64, !llvm.ptr
    func.return
  }
  func.func @main() -> i32 {
    %1375 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1376 = llvm.load %1375 : !llvm.ptr -> i64
    %1377 = arith.constant 8 : i32
    %1379 = arith.extsi %1377 : i32 to i64
    %1378 = arith.muli %1376, %1379 : i64
    %1374 = func.call @malloc(%1378) : (i64) -> !llvm.ptr
    %1380 = llvm.mlir.addressof @st_A : !llvm.ptr
    llvm.store %1374, %1380 : !llvm.ptr, !llvm.ptr
    %1382 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1383 = llvm.load %1382 : !llvm.ptr -> i64
    %1384 = arith.constant 8 : i32
    %1386 = arith.extsi %1384 : i32 to i64
    %1385 = arith.muli %1383, %1386 : i64
    %1381 = func.call @malloc(%1385) : (i64) -> !llvm.ptr
    %1387 = llvm.mlir.addressof @st_B : !llvm.ptr
    llvm.store %1381, %1387 : !llvm.ptr, !llvm.ptr
    %1389 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1390 = llvm.load %1389 : !llvm.ptr -> i64
    %1391 = arith.constant 8 : i32
    %1393 = arith.extsi %1391 : i32 to i64
    %1392 = arith.muli %1390, %1393 : i64
    %1388 = func.call @malloc(%1392) : (i64) -> !llvm.ptr
    %1394 = llvm.mlir.addressof @st_C : !llvm.ptr
    llvm.store %1388, %1394 : !llvm.ptr, !llvm.ptr
    %1396 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1397 = llvm.load %1396 : !llvm.ptr -> i64
    %1398 = arith.constant 8 : i32
    %1400 = arith.extsi %1398 : i32 to i64
    %1399 = arith.muli %1397, %1400 : i64
    %1395 = func.call @malloc(%1399) : (i64) -> !llvm.ptr
    %1401 = llvm.mlir.addressof @st_D : !llvm.ptr
    llvm.store %1395, %1401 : !llvm.ptr, !llvm.ptr
    %1403 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1404 = llvm.load %1403 : !llvm.ptr -> i64
    %1405 = arith.constant 4 : i32
    %1407 = arith.extsi %1405 : i32 to i64
    %1406 = arith.muli %1404, %1407 : i64
    %1402 = func.call @malloc(%1406) : (i64) -> !llvm.ptr
    %1408 = llvm.mlir.addressof @st_ids : !llvm.ptr
    llvm.store %1402, %1408 : !llvm.ptr, !llvm.ptr
    %1410 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1411 = llvm.load %1410 : !llvm.ptr -> i64
    %1412 = arith.constant 4 : i32
    %1414 = arith.extsi %1412 : i32 to i64
    %1413 = arith.muli %1411, %1414 : i64
    %1409 = func.call @malloc(%1413) : (i64) -> !llvm.ptr
    %1415 = llvm.mlir.addressof @next1_arr : !llvm.ptr
    llvm.store %1409, %1415 : !llvm.ptr, !llvm.ptr
    %1417 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1418 = llvm.load %1417 : !llvm.ptr -> i64
    %1419 = arith.constant 4 : i32
    %1421 = arith.extsi %1419 : i32 to i64
    %1420 = arith.muli %1418, %1421 : i64
    %1416 = func.call @malloc(%1420) : (i64) -> !llvm.ptr
    %1422 = llvm.mlir.addressof @next2_arr : !llvm.ptr
    llvm.store %1416, %1422 : !llvm.ptr, !llvm.ptr
    %1424 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1425 = llvm.load %1424 : !llvm.ptr -> i64
    %1426 = arith.constant 8 : i32
    %1428 = arith.extsi %1426 : i32 to i64
    %1427 = arith.muli %1425, %1428 : i64
    %1423 = func.call @malloc(%1427) : (i64) -> !llvm.ptr
    %1429 = llvm.mlir.addressof @cnt1_arr : !llvm.ptr
    llvm.store %1423, %1429 : !llvm.ptr, !llvm.ptr
    %1431 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1432 = llvm.load %1431 : !llvm.ptr -> i64
    %1433 = arith.constant 8 : i32
    %1435 = arith.extsi %1433 : i32 to i64
    %1434 = arith.muli %1432, %1435 : i64
    %1430 = func.call @malloc(%1434) : (i64) -> !llvm.ptr
    %1436 = llvm.mlir.addressof @sum1_arr : !llvm.ptr
    llvm.store %1430, %1436 : !llvm.ptr, !llvm.ptr
    %1438 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1439 = llvm.load %1438 : !llvm.ptr -> i64
    %1440 = arith.constant 8 : i32
    %1442 = arith.extsi %1440 : i32 to i64
    %1441 = arith.muli %1439, %1442 : i64
    %1437 = func.call @malloc(%1441) : (i64) -> !llvm.ptr
    %1443 = llvm.mlir.addressof @cnt2_arr : !llvm.ptr
    llvm.store %1437, %1443 : !llvm.ptr, !llvm.ptr
    %1445 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1446 = llvm.load %1445 : !llvm.ptr -> i64
    %1447 = arith.constant 8 : i32
    %1449 = arith.extsi %1447 : i32 to i64
    %1448 = arith.muli %1446, %1449 : i64
    %1444 = func.call @malloc(%1448) : (i64) -> !llvm.ptr
    %1450 = llvm.mlir.addressof @sum2_arr : !llvm.ptr
    llvm.store %1444, %1450 : !llvm.ptr, !llvm.ptr
    %1452 = llvm.mlir.addressof @MAX_POW : !llvm.ptr
    %1453 = llvm.load %1452 : !llvm.ptr -> i64
    %1454 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1455 = llvm.load %1454 : !llvm.ptr -> i64
    %1456 = arith.muli %1453, %1455 : i64
    %1457 = arith.constant 4 : i32
    %1459 = arith.extsi %1457 : i32 to i64
    %1458 = arith.muli %1456, %1459 : i64
    %1451 = func.call @malloc(%1458) : (i64) -> !llvm.ptr
    %1460 = llvm.mlir.addressof @pow_next_arr : !llvm.ptr
    llvm.store %1451, %1460 : !llvm.ptr, !llvm.ptr
    %1462 = llvm.mlir.addressof @MAX_POW : !llvm.ptr
    %1463 = llvm.load %1462 : !llvm.ptr -> i64
    %1464 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1465 = llvm.load %1464 : !llvm.ptr -> i64
    %1466 = arith.muli %1463, %1465 : i64
    %1467 = arith.constant 8 : i32
    %1469 = arith.extsi %1467 : i32 to i64
    %1468 = arith.muli %1466, %1469 : i64
    %1461 = func.call @malloc(%1468) : (i64) -> !llvm.ptr
    %1470 = llvm.mlir.addressof @pow_cnt_arr : !llvm.ptr
    llvm.store %1461, %1470 : !llvm.ptr, !llvm.ptr
    %1472 = llvm.mlir.addressof @MAX_POW : !llvm.ptr
    %1473 = llvm.load %1472 : !llvm.ptr -> i64
    %1474 = llvm.mlir.addressof @STATE_HT_SIZE : !llvm.ptr
    %1475 = llvm.load %1474 : !llvm.ptr -> i64
    %1476 = arith.muli %1473, %1475 : i64
    %1477 = arith.constant 8 : i32
    %1479 = arith.extsi %1477 : i32 to i64
    %1478 = arith.muli %1476, %1479 : i64
    %1471 = func.call @malloc(%1478) : (i64) -> !llvm.ptr
    %1480 = llvm.mlir.addressof @pow_sum_arr : !llvm.ptr
    llvm.store %1471, %1480 : !llvm.ptr, !llvm.ptr
    %1482 = arith.constant 16 : i32
    %1483 = arith.constant 8 : i32
    %1484 = arith.muli %1482, %1483 : i32
    %1485 = arith.extsi %1484 : i32 to i64
    %1481 = func.call @malloc(%1485) : (i64) -> !llvm.ptr
    %1486 = llvm.mlir.addressof @g_outs : !llvm.ptr
    llvm.store %1481, %1486 : !llvm.ptr, !llvm.ptr
    %1488 = arith.constant 20000 : i32
    %1489 = arith.constant 8 : i32
    %1490 = arith.muli %1488, %1489 : i32
    %1491 = arith.extsi %1490 : i32 to i64
    %1487 = func.call @malloc(%1491) : (i64) -> !llvm.ptr
    %1492 = llvm.mlir.addressof @primes_arr : !llvm.ptr
    llvm.store %1487, %1492 : !llvm.ptr, !llvm.ptr
    func.call @prepare_tables() : () -> ()
    %1494 = arith.constant 100000000 : i32
    %1495 = arith.extsi %1494 : i32 to i64
    func.call @alpha_init() : () -> ()
    %1497 = arith.constant 0 : i32
    %1498 = arith.extsi %1497 : i32 to i64
    %1499 = llvm.mlir.constant(1 : i64) : i64
    %1500 = llvm.alloca %1499 x i64 : (i64) -> !llvm.ptr
    llvm.store %1498, %1500 : i64, !llvm.ptr
    %1501 = arith.constant 0 : i32
    %1502 = arith.extsi %1501 : i32 to i64
    %1503 = llvm.mlir.constant(1 : i64) : i64
    %1504 = llvm.alloca %1503 x i64 : (i64) -> !llvm.ptr
    llvm.store %1502, %1504 : i64, !llvm.ptr
    %1505 = arith.constant 0 : i32
    %1506 = arith.extsi %1505 : i32 to i64
    %1507 = llvm.mlir.constant(1 : i64) : i64
    %1508 = llvm.alloca %1507 x i64 : (i64) -> !llvm.ptr
    llvm.store %1506, %1508 : i64, !llvm.ptr
    %1509 = arith.constant 2000 : i32
    %1510 = arith.extsi %1509 : i32 to i64
    %1511 = arith.subi %1495, %1510 : i64
    %1512 = llvm.mlir.constant(1 : i64) : i64
    %1513 = llvm.alloca %1512 x i64 : (i64) -> !llvm.ptr
    llvm.store %1511, %1513 : i64, !llvm.ptr
    %1514 = llvm.load %1513 : !llvm.ptr -> i64
    %1515 = arith.constant 0 : i32
    %1517 = arith.extsi %1515 : i32 to i64
    %1516 = arith.cmpi slt, %1514, %1517 : i64
    cf.cond_br %1516, ^bb123, ^bb124
    ^bb123:
      %1518 = arith.constant 0 : i32
      %1519 = arith.extsi %1518 : i32 to i64
      llvm.store %1519, %1513 : i64, !llvm.ptr
      cf.br ^bb125
    ^bb124:
      cf.br ^bb125
    ^bb125:
    cf.br ^bb126
    ^bb126:
    %1520 = llvm.load %1508 : !llvm.ptr -> i64
    %1521 = llvm.load %1513 : !llvm.ptr -> i64
    %1522 = arith.cmpi slt, %1520, %1521 : i64
    cf.cond_br %1522, ^bb127, ^bb128
    ^bb127:
      %1523 = func.call @alpha_can_skip_ones() : () -> i1
      cf.cond_br %1523, ^bb129, ^bb130
      ^bb129:
        %1524 = llvm.load %1513 : !llvm.ptr -> i64
        %1525 = llvm.load %1508 : !llvm.ptr -> i64
        %1526 = arith.subi %1524, %1525 : i64
        %1527 = llvm.mlir.addressof @alpha_ones_left : !llvm.ptr
        %1528 = llvm.load %1527 : !llvm.ptr -> i64
        %1530 = llvm.load %1500 : !llvm.ptr -> i64
        func.call @consume_ones_with_limit(%1530, %1528, %1526) : (i64, i64, i64) -> ()
        %1531 = llvm.mlir.addressof @g_consumed : !llvm.ptr
        %1532 = llvm.load %1531 : !llvm.ptr -> i64
        %1533 = arith.constant 0 : i32
        %1535 = arith.extsi %1533 : i32 to i64
        %1534 = arith.cmpi eq, %1532, %1535 : i64
        cf.cond_br %1534, ^bb132, ^bb133
        ^bb132:
          cf.br ^bb128
        ^bb133:
          cf.br ^bb134
        ^bb134:
        %1537 = llvm.mlir.addressof @g_consumed : !llvm.ptr
        %1538 = llvm.load %1537 : !llvm.ptr -> i64
        func.call @alpha_skip_ones(%1538) : (i64) -> ()
        %1539 = llvm.load %1508 : !llvm.ptr -> i64
        %1540 = llvm.mlir.addressof @g_emitted_c : !llvm.ptr
        %1541 = llvm.load %1540 : !llvm.ptr -> i64
        %1542 = arith.addi %1539, %1541 : i64
        llvm.store %1542, %1508 : i64, !llvm.ptr
        %1543 = llvm.load %1504 : !llvm.ptr -> i64
        %1544 = llvm.mlir.addressof @g_emitted_s : !llvm.ptr
        %1545 = llvm.load %1544 : !llvm.ptr -> i64
        %1546 = arith.addi %1543, %1545 : i64
        llvm.store %1546, %1504 : i64, !llvm.ptr
        %1547 = llvm.mlir.addressof @g_new_state : !llvm.ptr
        %1548 = llvm.load %1547 : !llvm.ptr -> i64
        llvm.store %1548, %1500 : i64, !llvm.ptr
        %1549 = llvm.mlir.addressof @g_consumed : !llvm.ptr
        %1550 = llvm.load %1549 : !llvm.ptr -> i64
        %1551 = arith.cmpi slt, %1550, %1528 : i64
        cf.cond_br %1551, ^bb135, ^bb136
        ^bb135:
          cf.br ^bb128
        ^bb136:
          cf.br ^bb137
        ^bb137:
        cf.br ^bb131
      ^bb130:
        %1553 = llvm.mlir.addressof @cnt2_arr : !llvm.ptr
        %1554 = llvm.load %1553 : !llvm.ptr -> !llvm.ptr
        %1555 = llvm.load %1500 : !llvm.ptr -> i64
        %1556 = llvm.getelementptr %1554[%1555] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1552 = llvm.load %1556 : !llvm.ptr -> i64
        %1557 = llvm.load %1508 : !llvm.ptr -> i64
        %1558 = arith.addi %1557, %1552 : i64
        %1559 = llvm.load %1513 : !llvm.ptr -> i64
        %1560 = arith.cmpi sgt, %1558, %1559 : i64
        cf.cond_br %1560, ^bb138, ^bb139
        ^bb138:
          cf.br ^bb128
        ^bb139:
          cf.br ^bb140
        ^bb140:
        %1561 = llvm.load %1504 : !llvm.ptr -> i64
        %1563 = llvm.mlir.addressof @sum2_arr : !llvm.ptr
        %1564 = llvm.load %1563 : !llvm.ptr -> !llvm.ptr
        %1565 = llvm.load %1500 : !llvm.ptr -> i64
        %1566 = llvm.getelementptr %1564[%1565] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1562 = llvm.load %1566 : !llvm.ptr -> i64
        %1567 = arith.addi %1561, %1562 : i64
        llvm.store %1567, %1504 : i64, !llvm.ptr
        %1568 = llvm.load %1508 : !llvm.ptr -> i64
        %1569 = arith.addi %1568, %1552 : i64
        llvm.store %1569, %1508 : i64, !llvm.ptr
        %1571 = llvm.mlir.addressof @next2_arr : !llvm.ptr
        %1572 = llvm.load %1571 : !llvm.ptr -> !llvm.ptr
        %1573 = llvm.load %1500 : !llvm.ptr -> i64
        %1574 = llvm.getelementptr %1572[%1573] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1570 = llvm.load %1574 : !llvm.ptr -> i32
        %1575 = arith.extsi %1570 : i32 to i64
        llvm.store %1575, %1500 : i64, !llvm.ptr
        %1576 = func.call @alpha_next() : () -> i64
        cf.br ^bb131
      ^bb131:
      cf.br ^bb126
    ^bb128:
    cf.br ^bb141
    ^bb141:
    %1577 = llvm.load %1508 : !llvm.ptr -> i64
    %1578 = arith.cmpi slt, %1577, %1495 : i64
    cf.cond_br %1578, ^bb142, ^bb143
    ^bb142:
      %1579 = func.call @alpha_next() : () -> i64
      %1580 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %1582 = llvm.mlir.addressof @st_A : !llvm.ptr
      %1583 = llvm.load %1582 : !llvm.ptr -> !llvm.ptr
      %1584 = llvm.load %1500 : !llvm.ptr -> i64
      %1585 = llvm.getelementptr %1583[%1584] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1581 = llvm.load %1585 : !llvm.ptr -> i64
      %1586 = llvm.insertvalue %1581, %1580[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1588 = llvm.mlir.addressof @st_B : !llvm.ptr
      %1589 = llvm.load %1588 : !llvm.ptr -> !llvm.ptr
      %1590 = llvm.load %1500 : !llvm.ptr -> i64
      %1591 = llvm.getelementptr %1589[%1590] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1587 = llvm.load %1591 : !llvm.ptr -> i64
      %1592 = llvm.insertvalue %1587, %1586[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1594 = llvm.mlir.addressof @st_C : !llvm.ptr
      %1595 = llvm.load %1594 : !llvm.ptr -> !llvm.ptr
      %1596 = llvm.load %1500 : !llvm.ptr -> i64
      %1597 = llvm.getelementptr %1595[%1596] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1593 = llvm.load %1597 : !llvm.ptr -> i64
      %1598 = llvm.insertvalue %1593, %1592[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1600 = llvm.mlir.addressof @st_D : !llvm.ptr
      %1601 = llvm.load %1600 : !llvm.ptr -> !llvm.ptr
      %1602 = llvm.load %1500 : !llvm.ptr -> i64
      %1603 = llvm.getelementptr %1601[%1602] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1599 = llvm.load %1603 : !llvm.ptr -> i64
      %1604 = llvm.insertvalue %1599, %1598[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1605 = llvm.mlir.constant(1 : i64) : i64
      %1606 = llvm.alloca %1605 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %1604, %1606 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1608 = llvm.load %1606 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %1609 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %1610 = llvm.extractvalue %1608[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1611 = llvm.insertvalue %1610, %1609[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1612 = llvm.extractvalue %1608[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1613 = llvm.insertvalue %1612, %1611[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1614 = llvm.extractvalue %1608[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1615 = llvm.insertvalue %1614, %1613[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1616 = llvm.extractvalue %1608[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1617 = llvm.insertvalue %1616, %1615[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1607 = func.call @step_transition(%1617, %1579) : (!llvm.struct<(i64, i64, i64, i64)>, i64) -> !llvm.struct<(i64, i64, i64, i64)>
      %1618 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %1619 = llvm.extractvalue %1607[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1620 = llvm.insertvalue %1619, %1618[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1621 = llvm.extractvalue %1607[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1622 = llvm.insertvalue %1621, %1620[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1623 = llvm.extractvalue %1607[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1624 = llvm.insertvalue %1623, %1622[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1625 = llvm.extractvalue %1607[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1626 = llvm.insertvalue %1625, %1624[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1627 = llvm.mlir.constant(1 : i64) : i64
      %1628 = llvm.alloca %1627 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %1626, %1628 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1629 = llvm.load %1628 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %1630 = llvm.mlir.undef : !llvm.struct<(i64, i64, i64, i64)>
      %1631 = llvm.extractvalue %1617[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1632 = llvm.insertvalue %1631, %1630[0] : !llvm.struct<(i64, i64, i64, i64)>
      %1633 = llvm.extractvalue %1617[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1634 = llvm.insertvalue %1633, %1632[1] : !llvm.struct<(i64, i64, i64, i64)>
      %1635 = llvm.extractvalue %1617[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1636 = llvm.insertvalue %1635, %1634[2] : !llvm.struct<(i64, i64, i64, i64)>
      %1637 = llvm.extractvalue %1617[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1638 = llvm.insertvalue %1637, %1636[3] : !llvm.struct<(i64, i64, i64, i64)>
      %1639 = llvm.mlir.constant(1 : i64) : i64
      %1640 = llvm.alloca %1639 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %1638, %1640 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1641 = llvm.load %1640 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      llvm.store %1641, %1606 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1642 = llvm.mlir.constant(1 : i64) : i64
      %1643 = llvm.alloca %1642 x !llvm.struct<(i64, i64, i64, i64)> : (i64) -> !llvm.ptr
      llvm.store %1629, %1643 : !llvm.struct<(i64, i64, i64, i64)>, !llvm.ptr
      %1645 = llvm.load %1643 : !llvm.ptr -> !llvm.struct<(i64, i64, i64, i64)>
      %1644 = func.call @state_find(%1645) : (!llvm.struct<(i64, i64, i64, i64)>) -> i64
      llvm.store %1644, %1500 : i64, !llvm.ptr
      %1646 = arith.constant 0 : i32
      %1647 = arith.extsi %1646 : i32 to i64
      %1648 = llvm.mlir.constant(1 : i64) : i64
      %1649 = llvm.alloca %1648 x i64 : (i64) -> !llvm.ptr
      llvm.store %1647, %1649 : i64, !llvm.ptr
      cf.br ^bb144
      ^bb144:
      %1650 = llvm.load %1649 : !llvm.ptr -> i64
      %1651 = llvm.mlir.addressof @g_n_outs : !llvm.ptr
      %1652 = llvm.load %1651 : !llvm.ptr -> i64
      %1653 = arith.cmpi slt, %1650, %1652 : i64
      cf.cond_br %1653, ^bb145, ^bb146
      ^bb145:
        %1654 = llvm.load %1508 : !llvm.ptr -> i64
        %1655 = arith.cmpi sge, %1654, %1495 : i64
        cf.cond_br %1655, ^bb147, ^bb148
        ^bb147:
          cf.br ^bb146
        ^bb148:
          cf.br ^bb149
        ^bb149:
        %1656 = llvm.load %1504 : !llvm.ptr -> i64
        %1658 = llvm.mlir.addressof @g_outs : !llvm.ptr
        %1659 = llvm.load %1658 : !llvm.ptr -> !llvm.ptr
        %1660 = llvm.load %1649 : !llvm.ptr -> i64
        %1661 = llvm.getelementptr %1659[%1660] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1657 = llvm.load %1661 : !llvm.ptr -> i64
        %1662 = arith.addi %1656, %1657 : i64
        llvm.store %1662, %1504 : i64, !llvm.ptr
        %1663 = llvm.load %1508 : !llvm.ptr -> i64
        %1664 = arith.constant 1 : i32
        %1666 = arith.extsi %1664 : i32 to i64
        %1665 = arith.addi %1663, %1666 : i64
        llvm.store %1665, %1508 : i64, !llvm.ptr
        %1667 = llvm.load %1649 : !llvm.ptr -> i64
        %1668 = arith.constant 1 : i32
        %1670 = arith.extsi %1668 : i32 to i64
        %1669 = arith.addi %1667, %1670 : i64
        llvm.store %1669, %1649 : i64, !llvm.ptr
        cf.br ^bb144
      ^bb146:
      cf.br ^bb141
    ^bb143:
    %1671 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %1672 = llvm.load %1504 : !llvm.ptr -> i64
    %1673 = llvm.call @printf(%1671, %1672) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %1675 = llvm.mlir.addressof @st_A : !llvm.ptr
    %1676 = llvm.load %1675 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1676) : (!llvm.ptr) -> ()
    %1678 = llvm.mlir.addressof @st_B : !llvm.ptr
    %1679 = llvm.load %1678 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1679) : (!llvm.ptr) -> ()
    %1681 = llvm.mlir.addressof @st_C : !llvm.ptr
    %1682 = llvm.load %1681 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1682) : (!llvm.ptr) -> ()
    %1684 = llvm.mlir.addressof @st_D : !llvm.ptr
    %1685 = llvm.load %1684 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1685) : (!llvm.ptr) -> ()
    %1687 = llvm.mlir.addressof @st_ids : !llvm.ptr
    %1688 = llvm.load %1687 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1688) : (!llvm.ptr) -> ()
    %1690 = llvm.mlir.addressof @next1_arr : !llvm.ptr
    %1691 = llvm.load %1690 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1691) : (!llvm.ptr) -> ()
    %1693 = llvm.mlir.addressof @next2_arr : !llvm.ptr
    %1694 = llvm.load %1693 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1694) : (!llvm.ptr) -> ()
    %1696 = llvm.mlir.addressof @cnt1_arr : !llvm.ptr
    %1697 = llvm.load %1696 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1697) : (!llvm.ptr) -> ()
    %1699 = llvm.mlir.addressof @sum1_arr : !llvm.ptr
    %1700 = llvm.load %1699 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1700) : (!llvm.ptr) -> ()
    %1702 = llvm.mlir.addressof @cnt2_arr : !llvm.ptr
    %1703 = llvm.load %1702 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1703) : (!llvm.ptr) -> ()
    %1705 = llvm.mlir.addressof @sum2_arr : !llvm.ptr
    %1706 = llvm.load %1705 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1706) : (!llvm.ptr) -> ()
    %1708 = llvm.mlir.addressof @pow_next_arr : !llvm.ptr
    %1709 = llvm.load %1708 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1709) : (!llvm.ptr) -> ()
    %1711 = llvm.mlir.addressof @pow_cnt_arr : !llvm.ptr
    %1712 = llvm.load %1711 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1712) : (!llvm.ptr) -> ()
    %1714 = llvm.mlir.addressof @pow_sum_arr : !llvm.ptr
    %1715 = llvm.load %1714 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1715) : (!llvm.ptr) -> ()
    %1717 = llvm.mlir.addressof @g_outs : !llvm.ptr
    %1718 = llvm.load %1717 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1718) : (!llvm.ptr) -> ()
    %1720 = llvm.mlir.addressof @primes_arr : !llvm.ptr
    %1721 = llvm.load %1720 : !llvm.ptr -> !llvm.ptr
    func.call @free(%1721) : (!llvm.ptr) -> ()
    %1722 = arith.constant 0 : i32
    func.return %1722 : i32
  }
}