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

; 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.6 }
%struct.anon.6 = 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.iovec = type { ptr, i64 }
%struct.MDBX_cursor = type { i32, %union.anon.8, i8, i8, ptr, ptr, ptr, ptr, ptr, [32 x ptr], [32 x i16], ptr, ptr }
%union.anon.8 = 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.12 }
%struct.geo = type { i16, i16, i32, i32, %union.anon.10, %union.anon.11 }
%union.anon.10 = type { i32 }
%union.anon.11 = type { i32 }
%struct.MDBX_canary = type { i64, i64, i64, i64 }
%union.anon.12 = type { %struct.anon.14 }
%struct.anon.14 = type { %struct.troika, ptr, %struct.anon.15, i8, i32, i32, i64, ptr, ptr, ptr, i64, %union.anon.16 }
%struct.troika = type { i8, i8, i8, i8, i32, [3 x i64] }
%struct.anon.15 = type { %struct.MDBX_rkl, i64, %struct.MDBX_rkl }
%struct.MDBX_rkl = type { i64, i64, i32, i32, ptr, [12 x i64] }
%union.anon.16 = type { %struct.anon.17 }
%struct.anon.17 = type { i64, ptr }
%struct.anon.9 = type { i8, i8 }
%struct.page = type <{ i64, i16, i16, %union.anon.18, i32, [0 x i16] }>
%union.anon.18 = type { i32 }
%struct.anon.19 = type { i16, i16 }

@globals = external global %struct.libmdbx_globals, align 8
@.str.5 = external hidden unnamed_addr constant [22 x i8], align 1
@__func__.tree_propagate_key = external hidden unnamed_addr constant [19 x i8], align 1
@.str.105 = external hidden unnamed_addr constant [53 x i8], align 1
@.str.106 = external hidden unnamed_addr constant [44 x i8], align 1
@.str.107 = external hidden unnamed_addr constant [24 x i8], align 1
@.str.108 = external hidden unnamed_addr constant [19 x i8], align 1

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

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

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

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

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

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden ptr @page_node(ptr noundef, i64 noundef) #3

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden i32 @node_pgno(ptr noalias noundef) #3

declare zeroext i1 @cursor_is_tracked(ptr noundef) #4

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

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

declare i32 @cursor_validate_updating(ptr noundef) #4

; Function Attrs: nounwind uwtable
declare dso_local i32 @page_split(ptr noundef, ptr noundef, ptr noundef, i32 noundef, i32 noundef) #5

declare ptr @mdbx_dump_val(ptr noundef, ptr noundef, i64 noundef) #4

; 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) #6

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

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden i64 @node_ks(ptr noalias noundef) #3

; Function Attrs: inlinehint nounwind willreturn memory(read) uwtable
declare hidden ptr @node_key(ptr noalias noundef) #3

; Function Attrs: nounwind uwtable
define dso_local i32 @tree_propagate_key(ptr noundef %0, ptr noundef %1) #5 {
  %3 = alloca i32, align 4
  %4 = alloca ptr, align 8
  %5 = alloca ptr, align 8
  %6 = alloca ptr, align 8
  %7 = alloca ptr, align 8
  %8 = alloca i64, align 8
  %9 = alloca i64, align 8
  %10 = alloca i64, align 8
  %11 = alloca i64, align 8
  %12 = alloca i64, align 8
  %13 = alloca i64, align 8
  %14 = alloca i64, align 8
  %15 = alloca i64, align 8
  %16 = alloca [510 x i8], align 16
  %17 = alloca %struct.iovec, align 8
  %18 = alloca i32, align 4
  %19 = alloca i32, align 4
  %20 = alloca i32, align 4
  %21 = alloca ptr, align 8
  store ptr %0, ptr %4, align 8, !tbaa !5
  store ptr %1, ptr %5, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 8, ptr %6) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %7) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %8) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %9) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %10) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %11) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %12) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %13) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %14) #8
  call void @llvm.lifetime.start.p0(i64 8, ptr %15) #8
  call void @llvm.lifetime.start.p0(i64 510, ptr %16) #8
  br label %22

22:                                               ; preds = %2
  %23 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !9
  %24 = zext i8 %23 to i32
  %25 = and i32 %24, 1
  %26 = icmp ne i32 %25, 0
  %27 = xor i1 %26, true
  %28 = xor i1 %27, true
  %29 = zext i1 %28 to i32
  %30 = sext i32 %29 to i64
  %31 = call i64 @llvm.expect.i64(i64 %30, i64 1)
  %32 = icmp ne i64 %31, 0
  br i1 %32, label %33, label %53

33:                                               ; preds = %22
  br label %34

34:                                               ; preds = %33
  %35 = load ptr, ptr %4, align 8, !tbaa !5
  %36 = call zeroext i1 @cursor_is_tracked(ptr noundef %35)
  %37 = xor i1 %36, true
  %38 = xor i1 %37, true
  %39 = xor i1 %38, true
  %40 = zext i1 %39 to i32
  %41 = sext i32 %40 to i64
  %42 = call i64 @llvm.expect.i64(i64 %41, i64 0)
  %43 = icmp ne i64 %42, 0
  br i1 %43, label %44, label %50

44:                                               ; preds = %34
  %45 = load ptr, ptr %4, align 8, !tbaa !5
  %46 = getelementptr inbounds %struct.MDBX_cursor, ptr %45, i32 0, i32 5
  %47 = load ptr, ptr %46, align 8, !tbaa !14
  %48 = getelementptr inbounds %struct.MDBX_txn, ptr %47, i32 0, i32 9
  %49 = load ptr, ptr %48, align 8, !tbaa !16
  call void @mdbx_assert_fail(ptr noundef %49, ptr noundef @.str.5, ptr noundef @__func__.tree_propagate_key, i32 noundef 1528) #9
  unreachable

50:                                               ; preds = %34
  br label %51

51:                                               ; preds = %50
  br label %52

52:                                               ; preds = %51
  br label %53

53:                                               ; preds = %52, %22
  br label %54

54:                                               ; preds = %53
  br label %55

