; LLVM IR from square/subzero :: core/external-crypto/modes/ltc (ltc_gcm)

; 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.gcm_state = type { [1 x %struct.aes_crypt_ctx], [16 x i8], [16 x i8], [16 x i8], [16 x i8], [16 x i8], i32, i32, i32, i64, i64, [16 x [256 x [16 x i8]]] }
%struct.aes_crypt_ctx = type { [60 x i32], %union.aes_inf, [12 x i8] }
%union.aes_inf = type { i32 }

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

declare i32 @aes_encrypt(ptr noundef, ptr noundef, ptr noundef) #1

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

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

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

20:                                               ; preds = %5
  %21 = load ptr, ptr %11, align 8, !tbaa !5
  %22 = getelementptr inbounds %struct.gcm_state, ptr %21, i32 0, i32 8
  %23 = load i32, ptr %22, align 8, !tbaa !13
  %24 = icmp slt i32 %23, 0
  br i1 %24, label %25, label %26

25:                                               ; preds = %20, %5
  store i32 1, ptr %6, align 4
  store i32 1, ptr %15, align 4
  br label %220

26:                                               ; preds = %20
  %27 = load ptr, ptr %11, align 8, !tbaa !5
  %28 = getelementptr inbounds %struct.gcm_state, ptr %27, i32 0, i32 7
  %29 = load i32, ptr %28, align 4, !tbaa !15
  %30 = icmp eq i32 %29, 1
  br i1 %30, label %31, label %88

31:                                               ; preds = %26
  %32 = load ptr, ptr %11, align 8, !tbaa !5
  %33 = getelementptr inbounds %struct.gcm_state, ptr %32, i32 0, i32 8
  %34 = load i32, ptr %33, align 8, !tbaa !13
  %35 = icmp ne i32 %34, 0
  br i1 %35, label %36, label %50

36:                                               ; preds = %31
  %37 = load ptr, ptr %11, align 8, !tbaa !5
  %38 = getelementptr inbounds %struct.gcm_state, ptr %37, i32 0, i32 8
  %39 = load i32, ptr %38, align 8, !tbaa !13
  %40 = mul nsw i32 %39, 8
  %41 = sext i32 %40 to i64
  %42 = load ptr, ptr %11, align 8, !tbaa !5
  %43 = getelementptr inbounds %struct.gcm_state, ptr %42, i32 0, i32 9
  %44 = load i64, ptr %43, align 16, !tbaa !16
  %45 = add i64 %44, %41
  store i64 %45, ptr %43, align 16, !tbaa !16
  %46 = load ptr, ptr %11, align 8, !tbaa !5
  %47 = load ptr, ptr %11, align 8, !tbaa !5
  %48 = getelementptr inbounds %struct.gcm_state, ptr %47, i32 0, i32 2
  %49 = getelementptr inbounds [16 x i8], ptr %48, i64 0, i64 0
  call void @gcm_mult_h(ptr noundef %46, ptr noundef %49)
  br label %50

50:                                               ; preds = %36, %31
  store i32 15, ptr %13, align 4, !tbaa !11
  br label %51

51:                                               ; preds = %67, %50
  %52 = load i32, ptr %13, align 4, !tbaa !11
  %53 = icmp uge i32 %52, 12
  br i1 %53, label %54, label %70

54:                                               ; preds = %51
  %55 = load ptr, ptr %11, align 8, !tbaa !5
  %56 = getelementptr inbounds %struct.gcm_state, ptr %55, i32 0, i32 3
  %57 = load i32, ptr %13, align 4, !tbaa !11
  %58 = zext i32 %57 to i64
  %59 = getelementptr inbounds [16 x i8], ptr %56, i64 0, i64 %58
  %60 = load i8, ptr %59, align 1, !tbaa !17
  %61 = add i8 %60, 1
  store i8 %61, ptr %59, align 1, !tbaa !17
  %62 = zext i8 %61 to i32
  %63 = and i32 %62, 255
  %64 = icmp ne i32 %63, 0
  br i1 %64, label %65, label %66

