; ModuleID = 'LFortran'
source_filename = "LFortran"
target datalayout = "..."

%string_descriptor = type <{ i8*, i64 }>

@0 = private unnamed_addr constant [2 x i8] c" \00", align 1
@1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@string_const_data = private constant [4 x i8] c"(g0)"
@string_const = private global %string_descriptor <{ i8* getelementptr inbounds ([4 x i8], [4 x i8]* @string_const_data, i32 0, i32 0), i64 4 }>
@serialization_info = private unnamed_addr constant [3 x i8] c"R8\00", align 1
@2 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
@__Wrong_allocation = private unnamed_addr constant [51 x i8] c"Attempting to allocate already allocated variable!\00", align 1
@string_const_data.1 = private constant [1 x i8] c" "
@string_const.2 = private global %string_descriptor <{ i8* getelementptr inbounds ([1 x i8], [1 x i8]* @string_const_data.1, i32 0, i32 0), i64 1 }>
@3 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@serialization_info.3 = private unnamed_addr constant [7 x i8] c"S-DESC\00", align 1
@4 = private unnamed_addr constant [5 x i8] c"%s%s\00", align 1
@string_const_data.4 = private constant [18 x i8] c"10.000000000000000"
@string_const.5 = private global %string_descriptor <{ i8* getelementptr inbounds ([18 x i8], [18 x i8]* @string_const_data.4, i32 0, i32 0), i64 18 }>
@"ERROR STOP" = private unnamed_addr constant [11 x i8] c"ERROR STOP\00", align 1
@5 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@6 = private unnamed_addr constant [5 x i8] c"%s%s\00", align 1

define i32 @_lcompilers_len_trim_str(%string_descriptor* %str) {
.entry:
  %StringItem = alloca %string_descriptor, align 8
  %result = alloca i32, align 4
  %0 = getelementptr %string_descriptor, %string_descriptor* %str, i32 0, i32 1
  %1 = load i64, i64* %0, align 8
  %2 = trunc i64 %1 to i32
  store i32 %2, i32* %result, align 4
  %3 = load i32, i32* %result, align 4
  %4 = icmp ne i32 %3, 0
  br i1 %4, label %then, label %else2

then:                                             ; preds = %.entry
  br label %loop.head

loop.head:                                        ; preds = %ifcont, %then
  %5 = load i32, i32* %result, align 4
  %6 = getelementptr %string_descriptor, %string_descriptor* %str, i32 0, i32 0
  %7 = load i8*, i8** %6, align 8
  %8 = sext i32 %5 to i64
  %9 = sub i64 %8, 1
  %10 = getelementptr i8, i8* %7, i64 %9
  %11 = getelementptr %string_descriptor, %string_descriptor* %StringItem, i32 0, i32 0
  store i8* %10, i8** %11, align 8
  %12 = getelementptr %string_descriptor, %string_descriptor* %StringItem, i32 0, i32 1
  store i64 1, i64* %12, align 8
  %13 = getelementptr %string_descriptor, %string_descriptor* %StringItem, i32 0, i32 0
  %14 = load i8*, i8** %13, align 8
  %15 = load i8*, i8** getelementptr inbounds (%string_descriptor, %string_descriptor* @string_const.2, i32 0, i32 0), align 8
  %16 = load i8, i8* %14, align 1
  %17 = load i8, i8* %15, align 1
  %18 = icmp eq i8 %16, %17
  br i1 %18, label %loop.body, label %loop.end

loop.body:                                        ; preds = %loop.head
  %19 = load i32, i32* %result, align 4
  %20 = sub i32 %19, 1
  store i32 %20, i32* %result, align 4
  %21 = load i32, i32* %result, align 4
  %22 = icmp eq i32 %21, 0
  br i1 %22, label %then1, label %else

then1:                                            ; preds = %loop.body
  br label %loop.end

unreachable_after_exit:                           ; No predecessors!
  br label %ifcont

else:                                             ; preds = %loop.body
  br label %ifcont

ifcont:                                           ; preds = %else, %unreachable_after_exit
  br label %loop.head

loop.end:                                         ; preds = %then1, %loop.head
  br label %ifcont3

else2:                                            ; preds = %.entry
  br label %ifcont3

ifcont3:                                          ; preds = %else2, %loop.end
  br label %return

return:                                           ; preds = %ifcont3
  br label %FINALIZE_SYMTABLE__lcompilers_len_trim_str

FINALIZE_SYMTABLE__lcompilers_len_trim_str:       ; preds = %return
  %23 = load i32, i32* %result, align 4
  ret i32 %23
}

