; LLVM IR from imkcat/CatCrypto :: Sources/ModuleMaps/Argon2 (ref)

; 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.Argon2_position_t = type { i32, i32, i8, i32 }
%struct.block_ = type { [128 x i64] }
%struct.Argon2_instance_t = type { ptr, i32, i32, i32, i32, i32, i32, i32, i32, i32, ptr }

; Function Attrs: nounwind uwtable
define dso_local void @fill_segment(ptr noundef %0, i64 %1, i64 %2) #0 {
  %4 = alloca %struct.Argon2_position_t, align 4
  %5 = alloca ptr, align 8
  %6 = alloca ptr, align 8
  %7 = alloca ptr, align 8
  %8 = alloca %struct.block_, align 8
  %9 = alloca %struct.block_, align 8
  %10 = alloca %struct.block_, align 8
  %11 = alloca i64, align 8
  %12 = alloca i64, align 8
  %13 = alloca i64, align 8
  %14 = alloca i32, align 4
  %15 = alloca i32, align 4
  %16 = alloca i32, align 4
  %17 = alloca i32, align 4
  %18 = alloca i32, align 4
  %19 = alloca i32, align 4
  %20 = getelementptr inbounds { i64, i64 }, ptr %4, i32 0, i32 0
  store i64 %1, ptr %20, align 4
  %21 = getelementptr inbounds { i64, i64 }, ptr %4, i32 0, i32 1
  store i64 %2, ptr %21, align 4
  store ptr %0, ptr %5, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 8, ptr %6) #3
  store ptr null, ptr %6, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 8, ptr %7) #3
  store ptr null, ptr %7, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 1024, ptr %8) #3
  call void @llvm.lifetime.start.p0(i64 1024, ptr %9) #3
  call void @llvm.lifetime.start.p0(i64 1024, ptr %10) #3
  call void @llvm.lifetime.start.p0(i64 8, ptr %11) #3
  call void @llvm.lifetime.start.p0(i64 8, ptr %12) #3
  call void @llvm.lifetime.start.p0(i64 8, ptr %13) #3
  call void @llvm.lifetime.start.p0(i64 4, ptr %14) #3
  call void @llvm.lifetime.start.p0(i64 4, ptr %15) #3
  call void @llvm.lifetime.start.p0(i64 4, ptr %16) #3
  call void @llvm.lifetime.start.p0(i64 4, ptr %17) #3
  call void @llvm.lifetime.start.p0(i64 4, ptr %18) #3
  %22 = load ptr, ptr %5, align 8, !tbaa !5
  %23 = icmp eq ptr %22, null
  br i1 %23, label %24, label %25

24:                                               ; preds = %3
  store i32 1, ptr %19, align 4
  br label %273

25:                                               ; preds = %3
  %26 = load ptr, ptr %5, align 8, !tbaa !5
  %27 = getelementptr inbounds %struct.Argon2_instance_t, ptr %26, i32 0, i32 8
  %28 = load i32, ptr %27, align 4, !tbaa !9
  %29 = icmp eq i32 %28, 1
  br i1 %29, label %46, label %30

30:                                               ; preds = %25
  %31 = load ptr, ptr %5, align 8, !tbaa !5
  %32 = getelementptr inbounds %struct.Argon2_instance_t, ptr %31, i32 0, i32 8
  %33 = load i32, ptr %32, align 4, !tbaa !9
  %34 = icmp eq i32 %33, 2
  br i1 %34, label %35, label %44

35:                                               ; preds = %30
  %36 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 0
  %37 = load i32, ptr %36, align 4, !tbaa !12
  %38 = icmp eq i32 %37, 0
  br i1 %38, label %39, label %44

39:                                               ; preds = %35
  %40 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 2
  %41 = load i8, ptr %40, align 4, !tbaa !14
  %42 = zext i8 %41 to i32
  %43 = icmp ult i32 %42, 2
  br label %44

44:                                               ; preds = %39, %35, %30
  %45 = phi i1 [ false, %35 ], [ false, %30 ], [ %43, %39 ]
  br label %46

46:                                               ; preds = %44, %25
  %47 = phi i1 [ true, %25 ], [ %45, %44 ]
  %48 = zext i1 %47 to i32
  store i32 %48, ptr %18, align 4, !tbaa !15
  %49 = load i32, ptr %18, align 4, !tbaa !15
  %50 = icmp ne i32 %49, 0
  br i1 %50, label %51, label %85

