; 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.cursor_couple = type { %struct.MDBX_cursor, ptr, %struct.inner_cursor }
%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.inner_cursor = type { %struct.MDBX_cursor, %struct.tree }
%struct.tree = type { i16, i16, i32, i32, i32, i32, i32, i64, i64, i64 }
%struct.cursor_set_result = type { i32, i8 }
%struct.iovec = type { ptr, i64 }
%struct.clc2 = type { %struct.clc, %struct.clc }
%struct.clc = type { ptr, i64, i64 }
%struct.anon.1 = type { i8, i8 }

@globals = external global %struct.libmdbx_globals, align 8
@__func__.mdbx_estimate_range = external hidden unnamed_addr constant [20 x i8], align 1
@.str.1 = external hidden unnamed_addr constant [41 x i8], align 1
@.str.2 = external hidden unnamed_addr constant [43 x i8], align 1
@.str.3 = external hidden unnamed_addr constant [104 x i8], align 1

; Function Attrs: hot nounwind uwtable
declare dso_local i32 @mdbx_estimate_distance(ptr noundef, ptr noundef, ptr noundef) #0

; 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 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: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3

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

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

; Function Attrs: hot nounwind uwtable
define dso_local i32 @mdbx_estimate_range(ptr noundef %0, i32 noundef %1, ptr noundef %2, ptr noundef %3, ptr noundef %4, ptr noundef %5, ptr noundef %6) #0 {
  %8 = alloca i32, align 4
  %9 = alloca ptr, align 8
  %10 = alloca i32, align 4
  %11 = alloca ptr, align 8
  %12 = alloca ptr, align 8
  %13 = alloca ptr, align 8
  %14 = alloca ptr, align 8
  %15 = alloca ptr, align 8
  %16 = alloca i32, align 4
  %17 = alloca i32, align 4
  %18 = alloca %struct.cursor_couple, align 8
  %19 = alloca %struct.cursor_set_result, align 4
  %20 = alloca %struct.iovec, align 8
  %21 = alloca %struct.iovec, align 8
  %22 = alloca %struct.cursor_set_result, align 4
  %23 = alloca %struct.cursor_couple, align 8
  %24 = alloca %struct.iovec, align 8
  %25 = alloca %struct.iovec, align 8
  %26 = alloca %struct.cursor_set_result, align 4
  store ptr %0, ptr %9, align 8, !tbaa !5
  store i32 %1, ptr %10, align 4, !tbaa !9
  store ptr %2, ptr %11, align 8, !tbaa !5
  store ptr %3, ptr %12, align 8, !tbaa !5
  store ptr %4, ptr %13, align 8, !tbaa !5
  store ptr %5, ptr %14, align 8, !tbaa !5
  store ptr %6, ptr %15, align 8, !tbaa !5
  %27 = load ptr, ptr %15, align 8, !tbaa !5
  %28 = icmp ne ptr %27, null
  %29 = xor i1 %28, true
  %30 = xor i1 %29, true
  %31 = xor i1 %30, true
  %32 = zext i1 %31 to i32
  %33 = sext i32 %32 to i64
  %34 = call i64 @llvm.expect.i64(i64 %33, i64 0)
  %35 = icmp ne i64 %34, 0
  br i1 %35, label %36, label %38

36:                                               ; preds = %7
  %37 = call i32 @log_if_error(i32 noundef 22, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 234)
  store i32 %37, ptr %8, align 4
  br label %510

38:                                               ; preds = %7
  %39 = load ptr, ptr %12, align 8, !tbaa !5
  %40 = icmp ne ptr %39, null
  br i1 %40, label %41, label %49

41:                                               ; preds = %38
  %42 = load ptr, ptr %11, align 8, !tbaa !5
  %43 = icmp eq ptr %42, null
  br i1 %43, label %47, label %44

44:                                               ; preds = %41
  %45 = load ptr, ptr %11, align 8, !tbaa !5
  %46 = icmp eq ptr %45, inttoptr (i64 -1 to ptr)
  br label %47

47:                                               ; preds = %44, %41
  %48 = phi i1 [ true, %41 ], [ %46, %44 ]
  br label %49

49:                                               ; preds = %47, %38
  %50 = phi i1 [ false, %38 ], [ %48, %47 ]
  %51 = xor i1 %50, true
  %52 = xor i1 %51, true
  %53 = zext i1 %52 to i32
  %54 = sext i32 %53 to i64
  %55 = call i64 @llvm.expect.i64(i64 %54, i64 0)
  %56 = icmp ne i64 %55, 0
  br i1 %56, label %57, label %59

57:                                               ; preds = %49
  %58 = call i32 @log_if_error(i32 noundef 22, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 237)
  store i32 %58, ptr %8, align 4
  br label %510

59:                                               ; preds = %49
  %60 = load ptr, ptr %14, align 8, !tbaa !5
  %61 = icmp ne ptr %60, null
  br i1 %61, label %62, label %70

62:                                               ; preds = %59
  %63 = load ptr, ptr %13, align 8, !tbaa !5
  %64 = icmp eq ptr %63, null
  br i1 %64, label %68, label %65

65:                                               ; preds = %62
  %66 = load ptr, ptr %13, align 8, !tbaa !5
  %67 = icmp eq ptr %66, inttoptr (i64 -1 to ptr)
  br label %68

68:                                               ; preds = %65, %62
  %69 = phi i1 [ true, %62 ], [ %67, %65 ]
  br label %70

70:                                               ; preds = %68, %59
  %71 = phi i1 [ false, %59 ], [ %69, %68 ]
  %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 0)
  %77 = icmp ne i64 %76, 0
  br i1 %77, label %78, label %80

78:                                               ; preds = %70
  %79 = call i32 @log_if_error(i32 noundef 22, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 240)
  store i32 %79, ptr %8, align 4
  br label %510

80:                                               ; preds = %70
  %81 = load ptr, ptr %11, align 8, !tbaa !5
  %82 = icmp eq ptr %81, inttoptr (i64 -1 to ptr)
  br i1 %82, label %83, label %86

83:                                               ; preds = %80
  %84 = load ptr, ptr %13, align 8, !tbaa !5
  %85 = icmp eq ptr %84, inttoptr (i64 -1 to ptr)
  br label %86

86:                                               ; preds = %83, %80
  %87 = phi i1 [ false, %80 ], [ %85, %83 ]
  %88 = xor i1 %87, true
  %89 = xor i1 %88, true
  %90 = zext i1 %89 to i32
  %91 = sext i32 %90 to i64
  %92 = call i64 @llvm.expect.i64(i64 %91, i64 0)
  %93 = icmp ne i64 %92, 0
  br i1 %93, label %94, label %96

94:                                               ; preds = %86
  %95 = call i32 @log_if_error(i32 noundef 22, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 243)
  store i32 %95, ptr %8, align 4
  br label %510

