; LLVM IR from erthink/libmdbx :: src (tree-search)

; 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.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.tree = type { i16, i16, i32, i32, i32, i32, i32, i64, i64, i64 }
%struct.anon.1 = type { i8, i8 }
%struct.page = type <{ i64, i16, i16, %union.anon.10, i32, [0 x i16] }>
%union.anon.10 = type { i32 }

@globals = external global %struct.libmdbx_globals, align 8
@__func__.tree_search = external hidden unnamed_addr constant [12 x i8], align 1
@.str.2 = external hidden unnamed_addr constant [4 x i8], align 1
@.str.3 = external hidden unnamed_addr constant [35 x i8], align 1
@.str.4 = external hidden unnamed_addr constant [14 x i8], align 1
@.str.5 = external hidden unnamed_addr constant [12 x i8], align 1
@.str.6 = external hidden unnamed_addr constant [51 x i8], align 1
@.str.7 = external hidden unnamed_addr constant [35 x i8], align 1

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

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

; Function Attrs: 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 @page_get(ptr noundef, i32 noundef, ptr noundef, i64 noundef) #3

; Function Attrs: hot noinline nounwind uwtable
declare dso_local i32 @tree_search_finalize(ptr noundef, ptr noundef, i32 noundef) #4

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

; Function Attrs: hot nounwind uwtable
define dso_local i32 @tree_search(ptr noundef %0, ptr noundef %1, i32 noundef %2) #5 {
  %4 = alloca i32, align 4
  %5 = alloca ptr, align 8
  %6 = alloca ptr, align 8
  %7 = alloca i32, align 4
  %8 = alloca i32, align 4
  %9 = alloca i32, align 4
  %10 = alloca i64, align 8
  %11 = alloca i32, align 4
  %12 = alloca i64, align 8
  %13 = alloca ptr, align 8
  store ptr %0, ptr %5, align 8, !tbaa !5
  store ptr %1, ptr %6, align 8, !tbaa !5
  store i32 %2, ptr %7, align 4, !tbaa !9
  call void @llvm.lifetime.start.p0(i64 4, ptr %8) #8
  %14 = load ptr, ptr %5, align 8, !tbaa !5
  %15 = getelementptr inbounds %struct.MDBX_cursor, ptr %14, i32 0, i32 5
  %16 = load ptr, ptr %15, align 8, !tbaa !11
  %17 = getelementptr inbounds %struct.MDBX_txn, ptr %16, i32 0, i32 1
  %18 = load i32, ptr %17, align 4, !tbaa !13
  %19 = and i32 %18, 51
  %20 = icmp ne i32 %19, 0
  %21 = xor i1 %20, true
  %22 = xor i1 %21, true
  %23 = zext i1 %22 to i32
  %24 = sext i32 %23 to i64
  %25 = call i64 @llvm.expect.i64(i64 %24, i64 0)
  %26 = icmp ne i64 %25, 0
  br i1 %26, label %27, label %45

27:                                               ; preds = %3
  br label %28

28:                                               ; preds = %27
  %29 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 5), align 2, !tbaa !19
  %30 = zext i8 %29 to i32
  %31 = icmp sle i32 5, %30
  %32 = xor i1 %31, true
  %33 = xor i1 %32, true
  %34 = zext i1 %33 to i32
  %35 = sext i32 %34 to i64
  %36 = call i64 @llvm.expect.i64(i64 %35, i64 0)
  %37 = icmp ne i64 %36, 0
  br i1 %37, label %38, label %39

38:                                               ; preds = %28
  call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef @__func__.tree_search, i32 noundef 33, ptr noundef @.str.2, ptr noundef @.str.3)
  br label %39

39:                                               ; preds = %38, %28
  br label %40

40:                                               ; preds = %39
  br label %41

41:                                               ; preds = %40
  store i32 -30782, ptr %8, align 4, !tbaa !9
  br label %42

42:                                               ; preds = %345, %283, %74, %41
  %43 = load ptr, ptr %5, align 8, !tbaa !5
  call void @be_poor(ptr noundef %43)
  %44 = load i32, ptr %8, align 4, !tbaa !9
  store i32 %44, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %357

45:                                               ; preds = %3
  %46 = load ptr, ptr %5, align 8, !tbaa !5
  %47 = call i64 @cursor_dbi(ptr noundef %46) #9
  store i64 %47, ptr %10, align 8, !tbaa !22
  %48 = load ptr, ptr %5, align 8, !tbaa !5
  %49 = call ptr @cursor_dbi_state(ptr noundef %48) #9
  %50 = load i8, ptr %49, align 1, !tbaa !23
  %51 = zext i8 %50 to i32
  %52 = and i32 %51, 2
  %53 = icmp ne i32 %52, 0
  %54 = xor i1 %53, true
  %55 = xor i1 %54, true
  %56 = zext i1 %55 to i32
  %57 = sext i32 %56 to i64
  %58 = call i64 @llvm.expect.i64(i64 %57, i64 0)
  %59 = icmp ne i64 %58, 0
  br i1 %59, label %60, label %76

60:                                               ; preds = %45
  %61 = load ptr, ptr %5, align 8, !tbaa !5
  %62 = getelementptr inbounds %struct.MDBX_cursor, ptr %61, i32 0, i32 5
  %63 = load ptr, ptr %62, align 8, !tbaa !11
  %64 = load i64, ptr %10, align 8, !tbaa !22
  %65 = call i32 @tbl_fetch(ptr noundef %63, i64 noundef %64)
  store i32 %65, ptr %8, align 4, !tbaa !9
  %66 = load i32, ptr %8, align 4, !tbaa !9
  %67 = icmp ne i32 %66, 0
  %68 = xor i1 %67, true
  %69 = xor i1 %68, true
  %70 = zext i1 %69 to i32
  %71 = sext i32 %70 to i64
  %72 = call i64 @llvm.expect.i64(i64 %71, i64 0)
  %73 = icmp ne i64 %72, 0
  br i1 %73, label %74, label %75