51:                                               ; preds = %46
  call void @init_block_value(ptr noundef %10, i8 noundef zeroext 0)
  call void @init_block_value(ptr noundef %9, i8 noundef zeroext 0)
  %52 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 0
  %53 = load i32, ptr %52, align 4, !tbaa !12
  %54 = zext i32 %53 to i64
  %55 = getelementptr inbounds %struct.block_, ptr %9, i32 0, i32 0
  %56 = getelementptr inbounds [128 x i64], ptr %55, i64 0, i64 0
  store i64 %54, ptr %56, align 8, !tbaa !16
  %57 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 1
  %58 = load i32, ptr %57, align 4, !tbaa !18
  %59 = zext i32 %58 to i64
  %60 = getelementptr inbounds %struct.block_, ptr %9, i32 0, i32 0
  %61 = getelementptr inbounds [128 x i64], ptr %60, i64 0, i64 1
  store i64 %59, ptr %61, align 8, !tbaa !16
  %62 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 2
  %63 = load i8, ptr %62, align 4, !tbaa !14
  %64 = zext i8 %63 to i64
  %65 = getelementptr inbounds %struct.block_, ptr %9, i32 0, i32 0
  %66 = getelementptr inbounds [128 x i64], ptr %65, i64 0, i64 2
  store i64 %64, ptr %66, align 8, !tbaa !16
  %67 = load ptr, ptr %5, align 8, !tbaa !5
  %68 = getelementptr inbounds %struct.Argon2_instance_t, ptr %67, i32 0, i32 3
  %69 = load i32, ptr %68, align 8, !tbaa !19
  %70 = zext i32 %69 to i64
  %71 = getelementptr inbounds %struct.block_, ptr %9, i32 0, i32 0
  %72 = getelementptr inbounds [128 x i64], ptr %71, i64 0, i64 3
  store i64 %70, ptr %72, align 8, !tbaa !16
  %73 = load ptr, ptr %5, align 8, !tbaa !5
  %74 = getelementptr inbounds %struct.Argon2_instance_t, ptr %73, i32 0, i32 2
  %75 = load i32, ptr %74, align 4, !tbaa !20
  %76 = zext i32 %75 to i64
  %77 = getelementptr inbounds %struct.block_, ptr %9, i32 0, i32 0
  %78 = getelementptr inbounds [128 x i64], ptr %77, i64 0, i64 4
  store i64 %76, ptr %78, align 8, !tbaa !16
  %79 = load ptr, ptr %5, align 8, !tbaa !5
  %80 = getelementptr inbounds %struct.Argon2_instance_t, ptr %79, i32 0, i32 8
  %81 = load i32, ptr %80, align 4, !tbaa !9
  %82 = zext i32 %81 to i64
  %83 = getelementptr inbounds %struct.block_, ptr %9, i32 0, i32 0
  %84 = getelementptr inbounds [128 x i64], ptr %83, i64 0, i64 5
  store i64 %82, ptr %84, align 8, !tbaa !16
  br label %85

85:                                               ; preds = %51, %46
  store i32 0, ptr %16, align 4, !tbaa !15
  %86 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 0
  %87 = load i32, ptr %86, align 4, !tbaa !12
  %88 = icmp eq i32 0, %87
  br i1 %88, label %89, label %99

89:                                               ; preds = %85
  %90 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 2
  %91 = load i8, ptr %90, align 4, !tbaa !14
  %92 = zext i8 %91 to i32
  %93 = icmp eq i32 0, %92
  br i1 %93, label %94, label %99

94:                                               ; preds = %89
  store i32 2, ptr %16, align 4, !tbaa !15
  %95 = load i32, ptr %18, align 4, !tbaa !15
  %96 = icmp ne i32 %95, 0
  br i1 %96, label %97, label %98

97:                                               ; preds = %94
  call void @next_addresses(ptr noundef %8, ptr noundef %9, ptr noundef %10)
  br label %98

98:                                               ; preds = %97, %94
  br label %99

99:                                               ; preds = %98, %89, %85
  %100 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 1
  %101 = load i32, ptr %100, align 4, !tbaa !18
  %102 = load ptr, ptr %5, align 8, !tbaa !5
  %103 = getelementptr inbounds %struct.Argon2_instance_t, ptr %102, i32 0, i32 5
  %104 = load i32, ptr %103, align 8, !tbaa !21
  %105 = mul i32 %101, %104
  %106 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 2
  %107 = load i8, ptr %106, align 4, !tbaa !14
  %108 = zext i8 %107 to i32
  %109 = load ptr, ptr %5, align 8, !tbaa !5
  %110 = getelementptr inbounds %struct.Argon2_instance_t, ptr %109, i32 0, i32 4
  %111 = load i32, ptr %110, align 4, !tbaa !22
  %112 = mul i32 %108, %111
  %113 = add i32 %105, %112
  %114 = load i32, ptr %16, align 4, !tbaa !15
  %115 = add i32 %113, %114
  store i32 %115, ptr %15, align 4, !tbaa !15
  %116 = load i32, ptr %15, align 4, !tbaa !15
  %117 = load ptr, ptr %5, align 8, !tbaa !5
  %118 = getelementptr inbounds %struct.Argon2_instance_t, ptr %117, i32 0, i32 5
  %119 = load i32, ptr %118, align 8, !tbaa !21
  %120 = urem i32 %116, %119
  %121 = icmp eq i32 0, %120
  br i1 %121, label %122, label %129