55:                                               ; preds = %54
  %56 = load ptr, ptr %4, align 8, !tbaa !5
  %57 = getelementptr inbounds %struct.MDBX_cursor, ptr %56, i32 0, i32 10
  %58 = load ptr, ptr %4, align 8, !tbaa !5
  %59 = getelementptr inbounds %struct.MDBX_cursor, ptr %58, i32 0, i32 1
  %60 = getelementptr inbounds %struct.anon.9, ptr %59, i32 0, i32 1
  %61 = load i8, ptr %60, align 1, !tbaa !21
  %62 = sext i8 %61 to i64
  %63 = getelementptr inbounds [32 x i16], ptr %57, i64 0, i64 %62
  %64 = load i16, ptr %63, align 2, !tbaa !22
  %65 = zext i16 %64 to i64
  store i64 %65, ptr %15, align 8, !tbaa !23
  %66 = load ptr, ptr %4, align 8, !tbaa !5
  %67 = getelementptr inbounds %struct.MDBX_cursor, ptr %66, i32 0, i32 9
  %68 = load ptr, ptr %4, align 8, !tbaa !5
  %69 = getelementptr inbounds %struct.MDBX_cursor, ptr %68, i32 0, i32 1
  %70 = getelementptr inbounds %struct.anon.9, ptr %69, i32 0, i32 1
  %71 = load i8, ptr %70, align 1, !tbaa !21
  %72 = sext i8 %71 to i64
  %73 = getelementptr inbounds [32 x ptr], ptr %67, i64 0, i64 %72
  %74 = load ptr, ptr %73, align 8, !tbaa !5
  store ptr %74, ptr %6, align 8, !tbaa !5
  %75 = load ptr, ptr %6, align 8, !tbaa !5
  %76 = load i64, ptr %15, align 8, !tbaa !23
  %77 = call ptr @page_node(ptr noundef %75, i64 noundef %76) #10
  store ptr %77, ptr %7, align 8, !tbaa !5
  %78 = load ptr, ptr %6, align 8, !tbaa !5
  %79 = getelementptr inbounds %struct.page, ptr %78, i32 0, i32 5
  %80 = load i64, ptr %15, align 8, !tbaa !23
  %81 = getelementptr inbounds [0 x i16], ptr %79, i64 0, i64 %80
  %82 = load i16, ptr %81, align 1, !tbaa !22
  %83 = zext i16 %82 to i64
  store i64 %83, ptr %12, align 8, !tbaa !23
  call void @llvm.lifetime.start.p0(i64 16, ptr %17) #8
  %84 = load ptr, ptr %7, align 8, !tbaa !5
  %85 = call ptr @node_key(ptr noundef %84) #10
  %86 = getelementptr inbounds %struct.iovec, ptr %17, i32 0, i32 0
  store ptr %85, ptr %86, align 8, !tbaa !24
  %87 = load ptr, ptr %7, align 8, !tbaa !5
  %88 = call i64 @node_ks(ptr noundef %87) #10
  %89 = getelementptr inbounds %struct.iovec, ptr %17, i32 0, i32 1
  store i64 %88, ptr %89, align 8, !tbaa !26
  br label %90

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

100:                                              ; preds = %90
  %101 = load i64, ptr %15, align 8, !tbaa !23
  %102 = load i64, ptr %12, align 8, !tbaa !23
  %103 = getelementptr inbounds [510 x i8], ptr %16, i64 0, i64 0
  %104 = getelementptr inbounds i8, ptr %103, i64 254
  %105 = getelementptr inbounds i8, ptr %104, i64 1
  %106 = call ptr @mdbx_dump_val(ptr noundef %17, ptr noundef %105, i64 noundef 255)
  %107 = load ptr, ptr %5, align 8, !tbaa !5
  %108 = getelementptr inbounds [510 x i8], ptr %16, i64 0, i64 0
  %109 = call ptr @mdbx_dump_val(ptr noundef %107, ptr noundef %108, i64 noundef 255)
  %110 = load ptr, ptr %6, align 8, !tbaa !5
  %111 = getelementptr inbounds %struct.page, ptr %110, i32 0, i32 4
  %112 = load i32, ptr %111, align 1, !tbaa !28
  call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef @__func__.tree_propagate_key, i32 noundef 1538, ptr noundef @.str.105, i64 noundef %101, i64 noundef %102, ptr noundef %106, ptr noundef %109, i32 noundef %112)
  br label %113

113:                                              ; preds = %100, %90
  br label %114

114:                                              ; preds = %113
  br label %115

115:                                              ; preds = %114
  %116 = load ptr, ptr %5, align 8, !tbaa !5
  %117 = getelementptr inbounds %struct.iovec, ptr %116, i32 0, i32 1
  %118 = load i64, ptr %117, align 8, !tbaa !26
  %119 = add i64 %118, 1
  %120 = and i64 %119, -2
  store i64 %120, ptr %10, align 8, !tbaa !23
  %121 = load ptr, ptr %7, align 8, !tbaa !5
  %122 = call i64 @node_ks(ptr noundef %121) #10
  %123 = add i64 %122, 1
  %124 = and i64 %123, -2
  store i64 %124, ptr %11, align 8, !tbaa !23
  %125 = load i64, ptr %10, align 8, !tbaa !23
  %126 = load i64, ptr %11, align 8, !tbaa !23
  %127 = sub nsw i64 %125, %126
  store i64 %127, ptr %9, align 8, !tbaa !23
  %128 = load i64, ptr %9, align 8, !tbaa !23
  %129 = icmp ne i64 %128, 0
  br i1 %129, label %130, label %330

130:                                              ; preds = %115
  %131 = load i64, ptr %9, align 8, !tbaa !23
  %132 = load ptr, ptr %6, align 8, !tbaa !5
  %133 = call i64 @page_room(ptr noundef %132) #10
  %134 = trunc i64 %133 to i32
  %135 = sext i32 %134 to i64
  %136 = icmp sgt i64 %131, %135
  br i1 %136, label %137, label %178

137:                                              ; preds = %130
  br label %138

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

148:                                              ; preds = %138
  %149 = load i64, ptr %9, align 8, !tbaa !23
  call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef @__func__.tree_propagate_key, i32 noundef 1550, ptr noundef @.str.106, i64 noundef %149)
  br label %150

150:                                              ; preds = %148, %138
  br label %151

151:                                              ; preds = %150
  br label %152

152:                                              ; preds = %151
  call void @llvm.lifetime.start.p0(i64 4, ptr %18) #8
  %153 = load ptr, ptr %7, align 8, !tbaa !5
  %154 = call i32 @node_pgno(ptr noundef %153) #10
  store i32 %154, ptr %18, align 4, !tbaa !28
  %155 = load ptr, ptr %4, align 8, !tbaa !5
  call void @node_del(ptr noundef %155, i64 noundef 0)
  call void @llvm.lifetime.start.p0(i64 4, ptr %19) #8
  %156 = load ptr, ptr %4, align 8, !tbaa !5
  %157 = load ptr, ptr %5, align 8, !tbaa !5
  %158 = load i32, ptr %18, align 4, !tbaa !28
  %159 = call i32 @page_split(ptr noundef %156, ptr noundef %157, ptr noundef null, i32 noundef %158, i32 noundef 262144)
  store i32 %159, ptr %19, align 4, !tbaa !28
  %160 = load i32, ptr %19, align 4, !tbaa !28
  %161 = icmp eq i32 %160, 0
  br i1 %161, label %162, label %176

