target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

declare noalias i8* @malloc(i64)

define i8* @__add(i8* %lft, i8* %rgt)
{
    %lft_len = call i64 @__strlen(i8* %lft)
    %rgt_len = call i64 @__strlen(i8* %rgt)
    %new_len = add i64 %lft_len, %rgt_len

    %res = call i8* @malloc(i64 %new_len)
    ; todo: copy lft
    ; todo: copy rgt
    ; todo: set 0 byte
    ret i8* %res
}

define i64 @__strlen(i8* %str)
{
start:
    br label %loop_start

loop_start:
    %i.0 = phi i64 [0, %start], [%i.new, %loop]
    %c_adr = getelementptr i8, i8* %str, i64 %i.0
    %c = load i8, i8* %c_adr
    %done = icmp eq i8 %c, 0
    br i1 %done, label %exit, label %loop

loop:
    %i.new = add i64 %i.0, 1
    br label %loop_start

exit:
    ret i64 %i.0
}

define i8* @__mapgetkey(i8* %mapname, i8* %key, i8* %def)
{
    ; todo
    ret i8* %def
}

define i8* @addstringchar(i8* %0, i8* %1)
{
    ; todo
    ret i8* %0
}

define i8* @registerid(i8* %id_id)
{
    %id_idname = call i8* @__mapgetkey(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @str.01, i64 0, i64 0), i8* %id_id, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @str.011, i64 0, i64 0))
    %1 = call i64 @__strlen(i8* %id_idname)
    %11 = icmp ne i64 %1, 0
    br i1 %11, label %lbl1, label %lbl11
lbl1:
        ret i8* %id_idname
lbl11:
    %id_idnamea = call i8* @__add(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @str.0111, i64 0, i64 0), i8* %id_id)
    ret i8* %id_idnamea
}

define i64 @main() {
    %res = call i64 @__strlen(i8* @str.01)
    ret i64 %res
}

@str.01 = internal constant [11 x i8] c"REGISTERID\00"
@str.011 = internal constant [0 x i8] c""
@str.0111 = internal constant [3 x i8] c"id_"
