← All problems
Problem 917
N x N matrix M[i,j] = a_i + b_j, path sum from (1,1) to (N,N) with Right/Down. A(N) = sum(a_i) + sum(b_j) + D(N), where D(N) is shortest path in grid graph. Only lower convex hull vertices matter. We compute hulls of (i, a_i) and (i, b_i), then DP on compressed grid.
View problem on Project Euler
Performance comparison
Metric Our solution Best known
Time complexity O(n^2)O(n^2)
Space complexity O(1)O(n^2)
Approach Flow solution Bottom-up DP
Verdict Optimal
Flow source
# Project Euler 917
# N x N matrix M[i,j] = a_i + b_j, path sum from (1,1) to (N,N) with Right/Down.
# A(N) = sum(a_i) + sum(b_j) + D(N), where D(N) is shortest path in grid graph.
# Only lower convex hull vertices matter. We compute hulls of (i, a_i) and (i, b_i),
# then DP on compressed grid.
extern {
function calloc(n: i64, size: i64) -> ptr<void>
function malloc(n: i64) -> ptr<void>
function free(p: ptr<void>) -> void
function memcpy(dst: ptr<void>, src: ptr<void>, n: i64) -> ptr<void>
}
const MOD: i64 = 998388889
const S1: i64 = 102022661
const N: i64 = 10000000
function cross(x1: i128, y1: i128, x2: i128, y2: i128, x3: i128, y3: i128) -> i128 {
return (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2)
}
function main() -> i32 {
let mut s: i64 = S1
let mut sum_a: i128 = 0 as i128
let mut sum_b: i128 = 0 as i128
let mut ax: ptr<i64> = malloc(8192)
let mut ay: ptr<i64> = malloc(8192)
let mut bx: ptr<i64> = malloc(8192)
let mut by: ptr<i64> = malloc(8192)
let mut asz: i32 = 0
let mut bsz: i32 = 0
let mut acap: i32 = 1024
let mut bcap: i32 = 1024
let mut i: i64 = 1
while i <= N {
let a: i64 = s
s = (s * s) % MOD
let b: i64 = s
s = (s * s) % MOD
sum_a = sum_a + (a as i128)
sum_b = sum_b + (b as i128)
# Update lower hull for (i, a)
while asz >= 2 {
let cr: i128 = cross(
(ax[(asz - 2) as i64] as i128), (ay[(asz - 2) as i64] as i128),
(ax[(asz - 1) as i64] as i128), (ay[(asz - 1) as i64] as i128),
(i as i128), (a as i128))
if cr <= (0 as i128) {
asz = asz - 1
} else {
break
}
}
if asz >= acap {
let new_acap: i32 = acap * 2
let new_ax: ptr<i64> = malloc((new_acap as i64) * 8)
let new_ay: ptr<i64> = malloc((new_acap as i64) * 8)
memcpy(new_ax, ax, (acap as i64) * 8)
memcpy(new_ay, ay, (acap as i64) * 8)
free(ax)
free(ay)
ax = new_ax
ay = new_ay
acap = new_acap
}
ax[asz as i64] = i
ay[asz as i64] = a
asz = asz + 1
# Update lower hull for (i, b)
while bsz >= 2 {
let cr: i128 = cross(
(bx[(bsz - 2) as i64] as i128), (by[(bsz - 2) as i64] as i128),
(bx[(bsz - 1) as i64] as i128), (by[(bsz - 1) as i64] as i128),
(i as i128), (b as i128))
if cr <= (0 as i128) {
bsz = bsz - 1
} else {
break
}
}
if bsz >= bcap {
let new_bcap: i32 = bcap * 2
let new_bx: ptr<i64> = malloc((new_bcap as i64) * 8)
let new_by: ptr<i64> = malloc((new_bcap as i64) * 8)
memcpy(new_bx, bx, (bcap as i64) * 8)
memcpy(new_by, by, (bcap as i64) * 8)
free(bx)
free(by)
bx = new_bx
by = new_by
bcap = new_bcap
}
bx[bsz as i64] = i
by[bsz as i64] = b
bsz = bsz + 1
i = i + 1
}
# DP on compressed grid
let R: i32 = asz
let C: i32 = bsz
let mut dp: ptr<i128> = malloc((C as i64) * 16)
let mut ndp: ptr<i128> = malloc((C as i64) * 16)
dp[0] = 0 as i128
let a0: i64 = ay[0]
let mut j: i32 = 1
while j < C {
dp[j as i64] = dp[(j - 1) as i64] + (a0 as i128) * ((bx[j as i64] - bx[(j - 1) as i64]) as i128)
j = j + 1
}
let mut i2: i32 = 1
while i2 < R {
let dr: i128 = ((ax[i2 as i64] - ax[(i2 - 1) as i64]) as i128)
ndp[0] = dp[0] + (by[0] as i128) * dr
let ai: i64 = ay[i2 as i64]
let mut j2: i32 = 1
while j2 < C {
let down: i128 = dp[j2 as i64] + (by[j2 as i64] as i128) * dr
let dc: i128 = ((bx[j2 as i64] - bx[(j2 - 1) as i64]) as i128)
let right: i128 = ndp[(j2 - 1) as i64] + (ai as i128) * dc
if down < right {
ndp[j2 as i64] = down
} else {
ndp[j2 as i64] = right
}
j2 = j2 + 1
}
# swap dp and ndp
let tmp: ptr<i128> = dp
dp = ndp
ndp = tmp
i2 = i2 + 1
}
let D: i128 = dp[(C - 1) as i64]
let result: i128 = sum_a + sum_b + D
free(dp)
free(ndp)
free(ax)
free(ay)
free(bx)
free(by)
printf("%lld\n", result as i64)
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; }
__int128 cross_i128_i128_i128_i128_i128_i128(__int128 x1, __int128 y1, __int128 x2, __int128 y2, __int128 x3, __int128 y3);
int32_t main(void);
static const int64_t MOD = 998388889;
static const int64_t S1 = 102022661;
static const int64_t N = 10000000;
__int128 cross_i128_i128_i128_i128_i128_i128(__int128 x1, __int128 y1, __int128 x2, __int128 y2, __int128 x3, __int128 y3) {
return (((x2 - x1) * (y3 - y2)) - ((y2 - y1) * (x3 - x2)));
}
int32_t main(void) {
int64_t s = S1;
__int128 sum_a = ((__int128)(0));
__int128 sum_b = ((__int128)(0));
int64_t* ax = (int64_t*)(malloc(8192));
int64_t* ay = (int64_t*)(malloc(8192));
int64_t* bx = (int64_t*)(malloc(8192));
int64_t* by = (int64_t*)(malloc(8192));
int32_t asz = 0;
int32_t bsz = 0;
int32_t acap = 1024;
int32_t bcap = 1024;
int64_t i = 1;
while (i <= N) {
int64_t a = s;
s = FLOW_CHECKED_MOD(((s * s)), (MOD));
int64_t b = s;
s = FLOW_CHECKED_MOD(((s * s)), (MOD));
sum_a = (sum_a + ((__int128)(a)));
sum_b = (sum_b + ((__int128)(b)));
while (asz >= 2) {
__int128 cr = cross_i128_i128_i128_i128_i128_i128(((__int128)(ax[((int64_t)((asz - 2)))])), ((__int128)(ay[((int64_t)((asz - 2)))])), ((__int128)(ax[((int64_t)((asz - 1)))])), ((__int128)(ay[((int64_t)((asz - 1)))])), ((__int128)(i)), ((__int128)(a)));
if (cr <= ((__int128)(0))) {
asz = (asz - 1);
} else {
break;
}
}
if (asz >= acap) {
int32_t new_acap = (acap * 2);
int64_t* new_ax = (int64_t*)(malloc((((int64_t)(new_acap)) * 8)));
int64_t* new_ay = (int64_t*)(malloc((((int64_t)(new_acap)) * 8)));
memcpy(new_ax, ax, (((int64_t)(acap)) * 8));
memcpy(new_ay, ay, (((int64_t)(acap)) * 8));
free(ax);
free(ay);
ax = new_ax;
ay = new_ay;
acap = new_acap;
}
ax[((int64_t)(asz))] = i;
ay[((int64_t)(asz))] = a;
asz = (asz + 1);
while (bsz >= 2) {
__int128 cr = cross_i128_i128_i128_i128_i128_i128(((__int128)(bx[((int64_t)((bsz - 2)))])), ((__int128)(by[((int64_t)((bsz - 2)))])), ((__int128)(bx[((int64_t)((bsz - 1)))])), ((__int128)(by[((int64_t)((bsz - 1)))])), ((__int128)(i)), ((__int128)(b)));
if (cr <= ((__int128)(0))) {
bsz = (bsz - 1);
} else {
break;
}
}
if (bsz >= bcap) {
int32_t new_bcap = (bcap * 2);
int64_t* new_bx = (int64_t*)(malloc((((int64_t)(new_bcap)) * 8)));
int64_t* new_by = (int64_t*)(malloc((((int64_t)(new_bcap)) * 8)));
memcpy(new_bx, bx, (((int64_t)(bcap)) * 8));
memcpy(new_by, by, (((int64_t)(bcap)) * 8));
free(bx);
free(by);
bx = new_bx;
by = new_by;
bcap = new_bcap;
}
bx[((int64_t)(bsz))] = i;
by[((int64_t)(bsz))] = b;
bsz = (bsz + 1);
i = (i + 1);
}
int32_t R = asz;
int32_t C = bsz;
__int128* dp = (__int128*)(malloc((((int64_t)(C)) * 16)));
__int128* ndp = (__int128*)(malloc((((int64_t)(C)) * 16)));
dp[0] = ((__int128)(0));
int64_t a0 = ay[0];
int32_t j = 1;
while (j < C) {
dp[((int64_t)(j))] = (dp[((int64_t)((j - 1)))] + (((__int128)(a0)) * ((__int128)((bx[((int64_t)(j))] - bx[((int64_t)((j - 1)))])))));
j = (j + 1);
}
int32_t i2 = 1;
while (i2 < R) {
__int128 dr = ((__int128)((ax[((int64_t)(i2))] - ax[((int64_t)((i2 - 1)))])));
ndp[0] = (dp[0] + (((__int128)(by[0])) * dr));
int64_t ai = ay[((int64_t)(i2))];
int32_t j2 = 1;
while (j2 < C) {
__int128 down = (dp[((int64_t)(j2))] + (((__int128)(by[((int64_t)(j2))])) * dr));
__int128 dc = ((__int128)((bx[((int64_t)(j2))] - bx[((int64_t)((j2 - 1)))])));
__int128 right = (ndp[((int64_t)((j2 - 1)))] + (((__int128)(ai)) * dc));
if (down < right) {
ndp[((int64_t)(j2))] = down;
} else {
ndp[((int64_t)(j2))] = right;
}
j2 = (j2 + 1);
}
__int128* tmp = (__int128*)(dp);
dp = ndp;
ndp = tmp;
i2 = (i2 + 1);
}
__int128 D = dp[((int64_t)((C - 1)))];
__int128 result = ((sum_a + sum_b) + D);
free(dp);
free(ndp);
free(ax);
free(ay);
free(bx);
free(by);
printf("%lld\n", ((int64_t)(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 @malloc(i64) -> !llvm.ptr
func.func private @free(!llvm.ptr) -> ()
func.func private @memcpy(!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
// Constant: MOD
llvm.mlir.global internal constant @MOD(998388889 : i64) : i64
// Constant: S1
llvm.mlir.global internal constant @S1(102022661 : i64) : i64
// Constant: N
llvm.mlir.global internal constant @N(10000000 : i64) : i64
func.func @cross(%arg0: i128, %arg1: i128, %arg2: i128, %arg3: i128, %arg4: i128, %arg5: i128) -> i128 {
%1 = arith.trunci %arg2 : i128 to i64
%2 = arith.trunci %arg0 : i128 to i64
%0 = arith.subi %1, %2 : i64
%4 = arith.trunci %arg5 : i128 to i64
%5 = arith.trunci %arg3 : i128 to i64
%3 = arith.subi %4, %5 : i64
%6 = arith.muli %0, %3 : i64
%8 = arith.trunci %arg3 : i128 to i64
%9 = arith.trunci %arg1 : i128 to i64
%7 = arith.subi %8, %9 : i64
%11 = arith.trunci %arg4 : i128 to i64
%12 = arith.trunci %arg2 : i128 to i64
%10 = arith.subi %11, %12 : i64
%13 = arith.muli %7, %10 : i64
%14 = arith.subi %6, %13 : i64
%15 = arith.extsi %14 : i64 to i128
func.return %15 : i128
}
func.func @main() -> i32 {
%16 = llvm.mlir.addressof @S1 : !llvm.ptr
%17 = llvm.load %16 : !llvm.ptr -> i64
%18 = llvm.mlir.constant(1 : i64) : i64
%19 = llvm.alloca %18 x i64 : (i64) -> !llvm.ptr
llvm.store %17, %19 : i64, !llvm.ptr
%20 = arith.constant 0 : i32
%21 = arith.extsi %20 : i32 to i128
%22 = llvm.mlir.constant(1 : i64) : i64
%23 = llvm.alloca %22 x i128 : (i64) -> !llvm.ptr
llvm.store %21, %23 : i128, !llvm.ptr
%24 = arith.constant 0 : i32
%25 = arith.extsi %24 : i32 to i128
%26 = llvm.mlir.constant(1 : i64) : i64
%27 = llvm.alloca %26 x i128 : (i64) -> !llvm.ptr
llvm.store %25, %27 : i128, !llvm.ptr
%29 = arith.constant 8192 : i32
%30 = arith.extsi %29 : i32 to i64
%28 = func.call @malloc(%30) : (i64) -> !llvm.ptr
%31 = llvm.mlir.constant(1 : i64) : i64
%32 = llvm.alloca %31 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %28, %32 : !llvm.ptr, !llvm.ptr
%34 = arith.constant 8192 : i32
%35 = arith.extsi %34 : i32 to i64
%33 = func.call @malloc(%35) : (i64) -> !llvm.ptr
%36 = llvm.mlir.constant(1 : i64) : i64
%37 = llvm.alloca %36 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %33, %37 : !llvm.ptr, !llvm.ptr
%39 = arith.constant 8192 : i32
%40 = arith.extsi %39 : i32 to i64
%38 = func.call @malloc(%40) : (i64) -> !llvm.ptr
%41 = llvm.mlir.constant(1 : i64) : i64
%42 = llvm.alloca %41 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %38, %42 : !llvm.ptr, !llvm.ptr
%44 = arith.constant 8192 : i32
%45 = arith.extsi %44 : i32 to i64
%43 = func.call @malloc(%45) : (i64) -> !llvm.ptr
%46 = llvm.mlir.constant(1 : i64) : i64
%47 = llvm.alloca %46 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %43, %47 : !llvm.ptr, !llvm.ptr
%48 = arith.constant 0 : i32
%49 = llvm.mlir.constant(1 : i64) : i64
%50 = llvm.alloca %49 x i32 : (i64) -> !llvm.ptr
llvm.store %48, %50 : i32, !llvm.ptr
%51 = arith.constant 0 : i32
%52 = llvm.mlir.constant(1 : i64) : i64
%53 = llvm.alloca %52 x i32 : (i64) -> !llvm.ptr
llvm.store %51, %53 : i32, !llvm.ptr
%54 = arith.constant 1024 : i32
%55 = llvm.mlir.constant(1 : i64) : i64
%56 = llvm.alloca %55 x i32 : (i64) -> !llvm.ptr
llvm.store %54, %56 : i32, !llvm.ptr
%57 = arith.constant 1024 : i32
%58 = llvm.mlir.constant(1 : i64) : i64
%59 = llvm.alloca %58 x i32 : (i64) -> !llvm.ptr
llvm.store %57, %59 : i32, !llvm.ptr
%60 = arith.constant 1 : i32
%61 = arith.extsi %60 : i32 to i64
%62 = llvm.mlir.constant(1 : i64) : i64
%63 = llvm.alloca %62 x i64 : (i64) -> !llvm.ptr
llvm.store %61, %63 : i64, !llvm.ptr
cf.br ^bb0
^bb0:
%64 = llvm.load %63 : !llvm.ptr -> i64
%65 = llvm.mlir.addressof @N : !llvm.ptr
%66 = llvm.load %65 : !llvm.ptr -> i64
%67 = arith.cmpi sle, %64, %66 : i64
cf.cond_br %67, ^bb1, ^bb2
^bb1:
%68 = llvm.load %19 : !llvm.ptr -> i64
%69 = llvm.load %19 : !llvm.ptr -> i64
%70 = llvm.load %19 : !llvm.ptr -> i64
%71 = arith.muli %69, %70 : i64
%72 = llvm.mlir.addressof @MOD : !llvm.ptr
%73 = llvm.load %72 : !llvm.ptr -> i64
%74 = arith.remsi %71, %73 : i64
llvm.store %74, %19 : i64, !llvm.ptr
%75 = llvm.load %19 : !llvm.ptr -> i64
%76 = llvm.load %19 : !llvm.ptr -> i64
%77 = llvm.load %19 : !llvm.ptr -> i64
%78 = arith.muli %76, %77 : i64
%79 = llvm.mlir.addressof @MOD : !llvm.ptr
%80 = llvm.load %79 : !llvm.ptr -> i64
%81 = arith.remsi %78, %80 : i64
llvm.store %81, %19 : i64, !llvm.ptr
%82 = llvm.load %23 : !llvm.ptr -> i128
%83 = arith.extsi %68 : i64 to i128
%85 = arith.trunci %82 : i128 to i64
%86 = arith.trunci %83 : i128 to i64
%84 = arith.addi %85, %86 : i64
%87 = arith.extsi %84 : i64 to i128
llvm.store %87, %23 : i128, !llvm.ptr
%88 = llvm.load %27 : !llvm.ptr -> i128
%89 = arith.extsi %75 : i64 to i128
%91 = arith.trunci %88 : i128 to i64
%92 = arith.trunci %89 : i128 to i64
%90 = arith.addi %91, %92 : i64
%93 = arith.extsi %90 : i64 to i128
llvm.store %93, %27 : i128, !llvm.ptr
cf.br ^bb3
^bb3:
%94 = llvm.load %50 : !llvm.ptr -> i32
%95 = arith.constant 2 : i32
%96 = arith.cmpi sge, %94, %95 : i32
cf.cond_br %96, ^bb4, ^bb5
^bb4:
%99 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
%100 = llvm.load %50 : !llvm.ptr -> i32
%101 = arith.constant 2 : i32
%102 = arith.subi %100, %101 : i32
%103 = arith.extsi %102 : i32 to i64
%104 = llvm.getelementptr %99[%103] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%98 = llvm.load %104 : !llvm.ptr -> i64
%105 = arith.extsi %98 : i64 to i128
%107 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
%108 = llvm.load %50 : !llvm.ptr -> i32
%109 = arith.constant 2 : i32
%110 = arith.subi %108, %109 : i32
%111 = arith.extsi %110 : i32 to i64
%112 = llvm.getelementptr %107[%111] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%106 = llvm.load %112 : !llvm.ptr -> i64
%113 = arith.extsi %106 : i64 to i128
%115 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
%116 = llvm.load %50 : !llvm.ptr -> i32
%117 = arith.constant 1 : i32
%118 = arith.subi %116, %117 : i32
%119 = arith.extsi %118 : i32 to i64
%120 = llvm.getelementptr %115[%119] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%114 = llvm.load %120 : !llvm.ptr -> i64
%121 = arith.extsi %114 : i64 to i128
%123 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
%124 = llvm.load %50 : !llvm.ptr -> i32
%125 = arith.constant 1 : i32
%126 = arith.subi %124, %125 : i32
%127 = arith.extsi %126 : i32 to i64
%128 = llvm.getelementptr %123[%127] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%122 = llvm.load %128 : !llvm.ptr -> i64
%129 = arith.extsi %122 : i64 to i128
%130 = llvm.load %63 : !llvm.ptr -> i64
%131 = arith.extsi %130 : i64 to i128
%132 = arith.extsi %68 : i64 to i128
%97 = func.call @cross(%105, %113, %121, %129, %131, %132) : (i128, i128, i128, i128, i128, i128) -> i128
%133 = arith.constant 0 : i32
%134 = arith.extsi %133 : i32 to i128
%136 = arith.trunci %97 : i128 to i64
%137 = arith.trunci %134 : i128 to i64
%135 = arith.cmpi sle, %136, %137 : i64
cf.cond_br %135, ^bb6, ^bb7
^bb6:
%138 = llvm.load %50 : !llvm.ptr -> i32
%139 = arith.constant 1 : i32
%140 = arith.subi %138, %139 : i32
llvm.store %140, %50 : i32, !llvm.ptr
cf.br ^bb8
^bb7:
cf.br ^bb5
^bb8:
cf.br ^bb3
^bb5:
%141 = llvm.load %50 : !llvm.ptr -> i32
%142 = llvm.load %56 : !llvm.ptr -> i32
%143 = arith.cmpi sge, %141, %142 : i32
cf.cond_br %143, ^bb9, ^bb10
^bb9:
%144 = llvm.load %56 : !llvm.ptr -> i32
%145 = arith.constant 2 : i32
%146 = arith.muli %144, %145 : i32
%148 = arith.extsi %146 : i32 to i64
%149 = arith.constant 8 : i32
%151 = arith.extsi %149 : i32 to i64
%150 = arith.muli %148, %151 : i64
%147 = func.call @malloc(%150) : (i64) -> !llvm.ptr
%153 = arith.extsi %146 : i32 to i64
%154 = arith.constant 8 : i32
%156 = arith.extsi %154 : i32 to i64
%155 = arith.muli %153, %156 : i64
%152 = func.call @malloc(%155) : (i64) -> !llvm.ptr
%158 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
%159 = llvm.load %56 : !llvm.ptr -> i32
%160 = arith.extsi %159 : i32 to i64
%161 = arith.constant 8 : i32
%163 = arith.extsi %161 : i32 to i64
%162 = arith.muli %160, %163 : i64
%157 = func.call @memcpy(%147, %158, %162) : (!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
%165 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
%166 = llvm.load %56 : !llvm.ptr -> i32
%167 = arith.extsi %166 : i32 to i64
%168 = arith.constant 8 : i32
%170 = arith.extsi %168 : i32 to i64
%169 = arith.muli %167, %170 : i64
%164 = func.call @memcpy(%152, %165, %169) : (!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
%172 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
func.call @free(%172) : (!llvm.ptr) -> ()
%174 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
func.call @free(%174) : (!llvm.ptr) -> ()
llvm.store %147, %32 : !llvm.ptr, !llvm.ptr
llvm.store %152, %37 : !llvm.ptr, !llvm.ptr
llvm.store %146, %56 : i32, !llvm.ptr
cf.br ^bb11
^bb10:
cf.br ^bb11
^bb11:
%175 = llvm.load %63 : !llvm.ptr -> i64
%176 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
%177 = llvm.load %50 : !llvm.ptr -> i32
%178 = arith.extsi %177 : i32 to i64
%179 = llvm.getelementptr %176[%178] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %175, %179 : i64, !llvm.ptr
%180 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
%181 = llvm.load %50 : !llvm.ptr -> i32
%182 = arith.extsi %181 : i32 to i64
%183 = llvm.getelementptr %180[%182] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %68, %183 : i64, !llvm.ptr
%184 = llvm.load %50 : !llvm.ptr -> i32
%185 = arith.constant 1 : i32
%186 = arith.addi %184, %185 : i32
llvm.store %186, %50 : i32, !llvm.ptr
cf.br ^bb12
^bb12:
%187 = llvm.load %53 : !llvm.ptr -> i32
%188 = arith.constant 2 : i32
%189 = arith.cmpi sge, %187, %188 : i32
cf.cond_br %189, ^bb13, ^bb14
^bb13:
%192 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%193 = llvm.load %53 : !llvm.ptr -> i32
%194 = arith.constant 2 : i32
%195 = arith.subi %193, %194 : i32
%196 = arith.extsi %195 : i32 to i64
%197 = llvm.getelementptr %192[%196] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%191 = llvm.load %197 : !llvm.ptr -> i64
%198 = arith.extsi %191 : i64 to i128
%200 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
%201 = llvm.load %53 : !llvm.ptr -> i32
%202 = arith.constant 2 : i32
%203 = arith.subi %201, %202 : i32
%204 = arith.extsi %203 : i32 to i64
%205 = llvm.getelementptr %200[%204] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%199 = llvm.load %205 : !llvm.ptr -> i64
%206 = arith.extsi %199 : i64 to i128
%208 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%209 = llvm.load %53 : !llvm.ptr -> i32
%210 = arith.constant 1 : i32
%211 = arith.subi %209, %210 : i32
%212 = arith.extsi %211 : i32 to i64
%213 = llvm.getelementptr %208[%212] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%207 = llvm.load %213 : !llvm.ptr -> i64
%214 = arith.extsi %207 : i64 to i128
%216 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
%217 = llvm.load %53 : !llvm.ptr -> i32
%218 = arith.constant 1 : i32
%219 = arith.subi %217, %218 : i32
%220 = arith.extsi %219 : i32 to i64
%221 = llvm.getelementptr %216[%220] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%215 = llvm.load %221 : !llvm.ptr -> i64
%222 = arith.extsi %215 : i64 to i128
%223 = llvm.load %63 : !llvm.ptr -> i64
%224 = arith.extsi %223 : i64 to i128
%225 = arith.extsi %75 : i64 to i128
%190 = func.call @cross(%198, %206, %214, %222, %224, %225) : (i128, i128, i128, i128, i128, i128) -> i128
%226 = arith.constant 0 : i32
%227 = arith.extsi %226 : i32 to i128
%229 = arith.trunci %190 : i128 to i64
%230 = arith.trunci %227 : i128 to i64
%228 = arith.cmpi sle, %229, %230 : i64
cf.cond_br %228, ^bb15, ^bb16
^bb15:
%231 = llvm.load %53 : !llvm.ptr -> i32
%232 = arith.constant 1 : i32
%233 = arith.subi %231, %232 : i32
llvm.store %233, %53 : i32, !llvm.ptr
cf.br ^bb17
^bb16:
cf.br ^bb14
^bb17:
cf.br ^bb12
^bb14:
%234 = llvm.load %53 : !llvm.ptr -> i32
%235 = llvm.load %59 : !llvm.ptr -> i32
%236 = arith.cmpi sge, %234, %235 : i32
cf.cond_br %236, ^bb18, ^bb19
^bb18:
%237 = llvm.load %59 : !llvm.ptr -> i32
%238 = arith.constant 2 : i32
%239 = arith.muli %237, %238 : i32
%241 = arith.extsi %239 : i32 to i64
%242 = arith.constant 8 : i32
%244 = arith.extsi %242 : i32 to i64
%243 = arith.muli %241, %244 : i64
%240 = func.call @malloc(%243) : (i64) -> !llvm.ptr
%246 = arith.extsi %239 : i32 to i64
%247 = arith.constant 8 : i32
%249 = arith.extsi %247 : i32 to i64
%248 = arith.muli %246, %249 : i64
%245 = func.call @malloc(%248) : (i64) -> !llvm.ptr
%251 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%252 = llvm.load %59 : !llvm.ptr -> i32
%253 = arith.extsi %252 : i32 to i64
%254 = arith.constant 8 : i32
%256 = arith.extsi %254 : i32 to i64
%255 = arith.muli %253, %256 : i64
%250 = func.call @memcpy(%240, %251, %255) : (!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
%258 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
%259 = llvm.load %59 : !llvm.ptr -> i32
%260 = arith.extsi %259 : i32 to i64
%261 = arith.constant 8 : i32
%263 = arith.extsi %261 : i32 to i64
%262 = arith.muli %260, %263 : i64
%257 = func.call @memcpy(%245, %258, %262) : (!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
%265 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
func.call @free(%265) : (!llvm.ptr) -> ()
%267 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
func.call @free(%267) : (!llvm.ptr) -> ()
llvm.store %240, %42 : !llvm.ptr, !llvm.ptr
llvm.store %245, %47 : !llvm.ptr, !llvm.ptr
llvm.store %239, %59 : i32, !llvm.ptr
cf.br ^bb20
^bb19:
cf.br ^bb20
^bb20:
%268 = llvm.load %63 : !llvm.ptr -> i64
%269 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%270 = llvm.load %53 : !llvm.ptr -> i32
%271 = arith.extsi %270 : i32 to i64
%272 = llvm.getelementptr %269[%271] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %268, %272 : i64, !llvm.ptr
%273 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
%274 = llvm.load %53 : !llvm.ptr -> i32
%275 = arith.extsi %274 : i32 to i64
%276 = llvm.getelementptr %273[%275] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %75, %276 : i64, !llvm.ptr
%277 = llvm.load %53 : !llvm.ptr -> i32
%278 = arith.constant 1 : i32
%279 = arith.addi %277, %278 : i32
llvm.store %279, %53 : i32, !llvm.ptr
%280 = llvm.load %63 : !llvm.ptr -> i64
%281 = arith.constant 1 : i32
%283 = arith.extsi %281 : i32 to i64
%282 = arith.addi %280, %283 : i64
llvm.store %282, %63 : i64, !llvm.ptr
cf.br ^bb0
^bb2:
%284 = llvm.load %50 : !llvm.ptr -> i32
%285 = llvm.load %53 : !llvm.ptr -> i32
%287 = arith.extsi %285 : i32 to i64
%288 = arith.constant 16 : i32
%290 = arith.extsi %288 : i32 to i64
%289 = arith.muli %287, %290 : i64
%286 = func.call @malloc(%289) : (i64) -> !llvm.ptr
%291 = llvm.mlir.constant(1 : i64) : i64
%292 = llvm.alloca %291 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %286, %292 : !llvm.ptr, !llvm.ptr
%294 = arith.extsi %285 : i32 to i64
%295 = arith.constant 16 : i32
%297 = arith.extsi %295 : i32 to i64
%296 = arith.muli %294, %297 : i64
%293 = func.call @malloc(%296) : (i64) -> !llvm.ptr
%298 = llvm.mlir.constant(1 : i64) : i64
%299 = llvm.alloca %298 x !llvm.ptr : (i64) -> !llvm.ptr
llvm.store %293, %299 : !llvm.ptr, !llvm.ptr
%300 = arith.constant 0 : i32
%301 = arith.extsi %300 : i32 to i128
%302 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
%303 = arith.constant 0 : i32
%304 = arith.extsi %303 : i32 to i64
%305 = llvm.getelementptr %302[%304] : (!llvm.ptr, i64) -> !llvm.ptr, i128
llvm.store %301, %305 : i128, !llvm.ptr
%307 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
%308 = arith.constant 0 : i32
%309 = arith.extsi %308 : i32 to i64
%310 = llvm.getelementptr %307[%309] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%306 = llvm.load %310 : !llvm.ptr -> i64
%311 = arith.constant 1 : i32
%312 = llvm.mlir.constant(1 : i64) : i64
%313 = llvm.alloca %312 x i32 : (i64) -> !llvm.ptr
llvm.store %311, %313 : i32, !llvm.ptr
cf.br ^bb21
^bb21:
%314 = llvm.load %313 : !llvm.ptr -> i32
%315 = arith.cmpi slt, %314, %285 : i32
cf.cond_br %315, ^bb22, ^bb23
^bb22:
%317 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
%318 = llvm.load %313 : !llvm.ptr -> i32
%319 = arith.constant 1 : i32
%320 = arith.subi %318, %319 : i32
%321 = arith.extsi %320 : i32 to i64
%322 = llvm.getelementptr %317[%321] : (!llvm.ptr, i64) -> !llvm.ptr, i128
%316 = llvm.load %322 : !llvm.ptr -> i128
%323 = arith.extsi %306 : i64 to i128
%325 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%326 = llvm.load %313 : !llvm.ptr -> i32
%327 = arith.extsi %326 : i32 to i64
%328 = llvm.getelementptr %325[%327] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%324 = llvm.load %328 : !llvm.ptr -> i64
%330 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%331 = llvm.load %313 : !llvm.ptr -> i32
%332 = arith.constant 1 : i32
%333 = arith.subi %331, %332 : i32
%334 = arith.extsi %333 : i32 to i64
%335 = llvm.getelementptr %330[%334] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%329 = llvm.load %335 : !llvm.ptr -> i64
%336 = arith.subi %324, %329 : i64
%337 = arith.extsi %336 : i64 to i128
%339 = arith.trunci %323 : i128 to i64
%340 = arith.trunci %337 : i128 to i64
%338 = arith.muli %339, %340 : i64
%342 = arith.trunci %316 : i128 to i64
%341 = arith.addi %342, %338 : i64
%343 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
%344 = llvm.load %313 : !llvm.ptr -> i32
%345 = arith.extsi %344 : i32 to i64
%346 = arith.extsi %341 : i64 to i128
%347 = llvm.getelementptr %343[%345] : (!llvm.ptr, i64) -> !llvm.ptr, i128
llvm.store %346, %347 : i128, !llvm.ptr
%348 = llvm.load %313 : !llvm.ptr -> i32
%349 = arith.constant 1 : i32
%350 = arith.addi %348, %349 : i32
llvm.store %350, %313 : i32, !llvm.ptr
cf.br ^bb21
^bb23:
%351 = arith.constant 1 : i32
%352 = llvm.mlir.constant(1 : i64) : i64
%353 = llvm.alloca %352 x i32 : (i64) -> !llvm.ptr
llvm.store %351, %353 : i32, !llvm.ptr
cf.br ^bb24
^bb24:
%354 = llvm.load %353 : !llvm.ptr -> i32
%355 = arith.cmpi slt, %354, %284 : i32
cf.cond_br %355, ^bb25, ^bb26
^bb25:
%357 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
%358 = llvm.load %353 : !llvm.ptr -> i32
%359 = arith.extsi %358 : i32 to i64
%360 = llvm.getelementptr %357[%359] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%356 = llvm.load %360 : !llvm.ptr -> i64
%362 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
%363 = llvm.load %353 : !llvm.ptr -> i32
%364 = arith.constant 1 : i32
%365 = arith.subi %363, %364 : i32
%366 = arith.extsi %365 : i32 to i64
%367 = llvm.getelementptr %362[%366] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%361 = llvm.load %367 : !llvm.ptr -> i64
%368 = arith.subi %356, %361 : i64
%369 = arith.extsi %368 : i64 to i128
%371 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
%372 = arith.constant 0 : i32
%373 = arith.extsi %372 : i32 to i64
%374 = llvm.getelementptr %371[%373] : (!llvm.ptr, i64) -> !llvm.ptr, i128
%370 = llvm.load %374 : !llvm.ptr -> i128
%376 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
%377 = arith.constant 0 : i32
%378 = arith.extsi %377 : i32 to i64
%379 = llvm.getelementptr %376[%378] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%375 = llvm.load %379 : !llvm.ptr -> i64
%380 = arith.extsi %375 : i64 to i128
%382 = arith.trunci %380 : i128 to i64
%383 = arith.trunci %369 : i128 to i64
%381 = arith.muli %382, %383 : i64
%385 = arith.trunci %370 : i128 to i64
%384 = arith.addi %385, %381 : i64
%386 = llvm.load %299 : !llvm.ptr -> !llvm.ptr
%387 = arith.constant 0 : i32
%388 = arith.extsi %384 : i64 to i128
%389 = arith.extsi %387 : i32 to i64
%390 = llvm.getelementptr %386[%389] : (!llvm.ptr, i64) -> !llvm.ptr, i128
llvm.store %388, %390 : i128, !llvm.ptr
%392 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
%393 = llvm.load %353 : !llvm.ptr -> i32
%394 = arith.extsi %393 : i32 to i64
%395 = llvm.getelementptr %392[%394] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%391 = llvm.load %395 : !llvm.ptr -> i64
%396 = arith.constant 1 : i32
%397 = llvm.mlir.constant(1 : i64) : i64
%398 = llvm.alloca %397 x i32 : (i64) -> !llvm.ptr
llvm.store %396, %398 : i32, !llvm.ptr
cf.br ^bb27
^bb27:
%399 = llvm.load %398 : !llvm.ptr -> i32
%400 = arith.cmpi slt, %399, %285 : i32
cf.cond_br %400, ^bb28, ^bb29
^bb28:
%402 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
%403 = llvm.load %398 : !llvm.ptr -> i32
%404 = arith.extsi %403 : i32 to i64
%405 = llvm.getelementptr %402[%404] : (!llvm.ptr, i64) -> !llvm.ptr, i128
%401 = llvm.load %405 : !llvm.ptr -> i128
%407 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
%408 = llvm.load %398 : !llvm.ptr -> i32
%409 = arith.extsi %408 : i32 to i64
%410 = llvm.getelementptr %407[%409] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%406 = llvm.load %410 : !llvm.ptr -> i64
%411 = arith.extsi %406 : i64 to i128
%413 = arith.trunci %411 : i128 to i64
%414 = arith.trunci %369 : i128 to i64
%412 = arith.muli %413, %414 : i64
%416 = arith.trunci %401 : i128 to i64
%415 = arith.addi %416, %412 : i64
%417 = arith.extsi %415 : i64 to i128
%419 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%420 = llvm.load %398 : !llvm.ptr -> i32
%421 = arith.extsi %420 : i32 to i64
%422 = llvm.getelementptr %419[%421] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%418 = llvm.load %422 : !llvm.ptr -> i64
%424 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
%425 = llvm.load %398 : !llvm.ptr -> i32
%426 = arith.constant 1 : i32
%427 = arith.subi %425, %426 : i32
%428 = arith.extsi %427 : i32 to i64
%429 = llvm.getelementptr %424[%428] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%423 = llvm.load %429 : !llvm.ptr -> i64
%430 = arith.subi %418, %423 : i64
%431 = arith.extsi %430 : i64 to i128
%433 = llvm.load %299 : !llvm.ptr -> !llvm.ptr
%434 = llvm.load %398 : !llvm.ptr -> i32
%435 = arith.constant 1 : i32
%436 = arith.subi %434, %435 : i32
%437 = arith.extsi %436 : i32 to i64
%438 = llvm.getelementptr %433[%437] : (!llvm.ptr, i64) -> !llvm.ptr, i128
%432 = llvm.load %438 : !llvm.ptr -> i128
%439 = arith.extsi %391 : i64 to i128
%441 = arith.trunci %439 : i128 to i64
%442 = arith.trunci %431 : i128 to i64
%440 = arith.muli %441, %442 : i64
%444 = arith.trunci %432 : i128 to i64
%443 = arith.addi %444, %440 : i64
%445 = arith.extsi %443 : i64 to i128
%447 = arith.trunci %417 : i128 to i64
%448 = arith.trunci %445 : i128 to i64
%446 = arith.cmpi slt, %447, %448 : i64
cf.cond_br %446, ^bb30, ^bb31
^bb30:
%449 = llvm.load %299 : !llvm.ptr -> !llvm.ptr
%450 = llvm.load %398 : !llvm.ptr -> i32
%451 = arith.extsi %450 : i32 to i64
%452 = llvm.getelementptr %449[%451] : (!llvm.ptr, i64) -> !llvm.ptr, i128
llvm.store %417, %452 : i128, !llvm.ptr
cf.br ^bb32
^bb31:
%453 = llvm.load %299 : !llvm.ptr -> !llvm.ptr
%454 = llvm.load %398 : !llvm.ptr -> i32
%455 = arith.extsi %454 : i32 to i64
%456 = llvm.getelementptr %453[%455] : (!llvm.ptr, i64) -> !llvm.ptr, i128
llvm.store %445, %456 : i128, !llvm.ptr
cf.br ^bb32
^bb32:
%457 = llvm.load %398 : !llvm.ptr -> i32
%458 = arith.constant 1 : i32
%459 = arith.addi %457, %458 : i32
llvm.store %459, %398 : i32, !llvm.ptr
cf.br ^bb27
^bb29:
%460 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
%461 = llvm.load %299 : !llvm.ptr -> !llvm.ptr
llvm.store %461, %292 : !llvm.ptr, !llvm.ptr
llvm.store %460, %299 : !llvm.ptr, !llvm.ptr
%462 = llvm.load %353 : !llvm.ptr -> i32
%463 = arith.constant 1 : i32
%464 = arith.addi %462, %463 : i32
llvm.store %464, %353 : i32, !llvm.ptr
cf.br ^bb24
^bb26:
%466 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
%467 = arith.constant 1 : i32
%468 = arith.subi %285, %467 : i32
%469 = arith.extsi %468 : i32 to i64
%470 = llvm.getelementptr %466[%469] : (!llvm.ptr, i64) -> !llvm.ptr, i128
%465 = llvm.load %470 : !llvm.ptr -> i128
%471 = llvm.load %23 : !llvm.ptr -> i128
%472 = llvm.load %27 : !llvm.ptr -> i128
%474 = arith.trunci %471 : i128 to i64
%475 = arith.trunci %472 : i128 to i64
%473 = arith.addi %474, %475 : i64
%477 = arith.trunci %465 : i128 to i64
%476 = arith.addi %473, %477 : i64
%478 = arith.extsi %476 : i64 to i128
%480 = llvm.load %292 : !llvm.ptr -> !llvm.ptr
func.call @free(%480) : (!llvm.ptr) -> ()
%482 = llvm.load %299 : !llvm.ptr -> !llvm.ptr
func.call @free(%482) : (!llvm.ptr) -> ()
%484 = llvm.load %32 : !llvm.ptr -> !llvm.ptr
func.call @free(%484) : (!llvm.ptr) -> ()
%486 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
func.call @free(%486) : (!llvm.ptr) -> ()
%488 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
func.call @free(%488) : (!llvm.ptr) -> ()
%490 = llvm.load %47 : !llvm.ptr -> !llvm.ptr
func.call @free(%490) : (!llvm.ptr) -> ()
%491 = llvm.mlir.addressof @str_0 : !llvm.ptr
%492 = arith.trunci %478 : i128 to i64
%493 = llvm.call @printf(%491, %492) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
%494 = arith.constant 0 : i32
func.return %494 : i32
}
}