74:                                               ; preds = %60
  br label %42

75:                                               ; preds = %60
  br label %76

76:                                               ; preds = %75, %45
  %77 = load ptr, ptr %5, align 8, !tbaa !5
  %78 = getelementptr inbounds %struct.MDBX_cursor, ptr %77, i32 0, i32 6
  %79 = load ptr, ptr %78, align 8, !tbaa !24
  %80 = getelementptr inbounds %struct.tree, ptr %79, i32 0, i32 3
  %81 = load i32, ptr %80, align 4, !tbaa !25
  store i32 %81, ptr %11, align 4, !tbaa !9
  %82 = load i32, ptr %11, align 4, !tbaa !9
  %83 = icmp eq i32 %82, -1
  %84 = xor i1 %83, true
  %85 = xor i1 %84, true
  %86 = zext i1 %85 to i32
  %87 = sext i32 %86 to i64
  %88 = call i64 @llvm.expect.i64(i64 %87, i64 0)
  %89 = icmp ne i64 %88, 0
  br i1 %89, label %90, label %139

90:                                               ; preds = %76
  br label %91

91:                                               ; preds = %90
  %92 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 5), align 2, !tbaa !19
  %93 = zext i8 %92 to i32
  %94 = icmp sle i32 5, %93
  %95 = xor i1 %94, true
  %96 = xor i1 %95, true
  %97 = zext i1 %96 to i32
  %98 = sext i32 %97 to i64
  %99 = call i64 @llvm.expect.i64(i64 %98, i64 0)
  %100 = icmp ne i64 %99, 0
  br i1 %100, label %101, label %102

101:                                              ; preds = %91
  call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef @__func__.tree_search, i32 noundef 49, ptr noundef @.str.2, ptr noundef @.str.4)
  br label %102

102:                                              ; preds = %101, %91
  br label %103

103:                                              ; preds = %102
  br label %104

104:                                              ; preds = %103
  br label %105

105:                                              ; preds = %104
  %106 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !27
  %107 = zext i8 %106 to i32
  %108 = and i32 %107, 1
  %109 = icmp ne i32 %108, 0
  %110 = xor i1 %109, true
  %111 = xor i1 %110, true
  %112 = zext i1 %111 to i32
  %113 = sext i32 %112 to i64
  %114 = call i64 @llvm.expect.i64(i64 %113, i64 1)
  %115 = icmp ne i64 %114, 0
  br i1 %115, label %116, label %136

116:                                              ; preds = %105
  br label %117

117:                                              ; preds = %116
  %118 = load ptr, ptr %5, align 8, !tbaa !5
  %119 = call zeroext i1 @is_poor(ptr noundef %118) #9
  %120 = xor i1 %119, true
  %121 = xor i1 %120, true
  %122 = xor i1 %121, true
  %123 = zext i1 %122 to i32
  %124 = sext i32 %123 to i64
  %125 = call i64 @llvm.expect.i64(i64 %124, i64 0)
  %126 = icmp ne i64 %125, 0
  br i1 %126, label %127, label %133

127:                                              ; preds = %117
  %128 = load ptr, ptr %5, align 8, !tbaa !5
  %129 = getelementptr inbounds %struct.MDBX_cursor, ptr %128, i32 0, i32 5
  %130 = load ptr, ptr %129, align 8, !tbaa !11
  %131 = getelementptr inbounds %struct.MDBX_txn, ptr %130, i32 0, i32 9
  %132 = load ptr, ptr %131, align 8, !tbaa !28
  call void @mdbx_assert_fail(ptr noundef %132, ptr noundef @.str.5, ptr noundef @__func__.tree_search, i32 noundef 50) #10
  unreachable

133:                                              ; preds = %117
  br label %134

134:                                              ; preds = %133
  br label %135

135:                                              ; preds = %134
  br label %136

136:                                              ; preds = %135, %105
  br label %137

137:                                              ; preds = %136
  br label %138

138:                                              ; preds = %137
  store i32 -30798, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %357

139:                                              ; preds = %76
  br label %140

140:                                              ; preds = %139
  %141 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !27
  %142 = zext i8 %141 to i32
  %143 = and i32 %142, 1
  %144 = icmp ne i32 %143, 0
  %145 = xor i1 %144, true
  %146 = xor i1 %145, true
  %147 = zext i1 %146 to i32
  %148 = sext i32 %147 to i64
  %149 = call i64 @llvm.expect.i64(i64 %148, i64 1)
  %150 = icmp ne i64 %149, 0
  br i1 %150, label %151, label %182

151:                                              ; preds = %140
  br label %152

152:                                              ; preds = %151
  %153 = load i32, ptr %11, align 4, !tbaa !9
  %154 = icmp uge i32 %153, 3
  br i1 %154, label %155, label %164

155:                                              ; preds = %152
  %156 = load i32, ptr %11, align 4, !tbaa !9
  %157 = load ptr, ptr %5, align 8, !tbaa !5
  %158 = getelementptr inbounds %struct.MDBX_cursor, ptr %157, i32 0, i32 5
  %159 = load ptr, ptr %158, align 8, !tbaa !11
  %160 = getelementptr inbounds %struct.MDBX_txn, ptr %159, i32 0, i32 6
  %161 = getelementptr inbounds %struct.geo, ptr %160, i32 0, i32 5
  %162 = load i32, ptr %161, align 8, !tbaa !23
  %163 = icmp ult i32 %156, %162
  br label %164