122:                                              ; preds = %99
  %123 = load i32, ptr %15, align 4, !tbaa !15
  %124 = load ptr, ptr %5, align 8, !tbaa !5
  %125 = getelementptr inbounds %struct.Argon2_instance_t, ptr %124, i32 0, i32 5
  %126 = load i32, ptr %125, align 8, !tbaa !21
  %127 = add i32 %123, %126
  %128 = sub i32 %127, 1
  store i32 %128, ptr %14, align 4, !tbaa !15
  br label %132

129:                                              ; preds = %99
  %130 = load i32, ptr %15, align 4, !tbaa !15
  %131 = sub i32 %130, 1
  store i32 %131, ptr %14, align 4, !tbaa !15
  br label %132

132:                                              ; preds = %129, %122
  %133 = load i32, ptr %16, align 4, !tbaa !15
  store i32 %133, ptr %17, align 4, !tbaa !15
  br label %134

134:                                              ; preds = %265, %132
  %135 = load i32, ptr %17, align 4, !tbaa !15
  %136 = load ptr, ptr %5, align 8, !tbaa !5
  %137 = getelementptr inbounds %struct.Argon2_instance_t, ptr %136, i32 0, i32 4
  %138 = load i32, ptr %137, align 4, !tbaa !22
  %139 = icmp ult i32 %135, %138
  br i1 %139, label %140, label %272

140:                                              ; preds = %134
  %141 = load i32, ptr %15, align 4, !tbaa !15
  %142 = load ptr, ptr %5, align 8, !tbaa !5
  %143 = getelementptr inbounds %struct.Argon2_instance_t, ptr %142, i32 0, i32 5
  %144 = load i32, ptr %143, align 8, !tbaa !21
  %145 = urem i32 %141, %144
  %146 = icmp eq i32 %145, 1
  br i1 %146, label %147, label %150

147:                                              ; preds = %140
  %148 = load i32, ptr %15, align 4, !tbaa !15
  %149 = sub i32 %148, 1
  store i32 %149, ptr %14, align 4, !tbaa !15
  br label %150

150:                                              ; preds = %147, %140
  %151 = load i32, ptr %18, align 4, !tbaa !15
  %152 = icmp ne i32 %151, 0
  br i1 %152, label %153, label %165

153:                                              ; preds = %150
  %154 = load i32, ptr %17, align 4, !tbaa !15
  %155 = urem i32 %154, 128
  %156 = icmp eq i32 %155, 0
  br i1 %156, label %157, label %158

157:                                              ; preds = %153
  call void @next_addresses(ptr noundef %8, ptr noundef %9, ptr noundef %10)
  br label %158

158:                                              ; preds = %157, %153
  %159 = getelementptr inbounds %struct.block_, ptr %8, i32 0, i32 0
  %160 = load i32, ptr %17, align 4, !tbaa !15
  %161 = urem i32 %160, 128
  %162 = zext i32 %161 to i64
  %163 = getelementptr inbounds [128 x i64], ptr %159, i64 0, i64 %162
  %164 = load i64, ptr %163, align 8, !tbaa !16
  store i64 %164, ptr %11, align 8, !tbaa !16
  br label %175

165:                                              ; preds = %150
  %166 = load ptr, ptr %5, align 8, !tbaa !5
  %167 = getelementptr inbounds %struct.Argon2_instance_t, ptr %166, i32 0, i32 0
  %168 = load ptr, ptr %167, align 8, !tbaa !23
  %169 = load i32, ptr %14, align 4, !tbaa !15
  %170 = zext i32 %169 to i64
  %171 = getelementptr inbounds %struct.block_, ptr %168, i64 %170
  %172 = getelementptr inbounds %struct.block_, ptr %171, i32 0, i32 0
  %173 = getelementptr inbounds [128 x i64], ptr %172, i64 0, i64 0
  %174 = load i64, ptr %173, align 8, !tbaa !16
  store i64 %174, ptr %11, align 8, !tbaa !16
  br label %175

