Problem 576

Irrational Jumps — piecewise S(l,g,d) merge for max sum.

Answer344457.5871
Output344457.5871
StatusPASS
Native helperno
Runtime2460 ms
Peak memory92720 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

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

Flow source

# Project Euler 576
# Irrational Jumps — piecewise S(l,g,d) merge for max sum.

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

struct Seg {
    ends: ptr<f64>,
    vals: ptr<f64>,
    n: i32
}

function sift_down(arr: ptr<f64>, start: i64, end: i64) -> void {
    let mut root: i64 = start
    while 2 * root + 1 < end {
        let mut child: i64 = 2 * root + 1
        if child + 1 < end {
            if arr[child] < arr[child + 1] {
                child = child + 1
            }
        }
        if arr[root] < arr[child] {
            let tmp: f64 = arr[root]
            arr[root] = arr[child]
            arr[child] = tmp
            root = child
        } else {
            return
        }
    }
}

function sort_doubles(arr: ptr<f64>, n: i64) -> void {
    if n < 2 { return }
    let mut start: i64 = n / 2
    while start > 0 {
        start = start - 1
        sift_down(arr, start, n)
    }
    let mut end: i64 = n
    while end > 1 {
        end = end - 1
        let tmp: f64 = arr[0]
        arr[0] = arr[end]
        arr[end] = tmp
        sift_down(arr, 0, end)
    }
}

function bisect_left(a: ptr<f64>, n: i32, x: f64) -> i32 {
    let mut lo: i32 = 0
    let mut hi: i32 = n
    while lo < hi {
        let mid: i32 = lo + (hi - lo) / 2
        if a[mid] < x {
            lo = mid + 1
        } else {
            hi = mid
        }
    }
    return lo
}

function findp(parent: ptr<i32>, i0: i32) -> i32 {
    let mut i: i32 = i0
    while parent[i] != i {
        parent[i] = parent[parent[i]]
        i = parent[i]
    }
    return i
}

function build_piecewise(l: f64, g: f64) -> Seg {
    let domain_end: f64 = 1.0 - g
    let mut K: i32 = (1.5 / g) as i32
    if K < 10 { K = 10 }

    while true {
        if K > 4000000 {
            return Seg { ends: null, vals: null, n: 0 }
        }
        let starts: ptr<f64> = malloc((K as i64) * 8) as ptr<f64>
        let ends_arr: ptr<f64> = malloc((K as i64) * 8) as ptr<f64>
        let labels: ptr<i32> = malloc((K as i64) * 4) as ptr<i32>
        let nint: i32 = 0
        let endpoints: ptr<f64> = malloc(((2 * K + 2) as i64) * 8) as ptr<f64>
        let nep: i32 = 0
        endpoints[0] = 0.0
        nep = 1
        endpoints[1] = domain_end
        nep = 2

        let mut x: f64 = 0.0
        let mut k: i32 = 1
        while k <= K {
            x = x + l
            x = x - floor(x)
            let s: f64 = x - g
            let e: f64 = x
            if e <= 0.0 || s >= domain_end {
                k = k + 1
                continue
            }
            let mut ss: f64 = s
            let mut ee: f64 = e
            if ss < 0.0 { ss = 0.0 }
            if ee > domain_end { ee = domain_end }
            if ss < ee {
                starts[nint] = ss
                ends_arr[nint] = ee
                labels[nint] = k
                endpoints[nep] = ss
                nep = nep + 1
                endpoints[nep] = ee
                nep = nep + 1
                nint = nint + 1
            }
            k = k + 1
        }

        sort_doubles(endpoints, nep as i64)

        let nu: i32 = 0
        let mut i: i32 = 0
        while i < nep {
            if nu == 0 || endpoints[i] != endpoints[nu - 1] {
                endpoints[nu] = endpoints[i]
                nu = nu + 1
            }
            i = i + 1
        }

        let num_cells: i32 = nu - 1
        let parent: ptr<i32> = malloc(((num_cells + 1) as i64) * 4) as ptr<i32>
        let values: ptr<i32> = calloc(num_cells as i64, 4) as ptr<i32>

        i = 0
        while i <= num_cells {
            parent[i] = i
            i = i + 1
        }

        let mut t: i32 = 0
        while t < nint {
            let bi: i32 = bisect_left(endpoints, nu, starts[t])
            let bj: i32 = bisect_left(endpoints, nu, ends_arr[t])
            let mut idx: i32 = findp(parent, bi)
            while idx < bj {
                values[idx] = labels[t]
                parent[idx] = idx + 1
                idx = findp(parent, idx)
            }
            t = t + 1
        }

        if findp(parent, 0) == num_cells {
            let seg_ends: ptr<f64> = malloc(((num_cells + 1) as i64) * 8) as ptr<f64>
            let seg_vals: ptr<f64> = malloc(((num_cells + 1) as i64) * 8) as ptr<f64>
            let seg_n: i32 = 0
            let mut curr: i32 = values[0]
            i = 1
            while i < num_cells {
                if values[i] != curr {
                    seg_ends[seg_n] = endpoints[i]
                    seg_vals[seg_n] = (curr as f64) * l
                    seg_n = seg_n + 1
                    curr = values[i]
                }
                i = i + 1
            }
            seg_ends[seg_n] = domain_end
            seg_vals[seg_n] = (curr as f64) * l
            seg_n = seg_n + 1

            free(starts)
            free(ends_arr)
            free(labels)
            free(endpoints)
            free(parent)
            free(values)
            return Seg { ends: seg_ends, vals: seg_vals, n: seg_n }
        }

        free(starts)
        free(ends_arr)
        free(labels)
        free(endpoints)
        free(parent)
        free(values)
        K = K * 2
    }
    return Seg { ends: null, vals: null, n: 0 }
}

function hpush(heap_keys: ptr<f64>, heap_ids: ptr<i32>, hn0: i32, key: f64, id: i32) -> i32 {
    let mut n: i32 = hn0
    let mut i: i32 = n
    n = n + 1
    heap_keys[i] = key
    heap_ids[i] = id
    while i > 0 {
        let p: i32 = (i - 1) / 2
        if heap_keys[p] <= heap_keys[i] { break }
        let tk: f64 = heap_keys[p]
        let ti: i32 = heap_ids[p]
        heap_keys[p] = heap_keys[i]
        heap_ids[p] = heap_ids[i]
        heap_keys[i] = tk
        heap_ids[i] = ti
        i = p
    }
    return n
}

function hpop(heap_keys: ptr<f64>, heap_ids: ptr<i32>, hn0: i32, out_id: ptr<i32>) -> i32 {
    out_id[0] = heap_ids[0]
    let mut n: i32 = hn0 - 1
    heap_keys[0] = heap_keys[n]
    heap_ids[0] = heap_ids[n]
    let mut i: i32 = 0
    while true {
        let l: i32 = 2 * i + 1
        let rg: i32 = 2 * i + 2
        let mut sm: i32 = i
        if l < n {
            if heap_keys[l] < heap_keys[sm] { sm = l }
        }
        if rg < n {
            if heap_keys[rg] < heap_keys[sm] { sm = rg }
        }
        if sm == i { break }
        let tk: f64 = heap_keys[i]
        let ti: i32 = heap_ids[i]
        heap_keys[i] = heap_keys[sm]
        heap_ids[i] = heap_ids[sm]
        heap_keys[sm] = tk
        heap_ids[sm] = ti
        i = sm
    }
    return n
}

function merge_max_sum(seg_ends_arr: ptr<ptr<f64> >, seg_vals_arr: ptr<ptr<f64> >, seg_n_arr: ptr<i32>, P: i32, domain_end: f64) -> f64 {
    let idx: ptr<i32> = calloc(P as i64, 4) as ptr<i32>
    let cur: ptr<f64> = malloc((P as i64) * 8) as ptr<f64>
    let mut total: f64 = 0.0
    let mut i: i32 = 0
    while i < P {
        cur[i] = seg_vals_arr[i][0]
        total = total + cur[i]
        i = i + 1
    }

    let heap_keys: ptr<f64> = malloc(((P * 2 + 8) as i64) * 8) as ptr<f64>
    let heap_ids: ptr<i32> = malloc(((P * 2 + 8) as i64) * 4) as ptr<i32>
    let mut hn: i32 = 0
    i = 0
    while i < P {
        hn = hpush(heap_keys, heap_ids, hn, seg_ends_arr[i][0], i)
        i = i + 1
    }

    let mut cur_pos: f64 = 0.0
    let mut best: f64 = total
    let eps: f64 = 1e-15
    let aff: ptr<i32> = malloc(512 * 4) as ptr<i32>

    while hn > 0 {
        let boundary: f64 = heap_keys[0]
        if boundary > cur_pos + 1e-18 {
            if total > best { best = total }
        }
        let na: i32 = 0
        while hn > 0 && fabs(heap_keys[0] - boundary) <= eps {
            let out_id: ptr<i32> = calloc(1, 4) as ptr<i32>
            hn = hpop(heap_keys, heap_ids, hn, out_id)
            if na < 512 {
                aff[na] = out_id[0]
                na = na + 1
            }
            free(out_id)
        }
        cur_pos = boundary
        if cur_pos >= domain_end - 1e-15 { break }
        let mut a: i32 = 0
        while a < na {
            let ii: i32 = aff[a]
            let old: f64 = cur[ii]
            idx[ii] = idx[ii] + 1
            let nv: f64 = seg_vals_arr[ii][idx[ii]]
            cur[ii] = nv
            total = total + nv - old
            hn = hpush(heap_keys, heap_ids, hn, seg_ends_arr[ii][idx[ii]], ii)
            a = a + 1
        }
    }

    free(idx)
    free(cur)
    free(heap_keys)
    free(heap_ids)
    free(aff)
    return best
}

function primes_up_to(n: i32, outc: ptr<i32>) -> ptr<i32> {
    let sv: ptr<i8> = calloc((n + 1) as i64, 1) as ptr<i8>
    let mut i: i32 = 0
    while i <= n {
        sv[i] = 1
        i = i + 1
    }
    sv[0] = 0
    sv[1] = 0
    let r: i32 = sqrt((n as f64)) as i32
    i = 2
    while i <= r {
        if sv[i] == 1 {
            let mut j: i64 = (i as i64) * (i as i64)
            while j <= (n as i64) {
                sv[j] = 0
                j = j + (i as i64)
            }
        }
        i = i + 1
    }
    let mut c: i32 = 0
    i = 2
    while i <= n {
        if sv[i] == 1 { c = c + 1 }
        i = i + 1
    }
    let ps: ptr<i32> = malloc((c as i64) * 4) as ptr<i32>
    c = 0
    i = 2
    while i <= n {
        if sv[i] == 1 {
            ps[c] = i
            c = c + 1
        }
        i = i + 1
    }
    free(sv)
    outc[0] = c
    return ps
}

