Problem 751
Concatenation Coincidence: 24 decimals of theta.
View problem on Project Euler
Performance comparison
| Metric | Our solution | Best known |
| Time complexity | O(n^2) | O(n * m) |
| Space complexity | O(1) | O(n) |
| Approach | Flow solution | Dynamic programming or generating function |
| Verdict | Unknown |
Flow source
# Project Euler 751
# Concatenation Coincidence: 24 decimals of theta.
extern {
function calloc(n: i64, size: i64) -> ptr<void>
function free(p: ptr<void>) -> void
function floor(x: f64) -> f64
function strtod(s: ptr<i8>, endp: ptr<void>) -> f64
function strlen(s: ptr<i8>) -> i64
function strcmp(a: ptr<i8>, b: ptr<i8>) -> i32
}
# Write integer n as decimal string into buf at position pos.
# Returns new position.
function int_to_str(n: i32, buf: ptr<i8>, pos: i32) -> i32 {
if n == 0 {
buf[pos] = 48
return pos + 1
}
let mut digits: array<i8, 16>
let mut len: i32 = 0
let mut v: i32 = n
while v > 0 {
digits[len] = (48 + (v % 10)) as i8
len = len + 1
v = v / 10
}
let mut i: i32 = len - 1
while i >= 0 {
buf[pos] = digits[i]
pos = pos + 1
i = i - 1
}
return pos
}
# Build the sequence string from theta into out, up to `length` chars.
function sequence(theta: f64, length: i32, out: ptr<i8>) -> void {
let mut b1: f64 = theta
let mut pos: i32 = 0
pos = int_to_str(floor(b1) as i32, out, pos)
buf_set(out, pos, 46)
pos = pos + 1
while pos < length {
let floorb1: i32 = floor(b1) as i32
let bn: f64 = (floorb1 as f64) * (b1 - (floorb1 as f64) + 1.0)
pos = int_to_str(floor(bn) as i32, out, pos)
b1 = bn
}
buf_set(out, length, 0)
}
function buf_set(buf: ptr<i8>, idx: i32, val: i32) -> void {
buf[idx] = val as i8
}
function buf_get(buf: ptr<i8>, idx: i32) -> i32 {
return buf[idx] as i32
}
# Copy src into dst (null-terminated). Returns length.
function str_copy(dst: ptr<i8>, src: ptr<i8>) -> i32 {
let mut i: i32 = 0
while buf_get(src, i) != 0 {
buf_set(dst, i, buf_get(src, i))
i = i + 1
}
buf_set(dst, i, 0)
return i
}
# Append digit d to null-terminated string at dst. Returns new length.
function str_append_digit(dst: ptr<i8>, d: i32) -> i32 {
let mut i: i32 = 0
while buf_get(dst, i) != 0 {
i = i + 1
}
buf_set(dst, i, 48 + d)
buf_set(dst, i + 1, 0)
return i + 1
}
function main() -> i32 {
let curr: ptr<i8> = calloc(64, 1)
let temp: ptr<i8> = calloc(64, 1)
let seq: ptr<i8> = calloc(64, 1)
# Initialize curr = "2."
buf_set(curr, 0, 50)
buf_set(curr, 1, 46)
buf_set(curr, 2, 0)
let length: i32 = 26
while strlen(curr) < (length as i64) {
let mut found: i32 = 0 - 1
let mut x: i32 = 0
while x < 10 {
str_copy(temp, curr)
str_append_digit(temp, x)
let theta: f64 = strtod(temp, null)
sequence(theta, strlen(temp) as i32, seq)
if strcmp(temp, seq) == 0 {
found = x
break
}
x = x + 1
}
if found < 0 {
printf("fail\n")
free(curr)
free(temp)
free(seq)
return 1
}
str_append_digit(curr, found)
}
buf_set(curr, length, 0)
printf("%s\n", curr)
free(curr)
free(temp)
free(seq)
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 int_to_str_i32_ptr_i8_i32(int32_t n, int8_t* buf, int32_t pos);
void sequence_f64_i32_ptr_i8(double theta, int32_t length, int8_t* out);
void buf_set_ptr_i8_i32_i32(int8_t* buf, int32_t idx, int32_t val);
int32_t buf_get_ptr_i8_i32(int8_t* buf, int32_t idx);
int32_t str_copy_ptr_i8_ptr_i8(int8_t* dst, int8_t* src);
int32_t str_append_digit_ptr_i8_i32(int8_t* dst, int32_t d);
int32_t main(void);
int32_t int_to_str_i32_ptr_i8_i32(int32_t n, int8_t* buf, int32_t pos) {
if (n == 0) {
buf[pos] = 48;
return (pos + 1);
}
int8_t digits[16];
int32_t len = 0;
int32_t v = n;
while (v > 0) {
digits[len] = ((int8_t)((48 + FLOW_CHECKED_MOD((v), (10)))));
len = (len + 1);
v = FLOW_CHECKED_DIV((v), (10));
}
int32_t i = (len - 1);
while (i >= 0) {
buf[pos] = (((unsigned)(i) < 16) ? digits[i] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(i), 16), flow_fault_handler("array index out of bounds"), digits[0]));
pos = (pos + 1);
i = (i - 1);
}
return pos;
}
void sequence_f64_i32_ptr_i8(double theta, int32_t length, int8_t* out) {
double b1 = theta;
int32_t pos = 0;
pos = int_to_str_i32_ptr_i8_i32(((int32_t)(floor(b1))), out, pos);
buf_set_ptr_i8_i32_i32(out, pos, 46);
pos = (pos + 1);
while (pos < length) {
int32_t floorb1 = ((int32_t)(floor(b1)));
double bn = (((double)(floorb1)) * ((b1 - ((double)(floorb1))) + 1.0));
pos = int_to_str_i32_ptr_i8_i32(((int32_t)(floor(bn))), out, pos);
b1 = bn;
}
buf_set_ptr_i8_i32_i32(out, length, 0);
}
void buf_set_ptr_i8_i32_i32(int8_t* buf, int32_t idx, int32_t val) {
buf[idx] = ((int8_t)(val));
}
int32_t buf_get_ptr_i8_i32(int8_t* buf, int32_t idx) {
return ((int32_t)(buf[idx]));
}
int32_t str_copy_ptr_i8_ptr_i8(int8_t* dst, int8_t* src) {
int32_t i = 0;
while (buf_get_ptr_i8_i32(src, i) != 0) {
buf_set_ptr_i8_i32_i32(dst, i, buf_get_ptr_i8_i32(src, i));
i = (i + 1);
}
buf_set_ptr_i8_i32_i32(dst, i, 0);
return i;
}
int32_t str_append_digit_ptr_i8_i32(int8_t* dst, int32_t d) {
int32_t i = 0;
while (buf_get_ptr_i8_i32(dst, i) != 0) {
i = (i + 1);
}
buf_set_ptr_i8_i32_i32(dst, i, (48 + d));
buf_set_ptr_i8_i32_i32(dst, (i + 1), 0);
return (i + 1);
}
int32_t main(void) {
int8_t* curr = (int8_t*)(calloc(64, 1));
int8_t* temp = (int8_t*)(calloc(64, 1));
int8_t* seq = (int8_t*)(calloc(64, 1));
buf_set_ptr_i8_i32_i32(curr, 0, 50);
buf_set_ptr_i8_i32_i32(curr, 1, 46);
buf_set_ptr_i8_i32_i32(curr, 2, 0);
int32_t length = 26;
while (strlen(curr) < ((int64_t)(length))) {
int32_t found = (0 - 1);
int32_t x = 0;
while (x < 10) {
str_copy_ptr_i8_ptr_i8(temp, curr);
str_append_digit_ptr_i8_i32(temp, x);
double theta = strtod(temp, NULL);
sequence_f64_i32_ptr_i8(theta, ((int32_t)(strlen(temp))), seq);
if (strcmp(temp, seq) == 0) {
found = x;
break;
}
x = (x + 1);
}
if (found < 0) {
printf("fail\n");
free(curr);
free(temp);
free(seq);
return 1;
}
str_append_digit_ptr_i8_i32(curr, found);
}
buf_set_ptr_i8_i32_i32(curr, length, 0);
printf("%s\n", curr);
free(curr);
free(temp);
free(seq);
return 0;
}
Generated MLIR
module {
llvm.func @printf(!llvm.ptr, ...) -> i32
llvm.mlir.global internal constant @str_0("fail\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
llvm.mlir.global internal constant @str_1("%s\n\00") {addr_space = 0 : i32} : !llvm.array<4 x i8>
func.func private @calloc(i64, i64) -> !llvm.ptr
func.func private @free(!llvm.ptr) -> ()
func.func private @floor(f64) -> f64
func.func private @strtod(!llvm.ptr, !llvm.ptr) -> f64
func.func private @strlen(!llvm.ptr) -> i64
func.func private @strcmp(!llvm.ptr, !llvm.ptr) -> i32
func.func @int_to_str(%arg0: i32, %arg1: !llvm.ptr, %arg2: i32) -> i32 {
%0 = arith.constant 0 : i32
%1 = arith.cmpi eq, %arg0, %0 : i32
cf.cond_br %1, ^bb0, ^bb1
^bb0:
%2 = arith.constant 48 : i32
%3 = arith.trunci %2 : i32 to i8
%4 = arith.extsi %arg2 : i32 to i64
%5 = llvm.getelementptr %arg1[%4] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %3, %5 : i8, !llvm.ptr
%6 = arith.constant 1 : i32
%7 = arith.addi %arg2, %6 : i32
func.return %7 : i32
^bb1:
cf.br ^bb2
^bb2:
%8 = memref.alloca() {type = memref<16xi8>} : memref<16xi8>
%9 = arith.constant 0 : i32
%10 = llvm.mlir.constant(1 : i64) : i64
%11 = llvm.alloca %10 x i32 : (i64) -> !llvm.ptr
llvm.store %9, %11 : i32, !llvm.ptr
%12 = llvm.mlir.constant(1 : i64) : i64
%13 = llvm.alloca %12 x i32 : (i64) -> !llvm.ptr
llvm.store %arg0, %13 : i32, !llvm.ptr
cf.br ^bb3
^bb3:
%14 = llvm.load %13 : !llvm.ptr -> i32
%15 = arith.constant 0 : i32
%16 = arith.cmpi sgt, %14, %15 : i32
cf.cond_br %16, ^bb4, ^bb5
^bb4:
%17 = arith.constant 48 : i32
%18 = llvm.load %13 : !llvm.ptr -> i32
%19 = arith.constant 10 : i32
%20 = arith.remsi %18, %19 : i32
%21 = arith.addi %17, %20 : i32
%22 = arith.trunci %21 : i32 to i8
%23 = llvm.load %11 : !llvm.ptr -> i32
%24 = arith.index_cast %23 : i32 to index
memref.store %22, %8[%24] : memref<16xi8>
%25 = llvm.load %11 : !llvm.ptr -> i32
%26 = arith.constant 1 : i32
%27 = arith.addi %25, %26 : i32
llvm.store %27, %11 : i32, !llvm.ptr
%28 = llvm.load %13 : !llvm.ptr -> i32
%29 = arith.constant 10 : i32
%30 = arith.divsi %28, %29 : i32
llvm.store %30, %13 : i32, !llvm.ptr
cf.br ^bb3
^bb5:
%31 = llvm.load %11 : !llvm.ptr -> i32
%32 = arith.constant 1 : i32
%33 = arith.subi %31, %32 : i32
%34 = llvm.mlir.constant(1 : i64) : i64
%35 = llvm.alloca %34 x i32 : (i64) -> !llvm.ptr
llvm.store %33, %35 : i32, !llvm.ptr
cf.br ^bb6(%arg2 : i32)
^bb6(%36: i32):
%37 = llvm.load %35 : !llvm.ptr -> i32
%38 = arith.constant 0 : i32
%39 = arith.cmpi sge, %37, %38 : i32
cf.cond_br %39, ^bb7(%36 : i32), ^bb8(%36 : i32)
^bb7(%40: i32):
%42 = llvm.load %35 : !llvm.ptr -> i32
%43 = arith.index_cast %42 : i32 to index
%41 = memref.load %8[%43] : memref<16xi8>
%44 = arith.extsi %40 : i32 to i64
%45 = llvm.getelementptr %arg1[%44] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %41, %45 : i8, !llvm.ptr
%46 = arith.constant 1 : i32
%47 = arith.addi %40, %46 : i32
%48 = llvm.load %35 : !llvm.ptr -> i32
%49 = arith.constant 1 : i32
%50 = arith.subi %48, %49 : i32
llvm.store %50, %35 : i32, !llvm.ptr
cf.br ^bb6(%47 : i32)
^bb8(%51: i32):
func.return %51 : i32
}
func.func @sequence(%arg0: f64, %arg1: i32, %arg2: !llvm.ptr) -> () {
%52 = llvm.mlir.constant(1 : i64) : i64
%53 = llvm.alloca %52 x f64 : (i64) -> !llvm.ptr
llvm.store %arg0, %53 : f64, !llvm.ptr
%54 = arith.constant 0 : i32
%55 = llvm.mlir.constant(1 : i64) : i64
%56 = llvm.alloca %55 x i32 : (i64) -> !llvm.ptr
llvm.store %54, %56 : i32, !llvm.ptr
%59 = llvm.load %53 : !llvm.ptr -> f64
%58 = func.call @floor(%59) : (f64) -> f64
%60 = arith.fptosi %58 : f64 to i32
%61 = llvm.load %56 : !llvm.ptr -> i32
%57 = func.call @int_to_str(%60, %arg2, %61) : (i32, !llvm.ptr, i32) -> i32
llvm.store %57, %56 : i32, !llvm.ptr
%63 = llvm.load %56 : !llvm.ptr -> i32
%64 = arith.constant 46 : i32
func.call @buf_set(%arg2, %63, %64) : (!llvm.ptr, i32, i32) -> ()
%65 = llvm.load %56 : !llvm.ptr -> i32
%66 = arith.constant 1 : i32
%67 = arith.addi %65, %66 : i32
llvm.store %67, %56 : i32, !llvm.ptr
cf.br ^bb9
^bb9:
%68 = llvm.load %56 : !llvm.ptr -> i32
%69 = arith.cmpi slt, %68, %arg1 : i32
cf.cond_br %69, ^bb10, ^bb11
^bb10:
%71 = llvm.load %53 : !llvm.ptr -> f64
%70 = func.call @floor(%71) : (f64) -> f64
%72 = arith.fptosi %70 : f64 to i32
%73 = arith.sitofp %72 : i32 to f64
%74 = llvm.load %53 : !llvm.ptr -> f64
%75 = arith.sitofp %72 : i32 to f64
%76 = arith.subf %74, %75 : f64
%77 = arith.constant 1.0 : f32
%79 = arith.extf %77 : f32 to f64
%78 = arith.addf %76, %79 : f64
%80 = arith.mulf %73, %78 : f64
%82 = func.call @floor(%80) : (f64) -> f64
%83 = arith.fptosi %82 : f64 to i32
%84 = llvm.load %56 : !llvm.ptr -> i32
%81 = func.call @int_to_str(%83, %arg2, %84) : (i32, !llvm.ptr, i32) -> i32
llvm.store %81, %56 : i32, !llvm.ptr
llvm.store %80, %53 : f64, !llvm.ptr
cf.br ^bb9
^bb11:
%86 = arith.constant 0 : i32
func.call @buf_set(%arg2, %arg1, %86) : (!llvm.ptr, i32, i32) -> ()
func.return
}
func.func @buf_set(%arg0: !llvm.ptr, %arg1: i32, %arg2: i32) -> () {
%87 = arith.trunci %arg2 : i32 to i8
%88 = arith.extsi %arg1 : i32 to i64
%89 = llvm.getelementptr %arg0[%88] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.store %87, %89 : i8, !llvm.ptr
func.return
}
func.func @buf_get(%arg0: !llvm.ptr, %arg1: i32) -> i32 {
%91 = arith.extsi %arg1 : i32 to i64
%92 = llvm.getelementptr %arg0[%91] : (!llvm.ptr, i64) -> !llvm.ptr, i8
%90 = llvm.load %92 : !llvm.ptr -> i8
%93 = arith.extsi %90 : i8 to i32
func.return %93 : i32
}
func.func @str_copy(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> i32 {
%94 = arith.constant 0 : i32
%95 = llvm.mlir.constant(1 : i64) : i64
%96 = llvm.alloca %95 x i32 : (i64) -> !llvm.ptr
llvm.store %94, %96 : i32, !llvm.ptr
cf.br ^bb12
^bb12:
%98 = llvm.load %96 : !llvm.ptr -> i32
%97 = func.call @buf_get(%arg1, %98) : (!llvm.ptr, i32) -> i32
%99 = arith.constant 0 : i32
%100 = arith.cmpi ne, %97, %99 : i32
cf.cond_br %100, ^bb13, ^bb14
^bb13:
%102 = llvm.load %96 : !llvm.ptr -> i32
%104 = llvm.load %96 : !llvm.ptr -> i32
%103 = func.call @buf_get(%arg1, %104) : (!llvm.ptr, i32) -> i32
func.call @buf_set(%arg0, %102, %103) : (!llvm.ptr, i32, i32) -> ()
%105 = llvm.load %96 : !llvm.ptr -> i32
%106 = arith.constant 1 : i32
%107 = arith.addi %105, %106 : i32
llvm.store %107, %96 : i32, !llvm.ptr
cf.br ^bb12
^bb14:
%109 = llvm.load %96 : !llvm.ptr -> i32
%110 = arith.constant 0 : i32
func.call @buf_set(%arg0, %109, %110) : (!llvm.ptr, i32, i32) -> ()
%111 = llvm.load %96 : !llvm.ptr -> i32
func.return %111 : i32
}
func.func @str_append_digit(%arg0: !llvm.ptr, %arg1: i32) -> i32 {
%112 = arith.constant 0 : i32
%113 = llvm.mlir.constant(1 : i64) : i64
%114 = llvm.alloca %113 x i32 : (i64) -> !llvm.ptr
llvm.store %112, %114 : i32, !llvm.ptr
cf.br ^bb15
^bb15:
%116 = llvm.load %114 : !llvm.ptr -> i32
%115 = func.call @buf_get(%arg0, %116) : (!llvm.ptr, i32) -> i32
%117 = arith.constant 0 : i32
%118 = arith.cmpi ne, %115, %117 : i32
cf.cond_br %118, ^bb16, ^bb17
^bb16:
%119 = llvm.load %114 : !llvm.ptr -> i32
%120 = arith.constant 1 : i32
%121 = arith.addi %119, %120 : i32
llvm.store %121, %114 : i32, !llvm.ptr
cf.br ^bb15
^bb17:
%123 = llvm.load %114 : !llvm.ptr -> i32
%124 = arith.constant 48 : i32
%125 = arith.addi %124, %arg1 : i32
func.call @buf_set(%arg0, %123, %125) : (!llvm.ptr, i32, i32) -> ()
%127 = llvm.load %114 : !llvm.ptr -> i32
%128 = arith.constant 1 : i32
%129 = arith.addi %127, %128 : i32
%130 = arith.constant 0 : i32
func.call @buf_set(%arg0, %129, %130) : (!llvm.ptr, i32, i32) -> ()
%131 = llvm.load %114 : !llvm.ptr -> i32
%132 = arith.constant 1 : i32
%133 = arith.addi %131, %132 : i32
func.return %133 : i32
}
func.func @main() -> i32 {
%135 = arith.constant 64 : i32
%136 = arith.constant 1 : i32
%137 = arith.extsi %135 : i32 to i64
%138 = arith.extsi %136 : i32 to i64
%134 = func.call @calloc(%137, %138) : (i64, i64) -> !llvm.ptr
%140 = arith.constant 64 : i32
%141 = arith.constant 1 : i32
%142 = arith.extsi %140 : i32 to i64
%143 = arith.extsi %141 : i32 to i64
%139 = func.call @calloc(%142, %143) : (i64, i64) -> !llvm.ptr
%145 = arith.constant 64 : i32
%146 = arith.constant 1 : i32
%147 = arith.extsi %145 : i32 to i64
%148 = arith.extsi %146 : i32 to i64
%144 = func.call @calloc(%147, %148) : (i64, i64) -> !llvm.ptr
%150 = arith.constant 0 : i32
%151 = arith.constant 50 : i32
func.call @buf_set(%134, %150, %151) : (!llvm.ptr, i32, i32) -> ()
%153 = arith.constant 1 : i32
%154 = arith.constant 46 : i32
func.call @buf_set(%134, %153, %154) : (!llvm.ptr, i32, i32) -> ()
%156 = arith.constant 2 : i32
%157 = arith.constant 0 : i32
func.call @buf_set(%134, %156, %157) : (!llvm.ptr, i32, i32) -> ()
%158 = arith.constant 26 : i32
cf.br ^bb18
^bb18:
%159 = func.call @strlen(%134) : (!llvm.ptr) -> i64
%160 = arith.extsi %158 : i32 to i64
%161 = arith.cmpi slt, %159, %160 : i64
cf.cond_br %161, ^bb19, ^bb20
^bb19:
%162 = arith.constant 0 : i32
%163 = arith.constant 1 : i32
%164 = arith.subi %162, %163 : i32
%165 = llvm.mlir.constant(1 : i64) : i64
%166 = llvm.alloca %165 x i32 : (i64) -> !llvm.ptr
llvm.store %164, %166 : i32, !llvm.ptr
%167 = arith.constant 0 : i32
%168 = llvm.mlir.constant(1 : i64) : i64
%169 = llvm.alloca %168 x i32 : (i64) -> !llvm.ptr
llvm.store %167, %169 : i32, !llvm.ptr
cf.br ^bb21
^bb21:
%170 = llvm.load %169 : !llvm.ptr -> i32
%171 = arith.constant 10 : i32
%172 = arith.cmpi slt, %170, %171 : i32
cf.cond_br %172, ^bb22, ^bb23
^bb22:
%173 = func.call @str_copy(%139, %134) : (!llvm.ptr, !llvm.ptr) -> i32
%175 = llvm.load %169 : !llvm.ptr -> i32
%174 = func.call @str_append_digit(%139, %175) : (!llvm.ptr, i32) -> i32
%177 = llvm.mlir.zero : !llvm.ptr
%176 = func.call @strtod(%139, %177) : (!llvm.ptr, !llvm.ptr) -> f64
%179 = func.call @strlen(%139) : (!llvm.ptr) -> i64
%180 = arith.trunci %179 : i64 to i32
func.call @sequence(%176, %180, %144) : (f64, i32, !llvm.ptr) -> ()
%181 = func.call @strcmp(%139, %144) : (!llvm.ptr, !llvm.ptr) -> i32
%182 = arith.constant 0 : i32
%183 = arith.cmpi eq, %181, %182 : i32
cf.cond_br %183, ^bb24, ^bb25
^bb24:
%184 = llvm.load %169 : !llvm.ptr -> i32
llvm.store %184, %166 : i32, !llvm.ptr
cf.br ^bb23
^bb25:
cf.br ^bb26
^bb26:
%185 = llvm.load %169 : !llvm.ptr -> i32
%186 = arith.constant 1 : i32
%187 = arith.addi %185, %186 : i32
llvm.store %187, %169 : i32, !llvm.ptr
cf.br ^bb21
^bb23:
%188 = llvm.load %166 : !llvm.ptr -> i32
%189 = arith.constant 0 : i32
%190 = arith.cmpi slt, %188, %189 : i32
cf.cond_br %190, ^bb27, ^bb28
^bb27:
%191 = llvm.mlir.addressof @str_0 : !llvm.ptr
%192 = llvm.call @printf(%191) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr) -> i32
func.call @free(%134) : (!llvm.ptr) -> ()
func.call @free(%139) : (!llvm.ptr) -> ()
func.call @free(%144) : (!llvm.ptr) -> ()
%196 = arith.constant 1 : i32
func.return %196 : i32
^bb28:
cf.br ^bb29
^bb29:
%198 = llvm.load %166 : !llvm.ptr -> i32
%197 = func.call @str_append_digit(%134, %198) : (!llvm.ptr, i32) -> i32
cf.br ^bb18
^bb20:
%200 = arith.constant 0 : i32
func.call @buf_set(%134, %158, %200) : (!llvm.ptr, i32, i32) -> ()
%201 = llvm.mlir.addressof @str_1 : !llvm.ptr
%202 = llvm.call @printf(%201, %134) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, !llvm.ptr) -> i32
func.call @free(%134) : (!llvm.ptr) -> ()
func.call @free(%139) : (!llvm.ptr) -> ()
func.call @free(%144) : (!llvm.ptr) -> ()
%206 = arith.constant 0 : i32
func.return %206 : i32
}
}