; LLVM IR from erthink/libmdbx :: src (node)

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

@globals = external global %struct.libmdbx_globals, align 8
@.str.37 = external hidden unnamed_addr constant [28 x i8], align 1
@__func__.node_shrink = external hidden unnamed_addr constant [12 x i8], align 1
@.str.38 = external hidden unnamed_addr constant [39 x i8], align 1
@.str.39 = external hidden unnamed_addr constant [15 x i8], align 1
@.str.40 = external hidden unnamed_addr constant [24 x i8], align 1
@.str.41 = external hidden unnamed_addr constant [31 x i8], align 1
@.str.42 = external hidden unnamed_addr constant [42 x i8], align 1
@.str.43 = external hidden unnamed_addr constant [37 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: inlinehint nounwind willreturn memory(read) uwtable
declare hidden zeroext i1 @is_subpage(ptr noundef) #3

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

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

; 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 ptr @page_node(ptr noundef, i64 noundef) #3

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

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

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

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

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

; Function Attrs: nounwind uwtable
define dso_local ptr @node_shrink(ptr noundef %0, i64 noundef %1, ptr noundef %2) #6 {
  %4 = alloca ptr, align 8
  %5 = alloca ptr, align 8
  %6 = alloca i64, align 8
  %7 = alloca ptr, align 8
  %8 = alloca ptr, align 8
  %9 = alloca i64, align 8
  %10 = alloca i32, align 4
  %11 = alloca i64, align 8
  %12 = alloca i64, align 8
  %13 = alloca ptr, align 8
  %14 = alloca i64, align 8
  %15 = alloca ptr, align 8
  %16 = alloca i64, align 8
  %17 = alloca i64, align 8
  store ptr %0, ptr %5, align 8, !tbaa !5
  store i64 %1, ptr %6, align 8, !tbaa !9
  store ptr %2, ptr %7, align 8, !tbaa !5
  br label %18

18:                                               ; preds = %3
  %19 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !11
  %20 = zext i8 %19 to i32
  %21 = and i32 %20, 1
  %22 = icmp ne i32 %21, 0
  %23 = xor i1 %22, true
  %24 = xor i1 %23, true
  %25 = zext i1 %24 to i32
  %26 = sext i32 %25 to i64
  %27 = call i64 @llvm.expect.i64(i64 %26, i64 1)
  %28 = icmp ne i64 %27, 0
  br i1 %28, label %29, label %46

29:                                               ; preds = %18
  br label %30

30:                                               ; preds = %29
  %31 = load ptr, ptr %7, align 8, !tbaa !5
  %32 = load ptr, ptr %5, align 8, !tbaa !5
  %33 = load i64, ptr %6, align 8, !tbaa !9
  %34 = call ptr @page_node(ptr noundef %32, i64 noundef %33) #7
  %35 = icmp eq ptr %31, %34
  %36 = xor i1 %35, true
  %37 = xor i1 %36, true
  %38 = xor i1 %37, true
  %39 = zext i1 %38 to i32
  %40 = sext i32 %39 to i64
  %41 = call i64 @llvm.expect.i64(i64 %40, i64 0)
  %42 = icmp ne i64 %41, 0
  br i1 %42, label %43, label %44

43:                                               ; preds = %30
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.37, ptr noundef @__func__.node_shrink, i32 noundef 248) #8
  unreachable

44:                                               ; preds = %30
  br label %45

45:                                               ; preds = %44
  br label %46

46:                                               ; preds = %45, %18
  br label %47

47:                                               ; preds = %46
  call void @llvm.lifetime.start.p0(i64 8, ptr %8) #9
  %48 = load ptr, ptr %7, align 8, !tbaa !5
  %49 = call ptr @node_data(ptr noundef %48) #7
  store ptr %49, ptr %8, align 8, !tbaa !5
  br label %50

50:                                               ; preds = %47
  %51 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !11
  %52 = zext i8 %51 to i32
  %53 = and i32 %52, 1
  %54 = icmp ne i32 %53, 0
  %55 = xor i1 %54, true
  %56 = xor i1 %55, true
  %57 = zext i1 %56 to i32
  %58 = sext i32 %57 to i64
  %59 = call i64 @llvm.expect.i64(i64 %58, i64 1)
  %60 = icmp ne i64 %59, 0
  br i1 %60, label %61, label %82

61:                                               ; preds = %50
  br label %62

62:                                               ; preds = %61
  %63 = load ptr, ptr %8, align 8, !tbaa !5
  %64 = call zeroext i1 @is_subpage(ptr noundef %63) #7
  br i1 %64, label %65, label %69

65:                                               ; preds = %62
  %66 = load ptr, ptr %8, align 8, !tbaa !5
  %67 = call i64 @page_numkeys(ptr noundef %66) #7
  %68 = icmp ugt i64 %67, 0
  br label %69

69:                                               ; preds = %65, %62
  %70 = phi i1 [ false, %62 ], [ %68, %65 ]
  %71 = xor i1 %70, true
  %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 %79

78:                                               ; preds = %69
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.38, ptr noundef @__func__.node_shrink, i32 noundef 250) #8
  unreachable

79:                                               ; preds = %69
  br label %80

80:                                               ; preds = %79
  br label %81

81:                                               ; preds = %80
  br label %82

82:                                               ; preds = %81, %50
  br label %83

83:                                               ; preds = %82
  br label %84

84:                                               ; preds = %83
  call void @llvm.lifetime.start.p0(i64 8, ptr %9) #9
  %85 = load ptr, ptr %8, align 8, !tbaa !5
  %86 = call i64 @page_room(ptr noundef %85) #7
  %87 = and i64 %86, -2
  store i64 %87, ptr %9, align 8, !tbaa !9
  %88 = load i64, ptr %9, align 8, !tbaa !9
  %89 = icmp ne i64 %88, 0
  %90 = xor i1 %89, true
  %91 = xor i1 %90, true
  %92 = zext i1 %91 to i32
  %93 = sext i32 %92 to i64
  %94 = call i64 @llvm.expect.i64(i64 %93, i64 0)
  %95 = icmp eq i64 %94, 0
  br i1 %95, label %96, label %98

96:                                               ; preds = %84
  %97 = load ptr, ptr %7, align 8, !tbaa !5
  store ptr %97, ptr %4, align 8
  store i32 1, ptr %10, align 4
  br label %403

98:                                               ; preds = %84
  call void @llvm.lifetime.start.p0(i64 8, ptr %11) #9
  %99 = load ptr, ptr %7, align 8, !tbaa !5
  %100 = call i64 @node_ds(ptr noundef %99) #7
  %101 = load i64, ptr %9, align 8, !tbaa !9
  %102 = sub i64 %100, %101
  store i64 %102, ptr %11, align 8, !tbaa !9
  call void @llvm.lifetime.start.p0(i64 8, ptr %12) #9
  %103 = load i64, ptr %11, align 8, !tbaa !9
  store i64 %103, ptr %12, align 8, !tbaa !9
  br label %104

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

