; LLVM IR from erthink/libmdbx :: src (api-range-estimate)

; Unoptimized IR (clang -disable-llvm-passes):
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.libmdbx_globals = type { %union.bin128, i32, i32, i8, i8, i8, i8, i32, %union.logger_union, %union.pthread_mutex_t, i64, ptr }
%union.bin128 = type { %struct.anon }
%struct.anon = type { i64, i64 }
%union.logger_union = type { ptr }
%union.pthread_mutex_t = type { %struct.__pthread_mutex_s }
%struct.__pthread_mutex_s = type { i32, i32, i32, i32, i32, i16, i16, %struct.__pthread_internal_list }
%struct.__pthread_internal_list = type { ptr, ptr }
%struct.diff_result = type { i64, i64, i64 }
%struct.MDBX_cursor = type { i32, %union.anon, i8, i8, ptr, ptr, ptr, ptr, ptr, [32 x ptr], [32 x i16], ptr, ptr }
%union.anon = type { i16 }
%struct.MDBX_txn = type { i32, i32, i64, i64, ptr, ptr, %struct.geo, i64, i64, ptr, ptr, ptr, ptr, ptr, ptr, %struct.MDBX_canary, ptr, %union.anon.4 }
%struct.geo = type { i16, i16, i32, i32, %union.anon.2, %union.anon.3 }
%union.anon.2 = type { i32 }
%union.anon.3 = type { i32 }
%struct.MDBX_canary = type { i64, i64, i64, i64 }
%union.anon.4 = type { %struct.anon.6 }
%struct.anon.6 = type { %struct.troika, ptr, %struct.anon.7, i8, i32, i32, i64, ptr, ptr, ptr, i64, %union.anon.8 }
%struct.troika = type { i8, i8, i8, i8, i32, [3 x i64] }
%struct.anon.7 = type { %struct.MDBX_rkl, i64, %struct.MDBX_rkl }
%struct.MDBX_rkl = type { i64, i64, i32, i32, ptr, [12 x i64] }
%union.anon.8 = type { %struct.anon.9 }
%struct.anon.9 = type { i64, ptr }
%struct.inner_cursor = type { %struct.MDBX_cursor, %struct.tree }
%struct.tree = type { i16, i16, i32, i32, i32, i32, i32, i64, i64, i64 }

@__func__.mdbx_estimate_distance = external hidden unnamed_addr constant [23 x i8], align 1
@globals = external global %struct.libmdbx_globals, align 8
@.str = external hidden unnamed_addr constant [55 x i8], align 1

; Function Attrs: hot nounwind uwtable
define dso_local i32 @mdbx_estimate_distance(ptr noundef %0, ptr noundef %1, ptr noundef %2) #0 {
  %4 = alloca i32, align 4
  %5 = alloca ptr, align 8
  %6 = alloca ptr, align 8
  %7 = alloca ptr, align 8
  %8 = alloca i32, align 4
  %9 = alloca i32, align 4
  %10 = alloca %struct.diff_result, align 8
  store ptr %0, ptr %5, align 8, !tbaa !5
  store ptr %1, ptr %6, align 8, !tbaa !5
  store ptr %2, ptr %7, align 8, !tbaa !5
  %11 = load ptr, ptr %7, align 8, !tbaa !5
  %12 = icmp ne ptr %11, null
  %13 = xor i1 %12, true
  %14 = xor i1 %13, true
  %15 = xor i1 %14, true
  %16 = zext i1 %15 to i32
  %17 = sext i32 %16 to i64
  %18 = call i64 @llvm.expect.i64(i64 %17, i64 0)
  %19 = icmp ne i64 %18, 0
  br i1 %19, label %20, label %22

20:                                               ; preds = %3
  %21 = call i32 @log_if_error(i32 noundef 22, ptr noundef @__func__.mdbx_estimate_distance, i32 noundef 144)
  store i32 %21, ptr %4, align 4
  br label %167