65:                                               ; preds = %54
  br label %70

66:                                               ; preds = %54
  br label %67

67:                                               ; preds = %66
  %68 = load i32, ptr %13, align 4, !tbaa !11
  %69 = add i32 %68, -1
  store i32 %69, ptr %13, align 4, !tbaa !11
  br label %51, !llvm.loop !18

70:                                               ; preds = %65, %51
  %71 = load ptr, ptr %11, align 8, !tbaa !5
  %72 = getelementptr inbounds %struct.gcm_state, ptr %71, i32 0, i32 3
  %73 = getelementptr inbounds [16 x i8], ptr %72, i64 0, i64 0
  %74 = load ptr, ptr %11, align 8, !tbaa !5
  %75 = getelementptr inbounds %struct.gcm_state, ptr %74, i32 0, i32 5
  %76 = getelementptr inbounds [16 x i8], ptr %75, i64 0, i64 0
  %77 = load ptr, ptr %11, align 8, !tbaa !5
  %78 = getelementptr inbounds %struct.gcm_state, ptr %77, i32 0, i32 0
  %79 = getelementptr inbounds [1 x %struct.aes_crypt_ctx], ptr %78, i64 0, i64 0
  %80 = call i32 @aes_encrypt(ptr noundef %73, ptr noundef %76, ptr noundef %79)
  %81 = icmp ne i32 %80, 0
  br i1 %81, label %82, label %83

82:                                               ; preds = %70
  store i32 1, ptr %6, align 4
  store i32 1, ptr %15, align 4
  br label %220

83:                                               ; preds = %70
  %84 = load ptr, ptr %11, align 8, !tbaa !5
  %85 = getelementptr inbounds %struct.gcm_state, ptr %84, i32 0, i32 8
  store i32 0, ptr %85, align 8, !tbaa !13
  %86 = load ptr, ptr %11, align 8, !tbaa !5
  %87 = getelementptr inbounds %struct.gcm_state, ptr %86, i32 0, i32 7
  store i32 2, ptr %87, align 4, !tbaa !15
  br label %88

88:                                               ; preds = %83, %26
  %89 = load ptr, ptr %11, align 8, !tbaa !5
  %90 = getelementptr inbounds %struct.gcm_state, ptr %89, i32 0, i32 7
  %91 = load i32, ptr %90, align 4, !tbaa !15
  %92 = icmp ne i32 %91, 2
  br i1 %92, label %93, label %94

93:                                               ; preds = %88
  store i32 1, ptr %6, align 4
  store i32 1, ptr %15, align 4
  br label %220

94:                                               ; preds = %88
  store i32 0, ptr %12, align 4, !tbaa !11
  br label %95

95:                                               ; preds = %216, %94
  %96 = load i32, ptr %12, align 4, !tbaa !11
  %97 = zext i32 %96 to i64
  %98 = load i64, ptr %8, align 8, !tbaa !9
  %99 = icmp ult i64 %97, %98
  br i1 %99, label %100, label %219

100:                                              ; preds = %95
  %101 = load ptr, ptr %11, align 8, !tbaa !5
  %102 = getelementptr inbounds %struct.gcm_state, ptr %101, i32 0, i32 8
  %103 = load i32, ptr %102, align 8, !tbaa !13
  %104 = icmp eq i32 %103, 16
  br i1 %104, label %105, label %149

