; LLVM IR from machinefi/psa-crypto-arduino :: src/psa_layer (psa_crypto)

; 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.psa_global_data_t = type { i8, %struct.iotex_psa_external_random_context_t }
%struct.iotex_psa_external_random_context_t = type { [2 x i64] }

@global_data = external hidden global %struct.psa_global_data_t, align 8

; 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(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #0

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

; Function Attrs: inlinehint nounwind uwtable
declare hidden i32 @iotex_psa_safer_memcmp(ptr noundef, ptr noundef, i64 noundef) #2

declare i32 @psa_driver_wrapper_hash_compute(i32 noundef, ptr noundef, i64 noundef, ptr noundef, i64 noundef, ptr noundef) #3

; Function Attrs: nounwind uwtable
define dso_local i32 @psa_hash_compare(i32 noundef %0, ptr noundef %1, i64 noundef %2, ptr noundef %3, i64 noundef %4) #4 {
  %6 = alloca i32, align 4
  %7 = alloca i32, align 4
  %8 = alloca ptr, align 8
  %9 = alloca i64, align 8
  %10 = alloca ptr, align 8
  %11 = alloca i64, align 8
  %12 = alloca [32 x i8], align 16
  %13 = alloca i64, align 8
  %14 = alloca i32, align 4
  %15 = alloca i32, align 4
  store i32 %0, ptr %7, align 4, !tbaa !5
  store ptr %1, ptr %8, align 8, !tbaa !9
  store i64 %2, ptr %9, align 8, !tbaa !11
  store ptr %3, ptr %10, align 8, !tbaa !9
  store i64 %4, ptr %11, align 8, !tbaa !11
  %16 = load i8, ptr @global_data, align 8
  %17 = and i8 %16, 1
  %18 = zext i8 %17 to i32
  %19 = icmp eq i32 %18, 0
  br i1 %19, label %20, label %21

20:                                               ; preds = %5
  store i32 -137, ptr %6, align 4
  br label %159

21:                                               ; preds = %5
  call void @llvm.lifetime.start.p0(i64 32, ptr %12) #5
  call void @llvm.lifetime.start.p0(i64 8, ptr %13) #5
  %22 = load i64, ptr %11, align 8, !tbaa !11
  %23 = load i32, ptr %7, align 4, !tbaa !5
  %24 = and i32 %23, 255
  %25 = or i32 33554432, %24
  %26 = icmp eq i32 %25, 33554435
  br i1 %26, label %27, label %28

27:                                               ; preds = %21
  br label %123

28:                                               ; preds = %21
  %29 = load i32, ptr %7, align 4, !tbaa !5
  %30 = and i32 %29, 255
  %31 = or i32 33554432, %30
  %32 = icmp eq i32 %31, 33554436
  br i1 %32, label %33, label %34

33:                                               ; preds = %28
  br label %121

34:                                               ; preds = %28
  %35 = load i32, ptr %7, align 4, !tbaa !5
  %36 = and i32 %35, 255
  %37 = or i32 33554432, %36
  %38 = icmp eq i32 %37, 33554437
  br i1 %38, label %39, label %40

39:                                               ; preds = %34
  br label %119

40:                                               ; preds = %34
  %41 = load i32, ptr %7, align 4, !tbaa !5
  %42 = and i32 %41, 255
  %43 = or i32 33554432, %42
  %44 = icmp eq i32 %43, 33554440
  br i1 %44, label %45, label %46

45:                                               ; preds = %40
  br label %117

46:                                               ; preds = %40
  %47 = load i32, ptr %7, align 4, !tbaa !5
  %48 = and i32 %47, 255
  %49 = or i32 33554432, %48
  %50 = icmp eq i32 %49, 33554441
  br i1 %50, label %51, label %52

51:                                               ; preds = %46
  br label %115

52:                                               ; preds = %46
  %53 = load i32, ptr %7, align 4, !tbaa !5
  %54 = and i32 %53, 255
  %55 = or i32 33554432, %54
  %56 = icmp eq i32 %55, 33554442
  br i1 %56, label %57, label %58

57:                                               ; preds = %52
  br label %113

58:                                               ; preds = %52
  %59 = load i32, ptr %7, align 4, !tbaa !5
  %60 = and i32 %59, 255
  %61 = or i32 33554432, %60
  %62 = icmp eq i32 %61, 33554443
  br i1 %62, label %63, label %64

63:                                               ; preds = %58
  br label %111

64:                                               ; preds = %58
  %65 = load i32, ptr %7, align 4, !tbaa !5
  %66 = and i32 %65, 255
  %67 = or i32 33554432, %66
  %68 = icmp eq i32 %67, 33554444
  br i1 %68, label %69, label %70

69:                                               ; preds = %64
  br label %109

70:                                               ; preds = %64
  %71 = load i32, ptr %7, align 4, !tbaa !5
  %72 = and i32 %71, 255
  %73 = or i32 33554432, %72
  %74 = icmp eq i32 %73, 33554445
  br i1 %74, label %75, label %76

75:                                               ; preds = %70
  br label %107

76:                                               ; preds = %70
  %77 = load i32, ptr %7, align 4, !tbaa !5
  %78 = and i32 %77, 255
  %79 = or i32 33554432, %78
  %80 = icmp eq i32 %79, 33554448
  br i1 %80, label %81, label %82

81:                                               ; preds = %76
  br label %105

82:                                               ; preds = %76
  %83 = load i32, ptr %7, align 4, !tbaa !5
  %84 = and i32 %83, 255
  %85 = or i32 33554432, %84
  %86 = icmp eq i32 %85, 33554449
  br i1 %86, label %87, label %88

87:                                               ; preds = %82
  br label %103

88:                                               ; preds = %82
  %89 = load i32, ptr %7, align 4, !tbaa !5
  %90 = and i32 %89, 255
  %91 = or i32 33554432, %90
  %92 = icmp eq i32 %91, 33554450
  br i1 %92, label %93, label %94

93:                                               ; preds = %88
  br label %101

94:                                               ; preds = %88
  %95 = load i32, ptr %7, align 4, !tbaa !5
  %96 = and i32 %95, 255
  %97 = or i32 33554432, %96
  %98 = icmp eq i32 %97, 33554451
  %99 = zext i1 %98 to i64
  %100 = select i1 %98, i32 64, i32 0
  br label %101

101:                                              ; preds = %94, %93
  %102 = phi i32 [ 48, %93 ], [ %100, %94 ]
  br label %103

103:                                              ; preds = %101, %87
  %104 = phi i32 [ 32, %87 ], [ %102, %101 ]
  br label %105

105:                                              ; preds = %103, %81
  %106 = phi i32 [ 28, %81 ], [ %104, %103 ]
  br label %107

107:                                              ; preds = %105, %75
  %108 = phi i32 [ 32, %75 ], [ %106, %105 ]
  br label %109

109:                                              ; preds = %107, %69
  %110 = phi i32 [ 28, %69 ], [ %108, %107 ]
  br label %111

111:                                              ; preds = %109, %63
  %112 = phi i32 [ 64, %63 ], [ %110, %109 ]
  br label %113

113:                                              ; preds = %111, %57
  %114 = phi i32 [ 48, %57 ], [ %112, %111 ]
  br label %115

115:                                              ; preds = %113, %51
  %116 = phi i32 [ 32, %51 ], [ %114, %113 ]
  br label %117

117:                                              ; preds = %115, %45
  %118 = phi i32 [ 28, %45 ], [ %116, %115 ]
  br label %119

119:                                              ; preds = %117, %39
  %120 = phi i32 [ 20, %39 ], [ %118, %117 ]
  br label %121

121:                                              ; preds = %119, %33
  %122 = phi i32 [ 20, %33 ], [ %120, %119 ]
  br label %123

123:                                              ; preds = %121, %27
  %124 = phi i32 [ 16, %27 ], [ %122, %121 ]
  %125 = sext i32 %124 to i64
  %126 = icmp ult i64 %22, %125
  br i1 %126, label %127, label %128

127:                                              ; preds = %123
  store i32 -135, ptr %6, align 4
  store i32 1, ptr %14, align 4
  br label %158

128:                                              ; preds = %123
  %129 = load i32, ptr %7, align 4, !tbaa !5
  %130 = and i32 %129, 2130706432
  %131 = icmp eq i32 %130, 33554432
  br i1 %131, label %133, label %132

132:                                              ; preds = %128
  store i32 -135, ptr %6, align 4
  store i32 1, ptr %14, align 4
  br label %158

133:                                              ; preds = %128
  call void @llvm.lifetime.start.p0(i64 4, ptr %15) #5
  %134 = load i32, ptr %7, align 4, !tbaa !5
  %135 = load ptr, ptr %8, align 8, !tbaa !9
  %136 = load i64, ptr %9, align 8, !tbaa !11
  %137 = getelementptr inbounds [32 x i8], ptr %12, i64 0, i64 0
  %138 = call i32 @psa_driver_wrapper_hash_compute(i32 noundef %134, ptr noundef %135, i64 noundef %136, ptr noundef %137, i64 noundef 32, ptr noundef %13)
  store i32 %138, ptr %15, align 4, !tbaa !5
  %139 = load i32, ptr %15, align 4, !tbaa !5
  %140 = icmp ne i32 %139, 0
  br i1 %140, label %141, label %142

141:                                              ; preds = %133
  br label %155

142:                                              ; preds = %133
  %143 = load i64, ptr %13, align 8, !tbaa !11
  %144 = load i64, ptr %11, align 8, !tbaa !11
  %145 = icmp ne i64 %143, %144
  br i1 %145, label %146, label %147

146:                                              ; preds = %142
  store i32 -149, ptr %15, align 4, !tbaa !5
  br label %155

147:                                              ; preds = %142
  %148 = load ptr, ptr %10, align 8, !tbaa !9
  %149 = getelementptr inbounds [32 x i8], ptr %12, i64 0, i64 0
  %150 = load i64, ptr %13, align 8, !tbaa !11
  %151 = call i32 @iotex_psa_safer_memcmp(ptr noundef %148, ptr noundef %149, i64 noundef %150)
  %152 = icmp ne i32 %151, 0
  br i1 %152, label %153, label %154

153:                                              ; preds = %147
  store i32 -149, ptr %15, align 4, !tbaa !5
  br label %154

154:                                              ; preds = %153, %147
  br label %155

155:                                              ; preds = %154, %146, %141
  %156 = getelementptr inbounds [32 x i8], ptr %12, i64 0, i64 0
  call void @llvm.memset.p0.i64(ptr align 16 %156, i8 0, i64 32, i1 false)
  %157 = load i32, ptr %15, align 4, !tbaa !5
  store i32 %157, ptr %6, align 4
  store i32 1, ptr %14, align 4
  call void @llvm.lifetime.end.p0(i64 4, ptr %15) #5
  br label %158

158:                                              ; preds = %155, %132, %127
  call void @llvm.lifetime.end.p0(i64 8, ptr %13) #5
  call void @llvm.lifetime.end.p0(i64 32, ptr %12) #5
  br label %159

159:                                              ; preds = %158, %20
  %160 = load i32, ptr %6, align 4
  ret i32 %160
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: write) }
attributes #2 = { 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 #3 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #4 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #5 = { 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 = !{!"int", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}
!9 = !{!10, !10, i64 0}
!10 = !{!"any pointer", !7, i64 0}
!11 = !{!12, !12, i64 0}
!12 = !{!"long", !7, i64 0}


