Problem 548

Gozinta Chains — sum n <= 10^16 with g(n)=n.

Answer12144044603581281
Output12144044603581281
StatusPASS
Native helperno
Runtime770 ms
Peak memory1920 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 548
# Gozinta Chains — sum n <= 10^16 with g(n)=n.

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

const LIMIT: i64 = 10000000000000000
const MAX_EXP_SUM: i64 = 54
const MAX_N: i64 = 110

function gcd(a0: i64, b0: i64) -> i64 {
    let mut a: i64 = a0
    let mut b: i64 = b0
    while b != 0 {
        let t: i64 = a % b
        a = b
        b = t
    }
    return a
}

function init_comb(comb: ptr<i64>, binom: ptr<i64>) -> void {
    let mut n: i64 = 0
    while n <= MAX_N {
        comb[n * MAX_N + 0] = 1
        let mut k: i64 = 1
        while k <= n {
            if k < n {
                comb[n * MAX_N + k] = comb[(n - 1) * MAX_N + (k - 1)] + comb[(n - 1) * MAX_N + k]
            } else {
                comb[n * MAX_N + k] = 1
            }
            k = k + 1
        }
        n = n + 1
    }
    n = 0
    while n <= MAX_EXP_SUM {
        let mut k: i64 = 0
        while k <= n {
            binom[n * (MAX_EXP_SUM + 1) + k] = comb[n * MAX_N + k]
            k = k + 1
        }
        n = n + 1
    }
}

function gozinta_from_sig(sig: ptr<i64>, sig_len: i64, comb: ptr<i64>, binom: ptr<i64>, lim: i64) -> i64 {
    let mut s: i64 = 0
    let mut i: i64 = 0
    while i < sig_len { s = s + sig[i]; i = i + 1 }
    if s == 0 { return 1 }
    let P: ptr<i64> = calloc(s + 2, 8)
    if P == null { return 0 }
    let mut t: i64 = 1
    while t <= s {
        let mut prod: i64 = 1
        let tt: i64 = t - 1
        i = 0
        while i < sig_len {
            let a: i64 = sig[i]
            prod = prod * comb[(a + t - 1) * MAX_N + tt]
            i = i + 1
        }
        P[t] = prod
        t = t + 1
    }
    let mut total: i64 = 0
    let mut m: i64 = 1
    while m <= s {
        let mut A_m: i64 = 0
        t = 1
        while t <= m {
            let term: i64 = binom[m * (MAX_EXP_SUM + 1) + t] * P[t]
            if ((m - t) & 1) != 0 { A_m = A_m - term } else { A_m = A_m + term }
            t = t + 1
        }
        total = total + A_m
        if lim > 0 && total > lim { free(P); return lim + 1 }
        m = m + 1
    }
    free(P)
    return total
}

function sig_equals_g(sig: ptr<i64>, sig_len: i64, comb: ptr<i64>, binom: ptr<i64>) -> bool {
    let g: i64 = gozinta_from_sig(sig, sig_len, comb, binom, LIMIT)
    if g > LIMIT { return false }
    let gs: ptr<i64> = calloc(16, 8)
    if gs == null { return false }
    let mut n: i64 = g
    let mut glen: i64 = 0
    if n == 1 {
        free(gs)
        if sig_len == 0 { return true }
        return false
    }
    let mut p: i64 = 2
    while p * p <= n {
        if n % p == 0 {
            let mut e: i64 = 0
            while n % p == 0 {
                n = n / p
                e = e + 1
            }
            let mut j: i64 = glen
            while j > 0 && gs[j - 1] < e {
                gs[j] = gs[j - 1]
                j = j - 1
            }
            gs[j] = e
            glen = glen + 1
        }
        p = p + 1
    }
    if n > 1 {
        let mut j: i64 = glen
        while j > 0 && gs[j - 1] < 1 {
            gs[j] = gs[j - 1]
            j = j - 1
        }
        gs[j] = 1
        glen = glen + 1
    }
    if glen != sig_len { free(gs); return false }
    let mut i: i64 = 0
    while i < sig_len {
        if sig[i] != gs[i] { free(gs); return false }
        i = i + 1
    }
    free(gs)
    return true
}

function enumerate_sigs(first_primes: ptr<i64>, sig: ptr<i64>, sig_len: i64,
                        pos: i64, prev_e: i64, sum_used: i64, prod: i64,
                        comb: ptr<i64>, binom: ptr<i64>, total: ptr<i64>) -> void {
    if sig_len > 0 {
        if sig_equals_g(sig, sig_len, comb, binom) {
            let g: i64 = gozinta_from_sig(sig, sig_len, comb, binom, LIMIT)
            if g <= LIMIT { total[0] = total[0] + g }
        }
    }
    if sum_used == MAX_EXP_SUM || pos >= 60 { return }
    let p: i64 = first_primes[pos]
    let max_e: i64 = prev_e
    let rem: i64 = MAX_EXP_SUM - sum_used
    let mut me: i64 = max_e
    if rem < me { me = rem }
    let mut power: i64 = p
    let mut e: i64 = 1
    while e <= me {
        let new_prod: i64 = prod * power
        if new_prod > LIMIT { break }
        sig[sig_len] = e
        enumerate_sigs(first_primes, sig, sig_len + 1, pos + 1, e, sum_used + e, new_prod, comb, binom, total)
        if power > LIMIT / p { break }
        power = power * p
        e = e + 1
    }
}

function main() -> i32 {
    let comb: ptr<i64> = calloc((MAX_N + 1) * (MAX_N + 1), 8)
    let binom: ptr<i64> = calloc((MAX_EXP_SUM + 1) * (MAX_EXP_SUM + 2), 8)
    let first_primes: ptr<i64> = calloc(60, 8)
    let sig: ptr<i64> = calloc(16, 8)
    let total: ptr<i64> = calloc(1, 8)
    if comb == null || binom == null || first_primes == null || sig == null || total == null {
        return 1
    }
    init_comb(comb, binom)
    total[0] = 1
    let mut np: i64 = 0
    let mut p: i64 = 2
    while np < 60 {
        if p == 2 || p == 3 || (p > 3 && (p % 2) != 0 && (p % 3) != 0) {
            let mut ok: i32 = 1
            if p > 3 {
                let mut d: i64 = 5
                while d * d <= p {
                    if p % d == 0 || p % (d + 2) == 0 { ok = 0; break }
                    d = d + 6
                }
            }
            if ok == 1 {
                first_primes[np] = p
                np = np + 1
            }
        }
        p = p + 1
    }
    enumerate_sigs(first_primes, sig, 0, 0, MAX_EXP_SUM, 0, 1, comb, binom, total)
    printf("%lld\n", total[0])
    free(comb); free(binom); free(first_primes); free(sig); free(total)
    return 0
}

Generated C

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Flow runtime helpers */
typedef struct flow_temp_node { struct flow_temp_node* next; } flow_temp_node;
static flow_temp_node* flow_temp_head = NULL;
static int flow_temp_atexit_set = 0;
__attribute__((unused)) static void flow_temp_free_all(void) {
    while (flow_temp_head) {
        flow_temp_node* n = flow_temp_head;
        flow_temp_head = n->next;
        free(n);
    }
}
__attribute__((unused)) static void* flow_temp_alloc(size_t nbytes) {
    flow_temp_node* node = (flow_temp_node*)malloc(sizeof(flow_temp_node) + nbytes);
    if (!node) return NULL;
    node->next = flow_temp_head;
    flow_temp_head = node;
    if (!flow_temp_atexit_set) {
        flow_temp_atexit_set = 1;
        atexit(flow_temp_free_all);
    }
    return (void*)(node + 1);
}
#ifndef FLOW_DIAG
#define FLOW_DIAG(msg) fprintf(stderr, "%s", (msg))
#endif
#ifndef FLOW_LOG
#define FLOW_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
#ifndef FLOW_LOG_EMPTY
#define FLOW_LOG_EMPTY(fmt) printf(fmt)
#endif
static char* flow_strcat(const char* a, const char* b) {
    size_t la = strlen(a ? a : ""), lb = strlen(b ? b : "");
    char* r = (char*)flow_temp_alloc(la + lb + 1);
    if (!r) return NULL;
    if (la) memcpy(r, a, la);
    if (lb) memcpy(r + la, b, lb);
    r[la + lb] = '\0';
    return r;
}

#define __flow_in_arr(arr, val) __extension__ ({ \
    int _found = 0; \
    size_t _n = sizeof(arr)/sizeof((arr)[0]); \
    for (size_t _i = 0; _i < _n; _i++) { \
        if ((arr)[_i] == (val)) { _found = 1; break; } \
    } _found; })

/* Unified fault handler (MISRA #279) — override with -DFLOW_FAULT_HANDLER=fn */
#ifndef FLOW_FAULT_HANDLER
__attribute__((unused)) static inline void flow_fault_handler(const char* msg) {
    fprintf(stderr, "flow: %s\n", msg ? msg : "fault");
    abort();
#if defined(__GNUC__) || defined(__clang__)
    __builtin_unreachable();
#endif
}
#else
#define flow_fault_handler FLOW_FAULT_HANDLER
#endif
#define flow_div_by_zero_handler() flow_fault_handler("division by zero")
#define flow_shift_ub_handler() flow_fault_handler("invalid shift (amount out of range or left-shift of negative)")