105:                                              ; preds = %100
  %106 = load ptr, ptr %11, align 8, !tbaa !5
  %107 = getelementptr inbounds %struct.gcm_state, ptr %106, i32 0, i32 10
  %108 = load i64, ptr %107, align 8, !tbaa !20
  %109 = add i64 %108, 128
  store i64 %109, ptr %107, align 8, !tbaa !20
  %110 = load ptr, ptr %11, align 8, !tbaa !5
  %111 = load ptr, ptr %11, align 8, !tbaa !5
  %112 = getelementptr inbounds %struct.gcm_state, ptr %111, i32 0, i32 2
  %113 = getelementptr inbounds [16 x i8], ptr %112, i64 0, i64 0
  call void @gcm_mult_h(ptr noundef %110, ptr noundef %113)
  store i32 15, ptr %13, align 4, !tbaa !11
  br label %114

114:                                              ; preds = %130, %105
  %115 = load i32, ptr %13, align 4, !tbaa !11
  %116 = icmp uge i32 %115, 12
  br i1 %116, label %117, label %133

117:                                              ; preds = %114
  %118 = load ptr, ptr %11, align 8, !tbaa !5
  %119 = getelementptr inbounds %struct.gcm_state, ptr %118, i32 0, i32 3
  %120 = load i32, ptr %13, align 4, !tbaa !11
  %121 = zext i32 %120 to i64
  %122 = getelementptr inbounds [16 x i8], ptr %119, i64 0, i64 %121
  %123 = load i8, ptr %122, align 1, !tbaa !17
  %124 = add i8 %123, 1
  store i8 %124, ptr %122, align 1, !tbaa !17
  %125 = zext i8 %124 to i32
  %126 = and i32 %125, 255
  %127 = icmp ne i32 %126, 0
  br i1 %127, label %128, label %129

128:                                              ; preds = %117
  br label %133

129:                                              ; preds = %117
  br label %130

130:                                              ; preds = %129
  %131 = load i32, ptr %13, align 4, !tbaa !11
  %132 = add i32 %131, -1
  store i32 %132, ptr %13, align 4, !tbaa !11
  br label %114, !llvm.loop !21

133:                                              ; preds = %128, %114
  %134 = load ptr, ptr %11, align 8, !tbaa !5
  %135 = getelementptr inbounds %struct.gcm_state, ptr %134, i32 0, i32 3
  %136 = getelementptr inbounds [16 x i8], ptr %135, i64 0, i64 0
  %137 = load ptr, ptr %11, align 8, !tbaa !5
  %138 = getelementptr inbounds %struct.gcm_state, ptr %137, i32 0, i32 5
  %139 = getelementptr inbounds [16 x i8], ptr %138, i64 0, i64 0
  %140 = load ptr, ptr %11, align 8, !tbaa !5
  %141 = getelementptr inbounds %struct.gcm_state, ptr %140, i32 0, i32 0
  %142 = getelementptr inbounds [1 x %struct.aes_crypt_ctx], ptr %141, i64 0, i64 0
  %143 = call i32 @aes_encrypt(ptr noundef %136, ptr noundef %139, ptr noundef %142)
  %144 = icmp ne i32 %143, 0
  br i1 %144, label %145, label %146

145:                                              ; preds = %133
  store i32 1, ptr %6, align 4
  store i32 1, ptr %15, align 4
  br label %220

146:                                              ; preds = %133
  %147 = load ptr, ptr %11, align 8, !tbaa !5
  %148 = getelementptr inbounds %struct.gcm_state, ptr %147, i32 0, i32 8
  store i32 0, ptr %148, align 8, !tbaa !13
  br label %149

149:                                              ; preds = %146, %100
  %150 = load i32, ptr %10, align 4, !tbaa !11
  %151 = icmp eq i32 %150, 0
  br i1 %151, label %152, label %174