; 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.psa_global_data_t = type { i8, %struct.iotex_psa_external_random_context_t }
%struct.iotex_psa_external_random_context_t = type { [2 x i64] }

@global_data = external hidden local_unnamed_addr global %struct.psa_global_data_t, align 8
@switch.table.psa_hash_compare = 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

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

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

; Function Attrs: inlinehint nounwind uwtable
declare hidden i32 @iotex_psa_safer_memcmp(ptr noundef, ptr noundef, i64 noundef) local_unnamed_addr #1

declare i32 @psa_driver_wrapper_hash_compute(i32 noundef, ptr noundef, i64 noundef, ptr noundef, i64 noundef, ptr noundef) local_unnamed_addr #2

; Function Attrs: nounwind uwtable
define dso_local i32 @psa_hash_compare(i32 noundef %0, ptr noundef %1, i64 noundef %2, ptr noundef %3, i64 noundef %4) local_unnamed_addr #3 {
  %6 = alloca [32 x i8], align 16
  %7 = alloca i64, align 8
  %8 = load i8, ptr @global_data, align 8
  %9 = and i8 %8, 1
  %10 = icmp eq i8 %9, 0
  br i1 %10, label %30, label %11

11:                                               ; preds = %5
  call void @llvm.lifetime.start.p0(i64 32, ptr nonnull %6) #4
  call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %7) #4
  %trunc = trunc i32 %0 to i8
  %switch.tableidx = add i8 %trunc, -3
  %12 = icmp ult i8 %switch.tableidx, 16
  br i1 %12, label %switch.hole_check, label %13