#ifndef FLOW_CHECKED_DIV
#define FLOW_CHECKED_DIV(L, R) (((R) != 0) ? ((L) / (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_MOD
#define FLOW_CHECKED_MOD(L, R) (((R) != 0) ? ((L) % (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHL
#define FLOW_CHECKED_SHL(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull)) && ((L) >= 0)) ? ((L) << (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHR
#define FLOW_CHECKED_SHR(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull))) ? ((L) >> (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif

#include <math.h>

void* _ui_state = NULL;

static inline float i32_to_f32(int32_t v) { return (float)v; }

/* Host stub for @gpu kernels (device codegen replaces this). */
static inline int32_t gpu_thread_id(void) { return 0; }

int64_t gcd_i64_i64(int64_t a0, int64_t b0);
void init_comb_ptr_i64_ptr_i64(int64_t* comb, int64_t* binom);
int64_t gozinta_from_sig_ptr_i64_i64_ptr_i64_ptr_i64_i64(int64_t* sig, int64_t sig_len, int64_t* comb, int64_t* binom, int64_t lim);
bool sig_equals_g_ptr_i64_i64_ptr_i64_ptr_i64(int64_t* sig, int64_t sig_len, int64_t* comb, int64_t* binom);
void enumerate_sigs_ptr_i64_ptr_i64_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64(int64_t* first_primes, int64_t* sig, int64_t sig_len, int64_t pos, int64_t prev_e, int64_t sum_used, int64_t prod, int64_t* comb, int64_t* binom, int64_t* total);
int32_t main(void);

static const int64_t LIMIT = 10000000000000000;
static const int64_t MAX_EXP_SUM = 54;
static const int64_t MAX_N = 110;



int64_t gcd_i64_i64(int64_t a0, int64_t b0) {
    int64_t a = a0;
    int64_t b = b0;
    while (b != 0) {
        int64_t t = FLOW_CHECKED_MOD((a), (b));
        a = b;
        b = t;
    }
    return a;
}

void init_comb_ptr_i64_ptr_i64(int64_t* comb, int64_t* binom) {
    int64_t n = 0;
    while (n <= MAX_N) {
        comb[((n * MAX_N) + 0)] = 1;
        int64_t k = 1;
        while (k <= n) {
            if (k < n) {
                comb[((n * MAX_N) + k)] = (comb[(((n - 1) * MAX_N) + (k - 1))] + comb[(((n - 1) * MAX_N) + k)]);
            } else {
                comb[((n * MAX_N) + k)] = 1;
            }
            k = (k + 1);
        }
        n = (n + 1);
    }
    n = 0;
    while (n <= MAX_EXP_SUM) {
        int64_t k = 0;
        while (k <= n) {
            binom[((n * (MAX_EXP_SUM + 1)) + k)] = comb[((n * MAX_N) + k)];
            k = (k + 1);
        }
        n = (n + 1);
    }
}

int64_t gozinta_from_sig_ptr_i64_i64_ptr_i64_ptr_i64_i64(int64_t* sig, int64_t sig_len, int64_t* comb, int64_t* binom, int64_t lim) {
    int64_t s = 0;
    int64_t i = 0;
    while (i < sig_len) {
        s = (s + sig[i]);
        i = (i + 1);
    }
    if (s == 0) {
        return 1;
    }
    int64_t* P = (int64_t*)(calloc((s + 2), 8));
    if (P == NULL) {
        return 0;
    }
    int64_t t = 1;
    while (t <= s) {
        int64_t prod = 1;
        int64_t tt = (t - 1);
        i = 0;
        while (i < sig_len) {
            int64_t a = sig[i];
            prod = (prod * comb[((((a + t) - 1) * MAX_N) + tt)]);
            i = (i + 1);
        }
        P[t] = prod;
        t = (t + 1);
    }
    int64_t total = 0;
    int64_t m = 1;
    while (m <= s) {
        int64_t A_m = 0;
        t = 1;
        while (t <= m) {
            int64_t term = (binom[((m * (MAX_EXP_SUM + 1)) + t)] * P[t]);
            if (((m - t) & 1) != 0) {
                A_m = (A_m - term);
            } else {
                A_m = (A_m + term);
            }
            t = (t + 1);
        }
        total = (total + A_m);
        if ((lim > 0 && total > lim)) {
            free(P);
            return (lim + 1);
        }
        m = (m + 1);
    }
    free(P);
    return total;
}

bool sig_equals_g_ptr_i64_i64_ptr_i64_ptr_i64(int64_t* sig, int64_t sig_len, int64_t* comb, int64_t* binom) {
    int64_t g = gozinta_from_sig_ptr_i64_i64_ptr_i64_ptr_i64_i64(sig, sig_len, comb, binom, LIMIT);
    if (g > LIMIT) {
        return 0;
    }
    int64_t* gs = (int64_t*)(calloc(16, 8));
    if (gs == NULL) {
        return 0;
    }
    int64_t n = g;
    int64_t glen = 0;
    if (n == 1) {
        free(gs);
        if (sig_len == 0) {
            return 1;
        }
        return 0;
    }
    int64_t p = 2;
    while ((p * p) <= n) {
        if (FLOW_CHECKED_MOD((n), (p)) == 0) {
            int64_t e = 0;
            while (FLOW_CHECKED_MOD((n), (p)) == 0) {
                n = FLOW_CHECKED_DIV((n), (p));
                e = (e + 1);
            }
            int64_t j = glen;
            while ((j > 0 && gs[(j - 1)] < e)) {
                gs[j] = gs[(j - 1)];
                j = (j - 1);
            }
            gs[j] = e;
            glen = (glen + 1);
        }
        p = (p + 1);
    }
    if (n > 1) {
        int64_t j = glen;
        while ((j > 0 && gs[(j - 1)] < 1)) {
            gs[j] = gs[(j - 1)];
            j = (j - 1);
        }
        gs[j] = 1;
        glen = (glen + 1);
    }
    if (glen != sig_len) {
        free(gs);
        return 0;
    }
    int64_t i = 0;
    while (i < sig_len) {
        if (sig[i] != gs[i]) {
            free(gs);
            return 0;
        }
        i = (i + 1);
    }
    free(gs);
    return 1;
}

void enumerate_sigs_ptr_i64_ptr_i64_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64(int64_t* first_primes, int64_t* sig, int64_t sig_len, int64_t pos, int64_t prev_e, int64_t sum_used, int64_t prod, int64_t* comb, int64_t* binom, int64_t* total) {
    if (sig_len > 0) {
        if (sig_equals_g_ptr_i64_i64_ptr_i64_ptr_i64(sig, sig_len, comb, binom)) {
            int64_t g = gozinta_from_sig_ptr_i64_i64_ptr_i64_ptr_i64_i64(sig, sig_len, comb, binom, LIMIT);
            if (g <= LIMIT) {
                total[0] = (total[0] + g);
            }
        }
    }
    if ((sum_used == MAX_EXP_SUM || pos >= 60)) {
        return;
    }
    int64_t p = first_primes[pos];
    int64_t max_e = prev_e;
    int64_t rem = (MAX_EXP_SUM - sum_used);
    int64_t me = max_e;
    if (rem < me) {
        me = rem;
    }
    int64_t power = p;
    int64_t e = 1;
    while (e <= me) {
        int64_t new_prod = (prod * power);
        if (new_prod > LIMIT) {
            break;
        }
        sig[sig_len] = e;
        enumerate_sigs_ptr_i64_ptr_i64_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64(first_primes, sig, (sig_len + 1), (pos + 1), e, (sum_used + e), new_prod, comb, binom, total);
        if (power > FLOW_CHECKED_DIV((LIMIT), (p))) {
            break;
        }
        power = (power * p);
        e = (e + 1);
    }
}