96:                                               ; preds = %86
  call void @llvm.lifetime.start.p0(i64 4, ptr %16) #10
  %97 = load ptr, ptr %9, align 8, !tbaa !5
  %98 = call i32 @check_txn(ptr noundef %97, i32 noundef 51)
  store i32 %98, ptr %16, align 4, !tbaa !9
  %99 = load i32, ptr %16, align 4, !tbaa !9
  %100 = icmp ne i32 %99, 0
  %101 = xor i1 %100, true
  %102 = xor i1 %101, true
  %103 = zext i1 %102 to i32
  %104 = sext i32 %103 to i64
  %105 = call i64 @llvm.expect.i64(i64 %104, i64 0)
  %106 = icmp ne i64 %105, 0
  br i1 %106, label %107, label %110

107:                                              ; preds = %96
  %108 = load i32, ptr %16, align 4, !tbaa !9
  %109 = call i32 @log_if_error(i32 noundef %108, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 247)
  store i32 %109, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %509

110:                                              ; preds = %96
  call void @llvm.lifetime.start.p0(i64 824, ptr %18) #10
  %111 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %112 = load ptr, ptr %9, align 8, !tbaa !5
  %113 = load i32, ptr %10, align 4, !tbaa !9
  %114 = zext i32 %113 to i64
  %115 = call i32 @cursor_init(ptr noundef %111, ptr noundef %112, i64 noundef %114)
  store i32 %115, ptr %16, align 4, !tbaa !9
  %116 = load i32, ptr %16, align 4, !tbaa !9
  %117 = icmp ne i32 %116, 0
  %118 = xor i1 %117, true
  %119 = xor i1 %118, true
  %120 = zext i1 %119 to i32
  %121 = sext i32 %120 to i64
  %122 = call i64 @llvm.expect.i64(i64 %121, i64 0)
  %123 = icmp ne i64 %122, 0
  br i1 %123, label %124, label %127

124:                                              ; preds = %110
  %125 = load i32, ptr %16, align 4, !tbaa !9
  %126 = call i32 @log_if_error(i32 noundef %125, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 253)
  store i32 %126, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

127:                                              ; preds = %110
  %128 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %129 = getelementptr inbounds %struct.MDBX_cursor, ptr %128, i32 0, i32 6
  %130 = load ptr, ptr %129, align 8, !tbaa !11
  %131 = getelementptr inbounds %struct.tree, ptr %130, i32 0, i32 8
  %132 = load i64, ptr %131, align 4, !tbaa !18
  %133 = icmp eq i64 %132, 0
  %134 = xor i1 %133, true
  %135 = xor i1 %134, true
  %136 = zext i1 %135 to i32
  %137 = sext i32 %136 to i64
  %138 = call i64 @llvm.expect.i64(i64 %137, i64 0)
  %139 = icmp ne i64 %138, 0
  br i1 %139, label %140, label %142

140:                                              ; preds = %127
  %141 = load ptr, ptr %15, align 8, !tbaa !5
  store i64 0, ptr %141, align 8, !tbaa !19
  store i32 0, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

142:                                              ; preds = %127
  %143 = load ptr, ptr %11, align 8, !tbaa !5
  %144 = icmp ne ptr %143, null
  br i1 %144, label %186, label %145

145:                                              ; preds = %142
  %146 = load ptr, ptr %13, align 8, !tbaa !5
  %147 = icmp ne ptr %146, null
  %148 = xor i1 %147, true
  %149 = xor i1 %148, true
  %150 = xor i1 %149, true
  %151 = zext i1 %150 to i32
  %152 = sext i32 %151 to i64
  %153 = call i64 @llvm.expect.i64(i64 %152, i64 0)
  %154 = icmp ne i64 %153, 0
  br i1 %154, label %155, label %162

155:                                              ; preds = %145
  %156 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %157 = getelementptr inbounds %struct.MDBX_cursor, ptr %156, i32 0, i32 6
  %158 = load ptr, ptr %157, align 8, !tbaa !11
  %159 = getelementptr inbounds %struct.tree, ptr %158, i32 0, i32 8
  %160 = load i64, ptr %159, align 4, !tbaa !18
  %161 = load ptr, ptr %15, align 8, !tbaa !5
  store i64 %160, ptr %161, align 8, !tbaa !19
  store i32 0, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

162:                                              ; preds = %145
  %163 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %164 = call i32 @outer_first(ptr noundef %163, ptr noundef null, ptr noundef null)
  store i32 %164, ptr %16, align 4, !tbaa !9
  %165 = load ptr, ptr %13, align 8, !tbaa !5
  %166 = icmp eq ptr %165, inttoptr (i64 -1 to ptr)
  %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 %185

173:                                              ; preds = %162
  %174 = load i32, ptr %16, align 4, !tbaa !9
  %175 = icmp eq i32 %174, 0
  br i1 %175, label %176, label %180

176:                                              ; preds = %173
  %177 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %178 = load ptr, ptr %15, align 8, !tbaa !5
  %179 = call i32 @mdbx_cursor_count(ptr noundef %177, ptr noundef %178)
  br label %182

180:                                              ; preds = %173
  %181 = load i32, ptr %16, align 4, !tbaa !9
  br label %182

182:                                              ; preds = %180, %176
  %183 = phi i32 [ %179, %176 ], [ %181, %180 ]
  %184 = call i32 @log_if_error(i32 noundef %183, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 269)
  store i32 %184, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

185:                                              ; preds = %162
  br label %356

186:                                              ; preds = %142
  %187 = load ptr, ptr %11, align 8, !tbaa !5
  %188 = icmp eq ptr %187, inttoptr (i64 -1 to ptr)
  %189 = xor i1 %188, true
  %190 = xor i1 %189, true
  %191 = zext i1 %190 to i32
  %192 = sext i32 %191 to i64
  %193 = call i64 @llvm.expect.i64(i64 %192, i64 0)
  %194 = icmp ne i64 %193, 0
  br i1 %194, label %195, label %243

195:                                              ; preds = %186
  %196 = load ptr, ptr %13, align 8, !tbaa !5
  %197 = icmp eq ptr %196, null
  br i1 %197, label %198, label %212

198:                                              ; preds = %195
  %199 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %200 = call i32 @outer_last(ptr noundef %199, ptr noundef null, ptr noundef null)
  store i32 %200, ptr %16, align 4, !tbaa !9
  %201 = load i32, ptr %16, align 4, !tbaa !9
  %202 = icmp eq i32 %201, 0
  br i1 %202, label %203, label %207

203:                                              ; preds = %198
  %204 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %205 = load ptr, ptr %15, align 8, !tbaa !5
  %206 = call i32 @mdbx_cursor_count(ptr noundef %204, ptr noundef %205)
  br label %209

207:                                              ; preds = %198
  %208 = load i32, ptr %16, align 4, !tbaa !9
  br label %209

209:                                              ; preds = %207, %203
  %210 = phi i32 [ %206, %203 ], [ %208, %207 ]
  %211 = call i32 @log_if_error(i32 noundef %210, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 276)
  store i32 %211, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

212:                                              ; preds = %195
  br label %213