define void @_lcompilers_trim_str(%string_descriptor* %str, %string_descriptor* %result) {
.entry:
  %0 = call i8* @_lfortran_get_default_allocator()
  %StrSlice_StrView = alloca %string_descriptor, align 8
  %1 = call i32 @_lcompilers_len_trim_str(%string_descriptor* %str)
  %2 = sext i32 %1 to i64
  %3 = sub i64 %2, 1
  %4 = add i64 %3, 1
  %5 = icmp slt i64 %4, 0
  %6 = select i1 %5, i64 0, i64 %4
  %7 = getelementptr %string_descriptor, %string_descriptor* %str, i32 0, i32 0
  %8 = load i8*, i8** %7, align 8
  %StrSliceGEP = getelementptr i8, i8* %8, i64 0
  %9 = getelementptr %string_descriptor, %string_descriptor* %StrSlice_StrView, i32 0, i32 0
  store i8* %StrSliceGEP, i8** %9, align 8
  %10 = getelementptr %string_descriptor, %string_descriptor* %StrSlice_StrView, i32 0, i32 1
  store i64 %6, i64* %10, align 8
  %11 = getelementptr %string_descriptor, %string_descriptor* %result, i32 0, i32 0
  %12 = getelementptr %string_descriptor, %string_descriptor* %result, i32 0, i32 1
  %13 = getelementptr %string_descriptor, %string_descriptor* %StrSlice_StrView, i32 0, i32 0
  %14 = load i8*, i8** %13, align 8
  %15 = getelementptr %string_descriptor, %string_descriptor* %StrSlice_StrView, i32 0, i32 1
  %16 = load i64, i64* %15, align 8
  call void @_lfortran_strcpy_alloc(i8* %0, i8** %11, i64* %12, i8 0, i8 0, i8* %14, i64 %16, i32 1)
  br label %return

return:                                           ; preds = %.entry
  br label %FINALIZE_SYMTABLE__lcompilers_trim_str

FINALIZE_SYMTABLE__lcompilers_trim_str:           ; preds = %return
  ret void
}

