Problem 949

Ported from native C to pure Flow. Compute G(20, 7, 1001001011). Binary tree DP, histograms, convolution, pair counting.

Answer726010935
Output726010935
StatusPASS
Native helperno
Runtime8280 ms
Peak memory69136 KB
Time complexityO(n^3) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^3)?
Space complexityO(n^2)?
ApproachFlow solutionNot curated
VerdictUnknown

Flow source

# Project Euler 949
# Ported from native C to pure Flow.
# Compute G(20, 7, 1001001011).
# Binary tree DP, histograms, convolution, pair counting.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
    function malloc(n: i64) -> ptr<void>
}

const MOD: i64 = 1001001011
const NEG_INF: i64 = -1000000000000
const POS_INF: i64 = 1000000000000

struct Histogram {
    val: ptr<i64>,
    cnt: ptr<i64>,
    size: i64,
    cap: i64
}

# Global arrays for compute_u_hot
let mut u_full_arr: ptr<i64> = null
let mut hot_arr: ptr<i32> = null

function ceil_div_pow2(x: i64, s: i64) -> i64 {
    if s == 0 {
        return x
    }
    let d: i64 = 1 << s
    if x >= 0 {
        return (x + d - 1) >> s
    }
    return 0 - ((0 - x) >> s)
}

function safe_shl(val: i64, amt: i64) -> i64 {
    if val >= 0 {
        return val << amt
    }
    return 0 - ((0 - val) << amt)
}

function simplest_between(u: i64, d: i64, e: i64) -> i64 {
    let mut m: i64 = 0
    while m <= e {
        let s: i64 = e - m
        let p_min: i64 = (u >> s) + 1
        let p_max: i64 = ceil_div_pow2(d, s) - 1
        if p_min <= p_max {
            let mut p: i64 = 0
            if p_min > 0 {
                p = p_min
            } else {
                if p_max < 0 {
                    p = p_max
                } else {
                    p = 0
                }
            }
            if m > 0 && p != 0 && (p & 1) == 0 {
                if p + 1 <= p_max && ((p + 1) & 1) != 0 {
                    p = p + 1
                } else {
                    if p - 1 >= p_min && ((p - 1) & 1) != 0 {
                        p = p - 1
                    }
                }
            }
            return safe_shl(p, s)
        }
        m = m + 1
    }
    return 0
}

function compute_u_hot(n: i64) -> void {
    let e: i64 = n
    let scale: i64 = 1 << e
    let total: i64 = (1 << (n + 1)) - 1

    let dp_u: ptr<i64> = calloc(total, 8) as ptr<i64>
    let dp_d: ptr<i64> = calloc(total, 8) as ptr<i64>

    # Root's children at index 1, 2
    dp_u[1] = scale
    dp_d[1] = scale
    dp_u[2] = 0 - scale
    dp_d[2] = 0 - scale

    u_full_arr = calloc(1 << n, 8) as ptr<i64>
    hot_arr = calloc(1 << n, 4) as ptr<i32>

    let mut length: i64 = 2
    while length <= n {
        let size: i64 = 1 << length
        let start: i64 = (1 << length) - 1

        let mut bits: i64 = 0
        while bits < size {
            # u_raw = max over suffixes of dp_d
            let mut u_raw: i64 = NEG_INF
            let mut s_len: i64 = 1
            while s_len < length {
                let suf: i64 = bits & ((1 << s_len) - 1)
                let cand: i64 = dp_d[(1 << s_len) - 1 + suf]
                if cand > u_raw {
                    u_raw = cand
                }
                s_len = s_len + 1
            }

            # d_raw = min over prefixes of dp_u
            let mut d_raw: i64 = POS_INF
            let mut p_len: i64 = 1
            while p_len < length {
                let pre: i64 = bits >> (length - p_len)
                let cand: i64 = dp_u[(1 << p_len) - 1 + pre]
                if cand < d_raw {
                    d_raw = cand
                }
                p_len = p_len + 1
            }

            let idx: i64 = start + bits
            if u_raw < d_raw {
                let x: i64 = simplest_between(u_raw, d_raw, e)
                dp_u[idx] = x
                dp_d[idx] = x
                if length == n {
                    u_full_arr[bits] = x
                    hot_arr[bits] = 0
                }
            } else {
                dp_u[idx] = u_raw
                dp_d[idx] = d_raw
                if length == n {
                    u_full_arr[bits] = u_raw
                    hot_arr[bits] = 1
                }
            }
            bits = bits + 1
        }
        length = length + 1
    }

    free(dp_u as ptr<void>)
    free(dp_d as ptr<void>)
}