115:                                              ; preds = %104
  br label %116

116:                                              ; preds = %115
  %117 = load i64, ptr %11, align 8, !tbaa !9
  %118 = urem i64 %117, 1
  %119 = icmp eq i64 %118, 0
  %120 = xor i1 %119, true
  %121 = xor i1 %120, true
  %122 = xor i1 %121, true
  %123 = zext i1 %122 to i32
  %124 = sext i32 %123 to i64
  %125 = call i64 @llvm.expect.i64(i64 %124, i64 0)
  %126 = icmp ne i64 %125, 0
  br i1 %126, label %127, label %128

127:                                              ; preds = %116
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.39, ptr noundef @__func__.node_shrink, i32 noundef 257) #8
  unreachable

128:                                              ; preds = %116
  br label %129

129:                                              ; preds = %128
  br label %130

130:                                              ; preds = %129
  br label %131

131:                                              ; preds = %130, %104
  br label %132

132:                                              ; preds = %131
  br label %133

133:                                              ; preds = %132
  %134 = load ptr, ptr %8, align 8, !tbaa !5
  %135 = call zeroext i1 @is_dupfix_leaf(ptr noundef %134) #7
  br i1 %135, label %199, label %136

136:                                              ; preds = %133
  store i64 20, ptr %12, align 8, !tbaa !9
  call void @llvm.lifetime.start.p0(i64 8, ptr %13) #9
  %137 = load ptr, ptr %8, align 8, !tbaa !5
  %138 = ptrtoint ptr %137 to i64
  %139 = load i64, ptr %9, align 8, !tbaa !9
  %140 = add nsw i64 %138, %139
  %141 = inttoptr i64 %140 to ptr
  store ptr %141, ptr %13, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 8, ptr %14) #9
  %142 = load ptr, ptr %8, align 8, !tbaa !5
  %143 = call i64 @page_numkeys(ptr noundef %142) #7
  store i64 %143, ptr %14, align 8, !tbaa !9
  br label %144

144:                                              ; preds = %184, %136
  %145 = load i64, ptr %14, align 8, !tbaa !9
  %146 = add nsw i64 %145, -1
  store i64 %146, ptr %14, align 8, !tbaa !9
  %147 = icmp sge i64 %146, 0
  br i1 %147, label %149, label %148

148:                                              ; preds = %144
  store i32 14, ptr %10, align 4
  call void @llvm.lifetime.end.p0(i64 8, ptr %14) #9
  br label %198

149:                                              ; preds = %144
  br label %150

150:                                              ; preds = %149
  %151 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !11
  %152 = zext i8 %151 to i32
  %153 = and i32 %152, 1
  %154 = icmp ne i32 %153, 0
  %155 = xor i1 %154, true
  %156 = xor i1 %155, true
  %157 = zext i1 %156 to i32
  %158 = sext i32 %157 to i64
  %159 = call i64 @llvm.expect.i64(i64 %158, i64 1)
  %160 = icmp ne i64 %159, 0
  br i1 %160, label %161, label %182

161:                                              ; preds = %150
  br label %162

162:                                              ; preds = %161
  %163 = load ptr, ptr %8, align 8, !tbaa !5
  %164 = getelementptr inbounds %struct.page, ptr %163, i32 0, i32 5
  %165 = load i64, ptr %14, align 8, !tbaa !9
  %166 = getelementptr inbounds [0 x i16], ptr %164, i64 0, i64 %165
  %167 = load i16, ptr %166, align 1, !tbaa !15
  %168 = zext i16 %167 to i64
  %169 = load i64, ptr %9, align 8, !tbaa !9
  %170 = icmp uge i64 %168, %169
  %171 = xor i1 %170, true
  %172 = xor i1 %171, true
  %173 = xor i1 %172, true
  %174 = zext i1 %173 to i32
  %175 = sext i32 %174 to i64
  %176 = call i64 @llvm.expect.i64(i64 %175, i64 0)
  %177 = icmp ne i64 %176, 0
  br i1 %177, label %178, label %179

178:                                              ; preds = %162
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.40, ptr noundef @__func__.node_shrink, i32 noundef 262) #8
  unreachable

179:                                              ; preds = %162
  br label %180

180:                                              ; preds = %179
  br label %181

181:                                              ; preds = %180
  br label %182

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

183:                                              ; preds = %182
  br label %184

184:                                              ; preds = %183
  %185 = load ptr, ptr %8, align 8, !tbaa !5
  %186 = getelementptr inbounds %struct.page, ptr %185, i32 0, i32 5
  %187 = load i64, ptr %14, align 8, !tbaa !9
  %188 = getelementptr inbounds [0 x i16], ptr %186, i64 0, i64 %187
  %189 = load i16, ptr %188, align 1, !tbaa !15
  %190 = zext i16 %189 to i64
  %191 = load i64, ptr %9, align 8, !tbaa !9
  %192 = sub i64 %190, %191
  %193 = trunc i64 %192 to i16
  %194 = load ptr, ptr %13, align 8, !tbaa !5
  %195 = getelementptr inbounds %struct.page, ptr %194, i32 0, i32 5
  %196 = load i64, ptr %14, align 8, !tbaa !9
  %197 = getelementptr inbounds [0 x i16], ptr %195, i64 0, i64 %196
  store i16 %193, ptr %197, align 1, !tbaa !15
  br label %144, !llvm.loop !17

198:                                              ; preds = %148
  call void @llvm.lifetime.end.p0(i64 8, ptr %13) #9
  br label %199

199:                                              ; preds = %198, %133
  br label %200

200:                                              ; preds = %199
  %201 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !11
  %202 = zext i8 %201 to i32
  %203 = and i32 %202, 1
  %204 = icmp ne i32 %203, 0
  %205 = xor i1 %204, true
  %206 = xor i1 %205, true
  %207 = zext i1 %206 to i32
  %208 = sext i32 %207 to i64
  %209 = call i64 @llvm.expect.i64(i64 %208, i64 1)
  %210 = icmp ne i64 %209, 0
  br i1 %210, label %211, label %237

211:                                              ; preds = %200
  br label %212