define void @__module_testdrive_derived_types_32_real_dp_to_string(double* %val, %string_descriptor* %string) {
.entry:
  %stringFormat_desc = alloca %string_descriptor, align 8
  %0 = call i8* @_lfortran_get_default_allocator()
  %lfortran_iomsg = alloca %string_descriptor, align 8
  %buffer = alloca %string_descriptor, align 8
  %__libasr__created__var__2_return_slot = alloca %string_descriptor, align 8
  store %string_descriptor zeroinitializer, %string_descriptor* %__libasr__created__var__2_return_slot, align 1
  store %string_descriptor zeroinitializer, %string_descriptor* %buffer, align 1
  %1 = getelementptr %string_descriptor, %string_descriptor* %buffer, i32 0, i32 1
  store i64 128, i64* %1, align 8
  %2 = getelementptr %string_descriptor, %string_descriptor* %buffer, i32 0, i32 0
  %3 = call i8* @_lfortran_get_default_allocator()
  %4 = call i8* @_lfortran_malloc_alloc(i8* %3, i64 128)
  store i8* %4, i8** %2, align 8
  %buffer_len = alloca i32, align 4
  store i32 128, i32* %buffer_len, align 4
  store %string_descriptor zeroinitializer, %string_descriptor* %lfortran_iomsg, align 1
  %5 = getelementptr %string_descriptor, %string_descriptor* %lfortran_iomsg, i32 0, i32 1
  store i64 0, i64* %5, align 8
  %6 = getelementptr %string_descriptor, %string_descriptor* %lfortran_iomsg, i32 0, i32 0
  %7 = call i8* @_lfortran_get_default_allocator()
  %8 = call i8* @_lfortran_malloc_alloc(i8* %7, i64 1)
  store i8* %8, i8** %6, align 8
  %9 = load %string_descriptor, %string_descriptor* %string, align 1
  %10 = getelementptr %string_descriptor, %string_descriptor* %string, i32 0, i32 0
  %11 = load i8*, i8** %10, align 8
  %12 = icmp ne i8* %11, null
  br i1 %12, label %then, label %else

then:                                             ; preds = %.entry
  %13 = getelementptr %string_descriptor, %string_descriptor* %string, i32 0, i32 0
  %14 = getelementptr %string_descriptor, %string_descriptor* %string, i32 0, i32 1
  %15 = load i8*, i8** %13, align 8
  call void @_lfortran_free_alloc(i8* %0, i8* %15)
  store i8* null, i8** %13, align 8
  store i64 0, i64* %14, align 8
  br label %ifcont

else:                                             ; preds = %.entry
  br label %ifcont

ifcont:                                           ; preds = %else, %then
  %16 = getelementptr %string_descriptor, %string_descriptor* %buffer, i32 0, i32 0
  %17 = getelementptr %string_descriptor, %string_descriptor* %buffer, i32 0, i32 1
  %18 = alloca i32*, align 8
  store i32* null, i32** %18, align 8
  %19 = load i32*, i32** %18, align 8
  %20 = load i8*, i8** getelementptr inbounds (%string_descriptor, %string_descriptor* @string_const, i32 0, i32 0), align 8
  %21 = alloca i64, align 8
  %22 = call i8* (i8*, i8*, i64, i8*, i64*, i32, i32, i32, i32, i32, ...) @_lcompilers_string_format_fortran(i8* %0, i8* %20, i64 4, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @serialization_info, i32 0, i32 0), i64* %21, i32 0, i32 0, i32 0, i32 0, i32 0, double* %val)
  %23 = load i64, i64* %21, align 8
  %24 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 0
  store i8* %22, i8** %24, align 8
  %25 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 1
  store i64 %23, i64* %25, align 8
  %26 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 0
  %27 = load i8*, i8** %26, align 8
  %28 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 1
  %29 = load i64, i64* %28, align 8
  call void (i8*, i8**, i8, i8, i8, i64, i64*, i32*, i8*, i64, ...) @_lfortran_string_write(i8* %0, i8** %16, i8 0, i8 0, i8 0, i64 1, i64* %17, i32* %19, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @2, i32 0, i32 0), i64 2, i8* %27, i64 %29)
  %30 = icmp eq i8* %22, null
  br i1 %30, label %free_done, label %free_nonnull

free_nonnull:                                     ; preds = %ifcont
  call void @_lfortran_free_alloc(i8* %0, i8* %22)
  br label %free_done

free_done:                                        ; preds = %free_nonnull, %ifcont
  %31 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 0
  %32 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 1
  %33 = load i8*, i8** %31, align 8
  call void @_lfortran_free_alloc(i8* %0, i8* %33)
  store i8* null, i8** %31, align 8
  store i64 0, i64* %32, align 8
  %34 = call i32 @_lcompilers_len_trim_str(%string_descriptor* %buffer)
  %35 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 0
  %36 = load i8*, i8** %35, align 8
  %37 = icmp ne i8* %36, null
  br i1 %37, label %then1, label %else2

then1:                                            ; preds = %free_done
  call void (i8*, ...) @_lcompilers_print_error(i8* getelementptr inbounds ([51 x i8], [51 x i8]* @__Wrong_allocation, i32 0, i32 0))
  call void @exit(i32 1)
  br label %ifcont3

else2:                                            ; preds = %free_done
  br label %ifcont3