164:                                              ; preds = %155, %152
  %165 = phi i1 [ false, %152 ], [ %163, %155 ]
  %166 = xor i1 %165, true
  %167 = xor i1 %166, true
  %168 = xor i1 %167, true
  %169 = zext i1 %168 to i32
  %170 = sext i32 %169 to i64
  %171 = call i64 @llvm.expect.i64(i64 %170, i64 0)
  %172 = icmp ne i64 %171, 0
  br i1 %172, label %173, label %179

173:                                              ; preds = %164
  %174 = load ptr, ptr %5, align 8, !tbaa !5
  %175 = getelementptr inbounds %struct.MDBX_cursor, ptr %174, i32 0, i32 5
  %176 = load ptr, ptr %175, align 8, !tbaa !11
  %177 = getelementptr inbounds %struct.MDBX_txn, ptr %176, i32 0, i32 9
  %178 = load ptr, ptr %177, align 8, !tbaa !28
  call void @mdbx_assert_fail(ptr noundef %178, ptr noundef @.str.6, ptr noundef @__func__.tree_search, i32 noundef 54) #10
  unreachable

179:                                              ; preds = %164
  br label %180

180:                                              ; preds = %179
  br label %181

181:                                              ; preds = %180
  br label %182

182:                                              ; preds = %181, %140
  br label %183

183:                                              ; preds = %182
  br label %184

184:                                              ; preds = %183
  %185 = load ptr, ptr %5, align 8, !tbaa !5
  %186 = getelementptr inbounds %struct.MDBX_cursor, ptr %185, i32 0, i32 1
  %187 = getelementptr inbounds %struct.anon.1, ptr %186, i32 0, i32 1
  %188 = load i8, ptr %187, align 1, !tbaa !23
  %189 = sext i8 %188 to i32
  %190 = icmp slt i32 %189, 0
  br i1 %190, label %200, label %191

191:                                              ; preds = %184
  %192 = load ptr, ptr %5, align 8, !tbaa !5
  %193 = getelementptr inbounds %struct.MDBX_cursor, ptr %192, i32 0, i32 9
  %194 = getelementptr inbounds [32 x ptr], ptr %193, i64 0, i64 0
  %195 = load ptr, ptr %194, align 8, !tbaa !5
  %196 = getelementptr inbounds %struct.page, ptr %195, i32 0, i32 4
  %197 = load i32, ptr %196, align 1, !tbaa !9
  %198 = load i32, ptr %11, align 4, !tbaa !9
  %199 = icmp ne i32 %197, %198
  br i1 %199, label %200, label %286

200:                                              ; preds = %191, %184
  call void @llvm.lifetime.start.p0(i64 8, ptr %12) #8
  %201 = load ptr, ptr %5, align 8, !tbaa !5
  %202 = getelementptr inbounds %struct.MDBX_cursor, ptr %201, i32 0, i32 6
  %203 = load ptr, ptr %202, align 8, !tbaa !24
  %204 = getelementptr inbounds %struct.tree, ptr %203, i32 0, i32 9
  %205 = load i64, ptr %204, align 4, !tbaa !29
  store i64 %205, ptr %12, align 8, !tbaa !22
  %206 = load i64, ptr %12, align 8, !tbaa !22
  %207 = icmp ne i64 %206, 0
  br i1 %207, label %208, label %210

208:                                              ; preds = %200
  %209 = load i64, ptr %12, align 8, !tbaa !22
  br label %216

210:                                              ; preds = %200
  %211 = load ptr, ptr %5, align 8, !tbaa !5
  %212 = getelementptr inbounds %struct.MDBX_cursor, ptr %211, i32 0, i32 5
  %213 = load ptr, ptr %212, align 8, !tbaa !11
  %214 = getelementptr inbounds %struct.MDBX_txn, ptr %213, i32 0, i32 7
  %215 = load i64, ptr %214, align 8, !tbaa !30
  br label %216

216:                                              ; preds = %210, %208
  %217 = phi i64 [ %209, %208 ], [ %215, %210 ]
  store i64 %217, ptr %12, align 8, !tbaa !22
  %218 = load ptr, ptr %5, align 8, !tbaa !5
  %219 = getelementptr inbounds %struct.MDBX_cursor, ptr %218, i32 0, i32 5
  %220 = load ptr, ptr %219, align 8, !tbaa !11
  %221 = getelementptr inbounds %struct.MDBX_txn, ptr %220, i32 0, i32 1
  %222 = load i32, ptr %221, align 4, !tbaa !13
  %223 = and i32 %222, 131072
  %224 = icmp eq i32 %223, 0
  br i1 %224, label %225, label %265

225:                                              ; preds = %216
  call void @llvm.lifetime.start.p0(i64 8, ptr %13) #8
  %226 = load ptr, ptr %5, align 8, !tbaa !5
  %227 = getelementptr inbounds %struct.MDBX_cursor, ptr %226, i32 0, i32 5
  %228 = load ptr, ptr %227, align 8, !tbaa !11
  store ptr %228, ptr %13, align 8, !tbaa !5
  br label %229

229:                                              ; preds = %253, %225
  %230 = load ptr, ptr %13, align 8, !tbaa !5
  %231 = getelementptr inbounds %struct.MDBX_txn, ptr %230, i32 0, i32 1
  %232 = load i32, ptr %231, align 4, !tbaa !13
  %233 = and i32 %232, 4
  %234 = icmp ne i32 %233, 0
  br i1 %234, label %235, label %252

235:                                              ; preds = %229
  %236 = load i64, ptr %10, align 8, !tbaa !22
  %237 = icmp eq i64 %236, 1
  br i1 %237, label %248, label %238