162:                                              ; preds = %152
  %163 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !9
  %164 = zext i8 %163 to i32
  %165 = and i32 %164, 2
  %166 = icmp ne i32 %165, 0
  %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 %176

173:                                              ; preds = %162
  %174 = load ptr, ptr %4, align 8, !tbaa !5
  %175 = call i32 @cursor_validate_updating(ptr noundef %174)
  store i32 %175, ptr %19, align 4, !tbaa !28
  br label %176

176:                                              ; preds = %173, %162, %152
  %177 = load i32, ptr %19, align 4, !tbaa !28
  store i32 %177, ptr %3, align 4
  store i32 1, ptr %20, align 4
  call void @llvm.lifetime.end.p0(i64 4, ptr %19) #8
  call void @llvm.lifetime.end.p0(i64 4, ptr %18) #8
  br label %355

178:                                              ; preds = %130
  %179 = load ptr, ptr %6, align 8, !tbaa !5
  %180 = call i64 @page_numkeys(ptr noundef %179) #10
  store i64 %180, ptr %14, align 8, !tbaa !23
  store i64 0, ptr %13, align 8, !tbaa !23
  br label %181

181:                                              ; preds = %247, %178
  %182 = load i64, ptr %13, align 8, !tbaa !23
  %183 = load i64, ptr %14, align 8, !tbaa !23
  %184 = icmp slt i64 %182, %183
  br i1 %184, label %185, label %250

185:                                              ; preds = %181
  %186 = load ptr, ptr %6, align 8, !tbaa !5
  %187 = getelementptr inbounds %struct.page, ptr %186, i32 0, i32 5
  %188 = load i64, ptr %13, align 8, !tbaa !23
  %189 = getelementptr inbounds [0 x i16], ptr %187, i64 0, i64 %188
  %190 = load i16, ptr %189, align 1, !tbaa !22
  %191 = zext i16 %190 to i64
  %192 = load i64, ptr %12, align 8, !tbaa !23
  %193 = icmp sle i64 %191, %192
  br i1 %193, label %194, label %246

194:                                              ; preds = %185
  br label %195

195:                                              ; preds = %194
  %196 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !9
  %197 = zext i8 %196 to i32
  %198 = and i32 %197, 1
  %199 = icmp ne i32 %198, 0
  %200 = xor i1 %199, true
  %201 = xor i1 %200, true
  %202 = zext i1 %201 to i32
  %203 = sext i32 %202 to i64
  %204 = call i64 @llvm.expect.i64(i64 %203, i64 1)
  %205 = icmp ne i64 %204, 0
  br i1 %205, label %206, label %232

206:                                              ; preds = %195
  br label %207

207:                                              ; preds = %206
  %208 = load ptr, ptr %6, align 8, !tbaa !5
  %209 = getelementptr inbounds %struct.page, ptr %208, i32 0, i32 5
  %210 = load i64, ptr %13, align 8, !tbaa !23
  %211 = getelementptr inbounds [0 x i16], ptr %209, i64 0, i64 %210
  %212 = load i16, ptr %211, align 1, !tbaa !22
  %213 = zext i16 %212 to i64
  %214 = load i64, ptr %9, align 8, !tbaa !23
  %215 = icmp sge i64 %213, %214
  %216 = xor i1 %215, true
  %217 = xor i1 %216, true
  %218 = xor i1 %217, true
  %219 = zext i1 %218 to i32
  %220 = sext i32 %219 to i64
  %221 = call i64 @llvm.expect.i64(i64 %220, i64 0)
  %222 = icmp ne i64 %221, 0
  br i1 %222, label %223, label %229

223:                                              ; preds = %207
  %224 = load ptr, ptr %4, align 8, !tbaa !5
  %225 = getelementptr inbounds %struct.MDBX_cursor, ptr %224, i32 0, i32 5
  %226 = load ptr, ptr %225, align 8, !tbaa !14
  %227 = getelementptr inbounds %struct.MDBX_txn, ptr %226, i32 0, i32 9
  %228 = load ptr, ptr %227, align 8, !tbaa !16
  call void @mdbx_assert_fail(ptr noundef %228, ptr noundef @.str.107, ptr noundef @__func__.tree_propagate_key, i32 noundef 1562) #9
  unreachable

229:                                              ; preds = %207
  br label %230

230:                                              ; preds = %229
  br label %231

231:                                              ; preds = %230
  br label %232

232:                                              ; preds = %231, %195
  br label %233

233:                                              ; preds = %232
  br label %234

234:                                              ; preds = %233
  %235 = load i64, ptr %9, align 8, !tbaa !23
  %236 = trunc i64 %235 to i16
  %237 = zext i16 %236 to i32
  %238 = load ptr, ptr %6, align 8, !tbaa !5
  %239 = getelementptr inbounds %struct.page, ptr %238, i32 0, i32 5
  %240 = load i64, ptr %13, align 8, !tbaa !23
  %241 = getelementptr inbounds [0 x i16], ptr %239, i64 0, i64 %240
  %242 = load i16, ptr %241, align 1, !tbaa !22
  %243 = zext i16 %242 to i32
  %244 = sub nsw i32 %243, %237
  %245 = trunc i32 %244 to i16
  store i16 %245, ptr %241, align 1, !tbaa !22
  br label %246

246:                                              ; preds = %234, %185
  br label %247

247:                                              ; preds = %246
  %248 = load i64, ptr %13, align 8, !tbaa !23
  %249 = add nsw i64 %248, 1
  store i64 %249, ptr %13, align 8, !tbaa !23
  br label %181, !llvm.loop !29

250:                                              ; preds = %181
  call void @llvm.lifetime.start.p0(i64 8, ptr %21) #8
  %251 = load ptr, ptr %6, align 8, !tbaa !5
  %252 = ptrtoint ptr %251 to i64
  %253 = load ptr, ptr %6, align 8, !tbaa !5
  %254 = getelementptr inbounds %struct.page, ptr %253, i32 0, i32 3
  %255 = getelementptr inbounds %struct.anon.19, ptr %254, i32 0, i32 1
  %256 = load i16, ptr %255, align 1, !tbaa !21
  %257 = zext i16 %256 to i32
  %258 = add i32 %257, 20
  %259 = zext i32 %258 to i64
  %260 = add nsw i64 %252, %259
  %261 = inttoptr i64 %260 to ptr
  store ptr %261, ptr %21, align 8, !tbaa !5
  %262 = load i64, ptr %12, align 8, !tbaa !23
  %263 = load ptr, ptr %6, align 8, !tbaa !5
  %264 = getelementptr inbounds %struct.page, ptr %263, i32 0, i32 3
  %265 = getelementptr inbounds %struct.anon.19, ptr %264, i32 0, i32 1
  %266 = load i16, ptr %265, align 1, !tbaa !21
  %267 = zext i16 %266 to i64
  %268 = sub nsw i64 %262, %267
  %269 = add nsw i64 %268, 8
  store i64 %269, ptr %8, align 8, !tbaa !23
  %270 = load ptr, ptr %21, align 8, !tbaa !5
  %271 = ptrtoint ptr %270 to i64
  %272 = load i64, ptr %9, align 8, !tbaa !23
  %273 = sub nsw i64 0, %272
  %274 = add nsw i64 %271, %273
  %275 = inttoptr i64 %274 to ptr
  %276 = load ptr, ptr %21, align 8, !tbaa !5
  %277 = load i64, ptr %8, align 8, !tbaa !23
  call void @llvm.memmove.p0.p0.i64(ptr align 1 %275, ptr align 1 %276, i64 %277, i1 false)
  br label %278

