; LLVM IR from machinefi/psa-crypto-esp32 :: psa_layer (psa_crypto_hash)

; 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.iotex_psa_hash_operation_t = type { i32, %union.anon }
%union.anon = type { %struct.iotex_sha256_context }
%struct.iotex_sha256_context = type { ptr }

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

declare i32 @iotex_to_psa_error(i32 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
define dso_local i32 @iotex_psa_hash_finish(ptr noundef %0, ptr noundef %1, i64 noundef %2, ptr noundef %3) #2 {
  %5 = alloca i32, align 4
  %6 = alloca ptr, align 8
  %7 = alloca ptr, align 8
  %8 = alloca i64, align 8
  %9 = alloca ptr, align 8
  %10 = alloca i32, align 4
  %11 = alloca i32, align 4
  %12 = alloca i64, align 8
  %13 = alloca i32, align 4
  store ptr %0, ptr %6, align 8, !tbaa !5
  store ptr %1, ptr %7, align 8, !tbaa !5
  store i64 %2, ptr %8, align 8, !tbaa !9
  store ptr %3, ptr %9, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 4, ptr %10) #4
  call void @llvm.lifetime.start.p0(i64 4, ptr %11) #4
  store i32 -110, ptr %11, align 4, !tbaa !11
  call void @llvm.lifetime.start.p0(i64 8, ptr %12) #4
  %14 = load ptr, ptr %6, align 8, !tbaa !5
  %15 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %14, i32 0, i32 0
  %16 = load i32, ptr %15, align 8, !tbaa !13
  %17 = and i32 %16, 255
  %18 = or i32 33554432, %17
  %19 = icmp eq i32 %18, 33554435
  br i1 %19, label %20, label %21

20:                                               ; preds = %4
  br label %140

21:                                               ; preds = %4
  %22 = load ptr, ptr %6, align 8, !tbaa !5
  %23 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %22, i32 0, i32 0
  %24 = load i32, ptr %23, align 8, !tbaa !13
  %25 = and i32 %24, 255
  %26 = or i32 33554432, %25
  %27 = icmp eq i32 %26, 33554436
  br i1 %27, label %28, label %29

28:                                               ; preds = %21
  br label %138

29:                                               ; preds = %21
  %30 = load ptr, ptr %6, align 8, !tbaa !5
  %31 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %30, i32 0, i32 0
  %32 = load i32, ptr %31, align 8, !tbaa !13
  %33 = and i32 %32, 255
  %34 = or i32 33554432, %33
  %35 = icmp eq i32 %34, 33554437
  br i1 %35, label %36, label %37

36:                                               ; preds = %29
  br label %136

37:                                               ; preds = %29
  %38 = load ptr, ptr %6, align 8, !tbaa !5
  %39 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %38, i32 0, i32 0
  %40 = load i32, ptr %39, align 8, !tbaa !13
  %41 = and i32 %40, 255
  %42 = or i32 33554432, %41
  %43 = icmp eq i32 %42, 33554440
  br i1 %43, label %44, label %45

44:                                               ; preds = %37
  br label %134

45:                                               ; preds = %37
  %46 = load ptr, ptr %6, align 8, !tbaa !5
  %47 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %46, i32 0, i32 0
  %48 = load i32, ptr %47, align 8, !tbaa !13
  %49 = and i32 %48, 255
  %50 = or i32 33554432, %49
  %51 = icmp eq i32 %50, 33554441
  br i1 %51, label %52, label %53

52:                                               ; preds = %45
  br label %132

53:                                               ; preds = %45
  %54 = load ptr, ptr %6, align 8, !tbaa !5
  %55 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %54, i32 0, i32 0
  %56 = load i32, ptr %55, align 8, !tbaa !13
  %57 = and i32 %56, 255
  %58 = or i32 33554432, %57
  %59 = icmp eq i32 %58, 33554442
  br i1 %59, label %60, label %61

60:                                               ; preds = %53
  br label %130

