Problem 910
Polynomial arithmetic in Z/(10^9)[x] mod prod_{k=1}^{40}(x+k). All polynomials are degree-39 remainders.
View problem on Project Euler
Performance comparison
| Metric | Our solution | Best known |
| Time complexity | O(n^2) | ? |
| Space complexity | O(n^2) | ? |
| Approach | Flow solution | Not curated |
| Verdict | Unknown |
Flow source
# Project Euler 910: L-Expressions II
# Polynomial arithmetic in Z/(10^9)[x] mod prod_{k=1}^{40}(x+k).
# All polynomials are degree-39 remainders.
extern {
function calloc(n: i64, size: i64) -> ptr<void>
function free(p: ptr<void>) -> void
function memset(p: ptr<void>, c: i32, n: i64) -> ptr<void>
function memcpy(dst: ptr<void>, src: ptr<void>, n: i64) -> ptr<void>
}
const DEGREE: i64 = 40
const MOD: i64 = 1000000000
let mut FOLD: ptr<i64> = null
let mut ZERO: ptr<i64> = null
let mut ONE: ptr<i64> = null
let mut X: ptr<i64> = null
function init_globals() -> void {
# Build FOLD: coefficients to replace x^40
# prod_{k=1}^{40} (x + k) = x^40 + c39*x^39 + ... + c0
# x^40 = -(c39*x^39 + ... + c0) mod the product
let coeffs: ptr<i64> = calloc(DEGREE + 1, 8)
let nxt: ptr<i64> = calloc(DEGREE + 2, 8)
let mut i: i64 = 0
while i < DEGREE + 1 {
coeffs[i] = 0
i = i + 1
}
coeffs[0] = 1
let mut len: i64 = 1
let mut k: i64 = 1
while k <= DEGREE {
let mut j: i64 = 0
while j < DEGREE + 2 {
nxt[j] = 0
j = j + 1
}
j = 0
while j < len {
nxt[j] = (nxt[j] + coeffs[j] * k) % MOD
nxt[j + 1] = (nxt[j + 1] + coeffs[j]) % MOD
j = j + 1
}
len = len + 1
j = 0
while j < len {
coeffs[j] = nxt[j]
j = j + 1
}
k = k + 1
}
# FOLD[i] = -coeffs[i] for i=0..39
i = 0
while i < DEGREE {
FOLD[i] = (MOD - coeffs[i]) % MOD
i = i + 1
}
ZERO = calloc(DEGREE, 8)
i = 0
while i < DEGREE {
ZERO[i] = 0
i = i + 1
}
ONE = calloc(DEGREE, 8)
i = 0
while i < DEGREE {
ONE[i] = 0
i = i + 1
}
ONE[0] = 1
X = calloc(DEGREE, 8)
i = 0
while i < DEGREE {
X[i] = 0
i = i + 1
}
X[1] = 1
free(coeffs)
free(nxt)
}
function poly_add(a: ptr<i64>, b: ptr<i64>, out: ptr<i64>) -> void {
let mut i: i64 = 0
while i < DEGREE {
out[i] = (a[i] + b[i]) % MOD
i = i + 1
}
}
function mul_x(poly: ptr<i64>, out: ptr<i64>) -> void {
let overflow: i64 = poly[DEGREE - 1]
let mut i: i64 = DEGREE - 1
while i > 0 {
out[i] = poly[i - 1]
i = i - 1
}
out[0] = 0
if overflow != 0 {
i = 0
while i < DEGREE {
out[i] = (out[i] + overflow * FOLD[i]) % MOD
i = i + 1
}
}
}
function poly_mul(a: ptr<i64>, b: ptr<i64>, out: ptr<i64>) -> void {
let tmp: ptr<i64> = calloc(DEGREE, 8)
let shifted: ptr<i64> = calloc(DEGREE, 8)
let next_shifted: ptr<i64> = calloc(DEGREE, 8)
let mut i: i64 = 0
while i < DEGREE {
shifted[i] = b[i]
i = i + 1
}
i = 0
while i < DEGREE {
if a[i] != 0 {
let mut j1: i64 = 0
while j1 < DEGREE {
tmp[j1] = (tmp[j1] + a[i] * shifted[j1]) % MOD
j1 = j1 + 1
}
}
mul_x(shifted, next_shifted)
let mut j2: i64 = 0
while j2 < DEGREE {
shifted[j2] = next_shifted[j2]
j2 = j2 + 1
}
i = i + 1
}
i = 0
while i < DEGREE {
out[i] = tmp[i]
i = i + 1
}
free(tmp)
free(shifted)
free(next_shifted)
}
function poly_pow(base: ptr<i64>, exponent: i64, result: ptr<i64>) -> void {
let mut i: i64 = 0
while i < DEGREE {
result[i] = ONE[i]
i = i + 1
}
let power: ptr<i64> = calloc(DEGREE, 8)
let tmp: ptr<i64> = calloc(DEGREE, 8)
i = 0
while i < DEGREE {
power[i] = base[i]
i = i + 1
}
let mut exp: i64 = exponent
while exp != 0 {
if (exp & 1) == 1 {
poly_mul(power, result, tmp)
let mut j: i64 = 0
while j < DEGREE {
result[j] = tmp[j]
j = j + 1
}
}
exp = exp >> 1
if exp != 0 {
poly_mul(power, power, tmp)
let mut j: i64 = 0
while j < DEGREE {
power[j] = tmp[j]
j = j + 1
}
}
}
free(power)
free(tmp)
}
function poly_compose(outer: ptr<i64>, inner: ptr<i64>, result: ptr<i64>) -> void {
let mut i: i64 = 0
while i < DEGREE {
result[i] = ZERO[i]
i = i + 1
}
let tmp: ptr<i64> = calloc(DEGREE, 8)
i = DEGREE - 1
while i >= 0 {
poly_mul(result, inner, tmp)
let mut j: i64 = 0
while j < DEGREE {
result[j] = tmp[j]
j = j + 1
}
result[0] = (result[0] + outer[i]) % MOD
i = i - 1
}
free(tmp)
}
function iterate_composition(poly: ptr<i64>, count: i64, result: ptr<i64>) -> void {
let mut i: i64 = 0
while i < DEGREE {
result[i] = X[i]
i = i + 1
}
let power: ptr<i64> = calloc(DEGREE, 8)
let tmp: ptr<i64> = calloc(DEGREE, 8)
i = 0
while i < DEGREE {
power[i] = poly[i]
i = i + 1
}
let mut cnt: i64 = count
while cnt != 0 {
if (cnt & 1) == 1 {
poly_compose(power, result, tmp)
let mut j: i64 = 0
while j < DEGREE {
result[j] = tmp[j]
j = j + 1
}
}
cnt = cnt >> 1
if cnt != 0 {
poly_compose(power, power, tmp)
let mut j: i64 = 0
while j < DEGREE {
power[j] = tmp[j]
j = j + 1
}
}
}
free(power)
free(tmp)
}
function d1(length: i64, out: ptr<i64>) -> void {
let base: ptr<i64> = calloc(DEGREE, 8)
let base_x: ptr<i64> = calloc(DEGREE, 8)
poly_pow(X, length, base)
mul_x(base, base_x)
poly_add(base, base_x, out)
free(base)
free(base_x)
}
function d2(count: i64, poly: ptr<i64>, out: ptr<i64>) -> void {
let iter: ptr<i64> = calloc(DEGREE, 8)
let poly_x: ptr<i64> = calloc(DEGREE, 8)
iterate_composition(poly, count, iter)
mul_x(poly, poly_x)
poly_compose(iter, poly_x, out)
free(iter)
free(poly_x)
}
function evaluate(poly: ptr<i64>, x: i64) -> i64 {
let mut result: i64 = 0
let mut i: i64 = DEGREE - 1
while i >= 0 {
result = (result * x + poly[i]) % MOD
i = i - 1
}
return result
}
function main() -> i32 {
FOLD = calloc(DEGREE, 8)
init_globals()
let nesting: i64 = 12
let middle_count: i64 = 345678
let length: i64 = 9012345
let x_val: i64 = 678
let addend: i64 = 90
let base: ptr<i64> = calloc(DEGREE, 8)
d1(length, base)
let d2val: ptr<i64> = calloc(DEGREE, 8)
d2(middle_count, base, d2val)
let current: ptr<i64> = calloc(DEGREE, 8)
poly_compose(base, d2val, current)
let mut i: i64 = 0
while i < nesting {
let tmp: ptr<i64> = calloc(DEGREE, 8)
d2(middle_count, current, tmp)
let mut j: i64 = 0
while j < DEGREE {
current[j] = tmp[j]
j = j + 1
}
free(tmp)
i = i + 1
}
let val: i64 = evaluate(current, x_val)
printf("%lld\n", (val + addend) % MOD)
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; }
void init_globals(void);
void poly_add_ptr_i64_ptr_i64_ptr_i64(int64_t* a, int64_t* b, int64_t* out);
void mul_x_ptr_i64_ptr_i64(int64_t* poly, int64_t* out);
void poly_mul_ptr_i64_ptr_i64_ptr_i64(int64_t* a, int64_t* b, int64_t* out);
void poly_pow_ptr_i64_i64_ptr_i64(int64_t* base, int64_t exponent, int64_t* result);
void poly_compose_ptr_i64_ptr_i64_ptr_i64(int64_t* outer, int64_t* inner, int64_t* result);
void iterate_composition_ptr_i64_i64_ptr_i64(int64_t* poly, int64_t count, int64_t* result);
void d1_i64_ptr_i64(int64_t length, int64_t* out);
void d2_i64_ptr_i64_ptr_i64(int64_t count, int64_t* poly, int64_t* out);
int64_t evaluate_ptr_i64_i64(int64_t* poly, int64_t x);
int32_t main(void);
static const int64_t DEGREE = 40;
static const int64_t MOD = 1000000000;
/* Module statics */
static int64_t* FOLD = NULL;
static int64_t* ZERO = NULL;
static int64_t* ONE = NULL;
static int64_t* X = NULL;
void init_globals(void) {
int64_t* coeffs = (int64_t*)(calloc((DEGREE + 1), 8));
int64_t* nxt = (int64_t*)(calloc((DEGREE + 2), 8));
int64_t i = 0;
while (i < (DEGREE + 1)) {
coeffs[i] = 0;
i = (i + 1);
}
coeffs[0] = 1;
int64_t len = 1;
int64_t k = 1;
while (k <= DEGREE) {
int64_t j = 0;
while (j < (DEGREE + 2)) {
nxt[j] = 0;
j = (j + 1);
}
j = 0;
while (j < len) {
nxt[j] = FLOW_CHECKED_MOD(((nxt[j] + (coeffs[j] * k))), (MOD));
nxt[(j + 1)] = FLOW_CHECKED_MOD(((nxt[(j + 1)] + coeffs[j])), (MOD));
j = (j + 1);
}
len = (len + 1);
j = 0;
while (j < len) {
coeffs[j] = nxt[j];
j = (j + 1);
}
k = (k + 1);
}
i = 0;
while (i < DEGREE) {
FOLD[i] = FLOW_CHECKED_MOD(((MOD - coeffs[i])), (MOD));
i = (i + 1);
}
ZERO = calloc(DEGREE, 8);
i = 0;
while (i < DEGREE) {
ZERO[i] = 0;
i = (i + 1);
}
ONE = calloc(DEGREE, 8);
i = 0;
while (i < DEGREE) {
ONE[i] = 0;
i = (i + 1);
}
ONE[0] = 1;
X = calloc(DEGREE, 8);
i = 0;
while (i < DEGREE) {
X[i] = 0;
i = (i + 1);
}
X[1] = 1;
free(coeffs);
free(nxt);
}
void poly_add_ptr_i64_ptr_i64_ptr_i64(int64_t* a, int64_t* b, int64_t* out) {
int64_t i = 0;
while (i < DEGREE) {
out[i] = FLOW_CHECKED_MOD(((a[i] + b[i])), (MOD));
i = (i + 1);
}
}
void mul_x_ptr_i64_ptr_i64(int64_t* poly, int64_t* out) {
int64_t overflow = poly[(DEGREE - 1)];
int64_t i = (DEGREE - 1);
while (i > 0) {
out[i] = poly[(i - 1)];
i = (i - 1);
}
out[0] = 0;
if (overflow != 0) {
i = 0;
while (i < DEGREE) {
out[i] = FLOW_CHECKED_MOD(((out[i] + (overflow * FOLD[i]))), (MOD));
i = (i + 1);
}
}
}
void poly_mul_ptr_i64_ptr_i64_ptr_i64(int64_t* a, int64_t* b, int64_t* out) {
int64_t* tmp = (int64_t*)(calloc(DEGREE, 8));
int64_t* shifted = (int64_t*)(calloc(DEGREE, 8));
int64_t* next_shifted = (int64_t*)(calloc(DEGREE, 8));
int64_t i = 0;
while (i < DEGREE) {
shifted[i] = b[i];
i = (i + 1);
}
i = 0;
while (i < DEGREE) {
if (a[i] != 0) {
int64_t j1 = 0;
while (j1 < DEGREE) {
tmp[j1] = FLOW_CHECKED_MOD(((tmp[j1] + (a[i] * shifted[j1]))), (MOD));
j1 = (j1 + 1);
}
}
mul_x_ptr_i64_ptr_i64(shifted, next_shifted);
int64_t j2 = 0;
while (j2 < DEGREE) {
shifted[j2] = next_shifted[j2];
j2 = (j2 + 1);
}
i = (i + 1);
}
i = 0;
while (i < DEGREE) {
out[i] = tmp[i];
i = (i + 1);
}
free(tmp);
free(shifted);
free(next_shifted);
}
void poly_pow_ptr_i64_i64_ptr_i64(int64_t* base, int64_t exponent, int64_t* result) {
int64_t i = 0;
while (i < DEGREE) {
result[i] = ONE[i];
i = (i + 1);
}
int64_t* power = (int64_t*)(calloc(DEGREE, 8));
int64_t* tmp = (int64_t*)(calloc(DEGREE, 8));
i = 0;
while (i < DEGREE) {
power[i] = base[i];
i = (i + 1);
}
int64_t exp = exponent;
while (exp != 0) {
if ((exp & 1) == 1) {
poly_mul_ptr_i64_ptr_i64_ptr_i64(power, result, tmp);
int64_t j = 0;
while (j < DEGREE) {
result[j] = tmp[j];
j = (j + 1);
}
}
exp = FLOW_CHECKED_SHR((exp), (1));
if (exp != 0) {
poly_mul_ptr_i64_ptr_i64_ptr_i64(power, power, tmp);
int64_t j = 0;
while (j < DEGREE) {
power[j] = tmp[j];
j = (j + 1);
}
}
}
free(power);
free(tmp);
}
void poly_compose_ptr_i64_ptr_i64_ptr_i64(int64_t* outer, int64_t* inner, int64_t* result) {
int64_t i = 0;
while (i < DEGREE) {
result[i] = ZERO[i];
i = (i + 1);
}
int64_t* tmp = (int64_t*)(calloc(DEGREE, 8));
i = (DEGREE - 1);
while (i >= 0) {
poly_mul_ptr_i64_ptr_i64_ptr_i64(result, inner, tmp);
int64_t j = 0;
while (j < DEGREE) {
result[j] = tmp[j];
j = (j + 1);
}
result[0] = FLOW_CHECKED_MOD(((result[0] + outer[i])), (MOD));
i = (i - 1);
}
free(tmp);
}
void iterate_composition_ptr_i64_i64_ptr_i64(int64_t* poly, int64_t count, int64_t* result) {
int64_t i = 0;
while (i < DEGREE) {
result[i] = X[i];
i = (i + 1);
}
int64_t* power = (int64_t*)(calloc(DEGREE, 8));
int64_t* tmp = (int64_t*)(calloc(DEGREE, 8));
i = 0;
while (i < DEGREE) {
power[i] = poly[i];
i = (i + 1);
}
int64_t cnt = count;
while (cnt != 0) {
if ((cnt & 1) == 1) {
poly_compose_ptr_i64_ptr_i64_ptr_i64(power, result, tmp);
int64_t j = 0;
while (j < DEGREE) {
result[j] = tmp[j];
j = (j + 1);
}
}
cnt = FLOW_CHECKED_SHR((cnt), (1));
if (cnt != 0) {
poly_compose_ptr_i64_ptr_i64_ptr_i64(power, power, tmp);
int64_t j = 0;
while (j < DEGREE) {
power[j] = tmp[j];
j = (j + 1);
}
}
}
free(power);
free(tmp);
}
void d1_i64_ptr_i64(int64_t length, int64_t* out) {
int64_t* base = (int64_t*)(calloc(DEGREE, 8));
int64_t* base_x = (int64_t*)(calloc(DEGREE, 8));
poly_pow_ptr_i64_i64_ptr_i64(X, length, base);
mul_x_ptr_i64_ptr_i64(base, base_x);
poly_add_ptr_i64_ptr_i64_ptr_i64(base, base_x, out);
free(base);
free(base_x);
}
void d2_i64_ptr_i64_ptr_i64(int64_t count, int64_t* poly, int64_t* out) {
int64_t* iter = (int64_t*)(calloc(DEGREE, 8));
int64_t* poly_x = (int64_t*)(calloc(DEGREE, 8));
iterate_composition_ptr_i64_i64_ptr_i64(poly, count, iter);
mul_x_ptr_i64_ptr_i64(poly, poly_x);
poly_compose_ptr_i64_ptr_i64_ptr_i64(iter, poly_x, out);
free(iter);
free(poly_x);
}
int64_t evaluate_ptr_i64_i64(int64_t* poly, int64_t x) {
int64_t result = 0;
int64_t i = (DEGREE - 1);
while (i >= 0) {
result = FLOW_CHECKED_MOD((((result * x) + poly[i])), (MOD));
i = (i - 1);
}
return result;
}
int32_t main(void) {
FOLD = calloc(DEGREE, 8);
init_globals();
int64_t nesting = 12;
int64_t middle_count = 345678;
int64_t length = 9012345;
int64_t x_val = 678;
int64_t addend = 90;
int64_t* base = (int64_t*)(calloc(DEGREE, 8));
d1_i64_ptr_i64(length, base);
int64_t* d2val = (int64_t*)(calloc(DEGREE, 8));
d2_i64_ptr_i64_ptr_i64(middle_count, base, d2val);
int64_t* current = (int64_t*)(calloc(DEGREE, 8));
poly_compose_ptr_i64_ptr_i64_ptr_i64(base, d2val, current);
int64_t i = 0;
while (i < nesting) {
int64_t* tmp = (int64_t*)(calloc(DEGREE, 8));
d2_i64_ptr_i64_ptr_i64(middle_count, current, tmp);
int64_t j = 0;
while (j < DEGREE) {
current[j] = tmp[j];
j = (j + 1);
}
free(tmp);
i = (i + 1);
}
int64_t val = evaluate_ptr_i64_i64(current, x_val);
printf("%lld\n", FLOW_CHECKED_MOD(((val + addend)), (MOD)));
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 @memset(!llvm.ptr, i32, i64) -> !llvm.ptr
func.func private @memcpy(!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
// Constant: DEGREE
llvm.mlir.global internal constant @DEGREE(40 : i64) : i64
// Constant: MOD
llvm.mlir.global internal constant @MOD(1000000000 : i64) : i64
// Module static: FOLD
llvm.mlir.global internal @FOLD() {addr_space = 0 : i32} : !llvm.ptr {
%0 = llvm.mlir.zero : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
// Module static: ZERO
llvm.mlir.global internal @ZERO() {addr_space = 0 : i32} : !llvm.ptr {
%1 = llvm.mlir.zero : !llvm.ptr
llvm.return %1 : !llvm.ptr
}
// Module static: ONE
llvm.mlir.global internal @ONE() {addr_space = 0 : i32} : !llvm.ptr {
%2 = llvm.mlir.zero : !llvm.ptr
llvm.return %2 : !llvm.ptr
}
// Module static: X
llvm.mlir.global internal @X() {addr_space = 0 : i32} : !llvm.ptr {
%3 = llvm.mlir.zero : !llvm.ptr
llvm.return %3 : !llvm.ptr
}
func.func @init_globals() -> () {
%5 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%6 = llvm.load %5 : !llvm.ptr -> i64
%7 = arith.constant 1 : i32
%9 = arith.extsi %7 : i32 to i64
%8 = arith.addi %6, %9 : i64
%10 = arith.constant 8 : i32
%11 = arith.extsi %10 : i32 to i64
%4 = func.call @calloc(%8, %11) : (i64, i64) -> !llvm.ptr
%13 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%14 = llvm.load %13 : !llvm.ptr -> i64
%15 = arith.constant 2 : i32
%17 = arith.extsi %15 : i32 to i64
%16 = arith.addi %14, %17 : i64
%18 = arith.constant 8 : i32
%19 = arith.extsi %18 : i32 to i64
%12 = func.call @calloc(%16, %19) : (i64, i64) -> !llvm.ptr
%20 = arith.constant 0 : i32
%21 = arith.extsi %20 : i32 to i64
%22 = llvm.mlir.constant(1 : i64) : i64
%23 = llvm.alloca %22 x i64 : (i64) -> !llvm.ptr
llvm.store %21, %23 : i64, !llvm.ptr
cf.br ^bb0
^bb0:
%24 = llvm.load %23 : !llvm.ptr -> i64
%25 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%26 = llvm.load %25 : !llvm.ptr -> i64
%27 = arith.constant 1 : i32
%29 = arith.extsi %27 : i32 to i64
%28 = arith.addi %26, %29 : i64
%30 = arith.cmpi slt, %24, %28 : i64
cf.cond_br %30, ^bb1, ^bb2
^bb1:
%31 = arith.constant 0 : i32
%32 = llvm.load %23 : !llvm.ptr -> i64
%33 = arith.extsi %31 : i32 to i64
%34 = llvm.getelementptr %4[%32] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %33, %34 : i64, !llvm.ptr
%35 = llvm.load %23 : !llvm.ptr -> i64
%36 = arith.constant 1 : i32
%38 = arith.extsi %36 : i32 to i64
%37 = arith.addi %35, %38 : i64
llvm.store %37, %23 : i64, !llvm.ptr
cf.br ^bb0
^bb2:
%39 = arith.constant 1 : i32
%40 = arith.constant 0 : i32
%41 = arith.extsi %39 : i32 to i64
%42 = arith.extsi %40 : i32 to i64
%43 = llvm.getelementptr %4[%42] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %41, %43 : i64, !llvm.ptr
%44 = arith.constant 1 : i32
%45 = arith.extsi %44 : i32 to i64
%46 = llvm.mlir.constant(1 : i64) : i64
%47 = llvm.alloca %46 x i64 : (i64) -> !llvm.ptr
llvm.store %45, %47 : i64, !llvm.ptr
%48 = arith.constant 1 : i32
%49 = arith.extsi %48 : i32 to i64
%50 = llvm.mlir.constant(1 : i64) : i64
%51 = llvm.alloca %50 x i64 : (i64) -> !llvm.ptr
llvm.store %49, %51 : i64, !llvm.ptr
cf.br ^bb3
^bb3:
%52 = llvm.load %51 : !llvm.ptr -> i64
%53 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%54 = llvm.load %53 : !llvm.ptr -> i64
%55 = arith.cmpi sle, %52, %54 : i64
cf.cond_br %55, ^bb4, ^bb5
^bb4:
%56 = arith.constant 0 : i32
%57 = arith.extsi %56 : i32 to i64
%58 = llvm.mlir.constant(1 : i64) : i64
%59 = llvm.alloca %58 x i64 : (i64) -> !llvm.ptr
llvm.store %57, %59 : i64, !llvm.ptr
cf.br ^bb6
^bb6:
%60 = llvm.load %59 : !llvm.ptr -> i64
%61 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%62 = llvm.load %61 : !llvm.ptr -> i64
%63 = arith.constant 2 : i32
%65 = arith.extsi %63 : i32 to i64
%64 = arith.addi %62, %65 : i64
%66 = arith.cmpi slt, %60, %64 : i64
cf.cond_br %66, ^bb7, ^bb8
^bb7:
%67 = arith.constant 0 : i32
%68 = llvm.load %59 : !llvm.ptr -> i64
%69 = arith.extsi %67 : i32 to i64
%70 = llvm.getelementptr %12[%68] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %69, %70 : i64, !llvm.ptr
%71 = llvm.load %59 : !llvm.ptr -> i64
%72 = arith.constant 1 : i32
%74 = arith.extsi %72 : i32 to i64
%73 = arith.addi %71, %74 : i64
llvm.store %73, %59 : i64, !llvm.ptr
cf.br ^bb6
^bb8:
%75 = arith.constant 0 : i32
%76 = arith.extsi %75 : i32 to i64
llvm.store %76, %59 : i64, !llvm.ptr
cf.br ^bb9
^bb9:
%77 = llvm.load %59 : !llvm.ptr -> i64
%78 = llvm.load %47 : !llvm.ptr -> i64
%79 = arith.cmpi slt, %77, %78 : i64
cf.cond_br %79, ^bb10, ^bb11
^bb10:
%81 = llvm.load %59 : !llvm.ptr -> i64
%82 = llvm.getelementptr %12[%81] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%80 = llvm.load %82 : !llvm.ptr -> i64
%84 = llvm.load %59 : !llvm.ptr -> i64
%85 = llvm.getelementptr %4[%84] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%83 = llvm.load %85 : !llvm.ptr -> i64
%86 = llvm.load %51 : !llvm.ptr -> i64
%87 = arith.muli %83, %86 : i64
%88 = arith.addi %80, %87 : i64
%89 = llvm.mlir.addressof @MOD : !llvm.ptr
%90 = llvm.load %89 : !llvm.ptr -> i64
%91 = arith.remsi %88, %90 : i64
%92 = llvm.load %59 : !llvm.ptr -> i64
%93 = llvm.getelementptr %12[%92] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %91, %93 : i64, !llvm.ptr
%95 = llvm.load %59 : !llvm.ptr -> i64
%96 = arith.constant 1 : i32
%98 = arith.extsi %96 : i32 to i64
%97 = arith.addi %95, %98 : i64
%99 = llvm.getelementptr %12[%97] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%94 = llvm.load %99 : !llvm.ptr -> i64
%101 = llvm.load %59 : !llvm.ptr -> i64
%102 = llvm.getelementptr %4[%101] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%100 = llvm.load %102 : !llvm.ptr -> i64
%103 = arith.addi %94, %100 : i64
%104 = llvm.mlir.addressof @MOD : !llvm.ptr
%105 = llvm.load %104 : !llvm.ptr -> i64
%106 = arith.remsi %103, %105 : i64
%107 = llvm.load %59 : !llvm.ptr -> i64
%108 = arith.constant 1 : i32
%110 = arith.extsi %108 : i32 to i64
%109 = arith.addi %107, %110 : i64
%111 = llvm.getelementptr %12[%109] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %106, %111 : i64, !llvm.ptr
%112 = llvm.load %59 : !llvm.ptr -> i64
%113 = arith.constant 1 : i32
%115 = arith.extsi %113 : i32 to i64
%114 = arith.addi %112, %115 : i64
llvm.store %114, %59 : i64, !llvm.ptr
cf.br ^bb9
^bb11:
%116 = llvm.load %47 : !llvm.ptr -> i64
%117 = arith.constant 1 : i32
%119 = arith.extsi %117 : i32 to i64
%118 = arith.addi %116, %119 : i64
llvm.store %118, %47 : i64, !llvm.ptr
%120 = arith.constant 0 : i32
%121 = arith.extsi %120 : i32 to i64
llvm.store %121, %59 : i64, !llvm.ptr
cf.br ^bb12
^bb12:
%122 = llvm.load %59 : !llvm.ptr -> i64
%123 = llvm.load %47 : !llvm.ptr -> i64
%124 = arith.cmpi slt, %122, %123 : i64
cf.cond_br %124, ^bb13, ^bb14
^bb13:
%126 = llvm.load %59 : !llvm.ptr -> i64
%127 = llvm.getelementptr %12[%126] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%125 = llvm.load %127 : !llvm.ptr -> i64
%128 = llvm.load %59 : !llvm.ptr -> i64
%129 = llvm.getelementptr %4[%128] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %125, %129 : i64, !llvm.ptr
%130 = llvm.load %59 : !llvm.ptr -> i64
%131 = arith.constant 1 : i32
%133 = arith.extsi %131 : i32 to i64
%132 = arith.addi %130, %133 : i64
llvm.store %132, %59 : i64, !llvm.ptr
cf.br ^bb12
^bb14:
%134 = llvm.load %51 : !llvm.ptr -> i64
%135 = arith.constant 1 : i32
%137 = arith.extsi %135 : i32 to i64
%136 = arith.addi %134, %137 : i64
llvm.store %136, %51 : i64, !llvm.ptr
cf.br ^bb3
^bb5:
%138 = arith.constant 0 : i32
%139 = arith.extsi %138 : i32 to i64
llvm.store %139, %23 : i64, !llvm.ptr
cf.br ^bb15
^bb15:
%140 = llvm.load %23 : !llvm.ptr -> i64
%141 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%142 = llvm.load %141 : !llvm.ptr -> i64
%143 = arith.cmpi slt, %140, %142 : i64
cf.cond_br %143, ^bb16, ^bb17
^bb16:
%144 = llvm.mlir.addressof @MOD : !llvm.ptr
%145 = llvm.load %144 : !llvm.ptr -> i64
%147 = llvm.load %23 : !llvm.ptr -> i64
%148 = llvm.getelementptr %4[%147] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%146 = llvm.load %148 : !llvm.ptr -> i64
%149 = arith.subi %145, %146 : i64
%150 = llvm.mlir.addressof @MOD : !llvm.ptr
%151 = llvm.load %150 : !llvm.ptr -> i64
%152 = arith.remsi %149, %151 : i64
%153 = llvm.mlir.addressof @FOLD : !llvm.ptr
%154 = llvm.load %153 : !llvm.ptr -> !llvm.ptr
%155 = llvm.load %23 : !llvm.ptr -> i64
%156 = llvm.getelementptr %154[%155] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %152, %156 : i64, !llvm.ptr
%157 = llvm.load %23 : !llvm.ptr -> i64
%158 = arith.constant 1 : i32
%160 = arith.extsi %158 : i32 to i64
%159 = arith.addi %157, %160 : i64
llvm.store %159, %23 : i64, !llvm.ptr
cf.br ^bb15
^bb17:
%162 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%163 = llvm.load %162 : !llvm.ptr -> i64
%164 = arith.constant 8 : i32
%165 = arith.extsi %164 : i32 to i64
%161 = func.call @calloc(%163, %165) : (i64, i64) -> !llvm.ptr
%166 = llvm.mlir.addressof @ZERO : !llvm.ptr
llvm.store %161, %166 : !llvm.ptr, !llvm.ptr
%167 = arith.constant 0 : i32
%168 = arith.extsi %167 : i32 to i64
llvm.store %168, %23 : i64, !llvm.ptr
cf.br ^bb18
^bb18:
%169 = llvm.load %23 : !llvm.ptr -> i64
%170 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%171 = llvm.load %170 : !llvm.ptr -> i64
%172 = arith.cmpi slt, %169, %171 : i64
cf.cond_br %172, ^bb19, ^bb20
^bb19:
%173 = arith.constant 0 : i32
%174 = llvm.mlir.addressof @ZERO : !llvm.ptr
%175 = llvm.load %174 : !llvm.ptr -> !llvm.ptr
%176 = llvm.load %23 : !llvm.ptr -> i64
%177 = arith.extsi %173 : i32 to i64
%178 = llvm.getelementptr %175[%176] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %177, %178 : i64, !llvm.ptr
%179 = llvm.load %23 : !llvm.ptr -> i64
%180 = arith.constant 1 : i32
%182 = arith.extsi %180 : i32 to i64
%181 = arith.addi %179, %182 : i64
llvm.store %181, %23 : i64, !llvm.ptr
cf.br ^bb18
^bb20:
%184 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%185 = llvm.load %184 : !llvm.ptr -> i64
%186 = arith.constant 8 : i32
%187 = arith.extsi %186 : i32 to i64
%183 = func.call @calloc(%185, %187) : (i64, i64) -> !llvm.ptr
%188 = llvm.mlir.addressof @ONE : !llvm.ptr
llvm.store %183, %188 : !llvm.ptr, !llvm.ptr
%189 = arith.constant 0 : i32
%190 = arith.extsi %189 : i32 to i64
llvm.store %190, %23 : i64, !llvm.ptr
cf.br ^bb21
^bb21:
%191 = llvm.load %23 : !llvm.ptr -> i64
%192 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%193 = llvm.load %192 : !llvm.ptr -> i64
%194 = arith.cmpi slt, %191, %193 : i64
cf.cond_br %194, ^bb22, ^bb23
^bb22:
%195 = arith.constant 0 : i32
%196 = llvm.mlir.addressof @ONE : !llvm.ptr
%197 = llvm.load %196 : !llvm.ptr -> !llvm.ptr
%198 = llvm.load %23 : !llvm.ptr -> i64
%199 = arith.extsi %195 : i32 to i64
%200 = llvm.getelementptr %197[%198] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %199, %200 : i64, !llvm.ptr
%201 = llvm.load %23 : !llvm.ptr -> i64
%202 = arith.constant 1 : i32
%204 = arith.extsi %202 : i32 to i64
%203 = arith.addi %201, %204 : i64
llvm.store %203, %23 : i64, !llvm.ptr
cf.br ^bb21
^bb23:
%205 = arith.constant 1 : i32
%206 = llvm.mlir.addressof @ONE : !llvm.ptr
%207 = llvm.load %206 : !llvm.ptr -> !llvm.ptr
%208 = arith.constant 0 : i32
%209 = arith.extsi %205 : i32 to i64
%210 = arith.extsi %208 : i32 to i64
%211 = llvm.getelementptr %207[%210] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %209, %211 : i64, !llvm.ptr
%213 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%214 = llvm.load %213 : !llvm.ptr -> i64
%215 = arith.constant 8 : i32
%216 = arith.extsi %215 : i32 to i64
%212 = func.call @calloc(%214, %216) : (i64, i64) -> !llvm.ptr
%217 = llvm.mlir.addressof @X : !llvm.ptr
llvm.store %212, %217 : !llvm.ptr, !llvm.ptr
%218 = arith.constant 0 : i32
%219 = arith.extsi %218 : i32 to i64
llvm.store %219, %23 : i64, !llvm.ptr
cf.br ^bb24
^bb24:
%220 = llvm.load %23 : !llvm.ptr -> i64
%221 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%222 = llvm.load %221 : !llvm.ptr -> i64
%223 = arith.cmpi slt, %220, %222 : i64
cf.cond_br %223, ^bb25, ^bb26
^bb25:
%224 = arith.constant 0 : i32
%225 = llvm.mlir.addressof @X : !llvm.ptr
%226 = llvm.load %225 : !llvm.ptr -> !llvm.ptr
%227 = llvm.load %23 : !llvm.ptr -> i64
%228 = arith.extsi %224 : i32 to i64
%229 = llvm.getelementptr %226[%227] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %228, %229 : i64, !llvm.ptr
%230 = llvm.load %23 : !llvm.ptr -> i64
%231 = arith.constant 1 : i32
%233 = arith.extsi %231 : i32 to i64
%232 = arith.addi %230, %233 : i64
llvm.store %232, %23 : i64, !llvm.ptr
cf.br ^bb24
^bb26:
%234 = arith.constant 1 : i32
%235 = llvm.mlir.addressof @X : !llvm.ptr
%236 = llvm.load %235 : !llvm.ptr -> !llvm.ptr
%237 = arith.constant 1 : i32
%238 = arith.extsi %234 : i32 to i64
%239 = arith.extsi %237 : i32 to i64
%240 = llvm.getelementptr %236[%239] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %238, %240 : i64, !llvm.ptr
func.call @free(%4) : (!llvm.ptr) -> ()
func.call @free(%12) : (!llvm.ptr) -> ()
func.return
}
func.func @poly_add(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> () {
%243 = arith.constant 0 : i32
%244 = arith.extsi %243 : i32 to i64
%245 = llvm.mlir.constant(1 : i64) : i64
%246 = llvm.alloca %245 x i64 : (i64) -> !llvm.ptr
llvm.store %244, %246 : i64, !llvm.ptr
cf.br ^bb27
^bb27:
%247 = llvm.load %246 : !llvm.ptr -> i64
%248 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%249 = llvm.load %248 : !llvm.ptr -> i64
%250 = arith.cmpi slt, %247, %249 : i64
cf.cond_br %250, ^bb28, ^bb29
^bb28:
%252 = llvm.load %246 : !llvm.ptr -> i64
%253 = llvm.getelementptr %arg0[%252] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%251 = llvm.load %253 : !llvm.ptr -> i64
%255 = llvm.load %246 : !llvm.ptr -> i64
%256 = llvm.getelementptr %arg1[%255] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%254 = llvm.load %256 : !llvm.ptr -> i64
%257 = arith.addi %251, %254 : i64
%258 = llvm.mlir.addressof @MOD : !llvm.ptr
%259 = llvm.load %258 : !llvm.ptr -> i64
%260 = arith.remsi %257, %259 : i64
%261 = llvm.load %246 : !llvm.ptr -> i64
%262 = llvm.getelementptr %arg2[%261] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %260, %262 : i64, !llvm.ptr
%263 = llvm.load %246 : !llvm.ptr -> i64
%264 = arith.constant 1 : i32
%266 = arith.extsi %264 : i32 to i64
%265 = arith.addi %263, %266 : i64
llvm.store %265, %246 : i64, !llvm.ptr
cf.br ^bb27
^bb29:
func.return
}
func.func @mul_x(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () {
%268 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%269 = llvm.load %268 : !llvm.ptr -> i64
%270 = arith.constant 1 : i32
%272 = arith.extsi %270 : i32 to i64
%271 = arith.subi %269, %272 : i64
%273 = llvm.getelementptr %arg0[%271] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%267 = llvm.load %273 : !llvm.ptr -> i64
%274 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%275 = llvm.load %274 : !llvm.ptr -> i64
%276 = arith.constant 1 : i32
%278 = arith.extsi %276 : i32 to i64
%277 = arith.subi %275, %278 : i64
%279 = llvm.mlir.constant(1 : i64) : i64
%280 = llvm.alloca %279 x i64 : (i64) -> !llvm.ptr
llvm.store %277, %280 : i64, !llvm.ptr
cf.br ^bb30
^bb30:
%281 = llvm.load %280 : !llvm.ptr -> i64
%282 = arith.constant 0 : i32
%284 = arith.extsi %282 : i32 to i64
%283 = arith.cmpi sgt, %281, %284 : i64
cf.cond_br %283, ^bb31, ^bb32
^bb31:
%286 = llvm.load %280 : !llvm.ptr -> i64
%287 = arith.constant 1 : i32
%289 = arith.extsi %287 : i32 to i64
%288 = arith.subi %286, %289 : i64
%290 = llvm.getelementptr %arg0[%288] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%285 = llvm.load %290 : !llvm.ptr -> i64
%291 = llvm.load %280 : !llvm.ptr -> i64
%292 = llvm.getelementptr %arg1[%291] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %285, %292 : i64, !llvm.ptr
%293 = llvm.load %280 : !llvm.ptr -> i64
%294 = arith.constant 1 : i32
%296 = arith.extsi %294 : i32 to i64
%295 = arith.subi %293, %296 : i64
llvm.store %295, %280 : i64, !llvm.ptr
cf.br ^bb30
^bb32:
%297 = arith.constant 0 : i32
%298 = arith.constant 0 : i32
%299 = arith.extsi %297 : i32 to i64
%300 = arith.extsi %298 : i32 to i64
%301 = llvm.getelementptr %arg1[%300] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %299, %301 : i64, !llvm.ptr
%302 = arith.constant 0 : i32
%304 = arith.extsi %302 : i32 to i64
%303 = arith.cmpi ne, %267, %304 : i64
cf.cond_br %303, ^bb33, ^bb34
^bb33:
%305 = arith.constant 0 : i32
%306 = arith.extsi %305 : i32 to i64
llvm.store %306, %280 : i64, !llvm.ptr
cf.br ^bb36
^bb36:
%307 = llvm.load %280 : !llvm.ptr -> i64
%308 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%309 = llvm.load %308 : !llvm.ptr -> i64
%310 = arith.cmpi slt, %307, %309 : i64
cf.cond_br %310, ^bb37, ^bb38
^bb37:
%312 = llvm.load %280 : !llvm.ptr -> i64
%313 = llvm.getelementptr %arg1[%312] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%311 = llvm.load %313 : !llvm.ptr -> i64
%315 = llvm.mlir.addressof @FOLD : !llvm.ptr
%316 = llvm.load %315 : !llvm.ptr -> !llvm.ptr
%317 = llvm.load %280 : !llvm.ptr -> i64
%318 = llvm.getelementptr %316[%317] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%314 = llvm.load %318 : !llvm.ptr -> i64
%319 = arith.muli %267, %314 : i64
%320 = arith.addi %311, %319 : i64
%321 = llvm.mlir.addressof @MOD : !llvm.ptr
%322 = llvm.load %321 : !llvm.ptr -> i64
%323 = arith.remsi %320, %322 : i64
%324 = llvm.load %280 : !llvm.ptr -> i64
%325 = llvm.getelementptr %arg1[%324] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %323, %325 : i64, !llvm.ptr
%326 = llvm.load %280 : !llvm.ptr -> i64
%327 = arith.constant 1 : i32
%329 = arith.extsi %327 : i32 to i64
%328 = arith.addi %326, %329 : i64
llvm.store %328, %280 : i64, !llvm.ptr
cf.br ^bb36
^bb38:
cf.br ^bb35
^bb34:
cf.br ^bb35
^bb35:
func.return
}
func.func @poly_mul(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> () {
%331 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%332 = llvm.load %331 : !llvm.ptr -> i64
%333 = arith.constant 8 : i32
%334 = arith.extsi %333 : i32 to i64
%330 = func.call @calloc(%332, %334) : (i64, i64) -> !llvm.ptr
%336 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%337 = llvm.load %336 : !llvm.ptr -> i64
%338 = arith.constant 8 : i32
%339 = arith.extsi %338 : i32 to i64
%335 = func.call @calloc(%337, %339) : (i64, i64) -> !llvm.ptr
%341 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%342 = llvm.load %341 : !llvm.ptr -> i64
%343 = arith.constant 8 : i32
%344 = arith.extsi %343 : i32 to i64
%340 = func.call @calloc(%342, %344) : (i64, i64) -> !llvm.ptr
%345 = arith.constant 0 : i32
%346 = arith.extsi %345 : i32 to i64
%347 = llvm.mlir.constant(1 : i64) : i64
%348 = llvm.alloca %347 x i64 : (i64) -> !llvm.ptr
llvm.store %346, %348 : i64, !llvm.ptr
cf.br ^bb39
^bb39:
%349 = llvm.load %348 : !llvm.ptr -> i64
%350 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%351 = llvm.load %350 : !llvm.ptr -> i64
%352 = arith.cmpi slt, %349, %351 : i64
cf.cond_br %352, ^bb40, ^bb41
^bb40:
%354 = llvm.load %348 : !llvm.ptr -> i64
%355 = llvm.getelementptr %arg1[%354] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%353 = llvm.load %355 : !llvm.ptr -> i64
%356 = llvm.load %348 : !llvm.ptr -> i64
%357 = llvm.getelementptr %335[%356] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %353, %357 : i64, !llvm.ptr
%358 = llvm.load %348 : !llvm.ptr -> i64
%359 = arith.constant 1 : i32
%361 = arith.extsi %359 : i32 to i64
%360 = arith.addi %358, %361 : i64
llvm.store %360, %348 : i64, !llvm.ptr
cf.br ^bb39
^bb41:
%362 = arith.constant 0 : i32
%363 = arith.extsi %362 : i32 to i64
llvm.store %363, %348 : i64, !llvm.ptr
cf.br ^bb42
^bb42:
%364 = llvm.load %348 : !llvm.ptr -> i64
%365 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%366 = llvm.load %365 : !llvm.ptr -> i64
%367 = arith.cmpi slt, %364, %366 : i64
cf.cond_br %367, ^bb43, ^bb44
^bb43:
%369 = llvm.load %348 : !llvm.ptr -> i64
%370 = llvm.getelementptr %arg0[%369] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%368 = llvm.load %370 : !llvm.ptr -> i64
%371 = arith.constant 0 : i32
%373 = arith.extsi %371 : i32 to i64
%372 = arith.cmpi ne, %368, %373 : i64
cf.cond_br %372, ^bb45, ^bb46
^bb45:
%374 = arith.constant 0 : i32
%375 = arith.extsi %374 : i32 to i64
%376 = llvm.mlir.constant(1 : i64) : i64
%377 = llvm.alloca %376 x i64 : (i64) -> !llvm.ptr
llvm.store %375, %377 : i64, !llvm.ptr
cf.br ^bb48
^bb48:
%378 = llvm.load %377 : !llvm.ptr -> i64
%379 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%380 = llvm.load %379 : !llvm.ptr -> i64
%381 = arith.cmpi slt, %378, %380 : i64
cf.cond_br %381, ^bb49, ^bb50
^bb49:
%383 = llvm.load %377 : !llvm.ptr -> i64
%384 = llvm.getelementptr %330[%383] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%382 = llvm.load %384 : !llvm.ptr -> i64
%386 = llvm.load %348 : !llvm.ptr -> i64
%387 = llvm.getelementptr %arg0[%386] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%385 = llvm.load %387 : !llvm.ptr -> i64
%389 = llvm.load %377 : !llvm.ptr -> i64
%390 = llvm.getelementptr %335[%389] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%388 = llvm.load %390 : !llvm.ptr -> i64
%391 = arith.muli %385, %388 : i64
%392 = arith.addi %382, %391 : i64
%393 = llvm.mlir.addressof @MOD : !llvm.ptr
%394 = llvm.load %393 : !llvm.ptr -> i64
%395 = arith.remsi %392, %394 : i64
%396 = llvm.load %377 : !llvm.ptr -> i64
%397 = llvm.getelementptr %330[%396] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %395, %397 : i64, !llvm.ptr
%398 = llvm.load %377 : !llvm.ptr -> i64
%399 = arith.constant 1 : i32
%401 = arith.extsi %399 : i32 to i64
%400 = arith.addi %398, %401 : i64
llvm.store %400, %377 : i64, !llvm.ptr
cf.br ^bb48
^bb50:
cf.br ^bb47
^bb46:
cf.br ^bb47
^bb47:
func.call @mul_x(%335, %340) : (!llvm.ptr, !llvm.ptr) -> ()
%403 = arith.constant 0 : i32
%404 = arith.extsi %403 : i32 to i64
%405 = llvm.mlir.constant(1 : i64) : i64
%406 = llvm.alloca %405 x i64 : (i64) -> !llvm.ptr
llvm.store %404, %406 : i64, !llvm.ptr
cf.br ^bb51
^bb51:
%407 = llvm.load %406 : !llvm.ptr -> i64
%408 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%409 = llvm.load %408 : !llvm.ptr -> i64
%410 = arith.cmpi slt, %407, %409 : i64
cf.cond_br %410, ^bb52, ^bb53
^bb52:
%412 = llvm.load %406 : !llvm.ptr -> i64
%413 = llvm.getelementptr %340[%412] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%411 = llvm.load %413 : !llvm.ptr -> i64
%414 = llvm.load %406 : !llvm.ptr -> i64
%415 = llvm.getelementptr %335[%414] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %411, %415 : i64, !llvm.ptr
%416 = llvm.load %406 : !llvm.ptr -> i64
%417 = arith.constant 1 : i32
%419 = arith.extsi %417 : i32 to i64
%418 = arith.addi %416, %419 : i64
llvm.store %418, %406 : i64, !llvm.ptr
cf.br ^bb51
^bb53:
%420 = llvm.load %348 : !llvm.ptr -> i64
%421 = arith.constant 1 : i32
%423 = arith.extsi %421 : i32 to i64
%422 = arith.addi %420, %423 : i64
llvm.store %422, %348 : i64, !llvm.ptr
cf.br ^bb42
^bb44:
%424 = arith.constant 0 : i32
%425 = arith.extsi %424 : i32 to i64
llvm.store %425, %348 : i64, !llvm.ptr
cf.br ^bb54
^bb54:
%426 = llvm.load %348 : !llvm.ptr -> i64
%427 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%428 = llvm.load %427 : !llvm.ptr -> i64
%429 = arith.cmpi slt, %426, %428 : i64
cf.cond_br %429, ^bb55, ^bb56
^bb55:
%431 = llvm.load %348 : !llvm.ptr -> i64
%432 = llvm.getelementptr %330[%431] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%430 = llvm.load %432 : !llvm.ptr -> i64
%433 = llvm.load %348 : !llvm.ptr -> i64
%434 = llvm.getelementptr %arg2[%433] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %430, %434 : i64, !llvm.ptr
%435 = llvm.load %348 : !llvm.ptr -> i64
%436 = arith.constant 1 : i32
%438 = arith.extsi %436 : i32 to i64
%437 = arith.addi %435, %438 : i64
llvm.store %437, %348 : i64, !llvm.ptr
cf.br ^bb54
^bb56:
func.call @free(%330) : (!llvm.ptr) -> ()
func.call @free(%335) : (!llvm.ptr) -> ()
func.call @free(%340) : (!llvm.ptr) -> ()
func.return
}
func.func @poly_pow(%arg0: !llvm.ptr, %arg1: i64, %arg2: !llvm.ptr) -> () {
%442 = arith.constant 0 : i32
%443 = arith.extsi %442 : i32 to i64
%444 = llvm.mlir.constant(1 : i64) : i64
%445 = llvm.alloca %444 x i64 : (i64) -> !llvm.ptr
llvm.store %443, %445 : i64, !llvm.ptr
cf.br ^bb57
^bb57:
%446 = llvm.load %445 : !llvm.ptr -> i64
%447 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%448 = llvm.load %447 : !llvm.ptr -> i64
%449 = arith.cmpi slt, %446, %448 : i64
cf.cond_br %449, ^bb58, ^bb59
^bb58:
%451 = llvm.mlir.addressof @ONE : !llvm.ptr
%452 = llvm.load %451 : !llvm.ptr -> !llvm.ptr
%453 = llvm.load %445 : !llvm.ptr -> i64
%454 = llvm.getelementptr %452[%453] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%450 = llvm.load %454 : !llvm.ptr -> i64
%455 = llvm.load %445 : !llvm.ptr -> i64
%456 = llvm.getelementptr %arg2[%455] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %450, %456 : i64, !llvm.ptr
%457 = llvm.load %445 : !llvm.ptr -> i64
%458 = arith.constant 1 : i32
%460 = arith.extsi %458 : i32 to i64
%459 = arith.addi %457, %460 : i64
llvm.store %459, %445 : i64, !llvm.ptr
cf.br ^bb57
^bb59:
%462 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%463 = llvm.load %462 : !llvm.ptr -> i64
%464 = arith.constant 8 : i32
%465 = arith.extsi %464 : i32 to i64
%461 = func.call @calloc(%463, %465) : (i64, i64) -> !llvm.ptr
%467 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%468 = llvm.load %467 : !llvm.ptr -> i64
%469 = arith.constant 8 : i32
%470 = arith.extsi %469 : i32 to i64
%466 = func.call @calloc(%468, %470) : (i64, i64) -> !llvm.ptr
%471 = arith.constant 0 : i32
%472 = arith.extsi %471 : i32 to i64
llvm.store %472, %445 : i64, !llvm.ptr
cf.br ^bb60
^bb60:
%473 = llvm.load %445 : !llvm.ptr -> i64
%474 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%475 = llvm.load %474 : !llvm.ptr -> i64
%476 = arith.cmpi slt, %473, %475 : i64
cf.cond_br %476, ^bb61, ^bb62
^bb61:
%478 = llvm.load %445 : !llvm.ptr -> i64
%479 = llvm.getelementptr %arg0[%478] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%477 = llvm.load %479 : !llvm.ptr -> i64
%480 = llvm.load %445 : !llvm.ptr -> i64
%481 = llvm.getelementptr %461[%480] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %477, %481 : i64, !llvm.ptr
%482 = llvm.load %445 : !llvm.ptr -> i64
%483 = arith.constant 1 : i32
%485 = arith.extsi %483 : i32 to i64
%484 = arith.addi %482, %485 : i64
llvm.store %484, %445 : i64, !llvm.ptr
cf.br ^bb60
^bb62:
%486 = llvm.mlir.constant(1 : i64) : i64
%487 = llvm.alloca %486 x i64 : (i64) -> !llvm.ptr
llvm.store %arg1, %487 : i64, !llvm.ptr
cf.br ^bb63
^bb63:
%488 = llvm.load %487 : !llvm.ptr -> i64
%489 = arith.constant 0 : i32
%491 = arith.extsi %489 : i32 to i64
%490 = arith.cmpi ne, %488, %491 : i64
cf.cond_br %490, ^bb64, ^bb65
^bb64:
%492 = llvm.load %487 : !llvm.ptr -> i64
%493 = arith.constant 1 : i32
%495 = arith.extsi %493 : i32 to i64
%494 = arith.andi %492, %495 : i64
%496 = arith.constant 1 : i32
%498 = arith.extsi %496 : i32 to i64
%497 = arith.cmpi eq, %494, %498 : i64
cf.cond_br %497, ^bb66, ^bb67
^bb66:
func.call @poly_mul(%461, %arg2, %466) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
%500 = arith.constant 0 : i32
%501 = arith.extsi %500 : i32 to i64
%502 = llvm.mlir.constant(1 : i64) : i64
%503 = llvm.alloca %502 x i64 : (i64) -> !llvm.ptr
llvm.store %501, %503 : i64, !llvm.ptr
cf.br ^bb69
^bb69:
%504 = llvm.load %503 : !llvm.ptr -> i64
%505 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%506 = llvm.load %505 : !llvm.ptr -> i64
%507 = arith.cmpi slt, %504, %506 : i64
cf.cond_br %507, ^bb70, ^bb71
^bb70:
%509 = llvm.load %503 : !llvm.ptr -> i64
%510 = llvm.getelementptr %466[%509] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%508 = llvm.load %510 : !llvm.ptr -> i64
%511 = llvm.load %503 : !llvm.ptr -> i64
%512 = llvm.getelementptr %arg2[%511] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %508, %512 : i64, !llvm.ptr
%513 = llvm.load %503 : !llvm.ptr -> i64
%514 = arith.constant 1 : i32
%516 = arith.extsi %514 : i32 to i64
%515 = arith.addi %513, %516 : i64
llvm.store %515, %503 : i64, !llvm.ptr
cf.br ^bb69
^bb71:
cf.br ^bb68
^bb67:
cf.br ^bb68
^bb68:
%517 = llvm.load %487 : !llvm.ptr -> i64
%518 = arith.constant 1 : i32
%520 = arith.extsi %518 : i32 to i64
%519 = arith.shrsi %517, %520 : i64
llvm.store %519, %487 : i64, !llvm.ptr
%521 = llvm.load %487 : !llvm.ptr -> i64
%522 = arith.constant 0 : i32
%524 = arith.extsi %522 : i32 to i64
%523 = arith.cmpi ne, %521, %524 : i64
cf.cond_br %523, ^bb72, ^bb73
^bb72:
func.call @poly_mul(%461, %461, %466) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
%526 = arith.constant 0 : i32
%527 = arith.extsi %526 : i32 to i64
%528 = llvm.mlir.constant(1 : i64) : i64
%529 = llvm.alloca %528 x i64 : (i64) -> !llvm.ptr
llvm.store %527, %529 : i64, !llvm.ptr
cf.br ^bb75
^bb75:
%530 = llvm.load %529 : !llvm.ptr -> i64
%531 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%532 = llvm.load %531 : !llvm.ptr -> i64
%533 = arith.cmpi slt, %530, %532 : i64
cf.cond_br %533, ^bb76, ^bb77
^bb76:
%535 = llvm.load %529 : !llvm.ptr -> i64
%536 = llvm.getelementptr %466[%535] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%534 = llvm.load %536 : !llvm.ptr -> i64
%537 = llvm.load %529 : !llvm.ptr -> i64
%538 = llvm.getelementptr %461[%537] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %534, %538 : i64, !llvm.ptr
%539 = llvm.load %529 : !llvm.ptr -> i64
%540 = arith.constant 1 : i32
%542 = arith.extsi %540 : i32 to i64
%541 = arith.addi %539, %542 : i64
llvm.store %541, %529 : i64, !llvm.ptr
cf.br ^bb75
^bb77:
cf.br ^bb74
^bb73:
cf.br ^bb74
^bb74:
cf.br ^bb63
^bb65:
func.call @free(%461) : (!llvm.ptr) -> ()
func.call @free(%466) : (!llvm.ptr) -> ()
func.return
}
func.func @poly_compose(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> () {
%545 = arith.constant 0 : i32
%546 = arith.extsi %545 : i32 to i64
%547 = llvm.mlir.constant(1 : i64) : i64
%548 = llvm.alloca %547 x i64 : (i64) -> !llvm.ptr
llvm.store %546, %548 : i64, !llvm.ptr
cf.br ^bb78
^bb78:
%549 = llvm.load %548 : !llvm.ptr -> i64
%550 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%551 = llvm.load %550 : !llvm.ptr -> i64
%552 = arith.cmpi slt, %549, %551 : i64
cf.cond_br %552, ^bb79, ^bb80
^bb79:
%554 = llvm.mlir.addressof @ZERO : !llvm.ptr
%555 = llvm.load %554 : !llvm.ptr -> !llvm.ptr
%556 = llvm.load %548 : !llvm.ptr -> i64
%557 = llvm.getelementptr %555[%556] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%553 = llvm.load %557 : !llvm.ptr -> i64
%558 = llvm.load %548 : !llvm.ptr -> i64
%559 = llvm.getelementptr %arg2[%558] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %553, %559 : i64, !llvm.ptr
%560 = llvm.load %548 : !llvm.ptr -> i64
%561 = arith.constant 1 : i32
%563 = arith.extsi %561 : i32 to i64
%562 = arith.addi %560, %563 : i64
llvm.store %562, %548 : i64, !llvm.ptr
cf.br ^bb78
^bb80:
%565 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%566 = llvm.load %565 : !llvm.ptr -> i64
%567 = arith.constant 8 : i32
%568 = arith.extsi %567 : i32 to i64
%564 = func.call @calloc(%566, %568) : (i64, i64) -> !llvm.ptr
%569 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%570 = llvm.load %569 : !llvm.ptr -> i64
%571 = arith.constant 1 : i32
%573 = arith.extsi %571 : i32 to i64
%572 = arith.subi %570, %573 : i64
llvm.store %572, %548 : i64, !llvm.ptr
cf.br ^bb81
^bb81:
%574 = llvm.load %548 : !llvm.ptr -> i64
%575 = arith.constant 0 : i32
%577 = arith.extsi %575 : i32 to i64
%576 = arith.cmpi sge, %574, %577 : i64
cf.cond_br %576, ^bb82, ^bb83
^bb82:
func.call @poly_mul(%arg2, %arg1, %564) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
%579 = arith.constant 0 : i32
%580 = arith.extsi %579 : i32 to i64
%581 = llvm.mlir.constant(1 : i64) : i64
%582 = llvm.alloca %581 x i64 : (i64) -> !llvm.ptr
llvm.store %580, %582 : i64, !llvm.ptr
cf.br ^bb84
^bb84:
%583 = llvm.load %582 : !llvm.ptr -> i64
%584 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%585 = llvm.load %584 : !llvm.ptr -> i64
%586 = arith.cmpi slt, %583, %585 : i64
cf.cond_br %586, ^bb85, ^bb86
^bb85:
%588 = llvm.load %582 : !llvm.ptr -> i64
%589 = llvm.getelementptr %564[%588] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%587 = llvm.load %589 : !llvm.ptr -> i64
%590 = llvm.load %582 : !llvm.ptr -> i64
%591 = llvm.getelementptr %arg2[%590] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %587, %591 : i64, !llvm.ptr
%592 = llvm.load %582 : !llvm.ptr -> i64
%593 = arith.constant 1 : i32
%595 = arith.extsi %593 : i32 to i64
%594 = arith.addi %592, %595 : i64
llvm.store %594, %582 : i64, !llvm.ptr
cf.br ^bb84
^bb86:
%597 = arith.constant 0 : i32
%598 = arith.extsi %597 : i32 to i64
%599 = llvm.getelementptr %arg2[%598] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%596 = llvm.load %599 : !llvm.ptr -> i64
%601 = llvm.load %548 : !llvm.ptr -> i64
%602 = llvm.getelementptr %arg0[%601] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%600 = llvm.load %602 : !llvm.ptr -> i64
%603 = arith.addi %596, %600 : i64
%604 = llvm.mlir.addressof @MOD : !llvm.ptr
%605 = llvm.load %604 : !llvm.ptr -> i64
%606 = arith.remsi %603, %605 : i64
%607 = arith.constant 0 : i32
%608 = arith.extsi %607 : i32 to i64
%609 = llvm.getelementptr %arg2[%608] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %606, %609 : i64, !llvm.ptr
%610 = llvm.load %548 : !llvm.ptr -> i64
%611 = arith.constant 1 : i32
%613 = arith.extsi %611 : i32 to i64
%612 = arith.subi %610, %613 : i64
llvm.store %612, %548 : i64, !llvm.ptr
cf.br ^bb81
^bb83:
func.call @free(%564) : (!llvm.ptr) -> ()
func.return
}
func.func @iterate_composition(%arg0: !llvm.ptr, %arg1: i64, %arg2: !llvm.ptr) -> () {
%615 = arith.constant 0 : i32
%616 = arith.extsi %615 : i32 to i64
%617 = llvm.mlir.constant(1 : i64) : i64
%618 = llvm.alloca %617 x i64 : (i64) -> !llvm.ptr
llvm.store %616, %618 : i64, !llvm.ptr
cf.br ^bb87
^bb87:
%619 = llvm.load %618 : !llvm.ptr -> i64
%620 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%621 = llvm.load %620 : !llvm.ptr -> i64
%622 = arith.cmpi slt, %619, %621 : i64
cf.cond_br %622, ^bb88, ^bb89
^bb88:
%624 = llvm.mlir.addressof @X : !llvm.ptr
%625 = llvm.load %624 : !llvm.ptr -> !llvm.ptr
%626 = llvm.load %618 : !llvm.ptr -> i64
%627 = llvm.getelementptr %625[%626] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%623 = llvm.load %627 : !llvm.ptr -> i64
%628 = llvm.load %618 : !llvm.ptr -> i64
%629 = llvm.getelementptr %arg2[%628] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %623, %629 : i64, !llvm.ptr
%630 = llvm.load %618 : !llvm.ptr -> i64
%631 = arith.constant 1 : i32
%633 = arith.extsi %631 : i32 to i64
%632 = arith.addi %630, %633 : i64
llvm.store %632, %618 : i64, !llvm.ptr
cf.br ^bb87
^bb89:
%635 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%636 = llvm.load %635 : !llvm.ptr -> i64
%637 = arith.constant 8 : i32
%638 = arith.extsi %637 : i32 to i64
%634 = func.call @calloc(%636, %638) : (i64, i64) -> !llvm.ptr
%640 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%641 = llvm.load %640 : !llvm.ptr -> i64
%642 = arith.constant 8 : i32
%643 = arith.extsi %642 : i32 to i64
%639 = func.call @calloc(%641, %643) : (i64, i64) -> !llvm.ptr
%644 = arith.constant 0 : i32
%645 = arith.extsi %644 : i32 to i64
llvm.store %645, %618 : i64, !llvm.ptr
cf.br ^bb90
^bb90:
%646 = llvm.load %618 : !llvm.ptr -> i64
%647 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%648 = llvm.load %647 : !llvm.ptr -> i64
%649 = arith.cmpi slt, %646, %648 : i64
cf.cond_br %649, ^bb91, ^bb92
^bb91:
%651 = llvm.load %618 : !llvm.ptr -> i64
%652 = llvm.getelementptr %arg0[%651] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%650 = llvm.load %652 : !llvm.ptr -> i64
%653 = llvm.load %618 : !llvm.ptr -> i64
%654 = llvm.getelementptr %634[%653] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %650, %654 : i64, !llvm.ptr
%655 = llvm.load %618 : !llvm.ptr -> i64
%656 = arith.constant 1 : i32
%658 = arith.extsi %656 : i32 to i64
%657 = arith.addi %655, %658 : i64
llvm.store %657, %618 : i64, !llvm.ptr
cf.br ^bb90
^bb92:
%659 = llvm.mlir.constant(1 : i64) : i64
%660 = llvm.alloca %659 x i64 : (i64) -> !llvm.ptr
llvm.store %arg1, %660 : i64, !llvm.ptr
cf.br ^bb93
^bb93:
%661 = llvm.load %660 : !llvm.ptr -> i64
%662 = arith.constant 0 : i32
%664 = arith.extsi %662 : i32 to i64
%663 = arith.cmpi ne, %661, %664 : i64
cf.cond_br %663, ^bb94, ^bb95
^bb94:
%665 = llvm.load %660 : !llvm.ptr -> i64
%666 = arith.constant 1 : i32
%668 = arith.extsi %666 : i32 to i64
%667 = arith.andi %665, %668 : i64
%669 = arith.constant 1 : i32
%671 = arith.extsi %669 : i32 to i64
%670 = arith.cmpi eq, %667, %671 : i64
cf.cond_br %670, ^bb96, ^bb97
^bb96:
func.call @poly_compose(%634, %arg2, %639) : (!llvm.ptr, !llvm.ptr, !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 ^bb99
^bb99:
%677 = llvm.load %676 : !llvm.ptr -> i64
%678 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%679 = llvm.load %678 : !llvm.ptr -> i64
%680 = arith.cmpi slt, %677, %679 : i64
cf.cond_br %680, ^bb100, ^bb101
^bb100:
%682 = llvm.load %676 : !llvm.ptr -> i64
%683 = llvm.getelementptr %639[%682] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%681 = llvm.load %683 : !llvm.ptr -> i64
%684 = llvm.load %676 : !llvm.ptr -> i64
%685 = llvm.getelementptr %arg2[%684] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %681, %685 : i64, !llvm.ptr
%686 = llvm.load %676 : !llvm.ptr -> i64
%687 = arith.constant 1 : i32
%689 = arith.extsi %687 : i32 to i64
%688 = arith.addi %686, %689 : i64
llvm.store %688, %676 : i64, !llvm.ptr
cf.br ^bb99
^bb101:
cf.br ^bb98
^bb97:
cf.br ^bb98
^bb98:
%690 = llvm.load %660 : !llvm.ptr -> i64
%691 = arith.constant 1 : i32
%693 = arith.extsi %691 : i32 to i64
%692 = arith.shrsi %690, %693 : i64
llvm.store %692, %660 : i64, !llvm.ptr
%694 = llvm.load %660 : !llvm.ptr -> i64
%695 = arith.constant 0 : i32
%697 = arith.extsi %695 : i32 to i64
%696 = arith.cmpi ne, %694, %697 : i64
cf.cond_br %696, ^bb102, ^bb103
^bb102:
func.call @poly_compose(%634, %634, %639) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
%699 = arith.constant 0 : i32
%700 = arith.extsi %699 : i32 to i64
%701 = llvm.mlir.constant(1 : i64) : i64
%702 = llvm.alloca %701 x i64 : (i64) -> !llvm.ptr
llvm.store %700, %702 : i64, !llvm.ptr
cf.br ^bb105
^bb105:
%703 = llvm.load %702 : !llvm.ptr -> i64
%704 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%705 = llvm.load %704 : !llvm.ptr -> i64
%706 = arith.cmpi slt, %703, %705 : i64
cf.cond_br %706, ^bb106, ^bb107
^bb106:
%708 = llvm.load %702 : !llvm.ptr -> i64
%709 = llvm.getelementptr %639[%708] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%707 = llvm.load %709 : !llvm.ptr -> i64
%710 = llvm.load %702 : !llvm.ptr -> i64
%711 = llvm.getelementptr %634[%710] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %707, %711 : i64, !llvm.ptr
%712 = llvm.load %702 : !llvm.ptr -> i64
%713 = arith.constant 1 : i32
%715 = arith.extsi %713 : i32 to i64
%714 = arith.addi %712, %715 : i64
llvm.store %714, %702 : i64, !llvm.ptr
cf.br ^bb105
^bb107:
cf.br ^bb104
^bb103:
cf.br ^bb104
^bb104:
cf.br ^bb93
^bb95:
func.call @free(%634) : (!llvm.ptr) -> ()
func.call @free(%639) : (!llvm.ptr) -> ()
func.return
}
func.func @d1(%arg0: i64, %arg1: !llvm.ptr) -> () {
%719 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%720 = llvm.load %719 : !llvm.ptr -> i64
%721 = arith.constant 8 : i32
%722 = arith.extsi %721 : i32 to i64
%718 = func.call @calloc(%720, %722) : (i64, i64) -> !llvm.ptr
%724 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%725 = llvm.load %724 : !llvm.ptr -> i64
%726 = arith.constant 8 : i32
%727 = arith.extsi %726 : i32 to i64
%723 = func.call @calloc(%725, %727) : (i64, i64) -> !llvm.ptr
%729 = llvm.mlir.addressof @X : !llvm.ptr
%730 = llvm.load %729 : !llvm.ptr -> !llvm.ptr
func.call @poly_pow(%730, %arg0, %718) : (!llvm.ptr, i64, !llvm.ptr) -> ()
func.call @mul_x(%718, %723) : (!llvm.ptr, !llvm.ptr) -> ()
func.call @poly_add(%718, %723, %arg1) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
func.call @free(%718) : (!llvm.ptr) -> ()
func.call @free(%723) : (!llvm.ptr) -> ()
func.return
}
func.func @d2(%arg0: i64, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> () {
%736 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%737 = llvm.load %736 : !llvm.ptr -> i64
%738 = arith.constant 8 : i32
%739 = arith.extsi %738 : i32 to i64
%735 = func.call @calloc(%737, %739) : (i64, i64) -> !llvm.ptr
%741 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%742 = llvm.load %741 : !llvm.ptr -> i64
%743 = arith.constant 8 : i32
%744 = arith.extsi %743 : i32 to i64
%740 = func.call @calloc(%742, %744) : (i64, i64) -> !llvm.ptr
func.call @iterate_composition(%arg1, %arg0, %735) : (!llvm.ptr, i64, !llvm.ptr) -> ()
func.call @mul_x(%arg1, %740) : (!llvm.ptr, !llvm.ptr) -> ()
func.call @poly_compose(%735, %740, %arg2) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
func.call @free(%735) : (!llvm.ptr) -> ()
func.call @free(%740) : (!llvm.ptr) -> ()
func.return
}
func.func @evaluate(%arg0: !llvm.ptr, %arg1: i64) -> i64 {
%750 = arith.constant 0 : i32
%751 = arith.extsi %750 : i32 to i64
%752 = llvm.mlir.constant(1 : i64) : i64
%753 = llvm.alloca %752 x i64 : (i64) -> !llvm.ptr
llvm.store %751, %753 : i64, !llvm.ptr
%754 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%755 = llvm.load %754 : !llvm.ptr -> i64
%756 = arith.constant 1 : i32
%758 = arith.extsi %756 : i32 to i64
%757 = arith.subi %755, %758 : i64
%759 = llvm.mlir.constant(1 : i64) : i64
%760 = llvm.alloca %759 x i64 : (i64) -> !llvm.ptr
llvm.store %757, %760 : i64, !llvm.ptr
cf.br ^bb108
^bb108:
%761 = llvm.load %760 : !llvm.ptr -> i64
%762 = arith.constant 0 : i32
%764 = arith.extsi %762 : i32 to i64
%763 = arith.cmpi sge, %761, %764 : i64
cf.cond_br %763, ^bb109, ^bb110
^bb109:
%765 = llvm.load %753 : !llvm.ptr -> i64
%766 = arith.muli %765, %arg1 : i64
%768 = llvm.load %760 : !llvm.ptr -> i64
%769 = llvm.getelementptr %arg0[%768] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%767 = llvm.load %769 : !llvm.ptr -> i64
%770 = arith.addi %766, %767 : i64
%771 = llvm.mlir.addressof @MOD : !llvm.ptr
%772 = llvm.load %771 : !llvm.ptr -> i64
%773 = arith.remsi %770, %772 : i64
llvm.store %773, %753 : i64, !llvm.ptr
%774 = llvm.load %760 : !llvm.ptr -> i64
%775 = arith.constant 1 : i32
%777 = arith.extsi %775 : i32 to i64
%776 = arith.subi %774, %777 : i64
llvm.store %776, %760 : i64, !llvm.ptr
cf.br ^bb108
^bb110:
%778 = llvm.load %753 : !llvm.ptr -> i64
func.return %778 : i64
}
func.func @main() -> i32 {
%780 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%781 = llvm.load %780 : !llvm.ptr -> i64
%782 = arith.constant 8 : i32
%783 = arith.extsi %782 : i32 to i64
%779 = func.call @calloc(%781, %783) : (i64, i64) -> !llvm.ptr
%784 = llvm.mlir.addressof @FOLD : !llvm.ptr
llvm.store %779, %784 : !llvm.ptr, !llvm.ptr
func.call @init_globals() : () -> ()
%786 = arith.constant 12 : i32
%787 = arith.extsi %786 : i32 to i64
%788 = arith.constant 345678 : i32
%789 = arith.extsi %788 : i32 to i64
%790 = arith.constant 9012345 : i32
%791 = arith.extsi %790 : i32 to i64
%792 = arith.constant 678 : i32
%793 = arith.extsi %792 : i32 to i64
%794 = arith.constant 90 : i32
%795 = arith.extsi %794 : i32 to i64
%797 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%798 = llvm.load %797 : !llvm.ptr -> i64
%799 = arith.constant 8 : i32
%800 = arith.extsi %799 : i32 to i64
%796 = func.call @calloc(%798, %800) : (i64, i64) -> !llvm.ptr
func.call @d1(%791, %796) : (i64, !llvm.ptr) -> ()
%803 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%804 = llvm.load %803 : !llvm.ptr -> i64
%805 = arith.constant 8 : i32
%806 = arith.extsi %805 : i32 to i64
%802 = func.call @calloc(%804, %806) : (i64, i64) -> !llvm.ptr
func.call @d2(%789, %796, %802) : (i64, !llvm.ptr, !llvm.ptr) -> ()
%809 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%810 = llvm.load %809 : !llvm.ptr -> i64
%811 = arith.constant 8 : i32
%812 = arith.extsi %811 : i32 to i64
%808 = func.call @calloc(%810, %812) : (i64, i64) -> !llvm.ptr
func.call @poly_compose(%796, %802, %808) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
%814 = arith.constant 0 : i32
%815 = arith.extsi %814 : i32 to i64
%816 = llvm.mlir.constant(1 : i64) : i64
%817 = llvm.alloca %816 x i64 : (i64) -> !llvm.ptr
llvm.store %815, %817 : i64, !llvm.ptr
cf.br ^bb111
^bb111:
%818 = llvm.load %817 : !llvm.ptr -> i64
%819 = arith.cmpi slt, %818, %787 : i64
cf.cond_br %819, ^bb112, ^bb113
^bb112:
%821 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%822 = llvm.load %821 : !llvm.ptr -> i64
%823 = arith.constant 8 : i32
%824 = arith.extsi %823 : i32 to i64
%820 = func.call @calloc(%822, %824) : (i64, i64) -> !llvm.ptr
func.call @d2(%789, %808, %820) : (i64, !llvm.ptr, !llvm.ptr) -> ()
%826 = arith.constant 0 : i32
%827 = arith.extsi %826 : i32 to i64
%828 = llvm.mlir.constant(1 : i64) : i64
%829 = llvm.alloca %828 x i64 : (i64) -> !llvm.ptr
llvm.store %827, %829 : i64, !llvm.ptr
cf.br ^bb114
^bb114:
%830 = llvm.load %829 : !llvm.ptr -> i64
%831 = llvm.mlir.addressof @DEGREE : !llvm.ptr
%832 = llvm.load %831 : !llvm.ptr -> i64
%833 = arith.cmpi slt, %830, %832 : i64
cf.cond_br %833, ^bb115, ^bb116
^bb115:
%835 = llvm.load %829 : !llvm.ptr -> i64
%836 = llvm.getelementptr %820[%835] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%834 = llvm.load %836 : !llvm.ptr -> i64
%837 = llvm.load %829 : !llvm.ptr -> i64
%838 = llvm.getelementptr %808[%837] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %834, %838 : i64, !llvm.ptr
%839 = llvm.load %829 : !llvm.ptr -> i64
%840 = arith.constant 1 : i32
%842 = arith.extsi %840 : i32 to i64
%841 = arith.addi %839, %842 : i64
llvm.store %841, %829 : i64, !llvm.ptr
cf.br ^bb114
^bb116:
func.call @free(%820) : (!llvm.ptr) -> ()
%844 = llvm.load %817 : !llvm.ptr -> i64
%845 = arith.constant 1 : i32
%847 = arith.extsi %845 : i32 to i64
%846 = arith.addi %844, %847 : i64
llvm.store %846, %817 : i64, !llvm.ptr
cf.br ^bb111
^bb113:
%848 = func.call @evaluate(%808, %793) : (!llvm.ptr, i64) -> i64
%849 = llvm.mlir.addressof @str_0 : !llvm.ptr
%850 = arith.addi %848, %795 : i64
%851 = llvm.mlir.addressof @MOD : !llvm.ptr
%852 = llvm.load %851 : !llvm.ptr -> i64
%853 = arith.remsi %850, %852 : i64
%854 = llvm.call @printf(%849, %853) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
%855 = arith.constant 0 : i32
func.return %855 : i32
}
}