22:                                               ; preds = %3
  call void @llvm.lifetime.start.p0(i64 4, ptr %8) #6
  %23 = load ptr, ptr %5, align 8, !tbaa !5
  %24 = call i32 @cursor_check_pure(ptr noundef %23)
  store i32 %24, ptr %8, align 4, !tbaa !9
  %25 = load i32, ptr %8, align 4, !tbaa !9
  %26 = icmp ne i32 %25, 0
  %27 = xor i1 %26, true
  %28 = xor i1 %27, true
  %29 = zext i1 %28 to i32
  %30 = sext i32 %29 to i64
  %31 = call i64 @llvm.expect.i64(i64 %30, i64 0)
  %32 = icmp ne i64 %31, 0
  br i1 %32, label %33, label %36

33:                                               ; preds = %22
  %34 = load i32, ptr %8, align 4, !tbaa !9
  %35 = call i32 @log_if_error(i32 noundef %34, ptr noundef @__func__.mdbx_estimate_distance, i32 noundef 148)
  store i32 %35, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %166

36:                                               ; preds = %22
  %37 = load ptr, ptr %6, align 8, !tbaa !5
  %38 = call i32 @cursor_check_pure(ptr noundef %37)
  store i32 %38, ptr %8, align 4, !tbaa !9
  %39 = load i32, ptr %8, align 4, !tbaa !9
  %40 = icmp ne i32 %39, 0
  %41 = xor i1 %40, true
  %42 = xor i1 %41, true
  %43 = zext i1 %42 to i32
  %44 = sext i32 %43 to i64
  %45 = call i64 @llvm.expect.i64(i64 %44, i64 0)
  %46 = icmp ne i64 %45, 0
  br i1 %46, label %47, label %50

47:                                               ; preds = %36
  %48 = load i32, ptr %8, align 4, !tbaa !9
  %49 = call i32 @log_if_error(i32 noundef %48, ptr noundef @__func__.mdbx_estimate_distance, i32 noundef 152)
  store i32 %49, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %166

50:                                               ; preds = %36
  %51 = load ptr, ptr %7, align 8, !tbaa !5
  store i64 0, ptr %51, align 8, !tbaa !11
  call void @llvm.lifetime.start.p0(i64 24, ptr %10) #6
  %52 = load ptr, ptr %6, align 8, !tbaa !5
  %53 = load ptr, ptr %5, align 8, !tbaa !5
  %54 = call i32 @cursor_diff(ptr noundef %52, ptr noundef %53, ptr noundef %10) #7
  store i32 %54, ptr %8, align 4, !tbaa !9
  %55 = load i32, ptr %8, align 4, !tbaa !9
  %56 = icmp ne i32 %55, 0
  %57 = xor i1 %56, true
  %58 = xor i1 %57, true
  %59 = zext i1 %58 to i32
  %60 = sext i32 %59 to i64
  %61 = call i64 @llvm.expect.i64(i64 %60, i64 0)
  %62 = icmp ne i64 %61, 0
  br i1 %62, label %63, label %66

63:                                               ; preds = %50
  %64 = load i32, ptr %8, align 4, !tbaa !9
  %65 = call i32 @log_if_error(i32 noundef %64, ptr noundef @__func__.mdbx_estimate_distance, i32 noundef 158)
  store i32 %65, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %165

66:                                               ; preds = %50
  br label %67

67:                                               ; preds = %66
  %68 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !13
  %69 = zext i8 %68 to i32
  %70 = and i32 %69, 1
  %71 = icmp ne i32 %70, 0
  %72 = xor i1 %71, true
  %73 = xor i1 %72, true
  %74 = zext i1 %73 to i32
  %75 = sext i32 %74 to i64
  %76 = call i64 @llvm.expect.i64(i64 %75, i64 1)
  %77 = icmp ne i64 %76, 0
  br i1 %77, label %78, label %109

78:                                               ; preds = %67
  br label %79

79:                                               ; preds = %78
  %80 = getelementptr inbounds %struct.diff_result, ptr %10, i32 0, i32 0
  %81 = load i64, ptr %80, align 8, !tbaa !16
  %82 = icmp ne i64 %81, 0
  br i1 %82, label %91, label %83