61:                                               ; preds = %53
  %62 = load ptr, ptr %6, align 8, !tbaa !5
  %63 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %62, i32 0, i32 0
  %64 = load i32, ptr %63, align 8, !tbaa !13
  %65 = and i32 %64, 255
  %66 = or i32 33554432, %65
  %67 = icmp eq i32 %66, 33554443
  br i1 %67, label %68, label %69

68:                                               ; preds = %61
  br label %128

69:                                               ; preds = %61
  %70 = load ptr, ptr %6, align 8, !tbaa !5
  %71 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %70, i32 0, i32 0
  %72 = load i32, ptr %71, align 8, !tbaa !13
  %73 = and i32 %72, 255
  %74 = or i32 33554432, %73
  %75 = icmp eq i32 %74, 33554444
  br i1 %75, label %76, label %77

76:                                               ; preds = %69
  br label %126

77:                                               ; preds = %69
  %78 = load ptr, ptr %6, align 8, !tbaa !5
  %79 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %78, i32 0, i32 0
  %80 = load i32, ptr %79, align 8, !tbaa !13
  %81 = and i32 %80, 255
  %82 = or i32 33554432, %81
  %83 = icmp eq i32 %82, 33554445
  br i1 %83, label %84, label %85

84:                                               ; preds = %77
  br label %124

85:                                               ; preds = %77
  %86 = load ptr, ptr %6, align 8, !tbaa !5
  %87 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %86, i32 0, i32 0
  %88 = load i32, ptr %87, align 8, !tbaa !13
  %89 = and i32 %88, 255
  %90 = or i32 33554432, %89
  %91 = icmp eq i32 %90, 33554448
  br i1 %91, label %92, label %93

92:                                               ; preds = %85
  br label %122

93:                                               ; preds = %85
  %94 = load ptr, ptr %6, align 8, !tbaa !5
  %95 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %94, i32 0, i32 0
  %96 = load i32, ptr %95, align 8, !tbaa !13
  %97 = and i32 %96, 255
  %98 = or i32 33554432, %97
  %99 = icmp eq i32 %98, 33554449
  br i1 %99, label %100, label %101

100:                                              ; preds = %93
  br label %120

101:                                              ; preds = %93
  %102 = load ptr, ptr %6, align 8, !tbaa !5
  %103 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %102, i32 0, i32 0
  %104 = load i32, ptr %103, align 8, !tbaa !13
  %105 = and i32 %104, 255
  %106 = or i32 33554432, %105
  %107 = icmp eq i32 %106, 33554450
  br i1 %107, label %108, label %109

108:                                              ; preds = %101
  br label %118

109:                                              ; preds = %101
  %110 = load ptr, ptr %6, align 8, !tbaa !5
  %111 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %110, i32 0, i32 0
  %112 = load i32, ptr %111, align 8, !tbaa !13
  %113 = and i32 %112, 255
  %114 = or i32 33554432, %113
  %115 = icmp eq i32 %114, 33554451
  %116 = zext i1 %115 to i64
  %117 = select i1 %115, i32 64, i32 0
  br label %118

118:                                              ; preds = %109, %108
  %119 = phi i32 [ 48, %108 ], [ %117, %109 ]
  br label %120

120:                                              ; preds = %118, %100
  %121 = phi i32 [ 32, %100 ], [ %119, %118 ]
  br label %122

122:                                              ; preds = %120, %92
  %123 = phi i32 [ 28, %92 ], [ %121, %120 ]
  br label %124

124:                                              ; preds = %122, %84
  %125 = phi i32 [ 32, %84 ], [ %123, %122 ]
  br label %126

126:                                              ; preds = %124, %76
  %127 = phi i32 [ 28, %76 ], [ %125, %124 ]
  br label %128

128:                                              ; preds = %126, %68
  %129 = phi i32 [ 64, %68 ], [ %127, %126 ]
  br label %130

130:                                              ; preds = %128, %60
  %131 = phi i32 [ 48, %60 ], [ %129, %128 ]
  br label %132

132:                                              ; preds = %130, %52
  %133 = phi i32 [ 32, %52 ], [ %131, %130 ]
  br label %134

134:                                              ; preds = %132, %44
  %135 = phi i32 [ 28, %44 ], [ %133, %132 ]
  br label %136