13:                                               ; preds = %switch.hole_check, %11
  %14 = and i32 %0, 255
  %15 = icmp eq i32 %14, 19
  %16 = select i1 %15, i64 64, i64 0
  br label %18

switch.hole_check:                                ; preds = %11
  %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 %13

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

18:                                               ; preds = %switch.lookup, %13
  %19 = phi i64 [ %16, %13 ], [ %switch.load, %switch.lookup ]
  %20 = icmp ule i64 %19, %4
  %21 = and i32 %0, 2130706432
  %22 = icmp eq i32 %21, 33554432
  %or.cond = and i1 %22, %20
  br i1 %or.cond, label %23, label %29

23:                                               ; preds = %18
  %24 = call i32 @psa_driver_wrapper_hash_compute(i32 noundef %0, ptr noundef %1, i64 noundef %2, ptr noundef nonnull %6, i64 noundef 32, ptr noundef nonnull %7) #4
  %.not = icmp eq i32 %24, 0
  br i1 %.not, label %25, label %29

25:                                               ; preds = %23
  %26 = load i64, ptr %7, align 8, !tbaa !5
  %.not28 = icmp eq i64 %26, %4
  br i1 %.not28, label %27, label %29

27:                                               ; preds = %25
  %28 = call i32 @iotex_psa_safer_memcmp(ptr noundef %3, ptr noundef nonnull %6, i64 noundef %4)
  %.not29 = icmp eq i32 %28, 0
  %spec.select = select i1 %.not29, i32 0, i32 -149
  br label %29

29:                                               ; preds = %23, %25, %27, %18
  %.022 = phi i32 [ -135, %18 ], [ %24, %23 ], [ -149, %25 ], [ %spec.select, %27 ]
  call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %7) #4
  call void @llvm.lifetime.end.p0(i64 32, ptr nonnull %6) #4
  br label %30

30:                                               ; preds = %5, %29
  %.1 = phi i32 [ %.022, %29 ], [ -137, %5 ]
  ret i32 %.1
}

attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { 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 #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 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 }

!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 = !{!"long", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}


; Effective O3 passes: DSEPass,EarlyCSEPass,GVNPass,GlobalOptPass,IPSCCPPass,InferFunctionAttrsPass,InstCombinePass,ReassociatePass,SROAPass,SimplifyCFGPass