83:                                               ; preds = %79
  %84 = load ptr, ptr %5, align 8, !tbaa !5
  %85 = call zeroext i1 @inner_pointed(ptr noundef %84) #8
  %86 = zext i1 %85 to i32
  %87 = load ptr, ptr %6, align 8, !tbaa !5
  %88 = call zeroext i1 @inner_pointed(ptr noundef %87) #8
  %89 = zext i1 %88 to i32
  %90 = icmp eq i32 %86, %89
  br label %91

91:                                               ; preds = %83, %79
  %92 = phi i1 [ true, %79 ], [ %90, %83 ]
  %93 = xor i1 %92, true
  %94 = xor i1 %93, true
  %95 = xor i1 %94, true
  %96 = zext i1 %95 to i32
  %97 = sext i32 %96 to i64
  %98 = call i64 @llvm.expect.i64(i64 %97, i64 0)
  %99 = icmp ne i64 %98, 0
  br i1 %99, label %100, label %106

100:                                              ; preds = %91
  %101 = load ptr, ptr %5, align 8, !tbaa !5
  %102 = getelementptr inbounds %struct.MDBX_cursor, ptr %101, i32 0, i32 5
  %103 = load ptr, ptr %102, align 8, !tbaa !18
  %104 = getelementptr inbounds %struct.MDBX_txn, ptr %103, i32 0, i32 9
  %105 = load ptr, ptr %104, align 8, !tbaa !20
  call void @mdbx_assert_fail(ptr noundef %105, ptr noundef @.str, ptr noundef @__func__.mdbx_estimate_distance, i32 noundef 160) #9
  unreachable

106:                                              ; preds = %91
  br label %107

107:                                              ; preds = %106
  br label %108

108:                                              ; preds = %107
  br label %109

109:                                              ; preds = %108, %67
  br label %110

110:                                              ; preds = %109
  br label %111

111:                                              ; preds = %110
  %112 = getelementptr inbounds %struct.diff_result, ptr %10, i32 0, i32 0
  %113 = load i64, ptr %112, align 8, !tbaa !16
  %114 = icmp eq i64 %113, 0
  %115 = xor i1 %114, true
  %116 = xor i1 %115, true
  %117 = zext i1 %116 to i32
  %118 = sext i32 %117 to i64
  %119 = call i64 @llvm.expect.i64(i64 %118, i64 0)
  %120 = icmp ne i64 %119, 0
  br i1 %120, label %121, label %148

121:                                              ; preds = %111
  %122 = load ptr, ptr %5, align 8, !tbaa !5
  %123 = call zeroext i1 @inner_pointed(ptr noundef %122) #8
  br i1 %123, label %124, label %148

124:                                              ; preds = %121
  %125 = load ptr, ptr %5, align 8, !tbaa !5
  %126 = getelementptr inbounds %struct.MDBX_cursor, ptr %125, i32 0, i32 8
  %127 = load ptr, ptr %126, align 8, !tbaa !25
  %128 = getelementptr inbounds %struct.inner_cursor, ptr %127, i32 0, i32 0
  store ptr %128, ptr %5, align 8, !tbaa !5
  %129 = load ptr, ptr %6, align 8, !tbaa !5
  %130 = getelementptr inbounds %struct.MDBX_cursor, ptr %129, i32 0, i32 8
  %131 = load ptr, ptr %130, align 8, !tbaa !25
  %132 = getelementptr inbounds %struct.inner_cursor, ptr %131, i32 0, i32 0
  store ptr %132, ptr %6, align 8, !tbaa !5
  %133 = load ptr, ptr %5, align 8, !tbaa !5
  %134 = load ptr, ptr %6, align 8, !tbaa !5
  %135 = call i32 @cursor_diff(ptr noundef %133, ptr noundef %134, ptr noundef %10) #7
  store i32 %135, ptr %8, align 4, !tbaa !9
  %136 = load i32, ptr %8, align 4, !tbaa !9
  %137 = icmp ne i32 %136, 0
  %138 = xor i1 %137, true
  %139 = xor i1 %138, true
  %140 = zext i1 %139 to i32
  %141 = sext i32 %140 to i64
  %142 = call i64 @llvm.expect.i64(i64 %141, i64 0)
  %143 = icmp ne i64 %142, 0
  br i1 %143, label %144, label %147