175:                                              ; preds = %165, %158
  %176 = load i64, ptr %11, align 8, !tbaa !16
  %177 = lshr i64 %176, 32
  %178 = load ptr, ptr %5, align 8, !tbaa !5
  %179 = getelementptr inbounds %struct.Argon2_instance_t, ptr %178, i32 0, i32 6
  %180 = load i32, ptr %179, align 4, !tbaa !24
  %181 = zext i32 %180 to i64
  %182 = urem i64 %177, %181
  store i64 %182, ptr %13, align 8, !tbaa !16
  %183 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 0
  %184 = load i32, ptr %183, align 4, !tbaa !12
  %185 = icmp eq i32 %184, 0
  br i1 %185, label %186, label %195

186:                                              ; preds = %175
  %187 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 2
  %188 = load i8, ptr %187, align 4, !tbaa !14
  %189 = zext i8 %188 to i32
  %190 = icmp eq i32 %189, 0
  br i1 %190, label %191, label %195

191:                                              ; preds = %186
  %192 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 1
  %193 = load i32, ptr %192, align 4, !tbaa !18
  %194 = zext i32 %193 to i64
  store i64 %194, ptr %13, align 8, !tbaa !16
  br label %195

195:                                              ; preds = %191, %186, %175
  %196 = load i32, ptr %17, align 4, !tbaa !15
  %197 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 3
  store i32 %196, ptr %197, align 4, !tbaa !25
  %198 = load ptr, ptr %5, align 8, !tbaa !5
  %199 = load i64, ptr %11, align 8, !tbaa !16
  %200 = and i64 %199, 4294967295
  %201 = trunc i64 %200 to i32
  %202 = load i64, ptr %13, align 8, !tbaa !16
  %203 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 1
  %204 = load i32, ptr %203, align 4, !tbaa !18
  %205 = zext i32 %204 to i64
  %206 = icmp eq i64 %202, %205
  %207 = zext i1 %206 to i32
  %208 = call i32 @index_alpha(ptr noundef %198, ptr noundef %4, i32 noundef %201, i32 noundef %207)
  %209 = zext i32 %208 to i64
  store i64 %209, ptr %12, align 8, !tbaa !16
  %210 = load ptr, ptr %5, align 8, !tbaa !5
  %211 = getelementptr inbounds %struct.Argon2_instance_t, ptr %210, i32 0, i32 0
  %212 = load ptr, ptr %211, align 8, !tbaa !23
  %213 = load ptr, ptr %5, align 8, !tbaa !5
  %214 = getelementptr inbounds %struct.Argon2_instance_t, ptr %213, i32 0, i32 5
  %215 = load i32, ptr %214, align 8, !tbaa !21
  %216 = zext i32 %215 to i64
  %217 = load i64, ptr %13, align 8, !tbaa !16
  %218 = mul i64 %216, %217
  %219 = getelementptr inbounds %struct.block_, ptr %212, i64 %218
  %220 = load i64, ptr %12, align 8, !tbaa !16
  %221 = getelementptr inbounds %struct.block_, ptr %219, i64 %220
  store ptr %221, ptr %6, align 8, !tbaa !5
  %222 = load ptr, ptr %5, align 8, !tbaa !5
  %223 = getelementptr inbounds %struct.Argon2_instance_t, ptr %222, i32 0, i32 0
  %224 = load ptr, ptr %223, align 8, !tbaa !23
  %225 = load i32, ptr %15, align 4, !tbaa !15
  %226 = zext i32 %225 to i64
  %227 = getelementptr inbounds %struct.block_, ptr %224, i64 %226
  store ptr %227, ptr %7, align 8, !tbaa !5
  %228 = load ptr, ptr %5, align 8, !tbaa !5
  %229 = getelementptr inbounds %struct.Argon2_instance_t, ptr %228, i32 0, i32 1
  %230 = load i32, ptr %229, align 8, !tbaa !26
  %231 = icmp eq i32 16, %230
  br i1 %231, label %232, label %241

232:                                              ; preds = %195
  %233 = load ptr, ptr %5, align 8, !tbaa !5
  %234 = getelementptr inbounds %struct.Argon2_instance_t, ptr %233, i32 0, i32 0
  %235 = load ptr, ptr %234, align 8, !tbaa !23
  %236 = load i32, ptr %14, align 4, !tbaa !15
  %237 = zext i32 %236 to i64
  %238 = getelementptr inbounds %struct.block_, ptr %235, i64 %237
  %239 = load ptr, ptr %6, align 8, !tbaa !5
  %240 = load ptr, ptr %7, align 8, !tbaa !5
  call void @fill_block(ptr noundef %238, ptr noundef %239, ptr noundef %240, i32 noundef 0)
  br label %264

