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

%defs.point_class = type <{ i32 (...)**, %defs.point* }>
%defs.point = type {}
%defs.point2d_class = type <{ i32 (...)**, %defs.point2d* }>
%defs.point2d = type { %defs.point, float, float }

@_Name_point = private unnamed_addr constant [6 x i8] c"point\00", align 1
@_Type_Info_point = linkonce_odr unnamed_addr constant { i8*, i8*, i8* } { i8* getelementptr inbounds ([6 x i8], [6 x i8]* @_Name_point, i32 0, i32 0), i8* null, i8* null }, align 8
@_VTable_point = linkonce_odr unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_Type_Info_point to i8*), i8* bitcast (void (i8*, i8*)* @_copy_defs_point to i8*), i8* bitcast (void (i8**)* @_allocate_struct_defs_point to i8*), i8* null] }, align 8
@_Name_point2d = private unnamed_addr constant [8 x i8] c"point2d\00", align 1
@_Type_Info_point2d = linkonce_odr unnamed_addr constant { i8*, i8*, i8* } { i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_Name_point2d, i32 0, i32 0), i8* inttoptr (i64 8 to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_Type_Info_point to i8*) }, align 8
@_VTable_point2d = linkonce_odr unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_Type_Info_point2d to i8*), i8* bitcast (void (i8*, i8*)* @_copy_defs_point2d to i8*), i8* bitcast (void (i8**)* @_allocate_struct_defs_point2d to i8*), i8* bitcast (float (%defs.point2d_class*)* @__module_defs_r2d to i8*)] }, align 8
@"ERROR STOP" = private unnamed_addr constant [11 x i8] c"ERROR STOP\00", align 1
@0 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@1 = private unnamed_addr constant [5 x i8] c"%s%s\00", align 1

define float @__module_defs_r2d(%defs.point2d_class* %this) {
.entry:
  %r2d = alloca float, align 4
  %0 = getelementptr %defs.point2d_class, %defs.point2d_class* %this, i32 0, i32 1
  %1 = load %defs.point2d*, %defs.point2d** %0, align 8
  %2 = getelementptr %defs.point2d, %defs.point2d* %1, i32 0, i32 1
  %3 = load float, float* %2, align 4
  %simplified_pow_operation = fmul float %3, %3
  %4 = getelementptr %defs.point2d_class, %defs.point2d_class* %this, i32 0, i32 1
  %5 = load %defs.point2d*, %defs.point2d** %4, align 8
  %6 = getelementptr %defs.point2d, %defs.point2d* %5, i32 0, i32 2
  %7 = load float, float* %6, align 4
  %simplified_pow_operation1 = fmul float %7, %7
  %8 = fadd float %simplified_pow_operation, %simplified_pow_operation1
  %9 = call float @llvm.sqrt.f32(float %8)
  store float %9, float* %r2d, align 4
  br label %return

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

FINALIZE_SYMTABLE_r2d:                            ; preds = %return
  %10 = load float, float* %r2d, align 4
  ret float %10
}

; Function Attrs: nounwind readnone speculatable willreturn
declare float @llvm.sqrt.f32(float) #0