136:                                              ; preds = %134, %36
  %137 = phi i32 [ 20, %36 ], [ %135, %134 ]
  br label %138

138:                                              ; preds = %136, %28
  %139 = phi i32 [ 20, %28 ], [ %137, %136 ]
  br label %140

140:                                              ; preds = %138, %20
  %141 = phi i32 [ 16, %20 ], [ %139, %138 ]
  %142 = sext i32 %141 to i64
  store i64 %142, ptr %12, align 8, !tbaa !9
  %143 = load i64, ptr %8, align 8, !tbaa !9
  %144 = load ptr, ptr %9, align 8, !tbaa !5
  store i64 %143, ptr %144, align 8, !tbaa !9
  %145 = load i64, ptr %8, align 8, !tbaa !9
  %146 = icmp ne i64 %145, 0
  br i1 %146, label %147, label %150

147:                                              ; preds = %140
  %148 = load ptr, ptr %7, align 8, !tbaa !5
  %149 = load i64, ptr %8, align 8, !tbaa !9
  call void @llvm.memset.p0.i64(ptr align 1 %148, i8 33, i64 %149, i1 false)
  br label %150

150:                                              ; preds = %147, %140
  %151 = load i64, ptr %8, align 8, !tbaa !9
  %152 = load i64, ptr %12, align 8, !tbaa !9
  %153 = icmp ult i64 %151, %152
  br i1 %153, label %154, label %155

154:                                              ; preds = %150
  store i32 -138, ptr %10, align 4, !tbaa !11
  br label %174

155:                                              ; preds = %150
  %156 = load ptr, ptr %6, align 8, !tbaa !5
  %157 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %156, i32 0, i32 0
  %158 = load i32, ptr %157, align 8, !tbaa !13
  switch i32 %158, label %169 [
    i32 33554440, label %159
    i32 33554441, label %164
  ]

159:                                              ; preds = %155
  %160 = load ptr, ptr %6, align 8, !tbaa !5
  %161 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %160, i32 0, i32 1
  %162 = load ptr, ptr %7, align 8, !tbaa !5
  %163 = call i32 @iotex_sha256_finish(ptr noundef %161, ptr noundef %162)
  store i32 %163, ptr %11, align 4, !tbaa !11
  br label %171

164:                                              ; preds = %155
  %165 = load ptr, ptr %6, align 8, !tbaa !5
  %166 = getelementptr inbounds %struct.iotex_psa_hash_operation_t, ptr %165, i32 0, i32 1
  %167 = load ptr, ptr %7, align 8, !tbaa !5
  %168 = call i32 @iotex_sha256_finish(ptr noundef %166, ptr noundef %167)
  store i32 %168, ptr %11, align 4, !tbaa !11
  br label %171

169:                                              ; preds = %155
  %170 = load ptr, ptr %7, align 8, !tbaa !5
  store i32 -137, ptr %5, align 4
  store i32 1, ptr %13, align 4
  br label %182

171:                                              ; preds = %164, %159
  %172 = load i32, ptr %11, align 4, !tbaa !11
  %173 = call i32 @iotex_to_psa_error(i32 noundef %172)
  store i32 %173, ptr %10, align 4, !tbaa !11
  br label %174

174:                                              ; preds = %171, %154
  %175 = load i32, ptr %10, align 4, !tbaa !11
  %176 = icmp eq i32 %175, 0
  br i1 %176, label %177, label %180

177:                                              ; preds = %174
  %178 = load i64, ptr %12, align 8, !tbaa !9
  %179 = load ptr, ptr %9, align 8, !tbaa !5
  store i64 %178, ptr %179, align 8, !tbaa !9
  br label %180

180:                                              ; preds = %177, %174
  %181 = load i32, ptr %10, align 4, !tbaa !11
  store i32 %181, ptr %5, align 4
  store i32 1, ptr %13, align 4
  br label %182