241:                                              ; preds = %195
  %242 = getelementptr inbounds %struct.Argon2_position_t, ptr %4, i32 0, i32 0
  %243 = load i32, ptr %242, align 4, !tbaa !12
  %244 = icmp eq i32 0, %243
  br i1 %244, label %245, label %254

245:                                              ; preds = %241
  %246 = load ptr, ptr %5, align 8, !tbaa !5
  %247 = getelementptr inbounds %struct.Argon2_instance_t, ptr %246, i32 0, i32 0
  %248 = load ptr, ptr %247, align 8, !tbaa !23
  %249 = load i32, ptr %14, align 4, !tbaa !15
  %250 = zext i32 %249 to i64
  %251 = getelementptr inbounds %struct.block_, ptr %248, i64 %250
  %252 = load ptr, ptr %6, align 8, !tbaa !5
  %253 = load ptr, ptr %7, align 8, !tbaa !5
  call void @fill_block(ptr noundef %251, ptr noundef %252, ptr noundef %253, i32 noundef 0)
  br label %263

254:                                              ; preds = %241
  %255 = load ptr, ptr %5, align 8, !tbaa !5
  %256 = getelementptr inbounds %struct.Argon2_instance_t, ptr %255, i32 0, i32 0
  %257 = load ptr, ptr %256, align 8, !tbaa !23
  %258 = load i32, ptr %14, align 4, !tbaa !15
  %259 = zext i32 %258 to i64
  %260 = getelementptr inbounds %struct.block_, ptr %257, i64 %259
  %261 = load ptr, ptr %6, align 8, !tbaa !5
  %262 = load ptr, ptr %7, align 8, !tbaa !5
  call void @fill_block(ptr noundef %260, ptr noundef %261, ptr noundef %262, i32 noundef 1)
  br label %263

263:                                              ; preds = %254, %245
  br label %264

264:                                              ; preds = %263, %232
  br label %265

265:                                              ; preds = %264
  %266 = load i32, ptr %17, align 4, !tbaa !15
  %267 = add i32 %266, 1
  store i32 %267, ptr %17, align 4, !tbaa !15
  %268 = load i32, ptr %15, align 4, !tbaa !15
  %269 = add i32 %268, 1
  store i32 %269, ptr %15, align 4, !tbaa !15
  %270 = load i32, ptr %14, align 4, !tbaa !15
  %271 = add i32 %270, 1
  store i32 %271, ptr %14, align 4, !tbaa !15
  br label %134, !llvm.loop !27

272:                                              ; preds = %134
  store i32 0, ptr %19, align 4
  br label %273

273:                                              ; preds = %272, %24
  call void @llvm.lifetime.end.p0(i64 4, ptr %18) #3
  call void @llvm.lifetime.end.p0(i64 4, ptr %17) #3
  call void @llvm.lifetime.end.p0(i64 4, ptr %16) #3
  call void @llvm.lifetime.end.p0(i64 4, ptr %15) #3
  call void @llvm.lifetime.end.p0(i64 4, ptr %14) #3
  call void @llvm.lifetime.end.p0(i64 8, ptr %13) #3
  call void @llvm.lifetime.end.p0(i64 8, ptr %12) #3
  call void @llvm.lifetime.end.p0(i64 8, ptr %11) #3
  call void @llvm.lifetime.end.p0(i64 1024, ptr %10) #3
  call void @llvm.lifetime.end.p0(i64 1024, ptr %9) #3
  call void @llvm.lifetime.end.p0(i64 1024, ptr %8) #3
  call void @llvm.lifetime.end.p0(i64 8, ptr %7) #3
  call void @llvm.lifetime.end.p0(i64 8, ptr %6) #3
  %274 = load i32, ptr %19, align 4
  switch i32 %274, label %276 [
    i32 0, label %275
    i32 1, label %275
  ]

275:                                              ; preds = %273, %273
  ret void

276:                                              ; preds = %273
  unreachable
}

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

declare void @init_block_value(ptr noundef, i8 noundef zeroext) #2

; Function Attrs: nounwind uwtable
declare hidden void @next_addresses(ptr noundef, ptr noundef, ptr noundef) #0

declare i32 @index_alpha(ptr noundef, ptr noundef, i32 noundef, i32 noundef) #2

; Function Attrs: nounwind uwtable
declare hidden void @fill_block(ptr noundef, ptr noundef, ptr noundef, i32 noundef) #0

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