function main() -> i32 {
    let n: i32 = 100
    let g: f64 = 0.00002
    let outc: ptr<i32> = calloc(1, 4) as ptr<i32>
    let ps: ptr<i32> = primes_up_to(n, outc)
    let npc: i32 = outc[0]
    free(outc)

    let seg_ends_arr: ptr<ptr<f64> > = calloc(npc as i64, 8) as ptr<ptr<f64> >
    let seg_vals_arr: ptr<ptr<f64> > = calloc(npc as i64, 8) as ptr<ptr<f64> >
    let seg_n_arr: ptr<i32> = calloc(npc as i64, 4) as ptr<i32>

    let mut i: i32 = 0
    while i < npc {
        let seg: Seg = build_piecewise(1.0 / sqrt((ps[i] as f64)), g)
        seg_ends_arr[i] = seg.ends
        seg_vals_arr[i] = seg.vals
        seg_n_arr[i] = seg.n
        i = i + 1
    }

    let ans: f64 = merge_max_sum(seg_ends_arr, seg_vals_arr, seg_n_arr, npc, 1.0 - g)

    i = 0
    while i < npc {
        free(seg_ends_arr[i])
        free(seg_vals_arr[i])
        i = i + 1
    }
    free(seg_ends_arr)
    free(seg_vals_arr)
    free(seg_n_arr)
    free(ps)

    printf("%.4f\n", ans)
    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 Seg Seg;

struct Seg {
    double* ends;
    double* vals;
    int32_t n;
};

void sift_down_ptr_f64_i64_i64(double* arr, int64_t start, int64_t end);
void sort_doubles_ptr_f64_i64(double* arr, int64_t n);
int32_t bisect_left_ptr_f64_i32_f64(double* a, int32_t n, double x);
int32_t findp_ptr_i32_i32(int32_t* parent, int32_t i0);
Seg build_piecewise_f64_f64(double l, double g);
int32_t hpush_ptr_f64_ptr_i32_i32_f64_i32(double* heap_keys, int32_t* heap_ids, int32_t hn0, double key, int32_t id);
int32_t hpop_ptr_f64_ptr_i32_i32_ptr_i32(double* heap_keys, int32_t* heap_ids, int32_t hn0, int32_t* out_id);
double merge_max_sum_ptr_ptr_f64_ptr_ptr_f64_ptr_i32_i32_f64(double** seg_ends_arr, double** seg_vals_arr, int32_t* seg_n_arr, int32_t P, double domain_end);
int32_t* primes_up_to_i32_ptr_i32(int32_t n, int32_t* outc);
int32_t main(void);







void sift_down_ptr_f64_i64_i64(double* arr, int64_t start, int64_t end) {
    int64_t root = start;
    while (((2 * root) + 1) < end) {
        int64_t child = ((2 * root) + 1);
        if ((child + 1) < end) {
            if (arr[child] < arr[(child + 1)]) {
                child = (child + 1);
            }
        }
        if (arr[root] < arr[child]) {
            double tmp = arr[root];
            arr[root] = arr[child];
            arr[child] = tmp;
            root = child;
        } else {
            return;
        }
    }
}

void sort_doubles_ptr_f64_i64(double* arr, int64_t n) {
    if (n < 2) {
        return;
    }
    int64_t start = FLOW_CHECKED_DIV((n), (2));
    while (start > 0) {
        start = (start - 1);
        sift_down_ptr_f64_i64_i64(arr, start, n);
    }
    int64_t end = n;
    while (end > 1) {
        end = (end - 1);
        double tmp = arr[0];
        arr[0] = arr[end];
        arr[end] = tmp;
        sift_down_ptr_f64_i64_i64(arr, 0, end);
    }
}

int32_t bisect_left_ptr_f64_i32_f64(double* a, int32_t n, double x) {
    int32_t lo = 0;
    int32_t hi = n;
    while (lo < hi) {
        int32_t mid = (lo + FLOW_CHECKED_DIV(((hi - lo)), (2)));
        if (a[mid] < x) {
            lo = (mid + 1);
        } else {
            hi = mid;
        }
    }
    return lo;
}

int32_t findp_ptr_i32_i32(int32_t* parent, int32_t i0) {
    int32_t i = i0;
    while (parent[i] != i) {
        parent[i] = parent[parent[i]];
        i = parent[i];
    }
    return i;
}

Seg build_piecewise_f64_f64(double l, double g) {
    double domain_end = (1.0 - g);
    int32_t K = ((int32_t)((1.5 / g)));
    if (K < 10) {
        K = 10;
    }
    while (1) {
        if (K > 4000000) {
            return (Seg){ .ends = NULL, .vals = NULL, .n = 0 };
        }
        double* starts = (double*)(((double*)(malloc((((int64_t)(K)) * 8)))));
        double* ends_arr = (double*)(((double*)(malloc((((int64_t)(K)) * 8)))));
        int32_t* labels = (int32_t*)(((int32_t*)(malloc((((int64_t)(K)) * 4)))));
        int32_t nint = 0;
        double* endpoints = (double*)(((double*)(malloc((((int64_t)(((2 * K) + 2))) * 8)))));
        int32_t nep = 0;
        endpoints[0] = 0.0;
        nep = 1;
        endpoints[1] = domain_end;
        nep = 2;
        double x = 0.0;
        int32_t k = 1;
        while (k <= K) {
            x = (x + l);
            x = (x - floor(x));
            double s = (x - g);
            double e = x;
            if ((e <= 0.0 || s >= domain_end)) {
                k = (k + 1);
                continue;
            }
            double ss = s;
            double ee = e;
            if (ss < 0.0) {
                ss = 0.0;
            }
            if (ee > domain_end) {
                ee = domain_end;
            }
            if (ss < ee) {
                starts[nint] = ss;
                ends_arr[nint] = ee;
                labels[nint] = k;
                endpoints[nep] = ss;
                nep = (nep + 1);
                endpoints[nep] = ee;
                nep = (nep + 1);
                nint = (nint + 1);
            }
            k = (k + 1);
        }
        sort_doubles_ptr_f64_i64(endpoints, ((int64_t)(nep)));
        int32_t nu = 0;
        int32_t i = 0;
        while (i < nep) {
            if ((nu == 0 || endpoints[i] != endpoints[(nu - 1)])) {
                endpoints[nu] = endpoints[i];
                nu = (nu + 1);
            }
            i = (i + 1);
        }
        int32_t num_cells = (nu - 1);
        int32_t* parent = (int32_t*)(((int32_t*)(malloc((((int64_t)((num_cells + 1))) * 4)))));
        int32_t* values = (int32_t*)(((int32_t*)(calloc(((int64_t)(num_cells)), 4))));
        i = 0;
        while (i <= num_cells) {
            parent[i] = i;
            i = (i + 1);
        }
        int32_t t = 0;
        while (t < nint) {
            int32_t bi = bisect_left_ptr_f64_i32_f64(endpoints, nu, starts[t]);
            int32_t bj = bisect_left_ptr_f64_i32_f64(endpoints, nu, ends_arr[t]);
            int32_t idx = findp_ptr_i32_i32(parent, bi);
            while (idx < bj) {
                values[idx] = labels[t];
                parent[idx] = (idx + 1);
                idx = findp_ptr_i32_i32(parent, idx);
            }
            t = (t + 1);
        }
        if (findp_ptr_i32_i32(parent, 0) == num_cells) {
            double* seg_ends = (double*)(((double*)(malloc((((int64_t)((num_cells + 1))) * 8)))));
            double* seg_vals = (double*)(((double*)(malloc((((int64_t)((num_cells + 1))) * 8)))));
            int32_t seg_n = 0;
            int32_t curr = values[0];
            i = 1;
            while (i < num_cells) {
                if (values[i] != curr) {
                    seg_ends[seg_n] = endpoints[i];
                    seg_vals[seg_n] = (((double)(curr)) * l);
                    seg_n = (seg_n + 1);
                    curr = values[i];
                }
                i = (i + 1);
            }
            seg_ends[seg_n] = domain_end;
            seg_vals[seg_n] = (((double)(curr)) * l);
            seg_n = (seg_n + 1);
            free(starts);
            free(ends_arr);
            free(labels);
            free(endpoints);
            free(parent);
            free(values);
            return (Seg){ .ends = seg_ends, .vals = seg_vals, .n = seg_n };
        }
        free(starts);
        free(ends_arr);
        free(labels);
        free(endpoints);
        free(parent);
        free(values);
        K = (K * 2);
    }
    return (Seg){ .ends = NULL, .vals = NULL, .n = 0 };
}

int32_t hpush_ptr_f64_ptr_i32_i32_f64_i32(double* heap_keys, int32_t* heap_ids, int32_t hn0, double key, int32_t id) {
    int32_t n = hn0;
    int32_t i = n;
    n = (n + 1);
    heap_keys[i] = key;
    heap_ids[i] = id;
    while (i > 0) {
        int32_t p = FLOW_CHECKED_DIV(((i - 1)), (2));
        if (heap_keys[p] <= heap_keys[i]) {
            break;
        }
        double tk = heap_keys[p];
        int32_t ti = heap_ids[p];
        heap_keys[p] = heap_keys[i];
        heap_ids[p] = heap_ids[i];
        heap_keys[i] = tk;
        heap_ids[i] = ti;
        i = p;
    }
    return n;
}

int32_t hpop_ptr_f64_ptr_i32_i32_ptr_i32(double* heap_keys, int32_t* heap_ids, int32_t hn0, int32_t* out_id) {
    out_id[0] = heap_ids[0];
    int32_t n = (hn0 - 1);
    heap_keys[0] = heap_keys[n];
    heap_ids[0] = heap_ids[n];
    int32_t i = 0;
    while (1) {
        int32_t l = ((2 * i) + 1);
        int32_t rg = ((2 * i) + 2);
        int32_t sm = i;
        if (l < n) {
            if (heap_keys[l] < heap_keys[sm]) {
                sm = l;
            }
        }
        if (rg < n) {
            if (heap_keys[rg] < heap_keys[sm]) {
                sm = rg;
            }
        }
        if (sm == i) {
            break;
        }
        double tk = heap_keys[i];
        int32_t ti = heap_ids[i];
        heap_keys[i] = heap_keys[sm];
        heap_ids[i] = heap_ids[sm];
        heap_keys[sm] = tk;
        heap_ids[sm] = ti;
        i = sm;
    }
    return n;
}

double merge_max_sum_ptr_ptr_f64_ptr_ptr_f64_ptr_i32_i32_f64(double** seg_ends_arr, double** seg_vals_arr, int32_t* seg_n_arr, int32_t P, double domain_end) {
    int32_t* idx = (int32_t*)(((int32_t*)(calloc(((int64_t)(P)), 4))));
    double* cur = (double*)(((double*)(malloc((((int64_t)(P)) * 8)))));
    double total = 0.0;
    int32_t i = 0;
    while (i < P) {
        cur[i] = seg_vals_arr[i][0];
        total = (total + cur[i]);
        i = (i + 1);
    }
    double* heap_keys = (double*)(((double*)(malloc((((int64_t)(((P * 2) + 8))) * 8)))));
    int32_t* heap_ids = (int32_t*)(((int32_t*)(malloc((((int64_t)(((P * 2) + 8))) * 4)))));
    int32_t hn = 0;
    i = 0;
    while (i < P) {
        hn = hpush_ptr_f64_ptr_i32_i32_f64_i32(heap_keys, heap_ids, hn, seg_ends_arr[i][0], i);
        i = (i + 1);
    }
    double cur_pos = 0.0;
    double best = total;
    double eps = 1e-15;
    int32_t* aff = (int32_t*)(((int32_t*)(malloc((512 * 4)))));
    while (hn > 0) {
        double boundary = heap_keys[0];
        if (boundary > (cur_pos + 1e-18)) {
            if (total > best) {
                best = total;
            }
        }
        int32_t na = 0;
        while ((hn > 0 && fabs((heap_keys[0] - boundary)) <= eps)) {
            int32_t* out_id = (int32_t*)(((int32_t*)(calloc(1, 4))));
            hn = hpop_ptr_f64_ptr_i32_i32_ptr_i32(heap_keys, heap_ids, hn, out_id);
            if (na < 512) {
                aff[na] = out_id[0];
                na = (na + 1);
            }
            free(out_id);
        }
        cur_pos = boundary;
        if (cur_pos >= (domain_end - 1e-15)) {
            break;
        }
        int32_t a = 0;
        while (a < na) {
            int32_t ii = aff[a];
            double old = cur[ii];
            idx[ii] = (idx[ii] + 1);
            double nv = seg_vals_arr[ii][idx[ii]];
            cur[ii] = nv;
            total = ((total + nv) - old);
            hn = hpush_ptr_f64_ptr_i32_i32_f64_i32(heap_keys, heap_ids, hn, seg_ends_arr[ii][idx[ii]], ii);
            a = (a + 1);
        }
    }
    free(idx);
    free(cur);
    free(heap_keys);
    free(heap_ids);
    free(aff);
    return best;
}

int32_t* primes_up_to_i32_ptr_i32(int32_t n, int32_t* outc) {
    int8_t* sv = (int8_t*)(((int8_t*)(calloc(((int64_t)((n + 1))), 1))));
    int32_t i = 0;
    while (i <= n) {
        sv[i] = 1;
        i = (i + 1);
    }
    sv[0] = 0;
    sv[1] = 0;
    int32_t r = ((int32_t)(sqrt(((double)(n)))));
    i = 2;
    while (i <= r) {
        if (sv[i] == 1) {
            int64_t j = (((int64_t)(i)) * ((int64_t)(i)));
            while (j <= ((int64_t)(n))) {
                sv[j] = 0;
                j = (j + ((int64_t)(i)));
            }
        }
        i = (i + 1);
    }
    int32_t c = 0;
    i = 2;
    while (i <= n) {
        if (sv[i] == 1) {
            c = (c + 1);
        }
        i = (i + 1);
    }
    int32_t* ps = (int32_t*)(((int32_t*)(malloc((((int64_t)(c)) * 4)))));
    c = 0;
    i = 2;
    while (i <= n) {
        if (sv[i] == 1) {
            ps[c] = i;
            c = (c + 1);
        }
        i = (i + 1);
    }
    free(sv);
    outc[0] = c;
    return ps;
}

int32_t main(void) {
    int32_t n = 100;
    double g = 0.00002;
    int32_t* outc = (int32_t*)(((int32_t*)(calloc(1, 4))));
    int32_t* ps = (int32_t*)(primes_up_to_i32_ptr_i32(n, outc));
    int32_t npc = outc[0];
    free(outc);
    double** seg_ends_arr = (double**)(((double**)(calloc(((int64_t)(npc)), 8))));
    double** seg_vals_arr = (double**)(((double**)(calloc(((int64_t)(npc)), 8))));
    int32_t* seg_n_arr = (int32_t*)(((int32_t*)(calloc(((int64_t)(npc)), 4))));
    int32_t i = 0;
    while (i < npc) {
        Seg seg = build_piecewise_f64_f64((1.0 / sqrt(((double)(ps[i])))), g);
        seg_ends_arr[i] = seg.ends;
        seg_vals_arr[i] = seg.vals;
        seg_n_arr[i] = seg.n;
        i = (i + 1);
    }
    double ans = merge_max_sum_ptr_ptr_f64_ptr_ptr_f64_ptr_i32_i32_f64(seg_ends_arr, seg_vals_arr, seg_n_arr, npc, (1.0 - g));
    i = 0;
    while (i < npc) {
        free(seg_ends_arr[i]);
        free(seg_vals_arr[i]);
        i = (i + 1);
    }
    free(seg_ends_arr);
    free(seg_vals_arr);
    free(seg_n_arr);
    free(ps);
    printf("%.4f\n", ans);
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%.4f\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()
  func.func private @malloc(i64) -> !llvm.ptr
  func.func private @sqrt(f64) -> f64
  func.func private @fabs(f64) -> f64
  func.func private @floor(f64) -> f64
  // Struct: Seg
  // Fields:
  //   ends: !llvm.ptr
  //   vals: !llvm.ptr
  //   n: i32
  func.func @sift_down(%arg0: !llvm.ptr, %arg1: i64, %arg2: i64) -> () {
    %0 = llvm.mlir.constant(1 : i64) : i64
    %1 = llvm.alloca %0 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %1 : i64, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %2 = arith.constant 2 : i32
    %3 = llvm.load %1 : !llvm.ptr -> i64
    %5 = arith.extsi %2 : i32 to i64
    %4 = arith.muli %5, %3 : i64
    %6 = arith.constant 1 : i32
    %8 = arith.extsi %6 : i32 to i64
    %7 = arith.addi %4, %8 : i64
    %9 = arith.cmpi slt, %7, %arg2 : i64
    cf.cond_br %9, ^bb1, ^bb2
    ^bb1:
      %10 = arith.constant 2 : i32
      %11 = llvm.load %1 : !llvm.ptr -> i64
      %13 = arith.extsi %10 : i32 to i64
      %12 = arith.muli %13, %11 : i64
      %14 = arith.constant 1 : i32
      %16 = arith.extsi %14 : i32 to i64
      %15 = arith.addi %12, %16 : i64
      %17 = llvm.mlir.constant(1 : i64) : i64
      %18 = llvm.alloca %17 x i64 : (i64) -> !llvm.ptr
      llvm.store %15, %18 : i64, !llvm.ptr
      %19 = llvm.load %18 : !llvm.ptr -> i64
      %20 = arith.constant 1 : i32
      %22 = arith.extsi %20 : i32 to i64
      %21 = arith.addi %19, %22 : i64
      %23 = arith.cmpi slt, %21, %arg2 : i64
      cf.cond_br %23, ^bb3, ^bb4
      ^bb3:
        %25 = llvm.load %18 : !llvm.ptr -> i64
        %26 = llvm.getelementptr %arg0[%25] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %24 = llvm.load %26 : !llvm.ptr -> f64
        %28 = llvm.load %18 : !llvm.ptr -> i64
        %29 = arith.constant 1 : i32
        %31 = arith.extsi %29 : i32 to i64
        %30 = arith.addi %28, %31 : i64
        %32 = llvm.getelementptr %arg0[%30] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %27 = llvm.load %32 : !llvm.ptr -> f64
        %33 = arith.cmpf olt, %24, %27 : f64
        cf.cond_br %33, ^bb6, ^bb7
        ^bb6:
          %34 = llvm.load %18 : !llvm.ptr -> i64
          %35 = arith.constant 1 : i32
          %37 = arith.extsi %35 : i32 to i64
          %36 = arith.addi %34, %37 : i64
          llvm.store %36, %18 : i64, !llvm.ptr
          cf.br ^bb8
        ^bb7:
          cf.br ^bb8
        ^bb8:
        cf.br ^bb5
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %39 = llvm.load %1 : !llvm.ptr -> i64
      %40 = llvm.getelementptr %arg0[%39] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %38 = llvm.load %40 : !llvm.ptr -> f64
      %42 = llvm.load %18 : !llvm.ptr -> i64
      %43 = llvm.getelementptr %arg0[%42] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %41 = llvm.load %43 : !llvm.ptr -> f64
      %44 = arith.cmpf olt, %38, %41 : f64
      cf.cond_br %44, ^bb9, ^bb10
      ^bb9:
        %46 = llvm.load %1 : !llvm.ptr -> i64
        %47 = llvm.getelementptr %arg0[%46] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %45 = llvm.load %47 : !llvm.ptr -> f64
        %49 = llvm.load %18 : !llvm.ptr -> i64
        %50 = llvm.getelementptr %arg0[%49] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %48 = llvm.load %50 : !llvm.ptr -> f64
        %51 = llvm.load %1 : !llvm.ptr -> i64
        %52 = llvm.getelementptr %arg0[%51] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %48, %52 : f64, !llvm.ptr
        %53 = llvm.load %18 : !llvm.ptr -> i64
        %54 = llvm.getelementptr %arg0[%53] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %45, %54 : f64, !llvm.ptr
        %55 = llvm.load %18 : !llvm.ptr -> i64
        llvm.store %55, %1 : i64, !llvm.ptr
        cf.br ^bb11
      ^bb10:
        func.return
      ^bb11:
      cf.br ^bb0
    ^bb2:
    func.return
  }
  func.func @sort_doubles(%arg0: !llvm.ptr, %arg1: i64) -> () {
    %56 = arith.constant 2 : i32
    %58 = arith.extsi %56 : i32 to i64
    %57 = arith.cmpi slt, %arg1, %58 : i64
    cf.cond_br %57, ^bb12, ^bb13
    ^bb12:
      func.return
    ^bb13:
      cf.br ^bb14
    ^bb14:
    %59 = arith.constant 2 : i32
    %61 = arith.extsi %59 : i32 to i64
    %60 = arith.divsi %arg1, %61 : i64
    %62 = llvm.mlir.constant(1 : i64) : i64
    %63 = llvm.alloca %62 x i64 : (i64) -> !llvm.ptr
    llvm.store %60, %63 : i64, !llvm.ptr
    cf.br ^bb15
    ^bb15:
    %64 = llvm.load %63 : !llvm.ptr -> i64
    %65 = arith.constant 0 : i32
    %67 = arith.extsi %65 : i32 to i64
    %66 = arith.cmpi sgt, %64, %67 : i64
    cf.cond_br %66, ^bb16, ^bb17
    ^bb16:
      %68 = llvm.load %63 : !llvm.ptr -> i64
      %69 = arith.constant 1 : i32
      %71 = arith.extsi %69 : i32 to i64
      %70 = arith.subi %68, %71 : i64
      llvm.store %70, %63 : i64, !llvm.ptr
      %73 = llvm.load %63 : !llvm.ptr -> i64
      func.call @sift_down(%arg0, %73, %arg1) : (!llvm.ptr, i64, i64) -> ()
      cf.br ^bb15
    ^bb17:
    %74 = llvm.mlir.constant(1 : i64) : i64
    %75 = llvm.alloca %74 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %75 : i64, !llvm.ptr
    cf.br ^bb18
    ^bb18:
    %76 = llvm.load %75 : !llvm.ptr -> i64
    %77 = arith.constant 1 : i32
    %79 = arith.extsi %77 : i32 to i64
    %78 = arith.cmpi sgt, %76, %79 : i64
    cf.cond_br %78, ^bb19, ^bb20
    ^bb19:
      %80 = llvm.load %75 : !llvm.ptr -> i64
      %81 = arith.constant 1 : i32
      %83 = arith.extsi %81 : i32 to i64
      %82 = arith.subi %80, %83 : i64
      llvm.store %82, %75 : i64, !llvm.ptr
      %85 = arith.constant 0 : i32
      %86 = arith.extsi %85 : i32 to i64
      %87 = llvm.getelementptr %arg0[%86] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %84 = llvm.load %87 : !llvm.ptr -> f64
      %89 = llvm.load %75 : !llvm.ptr -> i64
      %90 = llvm.getelementptr %arg0[%89] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %88 = llvm.load %90 : !llvm.ptr -> f64
      %91 = arith.constant 0 : i32
      %92 = arith.extsi %91 : i32 to i64
      %93 = llvm.getelementptr %arg0[%92] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %88, %93 : f64, !llvm.ptr
      %94 = llvm.load %75 : !llvm.ptr -> i64
      %95 = llvm.getelementptr %arg0[%94] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %84, %95 : f64, !llvm.ptr
      %97 = arith.constant 0 : i32
      %98 = llvm.load %75 : !llvm.ptr -> i64
      %99 = arith.extsi %97 : i32 to i64
      func.call @sift_down(%arg0, %99, %98) : (!llvm.ptr, i64, i64) -> ()
      cf.br ^bb18
    ^bb20:
    func.return
  }
  func.func @bisect_left(%arg0: !llvm.ptr, %arg1: i32, %arg2: f64) -> i32 {
    %100 = arith.constant 0 : i32
    %101 = llvm.mlir.constant(1 : i64) : i64
    %102 = llvm.alloca %101 x i32 : (i64) -> !llvm.ptr
    llvm.store %100, %102 : i32, !llvm.ptr
    %103 = llvm.mlir.constant(1 : i64) : i64
    %104 = llvm.alloca %103 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg1, %104 : i32, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %105 = llvm.load %102 : !llvm.ptr -> i32
    %106 = llvm.load %104 : !llvm.ptr -> i32
    %107 = arith.cmpi slt, %105, %106 : i32
    cf.cond_br %107, ^bb22, ^bb23
    ^bb22:
      %108 = llvm.load %102 : !llvm.ptr -> i32
      %109 = llvm.load %104 : !llvm.ptr -> i32
      %110 = llvm.load %102 : !llvm.ptr -> i32
      %111 = arith.subi %109, %110 : i32
      %112 = arith.constant 2 : i32
      %113 = arith.divsi %111, %112 : i32
      %114 = arith.addi %108, %113 : i32
      %116 = arith.extsi %114 : i32 to i64
      %117 = llvm.getelementptr %arg0[%116] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %115 = llvm.load %117 : !llvm.ptr -> f64
      %118 = arith.cmpf olt, %115, %arg2 : f64
      cf.cond_br %118, ^bb24, ^bb25
      ^bb24:
        %119 = arith.constant 1 : i32
        %120 = arith.addi %114, %119 : i32
        llvm.store %120, %102 : i32, !llvm.ptr
        cf.br ^bb26
      ^bb25:
        llvm.store %114, %104 : i32, !llvm.ptr
        cf.br ^bb26
      ^bb26:
      cf.br ^bb21
    ^bb23:
    %121 = llvm.load %102 : !llvm.ptr -> i32
    func.return %121 : i32
  }
  func.func @findp(%arg0: !llvm.ptr, %arg1: i32) -> i32 {
    %122 = llvm.mlir.constant(1 : i64) : i64
    %123 = llvm.alloca %122 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg1, %123 : i32, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %125 = llvm.load %123 : !llvm.ptr -> i32
    %126 = arith.extsi %125 : i32 to i64
    %127 = llvm.getelementptr %arg0[%126] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %124 = llvm.load %127 : !llvm.ptr -> i32
    %128 = llvm.load %123 : !llvm.ptr -> i32
    %129 = arith.cmpi ne, %124, %128 : i32
    cf.cond_br %129, ^bb28, ^bb29
    ^bb28:
      %132 = llvm.load %123 : !llvm.ptr -> i32
      %133 = arith.extsi %132 : i32 to i64
      %134 = llvm.getelementptr %arg0[%133] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %131 = llvm.load %134 : !llvm.ptr -> i32
      %135 = arith.extsi %131 : i32 to i64
      %136 = llvm.getelementptr %arg0[%135] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %130 = llvm.load %136 : !llvm.ptr -> i32
      %137 = llvm.load %123 : !llvm.ptr -> i32
      %138 = arith.extsi %137 : i32 to i64
      %139 = llvm.getelementptr %arg0[%138] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %130, %139 : i32, !llvm.ptr
      %141 = llvm.load %123 : !llvm.ptr -> i32
      %142 = arith.extsi %141 : i32 to i64
      %143 = llvm.getelementptr %arg0[%142] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %140 = llvm.load %143 : !llvm.ptr -> i32
      llvm.store %140, %123 : i32, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %144 = llvm.load %123 : !llvm.ptr -> i32
    func.return %144 : i32
  }
  func.func @build_piecewise(%arg0: f64, %arg1: f64) -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)> {
    %145 = arith.constant 1.0 : f32
    %147 = arith.extf %145 : f32 to f64
    %146 = arith.subf %147, %arg1 : f64
    %148 = arith.constant 1.5 : f32
    %150 = arith.extf %148 : f32 to f64
    %149 = arith.divf %150, %arg1 : f64
    %151 = arith.fptosi %149 : f64 to i32
    %152 = llvm.mlir.constant(1 : i64) : i64
    %153 = llvm.alloca %152 x i32 : (i64) -> !llvm.ptr
    llvm.store %151, %153 : i32, !llvm.ptr
    %154 = llvm.load %153 : !llvm.ptr -> i32
    %155 = arith.constant 10 : i32
    %156 = arith.cmpi slt, %154, %155 : i32
    cf.cond_br %156, ^bb30, ^bb31
    ^bb30:
      %157 = arith.constant 10 : i32
      llvm.store %157, %153 : i32, !llvm.ptr
      cf.br ^bb32
    ^bb31:
      cf.br ^bb32
    ^bb32:
    cf.br ^bb33
    ^bb33:
    %158 = arith.constant 1 : i1
    cf.cond_br %158, ^bb34, ^bb35
    ^bb34:
      %159 = llvm.load %153 : !llvm.ptr -> i32
      %160 = arith.constant 4000000 : i32
      %161 = arith.cmpi sgt, %159, %160 : i32
      cf.cond_br %161, ^bb36, ^bb37
      ^bb36:
        %162 = llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %163 = llvm.mlir.zero : !llvm.ptr
        %164 = llvm.insertvalue %163, %162[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %165 = llvm.mlir.zero : !llvm.ptr
        %166 = llvm.insertvalue %165, %164[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %167 = arith.constant 0 : i32
        %168 = llvm.insertvalue %167, %166[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %169 = llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %170 = llvm.extractvalue %168[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %171 = llvm.insertvalue %170, %169[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %172 = llvm.extractvalue %168[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %173 = llvm.insertvalue %172, %171[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %174 = llvm.extractvalue %168[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %175 = llvm.insertvalue %174, %173[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %176 = llvm.mlir.constant(1 : i64) : i64
        %177 = llvm.alloca %176 x !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)> : (i64) -> !llvm.ptr
        llvm.store %175, %177 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>, !llvm.ptr
        %178 = llvm.load %177 : !llvm.ptr -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        func.return %178 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      ^bb37:
        cf.br ^bb38
      ^bb38:
      %180 = llvm.load %153 : !llvm.ptr -> i32
      %181 = arith.extsi %180 : i32 to i64
      %182 = arith.constant 8 : i32
      %184 = arith.extsi %182 : i32 to i64
      %183 = arith.muli %181, %184 : i64
      %179 = func.call @malloc(%183) : (i64) -> !llvm.ptr
      %186 = llvm.load %153 : !llvm.ptr -> i32
      %187 = arith.extsi %186 : i32 to i64
      %188 = arith.constant 8 : i32
      %190 = arith.extsi %188 : i32 to i64
      %189 = arith.muli %187, %190 : i64
      %185 = func.call @malloc(%189) : (i64) -> !llvm.ptr
      %192 = llvm.load %153 : !llvm.ptr -> i32
      %193 = arith.extsi %192 : i32 to i64
      %194 = arith.constant 4 : i32
      %196 = arith.extsi %194 : i32 to i64
      %195 = arith.muli %193, %196 : i64
      %191 = func.call @malloc(%195) : (i64) -> !llvm.ptr
      %197 = arith.constant 0 : i32
      %199 = arith.constant 2 : i32
      %200 = llvm.load %153 : !llvm.ptr -> i32
      %201 = arith.muli %199, %200 : i32
      %202 = arith.constant 2 : i32
      %203 = arith.addi %201, %202 : i32
      %204 = arith.extsi %203 : i32 to i64
      %205 = arith.constant 8 : i32
      %207 = arith.extsi %205 : i32 to i64
      %206 = arith.muli %204, %207 : i64
      %198 = func.call @malloc(%206) : (i64) -> !llvm.ptr
      %208 = arith.constant 0 : i32
      %209 = arith.constant 0.0 : f32
      %210 = arith.constant 0 : i32
      %211 = arith.extf %209 : f32 to f64
      %212 = arith.extsi %210 : i32 to i64
      %213 = llvm.getelementptr %198[%212] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %211, %213 : f64, !llvm.ptr
      %214 = arith.constant 1 : i32
      %215 = arith.constant 1 : i32
      %216 = arith.extsi %215 : i32 to i64
      %217 = llvm.getelementptr %198[%216] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %146, %217 : f64, !llvm.ptr
      %218 = arith.constant 2 : i32
      %219 = arith.constant 0.0 : f32
      %220 = arith.extf %219 : f32 to f64
      %221 = llvm.mlir.constant(1 : i64) : i64
      %222 = llvm.alloca %221 x f64 : (i64) -> !llvm.ptr
      llvm.store %220, %222 : f64, !llvm.ptr
      %223 = arith.constant 1 : i32
      %224 = llvm.mlir.constant(1 : i64) : i64
      %225 = llvm.alloca %224 x i32 : (i64) -> !llvm.ptr
      llvm.store %223, %225 : i32, !llvm.ptr
      cf.br ^bb39(%218, %197 : i32, i32)
      ^bb39(%226: i32, %227: i32):
      %228 = llvm.load %225 : !llvm.ptr -> i32
      %229 = llvm.load %153 : !llvm.ptr -> i32
      %230 = arith.cmpi sle, %228, %229 : i32
      cf.cond_br %230, ^bb40(%226, %227 : i32, i32), ^bb41(%226, %227 : i32, i32)
      ^bb40(%231: i32, %232: i32):
        %233 = llvm.load %222 : !llvm.ptr -> f64
        %234 = arith.addf %233, %arg0 : f64
        llvm.store %234, %222 : f64, !llvm.ptr
        %235 = llvm.load %222 : !llvm.ptr -> f64
        %237 = llvm.load %222 : !llvm.ptr -> f64
        %236 = func.call @floor(%237) : (f64) -> f64
        %238 = arith.subf %235, %236 : f64
        llvm.store %238, %222 : f64, !llvm.ptr
        %239 = llvm.load %222 : !llvm.ptr -> f64
        %240 = arith.subf %239, %arg1 : f64
        %241 = llvm.load %222 : !llvm.ptr -> f64
        %242 = arith.constant 0.0 : f32
        %244 = arith.extf %242 : f32 to f64
        %243 = arith.cmpf ole, %241, %244 : f64
        %245 = scf.if %243 -> (i1) {
          %246 = arith.constant true
          scf.yield %246 : i1
        } else {
          %247 = arith.cmpf oge, %240, %146 : f64
          scf.yield %247 : i1
        }
        cf.cond_br %245, ^bb42, ^bb43
        ^bb42:
          %248 = llvm.load %225 : !llvm.ptr -> i32
          %249 = arith.constant 1 : i32
          %250 = arith.addi %248, %249 : i32
          llvm.store %250, %225 : i32, !llvm.ptr
          cf.br ^bb39(%231, %232 : i32, i32)
        ^bb43:
          cf.br ^bb44
        ^bb44:
        %251 = llvm.mlir.constant(1 : i64) : i64
        %252 = llvm.alloca %251 x f64 : (i64) -> !llvm.ptr
        llvm.store %240, %252 : f64, !llvm.ptr
        %253 = llvm.mlir.constant(1 : i64) : i64
        %254 = llvm.alloca %253 x f64 : (i64) -> !llvm.ptr
        llvm.store %241, %254 : f64, !llvm.ptr
        %255 = llvm.load %252 : !llvm.ptr -> f64
        %256 = arith.constant 0.0 : f32
        %258 = arith.extf %256 : f32 to f64
        %257 = arith.cmpf olt, %255, %258 : f64
        cf.cond_br %257, ^bb45, ^bb46
        ^bb45:
          %259 = arith.constant 0.0 : f32
          %260 = arith.extf %259 : f32 to f64
          llvm.store %260, %252 : f64, !llvm.ptr
          cf.br ^bb47
        ^bb46:
          cf.br ^bb47
        ^bb47:
        %261 = llvm.load %254 : !llvm.ptr -> f64
        %262 = arith.cmpf ogt, %261, %146 : f64
        cf.cond_br %262, ^bb48, ^bb49
        ^bb48:
          llvm.store %146, %254 : f64, !llvm.ptr
          cf.br ^bb50
        ^bb49:
          cf.br ^bb50
        ^bb50:
        %263 = llvm.load %252 : !llvm.ptr -> f64
        %264 = llvm.load %254 : !llvm.ptr -> f64
        %265 = arith.cmpf olt, %263, %264 : f64
        %266, %267 = scf.if %265 -> (i32, i32) {
          %268 = llvm.load %252 : !llvm.ptr -> f64
          %269 = arith.extsi %232 : i32 to i64
          %270 = llvm.getelementptr %179[%269] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %268, %270 : f64, !llvm.ptr
          %271 = llvm.load %254 : !llvm.ptr -> f64
          %272 = arith.extsi %232 : i32 to i64
          %273 = llvm.getelementptr %185[%272] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %271, %273 : f64, !llvm.ptr
          %274 = llvm.load %225 : !llvm.ptr -> i32
          %275 = arith.extsi %232 : i32 to i64
          %276 = llvm.getelementptr %191[%275] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %274, %276 : i32, !llvm.ptr
          %277 = llvm.load %252 : !llvm.ptr -> f64
          %278 = arith.extsi %231 : i32 to i64
          %279 = llvm.getelementptr %198[%278] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %277, %279 : f64, !llvm.ptr
          %280 = arith.constant 1 : i32
          %281 = arith.addi %231, %280 : i32
          %282 = llvm.load %254 : !llvm.ptr -> f64
          %283 = arith.extsi %281 : i32 to i64
          %284 = llvm.getelementptr %198[%283] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %282, %284 : f64, !llvm.ptr
          %285 = arith.constant 1 : i32
          %286 = arith.addi %281, %285 : i32
          %287 = arith.constant 1 : i32
          %288 = arith.addi %232, %287 : i32
          scf.yield %286, %288 : i32, i32
        } else {
          scf.yield %231, %232 : i32, i32
        }
        %289 = llvm.load %225 : !llvm.ptr -> i32
        %290 = arith.constant 1 : i32
        %291 = arith.addi %289, %290 : i32
        llvm.store %291, %225 : i32, !llvm.ptr
        cf.br ^bb39(%266, %267 : i32, i32)
      ^bb41(%292: i32, %293: i32):
      %295 = arith.extsi %292 : i32 to i64
      func.call @sort_doubles(%198, %295) : (!llvm.ptr, i64) -> ()
      %296 = arith.constant 0 : i32
      %297 = arith.constant 0 : i32
      %298 = llvm.mlir.constant(1 : i64) : i64
      %299 = llvm.alloca %298 x i32 : (i64) -> !llvm.ptr
      llvm.store %297, %299 : i32, !llvm.ptr
      cf.br ^bb51(%296 : i32)
      ^bb51(%300: i32):
      %301 = llvm.load %299 : !llvm.ptr -> i32
      %302 = arith.cmpi slt, %301, %292 : i32
      cf.cond_br %302, ^bb52(%300 : i32), ^bb53(%300 : i32)
      ^bb52(%303: i32):
        %304 = arith.constant 0 : i32
        %305 = arith.cmpi eq, %303, %304 : i32
        %306 = scf.if %305 -> (i1) {
          %307 = arith.constant true
          scf.yield %307 : i1
        } else {
          %309 = llvm.load %299 : !llvm.ptr -> i32
          %310 = arith.extsi %309 : i32 to i64
          %311 = llvm.getelementptr %198[%310] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %308 = llvm.load %311 : !llvm.ptr -> f64
          %313 = arith.constant 1 : i32
          %314 = arith.subi %303, %313 : i32
          %315 = arith.extsi %314 : i32 to i64
          %316 = llvm.getelementptr %198[%315] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %312 = llvm.load %316 : !llvm.ptr -> f64
          %317 = arith.cmpf one, %308, %312 : f64
          scf.yield %317 : i1
        }
        %318 = scf.if %306 -> (i32) {
          %320 = llvm.load %299 : !llvm.ptr -> i32
          %321 = arith.extsi %320 : i32 to i64
          %322 = llvm.getelementptr %198[%321] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %319 = llvm.load %322 : !llvm.ptr -> f64
          %323 = arith.extsi %303 : i32 to i64
          %324 = llvm.getelementptr %198[%323] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %319, %324 : f64, !llvm.ptr
          %325 = arith.constant 1 : i32
          %326 = arith.addi %303, %325 : i32
          scf.yield %326 : i32
        } else {
          scf.yield %303 : i32
        }
        %327 = llvm.load %299 : !llvm.ptr -> i32
        %328 = arith.constant 1 : i32
        %329 = arith.addi %327, %328 : i32
        llvm.store %329, %299 : i32, !llvm.ptr
        cf.br ^bb51(%318 : i32)
      ^bb53(%330: i32):
      %331 = arith.constant 1 : i32
      %332 = arith.subi %330, %331 : i32
      %334 = arith.constant 1 : i32
      %335 = arith.addi %332, %334 : i32
      %336 = arith.extsi %335 : i32 to i64
      %337 = arith.constant 4 : i32
      %339 = arith.extsi %337 : i32 to i64
      %338 = arith.muli %336, %339 : i64
      %333 = func.call @malloc(%338) : (i64) -> !llvm.ptr
      %341 = arith.extsi %332 : i32 to i64
      %342 = arith.constant 4 : i32
      %343 = arith.extsi %342 : i32 to i64
      %340 = func.call @calloc(%341, %343) : (i64, i64) -> !llvm.ptr
      %344 = arith.constant 0 : i32
      llvm.store %344, %299 : i32, !llvm.ptr
      cf.br ^bb54
      ^bb54:
      %345 = llvm.load %299 : !llvm.ptr -> i32
      %346 = arith.cmpi sle, %345, %332 : i32
      cf.cond_br %346, ^bb55, ^bb56
      ^bb55:
        %347 = llvm.load %299 : !llvm.ptr -> i32
        %348 = llvm.load %299 : !llvm.ptr -> i32
        %349 = arith.extsi %348 : i32 to i64
        %350 = llvm.getelementptr %333[%349] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %347, %350 : i32, !llvm.ptr
        %351 = llvm.load %299 : !llvm.ptr -> i32
        %352 = arith.constant 1 : i32
        %353 = arith.addi %351, %352 : i32
        llvm.store %353, %299 : i32, !llvm.ptr
        cf.br ^bb54
      ^bb56:
      %354 = arith.constant 0 : i32
      %355 = llvm.mlir.constant(1 : i64) : i64
      %356 = llvm.alloca %355 x i32 : (i64) -> !llvm.ptr
      llvm.store %354, %356 : i32, !llvm.ptr
      cf.br ^bb57
      ^bb57:
      %357 = llvm.load %356 : !llvm.ptr -> i32
      %358 = arith.cmpi slt, %357, %293 : i32
      cf.cond_br %358, ^bb58, ^bb59
      ^bb58:
        %361 = llvm.load %356 : !llvm.ptr -> i32
        %362 = arith.extsi %361 : i32 to i64
        %363 = llvm.getelementptr %179[%362] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %360 = llvm.load %363 : !llvm.ptr -> f64
        %359 = func.call @bisect_left(%198, %330, %360) : (!llvm.ptr, i32, f64) -> i32
        %366 = llvm.load %356 : !llvm.ptr -> i32
        %367 = arith.extsi %366 : i32 to i64
        %368 = llvm.getelementptr %185[%367] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %365 = llvm.load %368 : !llvm.ptr -> f64
        %364 = func.call @bisect_left(%198, %330, %365) : (!llvm.ptr, i32, f64) -> i32
        %369 = func.call @findp(%333, %359) : (!llvm.ptr, i32) -> i32
        %370 = llvm.mlir.constant(1 : i64) : i64
        %371 = llvm.alloca %370 x i32 : (i64) -> !llvm.ptr
        llvm.store %369, %371 : i32, !llvm.ptr
        cf.br ^bb60
        ^bb60:
        %372 = llvm.load %371 : !llvm.ptr -> i32
        %373 = arith.cmpi slt, %372, %364 : i32
        cf.cond_br %373, ^bb61, ^bb62
        ^bb61:
          %375 = llvm.load %356 : !llvm.ptr -> i32
          %376 = arith.extsi %375 : i32 to i64
          %377 = llvm.getelementptr %191[%376] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %374 = llvm.load %377 : !llvm.ptr -> i32
          %378 = llvm.load %371 : !llvm.ptr -> i32
          %379 = arith.extsi %378 : i32 to i64
          %380 = llvm.getelementptr %340[%379] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %374, %380 : i32, !llvm.ptr
          %381 = llvm.load %371 : !llvm.ptr -> i32
          %382 = arith.constant 1 : i32
          %383 = arith.addi %381, %382 : i32
          %384 = llvm.load %371 : !llvm.ptr -> i32
          %385 = arith.extsi %384 : i32 to i64
          %386 = llvm.getelementptr %333[%385] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %383, %386 : i32, !llvm.ptr
          %388 = llvm.load %371 : !llvm.ptr -> i32
          %387 = func.call @findp(%333, %388) : (!llvm.ptr, i32) -> i32
          llvm.store %387, %371 : i32, !llvm.ptr
          cf.br ^bb60
        ^bb62:
        %389 = llvm.load %356 : !llvm.ptr -> i32
        %390 = arith.constant 1 : i32
        %391 = arith.addi %389, %390 : i32
        llvm.store %391, %356 : i32, !llvm.ptr
        cf.br ^bb57
      ^bb59:
      %393 = arith.constant 0 : i32
      %392 = func.call @findp(%333, %393) : (!llvm.ptr, i32) -> i32
      %394 = arith.cmpi eq, %392, %332 : i32
      cf.cond_br %394, ^bb63, ^bb64
      ^bb63:
        %396 = arith.constant 1 : i32
        %397 = arith.addi %332, %396 : i32
        %398 = arith.extsi %397 : i32 to i64
        %399 = arith.constant 8 : i32
        %401 = arith.extsi %399 : i32 to i64
        %400 = arith.muli %398, %401 : i64
        %395 = func.call @malloc(%400) : (i64) -> !llvm.ptr
        %403 = arith.constant 1 : i32
        %404 = arith.addi %332, %403 : i32
        %405 = arith.extsi %404 : i32 to i64
        %406 = arith.constant 8 : i32
        %408 = arith.extsi %406 : i32 to i64
        %407 = arith.muli %405, %408 : i64
        %402 = func.call @malloc(%407) : (i64) -> !llvm.ptr
        %409 = arith.constant 0 : i32
        %411 = arith.constant 0 : i32
        %412 = arith.extsi %411 : i32 to i64
        %413 = llvm.getelementptr %340[%412] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %410 = llvm.load %413 : !llvm.ptr -> i32
        %414 = llvm.mlir.constant(1 : i64) : i64
        %415 = llvm.alloca %414 x i32 : (i64) -> !llvm.ptr
        llvm.store %410, %415 : i32, !llvm.ptr
        %416 = arith.constant 1 : i32
        llvm.store %416, %299 : i32, !llvm.ptr
        cf.br ^bb66(%409 : i32)
        ^bb66(%417: i32):
        %418 = llvm.load %299 : !llvm.ptr -> i32
        %419 = arith.cmpi slt, %418, %332 : i32
        cf.cond_br %419, ^bb67(%417 : i32), ^bb68(%417 : i32)
        ^bb67(%420: i32):
          %422 = llvm.load %299 : !llvm.ptr -> i32
          %423 = arith.extsi %422 : i32 to i64
          %424 = llvm.getelementptr %340[%423] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %421 = llvm.load %424 : !llvm.ptr -> i32
          %425 = llvm.load %415 : !llvm.ptr -> i32
          %426 = arith.cmpi ne, %421, %425 : i32
          %427 = scf.if %426 -> (i32) {
            %429 = llvm.load %299 : !llvm.ptr -> i32
            %430 = arith.extsi %429 : i32 to i64
            %431 = llvm.getelementptr %198[%430] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            %428 = llvm.load %431 : !llvm.ptr -> f64
            %432 = arith.extsi %420 : i32 to i64
            %433 = llvm.getelementptr %395[%432] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            llvm.store %428, %433 : f64, !llvm.ptr
            %434 = llvm.load %415 : !llvm.ptr -> i32
            %435 = arith.sitofp %434 : i32 to f64
            %436 = arith.mulf %435, %arg0 : f64
            %437 = arith.extsi %420 : i32 to i64
            %438 = llvm.getelementptr %402[%437] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            llvm.store %436, %438 : f64, !llvm.ptr
            %439 = arith.constant 1 : i32
            %440 = arith.addi %420, %439 : i32
            %442 = llvm.load %299 : !llvm.ptr -> i32
            %443 = arith.extsi %442 : i32 to i64
            %444 = llvm.getelementptr %340[%443] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %441 = llvm.load %444 : !llvm.ptr -> i32
            llvm.store %441, %415 : i32, !llvm.ptr
            scf.yield %440 : i32
          } else {
            scf.yield %420 : i32
          }
          %445 = llvm.load %299 : !llvm.ptr -> i32
          %446 = arith.constant 1 : i32
          %447 = arith.addi %445, %446 : i32
          llvm.store %447, %299 : i32, !llvm.ptr
          cf.br ^bb66(%427 : i32)
        ^bb68(%448: i32):
        %449 = arith.extsi %448 : i32 to i64
        %450 = llvm.getelementptr %395[%449] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %146, %450 : f64, !llvm.ptr
        %451 = llvm.load %415 : !llvm.ptr -> i32
        %452 = arith.sitofp %451 : i32 to f64
        %453 = arith.mulf %452, %arg0 : f64
        %454 = arith.extsi %448 : i32 to i64
        %455 = llvm.getelementptr %402[%454] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %453, %455 : f64, !llvm.ptr
        %456 = arith.constant 1 : i32
        %457 = arith.addi %448, %456 : i32
        func.call @free(%179) : (!llvm.ptr) -> ()
        func.call @free(%185) : (!llvm.ptr) -> ()
        func.call @free(%191) : (!llvm.ptr) -> ()
        func.call @free(%198) : (!llvm.ptr) -> ()
        func.call @free(%333) : (!llvm.ptr) -> ()
        func.call @free(%340) : (!llvm.ptr) -> ()
        %464 = llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %465 = llvm.insertvalue %395, %464[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %466 = llvm.insertvalue %402, %465[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %467 = llvm.insertvalue %457, %466[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %468 = llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %469 = llvm.extractvalue %467[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %470 = llvm.insertvalue %469, %468[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %471 = llvm.extractvalue %467[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %472 = llvm.insertvalue %471, %470[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %473 = llvm.extractvalue %467[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %474 = llvm.insertvalue %473, %472[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        %475 = llvm.mlir.constant(1 : i64) : i64
        %476 = llvm.alloca %475 x !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)> : (i64) -> !llvm.ptr
        llvm.store %474, %476 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>, !llvm.ptr
        %477 = llvm.load %476 : !llvm.ptr -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
        func.return %477 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      ^bb64:
        cf.br ^bb65
      ^bb65:
      func.call @free(%179) : (!llvm.ptr) -> ()
      func.call @free(%185) : (!llvm.ptr) -> ()
      func.call @free(%191) : (!llvm.ptr) -> ()
      func.call @free(%198) : (!llvm.ptr) -> ()
      func.call @free(%333) : (!llvm.ptr) -> ()
      func.call @free(%340) : (!llvm.ptr) -> ()
      %484 = llvm.load %153 : !llvm.ptr -> i32
      %485 = arith.constant 2 : i32
      %486 = arith.muli %484, %485 : i32
      llvm.store %486, %153 : i32, !llvm.ptr
      cf.br ^bb33
    ^bb35:
    %487 = llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %488 = llvm.mlir.zero : !llvm.ptr
    %489 = llvm.insertvalue %488, %487[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %490 = llvm.mlir.zero : !llvm.ptr
    %491 = llvm.insertvalue %490, %489[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %492 = arith.constant 0 : i32
    %493 = llvm.insertvalue %492, %491[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %494 = llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %495 = llvm.extractvalue %493[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %496 = llvm.insertvalue %495, %494[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %497 = llvm.extractvalue %493[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %498 = llvm.insertvalue %497, %496[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %499 = llvm.extractvalue %493[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %500 = llvm.insertvalue %499, %498[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    %501 = llvm.mlir.constant(1 : i64) : i64
    %502 = llvm.alloca %501 x !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)> : (i64) -> !llvm.ptr
    llvm.store %500, %502 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>, !llvm.ptr
    %503 = llvm.load %502 : !llvm.ptr -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
    func.return %503 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
  }
  func.func @hpush(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: f64, %arg4: i32) -> i32 {
    %504 = llvm.mlir.constant(1 : i64) : i64
    %505 = llvm.alloca %504 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg2, %505 : i32, !llvm.ptr
    %506 = llvm.load %505 : !llvm.ptr -> i32
    %507 = llvm.mlir.constant(1 : i64) : i64
    %508 = llvm.alloca %507 x i32 : (i64) -> !llvm.ptr
    llvm.store %506, %508 : i32, !llvm.ptr
    %509 = llvm.load %505 : !llvm.ptr -> i32
    %510 = arith.constant 1 : i32
    %511 = arith.addi %509, %510 : i32
    llvm.store %511, %505 : i32, !llvm.ptr
    %512 = llvm.load %508 : !llvm.ptr -> i32
    %513 = arith.extsi %512 : i32 to i64
    %514 = llvm.getelementptr %arg0[%513] : (!llvm.ptr, i64) -> !llvm.ptr, f64
    llvm.store %arg3, %514 : f64, !llvm.ptr
    %515 = llvm.load %508 : !llvm.ptr -> i32
    %516 = arith.extsi %515 : i32 to i64
    %517 = llvm.getelementptr %arg1[%516] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg4, %517 : i32, !llvm.ptr
    cf.br ^bb69
    ^bb69:
    %518 = llvm.load %508 : !llvm.ptr -> i32
    %519 = arith.constant 0 : i32
    %520 = arith.cmpi sgt, %518, %519 : i32
    cf.cond_br %520, ^bb70, ^bb71
    ^bb70:
      %521 = llvm.load %508 : !llvm.ptr -> i32
      %522 = arith.constant 1 : i32
      %523 = arith.subi %521, %522 : i32
      %524 = arith.constant 2 : i32
      %525 = arith.divsi %523, %524 : i32
      %527 = arith.extsi %525 : i32 to i64
      %528 = llvm.getelementptr %arg0[%527] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %526 = llvm.load %528 : !llvm.ptr -> f64
      %530 = llvm.load %508 : !llvm.ptr -> i32
      %531 = arith.extsi %530 : i32 to i64
      %532 = llvm.getelementptr %arg0[%531] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %529 = llvm.load %532 : !llvm.ptr -> f64
      %533 = arith.cmpf ole, %526, %529 : f64
      cf.cond_br %533, ^bb72, ^bb73
      ^bb72:
        cf.br ^bb71
      ^bb73:
        cf.br ^bb74
      ^bb74:
      %535 = arith.extsi %525 : i32 to i64
      %536 = llvm.getelementptr %arg0[%535] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %534 = llvm.load %536 : !llvm.ptr -> f64
      %538 = arith.extsi %525 : i32 to i64
      %539 = llvm.getelementptr %arg1[%538] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %537 = llvm.load %539 : !llvm.ptr -> i32
      %541 = llvm.load %508 : !llvm.ptr -> i32
      %542 = arith.extsi %541 : i32 to i64
      %543 = llvm.getelementptr %arg0[%542] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %540 = llvm.load %543 : !llvm.ptr -> f64
      %544 = arith.extsi %525 : i32 to i64
      %545 = llvm.getelementptr %arg0[%544] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %540, %545 : f64, !llvm.ptr
      %547 = llvm.load %508 : !llvm.ptr -> i32
      %548 = arith.extsi %547 : i32 to i64
      %549 = llvm.getelementptr %arg1[%548] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %546 = llvm.load %549 : !llvm.ptr -> i32
      %550 = arith.extsi %525 : i32 to i64
      %551 = llvm.getelementptr %arg1[%550] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %546, %551 : i32, !llvm.ptr
      %552 = llvm.load %508 : !llvm.ptr -> i32
      %553 = arith.extsi %552 : i32 to i64
      %554 = llvm.getelementptr %arg0[%553] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %534, %554 : f64, !llvm.ptr
      %555 = llvm.load %508 : !llvm.ptr -> i32
      %556 = arith.extsi %555 : i32 to i64
      %557 = llvm.getelementptr %arg1[%556] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %537, %557 : i32, !llvm.ptr
      llvm.store %525, %508 : i32, !llvm.ptr
      cf.br ^bb69
    ^bb71:
    %558 = llvm.load %505 : !llvm.ptr -> i32
    func.return %558 : i32
  }
  func.func @hpop(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: !llvm.ptr) -> i32 {
    %560 = arith.constant 0 : i32
    %561 = arith.extsi %560 : i32 to i64
    %562 = llvm.getelementptr %arg1[%561] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %559 = llvm.load %562 : !llvm.ptr -> i32
    %563 = arith.constant 0 : i32
    %564 = arith.extsi %563 : i32 to i64
    %565 = llvm.getelementptr %arg3[%564] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %559, %565 : i32, !llvm.ptr
    %566 = arith.constant 1 : i32
    %567 = arith.subi %arg2, %566 : i32
    %568 = llvm.mlir.constant(1 : i64) : i64
    %569 = llvm.alloca %568 x i32 : (i64) -> !llvm.ptr
    llvm.store %567, %569 : i32, !llvm.ptr
    %571 = llvm.load %569 : !llvm.ptr -> i32
    %572 = arith.extsi %571 : i32 to i64
    %573 = llvm.getelementptr %arg0[%572] : (!llvm.ptr, i64) -> !llvm.ptr, f64
    %570 = llvm.load %573 : !llvm.ptr -> f64
    %574 = arith.constant 0 : i32
    %575 = arith.extsi %574 : i32 to i64
    %576 = llvm.getelementptr %arg0[%575] : (!llvm.ptr, i64) -> !llvm.ptr, f64
    llvm.store %570, %576 : f64, !llvm.ptr
    %578 = llvm.load %569 : !llvm.ptr -> i32
    %579 = arith.extsi %578 : i32 to i64
    %580 = llvm.getelementptr %arg1[%579] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %577 = llvm.load %580 : !llvm.ptr -> i32
    %581 = arith.constant 0 : i32
    %582 = arith.extsi %581 : i32 to i64
    %583 = llvm.getelementptr %arg1[%582] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %577, %583 : i32, !llvm.ptr
    %584 = arith.constant 0 : i32
    %585 = llvm.mlir.constant(1 : i64) : i64
    %586 = llvm.alloca %585 x i32 : (i64) -> !llvm.ptr
    llvm.store %584, %586 : i32, !llvm.ptr
    cf.br ^bb75
    ^bb75:
    %587 = arith.constant 1 : i1
    cf.cond_br %587, ^bb76, ^bb77
    ^bb76:
      %588 = arith.constant 2 : i32
      %589 = llvm.load %586 : !llvm.ptr -> i32
      %590 = arith.muli %588, %589 : i32
      %591 = arith.constant 1 : i32
      %592 = arith.addi %590, %591 : i32
      %593 = arith.constant 2 : i32
      %594 = llvm.load %586 : !llvm.ptr -> i32
      %595 = arith.muli %593, %594 : i32
      %596 = arith.constant 2 : i32
      %597 = arith.addi %595, %596 : i32
      %598 = llvm.load %586 : !llvm.ptr -> i32
      %599 = llvm.mlir.constant(1 : i64) : i64
      %600 = llvm.alloca %599 x i32 : (i64) -> !llvm.ptr
      llvm.store %598, %600 : i32, !llvm.ptr
      %601 = llvm.load %569 : !llvm.ptr -> i32
      %602 = arith.cmpi slt, %592, %601 : i32
      cf.cond_br %602, ^bb78, ^bb79
      ^bb78:
        %604 = arith.extsi %592 : i32 to i64
        %605 = llvm.getelementptr %arg0[%604] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %603 = llvm.load %605 : !llvm.ptr -> f64
        %607 = llvm.load %600 : !llvm.ptr -> i32
        %608 = arith.extsi %607 : i32 to i64
        %609 = llvm.getelementptr %arg0[%608] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %606 = llvm.load %609 : !llvm.ptr -> f64
        %610 = arith.cmpf olt, %603, %606 : f64
        cf.cond_br %610, ^bb81, ^bb82
        ^bb81:
          llvm.store %592, %600 : i32, !llvm.ptr
          cf.br ^bb83
        ^bb82:
          cf.br ^bb83
        ^bb83:
        cf.br ^bb80
      ^bb79:
        cf.br ^bb80
      ^bb80:
      %611 = llvm.load %569 : !llvm.ptr -> i32
      %612 = arith.cmpi slt, %597, %611 : i32
      cf.cond_br %612, ^bb84, ^bb85
      ^bb84:
        %614 = arith.extsi %597 : i32 to i64
        %615 = llvm.getelementptr %arg0[%614] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %613 = llvm.load %615 : !llvm.ptr -> f64
        %617 = llvm.load %600 : !llvm.ptr -> i32
        %618 = arith.extsi %617 : i32 to i64
        %619 = llvm.getelementptr %arg0[%618] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %616 = llvm.load %619 : !llvm.ptr -> f64
        %620 = arith.cmpf olt, %613, %616 : f64
        cf.cond_br %620, ^bb87, ^bb88
        ^bb87:
          llvm.store %597, %600 : i32, !llvm.ptr
          cf.br ^bb89
        ^bb88:
          cf.br ^bb89
        ^bb89:
        cf.br ^bb86
      ^bb85:
        cf.br ^bb86
      ^bb86:
      %621 = llvm.load %600 : !llvm.ptr -> i32
      %622 = llvm.load %586 : !llvm.ptr -> i32
      %623 = arith.cmpi eq, %621, %622 : i32
      cf.cond_br %623, ^bb90, ^bb91
      ^bb90:
        cf.br ^bb77
      ^bb91:
        cf.br ^bb92
      ^bb92:
      %625 = llvm.load %586 : !llvm.ptr -> i32
      %626 = arith.extsi %625 : i32 to i64
      %627 = llvm.getelementptr %arg0[%626] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %624 = llvm.load %627 : !llvm.ptr -> f64
      %629 = llvm.load %586 : !llvm.ptr -> i32
      %630 = arith.extsi %629 : i32 to i64
      %631 = llvm.getelementptr %arg1[%630] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %628 = llvm.load %631 : !llvm.ptr -> i32
      %633 = llvm.load %600 : !llvm.ptr -> i32
      %634 = arith.extsi %633 : i32 to i64
      %635 = llvm.getelementptr %arg0[%634] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %632 = llvm.load %635 : !llvm.ptr -> f64
      %636 = llvm.load %586 : !llvm.ptr -> i32
      %637 = arith.extsi %636 : i32 to i64
      %638 = llvm.getelementptr %arg0[%637] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %632, %638 : f64, !llvm.ptr
      %640 = llvm.load %600 : !llvm.ptr -> i32
      %641 = arith.extsi %640 : i32 to i64
      %642 = llvm.getelementptr %arg1[%641] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %639 = llvm.load %642 : !llvm.ptr -> i32
      %643 = llvm.load %586 : !llvm.ptr -> i32
      %644 = arith.extsi %643 : i32 to i64
      %645 = llvm.getelementptr %arg1[%644] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %639, %645 : i32, !llvm.ptr
      %646 = llvm.load %600 : !llvm.ptr -> i32
      %647 = arith.extsi %646 : i32 to i64
      %648 = llvm.getelementptr %arg0[%647] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %624, %648 : f64, !llvm.ptr
      %649 = llvm.load %600 : !llvm.ptr -> i32
      %650 = arith.extsi %649 : i32 to i64
      %651 = llvm.getelementptr %arg1[%650] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %628, %651 : i32, !llvm.ptr
      %652 = llvm.load %600 : !llvm.ptr -> i32
      llvm.store %652, %586 : i32, !llvm.ptr
      cf.br ^bb75
    ^bb77:
    %653 = llvm.load %569 : !llvm.ptr -> i32
    func.return %653 : i32
  }
  func.func @merge_max_sum(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: i32, %arg4: f64) -> f64 {
    %655 = arith.extsi %arg3 : i32 to i64
    %656 = arith.constant 4 : i32
    %657 = arith.extsi %656 : i32 to i64
    %654 = func.call @calloc(%655, %657) : (i64, i64) -> !llvm.ptr
    %659 = arith.extsi %arg3 : i32 to i64
    %660 = arith.constant 8 : i32
    %662 = arith.extsi %660 : i32 to i64
    %661 = arith.muli %659, %662 : i64
    %658 = func.call @malloc(%661) : (i64) -> !llvm.ptr
    %663 = arith.constant 0.0 : f32
    %664 = arith.extf %663 : f32 to f64
    %665 = llvm.mlir.constant(1 : i64) : i64
    %666 = llvm.alloca %665 x f64 : (i64) -> !llvm.ptr
    llvm.store %664, %666 : f64, !llvm.ptr
    %667 = arith.constant 0 : i32
    %668 = llvm.mlir.constant(1 : i64) : i64
    %669 = llvm.alloca %668 x i32 : (i64) -> !llvm.ptr
    llvm.store %667, %669 : i32, !llvm.ptr
    cf.br ^bb93
    ^bb93:
    %670 = llvm.load %669 : !llvm.ptr -> i32
    %671 = arith.cmpi slt, %670, %arg3 : i32
    cf.cond_br %671, ^bb94, ^bb95
    ^bb94:
      %674 = llvm.load %669 : !llvm.ptr -> i32
      %675 = arith.extsi %674 : i32 to i64
      %676 = llvm.getelementptr %arg1[%675] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %673 = llvm.load %676 : !llvm.ptr -> !llvm.ptr
      %677 = arith.constant 0 : i32
      %678 = arith.extsi %677 : i32 to i64
      %679 = llvm.getelementptr %673[%678] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %672 = llvm.load %679 : !llvm.ptr -> f64
      %680 = llvm.load %669 : !llvm.ptr -> i32
      %681 = arith.extsi %680 : i32 to i64
      %682 = llvm.getelementptr %658[%681] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %672, %682 : f64, !llvm.ptr
      %683 = llvm.load %666 : !llvm.ptr -> f64
      %685 = llvm.load %669 : !llvm.ptr -> i32
      %686 = arith.extsi %685 : i32 to i64
      %687 = llvm.getelementptr %658[%686] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %684 = llvm.load %687 : !llvm.ptr -> f64
      %688 = arith.addf %683, %684 : f64
      llvm.store %688, %666 : f64, !llvm.ptr
      %689 = llvm.load %669 : !llvm.ptr -> i32
      %690 = arith.constant 1 : i32
      %691 = arith.addi %689, %690 : i32
      llvm.store %691, %669 : i32, !llvm.ptr
      cf.br ^bb93
    ^bb95:
    %693 = arith.constant 2 : i32
    %694 = arith.muli %arg3, %693 : i32
    %695 = arith.constant 8 : i32
    %696 = arith.addi %694, %695 : i32
    %697 = arith.extsi %696 : i32 to i64
    %698 = arith.constant 8 : i32
    %700 = arith.extsi %698 : i32 to i64
    %699 = arith.muli %697, %700 : i64
    %692 = func.call @malloc(%699) : (i64) -> !llvm.ptr
    %702 = arith.constant 2 : i32
    %703 = arith.muli %arg3, %702 : i32
    %704 = arith.constant 8 : i32
    %705 = arith.addi %703, %704 : i32
    %706 = arith.extsi %705 : i32 to i64
    %707 = arith.constant 4 : i32
    %709 = arith.extsi %707 : i32 to i64
    %708 = arith.muli %706, %709 : i64
    %701 = func.call @malloc(%708) : (i64) -> !llvm.ptr
    %710 = arith.constant 0 : i32
    %711 = llvm.mlir.constant(1 : i64) : i64
    %712 = llvm.alloca %711 x i32 : (i64) -> !llvm.ptr
    llvm.store %710, %712 : i32, !llvm.ptr
    %713 = arith.constant 0 : i32
    llvm.store %713, %669 : i32, !llvm.ptr
    cf.br ^bb96
    ^bb96:
    %714 = llvm.load %669 : !llvm.ptr -> i32
    %715 = arith.cmpi slt, %714, %arg3 : i32
    cf.cond_br %715, ^bb97, ^bb98
    ^bb97:
      %717 = llvm.load %712 : !llvm.ptr -> i32
      %720 = llvm.load %669 : !llvm.ptr -> i32
      %721 = arith.extsi %720 : i32 to i64
      %722 = llvm.getelementptr %arg0[%721] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %719 = llvm.load %722 : !llvm.ptr -> !llvm.ptr
      %723 = arith.constant 0 : i32
      %724 = arith.extsi %723 : i32 to i64
      %725 = llvm.getelementptr %719[%724] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %718 = llvm.load %725 : !llvm.ptr -> f64
      %726 = llvm.load %669 : !llvm.ptr -> i32
      %716 = func.call @hpush(%692, %701, %717, %718, %726) : (!llvm.ptr, !llvm.ptr, i32, f64, i32) -> i32
      llvm.store %716, %712 : i32, !llvm.ptr
      %727 = llvm.load %669 : !llvm.ptr -> i32
      %728 = arith.constant 1 : i32
      %729 = arith.addi %727, %728 : i32
      llvm.store %729, %669 : i32, !llvm.ptr
      cf.br ^bb96
    ^bb98:
    %730 = arith.constant 0.0 : f32
    %731 = arith.extf %730 : f32 to f64
    %732 = llvm.mlir.constant(1 : i64) : i64
    %733 = llvm.alloca %732 x f64 : (i64) -> !llvm.ptr
    llvm.store %731, %733 : f64, !llvm.ptr
    %734 = llvm.load %666 : !llvm.ptr -> f64
    %735 = llvm.mlir.constant(1 : i64) : i64
    %736 = llvm.alloca %735 x f64 : (i64) -> !llvm.ptr
    llvm.store %734, %736 : f64, !llvm.ptr
    %737 = arith.constant 0 : f32
    %738 = arith.extf %737 : f32 to f64
    %740 = arith.constant 512 : i32
    %741 = arith.constant 4 : i32
    %742 = arith.muli %740, %741 : i32
    %743 = arith.extsi %742 : i32 to i64
    %739 = func.call @malloc(%743) : (i64) -> !llvm.ptr
    cf.br ^bb99
    ^bb99:
    %744 = llvm.load %712 : !llvm.ptr -> i32
    %745 = arith.constant 0 : i32
    %746 = arith.cmpi sgt, %744, %745 : i32
    cf.cond_br %746, ^bb100, ^bb101
    ^bb100:
      %748 = arith.constant 0 : i32
      %749 = arith.extsi %748 : i32 to i64
      %750 = llvm.getelementptr %692[%749] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      %747 = llvm.load %750 : !llvm.ptr -> f64
      %751 = llvm.load %733 : !llvm.ptr -> f64
      %752 = arith.constant 0 : f32
      %754 = arith.extf %752 : f32 to f64
      %753 = arith.addf %751, %754 : f64
      %755 = arith.cmpf ogt, %747, %753 : f64
      cf.cond_br %755, ^bb102, ^bb103
      ^bb102:
        %756 = llvm.load %666 : !llvm.ptr -> f64
        %757 = llvm.load %736 : !llvm.ptr -> f64
        %758 = arith.cmpf ogt, %756, %757 : f64
        cf.cond_br %758, ^bb105, ^bb106
        ^bb105:
          %759 = llvm.load %666 : !llvm.ptr -> f64
          llvm.store %759, %736 : f64, !llvm.ptr
          cf.br ^bb107
        ^bb106:
          cf.br ^bb107
        ^bb107:
        cf.br ^bb104
      ^bb103:
        cf.br ^bb104
      ^bb104:
      %760 = arith.constant 0 : i32
      cf.br ^bb108(%760 : i32)
      ^bb108(%761: i32):
      %762 = llvm.load %712 : !llvm.ptr -> i32
      %763 = arith.constant 0 : i32
      %764 = arith.cmpi sgt, %762, %763 : i32
      %765 = scf.if %764 -> (i1) {
        %767 = arith.constant 0 : i32
        %768 = arith.extsi %767 : i32 to i64
        %769 = llvm.getelementptr %692[%768] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %766 = llvm.load %769 : !llvm.ptr -> f64
        %770 = arith.subf %766, %747 : f64
        %771 = math.absf %770 : f64
        %772 = arith.cmpf ole, %771, %738 : f64
        scf.yield %772 : i1
      } else {
        %773 = arith.constant false
        scf.yield %773 : i1
      }
      cf.cond_br %765, ^bb109(%761 : i32), ^bb110(%761 : i32)
      ^bb109(%774: i32):
        %776 = arith.constant 1 : i32
        %777 = arith.constant 4 : i32
        %778 = arith.extsi %776 : i32 to i64
        %779 = arith.extsi %777 : i32 to i64
        %775 = func.call @calloc(%778, %779) : (i64, i64) -> !llvm.ptr
        %781 = llvm.load %712 : !llvm.ptr -> i32
        %780 = func.call @hpop(%692, %701, %781, %775) : (!llvm.ptr, !llvm.ptr, i32, !llvm.ptr) -> i32
        llvm.store %780, %712 : i32, !llvm.ptr
        %782 = arith.constant 512 : i32
        %783 = arith.cmpi slt, %774, %782 : i32
        %784 = scf.if %783 -> (i32) {
          %786 = arith.constant 0 : i32
          %787 = arith.extsi %786 : i32 to i64
          %788 = llvm.getelementptr %775[%787] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %785 = llvm.load %788 : !llvm.ptr -> i32
          %789 = arith.extsi %774 : i32 to i64
          %790 = llvm.getelementptr %739[%789] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %785, %790 : i32, !llvm.ptr
          %791 = arith.constant 1 : i32
          %792 = arith.addi %774, %791 : i32
          scf.yield %792 : i32
        } else {
          scf.yield %774 : i32
        }
        func.call @free(%775) : (!llvm.ptr) -> ()
        cf.br ^bb108(%784 : i32)
      ^bb110(%794: i32):
      llvm.store %747, %733 : f64, !llvm.ptr
      %795 = llvm.load %733 : !llvm.ptr -> f64
      %796 = arith.constant 0 : f32
      %798 = arith.extf %796 : f32 to f64
      %797 = arith.subf %arg4, %798 : f64
      %799 = arith.cmpf oge, %795, %797 : f64
      cf.cond_br %799, ^bb111, ^bb112
      ^bb111:
        cf.br ^bb101
      ^bb112:
        cf.br ^bb113
      ^bb113:
      %800 = arith.constant 0 : i32
      %801 = llvm.mlir.constant(1 : i64) : i64
      %802 = llvm.alloca %801 x i32 : (i64) -> !llvm.ptr
      llvm.store %800, %802 : i32, !llvm.ptr
      cf.br ^bb114
      ^bb114:
      %803 = llvm.load %802 : !llvm.ptr -> i32
      %804 = arith.cmpi slt, %803, %794 : i32
      cf.cond_br %804, ^bb115, ^bb116
      ^bb115:
        %806 = llvm.load %802 : !llvm.ptr -> i32
        %807 = arith.extsi %806 : i32 to i64
        %808 = llvm.getelementptr %739[%807] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %805 = llvm.load %808 : !llvm.ptr -> i32
        %810 = arith.extsi %805 : i32 to i64
        %811 = llvm.getelementptr %658[%810] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %809 = llvm.load %811 : !llvm.ptr -> f64
        %813 = arith.extsi %805 : i32 to i64
        %814 = llvm.getelementptr %654[%813] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %812 = llvm.load %814 : !llvm.ptr -> i32
        %815 = arith.constant 1 : i32
        %816 = arith.addi %812, %815 : i32
        %817 = arith.extsi %805 : i32 to i64
        %818 = llvm.getelementptr %654[%817] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %816, %818 : i32, !llvm.ptr
        %821 = arith.extsi %805 : i32 to i64
        %822 = llvm.getelementptr %arg1[%821] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
        %820 = llvm.load %822 : !llvm.ptr -> !llvm.ptr
        %824 = arith.extsi %805 : i32 to i64
        %825 = llvm.getelementptr %654[%824] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %823 = llvm.load %825 : !llvm.ptr -> i32
        %826 = arith.extsi %823 : i32 to i64
        %827 = llvm.getelementptr %820[%826] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %819 = llvm.load %827 : !llvm.ptr -> f64
        %828 = arith.extsi %805 : i32 to i64
        %829 = llvm.getelementptr %658[%828] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %819, %829 : f64, !llvm.ptr
        %830 = llvm.load %666 : !llvm.ptr -> f64
        %831 = arith.addf %830, %819 : f64
        %832 = arith.subf %831, %809 : f64
        llvm.store %832, %666 : f64, !llvm.ptr
        %834 = llvm.load %712 : !llvm.ptr -> i32
        %837 = arith.extsi %805 : i32 to i64
        %838 = llvm.getelementptr %arg0[%837] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
        %836 = llvm.load %838 : !llvm.ptr -> !llvm.ptr
        %840 = arith.extsi %805 : i32 to i64
        %841 = llvm.getelementptr %654[%840] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %839 = llvm.load %841 : !llvm.ptr -> i32
        %842 = arith.extsi %839 : i32 to i64
        %843 = llvm.getelementptr %836[%842] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %835 = llvm.load %843 : !llvm.ptr -> f64
        %833 = func.call @hpush(%692, %701, %834, %835, %805) : (!llvm.ptr, !llvm.ptr, i32, f64, i32) -> i32
        llvm.store %833, %712 : i32, !llvm.ptr
        %844 = llvm.load %802 : !llvm.ptr -> i32
        %845 = arith.constant 1 : i32
        %846 = arith.addi %844, %845 : i32
        llvm.store %846, %802 : i32, !llvm.ptr
        cf.br ^bb114
      ^bb116:
      cf.br ^bb99
    ^bb101:
    func.call @free(%654) : (!llvm.ptr) -> ()
    func.call @free(%658) : (!llvm.ptr) -> ()
    func.call @free(%692) : (!llvm.ptr) -> ()
    func.call @free(%701) : (!llvm.ptr) -> ()
    func.call @free(%739) : (!llvm.ptr) -> ()
    %852 = llvm.load %736 : !llvm.ptr -> f64
    func.return %852 : f64
  }
  func.func @primes_up_to(%arg0: i32, %arg1: !llvm.ptr) -> !llvm.ptr {
    %854 = arith.constant 1 : i32
    %855 = arith.addi %arg0, %854 : i32
    %856 = arith.extsi %855 : i32 to i64
    %857 = arith.constant 1 : i32
    %858 = arith.extsi %857 : i32 to i64
    %853 = func.call @calloc(%856, %858) : (i64, i64) -> !llvm.ptr
    %859 = arith.constant 0 : i32
    %860 = llvm.mlir.constant(1 : i64) : i64
    %861 = llvm.alloca %860 x i32 : (i64) -> !llvm.ptr
    llvm.store %859, %861 : i32, !llvm.ptr
    cf.br ^bb117
    ^bb117:
    %862 = llvm.load %861 : !llvm.ptr -> i32
    %863 = arith.cmpi sle, %862, %arg0 : i32
    cf.cond_br %863, ^bb118, ^bb119
    ^bb118:
      %864 = arith.constant 1 : i32
      %865 = llvm.load %861 : !llvm.ptr -> i32
      %866 = arith.trunci %864 : i32 to i8
      %867 = arith.extsi %865 : i32 to i64
      %868 = llvm.getelementptr %853[%867] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      llvm.store %866, %868 : i8, !llvm.ptr
      %869 = llvm.load %861 : !llvm.ptr -> i32
      %870 = arith.constant 1 : i32
      %871 = arith.addi %869, %870 : i32
      llvm.store %871, %861 : i32, !llvm.ptr
      cf.br ^bb117
    ^bb119:
    %872 = arith.constant 0 : i32
    %873 = arith.constant 0 : i32
    %874 = arith.trunci %872 : i32 to i8
    %875 = arith.extsi %873 : i32 to i64
    %876 = llvm.getelementptr %853[%875] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %874, %876 : i8, !llvm.ptr
    %877 = arith.constant 0 : i32
    %878 = arith.constant 1 : i32
    %879 = arith.trunci %877 : i32 to i8
    %880 = arith.extsi %878 : i32 to i64
    %881 = llvm.getelementptr %853[%880] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %879, %881 : i8, !llvm.ptr
    %882 = arith.sitofp %arg0 : i32 to f64
    %883 = math.sqrt %882 : f64
    %884 = arith.fptosi %883 : f64 to i32
    %885 = arith.constant 2 : i32
    llvm.store %885, %861 : i32, !llvm.ptr
    cf.br ^bb120
    ^bb120:
    %886 = llvm.load %861 : !llvm.ptr -> i32
    %887 = arith.cmpi sle, %886, %884 : i32
    cf.cond_br %887, ^bb121, ^bb122
    ^bb121:
      %889 = llvm.load %861 : !llvm.ptr -> i32
      %890 = arith.extsi %889 : i32 to i64
      %891 = llvm.getelementptr %853[%890] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %888 = llvm.load %891 : !llvm.ptr -> i8
      %892 = arith.constant 1 : i32
      %894 = arith.extsi %888 : i8 to i32
      %893 = arith.cmpi eq, %894, %892 : i32
      cf.cond_br %893, ^bb123, ^bb124
      ^bb123:
        %895 = llvm.load %861 : !llvm.ptr -> i32
        %896 = arith.extsi %895 : i32 to i64
        %897 = llvm.load %861 : !llvm.ptr -> i32
        %898 = arith.extsi %897 : i32 to i64
        %899 = arith.muli %896, %898 : i64
        %900 = llvm.mlir.constant(1 : i64) : i64
        %901 = llvm.alloca %900 x i64 : (i64) -> !llvm.ptr
        llvm.store %899, %901 : i64, !llvm.ptr
        cf.br ^bb126
        ^bb126:
        %902 = llvm.load %901 : !llvm.ptr -> i64
        %903 = arith.extsi %arg0 : i32 to i64
        %904 = arith.cmpi sle, %902, %903 : i64
        cf.cond_br %904, ^bb127, ^bb128
        ^bb127:
          %905 = arith.constant 0 : i32
          %906 = llvm.load %901 : !llvm.ptr -> i64
          %907 = arith.trunci %905 : i32 to i8
          %908 = llvm.getelementptr %853[%906] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %907, %908 : i8, !llvm.ptr
          %909 = llvm.load %901 : !llvm.ptr -> i64
          %910 = llvm.load %861 : !llvm.ptr -> i32
          %911 = arith.extsi %910 : i32 to i64
          %912 = arith.addi %909, %911 : i64
          llvm.store %912, %901 : i64, !llvm.ptr
          cf.br ^bb126
        ^bb128:
        cf.br ^bb125
      ^bb124:
        cf.br ^bb125
      ^bb125:
      %913 = llvm.load %861 : !llvm.ptr -> i32
      %914 = arith.constant 1 : i32
      %915 = arith.addi %913, %914 : i32
      llvm.store %915, %861 : i32, !llvm.ptr
      cf.br ^bb120
    ^bb122:
    %916 = arith.constant 0 : i32
    %917 = llvm.mlir.constant(1 : i64) : i64
    %918 = llvm.alloca %917 x i32 : (i64) -> !llvm.ptr
    llvm.store %916, %918 : i32, !llvm.ptr
    %919 = arith.constant 2 : i32
    llvm.store %919, %861 : i32, !llvm.ptr
    cf.br ^bb129
    ^bb129:
    %920 = llvm.load %861 : !llvm.ptr -> i32
    %921 = arith.cmpi sle, %920, %arg0 : i32
    cf.cond_br %921, ^bb130, ^bb131
    ^bb130:
      %923 = llvm.load %861 : !llvm.ptr -> i32
      %924 = arith.extsi %923 : i32 to i64
      %925 = llvm.getelementptr %853[%924] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %922 = llvm.load %925 : !llvm.ptr -> i8
      %926 = arith.constant 1 : i32
      %928 = arith.extsi %922 : i8 to i32
      %927 = arith.cmpi eq, %928, %926 : i32
      cf.cond_br %927, ^bb132, ^bb133
      ^bb132:
        %929 = llvm.load %918 : !llvm.ptr -> i32
        %930 = arith.constant 1 : i32
        %931 = arith.addi %929, %930 : i32
        llvm.store %931, %918 : i32, !llvm.ptr
        cf.br ^bb134
      ^bb133:
        cf.br ^bb134
      ^bb134:
      %932 = llvm.load %861 : !llvm.ptr -> i32
      %933 = arith.constant 1 : i32
      %934 = arith.addi %932, %933 : i32
      llvm.store %934, %861 : i32, !llvm.ptr
      cf.br ^bb129
    ^bb131:
    %936 = llvm.load %918 : !llvm.ptr -> i32
    %937 = arith.extsi %936 : i32 to i64
    %938 = arith.constant 4 : i32
    %940 = arith.extsi %938 : i32 to i64
    %939 = arith.muli %937, %940 : i64
    %935 = func.call @malloc(%939) : (i64) -> !llvm.ptr
    %941 = arith.constant 0 : i32
    llvm.store %941, %918 : i32, !llvm.ptr
    %942 = arith.constant 2 : i32
    llvm.store %942, %861 : i32, !llvm.ptr
    cf.br ^bb135
    ^bb135:
    %943 = llvm.load %861 : !llvm.ptr -> i32
    %944 = arith.cmpi sle, %943, %arg0 : i32
    cf.cond_br %944, ^bb136, ^bb137
    ^bb136:
      %946 = llvm.load %861 : !llvm.ptr -> i32
      %947 = arith.extsi %946 : i32 to i64
      %948 = llvm.getelementptr %853[%947] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %945 = llvm.load %948 : !llvm.ptr -> i8
      %949 = arith.constant 1 : i32
      %951 = arith.extsi %945 : i8 to i32
      %950 = arith.cmpi eq, %951, %949 : i32
      cf.cond_br %950, ^bb138, ^bb139
      ^bb138:
        %952 = llvm.load %861 : !llvm.ptr -> i32
        %953 = llvm.load %918 : !llvm.ptr -> i32
        %954 = arith.extsi %953 : i32 to i64
        %955 = llvm.getelementptr %935[%954] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %952, %955 : i32, !llvm.ptr
        %956 = llvm.load %918 : !llvm.ptr -> i32
        %957 = arith.constant 1 : i32
        %958 = arith.addi %956, %957 : i32
        llvm.store %958, %918 : i32, !llvm.ptr
        cf.br ^bb140
      ^bb139:
        cf.br ^bb140
      ^bb140:
      %959 = llvm.load %861 : !llvm.ptr -> i32
      %960 = arith.constant 1 : i32
      %961 = arith.addi %959, %960 : i32
      llvm.store %961, %861 : i32, !llvm.ptr
      cf.br ^bb135
    ^bb137:
    func.call @free(%853) : (!llvm.ptr) -> ()
    %963 = llvm.load %918 : !llvm.ptr -> i32
    %964 = arith.constant 0 : i32
    %965 = arith.extsi %964 : i32 to i64
    %966 = llvm.getelementptr %arg1[%965] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %963, %966 : i32, !llvm.ptr
    func.return %935 : !llvm.ptr
  }
  func.func @main() -> i32 {
    %967 = arith.constant 100 : i32
    %968 = arith.constant 0.00002 : f32
    %969 = arith.extf %968 : f32 to f64
    %971 = arith.constant 1 : i32
    %972 = arith.constant 4 : i32
    %973 = arith.extsi %971 : i32 to i64
    %974 = arith.extsi %972 : i32 to i64
    %970 = func.call @calloc(%973, %974) : (i64, i64) -> !llvm.ptr
    %975 = func.call @primes_up_to(%967, %970) : (i32, !llvm.ptr) -> !llvm.ptr
    %977 = arith.constant 0 : i32
    %978 = arith.extsi %977 : i32 to i64
    %979 = llvm.getelementptr %970[%978] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %976 = llvm.load %979 : !llvm.ptr -> i32
    func.call @free(%970) : (!llvm.ptr) -> ()
    %982 = arith.extsi %976 : i32 to i64
    %983 = arith.constant 8 : i32
    %984 = arith.extsi %983 : i32 to i64
    %981 = func.call @calloc(%982, %984) : (i64, i64) -> !llvm.ptr
    %986 = arith.extsi %976 : i32 to i64
    %987 = arith.constant 8 : i32
    %988 = arith.extsi %987 : i32 to i64
    %985 = func.call @calloc(%986, %988) : (i64, i64) -> !llvm.ptr
    %990 = arith.extsi %976 : i32 to i64
    %991 = arith.constant 4 : i32
    %992 = arith.extsi %991 : i32 to i64
    %989 = func.call @calloc(%990, %992) : (i64, i64) -> !llvm.ptr
    %993 = arith.constant 0 : i32
    %994 = llvm.mlir.constant(1 : i64) : i64
    %995 = llvm.alloca %994 x i32 : (i64) -> !llvm.ptr
    llvm.store %993, %995 : i32, !llvm.ptr
    cf.br ^bb141
    ^bb141:
    %996 = llvm.load %995 : !llvm.ptr -> i32
    %997 = arith.cmpi slt, %996, %976 : i32
    cf.cond_br %997, ^bb142, ^bb143
    ^bb142:
      %999 = arith.constant 1.0 : f32
      %1001 = llvm.load %995 : !llvm.ptr -> i32
      %1002 = arith.extsi %1001 : i32 to i64
      %1003 = llvm.getelementptr %975[%1002] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1000 = llvm.load %1003 : !llvm.ptr -> i32
      %1004 = arith.sitofp %1000 : i32 to f64
      %1005 = math.sqrt %1004 : f64
      %1007 = arith.extf %999 : f32 to f64
      %1006 = arith.divf %1007, %1005 : f64
      %998 = func.call @build_piecewise(%1006, %969) : (f64, f64) -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1008 = llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1009 = llvm.extractvalue %998[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1010 = llvm.insertvalue %1009, %1008[0] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1011 = llvm.extractvalue %998[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1012 = llvm.insertvalue %1011, %1010[1] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1013 = llvm.extractvalue %998[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1014 = llvm.insertvalue %1013, %1012[2] : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1015 = llvm.mlir.constant(1 : i64) : i64
      %1016 = llvm.alloca %1015 x !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)> : (i64) -> !llvm.ptr
      llvm.store %1014, %1016 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>, !llvm.ptr
      %1017 = llvm.load %1016 : !llvm.ptr -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1018 = llvm.mlir.constant(1 : i64) : i64
      %1019 = llvm.alloca %1018 x !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)> : (i64) -> !llvm.ptr
      llvm.store %1017, %1019 : !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>, !llvm.ptr
      %1020 = llvm.load %1019 : !llvm.ptr -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1021 = llvm.getelementptr %1019[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1022 = llvm.load %1021 : !llvm.ptr -> !llvm.ptr
      %1023 = llvm.load %995 : !llvm.ptr -> i32
      %1024 = arith.extsi %1023 : i32 to i64
      %1025 = llvm.getelementptr %981[%1024] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      llvm.store %1022, %1025 : !llvm.ptr, !llvm.ptr
      %1026 = llvm.load %1019 : !llvm.ptr -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1027 = llvm.getelementptr %1019[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1028 = llvm.load %1027 : !llvm.ptr -> !llvm.ptr
      %1029 = llvm.load %995 : !llvm.ptr -> i32
      %1030 = arith.extsi %1029 : i32 to i64
      %1031 = llvm.getelementptr %985[%1030] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      llvm.store %1028, %1031 : !llvm.ptr, !llvm.ptr
      %1032 = llvm.load %1019 : !llvm.ptr -> !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1033 = llvm.getelementptr %1019[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(!llvm.ptr, !llvm.ptr, i32)>
      %1034 = llvm.load %1033 : !llvm.ptr -> i32
      %1035 = llvm.load %995 : !llvm.ptr -> i32
      %1036 = arith.extsi %1035 : i32 to i64
      %1037 = llvm.getelementptr %989[%1036] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1034, %1037 : i32, !llvm.ptr
      %1038 = llvm.load %995 : !llvm.ptr -> i32
      %1039 = arith.constant 1 : i32
      %1040 = arith.addi %1038, %1039 : i32
      llvm.store %1040, %995 : i32, !llvm.ptr
      cf.br ^bb141
    ^bb143:
    %1042 = arith.constant 1.0 : f32
    %1044 = arith.extf %1042 : f32 to f64
    %1043 = arith.subf %1044, %969 : f64
    %1041 = func.call @merge_max_sum(%981, %985, %989, %976, %1043) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i32, f64) -> f64
    %1045 = arith.constant 0 : i32
    llvm.store %1045, %995 : i32, !llvm.ptr
    cf.br ^bb144
    ^bb144:
    %1046 = llvm.load %995 : !llvm.ptr -> i32
    %1047 = arith.cmpi slt, %1046, %976 : i32
    cf.cond_br %1047, ^bb145, ^bb146
    ^bb145:
      %1050 = llvm.load %995 : !llvm.ptr -> i32
      %1051 = arith.extsi %1050 : i32 to i64
      %1052 = llvm.getelementptr %981[%1051] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %1049 = llvm.load %1052 : !llvm.ptr -> !llvm.ptr
      func.call @free(%1049) : (!llvm.ptr) -> ()
      %1055 = llvm.load %995 : !llvm.ptr -> i32
      %1056 = arith.extsi %1055 : i32 to i64
      %1057 = llvm.getelementptr %985[%1056] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %1054 = llvm.load %1057 : !llvm.ptr -> !llvm.ptr
      func.call @free(%1054) : (!llvm.ptr) -> ()
      %1058 = llvm.load %995 : !llvm.ptr -> i32
      %1059 = arith.constant 1 : i32
      %1060 = arith.addi %1058, %1059 : i32
      llvm.store %1060, %995 : i32, !llvm.ptr
      cf.br ^bb144
    ^bb146:
    func.call @free(%981) : (!llvm.ptr) -> ()
    func.call @free(%985) : (!llvm.ptr) -> ()
    func.call @free(%989) : (!llvm.ptr) -> ()
    func.call @free(%975) : (!llvm.ptr) -> ()
    %1065 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %1066 = llvm.call @printf(%1065, %1041) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, f64) -> i32
    %1067 = arith.constant 0 : i32
    func.return %1067 : i32
  }
}