278:                                              ; preds = %250
  %279 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !9
  %280 = zext i8 %279 to i32
  %281 = and i32 %280, 1
  %282 = icmp ne i32 %281, 0
  %283 = xor i1 %282, true
  %284 = xor i1 %283, true
  %285 = zext i1 %284 to i32
  %286 = sext i32 %285 to i64
  %287 = call i64 @llvm.expect.i64(i64 %286, i64 1)
  %288 = icmp ne i64 %287, 0
  br i1 %288, label %289, label %314

289:                                              ; preds = %278
  br label %290

290:                                              ; preds = %289
  %291 = load ptr, ptr %6, align 8, !tbaa !5
  %292 = getelementptr inbounds %struct.page, ptr %291, i32 0, i32 3
  %293 = getelementptr inbounds %struct.anon.19, ptr %292, i32 0, i32 1
  %294 = load i16, ptr %293, align 1, !tbaa !21
  %295 = zext i16 %294 to i64
  %296 = load i64, ptr %9, align 8, !tbaa !23
  %297 = icmp sge i64 %295, %296
  %298 = xor i1 %297, true
  %299 = xor i1 %298, true
  %300 = xor i1 %299, true
  %301 = zext i1 %300 to i32
  %302 = sext i32 %301 to i64
  %303 = call i64 @llvm.expect.i64(i64 %302, i64 0)
  %304 = icmp ne i64 %303, 0
  br i1 %304, label %305, label %311

305:                                              ; preds = %290
  %306 = load ptr, ptr %4, align 8, !tbaa !5
  %307 = getelementptr inbounds %struct.MDBX_cursor, ptr %306, i32 0, i32 5
  %308 = load ptr, ptr %307, align 8, !tbaa !14
  %309 = getelementptr inbounds %struct.MDBX_txn, ptr %308, i32 0, i32 9
  %310 = load ptr, ptr %309, align 8, !tbaa !16
  call void @mdbx_assert_fail(ptr noundef %310, ptr noundef @.str.108, ptr noundef @__func__.tree_propagate_key, i32 noundef 1570) #9
  unreachable

311:                                              ; preds = %290
  br label %312

312:                                              ; preds = %311
  br label %313

313:                                              ; preds = %312
  br label %314

314:                                              ; preds = %313, %278
  br label %315

315:                                              ; preds = %314
  br label %316

316:                                              ; preds = %315
  %317 = load i64, ptr %9, align 8, !tbaa !23
  %318 = trunc i64 %317 to i16
  %319 = zext i16 %318 to i32
  %320 = load ptr, ptr %6, align 8, !tbaa !5
  %321 = getelementptr inbounds %struct.page, ptr %320, i32 0, i32 3
  %322 = getelementptr inbounds %struct.anon.19, ptr %321, i32 0, i32 1
  %323 = load i16, ptr %322, align 1, !tbaa !21
  %324 = zext i16 %323 to i32
  %325 = sub nsw i32 %324, %319
  %326 = trunc i32 %325 to i16
  store i16 %326, ptr %322, align 1, !tbaa !21
  %327 = load ptr, ptr %6, align 8, !tbaa !5
  %328 = load i64, ptr %15, align 8, !tbaa !23
  %329 = call ptr @page_node(ptr noundef %327, i64 noundef %328) #10
  store ptr %329, ptr %7, align 8, !tbaa !5
  call void @llvm.lifetime.end.p0(i64 8, ptr %21) #8
  br label %330

330:                                              ; preds = %316, %115
  %331 = load ptr, ptr %7, align 8, !tbaa !5
  %332 = load ptr, ptr %5, align 8, !tbaa !5
  %333 = getelementptr inbounds %struct.iovec, ptr %332, i32 0, i32 1
  %334 = load i64, ptr %333, align 8, !tbaa !26
  call void @node_set_ks(ptr noundef %331, i64 noundef %334)
  %335 = load ptr, ptr %5, align 8, !tbaa !5
  %336 = getelementptr inbounds %struct.iovec, ptr %335, i32 0, i32 1
  %337 = load i64, ptr %336, align 8, !tbaa !26
  %338 = icmp ne i64 %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 1)
  %344 = icmp ne i64 %343, 0
  br i1 %344, label %345, label %354

345:                                              ; preds = %330
  %346 = load ptr, ptr %7, align 8, !tbaa !5
  %347 = call ptr @node_key(ptr noundef %346) #10
  %348 = load ptr, ptr %5, align 8, !tbaa !5
  %349 = getelementptr inbounds %struct.iovec, ptr %348, i32 0, i32 0
  %350 = load ptr, ptr %349, align 8, !tbaa !24
  %351 = load ptr, ptr %5, align 8, !tbaa !5
  %352 = getelementptr inbounds %struct.iovec, ptr %351, i32 0, i32 1
  %353 = load i64, ptr %352, align 8, !tbaa !26
  call void @llvm.memcpy.p0.p0.i64(ptr align 1 %347, ptr align 1 %350, i64 %353, i1 false)
  br label %354

354:                                              ; preds = %345, %330
  store i32 0, ptr %3, align 4
  store i32 1, ptr %20, align 4
  br label %355

355:                                              ; preds = %354, %176
  call void @llvm.lifetime.end.p0(i64 16, ptr %17) #8
  call void @llvm.lifetime.end.p0(i64 510, ptr %16) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %15) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %14) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %13) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %12) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %11) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %10) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %9) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %8) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %7) #8
  call void @llvm.lifetime.end.p0(i64 8, ptr %6) #8
  %356 = load i32, ptr %3, align 4
  ret i32 %356
}

declare void @node_del(ptr noundef, i64 noundef) #4

; Function Attrs: inlinehint nounwind uwtable
declare hidden void @node_set_ks(ptr noalias noundef, i64 noundef) #7

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) }
attributes #2 = { 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 #3 = { 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 #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 = { 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 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #7 = { 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 #8 = { nounwind }
attributes #9 = { noreturn }
attributes #10 = { nounwind willreturn memory(read) }