attributes #0 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { "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 = { 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, !11, i64 36}
!10 = !{!"Argon2_instance_t", !6, i64 0, !11, i64 8, !11, i64 12, !11, i64 16, !11, i64 20, !11, i64 24, !11, i64 28, !11, i64 32, !11, i64 36, !11, i64 40, !6, i64 48}
!11 = !{!"int", !7, i64 0}
!12 = !{!13, !11, i64 0}
!13 = !{!"Argon2_position_t", !11, i64 0, !11, i64 4, !7, i64 8, !11, i64 12}
!14 = !{!13, !7, i64 8}
!15 = !{!11, !11, i64 0}
!16 = !{!17, !17, i64 0}
!17 = !{!"long", !7, i64 0}
!18 = !{!13, !11, i64 4}
!19 = !{!10, !11, i64 16}
!20 = !{!10, !11, i64 12}
!21 = !{!10, !11, i64 24}
!22 = !{!10, !11, i64 20}
!23 = !{!10, !6, i64 0}
!24 = !{!10, !11, i64 28}
!25 = !{!13, !11, i64 12}
!26 = !{!10, !11, i64 8}
!27 = distinct !{!27, !28}
!28 = !{!"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.Argon2_position_t = type { i32, i32, i8, i32 }
%struct.block_ = type { [128 x i64] }

; Function Attrs: nounwind uwtable
define dso_local void @fill_segment(ptr noundef %0, i64 %1, i64 %2) local_unnamed_addr #0 {
  %4 = alloca %struct.Argon2_position_t, align 8
  %5 = alloca %struct.block_, align 8
  %6 = alloca %struct.block_, align 8
  %7 = alloca %struct.block_, align 8
  store i64 %1, ptr %4, align 8
  %8 = getelementptr inbounds i8, ptr %4, i64 8
  store i64 %2, ptr %8, align 8
  call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %5) #3
  call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %6) #3
  call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %7) #3
  %9 = icmp eq ptr %0, null
  %10 = trunc i64 %1 to i32
  %11 = trunc i64 %2 to i8
  %12 = lshr i64 %1, 32
  %13 = trunc nuw i64 %12 to i32
  br i1 %9, label %.loopexit, label %14

14:                                               ; preds = %3
  %15 = getelementptr inbounds i8, ptr %0, i64 36
  %16 = load i32, ptr %15, align 4, !tbaa !5
  %17 = icmp eq i32 %16, 1
  br i1 %17, label %.thread71, label %18

18:                                               ; preds = %14
  %19 = icmp eq i32 %16, 2
  %20 = icmp eq i32 %10, 0
  %or.cond = select i1 %19, i1 %20, i1 false
  %21 = icmp ult i8 %11, 2
  %or.cond73 = select i1 %or.cond, i1 %21, i1 false
  br i1 %or.cond73, label %.thread71, label %.thread71.thread

.thread71.thread:                                 ; preds = %18
  %22 = icmp eq i32 %10, 0
  %23 = icmp eq i8 %11, 0
  %or.cond6.not76.not7882 = select i1 %22, i1 %23, i1 false
  %.mux84 = select i1 %or.cond6.not76.not7882, i32 2, i32 0
  br label %42

.thread71:                                        ; preds = %14, %18
  call void @init_block_value(ptr noundef nonnull %7, i8 noundef zeroext 0) #3
  call void @init_block_value(ptr noundef nonnull %6, i8 noundef zeroext 0) #3
  %24 = and i64 %1, 4294967295
  store i64 %24, ptr %6, align 8, !tbaa !11
  %25 = getelementptr inbounds i8, ptr %6, i64 8
  store i64 %12, ptr %25, align 8, !tbaa !11
  %26 = and i64 %2, 255
  %27 = getelementptr inbounds i8, ptr %6, i64 16
  store i64 %26, ptr %27, align 8, !tbaa !11
  %28 = getelementptr inbounds i8, ptr %0, i64 16
  %29 = load i32, ptr %28, align 8, !tbaa !13
  %30 = zext i32 %29 to i64
  %31 = getelementptr inbounds i8, ptr %6, i64 24
  store i64 %30, ptr %31, align 8, !tbaa !11
  %32 = getelementptr inbounds i8, ptr %0, i64 12
  %33 = load i32, ptr %32, align 4, !tbaa !14
  %34 = zext i32 %33 to i64
  %35 = getelementptr inbounds i8, ptr %6, i64 32
  store i64 %34, ptr %35, align 8, !tbaa !11
  %36 = load i32, ptr %15, align 4, !tbaa !5
  %37 = zext i32 %36 to i64
  %38 = getelementptr inbounds i8, ptr %6, i64 40
  store i64 %37, ptr %38, align 8, !tbaa !11
  %39 = icmp eq i32 %10, 0
  %40 = icmp eq i8 %11, 0
  %or.cond6.not76.not78 = select i1 %39, i1 %40, i1 false
  %.mux = select i1 %or.cond6.not76.not78, i32 2, i32 0
  br i1 %or.cond6.not76.not78, label %41, label %42