# ---- Histogram operations ----

function hist_init() -> Histogram {
    let cap: i64 = 16
    let val: ptr<i64> = malloc(cap * 8) as ptr<i64>
    let cnt: ptr<i64> = malloc(cap * 8) as ptr<i64>
    return Histogram { val: val, cnt: cnt, size: 0, cap: cap }
}

function hist_free(h: Histogram) -> void {
    free(h.val as ptr<void>)
    free(h.cnt as ptr<void>)
}

function hist_find(h: Histogram, val: i64) -> i64 {
    let mut lo: i64 = 0
    let mut hi: i64 = h.size
    while lo < hi {
        let mid: i64 = lo + (hi - lo) / 2
        if h.val[mid] < val {
            lo = mid + 1
        } else {
            hi = mid
        }
    }
    if lo < h.size && h.val[lo] == val {
        return lo
    }
    return -1
}

function hist_resize(h: Histogram) -> Histogram {
    let new_cap: i64 = h.cap * 2
    let new_val: ptr<i64> = malloc(new_cap * 8) as ptr<i64>
    let new_cnt: ptr<i64> = malloc(new_cap * 8) as ptr<i64>
    let mut i: i64 = 0
    while i < h.size {
        new_val[i] = h.val[i]
        new_cnt[i] = h.cnt[i]
        i = i + 1
    }
    free(h.val as ptr<void>)
    free(h.cnt as ptr<void>)
    return Histogram { val: new_val, cnt: new_cnt, size: h.size, cap: new_cap }
}

function hist_insert_sorted(h0: Histogram, val: i64, cnt: i64) -> Histogram {
    if cnt == 0 {
        return h0
    }
    let mut h: Histogram = h0
    let pos: i64 = hist_find(h, val)
    if pos >= 0 {
        h.cnt[pos] = (h.cnt[pos] + cnt) % MOD
        if h.cnt[pos] == 0 {
            # Remove zero entry by shifting
            let mut i: i64 = pos
            while i < h.size - 1 {
                h.val[i] = h.val[i + 1]
                h.cnt[i] = h.cnt[i + 1]
                i = i + 1
            }
            h.size = h.size - 1
        }
        return h
    }
    # Insert at sorted position
    let mut lo: i64 = 0
    let mut hi: i64 = h.size
    while lo < hi {
        let mid: i64 = lo + (hi - lo) / 2
        if h.val[mid] < val {
            lo = mid + 1
        } else {
            hi = mid
        }
    }
    if h.size >= h.cap {
        h = hist_resize(h)
    }
    # Shift elements right
    let mut i: i64 = h.size
    while i > lo {
        h.val[i] = h.val[i - 1]
        h.cnt[i] = h.cnt[i - 1]
        i = i - 1
    }
    h.val[lo] = val
    h.cnt[lo] = cnt % MOD
    if h.cnt[lo] == 0 {
        return h
    }
    h.size = h.size + 1
    return h
}

function hist_from_values(values: ptr<i64>, n: i64) -> Histogram {
    let mut h: Histogram = hist_init()
    let mut i: i64 = 0
    while i < n {
        let pos: i64 = hist_find(h, values[i])
        if pos >= 0 {
            h.cnt[pos] = (h.cnt[pos] + 1) % MOD
            if h.cnt[pos] == 0 {
                let mut j: i64 = pos
                while j < h.size - 1 {
                    h.val[j] = h.val[j + 1]
                    h.cnt[j] = h.cnt[j + 1]
                    j = j + 1
                }
                h.size = h.size - 1
            }
        } else {
            h = hist_insert_sorted(h, values[i], 1)
        }
        i = i + 1
    }
    return h
}

function hist_convolve(a: Histogram, b: Histogram) -> Histogram {
    let mut out: Histogram = hist_init()

    # Iterate over smaller
    let mut smaller: Histogram = a
    let mut larger: Histogram = b
    if a.size > b.size {
        smaller = b
        larger = a
    }

    let mut i: i64 = 0
    while i < smaller.size {
        let mut j: i64 = 0
        while j < larger.size {
            let key: i64 = smaller.val[i] + larger.val[j]
            let cnt: i64 = (((smaller.cnt[i] as i128) * (larger.cnt[j] as i128)) % (MOD as i128)) as i64
            out = hist_insert_sorted(out, key, cnt)
            j = j + 1
        }
        i = i + 1
    }
    return out
}