213:                                              ; preds = %212
  %214 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !20
  %215 = zext i8 %214 to i32
  %216 = and i32 %215, 1
  %217 = icmp ne i32 %216, 0
  %218 = xor i1 %217, true
  %219 = xor i1 %218, true
  %220 = zext i1 %219 to i32
  %221 = sext i32 %220 to i64
  %222 = call i64 @llvm.expect.i64(i64 %221, i64 1)
  %223 = icmp ne i64 %222, 0
  br i1 %223, label %224, label %239

224:                                              ; preds = %213
  br label %225

225:                                              ; preds = %224
  %226 = load ptr, ptr %13, align 8, !tbaa !5
  %227 = icmp ne ptr %226, inttoptr (i64 -1 to ptr)
  %228 = xor i1 %227, true
  %229 = xor i1 %228, true
  %230 = xor i1 %229, true
  %231 = zext i1 %230 to i32
  %232 = sext i32 %231 to i64
  %233 = call i64 @llvm.expect.i64(i64 %232, i64 0)
  %234 = icmp ne i64 %233, 0
  br i1 %234, label %235, label %236

235:                                              ; preds = %225
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.1, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 279) #11
  unreachable

236:                                              ; preds = %225
  br label %237

237:                                              ; preds = %236
  br label %238

238:                                              ; preds = %237
  br label %239

239:                                              ; preds = %238, %213
  br label %240

240:                                              ; preds = %239
  br label %241

241:                                              ; preds = %240
  %242 = load ptr, ptr %13, align 8, !tbaa !5
  store ptr %242, ptr %11, align 8, !tbaa !5
  br label %284

243:                                              ; preds = %186
  %244 = load ptr, ptr %13, align 8, !tbaa !5
  %245 = icmp eq ptr %244, inttoptr (i64 -1 to ptr)
  %246 = xor i1 %245, true
  %247 = xor i1 %246, true
  %248 = zext i1 %247 to i32
  %249 = sext i32 %248 to i64
  %250 = call i64 @llvm.expect.i64(i64 %249, i64 0)
  %251 = icmp ne i64 %250, 0
  br i1 %251, label %252, label %283

252:                                              ; preds = %243
  br label %253

253:                                              ; preds = %252
  %254 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !20
  %255 = zext i8 %254 to i32
  %256 = and i32 %255, 1
  %257 = icmp ne i32 %256, 0
  %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 1)
  %263 = icmp ne i64 %262, 0
  br i1 %263, label %264, label %279

264:                                              ; preds = %253
  br label %265

265:                                              ; preds = %264
  %266 = load ptr, ptr %11, align 8, !tbaa !5
  %267 = icmp ne ptr %266, inttoptr (i64 -1 to ptr)
  %268 = xor i1 %267, true
  %269 = xor i1 %268, true
  %270 = xor i1 %269, true
  %271 = zext i1 %270 to i32
  %272 = sext i32 %271 to i64
  %273 = call i64 @llvm.expect.i64(i64 %272, i64 0)
  %274 = icmp ne i64 %273, 0
  br i1 %274, label %275, label %276

275:                                              ; preds = %265
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.2, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 283) #11
  unreachable

276:                                              ; preds = %265
  br label %277

277:                                              ; preds = %276
  br label %278

278:                                              ; preds = %277
  br label %279

279:                                              ; preds = %278, %253
  br label %280

280:                                              ; preds = %279
  br label %281

281:                                              ; preds = %280
  %282 = load ptr, ptr %11, align 8, !tbaa !5
  store ptr %282, ptr %13, align 8, !tbaa !5
  br label %283

283:                                              ; preds = %281, %243
  br label %284

284:                                              ; preds = %283, %241
  %285 = load ptr, ptr %13, align 8, !tbaa !5
  %286 = icmp ne ptr %285, null
  br i1 %286, label %287, label %343

287:                                              ; preds = %284
  %288 = load ptr, ptr %12, align 8, !tbaa !5
  %289 = icmp ne ptr %288, null
  br i1 %289, label %343, label %290

290:                                              ; preds = %287
  %291 = load ptr, ptr %14, align 8, !tbaa !5
  %292 = icmp ne ptr %291, null
  br i1 %292, label %343, label %293

293:                                              ; preds = %290
  %294 = load ptr, ptr %11, align 8, !tbaa !5
  %295 = load ptr, ptr %13, align 8, !tbaa !5
  %296 = icmp eq ptr %294, %295
  br i1 %296, label %308, label %297

297:                                              ; preds = %293
  %298 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %299 = getelementptr inbounds %struct.MDBX_cursor, ptr %298, i32 0, i32 7
  %300 = load ptr, ptr %299, align 8, !tbaa !23
  %301 = getelementptr inbounds %struct.clc2, ptr %300, i32 0, i32 0
  %302 = getelementptr inbounds %struct.clc, ptr %301, i32 0, i32 0
  %303 = load ptr, ptr %302, align 8, !tbaa !24
  %304 = load ptr, ptr %11, align 8, !tbaa !5
  %305 = load ptr, ptr %13, align 8, !tbaa !5
  %306 = call i32 %303(ptr noundef %304, ptr noundef %305)
  %307 = icmp eq i32 %306, 0
  br i1 %307, label %308, label %343

308:                                              ; preds = %297, %293
  %309 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %310 = load ptr, ptr %11, align 8, !tbaa !5
  %311 = call i64 @cursor_seek(ptr noundef %309, ptr noundef %310, ptr noundef null, i32 noundef 15)
  store i64 %311, ptr %19, align 4
  %312 = getelementptr inbounds %struct.cursor_set_result, ptr %19, i32 0, i32 0
  %313 = load i32, ptr %312, align 4, !tbaa !27
  store i32 %313, ptr %16, align 4, !tbaa !9
  %314 = load i32, ptr %16, align 4, !tbaa !9
  %315 = icmp ne i32 %314, 0
  %316 = xor i1 %315, true
  %317 = xor i1 %316, true
  %318 = zext i1 %317 to i32
  %319 = sext i32 %318 to i64
  %320 = call i64 @llvm.expect.i64(i64 %319, i64 0)
  %321 = icmp ne i64 %320, 0
  br i1 %321, label %322, label %332

322:                                              ; preds = %308
  %323 = load ptr, ptr %15, align 8, !tbaa !5
  store i64 0, ptr %323, align 8, !tbaa !19
  %324 = load i32, ptr %16, align 4, !tbaa !9
  %325 = icmp eq i32 %324, -30798
  br i1 %325, label %326, label %327

326:                                              ; preds = %322
  br label %329

327:                                              ; preds = %322
  %328 = load i32, ptr %16, align 4, !tbaa !9
  br label %329

329:                                              ; preds = %327, %326
  %330 = phi i32 [ 0, %326 ], [ %328, %327 ]
  %331 = call i32 @log_if_error(i32 noundef %330, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 292)
  store i32 %331, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

332:                                              ; preds = %308
  %333 = load ptr, ptr %15, align 8, !tbaa !5
  store i64 1, ptr %333, align 8, !tbaa !19
  %334 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %335 = call zeroext i1 @inner_pointed(ptr noundef %334) #12
  br i1 %335, label %336, label %342