41:                                               ; preds = %.thread71
  call void @next_addresses(ptr noundef nonnull %5, ptr noundef nonnull %6, ptr noundef nonnull %7)
  br label %42

42:                                               ; preds = %.thread71.thread, %.thread71, %41
  %43 = phi i1 [ true, %41 ], [ true, %.thread71 ], [ false, %.thread71.thread ]
  %.064 = phi i32 [ 2, %41 ], [ %.mux, %.thread71 ], [ %.mux84, %.thread71.thread ]
  %44 = getelementptr inbounds i8, ptr %4, i64 4
  %45 = getelementptr inbounds i8, ptr %0, i64 24
  %46 = getelementptr inbounds i8, ptr %0, i64 20
  %47 = load i32, ptr %46, align 4, !tbaa !15
  %48 = icmp ult i32 %.064, %47
  br i1 %48, label %.lr.ph, label %.loopexit

.lr.ph:                                           ; preds = %42
  %49 = load i32, ptr %45, align 8, !tbaa !16
  %50 = mul i32 %49, %13
  %51 = add i32 %50, %.064
  %52 = trunc i64 %2 to i32
  %53 = and i32 %52, 255
  %54 = mul i32 %47, %53
  %55 = add i32 %51, %54
  %56 = urem i32 %55, %49
  %57 = icmp eq i32 %56, 0
  %58 = add i32 %49, -1
  %.066.in = select i1 %57, i32 %58, i32 -1
  %.066 = add i32 %.066.in, %55
  %59 = getelementptr inbounds i8, ptr %0, i64 28
  %60 = getelementptr inbounds i8, ptr %4, i64 12
  %61 = getelementptr inbounds i8, ptr %0, i64 8
  br label %62

62:                                               ; preds = %.lr.ph, %113
  %.081 = phi i32 [ %.064, %.lr.ph ], [ %114, %113 ]
  %.06580 = phi i32 [ %55, %.lr.ph ], [ %115, %113 ]
  %.179 = phi i32 [ %.066, %.lr.ph ], [ %116, %113 ]
  %63 = load i32, ptr %45, align 8, !tbaa !16
  %64 = urem i32 %.06580, %63
  %65 = icmp eq i32 %64, 1
  %66 = add i32 %.06580, -1
  %spec.select = select i1 %65, i32 %66, i32 %.179
  br i1 %43, label %67, label %74

67:                                               ; preds = %62
  %68 = and i32 %.081, 127
  %69 = icmp eq i32 %68, 0
  br i1 %69, label %70, label %71

70:                                               ; preds = %67
  call void @next_addresses(ptr noundef nonnull %5, ptr noundef nonnull %6, ptr noundef nonnull %7)
  br label %71

71:                                               ; preds = %70, %67
  %72 = zext nneg i32 %68 to i64
  %73 = getelementptr inbounds [128 x i64], ptr %5, i64 0, i64 %72
  br label %78

74:                                               ; preds = %62
  %75 = load ptr, ptr %0, align 8, !tbaa !17
  %76 = zext i32 %spec.select to i64
  %77 = getelementptr inbounds %struct.block_, ptr %75, i64 %76
  br label %78

78:                                               ; preds = %74, %71
  %.068.in = phi ptr [ %73, %71 ], [ %77, %74 ]
  %.068 = load i64, ptr %.068.in, align 8, !tbaa !11
  %79 = lshr i64 %.068, 32
  %80 = load i32, ptr %59, align 4, !tbaa !18
  %.lhs.trunc = trunc nuw i64 %79 to i32
  %81 = urem i32 %.lhs.trunc, %80
  %.zext = zext i32 %81 to i64
  %82 = load i32, ptr %4, align 8, !tbaa !19
  %83 = icmp eq i32 %82, 0
  %84 = load i8, ptr %8, align 8
  %85 = icmp eq i8 %84, 0
  %or.cond10 = select i1 %83, i1 %85, i1 false
  %86 = load i32, ptr %44, align 4
  %87 = zext i32 %86 to i64
  %.067 = select i1 %or.cond10, i64 %87, i64 %.zext
  store i32 %.081, ptr %60, align 4, !tbaa !21
  %88 = trunc i64 %.068 to i32
  %89 = icmp eq i64 %.067, %87
  %90 = zext i1 %89 to i32
  %91 = call i32 @index_alpha(ptr noundef nonnull %0, ptr noundef nonnull %4, i32 noundef %88, i32 noundef %90) #3
  %92 = zext i32 %91 to i64
  %93 = load ptr, ptr %0, align 8, !tbaa !17
  %94 = load i32, ptr %45, align 8, !tbaa !16
  %95 = zext i32 %94 to i64
  %96 = mul nuw i64 %.067, %95
  %97 = getelementptr inbounds %struct.block_, ptr %93, i64 %96
  %98 = getelementptr inbounds %struct.block_, ptr %97, i64 %92
  %99 = zext i32 %.06580 to i64
  %100 = getelementptr inbounds %struct.block_, ptr %93, i64 %99
  %101 = load i32, ptr %61, align 8, !tbaa !22
  %102 = icmp eq i32 %101, 16
  br i1 %102, label %103, label %106