238:                                              ; preds = %235
  %239 = load ptr, ptr %13, align 8, !tbaa !5
  %240 = getelementptr inbounds %struct.MDBX_txn, ptr %239, i32 0, i32 12
  %241 = load ptr, ptr %240, align 8, !tbaa !31
  %242 = load i64, ptr %10, align 8, !tbaa !22
  %243 = getelementptr inbounds i8, ptr %241, i64 %242
  %244 = load i8, ptr %243, align 1, !tbaa !23
  %245 = zext i8 %244 to i32
  %246 = and i32 %245, 1
  %247 = icmp ne i32 %246, 0
  br i1 %247, label %248, label %252

248:                                              ; preds = %238, %235
  %249 = load ptr, ptr %13, align 8, !tbaa !5
  %250 = getelementptr inbounds %struct.MDBX_txn, ptr %249, i32 0, i32 8
  %251 = load i64, ptr %250, align 8, !tbaa !32
  store i64 %251, ptr %12, align 8, !tbaa !22
  br label %264

252:                                              ; preds = %238, %229
  br label %253

253:                                              ; preds = %252
  %254 = load ptr, ptr %13, align 8, !tbaa !5
  %255 = getelementptr inbounds %struct.MDBX_txn, ptr %254, i32 0, i32 4
  %256 = load ptr, ptr %255, align 8, !tbaa !33
  store ptr %256, ptr %13, align 8, !tbaa !5
  %257 = icmp ne ptr %256, null
  %258 = xor i1 %257, true
  %259 = xor i1 %258, true
  %260 = zext i1 %259 to i32
  %261 = sext i32 %260 to i64
  %262 = call i64 @llvm.expect.i64(i64 %261, i64 0)
  %263 = icmp ne i64 %262, 0
  br i1 %263, label %229, label %264, !llvm.loop !34

264:                                              ; preds = %253, %248
  call void @llvm.lifetime.end.p0(i64 8, ptr %13) #8
  br label %265

265:                                              ; preds = %264, %216
  %266 = load ptr, ptr %5, align 8, !tbaa !5
  %267 = load i32, ptr %11, align 4, !tbaa !9
  %268 = load ptr, ptr %5, align 8, !tbaa !5
  %269 = getelementptr inbounds %struct.MDBX_cursor, ptr %268, i32 0, i32 9
  %270 = getelementptr inbounds [32 x ptr], ptr %269, i64 0, i64 0
  %271 = load i64, ptr %12, align 8, !tbaa !22
  %272 = call i32 @page_get(ptr noundef %266, i32 noundef %267, ptr noundef %270, i64 noundef %271)
  store i32 %272, ptr %8, align 4, !tbaa !9
  %273 = load i32, ptr %8, align 4, !tbaa !9
  %274 = icmp ne i32 %273, 0
  %275 = xor i1 %274, true
  %276 = xor i1 %275, true
  %277 = zext i1 %276 to i32
  %278 = sext i32 %277 to i64
  %279 = call i64 @llvm.expect.i64(i64 %278, i64 0)
  %280 = icmp ne i64 %279, 0
  br i1 %280, label %281, label %282

281:                                              ; preds = %265
  store i32 4, ptr %9, align 4
  br label %283

282:                                              ; preds = %265
  store i32 0, ptr %9, align 4
  br label %283

283:                                              ; preds = %282, %281
  call void @llvm.lifetime.end.p0(i64 8, ptr %12) #8
  %284 = load i32, ptr %9, align 4
  switch i32 %284, label %359 [
    i32 0, label %285
    i32 4, label %42
  ]

285:                                              ; preds = %283
  br label %286

286:                                              ; preds = %285, %191
  %287 = load ptr, ptr %5, align 8, !tbaa !5
  %288 = getelementptr inbounds %struct.MDBX_cursor, ptr %287, i32 0, i32 1
  %289 = getelementptr inbounds %struct.anon.1, ptr %288, i32 0, i32 1
  store i8 0, ptr %289, align 1, !tbaa !23
  %290 = load i32, ptr %7, align 4, !tbaa !9
  %291 = and i32 %290, 8
  %292 = icmp ne i32 %291, 0
  br i1 %292, label %293, label %300

293:                                              ; preds = %286
  %294 = load ptr, ptr %5, align 8, !tbaa !5
  %295 = getelementptr inbounds %struct.MDBX_cursor, ptr %294, i32 0, i32 9
  %296 = getelementptr inbounds [32 x ptr], ptr %295, i64 0, i64 0
  %297 = load ptr, ptr %296, align 8, !tbaa !5
  %298 = call i64 @page_numkeys(ptr noundef %297) #9
  %299 = sub i64 %298, 1
  br label %301

300:                                              ; preds = %286
  br label %301

301:                                              ; preds = %300, %293
  %302 = phi i64 [ %299, %293 ], [ 0, %300 ]
  %303 = trunc i64 %302 to i16
  %304 = load ptr, ptr %5, align 8, !tbaa !5
  %305 = getelementptr inbounds %struct.MDBX_cursor, ptr %304, i32 0, i32 10
  %306 = getelementptr inbounds [32 x i16], ptr %305, i64 0, i64 0
  store i16 %303, ptr %306, align 8, !tbaa !36
  br label %307

307:                                              ; preds = %301
  %308 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 5), align 2, !tbaa !19
  %309 = zext i8 %308 to i32
  %310 = icmp sle i32 5, %309
  %311 = xor i1 %310, true
  %312 = xor i1 %311, true
  %313 = zext i1 %312 to i32
  %314 = sext i32 %313 to i64
  %315 = call i64 @llvm.expect.i64(i64 %314, i64 0)
  %316 = icmp ne i64 %315, 0
  br i1 %316, label %317, label %328