int32_t main(void) {
    int64_t* comb = (int64_t*)(calloc(((MAX_N + 1) * (MAX_N + 1)), 8));
    int64_t* binom = (int64_t*)(calloc(((MAX_EXP_SUM + 1) * (MAX_EXP_SUM + 2)), 8));
    int64_t* first_primes = (int64_t*)(calloc(60, 8));
    int64_t* sig = (int64_t*)(calloc(16, 8));
    int64_t* total = (int64_t*)(calloc(1, 8));
    if (((((comb == NULL || binom == NULL) || first_primes == NULL) || sig == NULL) || total == NULL)) {
        return 1;
    }
    init_comb_ptr_i64_ptr_i64(comb, binom);
    total[0] = 1;
    int64_t np = 0;
    int64_t p = 2;
    while (np < 60) {
        if (((p == 2 || p == 3) || ((p > 3 && FLOW_CHECKED_MOD((p), (2)) != 0) && FLOW_CHECKED_MOD((p), (3)) != 0))) {
            int32_t ok = 1;
            if (p > 3) {
                int64_t d = 5;
                while ((d * d) <= p) {
                    if ((FLOW_CHECKED_MOD((p), (d)) == 0 || FLOW_CHECKED_MOD((p), ((d + 2))) == 0)) {
                        ok = 0;
                        break;
                    }
                    d = (d + 6);
                }
            }
            if (ok == 1) {
                first_primes[np] = p;
                np = (np + 1);
            }
        }
        p = (p + 1);
    }
    enumerate_sigs_ptr_i64_ptr_i64_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64(first_primes, sig, 0, 0, MAX_EXP_SUM, 0, 1, comb, binom, total);
    printf("%lld\n", total[0]);
    free(comb);
    free(binom);
    free(first_primes);
    free(sig);
    free(total);
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()
  // Constant: LIMIT
  llvm.mlir.global internal constant @LIMIT(10000000000000000 : i64) : i64
  // Constant: MAX_EXP_SUM
  llvm.mlir.global internal constant @MAX_EXP_SUM(54 : i64) : i64
  // Constant: MAX_N
  llvm.mlir.global internal constant @MAX_N(110 : i64) : i64
  func.func @gcd(%arg0: i64, %arg1: i64) -> i64 {
    %0 = llvm.mlir.constant(1 : i64) : i64
    %1 = llvm.alloca %0 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %1 : i64, !llvm.ptr
    %2 = llvm.mlir.constant(1 : i64) : i64
    %3 = llvm.alloca %2 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %3 : i64, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %4 = llvm.load %3 : !llvm.ptr -> i64
    %5 = arith.constant 0 : i32
    %7 = arith.extsi %5 : i32 to i64
    %6 = arith.cmpi ne, %4, %7 : i64
    cf.cond_br %6, ^bb1, ^bb2
    ^bb1:
      %8 = llvm.load %1 : !llvm.ptr -> i64
      %9 = llvm.load %3 : !llvm.ptr -> i64
      %10 = arith.remsi %8, %9 : i64
      %11 = llvm.load %3 : !llvm.ptr -> i64
      llvm.store %11, %1 : i64, !llvm.ptr
      llvm.store %10, %3 : i64, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %12 = llvm.load %1 : !llvm.ptr -> i64
    func.return %12 : i64
  }
  func.func @init_comb(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () {
    %13 = arith.constant 0 : i32
    %14 = arith.extsi %13 : i32 to i64
    %15 = llvm.mlir.constant(1 : i64) : i64
    %16 = llvm.alloca %15 x i64 : (i64) -> !llvm.ptr
    llvm.store %14, %16 : i64, !llvm.ptr
    cf.br ^bb3
    ^bb3:
    %17 = llvm.load %16 : !llvm.ptr -> i64
    %18 = llvm.mlir.addressof @MAX_N : !llvm.ptr
    %19 = llvm.load %18 : !llvm.ptr -> i64
    %20 = arith.cmpi sle, %17, %19 : i64
    cf.cond_br %20, ^bb4, ^bb5
    ^bb4:
      %21 = arith.constant 1 : i32
      %22 = llvm.load %16 : !llvm.ptr -> i64
      %23 = llvm.mlir.addressof @MAX_N : !llvm.ptr
      %24 = llvm.load %23 : !llvm.ptr -> i64
      %25 = arith.muli %22, %24 : i64
      %26 = arith.constant 0 : i32
      %28 = arith.extsi %26 : i32 to i64
      %27 = arith.addi %25, %28 : i64
      %29 = arith.extsi %21 : i32 to i64
      %30 = llvm.getelementptr %arg0[%27] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %29, %30 : i64, !llvm.ptr
      %31 = arith.constant 1 : i32
      %32 = arith.extsi %31 : i32 to i64
      %33 = llvm.mlir.constant(1 : i64) : i64
      %34 = llvm.alloca %33 x i64 : (i64) -> !llvm.ptr
      llvm.store %32, %34 : i64, !llvm.ptr
      cf.br ^bb6
      ^bb6:
      %35 = llvm.load %34 : !llvm.ptr -> i64
      %36 = llvm.load %16 : !llvm.ptr -> i64
      %37 = arith.cmpi sle, %35, %36 : i64
      cf.cond_br %37, ^bb7, ^bb8
      ^bb7:
        %38 = llvm.load %34 : !llvm.ptr -> i64
        %39 = llvm.load %16 : !llvm.ptr -> i64
        %40 = arith.cmpi slt, %38, %39 : i64
        cf.cond_br %40, ^bb9, ^bb10
        ^bb9:
          %42 = llvm.load %16 : !llvm.ptr -> i64
          %43 = arith.constant 1 : i32
          %45 = arith.extsi %43 : i32 to i64
          %44 = arith.subi %42, %45 : i64
          %46 = llvm.mlir.addressof @MAX_N : !llvm.ptr
          %47 = llvm.load %46 : !llvm.ptr -> i64
          %48 = arith.muli %44, %47 : i64
          %49 = llvm.load %34 : !llvm.ptr -> i64
          %50 = arith.constant 1 : i32
          %52 = arith.extsi %50 : i32 to i64
          %51 = arith.subi %49, %52 : i64
          %53 = arith.addi %48, %51 : i64
          %54 = llvm.getelementptr %arg0[%53] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %41 = llvm.load %54 : !llvm.ptr -> i64
          %56 = llvm.load %16 : !llvm.ptr -> i64
          %57 = arith.constant 1 : i32
          %59 = arith.extsi %57 : i32 to i64
          %58 = arith.subi %56, %59 : i64
          %60 = llvm.mlir.addressof @MAX_N : !llvm.ptr
          %61 = llvm.load %60 : !llvm.ptr -> i64
          %62 = arith.muli %58, %61 : i64
          %63 = llvm.load %34 : !llvm.ptr -> i64
          %64 = arith.addi %62, %63 : i64
          %65 = llvm.getelementptr %arg0[%64] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %55 = llvm.load %65 : !llvm.ptr -> i64
          %66 = arith.addi %41, %55 : i64
          %67 = llvm.load %16 : !llvm.ptr -> i64
          %68 = llvm.mlir.addressof @MAX_N : !llvm.ptr
          %69 = llvm.load %68 : !llvm.ptr -> i64
          %70 = arith.muli %67, %69 : i64
          %71 = llvm.load %34 : !llvm.ptr -> i64
          %72 = arith.addi %70, %71 : i64
          %73 = llvm.getelementptr %arg0[%72] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %66, %73 : i64, !llvm.ptr
          cf.br ^bb11
        ^bb10:
          %74 = arith.constant 1 : i32
          %75 = llvm.load %16 : !llvm.ptr -> i64
          %76 = llvm.mlir.addressof @MAX_N : !llvm.ptr
          %77 = llvm.load %76 : !llvm.ptr -> i64
          %78 = arith.muli %75, %77 : i64
          %79 = llvm.load %34 : !llvm.ptr -> i64
          %80 = arith.addi %78, %79 : i64
          %81 = arith.extsi %74 : i32 to i64
          %82 = llvm.getelementptr %arg0[%80] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %81, %82 : i64, !llvm.ptr
          cf.br ^bb11
        ^bb11:
        %83 = llvm.load %34 : !llvm.ptr -> i64
        %84 = arith.constant 1 : i32
        %86 = arith.extsi %84 : i32 to i64
        %85 = arith.addi %83, %86 : i64
        llvm.store %85, %34 : i64, !llvm.ptr
        cf.br ^bb6
      ^bb8:
      %87 = llvm.load %16 : !llvm.ptr -> i64
      %88 = arith.constant 1 : i32
      %90 = arith.extsi %88 : i32 to i64
      %89 = arith.addi %87, %90 : i64
      llvm.store %89, %16 : i64, !llvm.ptr
      cf.br ^bb3
    ^bb5:
    %91 = arith.constant 0 : i32
    %92 = arith.extsi %91 : i32 to i64
    llvm.store %92, %16 : i64, !llvm.ptr
    cf.br ^bb12
    ^bb12:
    %93 = llvm.load %16 : !llvm.ptr -> i64
    %94 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
    %95 = llvm.load %94 : !llvm.ptr -> i64
    %96 = arith.cmpi sle, %93, %95 : i64
    cf.cond_br %96, ^bb13, ^bb14
    ^bb13:
      %97 = arith.constant 0 : i32
      %98 = arith.extsi %97 : i32 to i64
      %99 = llvm.mlir.constant(1 : i64) : i64
      %100 = llvm.alloca %99 x i64 : (i64) -> !llvm.ptr
      llvm.store %98, %100 : i64, !llvm.ptr
      cf.br ^bb15
      ^bb15:
      %101 = llvm.load %100 : !llvm.ptr -> i64
      %102 = llvm.load %16 : !llvm.ptr -> i64
      %103 = arith.cmpi sle, %101, %102 : i64
      cf.cond_br %103, ^bb16, ^bb17
      ^bb16:
        %105 = llvm.load %16 : !llvm.ptr -> i64
        %106 = llvm.mlir.addressof @MAX_N : !llvm.ptr
        %107 = llvm.load %106 : !llvm.ptr -> i64
        %108 = arith.muli %105, %107 : i64
        %109 = llvm.load %100 : !llvm.ptr -> i64
        %110 = arith.addi %108, %109 : i64
        %111 = llvm.getelementptr %arg0[%110] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %104 = llvm.load %111 : !llvm.ptr -> i64
        %112 = llvm.load %16 : !llvm.ptr -> i64
        %113 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
        %114 = llvm.load %113 : !llvm.ptr -> i64
        %115 = arith.constant 1 : i32
        %117 = arith.extsi %115 : i32 to i64
        %116 = arith.addi %114, %117 : i64
        %118 = arith.muli %112, %116 : i64
        %119 = llvm.load %100 : !llvm.ptr -> i64
        %120 = arith.addi %118, %119 : i64
        %121 = llvm.getelementptr %arg1[%120] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %104, %121 : i64, !llvm.ptr
        %122 = llvm.load %100 : !llvm.ptr -> i64
        %123 = arith.constant 1 : i32
        %125 = arith.extsi %123 : i32 to i64
        %124 = arith.addi %122, %125 : i64
        llvm.store %124, %100 : i64, !llvm.ptr
        cf.br ^bb15
      ^bb17:
      %126 = llvm.load %16 : !llvm.ptr -> i64
      %127 = arith.constant 1 : i32
      %129 = arith.extsi %127 : i32 to i64
      %128 = arith.addi %126, %129 : i64
      llvm.store %128, %16 : i64, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    func.return
  }
  func.func @gozinta_from_sig(%arg0: !llvm.ptr, %arg1: i64, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: i64) -> i64 {
    %130 = arith.constant 0 : i32
    %131 = arith.extsi %130 : i32 to i64
    %132 = llvm.mlir.constant(1 : i64) : i64
    %133 = llvm.alloca %132 x i64 : (i64) -> !llvm.ptr
    llvm.store %131, %133 : i64, !llvm.ptr
    %134 = arith.constant 0 : i32
    %135 = arith.extsi %134 : i32 to i64
    %136 = llvm.mlir.constant(1 : i64) : i64
    %137 = llvm.alloca %136 x i64 : (i64) -> !llvm.ptr
    llvm.store %135, %137 : i64, !llvm.ptr
    cf.br ^bb18
    ^bb18:
    %138 = llvm.load %137 : !llvm.ptr -> i64
    %139 = arith.cmpi slt, %138, %arg1 : i64
    cf.cond_br %139, ^bb19, ^bb20
    ^bb19:
      %140 = llvm.load %133 : !llvm.ptr -> i64
      %142 = llvm.load %137 : !llvm.ptr -> i64
      %143 = llvm.getelementptr %arg0[%142] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %141 = llvm.load %143 : !llvm.ptr -> i64
      %144 = arith.addi %140, %141 : i64
      llvm.store %144, %133 : i64, !llvm.ptr
      %145 = llvm.load %137 : !llvm.ptr -> i64
      %146 = arith.constant 1 : i32
      %148 = arith.extsi %146 : i32 to i64
      %147 = arith.addi %145, %148 : i64
      llvm.store %147, %137 : i64, !llvm.ptr
      cf.br ^bb18
    ^bb20:
    %149 = llvm.load %133 : !llvm.ptr -> i64
    %150 = arith.constant 0 : i32
    %152 = arith.extsi %150 : i32 to i64
    %151 = arith.cmpi eq, %149, %152 : i64
    cf.cond_br %151, ^bb21, ^bb22
    ^bb21:
      %153 = arith.constant 1 : i32
      %154 = arith.extsi %153 : i32 to i64
      func.return %154 : i64
    ^bb22:
      cf.br ^bb23
    ^bb23:
    %156 = llvm.load %133 : !llvm.ptr -> i64
    %157 = arith.constant 2 : i32
    %159 = arith.extsi %157 : i32 to i64
    %158 = arith.addi %156, %159 : i64
    %160 = arith.constant 8 : i32
    %161 = arith.extsi %160 : i32 to i64
    %155 = func.call @calloc(%158, %161) : (i64, i64) -> !llvm.ptr
    %162 = llvm.mlir.zero : !llvm.ptr
    %163 = llvm.icmp "eq" %155, %162 : !llvm.ptr
    cf.cond_br %163, ^bb24, ^bb25
    ^bb24:
      %164 = arith.constant 0 : i32
      %165 = arith.extsi %164 : i32 to i64
      func.return %165 : i64
    ^bb25:
      cf.br ^bb26
    ^bb26:
    %166 = arith.constant 1 : i32
    %167 = arith.extsi %166 : i32 to i64
    %168 = llvm.mlir.constant(1 : i64) : i64
    %169 = llvm.alloca %168 x i64 : (i64) -> !llvm.ptr
    llvm.store %167, %169 : i64, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %170 = llvm.load %169 : !llvm.ptr -> i64
    %171 = llvm.load %133 : !llvm.ptr -> i64
    %172 = arith.cmpi sle, %170, %171 : i64
    cf.cond_br %172, ^bb28, ^bb29
    ^bb28:
      %173 = arith.constant 1 : i32
      %174 = arith.extsi %173 : i32 to i64
      %175 = llvm.mlir.constant(1 : i64) : i64
      %176 = llvm.alloca %175 x i64 : (i64) -> !llvm.ptr
      llvm.store %174, %176 : i64, !llvm.ptr
      %177 = llvm.load %169 : !llvm.ptr -> i64
      %178 = arith.constant 1 : i32
      %180 = arith.extsi %178 : i32 to i64
      %179 = arith.subi %177, %180 : i64
      %181 = arith.constant 0 : i32
      %182 = arith.extsi %181 : i32 to i64
      llvm.store %182, %137 : i64, !llvm.ptr
      cf.br ^bb30
      ^bb30:
      %183 = llvm.load %137 : !llvm.ptr -> i64
      %184 = arith.cmpi slt, %183, %arg1 : i64
      cf.cond_br %184, ^bb31, ^bb32
      ^bb31:
        %186 = llvm.load %137 : !llvm.ptr -> i64
        %187 = llvm.getelementptr %arg0[%186] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %185 = llvm.load %187 : !llvm.ptr -> i64
        %188 = llvm.load %176 : !llvm.ptr -> i64
        %190 = llvm.load %169 : !llvm.ptr -> i64
        %191 = arith.addi %185, %190 : i64
        %192 = arith.constant 1 : i32
        %194 = arith.extsi %192 : i32 to i64
        %193 = arith.subi %191, %194 : i64
        %195 = llvm.mlir.addressof @MAX_N : !llvm.ptr
        %196 = llvm.load %195 : !llvm.ptr -> i64
        %197 = arith.muli %193, %196 : i64
        %198 = arith.addi %197, %179 : i64
        %199 = llvm.getelementptr %arg2[%198] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %189 = llvm.load %199 : !llvm.ptr -> i64
        %200 = arith.muli %188, %189 : i64
        llvm.store %200, %176 : i64, !llvm.ptr
        %201 = llvm.load %137 : !llvm.ptr -> i64
        %202 = arith.constant 1 : i32
        %204 = arith.extsi %202 : i32 to i64
        %203 = arith.addi %201, %204 : i64
        llvm.store %203, %137 : i64, !llvm.ptr
        cf.br ^bb30
      ^bb32:
      %205 = llvm.load %176 : !llvm.ptr -> i64
      %206 = llvm.load %169 : !llvm.ptr -> i64
      %207 = llvm.getelementptr %155[%206] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %205, %207 : i64, !llvm.ptr
      %208 = llvm.load %169 : !llvm.ptr -> i64
      %209 = arith.constant 1 : i32
      %211 = arith.extsi %209 : i32 to i64
      %210 = arith.addi %208, %211 : i64
      llvm.store %210, %169 : i64, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %212 = arith.constant 0 : i32
    %213 = arith.extsi %212 : i32 to i64
    %214 = llvm.mlir.constant(1 : i64) : i64
    %215 = llvm.alloca %214 x i64 : (i64) -> !llvm.ptr
    llvm.store %213, %215 : i64, !llvm.ptr
    %216 = arith.constant 1 : i32
    %217 = arith.extsi %216 : i32 to i64
    %218 = llvm.mlir.constant(1 : i64) : i64
    %219 = llvm.alloca %218 x i64 : (i64) -> !llvm.ptr
    llvm.store %217, %219 : i64, !llvm.ptr
    cf.br ^bb33
    ^bb33:
    %220 = llvm.load %219 : !llvm.ptr -> i64
    %221 = llvm.load %133 : !llvm.ptr -> i64
    %222 = arith.cmpi sle, %220, %221 : i64
    cf.cond_br %222, ^bb34, ^bb35
    ^bb34:
      %223 = arith.constant 0 : i32
      %224 = arith.extsi %223 : i32 to i64
      %225 = llvm.mlir.constant(1 : i64) : i64
      %226 = llvm.alloca %225 x i64 : (i64) -> !llvm.ptr
      llvm.store %224, %226 : i64, !llvm.ptr
      %227 = arith.constant 1 : i32
      %228 = arith.extsi %227 : i32 to i64
      llvm.store %228, %169 : i64, !llvm.ptr
      cf.br ^bb36
      ^bb36:
      %229 = llvm.load %169 : !llvm.ptr -> i64
      %230 = llvm.load %219 : !llvm.ptr -> i64
      %231 = arith.cmpi sle, %229, %230 : i64
      cf.cond_br %231, ^bb37, ^bb38
      ^bb37:
        %233 = llvm.load %219 : !llvm.ptr -> i64
        %234 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
        %235 = llvm.load %234 : !llvm.ptr -> i64
        %236 = arith.constant 1 : i32
        %238 = arith.extsi %236 : i32 to i64
        %237 = arith.addi %235, %238 : i64
        %239 = arith.muli %233, %237 : i64
        %240 = llvm.load %169 : !llvm.ptr -> i64
        %241 = arith.addi %239, %240 : i64
        %242 = llvm.getelementptr %arg3[%241] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %232 = llvm.load %242 : !llvm.ptr -> i64
        %244 = llvm.load %169 : !llvm.ptr -> i64
        %245 = llvm.getelementptr %155[%244] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %243 = llvm.load %245 : !llvm.ptr -> i64
        %246 = arith.muli %232, %243 : i64
        %247 = llvm.load %219 : !llvm.ptr -> i64
        %248 = llvm.load %169 : !llvm.ptr -> i64
        %249 = arith.subi %247, %248 : i64
        %250 = arith.constant 1 : i32
        %252 = arith.extsi %250 : i32 to i64
        %251 = arith.andi %249, %252 : i64
        %253 = arith.constant 0 : i32
        %255 = arith.extsi %253 : i32 to i64
        %254 = arith.cmpi ne, %251, %255 : i64
        cf.cond_br %254, ^bb39, ^bb40
        ^bb39:
          %256 = llvm.load %226 : !llvm.ptr -> i64
          %257 = arith.subi %256, %246 : i64
          llvm.store %257, %226 : i64, !llvm.ptr
          cf.br ^bb41
        ^bb40:
          %258 = llvm.load %226 : !llvm.ptr -> i64
          %259 = arith.addi %258, %246 : i64
          llvm.store %259, %226 : i64, !llvm.ptr
          cf.br ^bb41
        ^bb41:
        %260 = llvm.load %169 : !llvm.ptr -> i64
        %261 = arith.constant 1 : i32
        %263 = arith.extsi %261 : i32 to i64
        %262 = arith.addi %260, %263 : i64
        llvm.store %262, %169 : i64, !llvm.ptr
        cf.br ^bb36
      ^bb38:
      %264 = llvm.load %215 : !llvm.ptr -> i64
      %265 = llvm.load %226 : !llvm.ptr -> i64
      %266 = arith.addi %264, %265 : i64
      llvm.store %266, %215 : i64, !llvm.ptr
      %267 = arith.constant 0 : i32
      %269 = arith.extsi %267 : i32 to i64
      %268 = arith.cmpi sgt, %arg4, %269 : i64
      %270 = scf.if %268 -> (i1) {
        %271 = llvm.load %215 : !llvm.ptr -> i64
        %272 = arith.cmpi sgt, %271, %arg4 : i64
        scf.yield %272 : i1
      } else {
        %273 = arith.constant false
        scf.yield %273 : i1
      }
      cf.cond_br %270, ^bb42, ^bb43
      ^bb42:
        func.call @free(%155) : (!llvm.ptr) -> ()
        %275 = arith.constant 1 : i32
        %277 = arith.extsi %275 : i32 to i64
        %276 = arith.addi %arg4, %277 : i64
        func.return %276 : i64
      ^bb43:
        cf.br ^bb44
      ^bb44:
      %278 = llvm.load %219 : !llvm.ptr -> i64
      %279 = arith.constant 1 : i32
      %281 = arith.extsi %279 : i32 to i64
      %280 = arith.addi %278, %281 : i64
      llvm.store %280, %219 : i64, !llvm.ptr
      cf.br ^bb33
    ^bb35:
    func.call @free(%155) : (!llvm.ptr) -> ()
    %283 = llvm.load %215 : !llvm.ptr -> i64
    func.return %283 : i64
  }
  func.func @sig_equals_g(%arg0: !llvm.ptr, %arg1: i64, %arg2: !llvm.ptr, %arg3: !llvm.ptr) -> i1 {
    %285 = llvm.mlir.addressof @LIMIT : !llvm.ptr
    %286 = llvm.load %285 : !llvm.ptr -> i64
    %284 = func.call @gozinta_from_sig(%arg0, %arg1, %arg2, %arg3, %286) : (!llvm.ptr, i64, !llvm.ptr, !llvm.ptr, i64) -> i64
    %287 = llvm.mlir.addressof @LIMIT : !llvm.ptr
    %288 = llvm.load %287 : !llvm.ptr -> i64
    %289 = arith.cmpi sgt, %284, %288 : i64
    cf.cond_br %289, ^bb45, ^bb46
    ^bb45:
      %290 = arith.constant 0 : i1
      func.return %290 : i1
    ^bb46:
      cf.br ^bb47
    ^bb47:
    %292 = arith.constant 16 : i32
    %293 = arith.constant 8 : i32
    %294 = arith.extsi %292 : i32 to i64
    %295 = arith.extsi %293 : i32 to i64
    %291 = func.call @calloc(%294, %295) : (i64, i64) -> !llvm.ptr
    %296 = llvm.mlir.zero : !llvm.ptr
    %297 = llvm.icmp "eq" %291, %296 : !llvm.ptr
    cf.cond_br %297, ^bb48, ^bb49
    ^bb48:
      %298 = arith.constant 0 : i1
      func.return %298 : i1
    ^bb49:
      cf.br ^bb50
    ^bb50:
    %299 = llvm.mlir.constant(1 : i64) : i64
    %300 = llvm.alloca %299 x i64 : (i64) -> !llvm.ptr
    llvm.store %284, %300 : i64, !llvm.ptr
    %301 = arith.constant 0 : i32
    %302 = arith.extsi %301 : i32 to i64
    %303 = llvm.mlir.constant(1 : i64) : i64
    %304 = llvm.alloca %303 x i64 : (i64) -> !llvm.ptr
    llvm.store %302, %304 : i64, !llvm.ptr
    %305 = llvm.load %300 : !llvm.ptr -> i64
    %306 = arith.constant 1 : i32
    %308 = arith.extsi %306 : i32 to i64
    %307 = arith.cmpi eq, %305, %308 : i64
    cf.cond_br %307, ^bb51, ^bb52
    ^bb51:
      func.call @free(%291) : (!llvm.ptr) -> ()
      %310 = arith.constant 0 : i32
      %312 = arith.extsi %310 : i32 to i64
      %311 = arith.cmpi eq, %arg1, %312 : i64
      cf.cond_br %311, ^bb54, ^bb55
      ^bb54:
        %313 = arith.constant 1 : i1
        func.return %313 : i1
      ^bb55:
        cf.br ^bb56
      ^bb56:
      %314 = arith.constant 0 : i1
      func.return %314 : i1
    ^bb52:
      cf.br ^bb53
    ^bb53:
    %315 = arith.constant 2 : i32
    %316 = arith.extsi %315 : i32 to i64
    %317 = llvm.mlir.constant(1 : i64) : i64
    %318 = llvm.alloca %317 x i64 : (i64) -> !llvm.ptr
    llvm.store %316, %318 : i64, !llvm.ptr
    cf.br ^bb57
    ^bb57:
    %319 = llvm.load %318 : !llvm.ptr -> i64
    %320 = llvm.load %318 : !llvm.ptr -> i64
    %321 = arith.muli %319, %320 : i64
    %322 = llvm.load %300 : !llvm.ptr -> i64
    %323 = arith.cmpi sle, %321, %322 : i64
    cf.cond_br %323, ^bb58, ^bb59
    ^bb58:
      %324 = llvm.load %300 : !llvm.ptr -> i64
      %325 = llvm.load %318 : !llvm.ptr -> i64
      %326 = arith.remsi %324, %325 : i64
      %327 = arith.constant 0 : i32
      %329 = arith.extsi %327 : i32 to i64
      %328 = arith.cmpi eq, %326, %329 : i64
      cf.cond_br %328, ^bb60, ^bb61
      ^bb60:
        %330 = arith.constant 0 : i32
        %331 = arith.extsi %330 : i32 to i64
        %332 = llvm.mlir.constant(1 : i64) : i64
        %333 = llvm.alloca %332 x i64 : (i64) -> !llvm.ptr
        llvm.store %331, %333 : i64, !llvm.ptr
        cf.br ^bb63
        ^bb63:
        %334 = llvm.load %300 : !llvm.ptr -> i64
        %335 = llvm.load %318 : !llvm.ptr -> i64
        %336 = arith.remsi %334, %335 : i64
        %337 = arith.constant 0 : i32
        %339 = arith.extsi %337 : i32 to i64
        %338 = arith.cmpi eq, %336, %339 : i64
        cf.cond_br %338, ^bb64, ^bb65
        ^bb64:
          %340 = llvm.load %300 : !llvm.ptr -> i64
          %341 = llvm.load %318 : !llvm.ptr -> i64
          %342 = arith.divsi %340, %341 : i64
          llvm.store %342, %300 : i64, !llvm.ptr
          %343 = llvm.load %333 : !llvm.ptr -> i64
          %344 = arith.constant 1 : i32
          %346 = arith.extsi %344 : i32 to i64
          %345 = arith.addi %343, %346 : i64
          llvm.store %345, %333 : i64, !llvm.ptr
          cf.br ^bb63
        ^bb65:
        %347 = llvm.load %304 : !llvm.ptr -> i64
        %348 = llvm.mlir.constant(1 : i64) : i64
        %349 = llvm.alloca %348 x i64 : (i64) -> !llvm.ptr
        llvm.store %347, %349 : i64, !llvm.ptr
        cf.br ^bb66
        ^bb66:
        %350 = llvm.load %349 : !llvm.ptr -> i64
        %351 = arith.constant 0 : i32
        %353 = arith.extsi %351 : i32 to i64
        %352 = arith.cmpi sgt, %350, %353 : i64
        %354 = scf.if %352 -> (i1) {
          %356 = llvm.load %349 : !llvm.ptr -> i64
          %357 = arith.constant 1 : i32
          %359 = arith.extsi %357 : i32 to i64
          %358 = arith.subi %356, %359 : i64
          %360 = llvm.getelementptr %291[%358] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %355 = llvm.load %360 : !llvm.ptr -> i64
          %361 = llvm.load %333 : !llvm.ptr -> i64
          %362 = arith.cmpi slt, %355, %361 : i64
          scf.yield %362 : i1
        } else {
          %363 = arith.constant false
          scf.yield %363 : i1
        }
        cf.cond_br %354, ^bb67, ^bb68
        ^bb67:
          %365 = llvm.load %349 : !llvm.ptr -> i64
          %366 = arith.constant 1 : i32
          %368 = arith.extsi %366 : i32 to i64
          %367 = arith.subi %365, %368 : i64
          %369 = llvm.getelementptr %291[%367] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %364 = llvm.load %369 : !llvm.ptr -> i64
          %370 = llvm.load %349 : !llvm.ptr -> i64
          %371 = llvm.getelementptr %291[%370] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %364, %371 : i64, !llvm.ptr
          %372 = llvm.load %349 : !llvm.ptr -> i64
          %373 = arith.constant 1 : i32
          %375 = arith.extsi %373 : i32 to i64
          %374 = arith.subi %372, %375 : i64
          llvm.store %374, %349 : i64, !llvm.ptr
          cf.br ^bb66
        ^bb68:
        %376 = llvm.load %333 : !llvm.ptr -> i64
        %377 = llvm.load %349 : !llvm.ptr -> i64
        %378 = llvm.getelementptr %291[%377] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %376, %378 : i64, !llvm.ptr
        %379 = llvm.load %304 : !llvm.ptr -> i64
        %380 = arith.constant 1 : i32
        %382 = arith.extsi %380 : i32 to i64
        %381 = arith.addi %379, %382 : i64
        llvm.store %381, %304 : i64, !llvm.ptr
        cf.br ^bb62
      ^bb61:
        cf.br ^bb62
      ^bb62:
      %383 = llvm.load %318 : !llvm.ptr -> i64
      %384 = arith.constant 1 : i32
      %386 = arith.extsi %384 : i32 to i64
      %385 = arith.addi %383, %386 : i64
      llvm.store %385, %318 : i64, !llvm.ptr
      cf.br ^bb57
    ^bb59:
    %387 = llvm.load %300 : !llvm.ptr -> i64
    %388 = arith.constant 1 : i32
    %390 = arith.extsi %388 : i32 to i64
    %389 = arith.cmpi sgt, %387, %390 : i64
    cf.cond_br %389, ^bb69, ^bb70
    ^bb69:
      %391 = llvm.load %304 : !llvm.ptr -> i64
      %392 = llvm.mlir.constant(1 : i64) : i64
      %393 = llvm.alloca %392 x i64 : (i64) -> !llvm.ptr
      llvm.store %391, %393 : i64, !llvm.ptr
      cf.br ^bb72
      ^bb72:
      %394 = llvm.load %393 : !llvm.ptr -> i64
      %395 = arith.constant 0 : i32
      %397 = arith.extsi %395 : i32 to i64
      %396 = arith.cmpi sgt, %394, %397 : i64
      %398 = scf.if %396 -> (i1) {
        %400 = llvm.load %393 : !llvm.ptr -> i64
        %401 = arith.constant 1 : i32
        %403 = arith.extsi %401 : i32 to i64
        %402 = arith.subi %400, %403 : i64
        %404 = llvm.getelementptr %291[%402] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %399 = llvm.load %404 : !llvm.ptr -> i64
        %405 = arith.constant 1 : i32
        %407 = arith.extsi %405 : i32 to i64
        %406 = arith.cmpi slt, %399, %407 : i64
        scf.yield %406 : i1
      } else {
        %408 = arith.constant false
        scf.yield %408 : i1
      }
      cf.cond_br %398, ^bb73, ^bb74
      ^bb73:
        %410 = llvm.load %393 : !llvm.ptr -> i64
        %411 = arith.constant 1 : i32
        %413 = arith.extsi %411 : i32 to i64
        %412 = arith.subi %410, %413 : i64
        %414 = llvm.getelementptr %291[%412] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %409 = llvm.load %414 : !llvm.ptr -> i64
        %415 = llvm.load %393 : !llvm.ptr -> i64
        %416 = llvm.getelementptr %291[%415] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %409, %416 : i64, !llvm.ptr
        %417 = llvm.load %393 : !llvm.ptr -> i64
        %418 = arith.constant 1 : i32
        %420 = arith.extsi %418 : i32 to i64
        %419 = arith.subi %417, %420 : i64
        llvm.store %419, %393 : i64, !llvm.ptr
        cf.br ^bb72
      ^bb74:
      %421 = arith.constant 1 : i32
      %422 = llvm.load %393 : !llvm.ptr -> i64
      %423 = arith.extsi %421 : i32 to i64
      %424 = llvm.getelementptr %291[%422] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %423, %424 : i64, !llvm.ptr
      %425 = llvm.load %304 : !llvm.ptr -> i64
      %426 = arith.constant 1 : i32
      %428 = arith.extsi %426 : i32 to i64
      %427 = arith.addi %425, %428 : i64
      llvm.store %427, %304 : i64, !llvm.ptr
      cf.br ^bb71
    ^bb70:
      cf.br ^bb71
    ^bb71:
    %429 = llvm.load %304 : !llvm.ptr -> i64
    %430 = arith.cmpi ne, %429, %arg1 : i64
    cf.cond_br %430, ^bb75, ^bb76
    ^bb75:
      func.call @free(%291) : (!llvm.ptr) -> ()
      %432 = arith.constant 0 : i1
      func.return %432 : i1
    ^bb76:
      cf.br ^bb77
    ^bb77:
    %433 = arith.constant 0 : i32
    %434 = arith.extsi %433 : i32 to i64
    %435 = llvm.mlir.constant(1 : i64) : i64
    %436 = llvm.alloca %435 x i64 : (i64) -> !llvm.ptr
    llvm.store %434, %436 : i64, !llvm.ptr
    cf.br ^bb78
    ^bb78:
    %437 = llvm.load %436 : !llvm.ptr -> i64
    %438 = arith.cmpi slt, %437, %arg1 : i64
    cf.cond_br %438, ^bb79, ^bb80
    ^bb79:
      %440 = llvm.load %436 : !llvm.ptr -> i64
      %441 = llvm.getelementptr %arg0[%440] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %439 = llvm.load %441 : !llvm.ptr -> i64
      %443 = llvm.load %436 : !llvm.ptr -> i64
      %444 = llvm.getelementptr %291[%443] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %442 = llvm.load %444 : !llvm.ptr -> i64
      %445 = arith.cmpi ne, %439, %442 : i64
      cf.cond_br %445, ^bb81, ^bb82
      ^bb81:
        func.call @free(%291) : (!llvm.ptr) -> ()
        %447 = arith.constant 0 : i1
        func.return %447 : i1
      ^bb82:
        cf.br ^bb83
      ^bb83:
      %448 = llvm.load %436 : !llvm.ptr -> i64
      %449 = arith.constant 1 : i32
      %451 = arith.extsi %449 : i32 to i64
      %450 = arith.addi %448, %451 : i64
      llvm.store %450, %436 : i64, !llvm.ptr
      cf.br ^bb78
    ^bb80:
    func.call @free(%291) : (!llvm.ptr) -> ()
    %453 = arith.constant 1 : i1
    func.return %453 : i1
  }
  func.func @enumerate_sigs(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i64, %arg3: i64, %arg4: i64, %arg5: i64, %arg6: i64, %arg7: !llvm.ptr, %arg8: !llvm.ptr, %arg9: !llvm.ptr) -> () {
    %454 = arith.constant 0 : i32
    %456 = arith.extsi %454 : i32 to i64
    %455 = arith.cmpi sgt, %arg2, %456 : i64
    cf.cond_br %455, ^bb84, ^bb85
    ^bb84:
      %457 = func.call @sig_equals_g(%arg1, %arg2, %arg7, %arg8) : (!llvm.ptr, i64, !llvm.ptr, !llvm.ptr) -> i1
      cf.cond_br %457, ^bb87, ^bb88
      ^bb87:
        %459 = llvm.mlir.addressof @LIMIT : !llvm.ptr
        %460 = llvm.load %459 : !llvm.ptr -> i64
        %458 = func.call @gozinta_from_sig(%arg1, %arg2, %arg7, %arg8, %460) : (!llvm.ptr, i64, !llvm.ptr, !llvm.ptr, i64) -> i64
        %461 = llvm.mlir.addressof @LIMIT : !llvm.ptr
        %462 = llvm.load %461 : !llvm.ptr -> i64
        %463 = arith.cmpi sle, %458, %462 : i64
        cf.cond_br %463, ^bb90, ^bb91
        ^bb90:
          %465 = arith.constant 0 : i32
          %466 = arith.extsi %465 : i32 to i64
          %467 = llvm.getelementptr %arg9[%466] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %464 = llvm.load %467 : !llvm.ptr -> i64
          %468 = arith.addi %464, %458 : i64
          %469 = arith.constant 0 : i32
          %470 = arith.extsi %469 : i32 to i64
          %471 = llvm.getelementptr %arg9[%470] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %468, %471 : i64, !llvm.ptr
          cf.br ^bb92
        ^bb91:
          cf.br ^bb92
        ^bb92:
        cf.br ^bb89
      ^bb88:
        cf.br ^bb89
      ^bb89:
      cf.br ^bb86
    ^bb85:
      cf.br ^bb86
    ^bb86:
    %472 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
    %473 = llvm.load %472 : !llvm.ptr -> i64
    %474 = arith.cmpi eq, %arg5, %473 : i64
    %475 = scf.if %474 -> (i1) {
      %476 = arith.constant true
      scf.yield %476 : i1
    } else {
      %477 = arith.constant 60 : i32
      %479 = arith.extsi %477 : i32 to i64
      %478 = arith.cmpi sge, %arg3, %479 : i64
      scf.yield %478 : i1
    }
    cf.cond_br %475, ^bb93, ^bb94
    ^bb93:
      func.return
    ^bb94:
      cf.br ^bb95
    ^bb95:
    %481 = llvm.getelementptr %arg0[%arg3] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %480 = llvm.load %481 : !llvm.ptr -> i64
    %482 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
    %483 = llvm.load %482 : !llvm.ptr -> i64
    %484 = arith.subi %483, %arg5 : i64
    %485 = llvm.mlir.constant(1 : i64) : i64
    %486 = llvm.alloca %485 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg4, %486 : i64, !llvm.ptr
    %487 = llvm.load %486 : !llvm.ptr -> i64
    %488 = arith.cmpi slt, %484, %487 : i64
    cf.cond_br %488, ^bb96, ^bb97
    ^bb96:
      llvm.store %484, %486 : i64, !llvm.ptr
      cf.br ^bb98
    ^bb97:
      cf.br ^bb98
    ^bb98:
    %489 = llvm.mlir.constant(1 : i64) : i64
    %490 = llvm.alloca %489 x i64 : (i64) -> !llvm.ptr
    llvm.store %480, %490 : i64, !llvm.ptr
    %491 = arith.constant 1 : i32
    %492 = arith.extsi %491 : i32 to i64
    %493 = llvm.mlir.constant(1 : i64) : i64
    %494 = llvm.alloca %493 x i64 : (i64) -> !llvm.ptr
    llvm.store %492, %494 : i64, !llvm.ptr
    cf.br ^bb99
    ^bb99:
    %495 = llvm.load %494 : !llvm.ptr -> i64
    %496 = llvm.load %486 : !llvm.ptr -> i64
    %497 = arith.cmpi sle, %495, %496 : i64
    cf.cond_br %497, ^bb100, ^bb101
    ^bb100:
      %498 = llvm.load %490 : !llvm.ptr -> i64
      %499 = arith.muli %arg6, %498 : i64
      %500 = llvm.mlir.addressof @LIMIT : !llvm.ptr
      %501 = llvm.load %500 : !llvm.ptr -> i64
      %502 = arith.cmpi sgt, %499, %501 : i64
      cf.cond_br %502, ^bb102, ^bb103
      ^bb102:
        cf.br ^bb101
      ^bb103:
        cf.br ^bb104
      ^bb104:
      %503 = llvm.load %494 : !llvm.ptr -> i64
      %504 = llvm.getelementptr %arg1[%arg2] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %503, %504 : i64, !llvm.ptr
      %506 = arith.constant 1 : i32
      %508 = arith.extsi %506 : i32 to i64
      %507 = arith.addi %arg2, %508 : i64
      %509 = arith.constant 1 : i32
      %511 = arith.extsi %509 : i32 to i64
      %510 = arith.addi %arg3, %511 : i64
      %512 = llvm.load %494 : !llvm.ptr -> i64
      %513 = llvm.load %494 : !llvm.ptr -> i64
      %514 = arith.addi %arg5, %513 : i64
      func.call @enumerate_sigs(%arg0, %arg1, %507, %510, %512, %514, %499, %arg7, %arg8, %arg9) : (!llvm.ptr, !llvm.ptr, i64, i64, i64, i64, i64, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
      %515 = llvm.load %490 : !llvm.ptr -> i64
      %516 = llvm.mlir.addressof @LIMIT : !llvm.ptr
      %517 = llvm.load %516 : !llvm.ptr -> i64
      %518 = arith.divsi %517, %480 : i64
      %519 = arith.cmpi sgt, %515, %518 : i64
      cf.cond_br %519, ^bb105, ^bb106
      ^bb105:
        cf.br ^bb101
      ^bb106:
        cf.br ^bb107
      ^bb107:
      %520 = llvm.load %490 : !llvm.ptr -> i64
      %521 = arith.muli %520, %480 : i64
      llvm.store %521, %490 : i64, !llvm.ptr
      %522 = llvm.load %494 : !llvm.ptr -> i64
      %523 = arith.constant 1 : i32
      %525 = arith.extsi %523 : i32 to i64
      %524 = arith.addi %522, %525 : i64
      llvm.store %524, %494 : i64, !llvm.ptr
      cf.br ^bb99
    ^bb101:
    func.return
  }
  func.func @main() -> i32 {
    %527 = llvm.mlir.addressof @MAX_N : !llvm.ptr
    %528 = llvm.load %527 : !llvm.ptr -> i64
    %529 = arith.constant 1 : i32
    %531 = arith.extsi %529 : i32 to i64
    %530 = arith.addi %528, %531 : i64
    %532 = llvm.mlir.addressof @MAX_N : !llvm.ptr
    %533 = llvm.load %532 : !llvm.ptr -> i64
    %534 = arith.constant 1 : i32
    %536 = arith.extsi %534 : i32 to i64
    %535 = arith.addi %533, %536 : i64
    %537 = arith.muli %530, %535 : i64
    %538 = arith.constant 8 : i32
    %539 = arith.extsi %538 : i32 to i64
    %526 = func.call @calloc(%537, %539) : (i64, i64) -> !llvm.ptr
    %541 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
    %542 = llvm.load %541 : !llvm.ptr -> i64
    %543 = arith.constant 1 : i32
    %545 = arith.extsi %543 : i32 to i64
    %544 = arith.addi %542, %545 : i64
    %546 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
    %547 = llvm.load %546 : !llvm.ptr -> i64
    %548 = arith.constant 2 : i32
    %550 = arith.extsi %548 : i32 to i64
    %549 = arith.addi %547, %550 : i64
    %551 = arith.muli %544, %549 : i64
    %552 = arith.constant 8 : i32
    %553 = arith.extsi %552 : i32 to i64
    %540 = func.call @calloc(%551, %553) : (i64, i64) -> !llvm.ptr
    %555 = arith.constant 60 : i32
    %556 = arith.constant 8 : i32
    %557 = arith.extsi %555 : i32 to i64
    %558 = arith.extsi %556 : i32 to i64
    %554 = func.call @calloc(%557, %558) : (i64, i64) -> !llvm.ptr
    %560 = arith.constant 16 : i32
    %561 = arith.constant 8 : i32
    %562 = arith.extsi %560 : i32 to i64
    %563 = arith.extsi %561 : i32 to i64
    %559 = func.call @calloc(%562, %563) : (i64, i64) -> !llvm.ptr
    %565 = arith.constant 1 : i32
    %566 = arith.constant 8 : i32
    %567 = arith.extsi %565 : i32 to i64
    %568 = arith.extsi %566 : i32 to i64
    %564 = func.call @calloc(%567, %568) : (i64, i64) -> !llvm.ptr
    %569 = llvm.mlir.zero : !llvm.ptr
    %570 = llvm.icmp "eq" %526, %569 : !llvm.ptr
    %571 = scf.if %570 -> (i1) {
      %572 = arith.constant true
      scf.yield %572 : i1
    } else {
      %573 = llvm.mlir.zero : !llvm.ptr
      %574 = llvm.icmp "eq" %540, %573 : !llvm.ptr
      scf.yield %574 : i1
    }
    %575 = scf.if %571 -> (i1) {
      %576 = arith.constant true
      scf.yield %576 : i1
    } else {
      %577 = llvm.mlir.zero : !llvm.ptr
      %578 = llvm.icmp "eq" %554, %577 : !llvm.ptr
      scf.yield %578 : i1
    }
    %579 = scf.if %575 -> (i1) {
      %580 = arith.constant true
      scf.yield %580 : i1
    } else {
      %581 = llvm.mlir.zero : !llvm.ptr
      %582 = llvm.icmp "eq" %559, %581 : !llvm.ptr
      scf.yield %582 : i1
    }
    %583 = scf.if %579 -> (i1) {
      %584 = arith.constant true
      scf.yield %584 : i1
    } else {
      %585 = llvm.mlir.zero : !llvm.ptr
      %586 = llvm.icmp "eq" %564, %585 : !llvm.ptr
      scf.yield %586 : i1
    }
    cf.cond_br %583, ^bb108, ^bb109
    ^bb108:
      %587 = arith.constant 1 : i32
      func.return %587 : i32
    ^bb109:
      cf.br ^bb110
    ^bb110:
    func.call @init_comb(%526, %540) : (!llvm.ptr, !llvm.ptr) -> ()
    %589 = arith.constant 1 : i32
    %590 = arith.constant 0 : i32
    %591 = arith.extsi %589 : i32 to i64
    %592 = arith.extsi %590 : i32 to i64
    %593 = llvm.getelementptr %564[%592] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %591, %593 : i64, !llvm.ptr
    %594 = arith.constant 0 : i32
    %595 = arith.extsi %594 : i32 to i64
    %596 = llvm.mlir.constant(1 : i64) : i64
    %597 = llvm.alloca %596 x i64 : (i64) -> !llvm.ptr
    llvm.store %595, %597 : i64, !llvm.ptr
    %598 = arith.constant 2 : i32
    %599 = arith.extsi %598 : i32 to i64
    %600 = llvm.mlir.constant(1 : i64) : i64
    %601 = llvm.alloca %600 x i64 : (i64) -> !llvm.ptr
    llvm.store %599, %601 : i64, !llvm.ptr
    cf.br ^bb111
    ^bb111:
    %602 = llvm.load %597 : !llvm.ptr -> i64
    %603 = arith.constant 60 : i32
    %605 = arith.extsi %603 : i32 to i64
    %604 = arith.cmpi slt, %602, %605 : i64
    cf.cond_br %604, ^bb112, ^bb113
    ^bb112:
      %606 = llvm.load %601 : !llvm.ptr -> i64
      %607 = arith.constant 2 : i32
      %609 = arith.extsi %607 : i32 to i64
      %608 = arith.cmpi eq, %606, %609 : i64
      %610 = scf.if %608 -> (i1) {
        %611 = arith.constant true
        scf.yield %611 : i1
      } else {
        %612 = llvm.load %601 : !llvm.ptr -> i64
        %613 = arith.constant 3 : i32
        %615 = arith.extsi %613 : i32 to i64
        %614 = arith.cmpi eq, %612, %615 : i64
        scf.yield %614 : i1
      }
      %616 = scf.if %610 -> (i1) {
        %617 = arith.constant true
        scf.yield %617 : i1
      } else {
        %618 = llvm.load %601 : !llvm.ptr -> i64
        %619 = arith.constant 3 : i32
        %621 = arith.extsi %619 : i32 to i64
        %620 = arith.cmpi sgt, %618, %621 : i64
        %622 = scf.if %620 -> (i1) {
          %623 = llvm.load %601 : !llvm.ptr -> i64
          %624 = arith.constant 2 : i32
          %626 = arith.extsi %624 : i32 to i64
          %625 = arith.remsi %623, %626 : i64
          %627 = arith.constant 0 : i32
          %629 = arith.extsi %627 : i32 to i64
          %628 = arith.cmpi ne, %625, %629 : i64
          scf.yield %628 : i1
        } else {
          %630 = arith.constant false
          scf.yield %630 : i1
        }
        %631 = scf.if %622 -> (i1) {
          %632 = llvm.load %601 : !llvm.ptr -> i64
          %633 = arith.constant 3 : i32
          %635 = arith.extsi %633 : i32 to i64
          %634 = arith.remsi %632, %635 : i64
          %636 = arith.constant 0 : i32
          %638 = arith.extsi %636 : i32 to i64
          %637 = arith.cmpi ne, %634, %638 : i64
          scf.yield %637 : i1
        } else {
          %639 = arith.constant false
          scf.yield %639 : i1
        }
        scf.yield %631 : i1
      }
      cf.cond_br %616, ^bb114, ^bb115
      ^bb114:
        %640 = arith.constant 1 : i32
        %641 = llvm.mlir.constant(1 : i64) : i64
        %642 = llvm.alloca %641 x i32 : (i64) -> !llvm.ptr
        llvm.store %640, %642 : i32, !llvm.ptr
        %643 = llvm.load %601 : !llvm.ptr -> i64
        %644 = arith.constant 3 : i32
        %646 = arith.extsi %644 : i32 to i64
        %645 = arith.cmpi sgt, %643, %646 : i64
        cf.cond_br %645, ^bb117, ^bb118
        ^bb117:
          %647 = arith.constant 5 : i32
          %648 = arith.extsi %647 : i32 to i64
          %649 = llvm.mlir.constant(1 : i64) : i64
          %650 = llvm.alloca %649 x i64 : (i64) -> !llvm.ptr
          llvm.store %648, %650 : i64, !llvm.ptr
          cf.br ^bb120
          ^bb120:
          %651 = llvm.load %650 : !llvm.ptr -> i64
          %652 = llvm.load %650 : !llvm.ptr -> i64
          %653 = arith.muli %651, %652 : i64
          %654 = llvm.load %601 : !llvm.ptr -> i64
          %655 = arith.cmpi sle, %653, %654 : i64
          cf.cond_br %655, ^bb121, ^bb122
          ^bb121:
            %656 = llvm.load %601 : !llvm.ptr -> i64
            %657 = llvm.load %650 : !llvm.ptr -> i64
            %658 = arith.remsi %656, %657 : i64
            %659 = arith.constant 0 : i32
            %661 = arith.extsi %659 : i32 to i64
            %660 = arith.cmpi eq, %658, %661 : i64
            %662 = scf.if %660 -> (i1) {
              %663 = arith.constant true
              scf.yield %663 : i1
            } else {
              %664 = llvm.load %601 : !llvm.ptr -> i64
              %665 = llvm.load %650 : !llvm.ptr -> i64
              %666 = arith.constant 2 : i32
              %668 = arith.extsi %666 : i32 to i64
              %667 = arith.addi %665, %668 : i64
              %669 = arith.remsi %664, %667 : i64
              %670 = arith.constant 0 : i32
              %672 = arith.extsi %670 : i32 to i64
              %671 = arith.cmpi eq, %669, %672 : i64
              scf.yield %671 : i1
            }
            cf.cond_br %662, ^bb123, ^bb124
            ^bb123:
              %673 = arith.constant 0 : i32
              llvm.store %673, %642 : i32, !llvm.ptr
              cf.br ^bb122
            ^bb124:
              cf.br ^bb125
            ^bb125:
            %674 = llvm.load %650 : !llvm.ptr -> i64
            %675 = arith.constant 6 : i32
            %677 = arith.extsi %675 : i32 to i64
            %676 = arith.addi %674, %677 : i64
            llvm.store %676, %650 : i64, !llvm.ptr
            cf.br ^bb120
          ^bb122:
          cf.br ^bb119
        ^bb118:
          cf.br ^bb119
        ^bb119:
        %678 = llvm.load %642 : !llvm.ptr -> i32
        %679 = arith.constant 1 : i32
        %680 = arith.cmpi eq, %678, %679 : i32
        cf.cond_br %680, ^bb126, ^bb127
        ^bb126:
          %681 = llvm.load %601 : !llvm.ptr -> i64
          %682 = llvm.load %597 : !llvm.ptr -> i64
          %683 = llvm.getelementptr %554[%682] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %681, %683 : i64, !llvm.ptr
          %684 = llvm.load %597 : !llvm.ptr -> i64
          %685 = arith.constant 1 : i32
          %687 = arith.extsi %685 : i32 to i64
          %686 = arith.addi %684, %687 : i64
          llvm.store %686, %597 : i64, !llvm.ptr
          cf.br ^bb128
        ^bb127:
          cf.br ^bb128
        ^bb128:
        cf.br ^bb116
      ^bb115:
        cf.br ^bb116
      ^bb116:
      %688 = llvm.load %601 : !llvm.ptr -> i64
      %689 = arith.constant 1 : i32
      %691 = arith.extsi %689 : i32 to i64
      %690 = arith.addi %688, %691 : i64
      llvm.store %690, %601 : i64, !llvm.ptr
      cf.br ^bb111
    ^bb113:
    %693 = arith.constant 0 : i32
    %694 = arith.constant 0 : i32
    %695 = llvm.mlir.addressof @MAX_EXP_SUM : !llvm.ptr
    %696 = llvm.load %695 : !llvm.ptr -> i64
    %697 = arith.constant 0 : i32
    %698 = arith.constant 1 : i32
    %699 = arith.extsi %693 : i32 to i64
    %700 = arith.extsi %694 : i32 to i64
    %701 = arith.extsi %697 : i32 to i64
    %702 = arith.extsi %698 : i32 to i64
    func.call @enumerate_sigs(%554, %559, %699, %700, %696, %701, %702, %526, %540, %564) : (!llvm.ptr, !llvm.ptr, i64, i64, i64, i64, i64, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
    %703 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %705 = arith.constant 0 : i32
    %706 = arith.extsi %705 : i32 to i64
    %707 = llvm.getelementptr %564[%706] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %704 = llvm.load %707 : !llvm.ptr -> i64
    %708 = llvm.call @printf(%703, %704) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%526) : (!llvm.ptr) -> ()
    func.call @free(%540) : (!llvm.ptr) -> ()
    func.call @free(%554) : (!llvm.ptr) -> ()
    func.call @free(%559) : (!llvm.ptr) -> ()
    func.call @free(%564) : (!llvm.ptr) -> ()
    %714 = arith.constant 0 : i32
    func.return %714 : i32
  }
}