152:                                              ; preds = %149
  %153 = load ptr, ptr %7, align 8, !tbaa !5
  %154 = load i32, ptr %12, align 4, !tbaa !11
  %155 = zext i32 %154 to i64
  %156 = getelementptr inbounds i8, ptr %153, i64 %155
  %157 = load i8, ptr %156, align 1, !tbaa !17
  %158 = zext i8 %157 to i32
  %159 = load ptr, ptr %11, align 8, !tbaa !5
  %160 = getelementptr inbounds %struct.gcm_state, ptr %159, i32 0, i32 5
  %161 = load ptr, ptr %11, align 8, !tbaa !5
  %162 = getelementptr inbounds %struct.gcm_state, ptr %161, i32 0, i32 8
  %163 = load i32, ptr %162, align 8, !tbaa !13
  %164 = sext i32 %163 to i64
  %165 = getelementptr inbounds [16 x i8], ptr %160, i64 0, i64 %164
  %166 = load i8, ptr %165, align 1, !tbaa !17
  %167 = zext i8 %166 to i32
  %168 = xor i32 %158, %167
  %169 = trunc i32 %168 to i8
  %170 = load ptr, ptr %9, align 8, !tbaa !5
  %171 = load i32, ptr %12, align 4, !tbaa !11
  %172 = zext i32 %171 to i64
  %173 = getelementptr inbounds i8, ptr %170, i64 %172
  store i8 %169, ptr %173, align 1, !tbaa !17
  store i8 %169, ptr %14, align 1, !tbaa !17
  br label %201

174:                                              ; preds = %149
  %175 = load ptr, ptr %9, align 8, !tbaa !5
  %176 = load i32, ptr %12, align 4, !tbaa !11
  %177 = zext i32 %176 to i64
  %178 = getelementptr inbounds i8, ptr %175, i64 %177
  %179 = load i8, ptr %178, align 1, !tbaa !17
  store i8 %179, ptr %14, align 1, !tbaa !17
  %180 = load ptr, ptr %9, align 8, !tbaa !5
  %181 = load i32, ptr %12, align 4, !tbaa !11
  %182 = zext i32 %181 to i64
  %183 = getelementptr inbounds i8, ptr %180, i64 %182
  %184 = load i8, ptr %183, align 1, !tbaa !17
  %185 = zext i8 %184 to i32
  %186 = load ptr, ptr %11, align 8, !tbaa !5
  %187 = getelementptr inbounds %struct.gcm_state, ptr %186, i32 0, i32 5
  %188 = load ptr, ptr %11, align 8, !tbaa !5
  %189 = getelementptr inbounds %struct.gcm_state, ptr %188, i32 0, i32 8
  %190 = load i32, ptr %189, align 8, !tbaa !13
  %191 = sext i32 %190 to i64
  %192 = getelementptr inbounds [16 x i8], ptr %187, i64 0, i64 %191
  %193 = load i8, ptr %192, align 1, !tbaa !17
  %194 = zext i8 %193 to i32
  %195 = xor i32 %185, %194
  %196 = trunc i32 %195 to i8
  %197 = load ptr, ptr %7, align 8, !tbaa !5
  %198 = load i32, ptr %12, align 4, !tbaa !11
  %199 = zext i32 %198 to i64
  %200 = getelementptr inbounds i8, ptr %197, i64 %199
  store i8 %196, ptr %200, align 1, !tbaa !17
  br label %201

201:                                              ; preds = %174, %152
  %202 = load i8, ptr %14, align 1, !tbaa !17
  %203 = zext i8 %202 to i32
  %204 = load ptr, ptr %11, align 8, !tbaa !5
  %205 = getelementptr inbounds %struct.gcm_state, ptr %204, i32 0, i32 2
  %206 = load ptr, ptr %11, align 8, !tbaa !5
  %207 = getelementptr inbounds %struct.gcm_state, ptr %206, i32 0, i32 8
  %208 = load i32, ptr %207, align 8, !tbaa !13
  %209 = add nsw i32 %208, 1
  store i32 %209, ptr %207, align 8, !tbaa !13
  %210 = sext i32 %208 to i64
  %211 = getelementptr inbounds [16 x i8], ptr %205, i64 0, i64 %210
  %212 = load i8, ptr %211, align 1, !tbaa !17
  %213 = zext i8 %212 to i32
  %214 = xor i32 %213, %203
  %215 = trunc i32 %214 to i8
  store i8 %215, ptr %211, align 1, !tbaa !17
  br label %216