ifcont3:                                          ; preds = %else2, %then1
  %38 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 0
  %39 = sext i32 %34 to i64
  %40 = call i8* @_lfortran_get_default_allocator()
  %41 = call i8* @_lfortran_string_malloc_alloc(i8* %40, i64 %39)
  store i8* %41, i8** %38, align 8
  %42 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 1
  %43 = sext i32 %34 to i64
  store i64 %43, i64* %42, align 8
  call void @_lcompilers_trim_str(%string_descriptor* %buffer, %string_descriptor* %__libasr__created__var__2_return_slot)
  %44 = getelementptr %string_descriptor, %string_descriptor* %string, i32 0, i32 0
  %45 = getelementptr %string_descriptor, %string_descriptor* %string, i32 0, i32 1
  %46 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 0
  %47 = load i8*, i8** %46, align 8
  %48 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 1
  %49 = load i64, i64* %48, align 8
  call void @_lfortran_strcpy_alloc(i8* %0, i8** %44, i64* %45, i8 1, i8 1, i8* %47, i64 %49, i32 1)
  br label %return

return:                                           ; preds = %ifcont3
  br label %FINALIZE_SYMTABLE_real_dp_to_string

FINALIZE_SYMTABLE_real_dp_to_string:              ; preds = %return
  br label %Finalize_Variable___libasr__created__var__2_return_slot

Finalize_Variable___libasr__created__var__2_return_slot: ; preds = %FINALIZE_SYMTABLE_real_dp_to_string
  %50 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__2_return_slot, i32 0, i32 0
  %51 = load i8*, i8** %50, align 8
  call void @_lfortran_free_alloc(i8* %0, i8* %51)
  br label %Finalize_Variable_buffer

Finalize_Variable_buffer:                         ; preds = %Finalize_Variable___libasr__created__var__2_return_slot
  %52 = getelementptr %string_descriptor, %string_descriptor* %buffer, i32 0, i32 0
  %53 = load i8*, i8** %52, align 8
  call void @_lfortran_free_alloc(i8* %0, i8* %53)
  br label %Finalize_Variable_lfortran_iomsg

Finalize_Variable_lfortran_iomsg:                 ; preds = %Finalize_Variable_buffer
  %54 = getelementptr %string_descriptor, %string_descriptor* %lfortran_iomsg, i32 0, i32 0
  %55 = load i8*, i8** %54, align 8
  call void @_lfortran_free_alloc(i8* %0, i8* %55)
  ret void
}

declare i8* @_lfortran_malloc_alloc(i8*, i64)

declare i8* @_lfortran_get_default_allocator()

declare void @_lfortran_free_alloc(i8*, i8*)

declare i8* @_lcompilers_string_format_fortran(i8*, i8*, i64, i8*, i64*, i32, i32, i32, i32, i32, ...)

declare void @_lfortran_string_write(i8*, i8**, i8, i8, i8, i64, i64*, i32*, i8*, i64, ...)

declare void @_lcompilers_print_error(i8*, ...)

declare void @exit(i32)

declare i8* @_lfortran_string_malloc_alloc(i8*, i64)

declare void @_lfortran_strcpy_alloc(i8*, i8**, i64*, i8, i8, i8*, i64, i32)

define i32 @main(i32 %0, i8** %1) {
.entry:
  %stringFormat_desc = alloca %string_descriptor, align 8
  %2 = call i8* @_lfortran_get_default_allocator()
  %__libasr__created__var__1_return_slot = alloca %string_descriptor, align 8
  %__libasr__created__var__0_return_slot = alloca %string_descriptor, align 8
  call void @_lpython_call_initial_functions(i32 %0, i8** %1)
  store %string_descriptor zeroinitializer, %string_descriptor* %__libasr__created__var__0_return_slot, align 1
  store %string_descriptor zeroinitializer, %string_descriptor* %__libasr__created__var__1_return_slot, align 1
  %value = alloca double, align 8
  store double 1.000000e+01, double* %value, align 8
  %3 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__0_return_slot, i32 0, i32 0
  %4 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__0_return_slot, i32 0, i32 1
  %5 = load i8*, i8** %3, align 8
  call void @_lfortran_free_alloc(i8* %2, i8* %5)
  store i8* null, i8** %3, align 8
  store i64 0, i64* %4, align 8
  call void @__module_testdrive_derived_types_32_real_dp_to_string(double* %value, %string_descriptor* %__libasr__created__var__0_return_slot)
  %6 = alloca i64, align 8
  %7 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__0_return_slot, i32 0, i32 1
  %8 = load i64, i64* %7, align 8
  %9 = load %string_descriptor, %string_descriptor* %__libasr__created__var__0_return_slot, align 1
  %10 = alloca %string_descriptor, align 8
  store %string_descriptor %9, %string_descriptor* %10, align 1
  %11 = call i8* (i8*, i8*, i64, i8*, i64*, i32, i32, i32, i32, i32, ...) @_lcompilers_string_format_fortran(i8* %2, i8* null, i64 0, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @serialization_info.3, i32 0, i32 0), i64* %6, i32 0, i32 1, i32 0, i32 0, i32 0, i64 %8, %string_descriptor* %10)
  %12 = load i64, i64* %6, align 8
  %13 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 0
  store i8* %11, i8** %13, align 8
  %14 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 1
  store i64 %12, i64* %14, align 8
  %15 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 0
  %16 = load i8*, i8** %15, align 8
  %17 = getelementptr %string_descriptor, %string_descriptor* %stringFormat_desc, i32 0, i32 1
  %18 = load i64, i64* %17, align 8
  %19 = trunc i64 %18 to i32
  call void @_lfortran_printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @4, i32 0, i32 0), i8* %16, i32 %19, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @3, i32 0, i32 0), i32 1)
  %20 = icmp eq i8* %11, null
  br i1 %20, label %free_done, label %free_nonnull