!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, !7, i64 25}
!10 = !{!"libmdbx_globals", !7, i64 0, !11, i64 16, !11, i64 20, !7, i64 24, !7, i64 25, !7, i64 26, !12, i64 27, !11, i64 28, !7, i64 32, !7, i64 40, !13, i64 80, !6, i64 88}
!11 = !{!"int", !7, i64 0}
!12 = !{!"_Bool", !7, i64 0}
!13 = !{!"long", !7, i64 0}
!14 = !{!15, !6, i64 16}
!15 = !{!"MDBX_cursor", !11, 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}
!16 = !{!17, !6, i64 80}
!17 = !{!"MDBX_txn", !11, i64 0, !11, i64 4, !13, i64 8, !13, i64 16, !6, i64 24, !6, i64 32, !18, i64 40, !13, i64 64, !13, i64 72, !6, i64 80, !6, i64 88, !6, i64 96, !6, i64 104, !6, i64 112, !6, i64 120, !20, i64 128, !6, i64 160, !7, i64 168}
!18 = !{!"geo", !19, i64 0, !19, i64 2, !11, i64 4, !11, i64 8, !7, i64 12, !7, i64 16}
!19 = !{!"short", !7, i64 0}
!20 = !{!"MDBX_canary", !13, i64 0, !13, i64 8, !13, i64 16, !13, i64 24}
!21 = !{!7, !7, i64 0}
!22 = !{!19, !19, i64 0}
!23 = !{!13, !13, i64 0}
!24 = !{!25, !6, i64 0}
!25 = !{!"iovec", !6, i64 0, !13, i64 8}
!26 = !{!25, !13, i64 8}
!27 = !{!10, !7, i64 26}
!28 = !{!11, !11, i64 0}
!29 = distinct !{!29, !30}
!30 = !{!"llvm.loop.mustprogress"}


; 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.6 }
%struct.anon.6 = 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.iovec = type { ptr, i64 }

@globals = external local_unnamed_addr global %struct.libmdbx_globals, align 8
@.str.5 = external hidden unnamed_addr constant [22 x i8], align 1
@__func__.tree_propagate_key = external hidden unnamed_addr constant [19 x i8], align 1
@.str.105 = external hidden unnamed_addr constant [53 x i8], align 1
@.str.106 = external hidden unnamed_addr constant [44 x i8], align 1
@.str.107 = external hidden unnamed_addr constant [24 x i8], align 1
@.str.108 = external hidden unnamed_addr constant [19 x i8], align 1

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

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

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

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

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

; Function Attrs: inlinehint mustprogress nofree nounwind willreturn memory(read) uwtable
declare hidden i32 @node_pgno(ptr noalias noundef) local_unnamed_addr #2

declare zeroext i1 @cursor_is_tracked(ptr noundef) local_unnamed_addr #3

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

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

declare i32 @cursor_validate_updating(ptr noundef) local_unnamed_addr #3

; Function Attrs: nounwind uwtable
declare dso_local i32 @page_split(ptr noundef, ptr noundef, ptr noundef, i32 noundef, i32 noundef) local_unnamed_addr #4

declare ptr @mdbx_dump_val(ptr noundef, ptr noundef, i64 noundef) local_unnamed_addr #3

; 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) #5

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

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

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

; Function Attrs: nounwind uwtable
define dso_local i32 @tree_propagate_key(ptr noundef %0, ptr noundef %1) local_unnamed_addr #4 {
  %3 = alloca [510 x i8], align 16
  %4 = alloca %struct.iovec, align 8
  call void @llvm.lifetime.start.p0(i64 510, ptr nonnull %3) #7
  %5 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !5
  %6 = and i8 %5, 1
  %.not = icmp eq i8 %6, 0
  br i1 %.not, label %14, label %7, !prof !13

7:                                                ; preds = %2
  %8 = tail call zeroext i1 @cursor_is_tracked(ptr noundef %0) #7
  br i1 %8, label %14, label %9, !prof !14

9:                                                ; preds = %7
  %10 = getelementptr inbounds i8, ptr %0, i64 16
  %11 = load ptr, ptr %10, align 8, !tbaa !15
  %12 = getelementptr inbounds i8, ptr %11, i64 80
  %13 = load ptr, ptr %12, align 8, !tbaa !17
  tail call void @mdbx_assert_fail(ptr noundef %13, ptr noundef nonnull @.str.5, ptr noundef nonnull @__func__.tree_propagate_key, i32 noundef 1528) #8
  unreachable

14:                                               ; preds = %7, %2
  %15 = getelementptr inbounds i8, ptr %0, i64 304
  %16 = getelementptr inbounds i8, ptr %0, i64 5
  %17 = load i8, ptr %16, align 1, !tbaa !22
  %18 = sext i8 %17 to i64
  %19 = getelementptr inbounds [32 x i16], ptr %15, i64 0, i64 %18
  %20 = load i16, ptr %19, align 2, !tbaa !23
  %21 = zext i16 %20 to i64
  %22 = getelementptr inbounds i8, ptr %0, i64 48
  %23 = getelementptr inbounds [32 x ptr], ptr %22, i64 0, i64 %18
  %24 = load ptr, ptr %23, align 8, !tbaa !24
  %25 = tail call ptr @page_node(ptr noundef %24, i64 noundef %21) #9
  %26 = getelementptr inbounds i8, ptr %24, i64 20
  %27 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %21
  %28 = load i16, ptr %27, align 1, !tbaa !23
  %29 = zext i16 %28 to i64
  call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %4) #7
  %30 = tail call ptr @node_key(ptr noundef %25) #9
  store ptr %30, ptr %4, align 8, !tbaa !25
  %31 = tail call i64 @node_ks(ptr noundef %25) #9
  %32 = getelementptr inbounds i8, ptr %4, i64 8
  store i64 %31, ptr %32, align 8, !tbaa !27
  %33 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 26), align 2, !tbaa !28
  %34 = icmp ugt i8 %33, 4
  br i1 %34, label %35, label %41, !prof !13

35:                                               ; preds = %14
  %36 = getelementptr inbounds i8, ptr %3, i64 255
  %37 = call ptr @mdbx_dump_val(ptr noundef nonnull %4, ptr noundef nonnull %36, i64 noundef 255) #7
  %38 = call ptr @mdbx_dump_val(ptr noundef %1, ptr noundef nonnull %3, i64 noundef 255) #7
  %39 = getelementptr inbounds i8, ptr %24, i64 16
  %40 = load i32, ptr %39, align 1, !tbaa !29
  call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef nonnull @__func__.tree_propagate_key, i32 noundef 1538, ptr noundef nonnull @.str.105, i64 noundef %21, i64 noundef %29, ptr noundef %37, ptr noundef %38, i32 noundef %40) #7
  br label %41