144:                                              ; preds = %124
  %145 = load i32, ptr %8, align 4, !tbaa !9
  %146 = call i32 @log_if_error(i32 noundef %145, ptr noundef @__func__.mdbx_estimate_distance, i32 noundef 166)
  store i32 %146, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %165

147:                                              ; preds = %124
  br label %148

148:                                              ; preds = %147, %121, %111
  %149 = getelementptr inbounds %struct.diff_result, ptr %10, i32 0, i32 0
  %150 = load i64, ptr %149, align 8, !tbaa !16
  %151 = icmp ne i64 %150, 0
  %152 = xor i1 %151, true
  %153 = xor i1 %152, true
  %154 = zext i1 %153 to i32
  %155 = sext i32 %154 to i64
  %156 = call i64 @llvm.expect.i64(i64 %155, i64 1)
  %157 = icmp ne i64 %156, 0
  br i1 %157, label %158, label %164

158:                                              ; preds = %148
  %159 = load ptr, ptr %5, align 8, !tbaa !5
  %160 = getelementptr inbounds %struct.MDBX_cursor, ptr %159, i32 0, i32 6
  %161 = load ptr, ptr %160, align 8, !tbaa !26
  %162 = call i64 @estimate(ptr noundef %161, ptr noundef %10) #7
  %163 = load ptr, ptr %7, align 8, !tbaa !5
  store i64 %162, ptr %163, align 8, !tbaa !11
  br label %164

164:                                              ; preds = %158, %148
  store i32 0, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %165

165:                                              ; preds = %164, %144, %63
  call void @llvm.lifetime.end.p0(i64 24, ptr %10) #6
  br label %166

166:                                              ; preds = %165, %47, %33
  call void @llvm.lifetime.end.p0(i64 4, ptr %8) #6
  br label %167

167:                                              ; preds = %166, %20
  %168 = load i32, ptr %4, align 4
  ret i32 %168
}

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
declare i64 @llvm.expect.i64(i64, i64) #1

; Function Attrs: inlinehint nounwind uwtable
declare hidden i32 @log_if_error(i32 noundef, ptr noundef, i32 noundef) #2

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3

; Function Attrs: inlinehint nounwind uwtable
declare hidden i32 @cursor_check_pure(ptr noundef) #2

; Function Attrs: hot nounwind uwtable
declare hidden i32 @cursor_diff(ptr noalias noundef, ptr noalias noundef, ptr noalias noundef) #0

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden zeroext i1 @inner_pointed(ptr noundef) #4

; Function Attrs: noreturn
declare void @mdbx_assert_fail(ptr noundef, ptr noundef, ptr noundef, i32 noundef) #5

; Function Attrs: hot nounwind uwtable
declare hidden i64 @estimate(ptr noundef, ptr noalias noundef) #0

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3