336:                                              ; preds = %332
  %337 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 2
  %338 = getelementptr inbounds %struct.inner_cursor, ptr %337, i32 0, i32 1
  %339 = getelementptr inbounds %struct.tree, ptr %338, i32 0, i32 8
  %340 = load i64, ptr %339, align 8, !tbaa !29
  %341 = load ptr, ptr %15, align 8, !tbaa !5
  store i64 %340, ptr %341, align 8, !tbaa !19
  br label %342

342:                                              ; preds = %336, %332
  store i32 0, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

343:                                              ; preds = %297, %290, %287, %284
  call void @llvm.lifetime.start.p0(i64 16, ptr %20) #10
  %344 = load ptr, ptr %11, align 8, !tbaa !5
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %20, ptr align 8 %344, i64 16, i1 false), !tbaa.struct !30
  call void @llvm.lifetime.start.p0(i64 16, ptr %21) #10
  call void @llvm.memset.p0.i64(ptr align 8 %21, i8 0, i64 16, i1 false)
  %345 = load ptr, ptr %12, align 8, !tbaa !5
  %346 = icmp ne ptr %345, null
  br i1 %346, label %347, label %349

347:                                              ; preds = %343
  %348 = load ptr, ptr %12, align 8, !tbaa !5
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %21, ptr align 8 %348, i64 16, i1 false), !tbaa.struct !30
  br label %349

349:                                              ; preds = %347, %343
  %350 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %351 = call i64 @cursor_seek(ptr noundef %350, ptr noundef %20, ptr noundef %21, i32 noundef 19)
  store i64 %351, ptr %22, align 4
  %352 = getelementptr inbounds %struct.cursor_set_result, ptr %22, i32 0, i32 0
  %353 = load i32, ptr %352, align 4, !tbaa !27
  %354 = call i32 @log_if_error(i32 noundef %353, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 307)
  store i32 %354, ptr %16, align 4, !tbaa !9
  call void @llvm.lifetime.end.p0(i64 16, ptr %21) #10
  call void @llvm.lifetime.end.p0(i64 16, ptr %20) #10
  br label %355

355:                                              ; preds = %349
  br label %356

356:                                              ; preds = %355, %185
  %357 = load i32, ptr %16, align 4, !tbaa !9
  %358 = icmp ne i32 %357, 0
  %359 = xor i1 %358, true
  %360 = xor i1 %359, true
  %361 = zext i1 %360 to i32
  %362 = sext i32 %361 to i64
  %363 = call i64 @llvm.expect.i64(i64 %362, i64 0)
  %364 = icmp ne i64 %363, 0
  br i1 %364, label %365, label %375

365:                                              ; preds = %356
  %366 = load i32, ptr %16, align 4, !tbaa !9
  %367 = icmp ne i32 %366, -30798
  br i1 %367, label %371, label %368

368:                                              ; preds = %365
  %369 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %370 = call zeroext i1 @is_pointed(ptr noundef %369) #12
  br i1 %370, label %374, label %371

371:                                              ; preds = %368, %365
  %372 = load i32, ptr %16, align 4, !tbaa !9
  %373 = call i32 @log_if_error(i32 noundef %372, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 313)
  store i32 %373, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %508

374:                                              ; preds = %368
  br label %375

375:                                              ; preds = %374, %356
  call void @llvm.lifetime.start.p0(i64 824, ptr %23) #10
  %376 = getelementptr inbounds %struct.cursor_couple, ptr %23, i32 0, i32 0
  %377 = load ptr, ptr %9, align 8, !tbaa !5
  %378 = load i32, ptr %10, align 4, !tbaa !9
  %379 = zext i32 %378 to i64
  %380 = call i32 @cursor_init(ptr noundef %376, ptr noundef %377, i64 noundef %379)
  store i32 %380, ptr %16, align 4, !tbaa !9
  %381 = load i32, ptr %16, align 4, !tbaa !9
  %382 = icmp ne i32 %381, 0
  %383 = xor i1 %382, true
  %384 = xor i1 %383, true
  %385 = zext i1 %384 to i32
  %386 = sext i32 %385 to i64
  %387 = call i64 @llvm.expect.i64(i64 %386, i64 0)
  %388 = icmp ne i64 %387, 0
  br i1 %388, label %389, label %392

389:                                              ; preds = %375
  %390 = load i32, ptr %16, align 4, !tbaa !9
  %391 = call i32 @log_if_error(i32 noundef %390, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 319)
  store i32 %391, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %507

392:                                              ; preds = %375
  %393 = load ptr, ptr %13, align 8, !tbaa !5
  %394 = icmp ne ptr %393, null
  br i1 %394, label %413, label %395

395:                                              ; preds = %392
  %396 = getelementptr inbounds %struct.cursor_couple, ptr %23, i32 0, i32 0
  %397 = call i32 @outer_last(ptr noundef %396, ptr noundef null, ptr noundef null)
  store i32 %397, ptr %16, align 4, !tbaa !9
  %398 = getelementptr inbounds %struct.cursor_couple, ptr %23, i32 0, i32 0
  %399 = getelementptr inbounds %struct.MDBX_cursor, ptr %398, i32 0, i32 1
  %400 = getelementptr inbounds %struct.anon.1, ptr %399, i32 0, i32 0
  %401 = load i8, ptr %400, align 4, !tbaa !31
  %402 = sext i8 %401 to i32
  %403 = or i32 %402, 64
  %404 = trunc i32 %403 to i8
  store i8 %404, ptr %400, align 4, !tbaa !31
  %405 = getelementptr inbounds %struct.cursor_couple, ptr %23, i32 0, i32 2
  %406 = getelementptr inbounds %struct.inner_cursor, ptr %405, i32 0, i32 0
  %407 = getelementptr inbounds %struct.MDBX_cursor, ptr %406, i32 0, i32 1
  %408 = getelementptr inbounds %struct.anon.1, ptr %407, i32 0, i32 0
  %409 = load i8, ptr %408, align 4, !tbaa !31
  %410 = sext i8 %409 to i32
  %411 = or i32 %410, 64
  %412 = trunc i32 %411 to i8
  store i8 %412, ptr %408, align 4, !tbaa !31
  br label %424

413:                                              ; preds = %392
  call void @llvm.lifetime.start.p0(i64 16, ptr %24) #10
  %414 = load ptr, ptr %13, align 8, !tbaa !5
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %24, ptr align 8 %414, i64 16, i1 false), !tbaa.struct !30
  call void @llvm.lifetime.start.p0(i64 16, ptr %25) #10
  call void @llvm.memset.p0.i64(ptr align 8 %25, i8 0, i64 16, i1 false)
  %415 = load ptr, ptr %14, align 8, !tbaa !5
  %416 = icmp ne ptr %415, null
  br i1 %416, label %417, label %419