212:                                              ; preds = %211
  %213 = load ptr, ptr %8, align 8, !tbaa !5
  %214 = getelementptr inbounds %struct.page, ptr %213, i32 0, i32 3
  %215 = getelementptr inbounds %struct.anon.3, ptr %214, i32 0, i32 1
  %216 = load i16, ptr %215, align 1, !tbaa !19
  %217 = zext i16 %216 to i64
  %218 = load ptr, ptr %8, align 8, !tbaa !5
  %219 = getelementptr inbounds %struct.page, ptr %218, i32 0, i32 3
  %220 = getelementptr inbounds %struct.anon.3, ptr %219, i32 0, i32 0
  %221 = load i16, ptr %220, align 1, !tbaa !19
  %222 = zext i16 %221 to i64
  %223 = load i64, ptr %9, align 8, !tbaa !9
  %224 = add i64 %222, %223
  %225 = icmp uge i64 %217, %224
  %226 = xor i1 %225, true
  %227 = xor i1 %226, true
  %228 = xor i1 %227, true
  %229 = zext i1 %228 to i32
  %230 = sext i32 %229 to i64
  %231 = call i64 @llvm.expect.i64(i64 %230, i64 0)
  %232 = icmp ne i64 %231, 0
  br i1 %232, label %233, label %234

233:                                              ; preds = %212
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.41, ptr noundef @__func__.node_shrink, i32 noundef 266) #8
  unreachable

234:                                              ; preds = %212
  br label %235

235:                                              ; preds = %234
  br label %236

236:                                              ; preds = %235
  br label %237

237:                                              ; preds = %236, %200
  br label %238

238:                                              ; preds = %237
  br label %239

239:                                              ; preds = %238
  %240 = load i64, ptr %9, align 8, !tbaa !9
  %241 = trunc i64 %240 to i16
  %242 = zext i16 %241 to i32
  %243 = load ptr, ptr %8, align 8, !tbaa !5
  %244 = getelementptr inbounds %struct.page, ptr %243, i32 0, i32 3
  %245 = getelementptr inbounds %struct.anon.3, ptr %244, i32 0, i32 1
  %246 = load i16, ptr %245, align 1, !tbaa !19
  %247 = zext i16 %246 to i32
  %248 = sub nsw i32 %247, %242
  %249 = trunc i32 %248 to i16
  store i16 %249, ptr %245, align 1, !tbaa !19
  %250 = load ptr, ptr %5, align 8, !tbaa !5
  %251 = getelementptr inbounds %struct.page, ptr %250, i32 0, i32 4
  %252 = load i32, ptr %251, align 1, !tbaa !20
  %253 = load ptr, ptr %8, align 8, !tbaa !5
  %254 = getelementptr inbounds %struct.page, ptr %253, i32 0, i32 4
  store i32 %252, ptr %254, align 1, !tbaa !20
  %255 = load ptr, ptr %7, align 8, !tbaa !5
  %256 = load i64, ptr %11, align 8, !tbaa !9
  call void @node_set_ds(ptr noundef %255, i64 noundef %256)
  call void @llvm.lifetime.start.p0(i64 8, ptr %15) #9
  %257 = load ptr, ptr %5, align 8, !tbaa !5
  %258 = ptrtoint ptr %257 to i64
  %259 = load ptr, ptr %5, align 8, !tbaa !5
  %260 = getelementptr inbounds %struct.page, ptr %259, i32 0, i32 3
  %261 = getelementptr inbounds %struct.anon.3, ptr %260, i32 0, i32 1
  %262 = load i16, ptr %261, align 1, !tbaa !19
  %263 = zext i16 %262 to i32
  %264 = add i32 %263, 20
  %265 = zext i32 %264 to i64
  %266 = add nsw i64 %258, %265
  %267 = inttoptr i64 %266 to ptr
  store ptr %267, ptr %15, align 8, !tbaa !5
  %268 = load ptr, ptr %15, align 8, !tbaa !5
  %269 = ptrtoint ptr %268 to i64
  %270 = load i64, ptr %9, align 8, !tbaa !9
  %271 = add nsw i64 %269, %270
  %272 = inttoptr i64 %271 to ptr
  %273 = load ptr, ptr %15, align 8, !tbaa !5
  %274 = load ptr, ptr %8, align 8, !tbaa !5
  %275 = ptrtoint ptr %274 to i64
  %276 = load ptr, ptr %15, align 8, !tbaa !5
  %277 = ptrtoint ptr %276 to i64
  %278 = sub nsw i64 %275, %277
  %279 = load i64, ptr %12, align 8, !tbaa !9
  %280 = add i64 %278, %279
  call void @llvm.memmove.p0.p0.i64(ptr align 1 %272, ptr align 1 %273, i64 %280, i1 false)
  call void @llvm.lifetime.start.p0(i64 8, ptr %16) #9
  %281 = load ptr, ptr %5, align 8, !tbaa !5
  %282 = getelementptr inbounds %struct.page, ptr %281, i32 0, i32 5
  %283 = load i64, ptr %6, align 8, !tbaa !9
  %284 = getelementptr inbounds [0 x i16], ptr %282, i64 0, i64 %283
  %285 = load i16, ptr %284, align 1, !tbaa !15
  %286 = zext i16 %285 to i64
  store i64 %286, ptr %16, align 8, !tbaa !9
  call void @llvm.lifetime.start.p0(i64 8, ptr %17) #9
  %287 = load ptr, ptr %5, align 8, !tbaa !5
  %288 = call i64 @page_numkeys(ptr noundef %287) #7
  store i64 %288, ptr %17, align 8, !tbaa !9
  br label %289

289:                                              ; preds = %351, %239
  %290 = load i64, ptr %17, align 8, !tbaa !9
  %291 = add nsw i64 %290, -1
  store i64 %291, ptr %17, align 8, !tbaa !9
  %292 = icmp sge i64 %291, 0
  br i1 %292, label %294, label %293

293:                                              ; preds = %289
  store i32 24, ptr %10, align 4
  call void @llvm.lifetime.end.p0(i64 8, ptr %17) #9
  br label %352

294:                                              ; preds = %289
  %295 = load ptr, ptr %5, align 8, !tbaa !5
  %296 = getelementptr inbounds %struct.page, ptr %295, i32 0, i32 5
  %297 = load i64, ptr %17, align 8, !tbaa !9
  %298 = getelementptr inbounds [0 x i16], ptr %296, i64 0, i64 %297
  %299 = load i16, ptr %298, align 1, !tbaa !15
  %300 = zext i16 %299 to i64
  %301 = load i64, ptr %16, align 8, !tbaa !9
  %302 = icmp ule i64 %300, %301
  br i1 %302, label %303, label %351

303:                                              ; preds = %294
  br label %304

304:                                              ; preds = %303
  %305 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !11
  %306 = zext i8 %305 to i32
  %307 = and i32 %306, 1
  %308 = icmp ne i32 %307, 0
  %309 = xor i1 %308, true
  %310 = xor i1 %309, true
  %311 = zext i1 %310 to i32
  %312 = sext i32 %311 to i64
  %313 = call i64 @llvm.expect.i64(i64 %312, i64 1)
  %314 = icmp ne i64 %313, 0
  br i1 %314, label %315, label %337