attributes #0 = { hot nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) }
attributes #2 = { inlinehint nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #4 = { inlinehint nounwind willreturn memory(read) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #5 = { noreturn "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #6 = { nounwind }
attributes #7 = { hot }
attributes #8 = { nounwind willreturn memory(read) }
attributes #9 = { noreturn }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.0 (git@github.com:llvm/llvm-project.git a4bf6cd7cfb1a1421ba92bca9d017b49936c55e4)"}
!5 = !{!6, !6, i64 0}
!6 = !{!"any pointer", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}
!9 = !{!10, !10, i64 0}
!10 = !{!"int", !7, i64 0}
!11 = !{!12, !12, i64 0}
!12 = !{!"long", !7, i64 0}
!13 = !{!14, !7, i64 25}
!14 = !{!"libmdbx_globals", !7, i64 0, !10, i64 16, !10, i64 20, !7, i64 24, !7, i64 25, !7, i64 26, !15, i64 27, !10, i64 28, !7, i64 32, !7, i64 40, !12, i64 80, !6, i64 88}
!15 = !{!"_Bool", !7, i64 0}
!16 = !{!17, !12, i64 0}
!17 = !{!"diff_result", !12, i64 0, !12, i64 8, !12, i64 16}
!18 = !{!19, !6, i64 16}
!19 = !{!"MDBX_cursor", !10, i64 0, !7, i64 4, !7, i64 6, !7, i64 7, !6, i64 8, !6, i64 16, !6, i64 24, !6, i64 32, !6, i64 40, !7, i64 48, !7, i64 304, !6, i64 368, !6, i64 376}
!20 = !{!21, !6, i64 80}
!21 = !{!"MDBX_txn", !10, i64 0, !10, i64 4, !12, i64 8, !12, i64 16, !6, i64 24, !6, i64 32, !22, i64 40, !12, i64 64, !12, i64 72, !6, i64 80, !6, i64 88, !6, i64 96, !6, i64 104, !6, i64 112, !6, i64 120, !24, i64 128, !6, i64 160, !7, i64 168}
!22 = !{!"geo", !23, i64 0, !23, i64 2, !10, i64 4, !10, i64 8, !7, i64 12, !7, i64 16}
!23 = !{!"short", !7, i64 0}
!24 = !{!"MDBX_canary", !12, i64 0, !12, i64 8, !12, i64 16, !12, i64 24}
!25 = !{!19, !6, i64 40}
!26 = !{!19, !6, i64 24}


; Optimized IR (opt -passes='default<O3>'):
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.libmdbx_globals = type { %union.bin128, i32, i32, i8, i8, i8, i8, i32, %union.logger_union, %union.pthread_mutex_t, i64, ptr }
%union.bin128 = type { %struct.anon }
%struct.anon = type { i64, i64 }
%union.logger_union = type { ptr }
%union.pthread_mutex_t = type { %struct.__pthread_mutex_s }
%struct.__pthread_mutex_s = type { i32, i32, i32, i32, i32, i16, i16, %struct.__pthread_internal_list }
%struct.__pthread_internal_list = type { ptr, ptr }
%struct.diff_result = type { i64, i64, i64 }

@__func__.mdbx_estimate_distance = external hidden unnamed_addr constant [23 x i8], align 1
@globals = external local_unnamed_addr global %struct.libmdbx_globals, align 8
@.str = external hidden unnamed_addr constant [55 x i8], align 1

; Function Attrs: hot nounwind uwtable
define dso_local i32 @mdbx_estimate_distance(ptr noundef %0, ptr noundef %1, ptr noundef writeonly %2) local_unnamed_addr #0 {
  %4 = alloca %struct.diff_result, align 8
  %.not = icmp eq ptr %2, null
  br i1 %.not, label %5, label %7, !prof !5

5:                                                ; preds = %3
  %6 = tail call i32 @log_if_error(i32 noundef 22, ptr noundef nonnull @__func__.mdbx_estimate_distance, i32 noundef 144)
  br label %45

7:                                                ; preds = %3
  %8 = tail call i32 @cursor_check_pure(ptr noundef %0)
  %.not29 = icmp eq i32 %8, 0
  br i1 %.not29, label %11, label %9, !prof !6

9:                                                ; preds = %7
  %10 = tail call i32 @log_if_error(i32 noundef %8, ptr noundef nonnull @__func__.mdbx_estimate_distance, i32 noundef 148)
  br label %45

11:                                               ; preds = %7
  %12 = tail call i32 @cursor_check_pure(ptr noundef %1)
  %.not30 = icmp eq i32 %12, 0
  br i1 %.not30, label %15, label %13, !prof !6

13:                                               ; preds = %11
  %14 = tail call i32 @log_if_error(i32 noundef %12, ptr noundef nonnull @__func__.mdbx_estimate_distance, i32 noundef 152)
  br label %45

15:                                               ; preds = %11
  store i64 0, ptr %2, align 8, !tbaa !7
  call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %4) #5
  %16 = call i32 @cursor_diff(ptr noundef %1, ptr noundef %0, ptr noundef nonnull %4) #6
  %.not31 = icmp eq i32 %16, 0
  br i1 %.not31, label %19, label %17, !prof !6