417:                                              ; preds = %413
  %418 = load ptr, ptr %14, align 8, !tbaa !5
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %25, ptr align 8 %418, i64 16, i1 false), !tbaa.struct !30
  br label %419

419:                                              ; preds = %417, %413
  %420 = getelementptr inbounds %struct.cursor_couple, ptr %23, i32 0, i32 0
  %421 = call i64 @cursor_seek(ptr noundef %420, ptr noundef %24, ptr noundef %25, i32 noundef 19)
  store i64 %421, ptr %26, align 4
  %422 = getelementptr inbounds %struct.cursor_set_result, ptr %26, i32 0, i32 0
  %423 = load i32, ptr %422, align 4, !tbaa !27
  store i32 %423, ptr %16, align 4, !tbaa !9
  call void @llvm.lifetime.end.p0(i64 16, ptr %25) #10
  call void @llvm.lifetime.end.p0(i64 16, ptr %24) #10
  br label %424

424:                                              ; preds = %419, %395
  %425 = load i32, ptr %16, align 4, !tbaa !9
  %426 = icmp ne i32 %425, 0
  %427 = xor i1 %426, true
  %428 = xor i1 %427, true
  %429 = zext i1 %428 to i32
  %430 = sext i32 %429 to i64
  %431 = call i64 @llvm.expect.i64(i64 %430, i64 0)
  %432 = icmp ne i64 %431, 0
  br i1 %432, label %433, label %443

433:                                              ; preds = %424
  %434 = load i32, ptr %16, align 4, !tbaa !9
  %435 = icmp ne i32 %434, -30798
  br i1 %435, label %439, label %436

436:                                              ; preds = %433
  %437 = getelementptr inbounds %struct.cursor_couple, ptr %23, i32 0, i32 0
  %438 = call zeroext i1 @is_pointed(ptr noundef %437) #12
  br i1 %438, label %442, label %439

439:                                              ; preds = %436, %433
  %440 = load i32, ptr %16, align 4, !tbaa !9
  %441 = call i32 @log_if_error(i32 noundef %440, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 333)
  store i32 %441, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %507

442:                                              ; preds = %436
  br label %443

443:                                              ; preds = %442, %424
  %444 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %445 = getelementptr inbounds %struct.cursor_couple, ptr %23, i32 0, i32 0
  %446 = load ptr, ptr %15, align 8, !tbaa !5
  %447 = call i32 @mdbx_estimate_distance(ptr noundef %444, ptr noundef %445, ptr noundef %446) #13
  store i32 %447, ptr %16, align 4, !tbaa !9
  %448 = load i32, ptr %16, align 4, !tbaa !9
  %449 = icmp ne i32 %448, 0
  %450 = xor i1 %449, true
  %451 = xor i1 %450, true
  %452 = zext i1 %451 to i32
  %453 = sext i32 %452 to i64
  %454 = call i64 @llvm.expect.i64(i64 %453, i64 0)
  %455 = icmp ne i64 %454, 0
  br i1 %455, label %456, label %459

456:                                              ; preds = %443
  %457 = load i32, ptr %16, align 4, !tbaa !9
  %458 = call i32 @log_if_error(i32 noundef %457, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 338)
  store i32 %458, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %507

459:                                              ; preds = %443
  br label %460

460:                                              ; preds = %459
  %461 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !20
  %462 = zext i8 %461 to i32
  %463 = and i32 %462, 1
  %464 = icmp ne i32 %463, 0
  %465 = xor i1 %464, true
  %466 = xor i1 %465, true
  %467 = zext i1 %466 to i32
  %468 = sext i32 %467 to i64
  %469 = call i64 @llvm.expect.i64(i64 %468, i64 1)
  %470 = icmp ne i64 %469, 0
  br i1 %470, label %471, label %504

471:                                              ; preds = %460
  br label %472

472:                                              ; preds = %471
  %473 = load ptr, ptr %15, align 8, !tbaa !5
  %474 = load i64, ptr %473, align 8, !tbaa !19
  %475 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %476 = getelementptr inbounds %struct.MDBX_cursor, ptr %475, i32 0, i32 6
  %477 = load ptr, ptr %476, align 8, !tbaa !11
  %478 = getelementptr inbounds %struct.tree, ptr %477, i32 0, i32 8
  %479 = load i64, ptr %478, align 4, !tbaa !18
  %480 = sub nsw i64 0, %479
  %481 = icmp sge i64 %474, %480
  br i1 %481, label %482, label %491

482:                                              ; preds = %472
  %483 = load ptr, ptr %15, align 8, !tbaa !5
  %484 = load i64, ptr %483, align 8, !tbaa !19
  %485 = getelementptr inbounds %struct.cursor_couple, ptr %18, i32 0, i32 0
  %486 = getelementptr inbounds %struct.MDBX_cursor, ptr %485, i32 0, i32 6
  %487 = load ptr, ptr %486, align 8, !tbaa !11
  %488 = getelementptr inbounds %struct.tree, ptr %487, i32 0, i32 8
  %489 = load i64, ptr %488, align 4, !tbaa !18
  %490 = icmp sle i64 %484, %489
  br label %491

491:                                              ; preds = %482, %472
  %492 = phi i1 [ false, %472 ], [ %490, %482 ]
  %493 = xor i1 %492, true
  %494 = xor i1 %493, true
  %495 = xor i1 %494, true
  %496 = zext i1 %495 to i32
  %497 = sext i32 %496 to i64
  %498 = call i64 @llvm.expect.i64(i64 %497, i64 0)
  %499 = icmp ne i64 %498, 0
  br i1 %499, label %500, label %501

500:                                              ; preds = %491
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.3, ptr noundef @__func__.mdbx_estimate_range, i32 noundef 339) #11
  unreachable

501:                                              ; preds = %491
  br label %502

502:                                              ; preds = %501
  br label %503

503:                                              ; preds = %502
  br label %504

504:                                              ; preds = %503, %460
  br label %505

505:                                              ; preds = %504
  br label %506

506:                                              ; preds = %505
  store i32 0, ptr %8, align 4
  store i32 1, ptr %17, align 4
  br label %507

507:                                              ; preds = %506, %456, %439, %389
  call void @llvm.lifetime.end.p0(i64 824, ptr %23) #10
  br label %508

508:                                              ; preds = %507, %371, %342, %329, %209, %182, %155, %140, %124
  call void @llvm.lifetime.end.p0(i64 824, ptr %18) #10
  br label %509

509:                                              ; preds = %508, %107
  call void @llvm.lifetime.end.p0(i64 4, ptr %16) #10
  br label %510

510:                                              ; preds = %509, %94, %78, %57, %36
  %511 = load i32, ptr %8, align 4
  ret i32 %511
}

; Function Attrs: alwaysinline nounwind uwtable
declare hidden i32 @check_txn(ptr noundef, i32 noundef) #7

declare i32 @outer_first(ptr noundef, ptr noundef, ptr noundef) #6

declare i32 @mdbx_cursor_count(ptr noundef, ptr noundef) #6