103:                                              ; preds = %78
  %104 = zext i32 %spec.select to i64
  %105 = getelementptr inbounds %struct.block_, ptr %93, i64 %104
  call void @fill_block(ptr noundef %105, ptr noundef %98, ptr noundef %100, i32 noundef 0)
  br label %113

106:                                              ; preds = %78
  %107 = load i32, ptr %4, align 8, !tbaa !19
  %108 = icmp eq i32 %107, 0
  %109 = zext i32 %spec.select to i64
  %110 = getelementptr inbounds %struct.block_, ptr %93, i64 %109
  br i1 %108, label %111, label %112

111:                                              ; preds = %106
  call void @fill_block(ptr noundef %110, ptr noundef %98, ptr noundef %100, i32 noundef 0)
  br label %113

112:                                              ; preds = %106
  call void @fill_block(ptr noundef %110, ptr noundef %98, ptr noundef %100, i32 noundef 1)
  br label %113

113:                                              ; preds = %103, %112, %111
  %114 = add nuw i32 %.081, 1
  %115 = add i32 %.06580, 1
  %116 = add i32 %spec.select, 1
  %117 = load i32, ptr %46, align 4, !tbaa !15
  %118 = icmp ult i32 %114, %117
  br i1 %118, label %62, label %.loopexit, !llvm.loop !23

.loopexit:                                        ; preds = %113, %42, %3
  call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %7) #3
  call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %6) #3
  call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %5) #3
  ret void
}

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

declare void @init_block_value(ptr noundef, i8 noundef zeroext) local_unnamed_addr #2

; Function Attrs: nounwind uwtable
declare hidden void @next_addresses(ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #0

declare i32 @index_alpha(ptr noundef, ptr noundef, i32 noundef, i32 noundef) local_unnamed_addr #2

; Function Attrs: nounwind uwtable
declare hidden void @fill_block(ptr noundef, ptr noundef, ptr noundef, i32 noundef) local_unnamed_addr #0

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

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

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

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.0 (git@github.com:llvm/llvm-project.git a4bf6cd7cfb1a1421ba92bca9d017b49936c55e4)"}
!5 = !{!6, !10, i64 36}
!6 = !{!"Argon2_instance_t", !7, i64 0, !10, i64 8, !10, i64 12, !10, i64 16, !10, i64 20, !10, i64 24, !10, i64 28, !10, i64 32, !10, i64 36, !10, i64 40, !7, i64 48}
!7 = !{!"any pointer", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C/C++ TBAA"}
!10 = !{!"int", !8, i64 0}
!11 = !{!12, !12, i64 0}
!12 = !{!"long", !8, i64 0}
!13 = !{!6, !10, i64 16}
!14 = !{!6, !10, i64 12}
!15 = !{!6, !10, i64 20}
!16 = !{!6, !10, i64 24}
!17 = !{!6, !7, i64 0}
!18 = !{!6, !10, i64 28}
!19 = !{!20, !10, i64 0}
!20 = !{!"Argon2_position_t", !10, i64 0, !10, i64 4, !8, i64 8, !10, i64 12}
!21 = !{!20, !10, i64 12}
!22 = !{!6, !10, i64 8}
!23 = distinct !{!23, !24}
!24 = !{!"llvm.loop.mustprogress"}


; Effective O3 passes: BDCEPass,CorrelatedValuePropagationPass,EarlyCSEPass,GVNPass,GlobalOptPass,IPSCCPPass,IndVarSimplifyPass,InferAlignmentPass,InferFunctionAttrsPass,InstCombinePass,JumpThreadingPass,LICMPass,LoopRotatePass,LoopSimplifyPass,LoopUnrollPass,ReassociatePass,SCCPPass,SROAPass,SimplifyCFGPass