← All problems
Problem 315
Sam vs Max digital-root clocks for primes in [10^7, 2*10^7].
View problem on Project Euler
Performance comparison
Metric Our solution Best known
Time complexity O(n log n)?
Space complexity O(n)?
Approach Flow solution Not curated
Verdict Unknown
Flow source
# Project Euler 315
# Sam vs Max digital-root clocks for primes in [10^7, 2*10^7].
extern {
function calloc(n: i64, size: i64) -> ptr<void>
function free(p: ptr<void>) -> void
}
function popcnt(x0: i64) -> i32 {
let mut x: i64 = x0
let mut r: i32 = 0
while x > 0 {
x = x & (x - 1)
r = r + 1
}
return r
}
function digit_sum(x0: i64) -> i64 {
let mut x: i64 = x0
let mut r: i64 = 0
while x > 0 {
r = r + x % 10
x = x / 10
}
return r
}
function get_segments(x0: i64, seg: ptr<i64>) -> i64 {
let mut x: i64 = x0
let mut result: i64 = 0
let mut shift: i64 = 0
while x > 0 {
result = result | (seg[x % 10] << shift)
x = x / 10
shift = shift + 8
}
return result
}
function sam(x0: i64, seg: ptr<i64>, cache: ptr<i32>) -> i32 {
let mut x: i64 = x0
if x < 100 && cache[x] > 0 { return cache[x] }
let segments: i64 = get_segments(x, seg)
let mut result: i32 = 2 * popcnt(segments)
if x > 9 {
result = result + sam(digit_sum(x), seg, cache)
}
if x < 100 { cache[x] = result }
return result
}
function max_clock(x0: i64, prev: i64, seg: ptr<i64>) -> i32 {
let segments: i64 = get_segments(x0, seg)
let mut result: i32 = popcnt(segments ^ prev)
if x0 > 9 {
result = result + max_clock(digit_sum(x0), segments, seg)
} else {
result = result + popcnt(segments)
}
return result
}
function main() -> i32 {
let lo: i64 = 10000000
let hi: i64 = 20000000
let half: i64 = (hi >> 1) + 1
let sieve: ptr<i8> = calloc(half, 1)
let seg: ptr<i64> = calloc(10, 8)
let cache: ptr<i32> = calloc(100, 4)
if sieve == null || seg == null || cache == null { return 1 }
# segment bitmasks
seg[0] = 119; seg[1] = 36; seg[2] = 93; seg[3] = 109; seg[4] = 46
seg[5] = 107; seg[6] = 123; seg[7] = 39; seg[8] = 127; seg[9] = 111
for i in 0..half { sieve[i] = 1 }
sieve[0] = 0
let mut i: i64 = 1
while 2 * i * i < half {
if sieve[i] == 1 {
let mut current: i64 = 3 * i + 1
let step: i64 = 2 * i + 1
while current < half {
sieve[current] = 0
current = current + step
}
}
i = i + 1
}
let mut sum_sam: i64 = 0
let mut sum_max: i64 = 0
let mut p: i64 = lo
if p % 2 == 0 { p = p + 1 }
while p <= hi {
if sieve[p >> 1] == 1 {
sum_sam = sum_sam + (sam(p, seg, cache) as i64)
sum_max = sum_max + (max_clock(p, 0, seg) as i64)
}
p = p + 2
}
printf("%lld\n", sum_sam - sum_max)
free(sieve); free(seg); free(cache)
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; }
int32_t popcnt_i64(int64_t x0);
int64_t digit_sum_i64(int64_t x0);
int64_t get_segments_i64_ptr_i64(int64_t x0, int64_t* seg);
int32_t sam_i64_ptr_i64_ptr_i32(int64_t x0, int64_t* seg, int32_t* cache);
int32_t max_clock_i64_i64_ptr_i64(int64_t x0, int64_t prev, int64_t* seg);
int32_t main(void);
int32_t popcnt_i64(int64_t x0) {
int64_t x = x0;
int32_t r = 0;
while (x > 0) {
x = (x & (x - 1));
r = (r + 1);
}
return r;
}
int64_t digit_sum_i64(int64_t x0) {
int64_t x = x0;
int64_t r = 0;
while (x > 0) {
r = (r + FLOW_CHECKED_MOD((x), (10)));
x = FLOW_CHECKED_DIV((x), (10));
}
return r;
}
int64_t get_segments_i64_ptr_i64(int64_t x0, int64_t* seg) {
int64_t x = x0;
int64_t result = 0;
int64_t shift = 0;
while (x > 0) {
result = (result | FLOW_CHECKED_SHL((seg[FLOW_CHECKED_MOD((x), (10))]), (shift)));
x = FLOW_CHECKED_DIV((x), (10));
shift = (shift + 8);
}
return result;
}
int32_t sam_i64_ptr_i64_ptr_i32(int64_t x0, int64_t* seg, int32_t* cache) {
int64_t x = x0;
if ((x < 100 && cache[x] > 0)) {
return cache[x];
}
int64_t segments = get_segments_i64_ptr_i64(x, seg);
int32_t result = (2 * popcnt_i64(segments));
if (x > 9) {
result = (result + sam_i64_ptr_i64_ptr_i32(digit_sum_i64(x), seg, cache));
}
if (x < 100) {
cache[x] = result;
}
return result;
}
int32_t max_clock_i64_i64_ptr_i64(int64_t x0, int64_t prev, int64_t* seg) {
int64_t segments = get_segments_i64_ptr_i64(x0, seg);
int32_t result = popcnt_i64((segments ^ prev));
if (x0 > 9) {
result = (result + max_clock_i64_i64_ptr_i64(digit_sum_i64(x0), segments, seg));
} else {
result = (result + popcnt_i64(segments));
}
return result;
}
int32_t main(void) {
int64_t lo = 10000000;
int64_t hi = 20000000;
int64_t half = (FLOW_CHECKED_SHR((hi), (1)) + 1);
int8_t* sieve = (int8_t*)(calloc(half, 1));
int64_t* seg = (int64_t*)(calloc(10, 8));
int32_t* cache = (int32_t*)(calloc(100, 4));
if (((sieve == NULL || seg == NULL) || cache == NULL)) {
return 1;
}
seg[0] = 119;
seg[1] = 36;
seg[2] = 93;
seg[3] = 109;
seg[4] = 46;
seg[5] = 107;
seg[6] = 123;
seg[7] = 39;
seg[8] = 127;
seg[9] = 111;
int32_t __flow_step_1 = 1;
for (int32_t i = 0; (0 <= half) ? i < half : i > half; i += (0 <= half) ? 1 : -1) {
sieve[i] = 1;
}
sieve[0] = 0;
int64_t i = 1;
while (((2 * i) * i) < half) {
if (sieve[i] == 1) {
int64_t current = ((3 * i) + 1);
int64_t step = ((2 * i) + 1);
while (current < half) {
sieve[current] = 0;
current = (current + step);
}
}
i = (i + 1);
}
int64_t sum_sam = 0;
int64_t sum_max = 0;
int64_t p = lo;
if (FLOW_CHECKED_MOD((p), (2)) == 0) {
p = (p + 1);
}
while (p <= hi) {
if (sieve[FLOW_CHECKED_SHR((p), (1))] == 1) {
sum_sam = (sum_sam + ((int64_t)(sam_i64_ptr_i64_ptr_i32(p, seg, cache))));
sum_max = (sum_max + ((int64_t)(max_clock_i64_i64_ptr_i64(p, 0, seg))));
}
p = (p + 2);
}
printf("%lld\n", (sum_sam - sum_max));
free(sieve);
free(seg);
free(cache);
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 @popcnt(%arg0: i64) -> i32 {
%0 = llvm.mlir.constant(1 : i64) : i64
%1 = llvm.alloca %0 x i64 : (i64) -> !llvm.ptr
llvm.store %arg0, %1 : i64, !llvm.ptr
%2 = arith.constant 0 : i32
%3 = llvm.mlir.constant(1 : i64) : i64
%4 = llvm.alloca %3 x i32 : (i64) -> !llvm.ptr
llvm.store %2, %4 : i32, !llvm.ptr
cf.br ^bb0
^bb0:
%5 = llvm.load %1 : !llvm.ptr -> i64
%6 = arith.constant 0 : i32
%8 = arith.extsi %6 : i32 to i64
%7 = arith.cmpi sgt, %5, %8 : i64
cf.cond_br %7, ^bb1, ^bb2
^bb1:
%9 = llvm.load %1 : !llvm.ptr -> i64
%10 = llvm.load %1 : !llvm.ptr -> i64
%11 = arith.constant 1 : i32
%13 = arith.extsi %11 : i32 to i64
%12 = arith.subi %10, %13 : i64
%14 = arith.andi %9, %12 : i64
llvm.store %14, %1 : i64, !llvm.ptr
%15 = llvm.load %4 : !llvm.ptr -> i32
%16 = arith.constant 1 : i32
%17 = arith.addi %15, %16 : i32
llvm.store %17, %4 : i32, !llvm.ptr
cf.br ^bb0
^bb2:
%18 = llvm.load %4 : !llvm.ptr -> i32
func.return %18 : i32
}
func.func @digit_sum(%arg0: i64) -> i64 {
%19 = llvm.mlir.constant(1 : i64) : i64
%20 = llvm.alloca %19 x i64 : (i64) -> !llvm.ptr
llvm.store %arg0, %20 : i64, !llvm.ptr
%21 = arith.constant 0 : i32
%22 = arith.extsi %21 : i32 to i64
%23 = llvm.mlir.constant(1 : i64) : i64
%24 = llvm.alloca %23 x i64 : (i64) -> !llvm.ptr
llvm.store %22, %24 : i64, !llvm.ptr
cf.br ^bb3
^bb3:
%25 = llvm.load %20 : !llvm.ptr -> i64
%26 = arith.constant 0 : i32
%28 = arith.extsi %26 : i32 to i64
%27 = arith.cmpi sgt, %25, %28 : i64
cf.cond_br %27, ^bb4, ^bb5
^bb4:
%29 = llvm.load %24 : !llvm.ptr -> i64
%30 = llvm.load %20 : !llvm.ptr -> i64
%31 = arith.constant 10 : i32
%33 = arith.extsi %31 : i32 to i64
%32 = arith.remsi %30, %33 : i64
%34 = arith.addi %29, %32 : i64
llvm.store %34, %24 : i64, !llvm.ptr
%35 = llvm.load %20 : !llvm.ptr -> i64
%36 = arith.constant 10 : i32
%38 = arith.extsi %36 : i32 to i64
%37 = arith.divsi %35, %38 : i64
llvm.store %37, %20 : i64, !llvm.ptr
cf.br ^bb3
^bb5:
%39 = llvm.load %24 : !llvm.ptr -> i64
func.return %39 : i64
}
func.func @get_segments(%arg0: i64, %arg1: !llvm.ptr) -> i64 {
%40 = llvm.mlir.constant(1 : i64) : i64
%41 = llvm.alloca %40 x i64 : (i64) -> !llvm.ptr
llvm.store %arg0, %41 : i64, !llvm.ptr
%42 = arith.constant 0 : i32
%43 = arith.extsi %42 : i32 to i64
%44 = llvm.mlir.constant(1 : i64) : i64
%45 = llvm.alloca %44 x i64 : (i64) -> !llvm.ptr
llvm.store %43, %45 : i64, !llvm.ptr
%46 = arith.constant 0 : i32
%47 = arith.extsi %46 : i32 to i64
%48 = llvm.mlir.constant(1 : i64) : i64
%49 = llvm.alloca %48 x i64 : (i64) -> !llvm.ptr
llvm.store %47, %49 : i64, !llvm.ptr
cf.br ^bb6
^bb6:
%50 = llvm.load %41 : !llvm.ptr -> i64
%51 = arith.constant 0 : i32
%53 = arith.extsi %51 : i32 to i64
%52 = arith.cmpi sgt, %50, %53 : i64
cf.cond_br %52, ^bb7, ^bb8
^bb7:
%54 = llvm.load %45 : !llvm.ptr -> i64
%56 = llvm.load %41 : !llvm.ptr -> i64
%57 = arith.constant 10 : i32
%59 = arith.extsi %57 : i32 to i64
%58 = arith.remsi %56, %59 : i64
%60 = llvm.getelementptr %arg1[%58] : (!llvm.ptr, i64) -> !llvm.ptr, i64
%55 = llvm.load %60 : !llvm.ptr -> i64
%61 = llvm.load %49 : !llvm.ptr -> i64
%62 = arith.shli %55, %61 : i64
%63 = arith.ori %54, %62 : i64
llvm.store %63, %45 : i64, !llvm.ptr
%64 = llvm.load %41 : !llvm.ptr -> i64
%65 = arith.constant 10 : i32
%67 = arith.extsi %65 : i32 to i64
%66 = arith.divsi %64, %67 : i64
llvm.store %66, %41 : i64, !llvm.ptr
%68 = llvm.load %49 : !llvm.ptr -> i64
%69 = arith.constant 8 : i32
%71 = arith.extsi %69 : i32 to i64
%70 = arith.addi %68, %71 : i64
llvm.store %70, %49 : i64, !llvm.ptr
cf.br ^bb6
^bb8:
%72 = llvm.load %45 : !llvm.ptr -> i64
func.return %72 : i64
}
func.func @sam(%arg0: i64, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
%73 = llvm.mlir.constant(1 : i64) : i64
%74 = llvm.alloca %73 x i64 : (i64) -> !llvm.ptr
llvm.store %arg0, %74 : i64, !llvm.ptr
%75 = llvm.load %74 : !llvm.ptr -> i64
%76 = arith.constant 100 : i32
%78 = arith.extsi %76 : i32 to i64
%77 = arith.cmpi slt, %75, %78 : i64
%79 = scf.if %77 -> (i1) {
%81 = llvm.load %74 : !llvm.ptr -> i64
%82 = llvm.getelementptr %arg2[%81] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%80 = llvm.load %82 : !llvm.ptr -> i32
%83 = arith.constant 0 : i32
%84 = arith.cmpi sgt, %80, %83 : i32
scf.yield %84 : i1
} else {
%85 = arith.constant false
scf.yield %85 : i1
}
cf.cond_br %79, ^bb9, ^bb10
^bb9:
%87 = llvm.load %74 : !llvm.ptr -> i64
%88 = llvm.getelementptr %arg2[%87] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%86 = llvm.load %88 : !llvm.ptr -> i32
func.return %86 : i32
^bb10:
cf.br ^bb11
^bb11:
%90 = llvm.load %74 : !llvm.ptr -> i64
%89 = func.call @get_segments(%90, %arg1) : (i64, !llvm.ptr) -> i64
%91 = arith.constant 2 : i32
%92 = func.call @popcnt(%89) : (i64) -> i32
%93 = arith.muli %91, %92 : i32
%94 = llvm.mlir.constant(1 : i64) : i64
%95 = llvm.alloca %94 x i32 : (i64) -> !llvm.ptr
llvm.store %93, %95 : i32, !llvm.ptr
%96 = llvm.load %74 : !llvm.ptr -> i64
%97 = arith.constant 9 : i32
%99 = arith.extsi %97 : i32 to i64
%98 = arith.cmpi sgt, %96, %99 : i64
cf.cond_br %98, ^bb12, ^bb13
^bb12:
%100 = llvm.load %95 : !llvm.ptr -> i32
%103 = llvm.load %74 : !llvm.ptr -> i64
%102 = func.call @digit_sum(%103) : (i64) -> i64
%101 = func.call @sam(%102, %arg1, %arg2) : (i64, !llvm.ptr, !llvm.ptr) -> i32
%104 = arith.addi %100, %101 : i32
llvm.store %104, %95 : i32, !llvm.ptr
cf.br ^bb14
^bb13:
cf.br ^bb14
^bb14:
%105 = llvm.load %74 : !llvm.ptr -> i64
%106 = arith.constant 100 : i32
%108 = arith.extsi %106 : i32 to i64
%107 = arith.cmpi slt, %105, %108 : i64
cf.cond_br %107, ^bb15, ^bb16
^bb15:
%109 = llvm.load %95 : !llvm.ptr -> i32
%110 = llvm.load %74 : !llvm.ptr -> i64
%111 = llvm.getelementptr %arg2[%110] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %109, %111 : i32, !llvm.ptr
cf.br ^bb17
^bb16:
cf.br ^bb17
^bb17:
%112 = llvm.load %95 : !llvm.ptr -> i32
func.return %112 : i32
}
func.func @max_clock(%arg0: i64, %arg1: i64, %arg2: !llvm.ptr) -> i32 {
%113 = func.call @get_segments(%arg0, %arg2) : (i64, !llvm.ptr) -> i64
%115 = arith.xori %113, %arg1 : i64
%114 = func.call @popcnt(%115) : (i64) -> i32
%116 = llvm.mlir.constant(1 : i64) : i64
%117 = llvm.alloca %116 x i32 : (i64) -> !llvm.ptr
llvm.store %114, %117 : i32, !llvm.ptr
%118 = arith.constant 9 : i32
%120 = arith.extsi %118 : i32 to i64
%119 = arith.cmpi sgt, %arg0, %120 : i64
cf.cond_br %119, ^bb18, ^bb19
^bb18:
%121 = llvm.load %117 : !llvm.ptr -> i32
%123 = func.call @digit_sum(%arg0) : (i64) -> i64
%122 = func.call @max_clock(%123, %113, %arg2) : (i64, i64, !llvm.ptr) -> i32
%124 = arith.addi %121, %122 : i32
llvm.store %124, %117 : i32, !llvm.ptr
cf.br ^bb20
^bb19:
%125 = llvm.load %117 : !llvm.ptr -> i32
%126 = func.call @popcnt(%113) : (i64) -> i32
%127 = arith.addi %125, %126 : i32
llvm.store %127, %117 : i32, !llvm.ptr
cf.br ^bb20
^bb20:
%128 = llvm.load %117 : !llvm.ptr -> i32
func.return %128 : i32
}
func.func @main() -> i32 {
%129 = arith.constant 10000000 : i32
%130 = arith.extsi %129 : i32 to i64
%131 = arith.constant 20000000 : i32
%132 = arith.extsi %131 : i32 to i64
%133 = arith.constant 1 : i32
%135 = arith.extsi %133 : i32 to i64
%134 = arith.shrsi %132, %135 : i64
%136 = arith.constant 1 : i32
%138 = arith.extsi %136 : i32 to i64
%137 = arith.addi %134, %138 : i64
%140 = arith.constant 1 : i32
%141 = arith.extsi %140 : i32 to i64
%139 = func.call @calloc(%137, %141) : (i64, i64) -> !llvm.ptr
%143 = arith.constant 10 : i32
%144 = arith.constant 8 : i32
%145 = arith.extsi %143 : i32 to i64
%146 = arith.extsi %144 : i32 to i64
%142 = func.call @calloc(%145, %146) : (i64, i64) -> !llvm.ptr
%148 = arith.constant 100 : i32
%149 = arith.constant 4 : i32
%150 = arith.extsi %148 : i32 to i64
%151 = arith.extsi %149 : i32 to i64
%147 = func.call @calloc(%150, %151) : (i64, i64) -> !llvm.ptr
%152 = llvm.mlir.zero : !llvm.ptr
%153 = llvm.icmp "eq" %139, %152 : !llvm.ptr
%154 = scf.if %153 -> (i1) {
%155 = arith.constant true
scf.yield %155 : i1
} else {
%156 = llvm.mlir.zero : !llvm.ptr
%157 = llvm.icmp "eq" %142, %156 : !llvm.ptr
scf.yield %157 : i1
}
%158 = scf.if %154 -> (i1) {
%159 = arith.constant true
scf.yield %159 : i1
} else {
%160 = llvm.mlir.zero : !llvm.ptr
%161 = llvm.icmp "eq" %147, %160 : !llvm.ptr
scf.yield %161 : i1
}
cf.cond_br %158, ^bb21, ^bb22
^bb21:
%162 = arith.constant 1 : i32
func.return %162 : i32
^bb22:
cf.br ^bb23
^bb23:
%163 = arith.constant 119 : i32
%164 = arith.constant 0 : i32
%165 = arith.extsi %163 : i32 to i64
%166 = arith.extsi %164 : i32 to i64
%167 = llvm.getelementptr %142[%166] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %165, %167 : i64, !llvm.ptr
%168 = arith.constant 36 : i32
%169 = arith.constant 1 : i32
%170 = arith.extsi %168 : i32 to i64
%171 = arith.extsi %169 : i32 to i64
%172 = llvm.getelementptr %142[%171] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %170, %172 : i64, !llvm.ptr
%173 = arith.constant 93 : i32
%174 = arith.constant 2 : i32
%175 = arith.extsi %173 : i32 to i64
%176 = arith.extsi %174 : i32 to i64
%177 = llvm.getelementptr %142[%176] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %175, %177 : i64, !llvm.ptr
%178 = arith.constant 109 : i32
%179 = arith.constant 3 : i32
%180 = arith.extsi %178 : i32 to i64
%181 = arith.extsi %179 : i32 to i64
%182 = llvm.getelementptr %142[%181] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %180, %182 : i64, !llvm.ptr
%183 = arith.constant 46 : i32
%184 = arith.constant 4 : i32
%185 = arith.extsi %183 : i32 to i64
%186 = arith.extsi %184 : i32 to i64
%187 = llvm.getelementptr %142[%186] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %185, %187 : i64, !llvm.ptr
%188 = arith.constant 107 : i32
%189 = arith.constant 5 : i32
%190 = arith.extsi %188 : i32 to i64
%191 = arith.extsi %189 : i32 to i64
%192 = llvm.getelementptr %142[%191] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %190, %192 : i64, !llvm.ptr
%193 = arith.constant 123 : i32
%194 = arith.constant 6 : i32
%195 = arith.extsi %193 : i32 to i64
%196 = arith.extsi %194 : i32 to i64
%197 = llvm.getelementptr %142[%196] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %195, %197 : i64, !llvm.ptr
%198 = arith.constant 39 : i32
%199 = arith.constant 7 : i32
%200 = arith.extsi %198 : i32 to i64
%201 = arith.extsi %199 : i32 to i64
%202 = llvm.getelementptr %142[%201] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %200, %202 : i64, !llvm.ptr
%203 = arith.constant 127 : i32
%204 = arith.constant 8 : i32
%205 = arith.extsi %203 : i32 to i64
%206 = arith.extsi %204 : i32 to i64
%207 = llvm.getelementptr %142[%206] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %205, %207 : i64, !llvm.ptr
%208 = arith.constant 111 : i32
%209 = arith.constant 9 : i32
%210 = arith.extsi %208 : i32 to i64
%211 = arith.extsi %209 : i32 to i64
%212 = llvm.getelementptr %142[%211] : (!llvm.ptr, i64) -> !llvm.ptr, i64
llvm.store %210, %212 : i64, !llvm.ptr
%213 = arith.constant 0 : i32
%214 = arith.index_cast %213 : i32 to index
%215 = arith.index_cast %137 : i32 to index
%217 = arith.constant 1 : index
%218 = arith.constant -1 : index
%219 = arith.cmpi sle, %214, %215 : index
%216 = arith.select %219, %217, %218 : index
cf.br ^bb24(%214 : index)
^bb24(%220: index):
%221 = arith.cmpi slt, %220, %215 : index
%222 = arith.cmpi sgt, %220, %215 : index
%223 = arith.select %219, %221, %222 : i1
cf.cond_br %223, ^bb25(%220 : index), ^bb26(%220 : index)
^bb25(%224: index):
%225 = arith.constant 1 : i32
%226 = arith.trunci %225 : i32 to i8
%227 = arith.index_cast %224 : index to i64
%228 = llvm.getelementptr %139[%227] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %226, %228 : i8, !llvm.ptr
%229 = arith.addi %224, %216 : index
cf.br ^bb24(%229 : index)
^bb26(%230: index):
%231 = arith.constant 0 : i32
%232 = arith.constant 0 : i32
%233 = arith.trunci %231 : i32 to i8
%234 = arith.extsi %232 : i32 to i64
%235 = llvm.getelementptr %139[%234] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %233, %235 : i8, !llvm.ptr
%236 = arith.constant 1 : i32
%237 = arith.extsi %236 : i32 to i64
%238 = llvm.mlir.constant(1 : i64) : i64
%239 = llvm.alloca %238 x i64 : (i64) -> !llvm.ptr
llvm.store %237, %239 : i64, !llvm.ptr
cf.br ^bb27
^bb27:
%240 = arith.constant 2 : i32
%241 = llvm.load %239 : !llvm.ptr -> i64
%243 = arith.extsi %240 : i32 to i64
%242 = arith.muli %243, %241 : i64
%244 = llvm.load %239 : !llvm.ptr -> i64
%245 = arith.muli %242, %244 : i64
%246 = arith.cmpi slt, %245, %137 : i64
cf.cond_br %246, ^bb28, ^bb29
^bb28:
%248 = llvm.load %239 : !llvm.ptr -> i64
%249 = llvm.getelementptr %139[%248] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%247 = llvm.load %249 : !llvm.ptr -> i8
%250 = arith.constant 1 : i32
%252 = arith.extsi %247 : i8 to i32
%251 = arith.cmpi eq, %252, %250 : i32
cf.cond_br %251, ^bb30, ^bb31
^bb30:
%253 = arith.constant 3 : i32
%254 = llvm.load %239 : !llvm.ptr -> i64
%256 = arith.extsi %253 : i32 to i64
%255 = arith.muli %256, %254 : i64
%257 = arith.constant 1 : i32
%259 = arith.extsi %257 : i32 to i64
%258 = arith.addi %255, %259 : i64
%260 = llvm.mlir.constant(1 : i64) : i64
%261 = llvm.alloca %260 x i64 : (i64) -> !llvm.ptr
llvm.store %258, %261 : i64, !llvm.ptr
%262 = arith.constant 2 : i32
%263 = llvm.load %239 : !llvm.ptr -> i64
%265 = arith.extsi %262 : i32 to i64
%264 = arith.muli %265, %263 : i64
%266 = arith.constant 1 : i32
%268 = arith.extsi %266 : i32 to i64
%267 = arith.addi %264, %268 : i64
cf.br ^bb33
^bb33:
%269 = llvm.load %261 : !llvm.ptr -> i64
%270 = arith.cmpi slt, %269, %137 : i64
cf.cond_br %270, ^bb34, ^bb35
^bb34:
%271 = arith.constant 0 : i32
%272 = llvm.load %261 : !llvm.ptr -> i64
%273 = arith.trunci %271 : i32 to i8
%274 = llvm.getelementptr %139[%272] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %273, %274 : i8, !llvm.ptr
%275 = llvm.load %261 : !llvm.ptr -> i64
%276 = arith.addi %275, %267 : i64
llvm.store %276, %261 : i64, !llvm.ptr
cf.br ^bb33
^bb35:
cf.br ^bb32
^bb31:
cf.br ^bb32
^bb32:
%277 = llvm.load %239 : !llvm.ptr -> i64
%278 = arith.constant 1 : i32
%280 = arith.extsi %278 : i32 to i64
%279 = arith.addi %277, %280 : i64
llvm.store %279, %239 : i64, !llvm.ptr
cf.br ^bb27
^bb29:
%281 = arith.constant 0 : i32
%282 = arith.extsi %281 : i32 to i64
%283 = llvm.mlir.constant(1 : i64) : i64
%284 = llvm.alloca %283 x i64 : (i64) -> !llvm.ptr
llvm.store %282, %284 : i64, !llvm.ptr
%285 = arith.constant 0 : i32
%286 = arith.extsi %285 : i32 to i64
%287 = llvm.mlir.constant(1 : i64) : i64
%288 = llvm.alloca %287 x i64 : (i64) -> !llvm.ptr
llvm.store %286, %288 : i64, !llvm.ptr
%289 = llvm.mlir.constant(1 : i64) : i64
%290 = llvm.alloca %289 x i64 : (i64) -> !llvm.ptr
llvm.store %130, %290 : i64, !llvm.ptr
%291 = llvm.load %290 : !llvm.ptr -> i64
%292 = arith.constant 2 : i32
%294 = arith.extsi %292 : i32 to i64
%293 = arith.remsi %291, %294 : i64
%295 = arith.constant 0 : i32
%297 = arith.extsi %295 : i32 to i64
%296 = arith.cmpi eq, %293, %297 : i64
cf.cond_br %296, ^bb36, ^bb37
^bb36:
%298 = llvm.load %290 : !llvm.ptr -> i64
%299 = arith.constant 1 : i32
%301 = arith.extsi %299 : i32 to i64
%300 = arith.addi %298, %301 : i64
llvm.store %300, %290 : i64, !llvm.ptr
cf.br ^bb38
^bb37:
cf.br ^bb38
^bb38:
cf.br ^bb39
^bb39:
%302 = llvm.load %290 : !llvm.ptr -> i64
%303 = arith.cmpi sle, %302, %132 : i64
cf.cond_br %303, ^bb40, ^bb41
^bb40:
%305 = llvm.load %290 : !llvm.ptr -> i64
%306 = arith.constant 1 : i32
%308 = arith.extsi %306 : i32 to i64
%307 = arith.shrsi %305, %308 : i64
%309 = llvm.getelementptr %139[%307] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%304 = llvm.load %309 : !llvm.ptr -> i8
%310 = arith.constant 1 : i32
%312 = arith.extsi %304 : i8 to i32
%311 = arith.cmpi eq, %312, %310 : i32
cf.cond_br %311, ^bb42, ^bb43
^bb42:
%313 = llvm.load %284 : !llvm.ptr -> i64
%315 = llvm.load %290 : !llvm.ptr -> i64
%314 = func.call @sam(%315, %142, %147) : (i64, !llvm.ptr, !llvm.ptr) -> i32
%316 = arith.extsi %314 : i32 to i64
%317 = arith.addi %313, %316 : i64
llvm.store %317, %284 : i64, !llvm.ptr
%318 = llvm.load %288 : !llvm.ptr -> i64
%320 = llvm.load %290 : !llvm.ptr -> i64
%321 = arith.constant 0 : i32
%322 = arith.extsi %321 : i32 to i64
%319 = func.call @max_clock(%320, %322, %142) : (i64, i64, !llvm.ptr) -> i32
%323 = arith.extsi %319 : i32 to i64
%324 = arith.addi %318, %323 : i64
llvm.store %324, %288 : i64, !llvm.ptr
cf.br ^bb44
^bb43:
cf.br ^bb44
^bb44:
%325 = llvm.load %290 : !llvm.ptr -> i64
%326 = arith.constant 2 : i32
%328 = arith.extsi %326 : i32 to i64
%327 = arith.addi %325, %328 : i64
llvm.store %327, %290 : i64, !llvm.ptr
cf.br ^bb39
^bb41:
%329 = llvm.mlir.addressof @str_0 : !llvm.ptr
%330 = llvm.load %284 : !llvm.ptr -> i64
%331 = llvm.load %288 : !llvm.ptr -> i64
%332 = arith.subi %330, %331 : i64
%333 = llvm.call @printf(%329, %332) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
func.call @free(%139) : (!llvm.ptr) -> ()
func.call @free(%142) : (!llvm.ptr) -> ()
func.call @free(%147) : (!llvm.ptr) -> ()
%337 = arith.constant 0 : i32
func.return %337 : i32
}
}