315:                                              ; preds = %304
  br label %316

316:                                              ; preds = %315
  %317 = load ptr, ptr %5, align 8, !tbaa !5
  %318 = getelementptr inbounds %struct.page, ptr %317, i32 0, i32 5
  %319 = load i64, ptr %17, align 8, !tbaa !9
  %320 = getelementptr inbounds [0 x i16], ptr %318, i64 0, i64 %319
  %321 = load i16, ptr %320, align 1, !tbaa !15
  %322 = zext i16 %321 to i64
  %323 = sub i64 65535, %322
  %324 = load i64, ptr %9, align 8, !tbaa !9
  %325 = icmp uge i64 %323, %324
  %326 = xor i1 %325, true
  %327 = xor i1 %326, true
  %328 = xor i1 %327, true
  %329 = zext i1 %328 to i32
  %330 = sext i32 %329 to i64
  %331 = call i64 @llvm.expect.i64(i64 %330, i64 0)
  %332 = icmp ne i64 %331, 0
  br i1 %332, label %333, label %334

333:                                              ; preds = %316
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.42, ptr noundef @__func__.node_shrink, i32 noundef 278) #8
  unreachable

334:                                              ; preds = %316
  br label %335

335:                                              ; preds = %334
  br label %336

336:                                              ; preds = %335
  br label %337

337:                                              ; preds = %336, %304
  br label %338

338:                                              ; preds = %337
  br label %339

339:                                              ; preds = %338
  %340 = load i64, ptr %9, align 8, !tbaa !9
  %341 = trunc i64 %340 to i16
  %342 = zext i16 %341 to i32
  %343 = load ptr, ptr %5, align 8, !tbaa !5
  %344 = getelementptr inbounds %struct.page, ptr %343, i32 0, i32 5
  %345 = load i64, ptr %17, align 8, !tbaa !9
  %346 = getelementptr inbounds [0 x i16], ptr %344, i64 0, i64 %345
  %347 = load i16, ptr %346, align 1, !tbaa !15
  %348 = zext i16 %347 to i32
  %349 = add nsw i32 %348, %342
  %350 = trunc i32 %349 to i16
  store i16 %350, ptr %346, align 1, !tbaa !15
  br label %351

351:                                              ; preds = %339, %294
  br label %289, !llvm.loop !21

352:                                              ; preds = %293
  br label %353

353:                                              ; preds = %352
  %354 = load i8, ptr getelementptr inbounds (%struct.libmdbx_globals, ptr @globals, i32 0, i32 4), align 1, !tbaa !11
  %355 = zext i8 %354 to i32
  %356 = and i32 %355, 1
  %357 = icmp ne i32 %356, 0
  %358 = xor i1 %357, true
  %359 = xor i1 %358, true
  %360 = zext i1 %359 to i32
  %361 = sext i32 %360 to i64
  %362 = call i64 @llvm.expect.i64(i64 %361, i64 1)
  %363 = icmp ne i64 %362, 0
  br i1 %363, label %364, label %385

364:                                              ; preds = %353
  br label %365

365:                                              ; preds = %364
  %366 = load ptr, ptr %5, align 8, !tbaa !5
  %367 = getelementptr inbounds %struct.page, ptr %366, i32 0, i32 3
  %368 = getelementptr inbounds %struct.anon.3, ptr %367, i32 0, i32 1
  %369 = load i16, ptr %368, align 1, !tbaa !19
  %370 = zext i16 %369 to i64
  %371 = sub i64 65535, %370
  %372 = load i64, ptr %9, align 8, !tbaa !9
  %373 = icmp uge i64 %371, %372
  %374 = xor i1 %373, true
  %375 = xor i1 %374, true
  %376 = xor i1 %375, true
  %377 = zext i1 %376 to i32
  %378 = sext i32 %377 to i64
  %379 = call i64 @llvm.expect.i64(i64 %378, i64 0)
  %380 = icmp ne i64 %379, 0
  br i1 %380, label %381, label %382

381:                                              ; preds = %365
  call void @mdbx_assert_fail(ptr noundef null, ptr noundef @.str.43, ptr noundef @__func__.node_shrink, i32 noundef 282) #8
  unreachable

382:                                              ; preds = %365
  br label %383

383:                                              ; preds = %382
  br label %384

384:                                              ; preds = %383
  br label %385

385:                                              ; preds = %384, %353
  br label %386

386:                                              ; preds = %385
  br label %387

387:                                              ; preds = %386
  %388 = load i64, ptr %9, align 8, !tbaa !9
  %389 = trunc i64 %388 to i16
  %390 = zext i16 %389 to i32
  %391 = load ptr, ptr %5, align 8, !tbaa !5
  %392 = getelementptr inbounds %struct.page, ptr %391, i32 0, i32 3
  %393 = getelementptr inbounds %struct.anon.3, ptr %392, i32 0, i32 1
  %394 = load i16, ptr %393, align 1, !tbaa !19
  %395 = zext i16 %394 to i32
  %396 = add nsw i32 %395, %390
  %397 = trunc i32 %396 to i16
  store i16 %397, ptr %393, align 1, !tbaa !19
  %398 = load ptr, ptr %7, align 8, !tbaa !5
  %399 = ptrtoint ptr %398 to i64
  %400 = load i64, ptr %9, align 8, !tbaa !9
  %401 = add nsw i64 %399, %400
  %402 = inttoptr i64 %401 to ptr
  store ptr %402, ptr %4, align 8
  store i32 1, ptr %10, align 4
  call void @llvm.lifetime.end.p0(i64 8, ptr %16) #9
  call void @llvm.lifetime.end.p0(i64 8, ptr %15) #9
  call void @llvm.lifetime.end.p0(i64 8, ptr %12) #9
  call void @llvm.lifetime.end.p0(i64 8, ptr %11) #9
  br label %403