317:                                              ; preds = %307
  %318 = load ptr, ptr %5, align 8, !tbaa !5
  %319 = call i32 @cursor_dbi_dbg(ptr noundef %318)
  %320 = load i32, ptr %11, align 4, !tbaa !9
  %321 = load ptr, ptr %5, align 8, !tbaa !5
  %322 = getelementptr inbounds %struct.MDBX_cursor, ptr %321, i32 0, i32 9
  %323 = getelementptr inbounds [32 x ptr], ptr %322, i64 0, i64 0
  %324 = load ptr, ptr %323, align 8, !tbaa !5
  %325 = getelementptr inbounds %struct.page, ptr %324, i32 0, i32 2
  %326 = load i16, ptr %325, align 1, !tbaa !36
  %327 = zext i16 %326 to i32
  call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef @__func__.tree_search, i32 noundef 75, ptr noundef @.str.7, i32 noundef %319, i32 noundef %320, i32 noundef %327)
  br label %328

328:                                              ; preds = %317, %307
  br label %329

329:                                              ; preds = %328
  br label %330

330:                                              ; preds = %329
  %331 = load i32, ptr %7, align 4, !tbaa !9
  %332 = and i32 %331, 1
  %333 = icmp ne i32 %332, 0
  br i1 %333, label %334, label %347

334:                                              ; preds = %330
  %335 = load ptr, ptr %5, align 8, !tbaa !5
  %336 = call i32 @page_touch(ptr noundef %335)
  store i32 %336, ptr %8, align 4, !tbaa !9
  %337 = load i32, ptr %8, align 4, !tbaa !9
  %338 = icmp ne i32 %337, 0
  %339 = xor i1 %338, true
  %340 = xor i1 %339, true
  %341 = zext i1 %340 to i32
  %342 = sext i32 %341 to i64
  %343 = call i64 @llvm.expect.i64(i64 %342, i64 0)
  %344 = icmp ne i64 %343, 0
  br i1 %344, label %345, label %346

345:                                              ; preds = %334
  br label %42

346:                                              ; preds = %334
  br label %347

347:                                              ; preds = %346, %330
  %348 = load i32, ptr %7, align 4, !tbaa !9
  %349 = and i32 %348, 2
  %350 = icmp ne i32 %349, 0
  br i1 %350, label %351, label %352

351:                                              ; preds = %347
  store i32 0, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %357

352:                                              ; preds = %347
  %353 = load ptr, ptr %5, align 8, !tbaa !5
  %354 = load ptr, ptr %6, align 8, !tbaa !5
  %355 = load i32, ptr %7, align 4, !tbaa !9
  %356 = call i32 @tree_search_finalize(ptr noundef %353, ptr noundef %354, i32 noundef %355)
  store i32 %356, ptr %4, align 4
  store i32 1, ptr %9, align 4
  br label %357

357:                                              ; preds = %352, %351, %138, %42
  call void @llvm.lifetime.end.p0(i64 4, ptr %8) #8
  %358 = load i32, ptr %4, align 4
  ret i32 %358

359:                                              ; preds = %283
  unreachable
}

declare void @debug_log(i32 noundef, ptr noundef, i32 noundef, ptr noundef, ...) #6

; Function Attrs: inlinehint nounwind uwtable
declare hidden void @be_poor(ptr noundef) #3

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden i64 @cursor_dbi(ptr noundef) #7

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden ptr @cursor_dbi_state(ptr noundef) #7

declare i32 @tbl_fetch(ptr noundef, i64 noundef) #6

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

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden i64 @page_numkeys(ptr noundef) #7

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

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

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
attributes #1 = { 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 #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { 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 #4 = { hot noinline 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 #5 = { 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 #6 = { "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 #7 = { 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 #8 = { nounwind }
attributes #9 = { nounwind willreturn memory(read) }
attributes #10 = { 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, !6, i64 16}
!12 = !{!"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}
!13 = !{!14, !10, i64 4}
!14 = !{!"MDBX_txn", !10, i64 0, !10, i64 4, !15, i64 8, !15, i64 16, !6, i64 24, !6, i64 32, !16, i64 40, !15, i64 64, !15, i64 72, !6, i64 80, !6, i64 88, !6, i64 96, !6, i64 104, !6, i64 112, !6, i64 120, !18, i64 128, !6, i64 160, !7, i64 168}
!15 = !{!"long", !7, i64 0}
!16 = !{!"geo", !17, i64 0, !17, i64 2, !10, i64 4, !10, i64 8, !7, i64 12, !7, i64 16}
!17 = !{!"short", !7, i64 0}
!18 = !{!"MDBX_canary", !15, i64 0, !15, i64 8, !15, i64 16, !15, i64 24}
!19 = !{!20, !7, i64 26}
!20 = !{!"libmdbx_globals", !7, i64 0, !10, i64 16, !10, i64 20, !7, i64 24, !7, i64 25, !7, i64 26, !21, i64 27, !10, i64 28, !7, i64 32, !7, i64 40, !15, i64 80, !6, i64 88}
!21 = !{!"_Bool", !7, i64 0}
!22 = !{!15, !15, i64 0}
!23 = !{!7, !7, i64 0}
!24 = !{!12, !6, i64 24}
!25 = !{!26, !10, i64 8}
!26 = !{!"tree", !17, i64 0, !17, i64 2, !10, i64 4, !10, i64 8, !10, i64 12, !10, i64 16, !10, i64 20, !15, i64 24, !15, i64 32, !15, i64 40}
!27 = !{!20, !7, i64 25}
!28 = !{!14, !6, i64 80}
!29 = !{!26, !15, i64 40}
!30 = !{!14, !15, i64 64}
!31 = !{!14, !6, i64 104}
!32 = !{!14, !15, i64 72}
!33 = !{!14, !6, i64 24}
!34 = distinct !{!34, !35}
!35 = !{!"llvm.loop.mustprogress"}
!36 = !{!17, !17, i64 0}


; 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 }