41:                                               ; preds = %35, %14
  %42 = getelementptr inbounds i8, ptr %1, i64 8
  %43 = load i64, ptr %42, align 8, !tbaa !27
  %44 = add i64 %43, 1
  %45 = and i64 %44, -2
  %46 = call i64 @node_ks(ptr noundef %25) #9
  %47 = add i64 %46, 1
  %48 = and i64 %47, -2
  %49 = sub nsw i64 %45, %48
  %.not74 = icmp eq i64 %45, %48
  br i1 %.not74, label %199, label %50

50:                                               ; preds = %41
  %51 = call i64 @page_room(ptr noundef nonnull %24) #9
  %sext = shl i64 %51, 32
  %52 = ashr exact i64 %sext, 32
  %53 = icmp sgt i64 %49, %52
  br i1 %53, label %54, label %67

54:                                               ; preds = %50
  %55 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 26), align 2, !tbaa !28
  %56 = icmp ugt i8 %55, 4
  br i1 %56, label %57, label %58, !prof !13

57:                                               ; preds = %54
  call void (i32, ptr, i32, ptr, ...) @debug_log(i32 noundef 5, ptr noundef nonnull @__func__.tree_propagate_key, i32 noundef 1550, ptr noundef nonnull @.str.106, i64 noundef %49) #7
  br label %58

58:                                               ; preds = %57, %54
  %59 = call i32 @node_pgno(ptr noundef %25) #9
  call void @node_del(ptr noundef nonnull %0, i64 noundef 0) #7
  %60 = call i32 @page_split(ptr noundef nonnull %0, ptr noundef nonnull %1, ptr noundef null, i32 noundef %59, i32 noundef 262144)
  %61 = icmp eq i32 %60, 0
  br i1 %61, label %62, label %205

62:                                               ; preds = %58
  %63 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !5
  %64 = and i8 %63, 2
  %.not81 = icmp eq i8 %64, 0
  br i1 %.not81, label %205, label %65, !prof !14

65:                                               ; preds = %62
  %66 = call i32 @cursor_validate_updating(ptr noundef nonnull %0) #7
  br label %205

67:                                               ; preds = %50
  %68 = call i64 @page_numkeys(ptr noundef nonnull %24) #9
  %69 = icmp sgt i64 %68, 0
  br i1 %69, label %.lr.ph, label %._crit_edge

.lr.ph:                                           ; preds = %67
  %70 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1
  %.fr83 = freeze i8 %70
  %71 = and i8 %.fr83, 1
  %.not79.not = icmp eq i8 %71, 0
  %72 = trunc i64 %49 to i16
  br i1 %.not79.not, label %.lr.ph.split.us.preheader, label %.lr.ph.split

.lr.ph.split.us.preheader:                        ; preds = %.lr.ph
  %min.iters.check = icmp ult i64 %68, 16
  br i1 %min.iters.check, label %.lr.ph.split.us.preheader120, label %vector.ph

vector.ph:                                        ; preds = %.lr.ph.split.us.preheader
  %n.vec = and i64 %68, 9223372036854775792
  %broadcast.splatinsert = insertelement <8 x i16> poison, i16 %28, i64 0
  %broadcast.splat = shufflevector <8 x i16> %broadcast.splatinsert, <8 x i16> poison, <8 x i32> zeroinitializer
  br label %vector.body

vector.body:                                      ; preds = %pred.store.continue119, %vector.ph
  %index = phi i64 [ 0, %vector.ph ], [ %index.next, %pred.store.continue119 ]
  %73 = or disjoint i64 %index, 8
  %74 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %index
  %75 = getelementptr inbounds i8, ptr %74, i64 16
  %wide.load = load <8 x i16>, ptr %74, align 1, !tbaa !23
  %wide.load89 = load <8 x i16>, ptr %75, align 1, !tbaa !23
  %76 = icmp ule <8 x i16> %wide.load, %broadcast.splat
  %77 = icmp ule <8 x i16> %wide.load89, %broadcast.splat
  %78 = extractelement <8 x i1> %76, i64 0
  br i1 %78, label %pred.store.if, label %pred.store.continue

pred.store.if:                                    ; preds = %vector.body
  %79 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %index
  %80 = extractelement <8 x i16> %wide.load, i64 0
  %81 = sub i16 %80, %72
  store i16 %81, ptr %79, align 1, !tbaa !23
  br label %pred.store.continue

pred.store.continue:                              ; preds = %pred.store.if, %vector.body
  %82 = extractelement <8 x i1> %76, i64 1
  br i1 %82, label %pred.store.if90, label %pred.store.continue91

pred.store.if90:                                  ; preds = %pred.store.continue
  %83 = or disjoint i64 %index, 1
  %84 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %83
  %85 = extractelement <8 x i16> %wide.load, i64 1
  %86 = sub i16 %85, %72
  store i16 %86, ptr %84, align 1, !tbaa !23
  br label %pred.store.continue91

pred.store.continue91:                            ; preds = %pred.store.if90, %pred.store.continue
  %87 = extractelement <8 x i1> %76, i64 2
  br i1 %87, label %pred.store.if92, label %pred.store.continue93

pred.store.if92:                                  ; preds = %pred.store.continue91
  %88 = or disjoint i64 %index, 2
  %89 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %88
  %90 = extractelement <8 x i16> %wide.load, i64 2
  %91 = sub i16 %90, %72
  store i16 %91, ptr %89, align 1, !tbaa !23
  br label %pred.store.continue93

pred.store.continue93:                            ; preds = %pred.store.if92, %pred.store.continue91
  %92 = extractelement <8 x i1> %76, i64 3
  br i1 %92, label %pred.store.if94, label %pred.store.continue95

pred.store.if94:                                  ; preds = %pred.store.continue93
  %93 = or disjoint i64 %index, 3
  %94 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %93
  %95 = extractelement <8 x i16> %wide.load, i64 3
  %96 = sub i16 %95, %72
  store i16 %96, ptr %94, align 1, !tbaa !23
  br label %pred.store.continue95

pred.store.continue95:                            ; preds = %pred.store.if94, %pred.store.continue93
  %97 = extractelement <8 x i1> %76, i64 4
  br i1 %97, label %pred.store.if96, label %pred.store.continue97

pred.store.if96:                                  ; preds = %pred.store.continue95
  %98 = or disjoint i64 %index, 4
  %99 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %98
  %100 = extractelement <8 x i16> %wide.load, i64 4
  %101 = sub i16 %100, %72
  store i16 %101, ptr %99, align 1, !tbaa !23
  br label %pred.store.continue97

pred.store.continue97:                            ; preds = %pred.store.if96, %pred.store.continue95
  %102 = extractelement <8 x i1> %76, i64 5
  br i1 %102, label %pred.store.if98, label %pred.store.continue99