403:                                              ; preds = %387, %96
  call void @llvm.lifetime.end.p0(i64 8, ptr %9) #9
  call void @llvm.lifetime.end.p0(i64 8, ptr %8) #9
  %404 = load ptr, ptr %4, align 8
  ret ptr %404
}

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

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

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.0 (git@github.com:llvm/llvm-project.git a4bf6cd7cfb1a1421ba92bca9d017b49936c55e4)"}
!5 = !{!6, !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 = !{!"long", !7, i64 0}
!11 = !{!12, !7, i64 25}
!12 = !{!"libmdbx_globals", !7, i64 0, !13, i64 16, !13, i64 20, !7, i64 24, !7, i64 25, !7, i64 26, !14, i64 27, !13, i64 28, !7, i64 32, !7, i64 40, !10, i64 80, !6, i64 88}
!13 = !{!"int", !7, i64 0}
!14 = !{!"_Bool", !7, i64 0}
!15 = !{!16, !16, i64 0}
!16 = !{!"short", !7, i64 0}
!17 = distinct !{!17, !18}
!18 = !{!"llvm.loop.mustprogress"}
!19 = !{!7, !7, i64 0}
!20 = !{!13, !13, i64 0}
!21 = distinct !{!21, !18}


; 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.0 }
%struct.anon.0 = type { i64, i64 }
%union.logger_union = type { ptr }
%union.pthread_mutex_t = type { %struct.__pthread_mutex_s }
%struct.__pthread_mutex_s = type { i32, i32, i32, i32, i32, i16, i16, %struct.__pthread_internal_list }
%struct.__pthread_internal_list = type { ptr, ptr }

@globals = external local_unnamed_addr global %struct.libmdbx_globals, align 8
@.str.37 = external hidden unnamed_addr constant [28 x i8], align 1
@__func__.node_shrink = external hidden unnamed_addr constant [12 x i8], align 1
@.str.38 = external hidden unnamed_addr constant [39 x i8], align 1
@.str.40 = external hidden unnamed_addr constant [24 x i8], align 1
@.str.41 = external hidden unnamed_addr constant [31 x i8], align 1
@.str.42 = external hidden unnamed_addr constant [42 x i8], align 1
@.str.43 = external hidden unnamed_addr constant [37 x i8], align 1

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

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

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

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

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

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

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

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

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

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

; Function Attrs: nounwind uwtable
define dso_local ptr @node_shrink(ptr noundef %0, i64 noundef %1, ptr noundef %2) local_unnamed_addr #4 {
  %4 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !5
  %5 = and i8 %4, 1
  %.not = icmp eq i8 %5, 0
  br i1 %.not, label %.thread, label %7, !prof !13

.thread:                                          ; preds = %3
  %6 = tail call ptr @node_data(ptr noundef %2) #5
  br label %16

7:                                                ; preds = %3
  %8 = tail call ptr @page_node(ptr noundef %0, i64 noundef %1) #5
  %.not68 = icmp eq ptr %8, %2
  br i1 %.not68, label %10, label %9, !prof !14

9:                                                ; preds = %7
  tail call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.37, ptr noundef nonnull @__func__.node_shrink, i32 noundef 248) #6
  unreachable

10:                                               ; preds = %7
  %11 = tail call ptr @node_data(ptr noundef %2) #5
  %12 = tail call zeroext i1 @is_subpage(ptr noundef %11) #5
  br i1 %12, label %13, label %.critedge, !prof !14

13:                                               ; preds = %10
  %14 = tail call i64 @page_numkeys(ptr noundef %11) #5
  %15 = icmp eq i64 %14, 0
  br i1 %15, label %.critedge, label %16, !prof !13

.critedge:                                        ; preds = %10, %13
  tail call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.38, ptr noundef nonnull @__func__.node_shrink, i32 noundef 250) #6
  unreachable

16:                                               ; preds = %.thread, %13
  %17 = phi ptr [ %6, %.thread ], [ %11, %13 ]
  %18 = ptrtoint ptr %17 to i64
  %19 = tail call i64 @page_room(ptr noundef %17) #5
  %20 = and i64 %19, -2
  %.not70 = icmp eq i64 %20, 0
  br i1 %.not70, label %194, label %21, !prof !14

21:                                               ; preds = %16
  %22 = tail call i64 @node_ds(ptr noundef %2) #5
  %23 = sub i64 %22, %20
  %24 = tail call zeroext i1 @is_dupfix_leaf(ptr noundef %17) #5
  br i1 %24, label %.loopexit, label %25

25:                                               ; preds = %21
  %26 = tail call i64 @page_numkeys(ptr noundef %17) #5
  %27 = icmp sgt i64 %26, 0
  br i1 %27, label %.lr.ph, label %.loopexit

.lr.ph:                                           ; preds = %25
  %28 = add nsw i64 %26, -1
  %29 = ptrtoint ptr %17 to i64
  %30 = add nsw i64 %20, %29
  %31 = inttoptr i64 %30 to ptr
  %32 = getelementptr inbounds i8, ptr %17, i64 20
  %33 = trunc i64 %20 to i16
  %34 = getelementptr inbounds i8, ptr %31, i64 20
  br i1 %.not, label %.lr.ph.split.us.preheader, label %.lr.ph.split, !prof !13

.lr.ph.split.us.preheader:                        ; preds = %.lr.ph
  %min.iters.check = icmp ult i64 %26, 16
  %35 = sub i64 %18, %30
  %diff.check = icmp ult i64 %35, 32
  %or.cond = select i1 %min.iters.check, i1 true, i1 %diff.check
  br i1 %or.cond, label %.lr.ph.split.us.preheader128, label %vector.ph

vector.ph:                                        ; preds = %.lr.ph.split.us.preheader
  %n.vec = and i64 %26, 9223372036854775792
  %ind.end = sub i64 %28, %n.vec
  %broadcast.splatinsert = insertelement <8 x i16> poison, i16 %33, i64 0
  %36 = shufflevector <8 x i16> %broadcast.splatinsert, <8 x i16> poison, <8 x i32> zeroinitializer
  %37 = shufflevector <8 x i16> %broadcast.splatinsert, <8 x i16> poison, <8 x i32> zeroinitializer
  br label %vector.body

vector.body:                                      ; preds = %vector.body, %vector.ph
  %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
  %offset.idx = sub i64 %28, %index
  %38 = getelementptr inbounds [0 x i16], ptr %32, i64 0, i64 %offset.idx
  %39 = getelementptr inbounds i8, ptr %38, i64 -14
  %40 = getelementptr inbounds i8, ptr %38, i64 -30
  %wide.load = load <8 x i16>, ptr %39, align 1, !tbaa !15
  %wide.load91 = load <8 x i16>, ptr %40, align 1, !tbaa !15
  %41 = getelementptr inbounds [0 x i16], ptr %34, i64 0, i64 %offset.idx
  %42 = getelementptr inbounds i8, ptr %41, i64 -14
  %43 = getelementptr inbounds i8, ptr %41, i64 -30
  %reverse93 = sub <8 x i16> %wide.load, %36
  store <8 x i16> %reverse93, ptr %42, align 1, !tbaa !15
  %reverse94 = sub <8 x i16> %wide.load91, %37
  store <8 x i16> %reverse94, ptr %43, align 1, !tbaa !15
  %index.next = add nuw i64 %index, 16
  %44 = icmp eq i64 %index.next, %n.vec
  br i1 %44, label %middle.block, label %vector.body, !llvm.loop !17