17:                                               ; preds = %15
  %18 = call i32 @log_if_error(i32 noundef %16, ptr noundef nonnull @__func__.mdbx_estimate_distance, i32 noundef 158)
  br label %.thread40

19:                                               ; preds = %15
  %20 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !11
  %21 = and i8 %20, 1
  %.not32 = icmp ne i8 %21, 0
  %22 = load i64, ptr %4, align 8
  %.not33 = icmp eq i64 %22, 0
  %or.cond = select i1 %.not32, i1 %.not33, i1 false
  br i1 %or.cond, label %23, label %.critedge, !prof !16

23:                                               ; preds = %19
  %24 = call zeroext i1 @inner_pointed(ptr noundef %0) #7
  %25 = call zeroext i1 @inner_pointed(ptr noundef %1) #7
  %26 = xor i1 %24, %25
  br i1 %26, label %27, label %.critedge.thread, !prof !5

27:                                               ; preds = %23
  %28 = getelementptr inbounds i8, ptr %0, i64 16
  %29 = load ptr, ptr %28, align 8, !tbaa !17
  %30 = getelementptr inbounds i8, ptr %29, i64 80
  %31 = load ptr, ptr %30, align 8, !tbaa !19
  call void @mdbx_assert_fail(ptr noundef %31, ptr noundef nonnull @.str, ptr noundef nonnull @__func__.mdbx_estimate_distance, i32 noundef 160) #8
  unreachable

.critedge:                                        ; preds = %19
  br i1 %.not33, label %.critedge.thread, label %.thread, !prof !24

.critedge.thread:                                 ; preds = %23, %.critedge
  %32 = call zeroext i1 @inner_pointed(ptr noundef %0) #7
  br i1 %32, label %33, label %.thread40

33:                                               ; preds = %.critedge.thread
  %34 = getelementptr inbounds i8, ptr %0, i64 40
  %35 = load ptr, ptr %34, align 8, !tbaa !25
  %36 = getelementptr inbounds i8, ptr %1, i64 40
  %37 = load ptr, ptr %36, align 8, !tbaa !25
  %38 = call i32 @cursor_diff(ptr noundef %35, ptr noundef %37, ptr noundef nonnull %4) #6
  %.not34 = icmp eq i32 %38, 0
  br i1 %.not34, label %41, label %39, !prof !6

39:                                               ; preds = %33
  %40 = call i32 @log_if_error(i32 noundef %38, ptr noundef nonnull @__func__.mdbx_estimate_distance, i32 noundef 166)
  br label %.thread40

41:                                               ; preds = %33
  %.pr.pre = load i64, ptr %4, align 8, !tbaa !26
  %.not35 = icmp eq i64 %.pr.pre, 0
  br i1 %.not35, label %.thread40, label %.thread, !prof !24

.thread:                                          ; preds = %.critedge, %41
  %.02438 = phi ptr [ %35, %41 ], [ %0, %.critedge ]
  %42 = getelementptr inbounds i8, ptr %.02438, i64 24
  %43 = load ptr, ptr %42, align 8, !tbaa !28
  %44 = call i64 @estimate(ptr noundef %43, ptr noundef nonnull %4) #6
  store i64 %44, ptr %2, align 8, !tbaa !7
  br label %.thread40

.thread40:                                        ; preds = %.critedge.thread, %41, %.thread, %39, %17
  %.0 = phi i32 [ %18, %17 ], [ %40, %39 ], [ 0, %.thread ], [ 0, %41 ], [ 0, %.critedge.thread ]
  call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %4) #5
  br label %45

45:                                               ; preds = %9, %13, %.thread40, %5
  %.2 = phi i32 [ %6, %5 ], [ %10, %9 ], [ %14, %13 ], [ %.0, %.thread40 ]
  ret i32 %.2
}

; Function Attrs: inlinehint nounwind uwtable
declare hidden i32 @log_if_error(i32 noundef, ptr noundef, i32 noundef) local_unnamed_addr #1

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2