function hist_pow(h: Histogram, t: i64) -> Histogram {
    if t == 0 {
        let r: Histogram = hist_init()
        return hist_insert_sorted(r, 0, 1)
    }
    let mut result: Histogram = hist_init()
    let mut i: i64 = 0
    while i < h.size {
        result = hist_insert_sorted(result, h.val[i], h.cnt[i])
        i = i + 1
    }

    let mut step: i64 = 1
    while step < t {
        let next: Histogram = hist_convolve(result, h)
        hist_free(result)
        result = next
        step = step + 1
    }
    return result
}

function count_sum_lt_zero(a: Histogram, b: Histogram) -> i64 {
    let b_sums: ptr<i64> = malloc(b.size * 8) as ptr<i64>
    let pref: ptr<i64> = malloc((b.size + 1) * 8) as ptr<i64>

    let mut i: i64 = 0
    while i < b.size {
        b_sums[i] = b.val[i]
        i = i + 1
    }
    pref[0] = 0
    i = 0
    while i < b.size {
        pref[i + 1] = (pref[i] + b.cnt[i]) % MOD
        i = i + 1
    }

    let mut ans: i64 = 0
    i = 0
    while i < a.size {
        let sa: i64 = a.val[i]
        let ca: i64 = a.cnt[i]
        # bisect_left for -sa in b_sums
        let mut lo: i64 = 0
        let mut hi: i64 = b.size
        while lo < hi {
            let mid: i64 = lo + (hi - lo) / 2
            if b_sums[mid] < 0 - sa {
                lo = mid + 1
            } else {
                hi = mid
            }
        }
        ans = (ans + (((ca as i128) * (pref[lo] as i128)) % (MOD as i128))) as i64
        i = i + 1
    }

    free(b_sums as ptr<void>)
    free(pref as ptr<void>)
    return ans
}

function count_sum_eq_zero(a: Histogram, b: Histogram) -> i64 {
    let mut smaller: Histogram = a
    let mut larger: Histogram = b
    if a.size > b.size {
        smaller = b
        larger = a
    }

    let mut ans: i64 = 0
    let mut i: i64 = 0
    while i < smaller.size {
        let s: i64 = smaller.val[i]
        let ca: i64 = smaller.cnt[i]
        let pos: i64 = hist_find(larger, 0 - s)
        if pos >= 0 {
            ans = (ans + (((ca as i128) * (larger.cnt[pos] as i128)) % (MOD as i128))) as i64
        }
        i = i + 1
    }
    return ans
}