middle.block:                                     ; preds = %vector.body
  %cmp.n = icmp eq i64 %26, %n.vec
  br i1 %cmp.n, label %.loopexit, label %.lr.ph.split.us.preheader128

.lr.ph.split.us.preheader128:                     ; preds = %middle.block, %.lr.ph.split.us.preheader
  %.ph129 = phi i64 [ %28, %.lr.ph.split.us.preheader ], [ %ind.end, %middle.block ]
  %45 = add i64 %.ph129, 1
  %xtraiter = and i64 %45, 3
  %lcmp.mod.not = icmp eq i64 %xtraiter, 0
  br i1 %lcmp.mod.not, label %.lr.ph.split.us.prol.loopexit, label %.lr.ph.split.us.prol

.lr.ph.split.us.prol:                             ; preds = %.lr.ph.split.us.preheader128, %.lr.ph.split.us.prol
  %46 = phi i64 [ %51, %.lr.ph.split.us.prol ], [ %.ph129, %.lr.ph.split.us.preheader128 ]
  %prol.iter = phi i64 [ %prol.iter.next, %.lr.ph.split.us.prol ], [ 0, %.lr.ph.split.us.preheader128 ]
  %47 = getelementptr inbounds [0 x i16], ptr %32, i64 0, i64 %46
  %48 = load i16, ptr %47, align 1, !tbaa !15
  %49 = sub i16 %48, %33
  %50 = getelementptr inbounds [0 x i16], ptr %34, i64 0, i64 %46
  store i16 %49, ptr %50, align 1, !tbaa !15
  %51 = add nsw i64 %46, -1
  %prol.iter.next = add i64 %prol.iter, 1
  %prol.iter.cmp.not = icmp eq i64 %prol.iter.next, %xtraiter
  br i1 %prol.iter.cmp.not, label %.lr.ph.split.us.prol.loopexit, label %.lr.ph.split.us.prol, !llvm.loop !21

.lr.ph.split.us.prol.loopexit:                    ; preds = %.lr.ph.split.us.prol, %.lr.ph.split.us.preheader128
  %.unr = phi i64 [ %.ph129, %.lr.ph.split.us.preheader128 ], [ %51, %.lr.ph.split.us.prol ]
  %52 = icmp ult i64 %.ph129, 3
  br i1 %52, label %.loopexit, label %.lr.ph.split.us

.lr.ph.split.us:                                  ; preds = %.lr.ph.split.us.prol.loopexit, %.lr.ph.split.us
  %53 = phi i64 [ %73, %.lr.ph.split.us ], [ %.unr, %.lr.ph.split.us.prol.loopexit ]
  %54 = getelementptr inbounds [0 x i16], ptr %32, i64 0, i64 %53
  %55 = load i16, ptr %54, align 1, !tbaa !15
  %56 = sub i16 %55, %33
  %57 = getelementptr inbounds [0 x i16], ptr %34, i64 0, i64 %53
  store i16 %56, ptr %57, align 1, !tbaa !15
  %58 = add nsw i64 %53, -1
  %59 = getelementptr inbounds [0 x i16], ptr %32, i64 0, i64 %58
  %60 = load i16, ptr %59, align 1, !tbaa !15
  %61 = sub i16 %60, %33
  %62 = getelementptr inbounds [0 x i16], ptr %34, i64 0, i64 %58
  store i16 %61, ptr %62, align 1, !tbaa !15
  %63 = add nsw i64 %53, -2
  %64 = getelementptr inbounds [0 x i16], ptr %32, i64 0, i64 %63
  %65 = load i16, ptr %64, align 1, !tbaa !15
  %66 = sub i16 %65, %33
  %67 = getelementptr inbounds [0 x i16], ptr %34, i64 0, i64 %63
  store i16 %66, ptr %67, align 1, !tbaa !15
  %68 = add nsw i64 %53, -3
  %69 = getelementptr inbounds [0 x i16], ptr %32, i64 0, i64 %68
  %70 = load i16, ptr %69, align 1, !tbaa !15
  %71 = sub i16 %70, %33
  %72 = getelementptr inbounds [0 x i16], ptr %34, i64 0, i64 %68
  store i16 %71, ptr %72, align 1, !tbaa !15
  %73 = add nsw i64 %53, -4
  %.not88.3 = icmp eq i64 %68, 0
  br i1 %.not88.3, label %.loopexit, label %.lr.ph.split.us, !llvm.loop !23

.lr.ph.split:                                     ; preds = %.lr.ph, %79
  %74 = phi i64 [ %82, %79 ], [ %28, %.lr.ph ]
  %75 = getelementptr inbounds [0 x i16], ptr %32, i64 0, i64 %74
  %76 = load i16, ptr %75, align 1, !tbaa !15
  %77 = zext i16 %76 to i64
  %.not73 = icmp ugt i64 %20, %77
  br i1 %.not73, label %78, label %79, !prof !13

78:                                               ; preds = %.lr.ph.split
  tail call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.40, ptr noundef nonnull @__func__.node_shrink, i32 noundef 262) #6
  unreachable

79:                                               ; preds = %.lr.ph.split
  %80 = sub i16 %76, %33
  %81 = getelementptr inbounds [0 x i16], ptr %34, i64 0, i64 %74
  store i16 %80, ptr %81, align 1, !tbaa !15
  %82 = add nsw i64 %74, -1
  %83 = icmp sgt i64 %74, 0
  br i1 %83, label %.lr.ph.split, label %.loopexit, !llvm.loop !24

.loopexit:                                        ; preds = %79, %.lr.ph.split.us.prol.loopexit, %.lr.ph.split.us, %middle.block, %25, %21
  %.064 = phi i64 [ %23, %21 ], [ 20, %25 ], [ 20, %middle.block ], [ 20, %.lr.ph.split.us ], [ 20, %.lr.ph.split.us.prol.loopexit ], [ 20, %79 ]
  br i1 %.not, label %.loopexit._crit_edge, label %84, !prof !13

.loopexit._crit_edge:                             ; preds = %.loopexit
  %.phi.trans.insert = getelementptr inbounds i8, ptr %17, i64 14
  %.pre = load i16, ptr %.phi.trans.insert, align 1, !tbaa !25
  br label %93

84:                                               ; preds = %.loopexit
  %85 = getelementptr inbounds i8, ptr %17, i64 12
  %86 = getelementptr inbounds i8, ptr %17, i64 14
  %87 = load i16, ptr %86, align 1, !tbaa !25
  %88 = zext i16 %87 to i64
  %89 = load i16, ptr %85, align 1, !tbaa !25
  %90 = zext i16 %89 to i64
  %91 = add i64 %20, %90
  %.not75 = icmp ugt i64 %91, %88
  br i1 %.not75, label %92, label %93, !prof !13