declare i32 @outer_last(ptr noundef, ptr noundef, ptr noundef) #6

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

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #8

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #9

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 = { "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 = { alwaysinline 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 #8 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #9 = { nocallback nofree nounwind willreturn memory(argmem: write) }
attributes #10 = { nounwind }
attributes #11 = { noreturn }
attributes #12 = { nounwind willreturn memory(read) }
attributes #13 = { hot }

!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 24}
!12 = !{!"cursor_couple", !13, i64 0, !6, i64 384, !14, i64 392}
!13 = !{!"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}
!14 = !{!"inner_cursor", !13, i64 0, !15, i64 384}
!15 = !{!"tree", !16, i64 0, !16, i64 2, !10, i64 4, !10, i64 8, !10, i64 12, !10, i64 16, !10, i64 20, !17, i64 24, !17, i64 32, !17, i64 40}
!16 = !{!"short", !7, i64 0}
!17 = !{!"long", !7, i64 0}
!18 = !{!15, !17, i64 32}
!19 = !{!17, !17, i64 0}
!20 = !{!21, !7, i64 25}
!21 = !{!"libmdbx_globals", !7, i64 0, !10, i64 16, !10, i64 20, !7, i64 24, !7, i64 25, !7, i64 26, !22, i64 27, !10, i64 28, !7, i64 32, !7, i64 40, !17, i64 80, !6, i64 88}
!22 = !{!"_Bool", !7, i64 0}
!23 = !{!12, !6, i64 32}
!24 = !{!25, !6, i64 0}
!25 = !{!"clc2", !26, i64 0, !26, i64 24}
!26 = !{!"clc", !6, i64 0, !17, i64 8, !17, i64 16}
!27 = !{!28, !10, i64 0}
!28 = !{!"cursor_set_result", !10, i64 0, !22, i64 4}
!29 = !{!12, !17, i64 808}
!30 = !{i64 0, i64 8, !5, i64 8, i64 8, !19}
!31 = !{!7, !7, 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 }
%struct.cursor_couple = type { %struct.MDBX_cursor, ptr, %struct.inner_cursor }
%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.inner_cursor = type { %struct.MDBX_cursor, %struct.tree }
%struct.tree = type { i16, i16, i32, i32, i32, i32, i32, i64, i64, i64 }
%struct.iovec = type { ptr, i64 }

@globals = external local_unnamed_addr global %struct.libmdbx_globals, align 8
@__func__.mdbx_estimate_range = external hidden unnamed_addr constant [20 x i8], align 1
@.str.1 = external hidden unnamed_addr constant [41 x i8], align 1
@.str.3 = external hidden unnamed_addr constant [104 x i8], align 1

; Function Attrs: hot nounwind uwtable
declare dso_local i32 @mdbx_estimate_distance(ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #0

; 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 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: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2

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

declare i32 @cursor_init(ptr noundef, ptr noundef, i64 noundef) local_unnamed_addr #5

; Function Attrs: hot nounwind uwtable
define dso_local i32 @mdbx_estimate_range(ptr noundef %0, i32 noundef %1, ptr noundef %2, ptr noundef readonly %3, ptr noundef %4, ptr noundef readonly %5, ptr noundef %6) local_unnamed_addr #0 {
  %8 = alloca %struct.cursor_couple, align 8
  %9 = alloca %struct.iovec, align 8
  %10 = alloca %struct.iovec, align 8
  %11 = alloca %struct.cursor_couple, align 8
  %12 = alloca %struct.iovec, align 8
  %13 = alloca %struct.iovec, align 8
  %.not = icmp eq ptr %6, null
  br i1 %.not, label %14, label %16, !prof !5

14:                                               ; preds = %7
  %15 = tail call i32 @log_if_error(i32 noundef 22, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 234)
  br label %145

16:                                               ; preds = %7
  %17 = icmp ne ptr %3, null
  br i1 %17, label %18, label %.critedge

18:                                               ; preds = %16
  %magicptr = ptrtoint ptr %2 to i64
  switch i64 %magicptr, label %.critedge [
    i64 -1, label %19
    i64 0, label %19
  ]

19:                                               ; preds = %18, %18
  %20 = tail call i32 @log_if_error(i32 noundef 22, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 237)
  br label %145

.critedge:                                        ; preds = %18, %16
  %21 = icmp ne ptr %5, null
  br i1 %21, label %22, label %.critedge114

22:                                               ; preds = %.critedge
  %magicptr116 = ptrtoint ptr %4 to i64
  switch i64 %magicptr116, label %.critedge114 [
    i64 -1, label %23
    i64 0, label %23
  ]

23:                                               ; preds = %22, %22
  %24 = tail call i32 @log_if_error(i32 noundef 22, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 240)
  br label %145

.critedge114:                                     ; preds = %22, %.critedge
  %25 = icmp eq ptr %2, inttoptr (i64 -1 to ptr)
  %26 = icmp eq ptr %4, inttoptr (i64 -1 to ptr)
  %27 = and i1 %25, %26
  br i1 %27, label %28, label %30, !prof !5

28:                                               ; preds = %.critedge114
  %29 = tail call i32 @log_if_error(i32 noundef 22, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 243)
  br label %145

30:                                               ; preds = %.critedge114
  %31 = tail call i32 @check_txn(ptr noundef %0, i32 noundef 51)
  %.not96 = icmp eq i32 %31, 0
  br i1 %.not96, label %34, label %32, !prof !6

32:                                               ; preds = %30
  %33 = tail call i32 @log_if_error(i32 noundef %31, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 247)
  br label %145

34:                                               ; preds = %30
  call void @llvm.lifetime.start.p0(i64 824, ptr nonnull %8) #9
  %35 = zext i32 %1 to i64
  %36 = call i32 @cursor_init(ptr noundef nonnull %8, ptr noundef %0, i64 noundef %35) #9
  %.not97 = icmp eq i32 %36, 0
  br i1 %.not97, label %39, label %37, !prof !6

37:                                               ; preds = %34
  %38 = call i32 @log_if_error(i32 noundef %36, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 253)
  br label %144

39:                                               ; preds = %34
  %40 = getelementptr inbounds i8, ptr %8, i64 24
  %41 = load ptr, ptr %40, align 8, !tbaa !7
  %42 = getelementptr inbounds i8, ptr %41, i64 32
  %43 = load i64, ptr %42, align 4, !tbaa !18
  %44 = icmp eq i64 %43, 0
  br i1 %44, label %45, label %46, !prof !5

45:                                               ; preds = %39
  store i64 0, ptr %6, align 8, !tbaa !19
  br label %144

46:                                               ; preds = %39
  %.not98 = icmp eq ptr %2, null
  br i1 %.not98, label %47, label %58

47:                                               ; preds = %46
  %.not99 = icmp eq ptr %4, null
  br i1 %.not99, label %48, label %49, !prof !5

48:                                               ; preds = %47
  store i64 %43, ptr %6, align 8, !tbaa !19
  br label %144

49:                                               ; preds = %47
  %50 = call i32 @outer_first(ptr noundef nonnull %8, ptr noundef null, ptr noundef null) #9
  br i1 %26, label %51, label %101, !prof !5

51:                                               ; preds = %49
  %52 = icmp eq i32 %50, 0
  br i1 %52, label %53, label %55

53:                                               ; preds = %51
  %54 = call i32 @mdbx_cursor_count(ptr noundef nonnull %8, ptr noundef nonnull %6) #9
  br label %55

55:                                               ; preds = %51, %53
  %56 = phi i32 [ %54, %53 ], [ %50, %51 ]
  %57 = call i32 @log_if_error(i32 noundef %56, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 269)
  br label %144

58:                                               ; preds = %46
  br i1 %25, label %59, label %73, !prof !5

59:                                               ; preds = %58
  %60 = icmp eq ptr %4, null
  br i1 %60, label %61, label %69

61:                                               ; preds = %59
  %62 = call i32 @outer_last(ptr noundef nonnull %8, ptr noundef null, ptr noundef null) #9
  %63 = icmp eq i32 %62, 0
  br i1 %63, label %64, label %66

64:                                               ; preds = %61
  %65 = call i32 @mdbx_cursor_count(ptr noundef nonnull %8, ptr noundef nonnull %6) #9
  br label %66

66:                                               ; preds = %61, %64
  %67 = phi i32 [ %65, %64 ], [ %62, %61 ]
  %68 = call i32 @log_if_error(i32 noundef %67, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 276)
  br label %144

69:                                               ; preds = %59
  %70 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !20
  %71 = and i8 %70, 1
  %.not101 = icmp ne i8 %71, 0
  %or.cond115 = and i1 %26, %.not101
  br i1 %or.cond115, label %72, label %75, !prof !23

72:                                               ; preds = %69
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.1, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 279) #10
  unreachable

73:                                               ; preds = %58
  br i1 %26, label %74, label %75, !prof !5

74:                                               ; preds = %73
  br label %75

75:                                               ; preds = %69, %73, %74
  %.078 = phi ptr [ %2, %74 ], [ %4, %73 ], [ %4, %69 ]
  %.077 = phi ptr [ %2, %74 ], [ %2, %73 ], [ %4, %69 ]
  %76 = icmp eq ptr %.078, null
  %or.cond = or i1 %17, %76
  %or.cond3 = or i1 %21, %or.cond
  br i1 %or.cond3, label %96, label %77

77:                                               ; preds = %75
  %78 = icmp eq ptr %.077, %.078
  br i1 %78, label %85, label %79

79:                                               ; preds = %77
  %80 = getelementptr inbounds i8, ptr %8, i64 32
  %81 = load ptr, ptr %80, align 8, !tbaa !24
  %82 = load ptr, ptr %81, align 8, !tbaa !25
  %83 = call i32 %82(ptr noundef nonnull %.077, ptr noundef nonnull %.078) #9
  %84 = icmp eq i32 %83, 0
  br i1 %84, label %85, label %.thread

.thread:                                          ; preds = %79
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %9) #9
  call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %9, ptr noundef nonnull align 8 dereferenceable(16) %.077, i64 16, i1 false), !tbaa.struct !28
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %10) #9
  call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %10, i8 0, i64 16, i1 false)
  br label %98