@globals = external local_unnamed_addr global %struct.libmdbx_globals, align 8
@__func__.tree_search = external hidden unnamed_addr constant [12 x i8], align 1
@.str.2 = external hidden unnamed_addr constant [4 x i8], align 1
@.str.3 = external hidden unnamed_addr constant [35 x i8], align 1
@.str.4 = external hidden unnamed_addr constant [14 x i8], align 1
@.str.5 = external hidden unnamed_addr constant [12 x i8], align 1
@.str.6 = external hidden unnamed_addr constant [51 x i8], align 1
@.str.7 = external hidden unnamed_addr constant [35 x i8], align 1

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

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

; Function Attrs: hot noinline nounwind uwtable
declare dso_local i32 @tree_search_finalize(ptr noundef, ptr noundef, i32 noundef) local_unnamed_addr #2

; Function Attrs: hot nounwind uwtable
define dso_local i32 @tree_search(ptr noundef %0, ptr noundef %1, i32 noundef %2) local_unnamed_addr #3 {
  %4 = getelementptr inbounds i8, ptr %0, i64 16
  %5 = load ptr, ptr %4, align 8, !tbaa !5
  %6 = getelementptr inbounds i8, ptr %5, i64 4
  %7 = load i32, ptr %6, align 4, !tbaa !11
  %8 = and i32 %7, 51
  %.not = icmp eq i32 %8, 0
  br i1 %.not, label %14, label %9, !prof !17

9:                                                ; preds = %3
  %10 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 26), align 2, !tbaa !18
  %11 = icmp ugt i8 %10, 4
  br i1 %11, label %12, label %13, !prof !21

12:                                               ; preds = %9
  tail call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef nonnull @__func__.tree_search, i32 noundef 33, ptr noundef nonnull @.str.2, ptr noundef nonnull @.str.3) #6
  br label %13

13:                                               ; preds = %.loopexit, %9, %12, %116, %19
  %.053 = phi i32 [ %20, %19 ], [ %93, %.loopexit ], [ %117, %116 ], [ -30782, %12 ], [ -30782, %9 ]
  tail call void @be_poor(ptr noundef %0)
  br label %122

14:                                               ; preds = %3
  %15 = tail call i64 @cursor_dbi(ptr noundef nonnull %0) #7
  %.fr78 = freeze i64 %15
  %16 = tail call ptr @cursor_dbi_state(ptr noundef nonnull %0) #7
  %17 = load i8, ptr %16, align 1, !tbaa !22
  %18 = and i8 %17, 2
  %.not61 = icmp eq i8 %18, 0
  br i1 %.not61, label %21, label %19, !prof !17

19:                                               ; preds = %14
  %20 = tail call i32 @tbl_fetch(ptr noundef nonnull %5, i64 noundef %.fr78) #6
  %.not62 = icmp eq i32 %20, 0
  br i1 %.not62, label %21, label %13, !prof !17

21:                                               ; preds = %19, %14
  %22 = getelementptr inbounds i8, ptr %0, i64 24
  %23 = load ptr, ptr %22, align 8, !tbaa !23
  %24 = getelementptr inbounds i8, ptr %23, i64 8
  %25 = load i32, ptr %24, align 4, !tbaa !24
  %26 = icmp eq i32 %25, -1
  br i1 %26, label %27, label %40, !prof !21

27:                                               ; preds = %21
  %28 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 26), align 2, !tbaa !18
  %29 = icmp ugt i8 %28, 4
  br i1 %29, label %30, label %31, !prof !21

30:                                               ; preds = %27
  tail call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef nonnull @__func__.tree_search, i32 noundef 49, ptr noundef nonnull @.str.2, ptr noundef nonnull @.str.4) #6
  br label %31

31:                                               ; preds = %27, %30
  %32 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !26
  %33 = and i8 %32, 1
  %.not74 = icmp eq i8 %33, 0
  br i1 %.not74, label %122, label %34, !prof !21

34:                                               ; preds = %31
  %35 = tail call zeroext i1 @is_poor(ptr noundef nonnull %0) #7
  br i1 %35, label %122, label %36, !prof !17

36:                                               ; preds = %34
  %37 = load ptr, ptr %4, align 8, !tbaa !5
  %38 = getelementptr inbounds i8, ptr %37, i64 80
  %39 = load ptr, ptr %38, align 8, !tbaa !27
  tail call void @mdbx_assert_fail(ptr noundef %39, ptr noundef nonnull @.str.5, ptr noundef nonnull @__func__.tree_search, i32 noundef 50) #8
  unreachable

40:                                               ; preds = %21
  %41 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !26
  %42 = and i8 %41, 1
  %.not63 = icmp eq i8 %42, 0
  br i1 %.not63, label %50, label %43, !prof !21

43:                                               ; preds = %40
  %44 = icmp ugt i32 %25, 2
  %.pre = load ptr, ptr %4, align 8, !tbaa !5
  br i1 %44, label %45, label %.critedge, !prof !17

45:                                               ; preds = %43
  %46 = getelementptr inbounds i8, ptr %.pre, i64 56
  %47 = load i32, ptr %46, align 8, !tbaa !22
  %.not75 = icmp ult i32 %25, %47
  br i1 %.not75, label %50, label %.critedge, !prof !17

.critedge:                                        ; preds = %43, %45
  %48 = getelementptr inbounds i8, ptr %.pre, i64 80
  %49 = load ptr, ptr %48, align 8, !tbaa !27
  tail call void @mdbx_assert_fail(ptr noundef %49, ptr noundef nonnull @.str.6, ptr noundef nonnull @__func__.tree_search, i32 noundef 54) #8
  unreachable