92:                                               ; preds = %84
  tail call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.41, ptr noundef nonnull @__func__.node_shrink, i32 noundef 266) #6
  unreachable

93:                                               ; preds = %.loopexit._crit_edge, %84
  %94 = phi i16 [ %.pre, %.loopexit._crit_edge ], [ %87, %84 ]
  %95 = trunc i64 %19 to i16
  %96 = and i16 %95, -2
  %97 = getelementptr inbounds i8, ptr %17, i64 14
  %98 = sub i16 %94, %96
  store i16 %98, ptr %97, align 1, !tbaa !25
  %99 = getelementptr inbounds i8, ptr %0, i64 16
  %100 = load i32, ptr %99, align 1, !tbaa !26
  %101 = getelementptr inbounds i8, ptr %17, i64 16
  store i32 %100, ptr %101, align 1, !tbaa !26
  tail call void @node_set_ds(ptr noundef %2, i64 noundef %23)
  %102 = ptrtoint ptr %0 to i64
  %103 = getelementptr inbounds i8, ptr %0, i64 14
  %104 = load i16, ptr %103, align 1, !tbaa !25
  %105 = zext i16 %104 to i64
  %106 = add i64 %102, 20
  %107 = add i64 %106, %105
  %108 = inttoptr i64 %107 to ptr
  %109 = add nsw i64 %107, %20
  %110 = inttoptr i64 %109 to ptr
  %111 = ptrtoint ptr %17 to i64
  %112 = add i64 %.064, %111
  %113 = sub i64 %112, %107
  tail call void @llvm.memmove.p0.p0.i64(ptr align 1 %110, ptr align 1 %108, i64 %113, i1 false)
  %114 = getelementptr inbounds i8, ptr %0, i64 20
  %115 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %1
  %116 = load i16, ptr %115, align 1, !tbaa !15
  %117 = tail call i64 @page_numkeys(ptr noundef %0) #5
  %118 = icmp sgt i64 %117, 0
  br i1 %118, label %.lr.ph81, label %._crit_edge

.lr.ph81:                                         ; preds = %93
  %119 = add nsw i64 %117, -1
  %120 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1
  %.fr82 = freeze i8 %120
  %121 = and i8 %.fr82, 1
  %.not79 = icmp eq i8 %121, 0
  br i1 %.not79, label %.lr.ph81.split.us.preheader, label %.lr.ph81.split, !prof !13

.lr.ph81.split.us.preheader:                      ; preds = %.lr.ph81
  %min.iters.check97 = icmp ult i64 %117, 8
  br i1 %min.iters.check97, label %.lr.ph81.split.us.preheader126, label %vector.ph98

vector.ph98:                                      ; preds = %.lr.ph81.split.us.preheader
  %n.vec100 = and i64 %117, 9223372036854775800
  %ind.end101 = sub i64 %119, %n.vec100
  %broadcast.splatinsert108 = insertelement <8 x i16> poison, i16 %116, i64 0
  %broadcast.splat109 = shufflevector <8 x i16> %broadcast.splatinsert108, <8 x i16> poison, <8 x i32> zeroinitializer
  %invariant.gep = getelementptr i8, ptr %114, i64 -14
  br label %vector.body103

vector.body103:                                   ; preds = %pred.store.continue123, %vector.ph98
  %index104 = phi i64 [ 0, %vector.ph98 ], [ %index.next124, %pred.store.continue123 ]
  %offset.idx105 = sub i64 %119, %index104
  %gep = getelementptr [0 x i16], ptr %invariant.gep, i64 0, i64 %offset.idx105
  %wide.load106 = load <8 x i16>, ptr %gep, align 1, !tbaa !15
  %reverse107 = shufflevector <8 x i16> %wide.load106, <8 x i16> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  %122 = icmp ule <8 x i16> %reverse107, %broadcast.splat109
  %123 = extractelement <8 x i1> %122, i64 0
  br i1 %123, label %pred.store.if, label %pred.store.continue

pred.store.if:                                    ; preds = %vector.body103
  %124 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %offset.idx105
  %125 = extractelement <8 x i16> %wide.load106, i64 7
  %126 = add i16 %125, %96
  store i16 %126, ptr %124, align 1, !tbaa !15
  br label %pred.store.continue

pred.store.continue:                              ; preds = %pred.store.if, %vector.body103
  %127 = extractelement <8 x i1> %122, i64 1
  br i1 %127, label %pred.store.if110, label %pred.store.continue111

pred.store.if110:                                 ; preds = %pred.store.continue
  %128 = add i64 %offset.idx105, -1
  %129 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %128
  %130 = extractelement <8 x i16> %wide.load106, i64 6
  %131 = add i16 %130, %96
  store i16 %131, ptr %129, align 1, !tbaa !15
  br label %pred.store.continue111

pred.store.continue111:                           ; preds = %pred.store.if110, %pred.store.continue
  %132 = extractelement <8 x i1> %122, i64 2
  br i1 %132, label %pred.store.if112, label %pred.store.continue113

pred.store.if112:                                 ; preds = %pred.store.continue111
  %133 = add i64 %offset.idx105, -2
  %134 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %133
  %135 = extractelement <8 x i16> %wide.load106, i64 5
  %136 = add i16 %135, %96
  store i16 %136, ptr %134, align 1, !tbaa !15
  br label %pred.store.continue113

pred.store.continue113:                           ; preds = %pred.store.if112, %pred.store.continue111
  %137 = extractelement <8 x i1> %122, i64 3
  br i1 %137, label %pred.store.if114, label %pred.store.continue115

pred.store.if114:                                 ; preds = %pred.store.continue113
  %138 = add i64 %offset.idx105, -3
  %139 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %138
  %140 = extractelement <8 x i16> %wide.load106, i64 4
  %141 = add i16 %140, %96
  store i16 %141, ptr %139, align 1, !tbaa !15
  br label %pred.store.continue115

pred.store.continue115:                           ; preds = %pred.store.if114, %pred.store.continue113
  %142 = extractelement <8 x i1> %122, i64 4
  br i1 %142, label %pred.store.if116, label %pred.store.continue117

pred.store.if116:                                 ; preds = %pred.store.continue115
  %143 = add i64 %offset.idx105, -4
  %144 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %143
  %145 = extractelement <8 x i16> %wide.load106, i64 3
  %146 = add i16 %145, %96
  store i16 %146, ptr %144, align 1, !tbaa !15
  br label %pred.store.continue117

pred.store.continue117:                           ; preds = %pred.store.if116, %pred.store.continue115
  %147 = extractelement <8 x i1> %122, i64 5
  br i1 %147, label %pred.store.if118, label %pred.store.continue119