85:                                               ; preds = %79, %77
  %86 = call i64 @cursor_seek(ptr noundef nonnull %8, ptr noundef nonnull %.077, ptr noundef null, i32 noundef 15) #9
  %.sroa.06.0.extract.trunc = trunc i64 %86 to i32
  %.not103 = icmp eq i32 %.sroa.06.0.extract.trunc, 0
  br i1 %.not103, label %91, label %87, !prof !6

87:                                               ; preds = %85
  store i64 0, ptr %6, align 8, !tbaa !19
  %88 = icmp eq i32 %.sroa.06.0.extract.trunc, -30798
  %89 = select i1 %88, i32 0, i32 %.sroa.06.0.extract.trunc
  %90 = call i32 @log_if_error(i32 noundef %89, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 292)
  br label %144

91:                                               ; preds = %85
  store i64 1, ptr %6, align 8, !tbaa !19
  %92 = call zeroext i1 @inner_pointed(ptr noundef nonnull %8) #11
  br i1 %92, label %93, label %144

93:                                               ; preds = %91
  %94 = getelementptr inbounds i8, ptr %8, i64 808
  %95 = load i64, ptr %94, align 8, !tbaa !30
  store i64 %95, ptr %6, align 8, !tbaa !19
  br label %144

96:                                               ; preds = %75
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %9) #9
  call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %9, ptr noundef nonnull align 8 dereferenceable(16) %.077, i64 16, i1 false), !tbaa.struct !28
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %10) #9
  call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %10, i8 0, i64 16, i1 false)
  br i1 %17, label %97, label %98

97:                                               ; preds = %96
  call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %10, ptr noundef nonnull align 8 dereferenceable(16) %3, i64 16, i1 false), !tbaa.struct !28
  br label %98

98:                                               ; preds = %.thread, %97, %96
  %99 = call i64 @cursor_seek(ptr noundef nonnull %8, ptr noundef nonnull %9, ptr noundef nonnull %10, i32 noundef 19) #9
  %.sroa.04.0.extract.trunc = trunc i64 %99 to i32
  %100 = call i32 @log_if_error(i32 noundef %.sroa.04.0.extract.trunc, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 307)
  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %10) #9
  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %9) #9
  br label %101

101:                                              ; preds = %49, %98
  %.080 = phi i32 [ %100, %98 ], [ %50, %49 ]
  %.179 = phi ptr [ %.078, %98 ], [ %4, %49 ]
  switch i32 %.080, label %104 [
    i32 0, label %106
    i32 -30798, label %102
  ], !prof !31

102:                                              ; preds = %101
  %103 = call zeroext i1 @is_pointed(ptr noundef nonnull %8) #11
  br i1 %103, label %106, label %104

104:                                              ; preds = %101, %102
  %105 = call i32 @log_if_error(i32 noundef %.080, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 313)
  br label %144

106:                                              ; preds = %101, %102
  call void @llvm.lifetime.start.p0(i64 824, ptr nonnull %11) #9
  %107 = call i32 @cursor_init(ptr noundef nonnull %11, ptr noundef %0, i64 noundef %35) #9
  %.not106 = icmp eq i32 %107, 0
  br i1 %.not106, label %110, label %108, !prof !6

108:                                              ; preds = %106
  %109 = call i32 @log_if_error(i32 noundef %107, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 319)
  br label %143

110:                                              ; preds = %106
  %.not107 = icmp eq ptr %.179, null
  br i1 %.not107, label %111, label %119

111:                                              ; preds = %110
  %112 = call i32 @outer_last(ptr noundef nonnull %11, ptr noundef null, ptr noundef null) #9
  %113 = getelementptr inbounds i8, ptr %11, i64 4
  %114 = load i8, ptr %113, align 4, !tbaa !32
  %115 = or i8 %114, 64
  store i8 %115, ptr %113, align 4, !tbaa !32
  %116 = getelementptr inbounds i8, ptr %11, i64 396
  %117 = load i8, ptr %116, align 4, !tbaa !32
  %118 = or i8 %117, 64
  store i8 %118, ptr %116, align 4, !tbaa !32
  br label %123