50:                                               ; preds = %45, %40
  %51 = getelementptr inbounds i8, ptr %0, i64 5
  %52 = load i8, ptr %51, align 1, !tbaa !22
  %53 = icmp slt i8 %52, 0
  br i1 %53, label %59, label %54

54:                                               ; preds = %50
  %55 = getelementptr inbounds i8, ptr %0, i64 48
  %56 = load ptr, ptr %55, align 8, !tbaa !28
  %57 = getelementptr inbounds i8, ptr %56, i64 16
  %58 = load i32, ptr %57, align 1, !tbaa !29
  %.not64 = icmp eq i32 %58, %25
  br i1 %.not64, label %94, label %59

59:                                               ; preds = %54, %50
  %60 = getelementptr inbounds i8, ptr %23, i64 40
  %61 = load i64, ptr %60, align 4, !tbaa !30
  %.not65 = icmp eq i64 %61, 0
  %.pre83 = load ptr, ptr %4, align 8, !tbaa !5
  br i1 %.not65, label %62, label %65

62:                                               ; preds = %59
  %63 = getelementptr inbounds i8, ptr %.pre83, i64 64
  %64 = load i64, ptr %63, align 8, !tbaa !31
  br label %65

65:                                               ; preds = %59, %62
  %66 = phi i64 [ %64, %62 ], [ %61, %59 ]
  %67 = getelementptr inbounds i8, ptr %.pre83, i64 4
  %68 = load i32, ptr %67, align 4, !tbaa !11
  %69 = and i32 %68, 131072
  %70 = icmp eq i32 %69, 0
  br i1 %70, label %.preheader, label %.loopexit

.preheader:                                       ; preds = %65
  %71 = icmp eq i64 %.fr78, 1
  br i1 %71, label %.preheader.split.us, label %.preheader.split

.preheader.split.us:                              ; preds = %.preheader, %75
  %.0.us = phi ptr [ %77, %75 ], [ %.pre83, %.preheader ]
  %72 = getelementptr inbounds i8, ptr %.0.us, i64 4
  %73 = load i32, ptr %72, align 4, !tbaa !11
  %74 = and i32 %73, 4
  %.not66.us = icmp eq i32 %74, 0
  br i1 %.not66.us, label %75, label %.split.us

75:                                               ; preds = %.preheader.split.us
  %76 = getelementptr inbounds i8, ptr %.0.us, i64 24
  %77 = load ptr, ptr %76, align 8, !tbaa !32
  %.not68.us = icmp eq ptr %77, null
  br i1 %.not68.us, label %.loopexit, label %.preheader.split.us, !prof !17, !llvm.loop !33

.preheader.split:                                 ; preds = %.preheader, %89
  %.0 = phi ptr [ %91, %89 ], [ %.pre83, %.preheader ]
  %78 = getelementptr inbounds i8, ptr %.0, i64 4
  %79 = load i32, ptr %78, align 4, !tbaa !11
  %80 = and i32 %79, 4
  %.not66 = icmp eq i32 %80, 0
  br i1 %.not66, label %89, label %81

81:                                               ; preds = %.preheader.split
  %82 = getelementptr inbounds i8, ptr %.0, i64 104
  %83 = load ptr, ptr %82, align 8, !tbaa !35
  %84 = getelementptr inbounds i8, ptr %83, i64 %.fr78
  %85 = load i8, ptr %84, align 1, !tbaa !22
  %86 = and i8 %85, 1
  %.not67 = icmp eq i8 %86, 0
  br i1 %.not67, label %89, label %.split.us

.split.us:                                        ; preds = %81, %.preheader.split.us
  %.us-phi = phi ptr [ %.0.us, %.preheader.split.us ], [ %.0, %81 ]
  %87 = getelementptr inbounds i8, ptr %.us-phi, i64 72
  %88 = load i64, ptr %87, align 8, !tbaa !36
  br label %.loopexit

89:                                               ; preds = %.preheader.split, %81
  %90 = getelementptr inbounds i8, ptr %.0, i64 24
  %91 = load ptr, ptr %90, align 8, !tbaa !32
  %.not68 = icmp eq ptr %91, null
  br i1 %.not68, label %.loopexit, label %.preheader.split, !prof !17, !llvm.loop !33

.loopexit:                                        ; preds = %89, %75, %.split.us, %65
  %.1 = phi i64 [ %66, %65 ], [ %88, %.split.us ], [ %66, %75 ], [ %66, %89 ]
  %92 = getelementptr inbounds i8, ptr %0, i64 48
  %93 = tail call i32 @page_get(ptr noundef %0, i32 noundef %25, ptr noundef nonnull %92, i64 noundef %.1)
  %.not69 = icmp eq i32 %93, 0
  br i1 %.not69, label %94, label %13

94:                                               ; preds = %.loopexit, %54
  store i8 0, ptr %51, align 1, !tbaa !22
  %95 = and i32 %2, 8
  %.not70 = icmp eq i32 %95, 0
  br i1 %.not70, label %102, label %96

96:                                               ; preds = %94
  %97 = getelementptr inbounds i8, ptr %0, i64 48
  %98 = load ptr, ptr %97, align 8, !tbaa !28
  %99 = tail call i64 @page_numkeys(ptr noundef %98) #7
  %100 = trunc i64 %99 to i16
  %101 = add i16 %100, -1
  br label %102

102:                                              ; preds = %94, %96
  %103 = phi i16 [ %101, %96 ], [ 0, %94 ]
  %104 = getelementptr inbounds i8, ptr %0, i64 304
  store i16 %103, ptr %104, align 8, !tbaa !37
  %105 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 26), align 2, !tbaa !18
  %106 = icmp ugt i8 %105, 4
  br i1 %106, label %107, label %114, !prof !21