pred.store.if98:                                  ; preds = %pred.store.continue97
  %103 = or disjoint i64 %index, 5
  %104 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %103
  %105 = extractelement <8 x i16> %wide.load, i64 5
  %106 = sub i16 %105, %72
  store i16 %106, ptr %104, align 1, !tbaa !23
  br label %pred.store.continue99

pred.store.continue99:                            ; preds = %pred.store.if98, %pred.store.continue97
  %107 = extractelement <8 x i1> %76, i64 6
  br i1 %107, label %pred.store.if100, label %pred.store.continue101

pred.store.if100:                                 ; preds = %pred.store.continue99
  %108 = or disjoint i64 %index, 6
  %109 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %108
  %110 = extractelement <8 x i16> %wide.load, i64 6
  %111 = sub i16 %110, %72
  store i16 %111, ptr %109, align 1, !tbaa !23
  br label %pred.store.continue101

pred.store.continue101:                           ; preds = %pred.store.if100, %pred.store.continue99
  %112 = extractelement <8 x i1> %76, i64 7
  br i1 %112, label %pred.store.if102, label %pred.store.continue103

pred.store.if102:                                 ; preds = %pred.store.continue101
  %113 = or disjoint i64 %index, 7
  %114 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %113
  %115 = extractelement <8 x i16> %wide.load, i64 7
  %116 = sub i16 %115, %72
  store i16 %116, ptr %114, align 1, !tbaa !23
  br label %pred.store.continue103

pred.store.continue103:                           ; preds = %pred.store.if102, %pred.store.continue101
  %117 = extractelement <8 x i1> %77, i64 0
  br i1 %117, label %pred.store.if104, label %pred.store.continue105

pred.store.if104:                                 ; preds = %pred.store.continue103
  %118 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %73
  %119 = extractelement <8 x i16> %wide.load89, i64 0
  %120 = sub i16 %119, %72
  store i16 %120, ptr %118, align 1, !tbaa !23
  br label %pred.store.continue105

pred.store.continue105:                           ; preds = %pred.store.if104, %pred.store.continue103
  %121 = extractelement <8 x i1> %77, i64 1
  br i1 %121, label %pred.store.if106, label %pred.store.continue107

pred.store.if106:                                 ; preds = %pred.store.continue105
  %122 = or disjoint i64 %index, 9
  %123 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %122
  %124 = extractelement <8 x i16> %wide.load89, i64 1
  %125 = sub i16 %124, %72
  store i16 %125, ptr %123, align 1, !tbaa !23
  br label %pred.store.continue107

pred.store.continue107:                           ; preds = %pred.store.if106, %pred.store.continue105
  %126 = extractelement <8 x i1> %77, i64 2
  br i1 %126, label %pred.store.if108, label %pred.store.continue109

pred.store.if108:                                 ; preds = %pred.store.continue107
  %127 = or disjoint i64 %index, 10
  %128 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %127
  %129 = extractelement <8 x i16> %wide.load89, i64 2
  %130 = sub i16 %129, %72
  store i16 %130, ptr %128, align 1, !tbaa !23
  br label %pred.store.continue109

pred.store.continue109:                           ; preds = %pred.store.if108, %pred.store.continue107
  %131 = extractelement <8 x i1> %77, i64 3
  br i1 %131, label %pred.store.if110, label %pred.store.continue111

pred.store.if110:                                 ; preds = %pred.store.continue109
  %132 = or disjoint i64 %index, 11
  %133 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %132
  %134 = extractelement <8 x i16> %wide.load89, i64 3
  %135 = sub i16 %134, %72
  store i16 %135, ptr %133, align 1, !tbaa !23
  br label %pred.store.continue111

pred.store.continue111:                           ; preds = %pred.store.if110, %pred.store.continue109
  %136 = extractelement <8 x i1> %77, i64 4
  br i1 %136, label %pred.store.if112, label %pred.store.continue113

pred.store.if112:                                 ; preds = %pred.store.continue111
  %137 = or disjoint i64 %index, 12
  %138 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %137
  %139 = extractelement <8 x i16> %wide.load89, i64 4
  %140 = sub i16 %139, %72
  store i16 %140, ptr %138, align 1, !tbaa !23
  br label %pred.store.continue113

pred.store.continue113:                           ; preds = %pred.store.if112, %pred.store.continue111
  %141 = extractelement <8 x i1> %77, i64 5
  br i1 %141, label %pred.store.if114, label %pred.store.continue115

pred.store.if114:                                 ; preds = %pred.store.continue113
  %142 = or disjoint i64 %index, 13
  %143 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %142
  %144 = extractelement <8 x i16> %wide.load89, i64 5
  %145 = sub i16 %144, %72
  store i16 %145, ptr %143, align 1, !tbaa !23
  br label %pred.store.continue115

pred.store.continue115:                           ; preds = %pred.store.if114, %pred.store.continue113
  %146 = extractelement <8 x i1> %77, i64 6
  br i1 %146, label %pred.store.if116, label %pred.store.continue117

pred.store.if116:                                 ; preds = %pred.store.continue115
  %147 = or disjoint i64 %index, 14
  %148 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %147
  %149 = extractelement <8 x i16> %wide.load89, i64 6
  %150 = sub i16 %149, %72
  store i16 %150, ptr %148, align 1, !tbaa !23
  br label %pred.store.continue117

pred.store.continue117:                           ; preds = %pred.store.if116, %pred.store.continue115
  %151 = extractelement <8 x i1> %77, i64 7
  br i1 %151, label %pred.store.if118, label %pred.store.continue119

pred.store.if118:                                 ; preds = %pred.store.continue117
  %152 = or disjoint i64 %index, 15
  %153 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %152
  %154 = extractelement <8 x i16> %wide.load89, i64 7
  %155 = sub i16 %154, %72
  store i16 %155, ptr %153, align 1, !tbaa !23
  br label %pred.store.continue119

pred.store.continue119:                           ; preds = %pred.store.if118, %pred.store.continue117
  %index.next = add nuw i64 %index, 16
  %156 = icmp eq i64 %index.next, %n.vec
  br i1 %156, label %middle.block, label %vector.body, !llvm.loop !30

middle.block:                                     ; preds = %pred.store.continue119
  %cmp.n = icmp eq i64 %68, %n.vec
  br i1 %cmp.n, label %._crit_edge, label %.lr.ph.split.us.preheader120

.lr.ph.split.us.preheader120:                     ; preds = %middle.block, %.lr.ph.split.us.preheader
  %.06982.us.ph = phi i64 [ 0, %.lr.ph.split.us.preheader ], [ %n.vec, %middle.block ]
  br label %.lr.ph.split.us