216:                                              ; preds = %201
  %217 = load i32, ptr %12, align 4, !tbaa !11
  %218 = add i32 %217, 1
  store i32 %218, ptr %12, align 4, !tbaa !11
  br label %95, !llvm.loop !22

219:                                              ; preds = %95
  store i32 0, ptr %6, align 4
  store i32 1, ptr %15, align 4
  br label %220

220:                                              ; preds = %219, %145, %93, %82, %25
  call void @llvm.lifetime.end.p0(i64 1, ptr %14) #3
  call void @llvm.lifetime.end.p0(i64 4, ptr %13) #3
  call void @llvm.lifetime.end.p0(i64 4, ptr %12) #3
  %221 = load i32, ptr %6, align 4
  ret i32 %221
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { "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 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #3 = { 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, !12, i64 0}
!12 = !{!"int", !7, i64 0}
!13 = !{!14, !12, i64 344}
!14 = !{!"", !7, i64 0, !7, i64 256, !7, i64 272, !7, i64 288, !7, i64 304, !7, i64 320, !12, i64 336, !12, i64 340, !12, i64 344, !10, i64 352, !10, i64 360, !7, i64 368}
!15 = !{!14, !12, i64 340}
!16 = !{!14, !10, i64 352}
!17 = !{!7, !7, i64 0}
!18 = distinct !{!18, !19}
!19 = !{!"llvm.loop.mustprogress"}
!20 = !{!14, !10, i64 360}
!21 = distinct !{!21, !19}
!22 = distinct !{!22, !19}


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

declare i32 @aes_encrypt(ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #0

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

; Function Attrs: nounwind uwtable
define dso_local range(i32 0, 2) i32 @gcm_process(ptr nocapture noundef %0, i64 noundef %1, ptr nocapture noundef %2, i32 noundef %3, ptr noundef %4) local_unnamed_addr #1 {
  %6 = getelementptr inbounds i8, ptr %4, i64 344
  %7 = load i32, ptr %6, align 8, !tbaa !5
  %or.cond = icmp ugt i32 %7, 16
  br i1 %or.cond, label %.loopexit, label %8

8:                                                ; preds = %5
  %9 = getelementptr inbounds i8, ptr %4, i64 340
  %10 = load i32, ptr %9, align 4, !tbaa !11
  switch i32 %10, label %.loopexit [
    i32 1, label %11
    i32 2, label %.preheader
  ]

11:                                               ; preds = %8
  %.not = icmp eq i32 %7, 0
  br i1 %.not, label %19, label %12

12:                                               ; preds = %11
  %13 = shl nuw nsw i32 %7, 3
  %14 = zext nneg i32 %13 to i64
  %15 = getelementptr inbounds i8, ptr %4, i64 352
  %16 = load i64, ptr %15, align 16, !tbaa !12
  %17 = add i64 %16, %14
  store i64 %17, ptr %15, align 16, !tbaa !12
  %18 = getelementptr inbounds i8, ptr %4, i64 272
  tail call void @gcm_mult_h(ptr noundef nonnull %4, ptr noundef nonnull %18)
  br label %19

19:                                               ; preds = %12, %11
  %20 = getelementptr inbounds i8, ptr %4, i64 288
  %21 = getelementptr inbounds i8, ptr %4, i64 303
  %22 = load i8, ptr %21, align 1, !tbaa !13
  %23 = add i8 %22, 1
  store i8 %23, ptr %21, align 1, !tbaa !13
  %.not56 = icmp eq i8 %23, 0
  br i1 %.not56, label %24, label %36

24:                                               ; preds = %19
  %25 = getelementptr inbounds i8, ptr %4, i64 302
  %26 = load i8, ptr %25, align 1, !tbaa !13
  %27 = add i8 %26, 1
  store i8 %27, ptr %25, align 1, !tbaa !13
  %.not56.1 = icmp eq i8 %27, 0
  br i1 %.not56.1, label %28, label %36

28:                                               ; preds = %24
  %29 = getelementptr inbounds i8, ptr %4, i64 301
  %30 = load i8, ptr %29, align 1, !tbaa !13
  %31 = add i8 %30, 1
  store i8 %31, ptr %29, align 1, !tbaa !13
  %.not56.2 = icmp eq i8 %31, 0
  br i1 %.not56.2, label %32, label %36

32:                                               ; preds = %28
  %33 = getelementptr inbounds i8, ptr %4, i64 300
  %34 = load i8, ptr %33, align 1, !tbaa !13
  %35 = add i8 %34, 1
  store i8 %35, ptr %33, align 1, !tbaa !13
  br label %36

36:                                               ; preds = %32, %28, %24, %19
  %37 = getelementptr inbounds i8, ptr %4, i64 320
  %38 = tail call i32 @aes_encrypt(ptr noundef nonnull %20, ptr noundef nonnull %37, ptr noundef nonnull %4) #2
  %.not57 = icmp eq i32 %38, 0
  br i1 %.not57, label %.thread, label %.loopexit

.thread:                                          ; preds = %36
  store i32 0, ptr %6, align 8, !tbaa !5
  store i32 2, ptr %9, align 4, !tbaa !11
  br label %.preheader

.preheader:                                       ; preds = %8, %.thread
  %.not69 = icmp eq i64 %1, 0
  br i1 %.not69, label %.loopexit, label %.lr.ph

.lr.ph:                                           ; preds = %.preheader
  %39 = getelementptr inbounds i8, ptr %4, i64 360
  %40 = getelementptr inbounds i8, ptr %4, i64 272
  %41 = getelementptr inbounds i8, ptr %4, i64 288
  %42 = getelementptr inbounds i8, ptr %4, i64 320
  %43 = icmp eq i32 %3, 0
  br i1 %43, label %.lr.ph.split.us.preheader, label %.lr.ph.split.preheader

.lr.ph.split.preheader:                           ; preds = %.lr.ph
  %44 = getelementptr inbounds i8, ptr %4, i64 303
  %45 = getelementptr inbounds i8, ptr %4, i64 302
  %46 = getelementptr inbounds i8, ptr %4, i64 301
  %47 = getelementptr inbounds i8, ptr %4, i64 300
  br label %.lr.ph.split

.lr.ph.split.us.preheader:                        ; preds = %.lr.ph
  %48 = getelementptr inbounds i8, ptr %4, i64 303
  %49 = getelementptr inbounds i8, ptr %4, i64 302
  %50 = getelementptr inbounds i8, ptr %4, i64 301
  %51 = getelementptr inbounds i8, ptr %4, i64 300
  br label %.lr.ph.split.us

.lr.ph.split.us:                                  ; preds = %.lr.ph.split.us.preheader, %72
  %52 = phi i64 [ %88, %72 ], [ 0, %.lr.ph.split.us.preheader ]
  %.05263.us = phi i32 [ %87, %72 ], [ 0, %.lr.ph.split.us.preheader ]
  %53 = load i32, ptr %6, align 8, !tbaa !5
  %54 = icmp eq i32 %53, 16
  br i1 %54, label %55, label %72

55:                                               ; preds = %.lr.ph.split.us
  %56 = load i64, ptr %39, align 8, !tbaa !14
  %57 = add i64 %56, 128
  store i64 %57, ptr %39, align 8, !tbaa !14
  tail call void @gcm_mult_h(ptr noundef nonnull %4, ptr noundef nonnull %40)
  %58 = load i8, ptr %48, align 1, !tbaa !13
  %59 = add i8 %58, 1
  store i8 %59, ptr %48, align 1, !tbaa !13
  %.not59.us = icmp eq i8 %59, 0
  br i1 %.not59.us, label %60, label %69, !llvm.loop !15

60:                                               ; preds = %55
  %61 = load i8, ptr %49, align 1, !tbaa !13
  %62 = add i8 %61, 1
  store i8 %62, ptr %49, align 1, !tbaa !13
  %.not59.us.1 = icmp eq i8 %62, 0
  br i1 %.not59.us.1, label %63, label %69, !llvm.loop !15

63:                                               ; preds = %60
  %64 = load i8, ptr %50, align 1, !tbaa !13
  %65 = add i8 %64, 1
  store i8 %65, ptr %50, align 1, !tbaa !13
  %.not59.us.2 = icmp eq i8 %65, 0
  br i1 %.not59.us.2, label %66, label %69, !llvm.loop !15

66:                                               ; preds = %63
  %67 = load i8, ptr %51, align 1, !tbaa !13
  %68 = add i8 %67, 1
  store i8 %68, ptr %51, align 1, !tbaa !13
  br label %69

69:                                               ; preds = %66, %63, %60, %55
  %70 = tail call i32 @aes_encrypt(ptr noundef nonnull %41, ptr noundef nonnull %42, ptr noundef nonnull %4) #2
  %.not60.us = icmp eq i32 %70, 0
  br i1 %.not60.us, label %71, label %.loopexit

71:                                               ; preds = %69
  store i32 0, ptr %6, align 8, !tbaa !5
  br label %72

72:                                               ; preds = %71, %.lr.ph.split.us
  %73 = phi i32 [ 0, %71 ], [ %53, %.lr.ph.split.us ]
  %74 = getelementptr inbounds i8, ptr %0, i64 %52
  %75 = load i8, ptr %74, align 1, !tbaa !13
  %76 = sext i32 %73 to i64
  %77 = getelementptr inbounds [16 x i8], ptr %42, i64 0, i64 %76
  %78 = load i8, ptr %77, align 1, !tbaa !13
  %79 = xor i8 %78, %75
  %80 = getelementptr inbounds i8, ptr %2, i64 %52
  store i8 %79, ptr %80, align 1, !tbaa !13
  %81 = load i32, ptr %6, align 8, !tbaa !5
  %82 = add nsw i32 %81, 1
  store i32 %82, ptr %6, align 8, !tbaa !5
  %83 = sext i32 %81 to i64
  %84 = getelementptr inbounds [16 x i8], ptr %40, i64 0, i64 %83
  %85 = load i8, ptr %84, align 1, !tbaa !13
  %86 = xor i8 %85, %79
  store i8 %86, ptr %84, align 1, !tbaa !13
  %87 = add i32 %.05263.us, 1
  %88 = zext i32 %87 to i64
  %89 = icmp ult i64 %88, %1
  br i1 %89, label %.lr.ph.split.us, label %.loopexit, !llvm.loop !17

.lr.ph.split:                                     ; preds = %.lr.ph.split.preheader, %110
  %90 = phi i64 [ %126, %110 ], [ 0, %.lr.ph.split.preheader ]
  %.05263 = phi i32 [ %125, %110 ], [ 0, %.lr.ph.split.preheader ]
  %91 = load i32, ptr %6, align 8, !tbaa !5
  %92 = icmp eq i32 %91, 16
  br i1 %92, label %93, label %110

93:                                               ; preds = %.lr.ph.split
  %94 = load i64, ptr %39, align 8, !tbaa !14
  %95 = add i64 %94, 128
  store i64 %95, ptr %39, align 8, !tbaa !14
  tail call void @gcm_mult_h(ptr noundef nonnull %4, ptr noundef nonnull %40)
  %96 = load i8, ptr %44, align 1, !tbaa !13
  %97 = add i8 %96, 1
  store i8 %97, ptr %44, align 1, !tbaa !13
  %.not59 = icmp eq i8 %97, 0
  br i1 %.not59, label %98, label %107, !llvm.loop !15

98:                                               ; preds = %93
  %99 = load i8, ptr %45, align 1, !tbaa !13
  %100 = add i8 %99, 1
  store i8 %100, ptr %45, align 1, !tbaa !13
  %.not59.1 = icmp eq i8 %100, 0
  br i1 %.not59.1, label %101, label %107, !llvm.loop !15

101:                                              ; preds = %98
  %102 = load i8, ptr %46, align 1, !tbaa !13
  %103 = add i8 %102, 1
  store i8 %103, ptr %46, align 1, !tbaa !13
  %.not59.2 = icmp eq i8 %103, 0
  br i1 %.not59.2, label %104, label %107, !llvm.loop !15

104:                                              ; preds = %101
  %105 = load i8, ptr %47, align 1, !tbaa !13
  %106 = add i8 %105, 1
  store i8 %106, ptr %47, align 1, !tbaa !13
  br label %107

107:                                              ; preds = %104, %101, %98, %93
  %108 = tail call i32 @aes_encrypt(ptr noundef nonnull %41, ptr noundef nonnull %42, ptr noundef nonnull %4) #2
  %.not60 = icmp eq i32 %108, 0
  br i1 %.not60, label %109, label %.loopexit

109:                                              ; preds = %107
  store i32 0, ptr %6, align 8, !tbaa !5
  br label %110

110:                                              ; preds = %109, %.lr.ph.split
  %111 = phi i32 [ 0, %109 ], [ %91, %.lr.ph.split ]
  %112 = getelementptr inbounds i8, ptr %2, i64 %90
  %113 = load i8, ptr %112, align 1, !tbaa !13
  %114 = sext i32 %111 to i64
  %115 = getelementptr inbounds [16 x i8], ptr %42, i64 0, i64 %114
  %116 = load i8, ptr %115, align 1, !tbaa !13
  %117 = xor i8 %116, %113
  %118 = getelementptr inbounds i8, ptr %0, i64 %90
  store i8 %117, ptr %118, align 1, !tbaa !13
  %119 = load i32, ptr %6, align 8, !tbaa !5
  %120 = add nsw i32 %119, 1
  store i32 %120, ptr %6, align 8, !tbaa !5
  %121 = sext i32 %119 to i64
  %122 = getelementptr inbounds [16 x i8], ptr %40, i64 0, i64 %121
  %123 = load i8, ptr %122, align 1, !tbaa !13
  %124 = xor i8 %123, %113
  store i8 %124, ptr %122, align 1, !tbaa !13
  %125 = add i32 %.05263, 1
  %126 = zext i32 %125 to i64
  %127 = icmp ult i64 %126, %1
  br i1 %127, label %.lr.ph.split, label %.loopexit, !llvm.loop !17

.loopexit:                                        ; preds = %107, %110, %69, %72, %8, %.preheader, %36, %5
  %.053 = phi i32 [ 1, %5 ], [ 1, %36 ], [ 0, %.preheader ], [ 1, %8 ], [ 1, %69 ], [ 0, %72 ], [ 1, %107 ], [ 0, %110 ]
  ret i32 %.053
}

attributes #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 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { 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, !9, i64 344}
!6 = !{!"", !7, i64 0, !7, i64 256, !7, i64 272, !7, i64 288, !7, i64 304, !7, i64 320, !9, i64 336, !9, i64 340, !9, i64 344, !10, i64 352, !10, i64 360, !7, i64 368}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}
!9 = !{!"int", !7, i64 0}
!10 = !{!"long", !7, i64 0}
!11 = !{!6, !9, i64 340}
!12 = !{!6, !10, i64 352}
!13 = !{!7, !7, i64 0}
!14 = !{!6, !10, i64 360}
!15 = distinct !{!15, !16}
!16 = !{!"llvm.loop.mustprogress"}
!17 = distinct !{!17, !16}


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