define i32 @main(i32 %0, i8** %1) {
.entry:
  %2 = call i8* @_lfortran_get_default_allocator()
  call void @_lpython_call_initial_functions(i32 %0, i8** %1)
  %p2d = alloca %defs.point2d, align 8
  %3 = getelementptr %defs.point2d, %defs.point2d* %p2d, i32 0, i32 1
  %4 = getelementptr %defs.point2d, %defs.point2d* %p2d, i32 0, i32 2
  %5 = getelementptr %defs.point2d, %defs.point2d* %p2d, i32 0, i32 0
  %ptr = alloca %defs.point_class*, align 8
  store %defs.point_class* null, %defs.point_class** %ptr, align 8
  %res = alloca float, align 4
  %6 = getelementptr %defs.point2d, %defs.point2d* %p2d, i32 0, i32 1
  store float 3.000000e+00, float* %6, align 4
  %7 = getelementptr %defs.point2d, %defs.point2d* %p2d, i32 0, i32 2
  store float 4.000000e+00, float* %7, align 4
  %8 = load %defs.point_class*, %defs.point_class** %ptr, align 8
  %9 = icmp eq %defs.point_class* %8, null
  br i1 %9, label %then, label %else

then:                                             ; preds = %.entry
  %10 = call i8* @_lfortran_get_default_allocator()
  %11 = call i8* @_lfortran_malloc_alloc(i8* %10, i64 16)
  call void @llvm.memset.p0i8.i32(i8* %11, i8 0, i32 16, i1 false)
  %12 = bitcast i8* %11 to %defs.point_class*
  store %defs.point_class* %12, %defs.point_class** %ptr, align 8
  br label %ifcont

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

ifcont:                                           ; preds = %else, %then
  %13 = load %defs.point_class*, %defs.point_class** %ptr, align 8
  %14 = bitcast %defs.point_class* %13 to i32 (...)***
  store i32 (...)** bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_VTable_point2d, i32 0, i32 0, i32 2) to i32 (...)**), i32 (...)*** %14, align 8
  %15 = getelementptr %defs.point_class, %defs.point_class* %13, i32 0, i32 1
  %16 = bitcast %defs.point2d* %p2d to %defs.point*
  store %defs.point* %16, %defs.point** %15, align 8
  %17 = load %defs.point_class*, %defs.point_class** %ptr, align 8
  %18 = bitcast %defs.point_class* %17 to float (%defs.point_class*)***
  %19 = load float (%defs.point_class*)**, float (%defs.point_class*)*** %18, align 8
  %20 = getelementptr inbounds float (%defs.point_class*)*, float (%defs.point_class*)** %19, i32 2
  %21 = load float (%defs.point_class*)*, float (%defs.point_class*)** %20, align 8
  %22 = call float %21(%defs.point_class* %17)
  store float %22, float* %res, align 4
  %23 = load float, float* %res, align 4
  %24 = fcmp une float %23, 5.000000e+00
  br i1 %24, label %then1, label %else2

then1:                                            ; preds = %ifcont
  call void (i8*, ...) @_lcompilers_print_error(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @1, 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]* @0, i32 0, i32 0))
  call void @_lfortran_internal_alloc_finalize()
  call void @exit(i32 1)
  br label %ifcont3

else2:                                            ; preds = %ifcont
  br label %ifcont3

ifcont3:                                          ; preds = %else2, %then1
  br label %return

return:                                           ; preds = %ifcont3
  br label %FINALIZE_SYMTABLE_main

FINALIZE_SYMTABLE_main:                           ; preds = %return
  br label %Finalize_Variable_ptr

Finalize_Variable_ptr:                            ; preds = %FINALIZE_SYMTABLE_main
  %25 = load %defs.point_class*, %defs.point_class** %ptr, align 8
  %26 = icmp ne %defs.point_class* %25, null
  br i1 %26, label %is_allocated.then, label %is_allocated.else

is_allocated.then:                                ; preds = %Finalize_Variable_ptr
  %27 = bitcast %defs.point_class* %25 to i8*
  call void @_lfortran_free_alloc(i8* %2, i8* %27)
  br label %is_allocated.ifcont

is_allocated.else:                                ; preds = %Finalize_Variable_ptr
  br label %is_allocated.ifcont

is_allocated.ifcont:                              ; preds = %is_allocated.else, %is_allocated.then
  call void @_lfortran_internal_alloc_finalize()
  ret i32 0
}

declare void @_lpython_call_initial_functions(i32, i8**)

declare i8* @_lfortran_malloc_alloc(i8*, i64)

declare i8* @_lfortran_get_default_allocator()

; Function Attrs: argmemonly nounwind willreturn writeonly
declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1 immarg) #1

define linkonce_odr void @_copy_defs_point(i8* %0, i8* %1) {
entry:
  %2 = bitcast i8* %0 to %defs.point*
  %3 = bitcast i8* %1 to %defs.point*
  ret void
}

