Problem 754
Product of Gauss Factorials: product of GF(n) for 1<=n<=10^8, mod 1e9+7.
View problem on Project Euler
Performance comparison
| Metric | Our solution | Best known |
| Time complexity | O(n^2) | O(n) |
| Space complexity | O(n^2) | O(n) |
| Approach | Flow solution | Big-integer factorial |
| Verdict | Suboptimal |
Flow source
# Project Euler 754
# Product of Gauss Factorials: product of GF(n) for 1<=n<=10^8, mod 1e9+7.
extern {
function calloc(n: i64, size: i64) -> ptr<void>
function free(p: ptr<void>) -> void
function malloc(n: i64) -> ptr<void>
}
const MOD: i64 = 1000000007
const EXP_MOD: i64 = 1000000006
const LIMIT: i64 = 100000000
function mm(a: i64, b: i64) -> i64 {
return ((a as i128) * (b as i128) % (MOD as i128)) as i64
}
function mpow(base0: i64, exp0: i64) -> i64 {
let mut r: i64 = 1
let mut base: i64 = base0 % MOD
if base < 0 { base = base + MOD }
let mut exp: i64 = exp0
while exp > 0 {
if (exp & 1) != 0 { r = mm(r, base) }
base = mm(base, base)
exp = exp >> 1
}
return r
}
# Heapsort for i64 arrays
function heapsort_i64(arr: ptr<i64>, n: i64) -> void {
let mut start: i64 = n / 2
while start > 0 {
start = start - 1
let mut root: i64 = start
while 2 * root + 1 < n {
let child: i64 = 2 * root + 1
let mut swap_idx: i64 = root
if arr[swap_idx] < arr[child] { swap_idx = child }
if child + 1 < n {
if arr[swap_idx] < arr[child + 1] { swap_idx = child + 1 }
}
if swap_idx == root { break }
let tmp: i64 = arr[root]
arr[root] = arr[swap_idx]
arr[swap_idx] = tmp
root = swap_idx
}
}
let mut end: i64 = n - 1
while end > 0 {
let tmp: i64 = arr[0]
arr[0] = arr[end]
arr[end] = tmp
let mut root: i64 = 0
while 2 * root + 1 < end {
let child: i64 = 2 * root + 1
let mut swap_idx: i64 = root
if arr[swap_idx] < arr[child] { swap_idx = child }
if child + 1 < end {
if arr[swap_idx] < arr[child + 1] { swap_idx = child + 1 }
}
if swap_idx == root { break }
let tmp2: i64 = arr[root]
arr[root] = arr[swap_idx]
arr[swap_idx] = tmp2
root = swap_idx
}
end = end - 1
}
}
# Global superfactorial table
let mut sf_keys: ptr<i64> = null
let mut sf_vals: ptr<i64> = null
let mut sf_count: i64 = 0
function sf_lookup(key: i64) -> i64 {
let mut lo: i64 = 0
let hi: i64 = sf_count
while lo < hi {
let mid: i64 = (lo + hi) / 2
if sf_keys[mid] < key { lo = mid + 1 }
else { hi = mid }
}
if lo < sf_count && sf_keys[lo] == key { return sf_vals[lo] }
return 1
}
function compute_superfactorials(keys: ptr<i64>, nkeys0: i64) -> void {
heapsort_i64(keys, nkeys0)
let mut unique: i64 = 0
let mut i: i64 = 0
while i < nkeys0 {
if i == 0 || keys[i] != keys[i - 1] {
keys[unique] = keys[i]
unique = unique + 1
}
i = i + 1
}
let nkeys: i64 = unique
sf_keys = malloc(nkeys * 8) as ptr<i64>
sf_vals = malloc(nkeys * 8) as ptr<i64>
sf_count = 0
let mut pos: i64 = 0
if nkeys > 0 && keys[0] == 0 {
sf_keys[0] = 0
sf_vals[0] = 1
sf_count = 1
pos = 1
}
let stop: i64 = if nkeys > 0 { keys[nkeys - 1] } else { 0 }
let mut factorial: i64 = 1
let mut superfactorial: i64 = 1
let mut x: i64 = 1
while x <= stop {
factorial = mm(factorial, x % MOD)
superfactorial = mm(superfactorial, factorial)
while pos < nkeys && keys[pos] == x {
sf_keys[sf_count] = x
sf_vals[sf_count] = superfactorial
sf_count = sf_count + 1
pos = pos + 1
}
x = x + 1
}
}
function main() -> i32 {
let mu: ptr<i8> = calloc(LIMIT + 1, 1) as ptr<i8>
let comp: ptr<i8> = calloc(LIMIT + 1, 1) as ptr<i8>
let primes: ptr<i32> = malloc(6000000 * 4) as ptr<i32>
let mut pc: i64 = 0
let mut agg_cap: i64 = 65536
let mut agg_q: ptr<i64> = malloc(agg_cap * 8) as ptr<i64>
let mut agg_pos_prod: ptr<i64> = malloc(agg_cap * 8) as ptr<i64>
let mut agg_neg_prod: ptr<i64> = malloc(agg_cap * 8) as ptr<i64>
let mut agg_mu_sum: ptr<i64> = malloc(agg_cap * 8) as ptr<i64>
let mut agg_n: i64 = 0
agg_q[0] = LIMIT
agg_pos_prod[0] = 1
agg_neg_prod[0] = 1
agg_mu_sum[0] = 1
agg_n = 1
mu[1] = 1
let mut lo: i64 = 2
if lo <= LIMIT {
let mut q: i64 = LIMIT / lo
let mut hi: i64 = LIMIT / q
let mut pos_prod: i64 = 1
let mut neg_prod: i64 = 1
let mut mu_sum: i64 = 0
let mut x: i64 = 2
let mut done: bool = false
while x <= LIMIT && !done {
let mux: i8 = if comp[x] == 0 { 2 } else { mu[x] }
if comp[x] == 0 {
primes[pc] = x as i32
pc = pc + 1
mu[x] = 2
}
if mux == 1 {
pos_prod = mm(pos_prod, x % MOD)
mu_sum = mu_sum + 1
} else {
if mux == 2 {
neg_prod = mm(neg_prod, x % MOD)
mu_sum = mu_sum - 1
}
}
let mut i: i64 = 0
while i < pc {
let p: i32 = primes[i]
let y: i64 = x * (p as i64)
if y > LIMIT { break }
comp[y] = 1
if x % (p as i64) == 0 { break }
if mux == 1 { mu[y] = 2 }
else { if mux == 2 { mu[y] = 1 } }
i = i + 1
}
if x == hi {
if agg_n >= agg_cap {
let new_cap: i64 = agg_cap * 2
let nq: ptr<i64> = malloc(new_cap * 8) as ptr<i64>
let npp: ptr<i64> = malloc(new_cap * 8) as ptr<i64>
let nnp: ptr<i64> = malloc(new_cap * 8) as ptr<i64>
let nms: ptr<i64> = malloc(new_cap * 8) as ptr<i64>
let mut ci: i64 = 0
while ci < agg_n {
nq[ci] = agg_q[ci]
npp[ci] = agg_pos_prod[ci]
nnp[ci] = agg_neg_prod[ci]
nms[ci] = agg_mu_sum[ci]
ci = ci + 1
}
free(agg_q)
free(agg_pos_prod)
free(agg_neg_prod)
free(agg_mu_sum)
agg_q = nq
agg_pos_prod = npp
agg_neg_prod = nnp
agg_mu_sum = nms
agg_cap = new_cap
}
agg_q[agg_n] = q
agg_pos_prod[agg_n] = pos_prod
agg_neg_prod[agg_n] = neg_prod
agg_mu_sum[agg_n] = mu_sum
agg_n = agg_n + 1
lo = hi + 1
if lo > LIMIT { done = true }
else {
q = LIMIT / lo
hi = LIMIT / q
pos_prod = 1
neg_prod = 1
mu_sum = 0
}
}
x = x + 1
}
}
free(mu)
free(comp)
free(primes)
let keys: ptr<i64> = malloc(agg_n * 8) as ptr<i64>
let mut i: i64 = 0
while i < agg_n {
keys[i] = agg_q[i] - 1
i = i + 1
}
compute_superfactorials(keys, agg_n)
free(keys)
let mut result: i64 = 1
i = 0
while i < agg_n {
let aq: i64 = agg_q[i]
let exponent: i64 = (aq * (aq - 1) / 2) % EXP_MOD
if exponent != 0 {
result = mm(result, mpow(agg_pos_prod[i], exponent))
let neg_exp: i64 = (EXP_MOD - exponent) % EXP_MOD
if neg_exp != 0 {
result = mm(result, mpow(agg_neg_prod[i], neg_exp))
}
}
let sf_power: i64 = ((agg_mu_sum[i] % EXP_MOD) + EXP_MOD) % EXP_MOD
if sf_power != 0 {
let sf: i64 = sf_lookup(agg_q[i] - 1)
result = mm(result, mpow(sf, sf_power))
}
i = i + 1
}
free(agg_q)
free(agg_pos_prod)
free(agg_neg_prod)
free(agg_mu_sum)
free(sf_keys)
free(sf_vals)
printf("%lld\n", result)
return 0
}
Generated C
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Flow runtime helpers */
typedef struct flow_temp_node { struct flow_temp_node* next; } flow_temp_node;
static flow_temp_node* flow_temp_head = NULL;
static int flow_temp_atexit_set = 0;
__attribute__((unused)) static void flow_temp_free_all(void) {
while (flow_temp_head) {
flow_temp_node* n = flow_temp_head;
flow_temp_head = n->next;
free(n);
}
}
__attribute__((unused)) static void* flow_temp_alloc(size_t nbytes) {
flow_temp_node* node = (flow_temp_node*)malloc(sizeof(flow_temp_node) + nbytes);
if (!node) return NULL;
node->next = flow_temp_head;
flow_temp_head = node;
if (!flow_temp_atexit_set) {
flow_temp_atexit_set = 1;
atexit(flow_temp_free_all);
}
return (void*)(node + 1);
}
#ifndef FLOW_DIAG
#define FLOW_DIAG(msg) fprintf(stderr, "%s", (msg))
#endif
#ifndef FLOW_LOG
#define FLOW_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
#ifndef FLOW_LOG_EMPTY
#define FLOW_LOG_EMPTY(fmt) printf(fmt)
#endif
static char* flow_strcat(const char* a, const char* b) {
size_t la = strlen(a ? a : ""), lb = strlen(b ? b : "");
char* r = (char*)flow_temp_alloc(la + lb + 1);
if (!r) return NULL;
if (la) memcpy(r, a, la);
if (lb) memcpy(r + la, b, lb);
r[la + lb] = '\0';
return r;
}
#define __flow_in_arr(arr, val) __extension__ ({ \
int _found = 0; \
size_t _n = sizeof(arr)/sizeof((arr)[0]); \
for (size_t _i = 0; _i < _n; _i++) { \
if ((arr)[_i] == (val)) { _found = 1; break; } \
} _found; })
/* Unified fault handler (MISRA #279) — override with -DFLOW_FAULT_HANDLER=fn */
#ifndef FLOW_FAULT_HANDLER
__attribute__((unused)) static inline void flow_fault_handler(const char* msg) {
fprintf(stderr, "flow: %s\n", msg ? msg : "fault");
abort();
#if defined(__GNUC__) || defined(__clang__)
__builtin_unreachable();
#endif
}
#else
#define flow_fault_handler FLOW_FAULT_HANDLER
#endif
#define flow_div_by_zero_handler() flow_fault_handler("division by zero")
#define flow_shift_ub_handler() flow_fault_handler("invalid shift (amount out of range or left-shift of negative)")
#ifndef FLOW_CHECKED_DIV
#define FLOW_CHECKED_DIV(L, R) (((R) != 0) ? ((L) / (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_MOD
#define FLOW_CHECKED_MOD(L, R) (((R) != 0) ? ((L) % (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHL
#define FLOW_CHECKED_SHL(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull)) && ((L) >= 0)) ? ((L) << (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHR
#define FLOW_CHECKED_SHR(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull))) ? ((L) >> (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#include <math.h>
void* _ui_state = NULL;
static inline float i32_to_f32(int32_t v) { return (float)v; }
/* Host stub for @gpu kernels (device codegen replaces this). */
static inline int32_t gpu_thread_id(void) { return 0; }
int64_t mm_i64_i64(int64_t a, int64_t b);
int64_t mpow_i64_i64(int64_t base0, int64_t exp0);
void heapsort_i64_ptr_i64_i64(int64_t* arr, int64_t n);
int64_t sf_lookup_i64(int64_t key);
void compute_superfactorials_ptr_i64_i64(int64_t* keys, int64_t nkeys0);
int32_t main(void);
static const int64_t MOD = 1000000007;
static const int64_t EXP_MOD = 1000000006;
static const int64_t LIMIT = 100000000;
/* Module statics */
static int64_t* sf_keys = NULL;
static int64_t* sf_vals = NULL;
static int64_t sf_count = 0;
int64_t mm_i64_i64(int64_t a, int64_t b) {
return ((int64_t)(FLOW_CHECKED_MOD(((((__int128)(a)) * ((__int128)(b)))), (((__int128)(MOD))))));
}
int64_t mpow_i64_i64(int64_t base0, int64_t exp0) {
int64_t r = 1;
int64_t base = FLOW_CHECKED_MOD((base0), (MOD));
if (base < 0) {
base = (base + MOD);
}
int64_t exp = exp0;
while (exp > 0) {
if ((exp & 1) != 0) {
r = mm_i64_i64(r, base);
}
base = mm_i64_i64(base, base);
exp = FLOW_CHECKED_SHR((exp), (1));
}
return r;
}
void heapsort_i64_ptr_i64_i64(int64_t* arr, int64_t n) {
int64_t start = FLOW_CHECKED_DIV((n), (2));
while (start > 0) {
start = (start - 1);
int64_t root = start;
while (((2 * root) + 1) < n) {
int64_t child = ((2 * root) + 1);
int64_t swap_idx = root;
if (arr[swap_idx] < arr[child]) {
swap_idx = child;
}
if ((child + 1) < n) {
if (arr[swap_idx] < arr[(child + 1)]) {
swap_idx = (child + 1);
}
}
if (swap_idx == root) {
break;
}
int64_t tmp = arr[root];
arr[root] = arr[swap_idx];
arr[swap_idx] = tmp;
root = swap_idx;
}
}
int64_t end = (n - 1);
while (end > 0) {
int64_t tmp = arr[0];
arr[0] = arr[end];
arr[end] = tmp;
int64_t root = 0;
while (((2 * root) + 1) < end) {
int64_t child = ((2 * root) + 1);
int64_t swap_idx = root;
if (arr[swap_idx] < arr[child]) {
swap_idx = child;
}
if ((child + 1) < end) {
if (arr[swap_idx] < arr[(child + 1)]) {
swap_idx = (child + 1);
}
}
if (swap_idx == root) {
break;
}
int64_t tmp2 = arr[root];
arr[root] = arr[swap_idx];
arr[swap_idx] = tmp2;
root = swap_idx;
}
end = (end - 1);
}
}
int64_t sf_lookup_i64(int64_t key) {
int64_t lo = 0;
int64_t hi = sf_count;
while (lo < hi) {
int64_t mid = FLOW_CHECKED_DIV(((lo + hi)), (2));
if (sf_keys[mid] < key) {
lo = (mid + 1);
} else {
hi = mid;
}
}
if ((lo < sf_count && sf_keys[lo] == key)) {
return sf_vals[lo];
}
return 1;
}
void compute_superfactorials_ptr_i64_i64(int64_t* keys, int64_t nkeys0) {
heapsort_i64_ptr_i64_i64(keys, nkeys0);
int64_t unique = 0;
int64_t i = 0;
while (i < nkeys0) {
if ((i == 0 || keys[i] != keys[(i - 1)])) {
keys[unique] = keys[i];
unique = (unique + 1);
}
i = (i + 1);
}
int64_t nkeys = unique;
sf_keys = ((int64_t*)(malloc((nkeys * 8))));
sf_vals = ((int64_t*)(malloc((nkeys * 8))));
sf_count = 0;
int64_t pos = 0;
if ((nkeys > 0 && keys[0] == 0)) {
sf_keys[0] = 0;
sf_vals[0] = 1;
sf_count = 1;
pos = 1;
}
int64_t stop = ((nkeys > 0) ? (keys[(nkeys - 1)]) : (0));
int64_t factorial = 1;
int64_t superfactorial = 1;
int64_t x = 1;
while (x <= stop) {
factorial = mm_i64_i64(factorial, FLOW_CHECKED_MOD((x), (MOD)));
superfactorial = mm_i64_i64(superfactorial, factorial);
while ((pos < nkeys && keys[pos] == x)) {
sf_keys[sf_count] = x;
sf_vals[sf_count] = superfactorial;
sf_count = (sf_count + 1);
pos = (pos + 1);
}
x = (x + 1);
}
}
int32_t main(void) {
int8_t* mu = (int8_t*)(((int8_t*)(calloc((LIMIT + 1), 1))));
int8_t* comp = (int8_t*)(((int8_t*)(calloc((LIMIT + 1), 1))));
int32_t* primes = (int32_t*)(((int32_t*)(malloc((6000000 * 4)))));
int64_t pc = 0;
int64_t agg_cap = 65536;
int64_t* agg_q = (int64_t*)(((int64_t*)(malloc((agg_cap * 8)))));
int64_t* agg_pos_prod = (int64_t*)(((int64_t*)(malloc((agg_cap * 8)))));
int64_t* agg_neg_prod = (int64_t*)(((int64_t*)(malloc((agg_cap * 8)))));
int64_t* agg_mu_sum = (int64_t*)(((int64_t*)(malloc((agg_cap * 8)))));
int64_t agg_n = 0;
agg_q[0] = LIMIT;
agg_pos_prod[0] = 1;
agg_neg_prod[0] = 1;
agg_mu_sum[0] = 1;
agg_n = 1;
mu[1] = 1;
int64_t lo = 2;
if (lo <= LIMIT) {
int64_t q = FLOW_CHECKED_DIV((LIMIT), (lo));
int64_t hi = FLOW_CHECKED_DIV((LIMIT), (q));
int64_t pos_prod = 1;
int64_t neg_prod = 1;
int64_t mu_sum = 0;
int64_t x = 2;
bool done = 0;
while ((x <= LIMIT && (!(done)))) {
int8_t mux = ((comp[x] == 0) ? (2) : (mu[x]));
if (comp[x] == 0) {
primes[pc] = ((int32_t)(x));
pc = (pc + 1);
mu[x] = 2;
}
if (mux == 1) {
pos_prod = mm_i64_i64(pos_prod, FLOW_CHECKED_MOD((x), (MOD)));
mu_sum = (mu_sum + 1);
} else {
if (mux == 2) {
neg_prod = mm_i64_i64(neg_prod, FLOW_CHECKED_MOD((x), (MOD)));
mu_sum = (mu_sum - 1);
}
}
int64_t i = 0;
while (i < pc) {
int32_t p = primes[i];
int64_t y = (x * ((int64_t)(p)));
if (y > LIMIT) {
break;
}
comp[y] = 1;
if (FLOW_CHECKED_MOD((x), (((int64_t)(p)))) == 0) {
break;
}
if (mux == 1) {
mu[y] = 2;
} else {
if (mux == 2) {
mu[y] = 1;
}
}
i = (i + 1);
}
if (x == hi) {
if (agg_n >= agg_cap) {
int64_t new_cap = (agg_cap * 2);
int64_t* nq = (int64_t*)(((int64_t*)(malloc((new_cap * 8)))));
int64_t* npp = (int64_t*)(((int64_t*)(malloc((new_cap * 8)))));
int64_t* nnp = (int64_t*)(((int64_t*)(malloc((new_cap * 8)))));
int64_t* nms = (int64_t*)(((int64_t*)(malloc((new_cap * 8)))));
int64_t ci = 0;
while (ci < agg_n) {
nq[ci] = agg_q[ci];
npp[ci] = agg_pos_prod[ci];
nnp[ci] = agg_neg_prod[ci];
nms[ci] = agg_mu_sum[ci];
ci = (ci + 1);
}
free(agg_q);
free(agg_pos_prod);
free(agg_neg_prod);
free(agg_mu_sum);
agg_q = nq;
agg_pos_prod = npp;
agg_neg_prod = nnp;
agg_mu_sum = nms;
agg_cap = new_cap;
}
agg_q[agg_n] = q;
agg_pos_prod[agg_n] = pos_prod;
agg_neg_prod[agg_n] = neg_prod;
agg_mu_sum[agg_n] = mu_sum;
agg_n = (agg_n + 1);
lo = (hi + 1);
if (lo > LIMIT) {
done = 1;
} else {
q = FLOW_CHECKED_DIV((LIMIT), (lo));
hi = FLOW_CHECKED_DIV((LIMIT), (q));
pos_prod = 1;
neg_prod = 1;
mu_sum = 0;
}
}
x = (x + 1);
}
}
free(mu);
free(comp);
free(primes);
int64_t* keys = (int64_t*)(((int64_t*)(malloc((agg_n * 8)))));
int64_t i = 0;
while (i < agg_n) {
keys[i] = (agg_q[i] - 1);
i = (i + 1);
}
compute_superfactorials_ptr_i64_i64(keys, agg_n);
free(keys);
int64_t result = 1;
i = 0;
while (i < agg_n) {
int64_t aq = agg_q[i];
int64_t exponent = FLOW_CHECKED_MOD((FLOW_CHECKED_DIV(((aq * (aq - 1))), (2))), (EXP_MOD));
if (exponent != 0) {
result = mm_i64_i64(result, mpow_i64_i64(agg_pos_prod[i], exponent));
int64_t neg_exp = FLOW_CHECKED_MOD(((EXP_MOD - exponent)), (EXP_MOD));
if (neg_exp != 0) {
result = mm_i64_i64(result, mpow_i64_i64(agg_neg_prod[i], neg_exp));
}
}
int64_t sf_power = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD((agg_mu_sum[i]), (EXP_MOD)) + EXP_MOD)), (EXP_MOD));
if (sf_power != 0) {
int64_t sf = sf_lookup_i64((agg_q[i] - 1));
result = mm_i64_i64(result, mpow_i64_i64(sf, sf_power));
}
i = (i + 1);
}
free(agg_q);
free(agg_pos_prod);
free(agg_neg_prod);
free(agg_mu_sum);
free(sf_keys);
free(sf_vals);
printf("%lld\n", result);
return 0;
}
Generated MLIR
module {
llvm.func @printf(!llvm.ptr, ...) -> i32
llvm.mlir.global internal constant @str_0("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
func.func private @calloc(i64, i64) -> !llvm.ptr
func.func private @free(!llvm.ptr) -> ()
func.func private @malloc(i64) -> !llvm.ptr
// Constant: MOD
llvm.mlir.global internal constant @MOD(1000000007 : i64) : i64
// Constant: EXP_MOD
llvm.mlir.global internal constant @EXP_MOD(1000000006 : i64) : i64
// Constant: LIMIT
llvm.mlir.global internal constant @LIMIT(100000000 : i64) : i64
func.func @mm(%arg0: i64, %arg1: i64) -> i64 {
%0 = arith.extsi %arg0 : i64 to i128
%1 = arith.extsi %arg1 : i64 to i128
%3 = arith.trunci %0 : i128 to i64
%4 = arith.trunci %1 : i128 to i64
%2 = arith.muli %3, %4 : i64
%5 = llvm.mlir.addressof @MOD : !llvm.ptr
%6 = llvm.load %5 : !llvm.ptr -> i64
%7 = arith.extsi %6 : i64 to i128
%9 = arith.trunci %7 : i128 to i64
%8 = arith.remsi %2, %9 : i64
func.return %8 : i64
}
func.func @mpow(%arg0: i64, %arg1: i64) -> i64 {
%10 = arith.constant 1 : i32
%11 = arith.extsi %10 : i32 to i64
%12 = llvm.mlir.constant(1 : i64) : i64
%13 = llvm.alloca %12 x i64 : (i64) -> !llvm.ptr
llvm.store %11, %13 : i64, !llvm.ptr
%14 = llvm.mlir.addressof @MOD : !llvm.ptr
%15 = llvm.load %14 : !llvm.ptr -> i64
%16 = arith.remsi %arg0, %15 : i64
%17 = llvm.mlir.constant(1 : i64) : i64
%18 = llvm.alloca %17 x i64 : (i64) -> !llvm.ptr
llvm.store %16, %18 : i64, !llvm.ptr
%19 = llvm.load %18 : !llvm.ptr -> i64
%20 = arith.constant 0 : i32
%22 = arith.extsi %20 : i32 to i64
%21 = arith.cmpi slt, %19, %22 : i64
cf.cond_br %21, ^bb0, ^bb1
^bb0:
%23 = llvm.load %18 : !llvm.ptr -> i64
%24 = llvm.mlir.addressof @MOD : !llvm.ptr
%25 = llvm.load %24 : !llvm.ptr -> i64
%26 = arith.addi %23, %25 : i64
llvm.store %26, %18 : i64, !llvm.ptr
cf.br ^bb2
^bb1:
cf.br ^bb2
^bb2:
%27 = llvm.mlir.constant(1 : i64) : i64
%28 = llvm.alloca %27 x i64 : (i64) -> !llvm.ptr
llvm.store %arg1, %28 : i64, !llvm.ptr
cf.br ^bb3
^bb3:
%29 = llvm.load %28 : !llvm.ptr -> i64
%30 = arith.constant 0 : i32
%32 = arith.extsi %30 : i32 to i64
%31 = arith.cmpi sgt, %29, %32 : i64
cf.cond_br %31, ^bb4, ^bb5
^bb4:
%33 = llvm.load %28 : !llvm.ptr -> i64
%34 = arith.constant 1 : i32
%36 = arith.extsi %34 : i32 to i64
%35 = arith.andi %33, %36 : i64
%37 = arith.constant 0 : i32
%39 = arith.extsi %37 : i32 to i64
%38 = arith.cmpi ne, %35, %39 : i64
cf.cond_br %38, ^bb6, ^bb7
^bb6:
%41 = llvm.load %13 : !llvm.ptr -> i64
%42 = llvm.load %18 : !llvm.ptr -> i64
%40 = func.call @mm(%41, %42) : (i64, i64) -> i64
llvm.store %40, %13 : i64, !llvm.ptr
cf.br ^bb8
^bb7:
cf.br ^bb8
^bb8:
%44 = llvm.load %18 : !llvm.ptr -> i64
%45 = llvm.load %18 : !llvm.ptr -> i64
%43 = func.call @mm(%44, %45) : (i64, i64) -> i64
llvm.store %43, %18 : i64, !llvm.ptr
%46 = llvm.load %28 : !llvm.ptr -> i64
%47 = arith.constant 1 : i32
%49 = arith.extsi %47 : i32 to i64
%48 = arith.shrsi %46, %49 : i64
llvm.store %48, %28 : i64, !llvm.ptr
cf.br ^bb3
^bb5:
%50 = llvm.load %13 : !llvm.ptr -> i64
func.return %50 : i64
}
func.func @heapsort_i64(%arg0: !llvm.ptr, %arg1: i64) -> () {
%51 = arith.constant 2 : i32
%53 = arith.extsi %51 : i32 to i64
%52 = arith.divsi %arg1, %53 : i64
%54 = llvm.mlir.constant(1 : i64) : i64
%55 = llvm.alloca %54 x i64 : (i64) -> !llvm.ptr
llvm.store %52, %55 : i64, !llvm.ptr
cf.br ^bb9
^bb9:
%56 = llvm.load %55 : !llvm.ptr -> i64
%57 = arith.constant 0 : i32
%59 = arith.extsi %57 : i32 to i64
%58 = arith.cmpi sgt, %56, %59 : i64
cf.cond_br %58, ^bb10, ^bb11
^bb10:
%60 = llvm.load %55 : !llvm.ptr -> i64
%61 = arith.constant 1 : i32
%63 = arith.extsi %61 : i32 to i64
%62 = arith.subi %60, %63 : i64
llvm.store %62, %55 : i64, !llvm.ptr
%64 = llvm.load %55 : !llvm.ptr -> i64
%65 = llvm.mlir.constant(1 : i64) : i64
%66 = llvm.alloca %65 x i64 : (i64) -> !llvm.ptr
llvm.store %64, %66 : i64, !llvm.ptr
cf.br ^bb12
^bb12:
%67 = arith.constant 2 : i32
%68 = llvm.load %66 : !llvm.ptr -> i64
%70 = arith.extsi %67 : i32 to i64
%69 = arith.muli %70, %68 : i64
%71 = arith.constant 1 : i32
%73 = arith.extsi %71 : i32 to i64
%72 = arith.addi %69, %73 : i64
%74 = arith.cmpi slt, %72, %arg1 : i64
cf.cond_br %74, ^bb13, ^bb14
^bb13:
%75 = arith.constant 2 : i32
%76 = llvm.load %66 : !llvm.ptr -> i64
%78 = arith.extsi %75 : i32 to i64
%77 = arith.muli %78, %76 : i64
%79 = arith.constant 1 : i32
%81 = arith.extsi %79 : i32 to i64
%80 = arith.addi %77, %81 : i64
%82 = llvm.load %66 : !llvm.ptr -> i64
%83 = llvm.mlir.constant(1 : i64) : i64
%84 = llvm.alloca %83 x i64 : (i64) -> !llvm.ptr
llvm.store %82, %84 : i64, !llvm.ptr
%86 = llvm.load %84 : !llvm.ptr -> i64
%87 = llvm.getelementptr %arg0[%86] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%85 = llvm.load %87 : !llvm.ptr -> i64
%89 = llvm.getelementptr %arg0[%80] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%88 = llvm.load %89 : !llvm.ptr -> i64
%90 = arith.cmpi slt, %85, %88 : i64
cf.cond_br %90, ^bb15, ^bb16
^bb15:
llvm.store %80, %84 : i64, !llvm.ptr
cf.br ^bb17
^bb16:
cf.br ^bb17
^bb17:
%91 = arith.constant 1 : i32
%93 = arith.extsi %91 : i32 to i64
%92 = arith.addi %80, %93 : i64
%94 = arith.cmpi slt, %92, %arg1 : i64
cf.cond_br %94, ^bb18, ^bb19
^bb18:
%96 = llvm.load %84 : !llvm.ptr -> i64
%97 = llvm.getelementptr %arg0[%96] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%95 = llvm.load %97 : !llvm.ptr -> i64
%99 = arith.constant 1 : i32
%101 = arith.extsi %99 : i32 to i64
%100 = arith.addi %80, %101 : i64
%102 = llvm.getelementptr %arg0[%100] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%98 = llvm.load %102 : !llvm.ptr -> i64
%103 = arith.cmpi slt, %95, %98 : i64
cf.cond_br %103, ^bb21, ^bb22
^bb21:
%104 = arith.constant 1 : i32
%106 = arith.extsi %104 : i32 to i64
%105 = arith.addi %80, %106 : i64
llvm.store %105, %84 : i64, !llvm.ptr
cf.br ^bb23
^bb22:
cf.br ^bb23
^bb23:
cf.br ^bb20
^bb19:
cf.br ^bb20
^bb20:
%107 = llvm.load %84 : !llvm.ptr -> i64
%108 = llvm.load %66 : !llvm.ptr -> i64
%109 = arith.cmpi eq, %107, %108 : i64
cf.cond_br %109, ^bb24, ^bb25
^bb24:
cf.br ^bb14
^bb25:
cf.br ^bb26
^bb26:
%111 = llvm.load %66 : !llvm.ptr -> i64
%112 = llvm.getelementptr %arg0[%111] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%110 = llvm.load %112 : !llvm.ptr -> i64
%114 = llvm.load %84 : !llvm.ptr -> i64
%115 = llvm.getelementptr %arg0[%114] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%113 = llvm.load %115 : !llvm.ptr -> i64
%116 = llvm.load %66 : !llvm.ptr -> i64
%117 = llvm.getelementptr %arg0[%116] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %113, %117 : i64, !llvm.ptr
%118 = llvm.load %84 : !llvm.ptr -> i64
%119 = llvm.getelementptr %arg0[%118] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %110, %119 : i64, !llvm.ptr
%120 = llvm.load %84 : !llvm.ptr -> i64
llvm.store %120, %66 : i64, !llvm.ptr
cf.br ^bb12
^bb14:
cf.br ^bb9
^bb11:
%121 = arith.constant 1 : i32
%123 = arith.extsi %121 : i32 to i64
%122 = arith.subi %arg1, %123 : i64
%124 = llvm.mlir.constant(1 : i64) : i64
%125 = llvm.alloca %124 x i64 : (i64) -> !llvm.ptr
llvm.store %122, %125 : i64, !llvm.ptr
cf.br ^bb27
^bb27:
%126 = llvm.load %125 : !llvm.ptr -> i64
%127 = arith.constant 0 : i32
%129 = arith.extsi %127 : i32 to i64
%128 = arith.cmpi sgt, %126, %129 : i64
cf.cond_br %128, ^bb28, ^bb29
^bb28:
%131 = arith.constant 0 : i32
%132 = arith.extsi %131 : i32 to i64
%133 = llvm.getelementptr %arg0[%132] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%130 = llvm.load %133 : !llvm.ptr -> i64
%135 = llvm.load %125 : !llvm.ptr -> i64
%136 = llvm.getelementptr %arg0[%135] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%134 = llvm.load %136 : !llvm.ptr -> i64
%137 = arith.constant 0 : i32
%138 = arith.extsi %137 : i32 to i64
%139 = llvm.getelementptr %arg0[%138] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %134, %139 : i64, !llvm.ptr
%140 = llvm.load %125 : !llvm.ptr -> i64
%141 = llvm.getelementptr %arg0[%140] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %130, %141 : i64, !llvm.ptr
%142 = arith.constant 0 : i32
%143 = arith.extsi %142 : i32 to i64
%144 = llvm.mlir.constant(1 : i64) : i64
%145 = llvm.alloca %144 x i64 : (i64) -> !llvm.ptr
llvm.store %143, %145 : i64, !llvm.ptr
cf.br ^bb30
^bb30:
%146 = arith.constant 2 : i32
%147 = llvm.load %145 : !llvm.ptr -> i64
%149 = arith.extsi %146 : i32 to i64
%148 = arith.muli %149, %147 : i64
%150 = arith.constant 1 : i32
%152 = arith.extsi %150 : i32 to i64
%151 = arith.addi %148, %152 : i64
%153 = llvm.load %125 : !llvm.ptr -> i64
%154 = arith.cmpi slt, %151, %153 : i64
cf.cond_br %154, ^bb31, ^bb32
^bb31:
%155 = arith.constant 2 : i32
%156 = llvm.load %145 : !llvm.ptr -> i64
%158 = arith.extsi %155 : i32 to i64
%157 = arith.muli %158, %156 : i64
%159 = arith.constant 1 : i32
%161 = arith.extsi %159 : i32 to i64
%160 = arith.addi %157, %161 : i64
%162 = llvm.load %145 : !llvm.ptr -> i64
%163 = llvm.mlir.constant(1 : i64) : i64
%164 = llvm.alloca %163 x i64 : (i64) -> !llvm.ptr
llvm.store %162, %164 : i64, !llvm.ptr
%166 = llvm.load %164 : !llvm.ptr -> i64
%167 = llvm.getelementptr %arg0[%166] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%165 = llvm.load %167 : !llvm.ptr -> i64
%169 = llvm.getelementptr %arg0[%160] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%168 = llvm.load %169 : !llvm.ptr -> i64
%170 = arith.cmpi slt, %165, %168 : i64
cf.cond_br %170, ^bb33, ^bb34
^bb33:
llvm.store %160, %164 : i64, !llvm.ptr
cf.br ^bb35
^bb34:
cf.br ^bb35
^bb35:
%171 = arith.constant 1 : i32
%173 = arith.extsi %171 : i32 to i64
%172 = arith.addi %160, %173 : i64
%174 = llvm.load %125 : !llvm.ptr -> i64
%175 = arith.cmpi slt, %172, %174 : i64
cf.cond_br %175, ^bb36, ^bb37
^bb36:
%177 = llvm.load %164 : !llvm.ptr -> i64
%178 = llvm.getelementptr %arg0[%177] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%176 = llvm.load %178 : !llvm.ptr -> i64
%180 = arith.constant 1 : i32
%182 = arith.extsi %180 : i32 to i64
%181 = arith.addi %160, %182 : i64
%183 = llvm.getelementptr %arg0[%181] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%179 = llvm.load %183 : !llvm.ptr -> i64
%184 = arith.cmpi slt, %176, %179 : i64
cf.cond_br %184, ^bb39, ^bb40
^bb39:
%185 = arith.constant 1 : i32
%187 = arith.extsi %185 : i32 to i64
%186 = arith.addi %160, %187 : i64
llvm.store %186, %164 : i64, !llvm.ptr
cf.br ^bb41
^bb40:
cf.br ^bb41
^bb41:
cf.br ^bb38
^bb37:
cf.br ^bb38
^bb38:
%188 = llvm.load %164 : !llvm.ptr -> i64
%189 = llvm.load %145 : !llvm.ptr -> i64
%190 = arith.cmpi eq, %188, %189 : i64
cf.cond_br %190, ^bb42, ^bb43
^bb42:
cf.br ^bb32
^bb43:
cf.br ^bb44
^bb44:
%192 = llvm.load %145 : !llvm.ptr -> i64
%193 = llvm.getelementptr %arg0[%192] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%191 = llvm.load %193 : !llvm.ptr -> i64
%195 = llvm.load %164 : !llvm.ptr -> i64
%196 = llvm.getelementptr %arg0[%195] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%194 = llvm.load %196 : !llvm.ptr -> i64
%197 = llvm.load %145 : !llvm.ptr -> i64
%198 = llvm.getelementptr %arg0[%197] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %194, %198 : i64, !llvm.ptr
%199 = llvm.load %164 : !llvm.ptr -> i64
%200 = llvm.getelementptr %arg0[%199] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %191, %200 : i64, !llvm.ptr
%201 = llvm.load %164 : !llvm.ptr -> i64
llvm.store %201, %145 : i64, !llvm.ptr
cf.br ^bb30
^bb32:
%202 = llvm.load %125 : !llvm.ptr -> i64
%203 = arith.constant 1 : i32
%205 = arith.extsi %203 : i32 to i64
%204 = arith.subi %202, %205 : i64
llvm.store %204, %125 : i64, !llvm.ptr
cf.br ^bb27
^bb29:
func.return
}
// Module static: sf_keys
llvm.mlir.global internal @sf_keys() {addr_space = 0 : i32} : !llvm.ptr {
%206 = llvm.mlir.zero : !llvm.ptr
llvm.return %206 : !llvm.ptr
}
// Module static: sf_vals
llvm.mlir.global internal @sf_vals() {addr_space = 0 : i32} : !llvm.ptr {
%207 = llvm.mlir.zero : !llvm.ptr
llvm.return %207 : !llvm.ptr
}
// Module static: sf_count
llvm.mlir.global internal @sf_count(0 : i64) : i64
func.func @sf_lookup(%arg0: i64) -> i64 {
%208 = arith.constant 0 : i32
%209 = arith.extsi %208 : i32 to i64
%210 = llvm.mlir.constant(1 : i64) : i64
%211 = llvm.alloca %210 x i64 : (i64) -> !llvm.ptr
llvm.store %209, %211 : i64, !llvm.ptr
%212 = llvm.mlir.addressof @sf_count : !llvm.ptr
%213 = llvm.load %212 : !llvm.ptr -> i64
cf.br ^bb45(%213 : i64)
^bb45(%214: i64):
%215 = llvm.load %211 : !llvm.ptr -> i64
%216 = arith.cmpi slt, %215, %214 : i64
cf.cond_br %216, ^bb46(%214 : i64), ^bb47(%214 : i64)
^bb46(%217: i64):
%218 = llvm.load %211 : !llvm.ptr -> i64
%219 = arith.addi %218, %217 : i64
%220 = arith.constant 2 : i32
%222 = arith.extsi %220 : i32 to i64
%221 = arith.divsi %219, %222 : i64
%224 = llvm.mlir.addressof @sf_keys : !llvm.ptr
%225 = llvm.load %224 : !llvm.ptr -> !llvm.ptr
%226 = llvm.getelementptr %225[%221] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%223 = llvm.load %226 : !llvm.ptr -> i64
%227 = arith.cmpi slt, %223, %arg0 : i64
%228 = scf.if %227 -> (i64) {
%229 = arith.constant 1 : i32
%231 = arith.extsi %229 : i32 to i64
%230 = arith.addi %221, %231 : i64
llvm.store %230, %211 : i64, !llvm.ptr
scf.yield %217 : i64
} else {
scf.yield %221 : i64
}
cf.br ^bb45(%228 : i64)
^bb47(%232: i64):
%233 = llvm.load %211 : !llvm.ptr -> i64
%234 = llvm.mlir.addressof @sf_count : !llvm.ptr
%235 = llvm.load %234 : !llvm.ptr -> i64
%236 = arith.cmpi slt, %233, %235 : i64
%237 = scf.if %236 -> (i1) {
%239 = llvm.mlir.addressof @sf_keys : !llvm.ptr
%240 = llvm.load %239 : !llvm.ptr -> !llvm.ptr
%241 = llvm.load %211 : !llvm.ptr -> i64
%242 = llvm.getelementptr %240[%241] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%238 = llvm.load %242 : !llvm.ptr -> i64
%243 = arith.cmpi eq, %238, %arg0 : i64
scf.yield %243 : i1
} else {
%244 = arith.constant false
scf.yield %244 : i1
}
cf.cond_br %237, ^bb48, ^bb49
^bb48:
%246 = llvm.mlir.addressof @sf_vals : !llvm.ptr
%247 = llvm.load %246 : !llvm.ptr -> !llvm.ptr
%248 = llvm.load %211 : !llvm.ptr -> i64
%249 = llvm.getelementptr %247[%248] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%245 = llvm.load %249 : !llvm.ptr -> i64
func.return %245 : i64
^bb49:
cf.br ^bb50
^bb50:
%250 = arith.constant 1 : i32
%251 = arith.extsi %250 : i32 to i64
func.return %251 : i64
}
func.func @compute_superfactorials(%arg0: !llvm.ptr, %arg1: i64) -> () {
func.call @heapsort_i64(%arg0, %arg1) : (!llvm.ptr, i64) -> ()
%253 = arith.constant 0 : i32
%254 = arith.extsi %253 : i32 to i64
%255 = llvm.mlir.constant(1 : i64) : i64
%256 = llvm.alloca %255 x i64 : (i64) -> !llvm.ptr
llvm.store %254, %256 : i64, !llvm.ptr
%257 = arith.constant 0 : i32
%258 = arith.extsi %257 : i32 to i64
%259 = llvm.mlir.constant(1 : i64) : i64
%260 = llvm.alloca %259 x i64 : (i64) -> !llvm.ptr
llvm.store %258, %260 : i64, !llvm.ptr
cf.br ^bb51
^bb51:
%261 = llvm.load %260 : !llvm.ptr -> i64
%262 = arith.cmpi slt, %261, %arg1 : i64
cf.cond_br %262, ^bb52, ^bb53
^bb52:
%263 = llvm.load %260 : !llvm.ptr -> i64
%264 = arith.constant 0 : i32
%266 = arith.extsi %264 : i32 to i64
%265 = arith.cmpi eq, %263, %266 : i64
%267 = scf.if %265 -> (i1) {
%268 = arith.constant true
scf.yield %268 : i1
} else {
%270 = llvm.load %260 : !llvm.ptr -> i64
%271 = llvm.getelementptr %arg0[%270] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%269 = llvm.load %271 : !llvm.ptr -> i64
%273 = llvm.load %260 : !llvm.ptr -> i64
%274 = arith.constant 1 : i32
%276 = arith.extsi %274 : i32 to i64
%275 = arith.subi %273, %276 : i64
%277 = llvm.getelementptr %arg0[%275] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%272 = llvm.load %277 : !llvm.ptr -> i64
%278 = arith.cmpi ne, %269, %272 : i64
scf.yield %278 : i1
}
cf.cond_br %267, ^bb54, ^bb55
^bb54:
%280 = llvm.load %260 : !llvm.ptr -> i64
%281 = llvm.getelementptr %arg0[%280] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%279 = llvm.load %281 : !llvm.ptr -> i64
%282 = llvm.load %256 : !llvm.ptr -> i64
%283 = llvm.getelementptr %arg0[%282] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %279, %283 : i64, !llvm.ptr
%284 = llvm.load %256 : !llvm.ptr -> i64
%285 = arith.constant 1 : i32
%287 = arith.extsi %285 : i32 to i64
%286 = arith.addi %284, %287 : i64
llvm.store %286, %256 : i64, !llvm.ptr
cf.br ^bb56
^bb55:
cf.br ^bb56
^bb56:
%288 = llvm.load %260 : !llvm.ptr -> i64
%289 = arith.constant 1 : i32
%291 = arith.extsi %289 : i32 to i64
%290 = arith.addi %288, %291 : i64
llvm.store %290, %260 : i64, !llvm.ptr
cf.br ^bb51
^bb53:
%292 = llvm.load %256 : !llvm.ptr -> i64
%294 = arith.constant 8 : i32
%296 = arith.extsi %294 : i32 to i64
%295 = arith.muli %292, %296 : i64
%293 = func.call @malloc(%295) : (i64) -> !llvm.ptr
%297 = llvm.mlir.addressof @sf_keys : !llvm.ptr
llvm.store %293, %297 : !llvm.ptr, !llvm.ptr
%299 = arith.constant 8 : i32
%301 = arith.extsi %299 : i32 to i64
%300 = arith.muli %292, %301 : i64
%298 = func.call @malloc(%300) : (i64) -> !llvm.ptr
%302 = llvm.mlir.addressof @sf_vals : !llvm.ptr
llvm.store %298, %302 : !llvm.ptr, !llvm.ptr
%303 = arith.constant 0 : i32
%304 = arith.extsi %303 : i32 to i64
%305 = llvm.mlir.addressof @sf_count : !llvm.ptr
llvm.store %304, %305 : i64, !llvm.ptr
%306 = arith.constant 0 : i32
%307 = arith.extsi %306 : i32 to i64
%308 = llvm.mlir.constant(1 : i64) : i64
%309 = llvm.alloca %308 x i64 : (i64) -> !llvm.ptr
llvm.store %307, %309 : i64, !llvm.ptr
%310 = arith.constant 0 : i32
%312 = arith.extsi %310 : i32 to i64
%311 = arith.cmpi sgt, %292, %312 : i64
%313 = scf.if %311 -> (i1) {
%315 = arith.constant 0 : i32
%316 = arith.extsi %315 : i32 to i64
%317 = llvm.getelementptr %arg0[%316] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%314 = llvm.load %317 : !llvm.ptr -> i64
%318 = arith.constant 0 : i32
%320 = arith.extsi %318 : i32 to i64
%319 = arith.cmpi eq, %314, %320 : i64
scf.yield %319 : i1
} else {
%321 = arith.constant false
scf.yield %321 : i1
}
cf.cond_br %313, ^bb57, ^bb58
^bb57:
%322 = arith.constant 0 : i32
%323 = llvm.mlir.addressof @sf_keys : !llvm.ptr
%324 = llvm.load %323 : !llvm.ptr -> !llvm.ptr
%325 = arith.constant 0 : i32
%326 = arith.extsi %322 : i32 to i64
%327 = arith.extsi %325 : i32 to i64
%328 = llvm.getelementptr %324[%327] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %326, %328 : i64, !llvm.ptr
%329 = arith.constant 1 : i32
%330 = llvm.mlir.addressof @sf_vals : !llvm.ptr
%331 = llvm.load %330 : !llvm.ptr -> !llvm.ptr
%332 = arith.constant 0 : i32
%333 = arith.extsi %329 : i32 to i64
%334 = arith.extsi %332 : i32 to i64
%335 = llvm.getelementptr %331[%334] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %333, %335 : i64, !llvm.ptr
%336 = arith.constant 1 : i32
%337 = arith.extsi %336 : i32 to i64
%338 = llvm.mlir.addressof @sf_count : !llvm.ptr
llvm.store %337, %338 : i64, !llvm.ptr
%339 = arith.constant 1 : i32
%340 = arith.extsi %339 : i32 to i64
llvm.store %340, %309 : i64, !llvm.ptr
cf.br ^bb59
^bb58:
cf.br ^bb59
^bb59:
%341 = arith.constant 0 : i32
%343 = arith.extsi %341 : i32 to i64
%342 = arith.cmpi sgt, %292, %343 : i64
%344 = scf.if %342 -> (i64) {
%346 = arith.constant 1 : i32
%348 = arith.extsi %346 : i32 to i64
%347 = arith.subi %292, %348 : i64
%349 = llvm.getelementptr %arg0[%347] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%345 = llvm.load %349 : !llvm.ptr -> i64
scf.yield %345 : i64
} else {
%350 = arith.constant 0 : i32
scf.yield %350 : i32
}
%351 = arith.constant 1 : i32
%352 = arith.extsi %351 : i32 to i64
%353 = llvm.mlir.constant(1 : i64) : i64
%354 = llvm.alloca %353 x i64 : (i64) -> !llvm.ptr
llvm.store %352, %354 : i64, !llvm.ptr
%355 = arith.constant 1 : i32
%356 = arith.extsi %355 : i32 to i64
%357 = llvm.mlir.constant(1 : i64) : i64
%358 = llvm.alloca %357 x i64 : (i64) -> !llvm.ptr
llvm.store %356, %358 : i64, !llvm.ptr
%359 = arith.constant 1 : i32
%360 = arith.extsi %359 : i32 to i64
%361 = llvm.mlir.constant(1 : i64) : i64
%362 = llvm.alloca %361 x i64 : (i64) -> !llvm.ptr
llvm.store %360, %362 : i64, !llvm.ptr
cf.br ^bb60
^bb60:
%363 = llvm.load %362 : !llvm.ptr -> i64
%364 = arith.cmpi sle, %363, %344 : i64
cf.cond_br %364, ^bb61, ^bb62
^bb61:
%366 = llvm.load %354 : !llvm.ptr -> i64
%367 = llvm.load %362 : !llvm.ptr -> i64
%368 = llvm.mlir.addressof @MOD : !llvm.ptr
%369 = llvm.load %368 : !llvm.ptr -> i64
%370 = arith.remsi %367, %369 : i64
%365 = func.call @mm(%366, %370) : (i64, i64) -> i64
llvm.store %365, %354 : i64, !llvm.ptr
%372 = llvm.load %358 : !llvm.ptr -> i64
%373 = llvm.load %354 : !llvm.ptr -> i64
%371 = func.call @mm(%372, %373) : (i64, i64) -> i64
llvm.store %371, %358 : i64, !llvm.ptr
cf.br ^bb63
^bb63:
%374 = llvm.load %309 : !llvm.ptr -> i64
%375 = arith.cmpi slt, %374, %292 : i64
%376 = scf.if %375 -> (i1) {
%378 = llvm.load %309 : !llvm.ptr -> i64
%379 = llvm.getelementptr %arg0[%378] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%377 = llvm.load %379 : !llvm.ptr -> i64
%380 = llvm.load %362 : !llvm.ptr -> i64
%381 = arith.cmpi eq, %377, %380 : i64
scf.yield %381 : i1
} else {
%382 = arith.constant false
scf.yield %382 : i1
}
cf.cond_br %376, ^bb64, ^bb65
^bb64:
%383 = llvm.load %362 : !llvm.ptr -> i64
%384 = llvm.mlir.addressof @sf_keys : !llvm.ptr
%385 = llvm.load %384 : !llvm.ptr -> !llvm.ptr
%386 = llvm.mlir.addressof @sf_count : !llvm.ptr
%387 = llvm.load %386 : !llvm.ptr -> i64
%388 = llvm.getelementptr %385[%387] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %383, %388 : i64, !llvm.ptr
%389 = llvm.load %358 : !llvm.ptr -> i64
%390 = llvm.mlir.addressof @sf_vals : !llvm.ptr
%391 = llvm.load %390 : !llvm.ptr -> !llvm.ptr
%392 = llvm.mlir.addressof @sf_count : !llvm.ptr
%393 = llvm.load %392 : !llvm.ptr -> i64
%394 = llvm.getelementptr %391[%393] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %389, %394 : i64, !llvm.ptr
%395 = llvm.mlir.addressof @sf_count : !llvm.ptr
%396 = llvm.load %395 : !llvm.ptr -> i64
%397 = arith.constant 1 : i32
%399 = arith.extsi %397 : i32 to i64
%398 = arith.addi %396, %399 : i64
%400 = llvm.mlir.addressof @sf_count : !llvm.ptr
llvm.store %398, %400 : i64, !llvm.ptr
%401 = llvm.load %309 : !llvm.ptr -> i64
%402 = arith.constant 1 : i32
%404 = arith.extsi %402 : i32 to i64
%403 = arith.addi %401, %404 : i64
llvm.store %403, %309 : i64, !llvm.ptr
cf.br ^bb63
^bb65:
%405 = llvm.load %362 : !llvm.ptr -> i64
%406 = arith.constant 1 : i32
%408 = arith.extsi %406 : i32 to i64
%407 = arith.addi %405, %408 : i64
llvm.store %407, %362 : i64, !llvm.ptr
cf.br ^bb60
^bb62:
func.return
}
func.func @main() -> i32 {
%410 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%411 = llvm.load %410 : !llvm.ptr -> i64
%412 = arith.constant 1 : i32
%414 = arith.extsi %412 : i32 to i64
%413 = arith.addi %411, %414 : i64
%415 = arith.constant 1 : i32
%416 = arith.extsi %415 : i32 to i64
%409 = func.call @calloc(%413, %416) : (i64, i64) -> !llvm.ptr
%418 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%419 = llvm.load %418 : !llvm.ptr -> i64
%420 = arith.constant 1 : i32
%422 = arith.extsi %420 : i32 to i64
%421 = arith.addi %419, %422 : i64
%423 = arith.constant 1 : i32
%424 = arith.extsi %423 : i32 to i64
%417 = func.call @calloc(%421, %424) : (i64, i64) -> !llvm.ptr
%426 = arith.constant 6000000 : i32
%427 = arith.constant 4 : i32
%428 = arith.muli %426, %427 : i32
%429 = arith.extsi %428 : i32 to i64
%425 = func.call @malloc(%429) : (i64) -> !llvm.ptr
%430 = arith.constant 0 : i32
%431 = arith.extsi %430 : i32 to i64
%432 = llvm.mlir.constant(1 : i64) : i64
%433 = llvm.alloca %432 x i64 : (i64) -> !llvm.ptr
llvm.store %431, %433 : i64, !llvm.ptr
%434 = arith.constant 65536 : i32
%435 = arith.extsi %434 : i32 to i64
%436 = llvm.mlir.constant(1 : i64) : i64
%437 = llvm.alloca %436 x i64 : (i64) -> !llvm.ptr
llvm.store %435, %437 : i64, !llvm.ptr
%439 = llvm.load %437 : !llvm.ptr -> i64
%440 = arith.constant 8 : i32
%442 = arith.extsi %440 : i32 to i64
%441 = arith.muli %439, %442 : i64
%438 = func.call @malloc(%441) : (i64) -> !llvm.ptr
%443 = llvm.mlir.constant(1 : i64) : i64
%444 = llvm.alloca %443 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %438, %444 : !llvm.ptr, !llvm.ptr
%446 = llvm.load %437 : !llvm.ptr -> i64
%447 = arith.constant 8 : i32
%449 = arith.extsi %447 : i32 to i64
%448 = arith.muli %446, %449 : i64
%445 = func.call @malloc(%448) : (i64) -> !llvm.ptr
%450 = llvm.mlir.constant(1 : i64) : i64
%451 = llvm.alloca %450 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %445, %451 : !llvm.ptr, !llvm.ptr
%453 = llvm.load %437 : !llvm.ptr -> i64
%454 = arith.constant 8 : i32
%456 = arith.extsi %454 : i32 to i64
%455 = arith.muli %453, %456 : i64
%452 = func.call @malloc(%455) : (i64) -> !llvm.ptr
%457 = llvm.mlir.constant(1 : i64) : i64
%458 = llvm.alloca %457 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %452, %458 : !llvm.ptr, !llvm.ptr
%460 = llvm.load %437 : !llvm.ptr -> i64
%461 = arith.constant 8 : i32
%463 = arith.extsi %461 : i32 to i64
%462 = arith.muli %460, %463 : i64
%459 = func.call @malloc(%462) : (i64) -> !llvm.ptr
%464 = llvm.mlir.constant(1 : i64) : i64
%465 = llvm.alloca %464 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %459, %465 : !llvm.ptr, !llvm.ptr
%466 = arith.constant 0 : i32
%467 = arith.extsi %466 : i32 to i64
%468 = llvm.mlir.constant(1 : i64) : i64
%469 = llvm.alloca %468 x i64 : (i64) -> !llvm.ptr
llvm.store %467, %469 : i64, !llvm.ptr
%470 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%471 = llvm.load %470 : !llvm.ptr -> i64
%472 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
%473 = arith.constant 0 : i32
%474 = arith.extsi %473 : i32 to i64
%475 = llvm.getelementptr %472[%474] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %471, %475 : i64, !llvm.ptr
%476 = arith.constant 1 : i32
%477 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
%478 = arith.constant 0 : i32
%479 = arith.extsi %476 : i32 to i64
%480 = arith.extsi %478 : i32 to i64
%481 = llvm.getelementptr %477[%480] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %479, %481 : i64, !llvm.ptr
%482 = arith.constant 1 : i32
%483 = llvm.load %458 : !llvm.ptr -> !llvm.ptr
%484 = arith.constant 0 : i32
%485 = arith.extsi %482 : i32 to i64
%486 = arith.extsi %484 : i32 to i64
%487 = llvm.getelementptr %483[%486] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %485, %487 : i64, !llvm.ptr
%488 = arith.constant 1 : i32
%489 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
%490 = arith.constant 0 : i32
%491 = arith.extsi %488 : i32 to i64
%492 = arith.extsi %490 : i32 to i64
%493 = llvm.getelementptr %489[%492] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %491, %493 : i64, !llvm.ptr
%494 = arith.constant 1 : i32
%495 = arith.extsi %494 : i32 to i64
llvm.store %495, %469 : i64, !llvm.ptr
%496 = arith.constant 1 : i32
%497 = arith.constant 1 : i32
%498 = arith.trunci %496 : i32 to i8
%499 = arith.extsi %497 : i32 to i64
%500 = llvm.getelementptr %409[%499] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %498, %500 : i8, !llvm.ptr
%501 = arith.constant 2 : i32
%502 = arith.extsi %501 : i32 to i64
%503 = llvm.mlir.constant(1 : i64) : i64
%504 = llvm.alloca %503 x i64 : (i64) -> !llvm.ptr
llvm.store %502, %504 : i64, !llvm.ptr
%505 = llvm.load %504 : !llvm.ptr -> i64
%506 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%507 = llvm.load %506 : !llvm.ptr -> i64
%508 = arith.cmpi sle, %505, %507 : i64
cf.cond_br %508, ^bb66, ^bb67
^bb66:
%509 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%510 = llvm.load %509 : !llvm.ptr -> i64
%511 = llvm.load %504 : !llvm.ptr -> i64
%512 = arith.divsi %510, %511 : i64
%513 = llvm.mlir.constant(1 : i64) : i64
%514 = llvm.alloca %513 x i64 : (i64) -> !llvm.ptr
llvm.store %512, %514 : i64, !llvm.ptr
%515 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%516 = llvm.load %515 : !llvm.ptr -> i64
%517 = llvm.load %514 : !llvm.ptr -> i64
%518 = arith.divsi %516, %517 : i64
%519 = llvm.mlir.constant(1 : i64) : i64
%520 = llvm.alloca %519 x i64 : (i64) -> !llvm.ptr
llvm.store %518, %520 : i64, !llvm.ptr
%521 = arith.constant 1 : i32
%522 = arith.extsi %521 : i32 to i64
%523 = llvm.mlir.constant(1 : i64) : i64
%524 = llvm.alloca %523 x i64 : (i64) -> !llvm.ptr
llvm.store %522, %524 : i64, !llvm.ptr
%525 = arith.constant 1 : i32
%526 = arith.extsi %525 : i32 to i64
%527 = llvm.mlir.constant(1 : i64) : i64
%528 = llvm.alloca %527 x i64 : (i64) -> !llvm.ptr
llvm.store %526, %528 : i64, !llvm.ptr
%529 = arith.constant 0 : i32
%530 = arith.extsi %529 : i32 to i64
%531 = llvm.mlir.constant(1 : i64) : i64
%532 = llvm.alloca %531 x i64 : (i64) -> !llvm.ptr
llvm.store %530, %532 : i64, !llvm.ptr
%533 = arith.constant 2 : i32
%534 = arith.extsi %533 : i32 to i64
%535 = llvm.mlir.constant(1 : i64) : i64
%536 = llvm.alloca %535 x i64 : (i64) -> !llvm.ptr
llvm.store %534, %536 : i64, !llvm.ptr
%537 = arith.constant 0 : i1
%538 = llvm.mlir.constant(1 : i64) : i64
%539 = llvm.alloca %538 x i1 : (i64) -> !llvm.ptr
llvm.store %537, %539 : i1, !llvm.ptr
cf.br ^bb69
^bb69:
%540 = llvm.load %536 : !llvm.ptr -> i64
%541 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%542 = llvm.load %541 : !llvm.ptr -> i64
%543 = arith.cmpi sle, %540, %542 : i64
%544 = scf.if %543 -> (i1) {
%545 = llvm.load %539 : !llvm.ptr -> i1
%547 = arith.constant 1 : i1
%546 = arith.xori %545, %547 : i1
scf.yield %546 : i1
} else {
%549 = arith.constant false
scf.yield %549 : i1
}
cf.cond_br %544, ^bb70, ^bb71
^bb70:
%551 = llvm.load %536 : !llvm.ptr -> i64
%552 = llvm.getelementptr %417[%551] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%550 = llvm.load %552 : !llvm.ptr -> i8
%553 = arith.constant 0 : i32
%555 = arith.extsi %550 : i8 to i32
%554 = arith.cmpi eq, %555, %553 : i32
%556 = scf.if %554 -> (i32) {
%557 = arith.constant 2 : i32
scf.yield %557 : i32
} else {
%559 = llvm.load %536 : !llvm.ptr -> i64
%560 = llvm.getelementptr %409[%559] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%558 = llvm.load %560 : !llvm.ptr -> i8
scf.yield %558 : i8
}
%561 = arith.trunci %556 : i32 to i8
%563 = llvm.load %536 : !llvm.ptr -> i64
%564 = llvm.getelementptr %417[%563] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%562 = llvm.load %564 : !llvm.ptr -> i8
%565 = arith.constant 0 : i32
%567 = arith.extsi %562 : i8 to i32
%566 = arith.cmpi eq, %567, %565 : i32
cf.cond_br %566, ^bb72, ^bb73
^bb72:
%568 = llvm.load %536 : !llvm.ptr -> i64
%569 = arith.trunci %568 : i64 to i32
%570 = llvm.load %433 : !llvm.ptr -> i64
%571 = llvm.getelementptr %425[%570] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %569, %571 : i32, !llvm.ptr
%572 = llvm.load %433 : !llvm.ptr -> i64
%573 = arith.constant 1 : i32
%575 = arith.extsi %573 : i32 to i64
%574 = arith.addi %572, %575 : i64
llvm.store %574, %433 : i64, !llvm.ptr
%576 = arith.constant 2 : i32
%577 = llvm.load %536 : !llvm.ptr -> i64
%578 = arith.trunci %576 : i32 to i8
%579 = llvm.getelementptr %409[%577] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %578, %579 : i8, !llvm.ptr
cf.br ^bb74
^bb73:
cf.br ^bb74
^bb74:
%580 = arith.constant 1 : i32
%582 = arith.extsi %561 : i8 to i32
%581 = arith.cmpi eq, %582, %580 : i32
cf.cond_br %581, ^bb75, ^bb76
^bb75:
%584 = llvm.load %524 : !llvm.ptr -> i64
%585 = llvm.load %536 : !llvm.ptr -> i64
%586 = llvm.mlir.addressof @MOD : !llvm.ptr
%587 = llvm.load %586 : !llvm.ptr -> i64
%588 = arith.remsi %585, %587 : i64
%583 = func.call @mm(%584, %588) : (i64, i64) -> i64
llvm.store %583, %524 : i64, !llvm.ptr
%589 = llvm.load %532 : !llvm.ptr -> i64
%590 = arith.constant 1 : i32
%592 = arith.extsi %590 : i32 to i64
%591 = arith.addi %589, %592 : i64
llvm.store %591, %532 : i64, !llvm.ptr
cf.br ^bb77
^bb76:
%593 = arith.constant 2 : i32
%595 = arith.extsi %561 : i8 to i32
%594 = arith.cmpi eq, %595, %593 : i32
cf.cond_br %594, ^bb78, ^bb79
^bb78:
%597 = llvm.load %528 : !llvm.ptr -> i64
%598 = llvm.load %536 : !llvm.ptr -> i64
%599 = llvm.mlir.addressof @MOD : !llvm.ptr
%600 = llvm.load %599 : !llvm.ptr -> i64
%601 = arith.remsi %598, %600 : i64
%596 = func.call @mm(%597, %601) : (i64, i64) -> i64
llvm.store %596, %528 : i64, !llvm.ptr
%602 = llvm.load %532 : !llvm.ptr -> i64
%603 = arith.constant 1 : i32
%605 = arith.extsi %603 : i32 to i64
%604 = arith.subi %602, %605 : i64
llvm.store %604, %532 : i64, !llvm.ptr
cf.br ^bb80
^bb79:
cf.br ^bb80
^bb80:
cf.br ^bb77
^bb77:
%606 = arith.constant 0 : i32
%607 = arith.extsi %606 : i32 to i64
%608 = llvm.mlir.constant(1 : i64) : i64
%609 = llvm.alloca %608 x i64 : (i64) -> !llvm.ptr
llvm.store %607, %609 : i64, !llvm.ptr
cf.br ^bb81
^bb81:
%610 = llvm.load %609 : !llvm.ptr -> i64
%611 = llvm.load %433 : !llvm.ptr -> i64
%612 = arith.cmpi slt, %610, %611 : i64
cf.cond_br %612, ^bb82, ^bb83
^bb82:
%614 = llvm.load %609 : !llvm.ptr -> i64
%615 = llvm.getelementptr %425[%614] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%613 = llvm.load %615 : !llvm.ptr -> i32
%616 = llvm.load %536 : !llvm.ptr -> i64
%617 = arith.extsi %613 : i32 to i64
%618 = arith.muli %616, %617 : i64
%619 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%620 = llvm.load %619 : !llvm.ptr -> i64
%621 = arith.cmpi sgt, %618, %620 : i64
cf.cond_br %621, ^bb84, ^bb85
^bb84:
cf.br ^bb83
^bb85:
cf.br ^bb86
^bb86:
%622 = arith.constant 1 : i32
%623 = arith.trunci %622 : i32 to i8
%624 = llvm.getelementptr %417[%618] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %623, %624 : i8, !llvm.ptr
%625 = llvm.load %536 : !llvm.ptr -> i64
%626 = arith.extsi %613 : i32 to i64
%627 = arith.remsi %625, %626 : i64
%628 = arith.constant 0 : i32
%630 = arith.extsi %628 : i32 to i64
%629 = arith.cmpi eq, %627, %630 : i64
cf.cond_br %629, ^bb87, ^bb88
^bb87:
cf.br ^bb83
^bb88:
cf.br ^bb89
^bb89:
%631 = arith.constant 1 : i32
%633 = arith.extsi %561 : i8 to i32
%632 = arith.cmpi eq, %633, %631 : i32
cf.cond_br %632, ^bb90, ^bb91
^bb90:
%634 = arith.constant 2 : i32
%635 = arith.trunci %634 : i32 to i8
%636 = llvm.getelementptr %409[%618] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %635, %636 : i8, !llvm.ptr
cf.br ^bb92
^bb91:
%637 = arith.constant 2 : i32
%639 = arith.extsi %561 : i8 to i32
%638 = arith.cmpi eq, %639, %637 : i32
cf.cond_br %638, ^bb93, ^bb94
^bb93:
%640 = arith.constant 1 : i32
%641 = arith.trunci %640 : i32 to i8
%642 = llvm.getelementptr %409[%618] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %641, %642 : i8, !llvm.ptr
cf.br ^bb95
^bb94:
cf.br ^bb95
^bb95:
cf.br ^bb92
^bb92:
%643 = llvm.load %609 : !llvm.ptr -> i64
%644 = arith.constant 1 : i32
%646 = arith.extsi %644 : i32 to i64
%645 = arith.addi %643, %646 : i64
llvm.store %645, %609 : i64, !llvm.ptr
cf.br ^bb81
^bb83:
%647 = llvm.load %536 : !llvm.ptr -> i64
%648 = llvm.load %520 : !llvm.ptr -> i64
%649 = arith.cmpi eq, %647, %648 : i64
cf.cond_br %649, ^bb96, ^bb97
^bb96:
%650 = llvm.load %469 : !llvm.ptr -> i64
%651 = llvm.load %437 : !llvm.ptr -> i64
%652 = arith.cmpi sge, %650, %651 : i64
cf.cond_br %652, ^bb99, ^bb100
^bb99:
%653 = llvm.load %437 : !llvm.ptr -> i64
%654 = arith.constant 2 : i32
%656 = arith.extsi %654 : i32 to i64
%655 = arith.muli %653, %656 : i64
%658 = arith.constant 8 : i32
%660 = arith.extsi %658 : i32 to i64
%659 = arith.muli %655, %660 : i64
%657 = func.call @malloc(%659) : (i64) -> !llvm.ptr
%662 = arith.constant 8 : i32
%664 = arith.extsi %662 : i32 to i64
%663 = arith.muli %655, %664 : i64
%661 = func.call @malloc(%663) : (i64) -> !llvm.ptr
%666 = arith.constant 8 : i32
%668 = arith.extsi %666 : i32 to i64
%667 = arith.muli %655, %668 : i64
%665 = func.call @malloc(%667) : (i64) -> !llvm.ptr
%670 = arith.constant 8 : i32
%672 = arith.extsi %670 : i32 to i64
%671 = arith.muli %655, %672 : i64
%669 = func.call @malloc(%671) : (i64) -> !llvm.ptr
%673 = arith.constant 0 : i32
%674 = arith.extsi %673 : i32 to i64
%675 = llvm.mlir.constant(1 : i64) : i64
%676 = llvm.alloca %675 x i64 : (i64) -> !llvm.ptr
llvm.store %674, %676 : i64, !llvm.ptr
cf.br ^bb102
^bb102:
%677 = llvm.load %676 : !llvm.ptr -> i64
%678 = llvm.load %469 : !llvm.ptr -> i64
%679 = arith.cmpi slt, %677, %678 : i64
cf.cond_br %679, ^bb103, ^bb104
^bb103:
%681 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
%682 = llvm.load %676 : !llvm.ptr -> i64
%683 = llvm.getelementptr %681[%682] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%680 = llvm.load %683 : !llvm.ptr -> i64
%684 = llvm.load %676 : !llvm.ptr -> i64
%685 = llvm.getelementptr %657[%684] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %680, %685 : i64, !llvm.ptr
%687 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
%688 = llvm.load %676 : !llvm.ptr -> i64
%689 = llvm.getelementptr %687[%688] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%686 = llvm.load %689 : !llvm.ptr -> i64
%690 = llvm.load %676 : !llvm.ptr -> i64
%691 = llvm.getelementptr %661[%690] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %686, %691 : i64, !llvm.ptr
%693 = llvm.load %458 : !llvm.ptr -> !llvm.ptr
%694 = llvm.load %676 : !llvm.ptr -> i64
%695 = llvm.getelementptr %693[%694] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%692 = llvm.load %695 : !llvm.ptr -> i64
%696 = llvm.load %676 : !llvm.ptr -> i64
%697 = llvm.getelementptr %665[%696] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %692, %697 : i64, !llvm.ptr
%699 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
%700 = llvm.load %676 : !llvm.ptr -> i64
%701 = llvm.getelementptr %699[%700] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%698 = llvm.load %701 : !llvm.ptr -> i64
%702 = llvm.load %676 : !llvm.ptr -> i64
%703 = llvm.getelementptr %669[%702] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %698, %703 : i64, !llvm.ptr
%704 = llvm.load %676 : !llvm.ptr -> i64
%705 = arith.constant 1 : i32
%707 = arith.extsi %705 : i32 to i64
%706 = arith.addi %704, %707 : i64
llvm.store %706, %676 : i64, !llvm.ptr
cf.br ^bb102
^bb104:
%709 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
func.call @free(%709) : (!llvm.ptr) -> ()
%711 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
func.call @free(%711) : (!llvm.ptr) -> ()
%713 = llvm.load %458 : !llvm.ptr -> !llvm.ptr
func.call @free(%713) : (!llvm.ptr) -> ()
%715 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
func.call @free(%715) : (!llvm.ptr) -> ()
llvm.store %657, %444 : !llvm.ptr, !llvm.ptr
llvm.store %661, %451 : !llvm.ptr, !llvm.ptr
llvm.store %665, %458 : !llvm.ptr, !llvm.ptr
llvm.store %669, %465 : !llvm.ptr, !llvm.ptr
llvm.store %655, %437 : i64, !llvm.ptr
cf.br ^bb101
^bb100:
cf.br ^bb101
^bb101:
%716 = llvm.load %514 : !llvm.ptr -> i64
%717 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
%718 = llvm.load %469 : !llvm.ptr -> i64
%719 = llvm.getelementptr %717[%718] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %716, %719 : i64, !llvm.ptr
%720 = llvm.load %524 : !llvm.ptr -> i64
%721 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
%722 = llvm.load %469 : !llvm.ptr -> i64
%723 = llvm.getelementptr %721[%722] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %720, %723 : i64, !llvm.ptr
%724 = llvm.load %528 : !llvm.ptr -> i64
%725 = llvm.load %458 : !llvm.ptr -> !llvm.ptr
%726 = llvm.load %469 : !llvm.ptr -> i64
%727 = llvm.getelementptr %725[%726] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %724, %727 : i64, !llvm.ptr
%728 = llvm.load %532 : !llvm.ptr -> i64
%729 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
%730 = llvm.load %469 : !llvm.ptr -> i64
%731 = llvm.getelementptr %729[%730] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %728, %731 : i64, !llvm.ptr
%732 = llvm.load %469 : !llvm.ptr -> i64
%733 = arith.constant 1 : i32
%735 = arith.extsi %733 : i32 to i64
%734 = arith.addi %732, %735 : i64
llvm.store %734, %469 : i64, !llvm.ptr
%736 = llvm.load %520 : !llvm.ptr -> i64
%737 = arith.constant 1 : i32
%739 = arith.extsi %737 : i32 to i64
%738 = arith.addi %736, %739 : i64
llvm.store %738, %504 : i64, !llvm.ptr
%740 = llvm.load %504 : !llvm.ptr -> i64
%741 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%742 = llvm.load %741 : !llvm.ptr -> i64
%743 = arith.cmpi sgt, %740, %742 : i64
cf.cond_br %743, ^bb105, ^bb106
^bb105:
%744 = arith.constant 1 : i1
llvm.store %744, %539 : i1, !llvm.ptr
cf.br ^bb107
^bb106:
%745 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%746 = llvm.load %745 : !llvm.ptr -> i64
%747 = llvm.load %504 : !llvm.ptr -> i64
%748 = arith.divsi %746, %747 : i64
llvm.store %748, %514 : i64, !llvm.ptr
%749 = llvm.mlir.addressof @LIMIT : !llvm.ptr
%750 = llvm.load %749 : !llvm.ptr -> i64
%751 = llvm.load %514 : !llvm.ptr -> i64
%752 = arith.divsi %750, %751 : i64
llvm.store %752, %520 : i64, !llvm.ptr
%753 = arith.constant 1 : i32
%754 = arith.extsi %753 : i32 to i64
llvm.store %754, %524 : i64, !llvm.ptr
%755 = arith.constant 1 : i32
%756 = arith.extsi %755 : i32 to i64
llvm.store %756, %528 : i64, !llvm.ptr
%757 = arith.constant 0 : i32
%758 = arith.extsi %757 : i32 to i64
llvm.store %758, %532 : i64, !llvm.ptr
cf.br ^bb107
^bb107:
cf.br ^bb98
^bb97:
cf.br ^bb98
^bb98:
%759 = llvm.load %536 : !llvm.ptr -> i64
%760 = arith.constant 1 : i32
%762 = arith.extsi %760 : i32 to i64
%761 = arith.addi %759, %762 : i64
llvm.store %761, %536 : i64, !llvm.ptr
cf.br ^bb69
^bb71:
cf.br ^bb68
^bb67:
cf.br ^bb68
^bb68:
func.call @free(%409) : (!llvm.ptr) -> ()
func.call @free(%417) : (!llvm.ptr) -> ()
func.call @free(%425) : (!llvm.ptr) -> ()
%767 = llvm.load %469 : !llvm.ptr -> i64
%768 = arith.constant 8 : i32
%770 = arith.extsi %768 : i32 to i64
%769 = arith.muli %767, %770 : i64
%766 = func.call @malloc(%769) : (i64) -> !llvm.ptr
%771 = arith.constant 0 : i32
%772 = arith.extsi %771 : i32 to i64
%773 = llvm.mlir.constant(1 : i64) : i64
%774 = llvm.alloca %773 x i64 : (i64) -> !llvm.ptr
llvm.store %772, %774 : i64, !llvm.ptr
cf.br ^bb108
^bb108:
%775 = llvm.load %774 : !llvm.ptr -> i64
%776 = llvm.load %469 : !llvm.ptr -> i64
%777 = arith.cmpi slt, %775, %776 : i64
cf.cond_br %777, ^bb109, ^bb110
^bb109:
%779 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
%780 = llvm.load %774 : !llvm.ptr -> i64
%781 = llvm.getelementptr %779[%780] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%778 = llvm.load %781 : !llvm.ptr -> i64
%782 = arith.constant 1 : i32
%784 = arith.extsi %782 : i32 to i64
%783 = arith.subi %778, %784 : i64
%785 = llvm.load %774 : !llvm.ptr -> i64
%786 = llvm.getelementptr %766[%785] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %783, %786 : i64, !llvm.ptr
%787 = llvm.load %774 : !llvm.ptr -> i64
%788 = arith.constant 1 : i32
%790 = arith.extsi %788 : i32 to i64
%789 = arith.addi %787, %790 : i64
llvm.store %789, %774 : i64, !llvm.ptr
cf.br ^bb108
^bb110:
%792 = llvm.load %469 : !llvm.ptr -> i64
func.call @compute_superfactorials(%766, %792) : (!llvm.ptr, i64) -> ()
func.call @free(%766) : (!llvm.ptr) -> ()
%794 = arith.constant 1 : i32
%795 = arith.extsi %794 : i32 to i64
%796 = llvm.mlir.constant(1 : i64) : i64
%797 = llvm.alloca %796 x i64 : (i64) -> !llvm.ptr
llvm.store %795, %797 : i64, !llvm.ptr
%798 = arith.constant 0 : i32
%799 = arith.extsi %798 : i32 to i64
llvm.store %799, %774 : i64, !llvm.ptr
cf.br ^bb111
^bb111:
%800 = llvm.load %774 : !llvm.ptr -> i64
%801 = llvm.load %469 : !llvm.ptr -> i64
%802 = arith.cmpi slt, %800, %801 : i64
cf.cond_br %802, ^bb112, ^bb113
^bb112:
%804 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
%805 = llvm.load %774 : !llvm.ptr -> i64
%806 = llvm.getelementptr %804[%805] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%803 = llvm.load %806 : !llvm.ptr -> i64
%807 = arith.constant 1 : i32
%809 = arith.extsi %807 : i32 to i64
%808 = arith.subi %803, %809 : i64
%810 = arith.muli %803, %808 : i64
%811 = arith.constant 2 : i32
%813 = arith.extsi %811 : i32 to i64
%812 = arith.divsi %810, %813 : i64
%814 = llvm.mlir.addressof @EXP_MOD : !llvm.ptr
%815 = llvm.load %814 : !llvm.ptr -> i64
%816 = arith.remsi %812, %815 : i64
%817 = arith.constant 0 : i32
%819 = arith.extsi %817 : i32 to i64
%818 = arith.cmpi ne, %816, %819 : i64
cf.cond_br %818, ^bb114, ^bb115
^bb114:
%821 = llvm.load %797 : !llvm.ptr -> i64
%824 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
%825 = llvm.load %774 : !llvm.ptr -> i64
%826 = llvm.getelementptr %824[%825] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%823 = llvm.load %826 : !llvm.ptr -> i64
%822 = func.call @mpow(%823, %816) : (i64, i64) -> i64
%820 = func.call @mm(%821, %822) : (i64, i64) -> i64
llvm.store %820, %797 : i64, !llvm.ptr
%827 = llvm.mlir.addressof @EXP_MOD : !llvm.ptr
%828 = llvm.load %827 : !llvm.ptr -> i64
%829 = arith.subi %828, %816 : i64
%830 = llvm.mlir.addressof @EXP_MOD : !llvm.ptr
%831 = llvm.load %830 : !llvm.ptr -> i64
%832 = arith.remsi %829, %831 : i64
%833 = arith.constant 0 : i32
%835 = arith.extsi %833 : i32 to i64
%834 = arith.cmpi ne, %832, %835 : i64
cf.cond_br %834, ^bb117, ^bb118
^bb117:
%837 = llvm.load %797 : !llvm.ptr -> i64
%840 = llvm.load %458 : !llvm.ptr -> !llvm.ptr
%841 = llvm.load %774 : !llvm.ptr -> i64
%842 = llvm.getelementptr %840[%841] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%839 = llvm.load %842 : !llvm.ptr -> i64
%838 = func.call @mpow(%839, %832) : (i64, i64) -> i64
%836 = func.call @mm(%837, %838) : (i64, i64) -> i64
llvm.store %836, %797 : i64, !llvm.ptr
cf.br ^bb119
^bb118:
cf.br ^bb119
^bb119:
cf.br ^bb116
^bb115:
cf.br ^bb116
^bb116:
%844 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
%845 = llvm.load %774 : !llvm.ptr -> i64
%846 = llvm.getelementptr %844[%845] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%843 = llvm.load %846 : !llvm.ptr -> i64
%847 = llvm.mlir.addressof @EXP_MOD : !llvm.ptr
%848 = llvm.load %847 : !llvm.ptr -> i64
%849 = arith.remsi %843, %848 : i64
%850 = llvm.mlir.addressof @EXP_MOD : !llvm.ptr
%851 = llvm.load %850 : !llvm.ptr -> i64
%852 = arith.addi %849, %851 : i64
%853 = llvm.mlir.addressof @EXP_MOD : !llvm.ptr
%854 = llvm.load %853 : !llvm.ptr -> i64
%855 = arith.remsi %852, %854 : i64
%856 = arith.constant 0 : i32
%858 = arith.extsi %856 : i32 to i64
%857 = arith.cmpi ne, %855, %858 : i64
cf.cond_br %857, ^bb120, ^bb121
^bb120:
%861 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
%862 = llvm.load %774 : !llvm.ptr -> i64
%863 = llvm.getelementptr %861[%862] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%860 = llvm.load %863 : !llvm.ptr -> i64
%864 = arith.constant 1 : i32
%866 = arith.extsi %864 : i32 to i64
%865 = arith.subi %860, %866 : i64
%859 = func.call @sf_lookup(%865) : (i64) -> i64
%868 = llvm.load %797 : !llvm.ptr -> i64
%869 = func.call @mpow(%859, %855) : (i64, i64) -> i64
%867 = func.call @mm(%868, %869) : (i64, i64) -> i64
llvm.store %867, %797 : i64, !llvm.ptr
cf.br ^bb122
^bb121:
cf.br ^bb122
^bb122:
%870 = llvm.load %774 : !llvm.ptr -> i64
%871 = arith.constant 1 : i32
%873 = arith.extsi %871 : i32 to i64
%872 = arith.addi %870, %873 : i64
llvm.store %872, %774 : i64, !llvm.ptr
cf.br ^bb111
^bb113:
%875 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
func.call @free(%875) : (!llvm.ptr) -> ()
%877 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
func.call @free(%877) : (!llvm.ptr) -> ()
%879 = llvm.load %458 : !llvm.ptr -> !llvm.ptr
func.call @free(%879) : (!llvm.ptr) -> ()
%881 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
func.call @free(%881) : (!llvm.ptr) -> ()
%883 = llvm.mlir.addressof @sf_keys : !llvm.ptr
%884 = llvm.load %883 : !llvm.ptr -> !llvm.ptr
func.call @free(%884) : (!llvm.ptr) -> ()
%886 = llvm.mlir.addressof @sf_vals : !llvm.ptr
%887 = llvm.load %886 : !llvm.ptr -> !llvm.ptr
func.call @free(%887) : (!llvm.ptr) -> ()
%888 = llvm.mlir.addressof @str_0 : !llvm.ptr
%889 = llvm.load %797 : !llvm.ptr -> i64
%890 = llvm.call @printf(%888, %889) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
%891 = arith.constant 0 : i32
func.return %891 : i32
}
}