182:                                              ; preds = %180, %169
  call void @llvm.lifetime.end.p0(i64 8, ptr %12) #4
  call void @llvm.lifetime.end.p0(i64 4, ptr %11) #4
  call void @llvm.lifetime.end.p0(i64 4, ptr %10) #4
  %183 = load i32, ptr %5, align 4
  ret i32 %183
}

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

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

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 = { nocallback nofree nounwind willreturn memory(argmem: write) }
attributes #4 = { 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 0}
!14 = !{!"", !12, i64 0, !7, i64 8}


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

@switch.table.iotex_psa_hash_finish = private unnamed_addr constant [16 x i64] [i64 16, i64 20, i64 20, i64 16, i64 16, i64 28, i64 32, i64 48, i64 64, i64 28, i64 32, i64 16, i64 16, i64 28, i64 32, i64 48], align 8

declare i32 @iotex_to_psa_error(i32 noundef) local_unnamed_addr #0

; Function Attrs: nounwind uwtable
define dso_local i32 @iotex_psa_hash_finish(ptr noundef %0, ptr noundef %1, i64 noundef %2, ptr nocapture noundef writeonly %3) local_unnamed_addr #1 {
  %5 = load i32, ptr %0, align 8, !tbaa !5
  %trunc = trunc i32 %5 to i8
  %switch.tableidx = add i8 %trunc, -3
  %6 = icmp ult i8 %switch.tableidx, 16
  br i1 %6, label %switch.hole_check, label %7

7:                                                ; preds = %switch.hole_check, %4
  %8 = and i32 %5, 255
  %9 = icmp eq i32 %8, 19
  %10 = select i1 %9, i64 64, i64 0
  br label %12

switch.hole_check:                                ; preds = %4
  %switch.maskindex = zext nneg i8 %switch.tableidx to i16
  %switch.shifted = lshr i16 -6169, %switch.maskindex
  %switch.lobit = trunc i16 %switch.shifted to i1
  br i1 %switch.lobit, label %switch.lookup, label %7

switch.lookup:                                    ; preds = %switch.hole_check
  %11 = zext nneg i8 %switch.tableidx to i64
  %switch.gep = getelementptr inbounds [16 x i64], ptr @switch.table.iotex_psa_hash_finish, i64 0, i64 %11
  %switch.load = load i64, ptr %switch.gep, align 8
  br label %12

12:                                               ; preds = %switch.lookup, %7
  %13 = phi i64 [ %10, %7 ], [ %switch.load, %switch.lookup ]
  store i64 %2, ptr %3, align 8, !tbaa !10
  %.not = icmp eq i64 %2, 0
  br i1 %.not, label %15, label %14

14:                                               ; preds = %12
  tail call void @llvm.memset.p0.i64(ptr align 1 %1, i8 33, i64 %2, i1 false)
  br label %15

15:                                               ; preds = %14, %12
  %16 = icmp ugt i64 %13, %2
  br i1 %16, label %.thread, label %17

17:                                               ; preds = %15
  %18 = load i32, ptr %0, align 8, !tbaa !5
  %19 = and i32 %18, -2
  %switch = icmp eq i32 %19, 33554440
  br i1 %switch, label %20, label %.thread

20:                                               ; preds = %17
  %21 = getelementptr inbounds i8, ptr %0, i64 8
  %22 = tail call i32 @iotex_sha256_finish(ptr noundef nonnull %21, ptr noundef %1) #3
  %23 = tail call i32 @iotex_to_psa_error(i32 noundef %22) #3
  %24 = icmp eq i32 %23, 0
  br i1 %24, label %25, label %.thread

25:                                               ; preds = %20
  store i64 %13, ptr %3, align 8, !tbaa !10
  br label %.thread

.thread:                                          ; preds = %17, %15, %20, %25
  %.0 = phi i32 [ -137, %17 ], [ 0, %25 ], [ %23, %20 ], [ -138, %15 ]
  ret i32 %.0
}

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

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

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 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: write) }
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, !7, i64 0}
!6 = !{!"", !7, i64 0, !8, i64 8}
!7 = !{!"int", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C/C++ TBAA"}
!10 = !{!11, !11, i64 0}
!11 = !{!"long", !8, i64 0}


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