pred.store.if118:                                 ; preds = %pred.store.continue117
  %148 = add i64 %offset.idx105, -5
  %149 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %148
  %150 = extractelement <8 x i16> %wide.load106, i64 2
  %151 = add i16 %150, %96
  store i16 %151, ptr %149, align 1, !tbaa !15
  br label %pred.store.continue119

pred.store.continue119:                           ; preds = %pred.store.if118, %pred.store.continue117
  %152 = extractelement <8 x i1> %122, i64 6
  br i1 %152, label %pred.store.if120, label %pred.store.continue121

pred.store.if120:                                 ; preds = %pred.store.continue119
  %153 = add i64 %offset.idx105, -6
  %154 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %153
  %155 = extractelement <8 x i16> %wide.load106, i64 1
  %156 = add i16 %155, %96
  store i16 %156, ptr %154, align 1, !tbaa !15
  br label %pred.store.continue121

pred.store.continue121:                           ; preds = %pred.store.if120, %pred.store.continue119
  %157 = extractelement <8 x i1> %122, i64 7
  br i1 %157, label %pred.store.if122, label %pred.store.continue123

pred.store.if122:                                 ; preds = %pred.store.continue121
  %158 = add i64 %offset.idx105, -7
  %159 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %158
  %160 = extractelement <8 x i16> %wide.load106, i64 0
  %161 = add i16 %160, %96
  store i16 %161, ptr %159, align 1, !tbaa !15
  br label %pred.store.continue123

pred.store.continue123:                           ; preds = %pred.store.if122, %pred.store.continue121
  %index.next124 = add nuw i64 %index104, 8
  %162 = icmp eq i64 %index.next124, %n.vec100
  br i1 %162, label %middle.block95, label %vector.body103, !llvm.loop !27

middle.block95:                                   ; preds = %pred.store.continue123
  %cmp.n125 = icmp eq i64 %117, %n.vec100
  br i1 %cmp.n125, label %._crit_edge, label %.lr.ph81.split.us.preheader126

.lr.ph81.split.us.preheader126:                   ; preds = %middle.block95, %.lr.ph81.split.us.preheader
  %.ph = phi i64 [ %119, %.lr.ph81.split.us.preheader ], [ %ind.end101, %middle.block95 ]
  br label %.lr.ph81.split.us

.lr.ph81.split.us:                                ; preds = %.lr.ph81.split.us.preheader126, %168
  %163 = phi i64 [ %169, %168 ], [ %.ph, %.lr.ph81.split.us.preheader126 ]
  %164 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %163
  %165 = load i16, ptr %164, align 1, !tbaa !15
  %.not78.us = icmp ugt i16 %165, %116
  br i1 %.not78.us, label %168, label %166

166:                                              ; preds = %.lr.ph81.split.us
  %167 = add i16 %165, %96
  store i16 %167, ptr %164, align 1, !tbaa !15
  br label %168

168:                                              ; preds = %166, %.lr.ph81.split.us
  %169 = add nsw i64 %163, -1
  %170 = icmp sgt i64 %163, 0
  br i1 %170, label %.lr.ph81.split.us, label %._crit_edge, !llvm.loop !28

._crit_edge:                                      ; preds = %182, %168, %middle.block95, %93
  %171 = load i8, ptr getelementptr inbounds (i8, ptr @globals, i64 25), align 1, !tbaa !5
  %172 = and i8 %171, 1
  %.not76 = icmp eq i8 %172, 0
  %.pre85 = load i16, ptr %103, align 1, !tbaa !25
  br i1 %.not76, label %189, label %185, !prof !13

.lr.ph81.split:                                   ; preds = %.lr.ph81, %182
  %173 = phi i64 [ %183, %182 ], [ %119, %.lr.ph81 ]
  %174 = getelementptr inbounds [0 x i16], ptr %114, i64 0, i64 %173
  %175 = load i16, ptr %174, align 1, !tbaa !15
  %.not78 = icmp ugt i16 %175, %116
  br i1 %.not78, label %182, label %176

176:                                              ; preds = %.lr.ph81.split
  %177 = xor i16 %175, -1
  %178 = zext i16 %177 to i64
  %.not80 = icmp ugt i64 %20, %178
  br i1 %.not80, label %179, label %180, !prof !13

179:                                              ; preds = %176
  tail call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.42, ptr noundef nonnull @__func__.node_shrink, i32 noundef 278) #6
  unreachable

180:                                              ; preds = %176
  %181 = add i16 %175, %96
  store i16 %181, ptr %174, align 1, !tbaa !15
  br label %182

182:                                              ; preds = %180, %.lr.ph81.split
  %183 = add nsw i64 %173, -1
  %184 = icmp sgt i64 %173, 0
  br i1 %184, label %.lr.ph81.split, label %._crit_edge, !llvm.loop !29

185:                                              ; preds = %._crit_edge
  %186 = xor i16 %.pre85, -1
  %187 = zext i16 %186 to i64
  %.not77 = icmp ugt i64 %20, %187
  br i1 %.not77, label %188, label %189, !prof !13

188:                                              ; preds = %185
  tail call void @mdbx_assert_fail(ptr noundef null, ptr noundef nonnull @.str.43, ptr noundef nonnull @__func__.node_shrink, i32 noundef 282) #6
  unreachable

189:                                              ; preds = %185, %._crit_edge
  %190 = add i16 %.pre85, %96
  store i16 %190, ptr %103, align 1, !tbaa !25
  %191 = ptrtoint ptr %2 to i64
  %192 = add nsw i64 %20, %191
  %193 = inttoptr i64 %192 to ptr
  br label %194

194:                                              ; preds = %16, %189
  %.062 = phi ptr [ %193, %189 ], [ %2, %16 ]
  ret ptr %.062
}

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

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

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.0 (git@github.com:llvm/llvm-project.git a4bf6cd7cfb1a1421ba92bca9d017b49936c55e4)"}
!5 = !{!6, !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, !16, i64 0}
!16 = !{!"short", !7, i64 0}
!17 = distinct !{!17, !18, !19, !20}
!18 = !{!"llvm.loop.mustprogress"}
!19 = !{!"llvm.loop.isvectorized", i32 1}
!20 = !{!"llvm.loop.unroll.runtime.disable"}
!21 = distinct !{!21, !22}
!22 = !{!"llvm.loop.unroll.disable"}
!23 = distinct !{!23, !18, !19}
!24 = distinct !{!24, !18}
!25 = !{!7, !7, i64 0}
!26 = !{!9, !9, i64 0}
!27 = distinct !{!27, !18, !19, !20}
!28 = distinct !{!28, !18, !20, !19}
!29 = distinct !{!29, !18}


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