.lr.ph.split.us:                                  ; preds = %.lr.ph.split.us.preheader120, %161
  %.06982.us = phi i64 [ %162, %161 ], [ %.06982.us.ph, %.lr.ph.split.us.preheader120 ]
  %157 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %.06982.us
  %158 = load i16, ptr %157, align 1, !tbaa !23
  %.not78.us = icmp ugt i16 %158, %28
  br i1 %.not78.us, label %161, label %159

159:                                              ; preds = %.lr.ph.split.us
  %160 = sub i16 %158, %72
  store i16 %160, ptr %157, align 1, !tbaa !23
  br label %161

161:                                              ; preds = %159, %.lr.ph.split.us
  %162 = add nuw nsw i64 %.06982.us, 1
  %exitcond85.not = icmp eq i64 %162, %68
  br i1 %exitcond85.not, label %._crit_edge, label %.lr.ph.split.us, !llvm.loop !34

.lr.ph.split:                                     ; preds = %.lr.ph, %174
  %.06982 = phi i64 [ %175, %174 ], [ 0, %.lr.ph ]
  %163 = getelementptr inbounds [0 x i16], ptr %26, i64 0, i64 %.06982
  %164 = load i16, ptr %163, align 1, !tbaa !23
  %.not78 = icmp ugt i16 %164, %28
  br i1 %.not78, label %174, label %165

165:                                              ; preds = %.lr.ph.split
  %166 = zext i16 %164 to i64
  %.not80 = icmp sgt i64 %49, %166
  br i1 %.not80, label %167, label %172, !prof !35

167:                                              ; preds = %165
  %168 = getelementptr inbounds i8, ptr %0, i64 16
  %169 = load ptr, ptr %168, align 8, !tbaa !15
  %170 = getelementptr inbounds i8, ptr %169, i64 80
  %171 = load ptr, ptr %170, align 8, !tbaa !17
  call void @mdbx_assert_fail(ptr noundef %171, ptr noundef nonnull @.str.107, ptr noundef nonnull @__func__.tree_propagate_key, i32 noundef 1562) #8
  unreachable

172:                                              ; preds = %165
  %173 = sub i16 %164, %72
  store i16 %173, ptr %163, align 1, !tbaa !23
  br label %174

174:                                              ; preds = %.lr.ph.split, %172
  %175 = add nuw nsw i64 %.06982, 1
  %exitcond.not = icmp eq i64 %175, %68
  br i1 %exitcond.not, label %._crit_edge, label %.lr.ph.split, !llvm.loop !36

._crit_edge:                                      ; preds = %174, %161, %middle.block, %67
  %176 = ptrtoint ptr %24 to i64
  %177 = getelementptr inbounds i8, ptr %24, i64 14
  %178 = load i16, ptr %177, align 1, !tbaa !22
  %179 = zext i16 %178 to i64
  %180 = add i64 %176, 20
  %181 = add i64 %180, %179
  %182 = inttoptr i64 %181 to ptr
  %183 = add nuw nsw i64 %29, 8
  %184 = sub nsw i64 %183, %179
  %185 = sub i64 %181, %49
  %186 = inttoptr i64 %185 to ptr
  call void @llvm.memmove.p0.p0.i64(ptr align 1 %186, ptr align 1 %182, i64 %184, i1 false)
  %187 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !5
  %188 = and i8 %187, 1
  %.not75 = icmp ne i8 %188, 0
  %.pre = load i16, ptr %177, align 1, !tbaa !22
  %189 = zext i16 %.pre to i64
  %.not76 = icmp sgt i64 %49, %189
  %or.cond = select i1 %.not75, i1 %.not76, i1 false
  br i1 %or.cond, label %190, label %195, !prof !35

190:                                              ; preds = %._crit_edge
  %191 = getelementptr inbounds i8, ptr %0, i64 16
  %192 = load ptr, ptr %191, align 8, !tbaa !15
  %193 = getelementptr inbounds i8, ptr %192, i64 80
  %194 = load ptr, ptr %193, align 8, !tbaa !17
  call void @mdbx_assert_fail(ptr noundef %194, ptr noundef nonnull @.str.108, ptr noundef nonnull @__func__.tree_propagate_key, i32 noundef 1570) #8
  unreachable

195:                                              ; preds = %._crit_edge
  %196 = trunc i64 %49 to i16
  %197 = sub i16 %.pre, %196
  store i16 %197, ptr %177, align 1, !tbaa !22
  %198 = call ptr @page_node(ptr noundef nonnull %24, i64 noundef %21) #9
  %.pre86 = load i64, ptr %42, align 8, !tbaa !27
  br label %199

199:                                              ; preds = %195, %41
  %200 = phi i64 [ %.pre86, %195 ], [ %43, %41 ]
  %.068 = phi ptr [ %198, %195 ], [ %25, %41 ]
  call void @node_set_ks(ptr noundef %.068, i64 noundef %200)
  %201 = load i64, ptr %42, align 8, !tbaa !27
  %.not77 = icmp eq i64 %201, 0
  br i1 %.not77, label %205, label %202, !prof !13

202:                                              ; preds = %199
  %203 = call ptr @node_key(ptr noundef %.068) #9
  %204 = load ptr, ptr %1, align 8, !tbaa !25
  call void @llvm.memcpy.p0.p0.i64(ptr align 1 %203, ptr align 1 %204, i64 %201, i1 false)
  br label %205

205:                                              ; preds = %199, %202, %58, %62, %65
  %.0 = phi i32 [ %66, %65 ], [ 0, %62 ], [ %60, %58 ], [ 0, %202 ], [ 0, %199 ]
  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %4) #7
  call void @llvm.lifetime.end.p0(i64 510, ptr nonnull %3) #7
  ret i32 %.0
}

declare void @node_del(ptr noundef, i64 noundef) local_unnamed_addr #3

; Function Attrs: inlinehint nounwind uwtable
declare hidden void @node_set_ks(ptr noalias noundef, i64 noundef) local_unnamed_addr #6

attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
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 = { 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 #3 = { "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 = { 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 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #6 = { 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 #7 = { nounwind }
attributes #8 = { noreturn nounwind }
attributes #9 = { nounwind willreturn memory(read) }

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


; Effective O3 passes: CorrelatedValuePropagationPass,EarlyCSEPass,GVNPass,GlobalOptPass,IPSCCPPass,IndVarSimplifyPass,InferFunctionAttrsPass,InstCombinePass,JumpThreadingPass,LICMPass,LoopInstSimplifyPass,LoopLoadEliminationPass,LoopRotatePass,LoopSimplifyCFGPass,LoopSimplifyPass,LoopUnrollPass,LoopVectorizePass,LowerExpectIntrinsicPass,ReassociatePass,SROAPass,SimplifyCFGPass,TailCallElimPass