119:                                              ; preds = %110
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %12) #9
  call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %12, ptr noundef nonnull align 8 dereferenceable(16) %.179, i64 16, i1 false), !tbaa.struct !28
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %13) #9
  call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %13, i8 0, i64 16, i1 false)
  br i1 %21, label %120, label %121

120:                                              ; preds = %119
  call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %13, ptr noundef nonnull align 8 dereferenceable(16) %5, i64 16, i1 false), !tbaa.struct !28
  br label %121

121:                                              ; preds = %120, %119
  %122 = call i64 @cursor_seek(ptr noundef nonnull %11, ptr noundef nonnull %12, ptr noundef nonnull %13, i32 noundef 19) #9
  %.sroa.0.0.extract.trunc = trunc i64 %122 to i32
  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %13) #9
  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %12) #9
  br label %123

123:                                              ; preds = %121, %111
  %.181 = phi i32 [ %.sroa.0.0.extract.trunc, %121 ], [ %112, %111 ]
  switch i32 %.181, label %126 [
    i32 0, label %128
    i32 -30798, label %124
  ], !prof !31

124:                                              ; preds = %123
  %125 = call zeroext i1 @is_pointed(ptr noundef nonnull %11) #11
  br i1 %125, label %128, label %126

126:                                              ; preds = %123, %124
  %127 = call i32 @log_if_error(i32 noundef %.181, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 333)
  br label %143

128:                                              ; preds = %123, %124
  %129 = call i32 @mdbx_estimate_distance(ptr noundef nonnull %8, ptr noundef nonnull %11, ptr noundef nonnull %6) #12
  %.not110 = icmp eq i32 %129, 0
  br i1 %.not110, label %132, label %130, !prof !6

130:                                              ; preds = %128
  %131 = call i32 @log_if_error(i32 noundef %129, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 338)
  br label %143

132:                                              ; preds = %128
  %133 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !20
  %134 = and i8 %133, 1
  %.not111 = icmp eq i8 %134, 0
  br i1 %.not111, label %143, label %135, !prof !5

135:                                              ; preds = %132
  %136 = load i64, ptr %6, align 8, !tbaa !19
  %137 = load ptr, ptr %40, align 8, !tbaa !7
  %138 = getelementptr inbounds i8, ptr %137, i64 32
  %139 = load i64, ptr %138, align 4, !tbaa !18
  %140 = sub nsw i64 0, %139
  %.not112 = icmp slt i64 %136, %140
  %141 = icmp sgt i64 %136, %139
  %spec.select = or i1 %.not112, %141
  br i1 %spec.select, label %142, label %143, !prof !5

142:                                              ; preds = %135
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.3, ptr noundef nonnull @__func__.mdbx_estimate_range, i32 noundef 339) #10
  unreachable

143:                                              ; preds = %132, %135, %130, %126, %108
  %.0 = phi i32 [ %109, %108 ], [ %127, %126 ], [ %131, %130 ], [ 0, %135 ], [ 0, %132 ]
  call void @llvm.lifetime.end.p0(i64 824, ptr nonnull %11) #9
  br label %144

144:                                              ; preds = %91, %93, %143, %104, %87, %66, %55, %48, %45, %37
  %.1 = phi i32 [ %38, %37 ], [ 0, %45 ], [ %68, %66 ], [ %105, %104 ], [ %.0, %143 ], [ %90, %87 ], [ 0, %48 ], [ %57, %55 ], [ 0, %93 ], [ 0, %91 ]
  call void @llvm.lifetime.end.p0(i64 824, ptr nonnull %8) #9
  br label %145

145:                                              ; preds = %32, %144, %28, %23, %19, %14
  %.3 = phi i32 [ %15, %14 ], [ %20, %19 ], [ %24, %23 ], [ %29, %28 ], [ %33, %32 ], [ %.1, %144 ]
  ret i32 %.3
}

; Function Attrs: alwaysinline nounwind uwtable
declare hidden i32 @check_txn(ptr noundef, i32 noundef) local_unnamed_addr #6

declare i32 @outer_first(ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #5

declare i32 @mdbx_cursor_count(ptr noundef, ptr noundef) local_unnamed_addr #5

declare i32 @outer_last(ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #5

declare i64 @cursor_seek(ptr noundef, ptr noundef, ptr noundef, i32 noundef) local_unnamed_addr #5

; Function Attrs: mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #7

; Function Attrs: mustprogress nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #8

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 = { "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 = { alwaysinline 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 #7 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #8 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: write) }
attributes #9 = { nounwind }
attributes #10 = { noreturn nounwind }
attributes #11 = { nounwind willreturn memory(read) }
attributes #12 = { hot }

!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, !13, i64 24}
!8 = !{!"cursor_couple", !9, i64 0, !13, i64 384, !14, i64 392}
!9 = !{!"MDBX_cursor", !10, i64 0, !11, i64 4, !11, i64 6, !11, i64 7, !13, i64 8, !13, i64 16, !13, i64 24, !13, i64 32, !13, i64 40, !11, i64 48, !11, i64 304, !13, i64 368, !13, i64 376}
!10 = !{!"int", !11, i64 0}
!11 = !{!"omnipotent char", !12, i64 0}
!12 = !{!"Simple C/C++ TBAA"}
!13 = !{!"any pointer", !11, i64 0}
!14 = !{!"inner_cursor", !9, i64 0, !15, i64 384}
!15 = !{!"tree", !16, i64 0, !16, i64 2, !10, i64 4, !10, i64 8, !10, i64 12, !10, i64 16, !10, i64 20, !17, i64 24, !17, i64 32, !17, i64 40}
!16 = !{!"short", !11, i64 0}
!17 = !{!"long", !11, i64 0}
!18 = !{!15, !17, i64 32}
!19 = !{!17, !17, i64 0}
!20 = !{!21, !11, i64 25}
!21 = !{!"libmdbx_globals", !11, i64 0, !10, i64 16, !10, i64 20, !11, i64 24, !11, i64 25, !11, i64 26, !22, i64 27, !10, i64 28, !11, i64 32, !11, i64 40, !17, i64 80, !13, i64 88}
!22 = !{!"_Bool", !11, i64 0}
!23 = !{!"branch_weights", i32 2000, i32 4002001}
!24 = !{!8, !13, i64 32}
!25 = !{!26, !13, i64 0}
!26 = !{!"clc2", !27, i64 0, !27, i64 24}
!27 = !{!"clc", !13, i64 0, !17, i64 8, !17, i64 16}
!28 = !{i64 0, i64 8, !29, i64 8, i64 8, !19}
!29 = !{!13, !13, i64 0}
!30 = !{!8, !17, i64 808}
!31 = !{!"branch_weights", i32 1, i32 4000, i32 1}
!32 = !{!11, !11, i64 0}


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