define linkonce_odr void @_allocate_struct_defs_point(i8** %0) {
entry:
  %1 = call i8* @_lfortran_get_default_allocator()
  %2 = call i8* @_lfortran_malloc_alloc(i8* %1, i64 16)
  call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 16, i1 false)
  store i8* %2, i8** %0, align 8
  %3 = load i8*, i8** %0, align 8
  %4 = bitcast i8* %3 to %defs.point_class*
  %5 = bitcast %defs.point_class* %4 to i32 (...)***
  store i32 (...)** bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_VTable_point, i32 0, i32 0, i32 2) to i32 (...)**), i32 (...)*** %5, align 8
  %6 = getelementptr %defs.point_class, %defs.point_class* %4, i32 0, i32 1
  %7 = call i8* @_lfortran_get_default_allocator()
  %8 = call i8* @_lfortran_malloc_alloc(i8* %7, i64 0)
  call void @llvm.memset.p0i8.i32(i8* %8, i8 0, i32 0, i1 false)
  %9 = bitcast i8* %8 to %defs.point*
  store %defs.point* %9, %defs.point** %6, align 8
  ret void
}

define linkonce_odr void @_copy_defs_point2d(i8* %0, i8* %1) {
entry:
  %2 = bitcast i8* %0 to %defs.point2d*
  %3 = bitcast i8* %1 to %defs.point2d*
  %4 = getelementptr %defs.point2d, %defs.point2d* %2, i32 0, i32 1
  %5 = load float, float* %4, align 4
  %6 = getelementptr %defs.point2d, %defs.point2d* %3, i32 0, i32 1
  br i1 true, label %then, label %else

then:                                             ; preds = %entry
  store float %5, float* %6, align 4
  br label %ifcont

else:                                             ; preds = %entry
  br label %ifcont

ifcont:                                           ; preds = %else, %then
  %7 = getelementptr %defs.point2d, %defs.point2d* %2, i32 0, i32 2
  %8 = load float, float* %7, align 4
  %9 = getelementptr %defs.point2d, %defs.point2d* %3, i32 0, i32 2
  br i1 true, label %then1, label %else2

then1:                                            ; preds = %ifcont
  store float %8, float* %9, align 4
  br label %ifcont3

else2:                                            ; preds = %ifcont
  br label %ifcont3

ifcont3:                                          ; preds = %else2, %then1
  %10 = getelementptr %defs.point2d, %defs.point2d* %2, i32 0, i32 0
  %11 = getelementptr %defs.point2d, %defs.point2d* %3, i32 0, i32 0
  ret void
}

define linkonce_odr void @_allocate_struct_defs_point2d(i8** %0) {
entry:
  %1 = call i8* @_lfortran_get_default_allocator()
  %2 = call i8* @_lfortran_malloc_alloc(i8* %1, i64 16)
  call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 16, i1 false)
  store i8* %2, i8** %0, align 8
  %3 = load i8*, i8** %0, align 8
  %4 = bitcast i8* %3 to %defs.point2d_class*
  %5 = bitcast %defs.point2d_class* %4 to i32 (...)***
  store i32 (...)** bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_VTable_point2d, i32 0, i32 0, i32 2) to i32 (...)**), i32 (...)*** %5, align 8
  %6 = getelementptr %defs.point2d_class, %defs.point2d_class* %4, i32 0, i32 1
  %7 = call i8* @_lfortran_get_default_allocator()
  %8 = call i8* @_lfortran_malloc_alloc(i8* %7, i64 8)
  call void @llvm.memset.p0i8.i32(i8* %8, i8 0, i32 8, i1 false)
  %9 = bitcast i8* %8 to %defs.point2d*
  store %defs.point2d* %9, %defs.point2d** %6, align 8
  %10 = getelementptr %defs.point2d, %defs.point2d* %9, i32 0, i32 1
  %11 = getelementptr %defs.point2d, %defs.point2d* %9, i32 0, i32 2
  %12 = getelementptr %defs.point2d, %defs.point2d* %9, i32 0, i32 0
  ret void
}

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

declare void @_lfortran_internal_alloc_finalize()

declare void @exit(i32)

declare void @_lfortran_free_alloc(i8*, i8*)

attributes #0 = { nounwind readnone speculatable willreturn }
attributes #1 = { argmemonly nounwind willreturn writeonly }