; Function Attrs: inlinehint nounwind uwtable
declare hidden i32 @cursor_check_pure(ptr noundef) local_unnamed_addr #1

; Function Attrs: hot nounwind uwtable
declare hidden i32 @cursor_diff(ptr noalias noundef, ptr noalias noundef, ptr noalias noundef) local_unnamed_addr #0

; Function Attrs: inlinehint mustprogress nofree nounwind willreturn memory(read) uwtable
declare hidden zeroext i1 @inner_pointed(ptr noundef) local_unnamed_addr #3

; Function Attrs: noreturn
declare void @mdbx_assert_fail(ptr noundef, ptr noundef, ptr noundef, i32 noundef) local_unnamed_addr #4

; Function Attrs: hot nounwind uwtable
declare hidden i64 @estimate(ptr noundef, ptr noalias noundef) local_unnamed_addr #0

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2

attributes #0 = { hot nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { inlinehint nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { inlinehint mustprogress nofree nounwind willreturn memory(read) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #4 = { noreturn "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #5 = { nounwind }
attributes #6 = { hot }
attributes #7 = { nounwind willreturn memory(read) }
attributes #8 = { noreturn nounwind }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.0 (git@github.com:llvm/llvm-project.git a4bf6cd7cfb1a1421ba92bca9d017b49936c55e4)"}
!5 = !{!"branch_weights", !"expected", i32 1, i32 2000}
!6 = !{!"branch_weights", !"expected", i32 2000, i32 1}
!7 = !{!8, !8, i64 0}
!8 = !{!"long", !9, i64 0}
!9 = !{!"omnipotent char", !10, i64 0}
!10 = !{!"Simple C/C++ TBAA"}
!11 = !{!12, !9, i64 25}
!12 = !{!"libmdbx_globals", !9, i64 0, !13, i64 16, !13, i64 20, !9, i64 24, !9, i64 25, !9, i64 26, !14, i64 27, !13, i64 28, !9, i64 32, !9, i64 40, !8, i64 80, !15, i64 88}
!13 = !{!"int", !9, i64 0}
!14 = !{!"_Bool", !9, i64 0}
!15 = !{!"any pointer", !9, i64 0}
!16 = !{!"branch_weights", i32 2000, i32 2002}
!17 = !{!18, !15, i64 16}
!18 = !{!"MDBX_cursor", !13, i64 0, !9, i64 4, !9, i64 6, !9, i64 7, !15, i64 8, !15, i64 16, !15, i64 24, !15, i64 32, !15, i64 40, !9, i64 48, !9, i64 304, !15, i64 368, !15, i64 376}
!19 = !{!20, !15, i64 80}
!20 = !{!"MDBX_txn", !13, i64 0, !13, i64 4, !8, i64 8, !8, i64 16, !15, i64 24, !15, i64 32, !21, i64 40, !8, i64 64, !8, i64 72, !15, i64 80, !15, i64 88, !15, i64 96, !15, i64 104, !15, i64 112, !15, i64 120, !23, i64 128, !15, i64 160, !9, i64 168}
!21 = !{!"geo", !22, i64 0, !22, i64 2, !13, i64 4, !13, i64 8, !9, i64 12, !9, i64 16}
!22 = !{!"short", !9, i64 0}
!23 = !{!"MDBX_canary", !8, i64 0, !8, i64 8, !8, i64 16, !8, i64 24}
!24 = !{!"branch_weights", !"expected", i32 0, i32 -2147483648}
!25 = !{!18, !15, i64 40}
!26 = !{!27, !8, i64 0}
!27 = !{!"diff_result", !8, i64 0, !8, i64 8, !8, i64 16}
!28 = !{!18, !15, i64 24}


; Effective O3 passes: EarlyCSEPass,GVNPass,GlobalOptPass,IPSCCPPass,InferFunctionAttrsPass,InstCombinePass,JumpThreadingPass,LowerExpectIntrinsicPass,PostOrderFunctionAttrsPass,SROAPass,SimplifyCFGPass,TailCallElimPass