free_nonnull:                                     ; preds = %.entry
  call void @_lfortran_free_alloc(i8* %2, i8* %11)
  br label %free_done

free_done:                                        ; preds = %free_nonnull, %.entry
  %21 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__1_return_slot, i32 0, i32 0
  %22 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__1_return_slot, i32 0, i32 1
  %23 = load i8*, i8** %21, align 8
  call void @_lfortran_free_alloc(i8* %2, i8* %23)
  store i8* null, i8** %21, align 8
  store i64 0, i64* %22, align 8
  call void @__module_testdrive_derived_types_32_real_dp_to_string(double* %value, %string_descriptor* %__libasr__created__var__1_return_slot)
  %24 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__1_return_slot, i32 0, i32 0
  %25 = load i8*, i8** %24, align 8
  %26 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__1_return_slot, i32 0, i32 1
  %27 = load i64, i64* %26, align 8
  %28 = load i8*, i8** getelementptr inbounds (%string_descriptor, %string_descriptor* @string_const.5, i32 0, i32 0), align 8
  %29 = call i32 @str_compare(i8* %25, i64 %27, i8* %28, i64 18)
  %30 = icmp ne i32 %29, 0
  br i1 %30, label %then, label %else

then:                                             ; preds = %free_done
  call void (i8*, ...) @_lcompilers_print_error(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @6, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"ERROR STOP", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @5, i32 0, i32 0))
  call void @_lfortran_internal_alloc_finalize()
  call void @exit(i32 1)
  br label %ifcont

else:                                             ; preds = %free_done
  br label %ifcont

ifcont:                                           ; preds = %else, %then
  br label %return

return:                                           ; preds = %ifcont
  br label %FINALIZE_SYMTABLE_main

FINALIZE_SYMTABLE_main:                           ; preds = %return
  br label %Finalize_Variable___libasr__created__var__0_return_slot

Finalize_Variable___libasr__created__var__0_return_slot: ; preds = %FINALIZE_SYMTABLE_main
  %31 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__0_return_slot, i32 0, i32 0
  %32 = load i8*, i8** %31, align 8
  call void @_lfortran_free_alloc(i8* %2, i8* %32)
  br label %Finalize_Variable___libasr__created__var__1_return_slot

Finalize_Variable___libasr__created__var__1_return_slot: ; preds = %Finalize_Variable___libasr__created__var__0_return_slot
  %33 = getelementptr %string_descriptor, %string_descriptor* %__libasr__created__var__1_return_slot, i32 0, i32 0
  %34 = load i8*, i8** %33, align 8
  call void @_lfortran_free_alloc(i8* %2, i8* %34)
  call void @_lfortran_internal_alloc_finalize()
  ret i32 0
}

declare void @_lpython_call_initial_functions(i32, i8**)

declare void @_lfortran_printf(i8*, i8*, i32, i8*, i32)

declare i32 @str_compare(i8*, i64, i8*, i64)

declare void @_lfortran_internal_alloc_finalize()