107:                                              ; preds = %102
  %108 = tail call i32 @cursor_dbi_dbg(ptr noundef nonnull %0)
  %109 = getelementptr inbounds i8, ptr %0, i64 48
  %110 = load ptr, ptr %109, align 8, !tbaa !28
  %111 = getelementptr inbounds i8, ptr %110, i64 10
  %112 = load i16, ptr %111, align 1, !tbaa !37
  %113 = zext i16 %112 to i32
  tail call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef nonnull @__func__.tree_search, i32 noundef 75, ptr noundef nonnull @.str.7, i32 noundef %108, i32 noundef %25, i32 noundef %113) #6
  br label %114

114:                                              ; preds = %107, %102
  %115 = and i32 %2, 1
  %.not71 = icmp eq i32 %115, 0
  br i1 %.not71, label %118, label %116

116:                                              ; preds = %114
  %117 = tail call i32 @page_touch(ptr noundef nonnull %0)
  %.not72 = icmp eq i32 %117, 0
  br i1 %.not72, label %118, label %13, !prof !17

118:                                              ; preds = %116, %114
  %119 = and i32 %2, 2
  %.not73 = icmp eq i32 %119, 0
  br i1 %.not73, label %120, label %122

120:                                              ; preds = %118
  %121 = tail call i32 @tree_search_finalize(ptr noundef nonnull %0, ptr noundef %1, i32 noundef %2)
  br label %122

122:                                              ; preds = %118, %31, %34, %120, %13
  %.052 = phi i32 [ %.053, %13 ], [ %121, %120 ], [ -30798, %34 ], [ -30798, %31 ], [ 0, %118 ]
  ret i32 %.052
}

declare void @debug_log(i32 noundef, ptr noundef, i32 noundef, ptr noundef, ...) local_unnamed_addr #4

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

; Function Attrs: inlinehint mustprogress nofree nounwind willreturn memory(read) uwtable
declare hidden i64 @cursor_dbi(ptr noundef) local_unnamed_addr #5

; Function Attrs: inlinehint mustprogress nofree nounwind willreturn memory(read) uwtable
declare hidden ptr @cursor_dbi_state(ptr noundef) local_unnamed_addr #5

declare i32 @tbl_fetch(ptr noundef, i64 noundef) local_unnamed_addr #4

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

; Function Attrs: inlinehint mustprogress nofree nounwind willreturn memory(read) uwtable
declare hidden i64 @page_numkeys(ptr noundef) local_unnamed_addr #5

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

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

attributes #0 = { 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 #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 = { hot noinline 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 = { 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 #4 = { "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 = { 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 #6 = { nounwind }
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 = !{!6, !10, i64 16}
!6 = !{!"MDBX_cursor", !7, i64 0, !8, i64 4, !8, i64 6, !8, i64 7, !10, i64 8, !10, i64 16, !10, i64 24, !10, i64 32, !10, i64 40, !8, i64 48, !8, i64 304, !10, i64 368, !10, i64 376}
!7 = !{!"int", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C/C++ TBAA"}
!10 = !{!"any pointer", !8, i64 0}
!11 = !{!12, !7, i64 4}
!12 = !{!"MDBX_txn", !7, i64 0, !7, i64 4, !13, i64 8, !13, i64 16, !10, i64 24, !10, i64 32, !14, i64 40, !13, i64 64, !13, i64 72, !10, i64 80, !10, i64 88, !10, i64 96, !10, i64 104, !10, i64 112, !10, i64 120, !16, i64 128, !10, i64 160, !8, i64 168}
!13 = !{!"long", !8, i64 0}
!14 = !{!"geo", !15, i64 0, !15, i64 2, !7, i64 4, !7, i64 8, !8, i64 12, !8, i64 16}
!15 = !{!"short", !8, i64 0}
!16 = !{!"MDBX_canary", !13, i64 0, !13, i64 8, !13, i64 16, !13, i64 24}
!17 = !{!"branch_weights", !"expected", i32 2000, i32 1}
!18 = !{!19, !8, i64 26}
!19 = !{!"libmdbx_globals", !8, i64 0, !7, i64 16, !7, i64 20, !8, i64 24, !8, i64 25, !8, i64 26, !20, i64 27, !7, i64 28, !8, i64 32, !8, i64 40, !13, i64 80, !10, i64 88}
!20 = !{!"_Bool", !8, i64 0}
!21 = !{!"branch_weights", !"expected", i32 1, i32 2000}
!22 = !{!8, !8, i64 0}
!23 = !{!6, !10, i64 24}
!24 = !{!25, !7, i64 8}
!25 = !{!"tree", !15, i64 0, !15, i64 2, !7, i64 4, !7, i64 8, !7, i64 12, !7, i64 16, !7, i64 20, !13, i64 24, !13, i64 32, !13, i64 40}
!26 = !{!19, !8, i64 25}
!27 = !{!12, !10, i64 80}
!28 = !{!10, !10, i64 0}
!29 = !{!7, !7, i64 0}
!30 = !{!25, !13, i64 40}
!31 = !{!12, !13, i64 64}
!32 = !{!12, !10, i64 24}
!33 = distinct !{!33, !34}
!34 = !{!"llvm.loop.mustprogress"}
!35 = !{!12, !10, i64 104}
!36 = !{!12, !13, i64 72}
!37 = !{!15, !15, i64 0}


; Effective O3 passes: CorrelatedValuePropagationPass,EarlyCSEPass,GVNPass,GlobalOptPass,IPSCCPPass,InferFunctionAttrsPass,InstCombinePass,InstSimplifyPass,JumpThreadingPass,LCSSAPass,LICMPass,LoopSimplifyCFGPass,LoopSimplifyPass,LoopUnrollPass,LowerExpectIntrinsicPass,SROAPass,SimplifyCFGPass,TailCallElimPass