function main() -> i32 {
    let n: i64 = 20
    let k: i64 = 7

    compute_u_hot(n)

    let total: i64 = 1 << n

    # u_hist from all u_full values
    let u_hist: Histogram = hist_from_values(u_full_arr, total)

    # cold_hist from cold values only
    let cold_values: ptr<i64> = malloc(total * 8) as ptr<i64>
    let mut n_cold: i64 = 0
    let mut i: i64 = 0
    while i < total {
        if hot_arr[i] == 0 {
            cold_values[n_cold] = u_full_arr[i]
            n_cold = n_cold + 1
        }
        i = i + 1
    }
    let cold_hist: Histogram = hist_from_values(cold_values, n_cold)

    let a_pow: i64 = k / 2
    let b_pow: i64 = k - a_pow

    let dist_a: Histogram = hist_pow(u_hist, a_pow)
    let dist_b: Histogram = hist_pow(u_hist, b_pow)

    let neg: i64 = count_sum_lt_zero(dist_a, dist_b)

    let cold_a: Histogram = hist_pow(cold_hist, a_pow)
    let cold_b: Histogram = hist_pow(cold_hist, b_pow)

    let zero_cold: i64 = count_sum_eq_zero(cold_a, cold_b)

    let mut result: i64 = (neg + zero_cold) % MOD
    if result < 0 {
        result = result + MOD
    }

    printf("%lld\n", result)

    # Cleanup
    hist_free(u_hist)
    hist_free(cold_hist)
    hist_free(dist_a)
    hist_free(dist_b)
    hist_free(cold_a)
    hist_free(cold_b)
    free(cold_values as ptr<void>)
    free(u_full_arr as ptr<void>)
    free(hot_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 Histogram Histogram;

struct Histogram {
    int64_t* val;
    int64_t* cnt;
    int64_t size;
    int64_t cap;
};

int64_t ceil_div_pow2_i64_i64(int64_t x, int64_t s);
int64_t safe_shl_i64_i64(int64_t val, int64_t amt);
int64_t simplest_between_i64_i64_i64(int64_t u, int64_t d, int64_t e);
void compute_u_hot_i64(int64_t n);
Histogram hist_init(void);
void hist_free_Histogram(Histogram h);
int64_t hist_find_Histogram_i64(Histogram h, int64_t val);
Histogram hist_resize_Histogram(Histogram h);
Histogram hist_insert_sorted_Histogram_i64_i64(Histogram h0, int64_t val, int64_t cnt);
Histogram hist_from_values_ptr_i64_i64(int64_t* values, int64_t n);
Histogram hist_convolve_Histogram_Histogram(Histogram a, Histogram b);
Histogram hist_pow_Histogram_i64(Histogram h, int64_t t);
int64_t count_sum_lt_zero_Histogram_Histogram(Histogram a, Histogram b);
int64_t count_sum_eq_zero_Histogram_Histogram(Histogram a, Histogram b);
int32_t main(void);

static const int64_t MOD = 1001001011;
static const int64_t NEG_INF = (-1000000000000);
static const int64_t POS_INF = 1000000000000;

/* Module statics */
static int64_t* u_full_arr = NULL;
static int32_t* hot_arr = NULL;




int64_t ceil_div_pow2_i64_i64(int64_t x, int64_t s) {
    if (s == 0) {
        return x;
    }
    int64_t d = FLOW_CHECKED_SHL((1), (s));
    if (x >= 0) {
        return FLOW_CHECKED_SHR((((x + d) - 1)), (s));
    }
    return (0 - FLOW_CHECKED_SHR(((0 - x)), (s)));
}

int64_t safe_shl_i64_i64(int64_t val, int64_t amt) {
    if (val >= 0) {
        return FLOW_CHECKED_SHL((val), (amt));
    }
    return (0 - FLOW_CHECKED_SHL(((0 - val)), (amt)));
}

int64_t simplest_between_i64_i64_i64(int64_t u, int64_t d, int64_t e) {
    int64_t m = 0;
    while (m <= e) {
        int64_t s = (e - m);
        int64_t p_min = (FLOW_CHECKED_SHR((u), (s)) + 1);
        int64_t p_max = (ceil_div_pow2_i64_i64(d, s) - 1);
        if (p_min <= p_max) {
            int64_t p = 0;
            if (p_min > 0) {
                p = p_min;
            } else {
                if (p_max < 0) {
                    p = p_max;
                } else {
                    p = 0;
                }
            }
            if (((m > 0 && p != 0) && (p & 1) == 0)) {
                if (((p + 1) <= p_max && ((p + 1) & 1) != 0)) {
                    p = (p + 1);
                } else {
                    if (((p - 1) >= p_min && ((p - 1) & 1) != 0)) {
                        p = (p - 1);
                    }
                }
            }
            return safe_shl_i64_i64(p, s);
        }
        m = (m + 1);
    }
    return 0;
}

void compute_u_hot_i64(int64_t n) {
    int64_t e = n;
    int64_t scale = FLOW_CHECKED_SHL((1), (e));
    int64_t total = (FLOW_CHECKED_SHL((1), ((n + 1))) - 1);
    int64_t* dp_u = (int64_t*)(((int64_t*)(calloc(total, 8))));
    int64_t* dp_d = (int64_t*)(((int64_t*)(calloc(total, 8))));
    dp_u[1] = scale;
    dp_d[1] = scale;
    dp_u[2] = (0 - scale);
    dp_d[2] = (0 - scale);
    u_full_arr = ((int64_t*)(calloc(FLOW_CHECKED_SHL((1), (n)), 8)));
    hot_arr = ((int32_t*)(calloc(FLOW_CHECKED_SHL((1), (n)), 4)));
    int64_t length = 2;
    while (length <= n) {
        int64_t size = FLOW_CHECKED_SHL((1), (length));
        int64_t start = (FLOW_CHECKED_SHL((1), (length)) - 1);
        int64_t bits = 0;
        while (bits < size) {
            int64_t u_raw = NEG_INF;
            int64_t s_len = 1;
            while (s_len < length) {
                int64_t suf = (bits & (FLOW_CHECKED_SHL((1), (s_len)) - 1));
                int64_t cand = dp_d[((FLOW_CHECKED_SHL((1), (s_len)) - 1) + suf)];
                if (cand > u_raw) {
                    u_raw = cand;
                }
                s_len = (s_len + 1);
            }
            int64_t d_raw = POS_INF;
            int64_t p_len = 1;
            while (p_len < length) {
                int64_t pre = FLOW_CHECKED_SHR((bits), ((length - p_len)));
                int64_t cand = dp_u[((FLOW_CHECKED_SHL((1), (p_len)) - 1) + pre)];
                if (cand < d_raw) {
                    d_raw = cand;
                }
                p_len = (p_len + 1);
            }
            int64_t idx = (start + bits);
            if (u_raw < d_raw) {
                int64_t x = simplest_between_i64_i64_i64(u_raw, d_raw, e);
                dp_u[idx] = x;
                dp_d[idx] = x;
                if (length == n) {
                    u_full_arr[bits] = x;
                    hot_arr[bits] = 0;
                }
            } else {
                dp_u[idx] = u_raw;
                dp_d[idx] = d_raw;
                if (length == n) {
                    u_full_arr[bits] = u_raw;
                    hot_arr[bits] = 1;
                }
            }
            bits = (bits + 1);
        }
        length = (length + 1);
    }
    free(((void*)(dp_u)));
    free(((void*)(dp_d)));
}

Histogram hist_init(void) {
    int64_t cap = 16;
    int64_t* val = (int64_t*)(((int64_t*)(malloc((cap * 8)))));
    int64_t* cnt = (int64_t*)(((int64_t*)(malloc((cap * 8)))));
    return (Histogram){ .val = val, .cnt = cnt, .size = 0, .cap = cap };
}

void hist_free_Histogram(Histogram h) {
    free(((void*)(h.val)));
    free(((void*)(h.cnt)));
}

int64_t hist_find_Histogram_i64(Histogram h, int64_t val) {
    int64_t lo = 0;
    int64_t hi = h.size;
    while (lo < hi) {
        int64_t mid = (lo + FLOW_CHECKED_DIV(((hi - lo)), (2)));
        if (h.val[mid] < val) {
            lo = (mid + 1);
        } else {
            hi = mid;
        }
    }
    if ((lo < h.size && h.val[lo] == val)) {
        return lo;
    }
    return (-1);
}

Histogram hist_resize_Histogram(Histogram h) {
    int64_t new_cap = (h.cap * 2);
    int64_t* new_val = (int64_t*)(((int64_t*)(malloc((new_cap * 8)))));
    int64_t* new_cnt = (int64_t*)(((int64_t*)(malloc((new_cap * 8)))));
    int64_t i = 0;
    while (i < h.size) {
        new_val[i] = h.val[i];
        new_cnt[i] = h.cnt[i];
        i = (i + 1);
    }
    free(((void*)(h.val)));
    free(((void*)(h.cnt)));
    return (Histogram){ .val = new_val, .cnt = new_cnt, .size = h.size, .cap = new_cap };
}

Histogram hist_insert_sorted_Histogram_i64_i64(Histogram h0, int64_t val, int64_t cnt) {
    if (cnt == 0) {
        return h0;
    }
    Histogram h = h0;
    int64_t pos = hist_find_Histogram_i64(h, val);
    if (pos >= 0) {
        h.cnt[pos] = FLOW_CHECKED_MOD(((h.cnt[pos] + cnt)), (MOD));
        if (h.cnt[pos] == 0) {
            int64_t i = pos;
            while (i < (h.size - 1)) {
                h.val[i] = h.val[(i + 1)];
                h.cnt[i] = h.cnt[(i + 1)];
                i = (i + 1);
            }
            h.size = (h.size - 1);
        }
        return h;
    }
    int64_t lo = 0;
    int64_t hi = h.size;
    while (lo < hi) {
        int64_t mid = (lo + FLOW_CHECKED_DIV(((hi - lo)), (2)));
        if (h.val[mid] < val) {
            lo = (mid + 1);
        } else {
            hi = mid;
        }
    }
    if (h.size >= h.cap) {
        h = hist_resize_Histogram(h);
    }
    int64_t i = h.size;
    while (i > lo) {
        h.val[i] = h.val[(i - 1)];
        h.cnt[i] = h.cnt[(i - 1)];
        i = (i - 1);
    }
    h.val[lo] = val;
    h.cnt[lo] = FLOW_CHECKED_MOD((cnt), (MOD));
    if (h.cnt[lo] == 0) {
        return h;
    }
    h.size = (h.size + 1);
    return h;
}

Histogram hist_from_values_ptr_i64_i64(int64_t* values, int64_t n) {
    Histogram h = hist_init();
    int64_t i = 0;
    while (i < n) {
        int64_t pos = hist_find_Histogram_i64(h, values[i]);
        if (pos >= 0) {
            h.cnt[pos] = FLOW_CHECKED_MOD(((h.cnt[pos] + 1)), (MOD));
            if (h.cnt[pos] == 0) {
                int64_t j = pos;
                while (j < (h.size - 1)) {
                    h.val[j] = h.val[(j + 1)];
                    h.cnt[j] = h.cnt[(j + 1)];
                    j = (j + 1);
                }
                h.size = (h.size - 1);
            }
        } else {
            h = hist_insert_sorted_Histogram_i64_i64(h, values[i], 1);
        }
        i = (i + 1);
    }
    return h;
}

Histogram hist_convolve_Histogram_Histogram(Histogram a, Histogram b) {
    Histogram out = hist_init();
    Histogram smaller = a;
    Histogram larger = b;
    if (a.size > b.size) {
        smaller = b;
        larger = a;
    }
    int64_t i = 0;
    while (i < smaller.size) {
        int64_t j = 0;
        while (j < larger.size) {
            int64_t key = (smaller.val[i] + larger.val[j]);
            int64_t cnt = ((int64_t)(FLOW_CHECKED_MOD(((((__int128)(smaller.cnt[i])) * ((__int128)(larger.cnt[j])))), (((__int128)(MOD))))));
            out = hist_insert_sorted_Histogram_i64_i64(out, key, cnt);
            j = (j + 1);
        }
        i = (i + 1);
    }
    return out;
}

Histogram hist_pow_Histogram_i64(Histogram h, int64_t t) {
    if (t == 0) {
        Histogram r = hist_init();
        return hist_insert_sorted_Histogram_i64_i64(r, 0, 1);
    }
    Histogram result = hist_init();
    int64_t i = 0;
    while (i < h.size) {
        result = hist_insert_sorted_Histogram_i64_i64(result, h.val[i], h.cnt[i]);
        i = (i + 1);
    }
    int64_t step = 1;
    while (step < t) {
        Histogram next = hist_convolve_Histogram_Histogram(result, h);
        hist_free_Histogram(result);
        result = next;
        step = (step + 1);
    }
    return result;
}

int64_t count_sum_lt_zero_Histogram_Histogram(Histogram a, Histogram b) {
    int64_t* b_sums = (int64_t*)(((int64_t*)(malloc((b.size * 8)))));
    int64_t* pref = (int64_t*)(((int64_t*)(malloc(((b.size + 1) * 8)))));
    int64_t i = 0;
    while (i < b.size) {
        b_sums[i] = b.val[i];
        i = (i + 1);
    }
    pref[0] = 0;
    i = 0;
    while (i < b.size) {
        pref[(i + 1)] = FLOW_CHECKED_MOD(((pref[i] + b.cnt[i])), (MOD));
        i = (i + 1);
    }
    int64_t ans = 0;
    i = 0;
    while (i < a.size) {
        int64_t sa = a.val[i];
        int64_t ca = a.cnt[i];
        int64_t lo = 0;
        int64_t hi = b.size;
        while (lo < hi) {
            int64_t mid = (lo + FLOW_CHECKED_DIV(((hi - lo)), (2)));
            if (b_sums[mid] < (0 - sa)) {
                lo = (mid + 1);
            } else {
                hi = mid;
            }
        }
        ans = ((int64_t)((ans + FLOW_CHECKED_MOD(((((__int128)(ca)) * ((__int128)(pref[lo])))), (((__int128)(MOD)))))));
        i = (i + 1);
    }
    free(((void*)(b_sums)));
    free(((void*)(pref)));
    return ans;
}

int64_t count_sum_eq_zero_Histogram_Histogram(Histogram a, Histogram b) {
    Histogram smaller = a;
    Histogram larger = b;
    if (a.size > b.size) {
        smaller = b;
        larger = a;
    }
    int64_t ans = 0;
    int64_t i = 0;
    while (i < smaller.size) {
        int64_t s = smaller.val[i];
        int64_t ca = smaller.cnt[i];
        int64_t pos = hist_find_Histogram_i64(larger, (0 - s));
        if (pos >= 0) {
            ans = ((int64_t)((ans + FLOW_CHECKED_MOD(((((__int128)(ca)) * ((__int128)(larger.cnt[pos])))), (((__int128)(MOD)))))));
        }
        i = (i + 1);
    }
    return ans;
}

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