; LLVM IR from DanEngelbrecht/longtail :: lib/brotli/ext/enc (encode)

; 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.BrotliEncoderStateStruct = type { %struct.BrotliEncoderParams, %struct.MemoryManager, i64, %struct.RingBuffer, i64, ptr, i64, i64, i64, i64, i64, [16 x i32], [4 x i32], i16, i8, i8, i8, i8, i64, ptr, %struct.Hasher, [1024 x i32], ptr, i64, ptr, ptr, ptr, ptr, i64, ptr, i64, i64, %union.anon.0, i32, i32, i32, i32 }
%struct.BrotliEncoderParams = type { i32, i32, i32, i32, i64, i64, i32, i32, %struct.BrotliHasherParams, %struct.BrotliDistanceParams, %struct.SharedEncoderDictionary }
%struct.BrotliHasherParams = type { i32, i32, i32, i32 }
%struct.BrotliDistanceParams = type { i32, i32, i32, i32, i64 }
%struct.SharedEncoderDictionary = type { i32, %struct.CompoundDictionary, %struct.ContextualEncoderDictionary, i32 }
%struct.CompoundDictionary = type { i64, i64, [16 x ptr], [16 x ptr], [16 x i64], i64, [16 x ptr] }
%struct.ContextualEncoderDictionary = type { i32, i8, [64 x i8], [64 x ptr], i64, %struct.BrotliEncoderDictionary, ptr }
%struct.BrotliEncoderDictionary = type { ptr, i32, i32, i64, ptr, ptr, ptr, ptr, %struct.BrotliTrie, i32, ptr, ptr, ptr, i64, ptr, i64, ptr, ptr }
%struct.BrotliTrie = type { ptr, i64, i64, %struct.BrotliTrieNode }
%struct.BrotliTrieNode = type { i8, i8, i8, i32, i32 }
%struct.MemoryManager = type { ptr, ptr, ptr }
%struct.RingBuffer = type { i32, i32, i32, i32, i32, i32, ptr, ptr }
%struct.Hasher = type { %struct.HasherCommon, %union.anon }
%struct.HasherCommon = type { [4 x ptr], i32, i64, i64, %struct.BrotliHasherParams, i32 }
%union.anon = type { %struct.H42 }
%struct.H42 = type { [512 x i16], i64, [2 x ptr], ptr }
%union.anon.0 = type { [2 x i64] }

; Function Attrs: nounwind uwtable
define dso_local i32 @BrotliEncoderSetParameter(ptr noundef %0, i32 noundef %1, i32 noundef %2) #0 {
  %4 = alloca i32, align 4
  %5 = alloca ptr, align 8
  %6 = alloca i32, align 4
  %7 = alloca i32, align 4
  store ptr %0, ptr %5, align 8, !tbaa !5
  store i32 %1, ptr %6, align 4, !tbaa !9
  store i32 %2, ptr %7, align 4, !tbaa !9
  %8 = load ptr, ptr %5, align 8, !tbaa !5
  %9 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %8, i32 0, i32 36
  %10 = load i32, ptr %9, align 4, !tbaa !11
  %11 = icmp ne i32 %10, 0
  br i1 %11, label %12, label %13

12:                                               ; preds = %3
  store i32 0, ptr %4, align 4
  br label %95

13:                                               ; preds = %3
  %14 = load i32, ptr %6, align 4, !tbaa !9
  switch i32 %14, label %94 [
    i32 0, label %15
    i32 1, label %20
    i32 2, label %25
    i32 3, label %30
    i32 4, label %35
    i32 5, label %54
    i32 6, label %60
    i32 7, label %72
    i32 8, label %78
    i32 9, label %84
  ]

15:                                               ; preds = %13
  %16 = load i32, ptr %7, align 4, !tbaa !9
  %17 = load ptr, ptr %5, align 8, !tbaa !5
  %18 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %17, i32 0, i32 0
  %19 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %18, i32 0, i32 0
  store i32 %16, ptr %19, align 8, !tbaa !28
  store i32 1, ptr %4, align 4
  br label %95

20:                                               ; preds = %13
  %21 = load i32, ptr %7, align 4, !tbaa !9
  %22 = load ptr, ptr %5, align 8, !tbaa !5
  %23 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %22, i32 0, i32 0
  %24 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %23, i32 0, i32 1
  store i32 %21, ptr %24, align 4, !tbaa !29
  store i32 1, ptr %4, align 4
  br label %95

25:                                               ; preds = %13
  %26 = load i32, ptr %7, align 4, !tbaa !9
  %27 = load ptr, ptr %5, align 8, !tbaa !5
  %28 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %27, i32 0, i32 0
  %29 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %28, i32 0, i32 2
  store i32 %26, ptr %29, align 8, !tbaa !30
  store i32 1, ptr %4, align 4
  br label %95

30:                                               ; preds = %13
  %31 = load i32, ptr %7, align 4, !tbaa !9
  %32 = load ptr, ptr %5, align 8, !tbaa !5
  %33 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %32, i32 0, i32 0
  %34 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %33, i32 0, i32 3
  store i32 %31, ptr %34, align 4, !tbaa !31
  store i32 1, ptr %4, align 4
  br label %95

35:                                               ; preds = %13
  %36 = load i32, ptr %7, align 4, !tbaa !9
  %37 = icmp ne i32 %36, 0
  br i1 %37, label %38, label %42

38:                                               ; preds = %35
  %39 = load i32, ptr %7, align 4, !tbaa !9
  %40 = icmp ne i32 %39, 1
  br i1 %40, label %41, label %42

41:                                               ; preds = %38
  store i32 0, ptr %4, align 4
  br label %95

42:                                               ; preds = %38, %35
  %43 = load i32, ptr %7, align 4, !tbaa !9
  %44 = icmp ne i32 %43, 0
  %45 = xor i1 %44, true
  %46 = xor i1 %45, true
  %47 = xor i1 %46, true
  %48 = xor i1 %47, true
  %49 = zext i1 %48 to i64
  %50 = select i1 %48, i32 1, i32 0
  %51 = load ptr, ptr %5, align 8, !tbaa !5
  %52 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %51, i32 0, i32 0
  %53 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %52, i32 0, i32 6
  store i32 %50, ptr %53, align 8, !tbaa !32
  store i32 1, ptr %4, align 4
  br label %95

54:                                               ; preds = %13
  %55 = load i32, ptr %7, align 4, !tbaa !9
  %56 = zext i32 %55 to i64
  %57 = load ptr, ptr %5, align 8, !tbaa !5
  %58 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %57, i32 0, i32 0
  %59 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %58, i32 0, i32 5
  store i64 %56, ptr %59, align 8, !tbaa !33
  store i32 1, ptr %4, align 4
  br label %95

60:                                               ; preds = %13
  %61 = load i32, ptr %7, align 4, !tbaa !9
  %62 = icmp ne i32 %61, 0
  %63 = xor i1 %62, true
  %64 = xor i1 %63, true
  %65 = xor i1 %64, true
  %66 = xor i1 %65, true
  %67 = zext i1 %66 to i64
  %68 = select i1 %66, i32 1, i32 0
  %69 = load ptr, ptr %5, align 8, !tbaa !5
  %70 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %69, i32 0, i32 0
  %71 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %70, i32 0, i32 7
  store i32 %68, ptr %71, align 4, !tbaa !34
  store i32 1, ptr %4, align 4
  br label %95

72:                                               ; preds = %13
  %73 = load i32, ptr %7, align 4, !tbaa !9
  %74 = load ptr, ptr %5, align 8, !tbaa !5
  %75 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %74, i32 0, i32 0
  %76 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %75, i32 0, i32 9
  %77 = getelementptr inbounds %struct.BrotliDistanceParams, ptr %76, i32 0, i32 0
  store i32 %73, ptr %77, align 8, !tbaa !35
  store i32 1, ptr %4, align 4
  br label %95

78:                                               ; preds = %13
  %79 = load i32, ptr %7, align 4, !tbaa !9
  %80 = load ptr, ptr %5, align 8, !tbaa !5
  %81 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %80, i32 0, i32 0
  %82 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %81, i32 0, i32 9
  %83 = getelementptr inbounds %struct.BrotliDistanceParams, ptr %82, i32 0, i32 1
  store i32 %79, ptr %83, align 4, !tbaa !36
  store i32 1, ptr %4, align 4
  br label %95

84:                                               ; preds = %13
  %85 = load i32, ptr %7, align 4, !tbaa !9
  %86 = icmp ugt i32 %85, 1073741824
  br i1 %86, label %87, label %88

87:                                               ; preds = %84
  store i32 0, ptr %4, align 4
  br label %95

88:                                               ; preds = %84
  %89 = load i32, ptr %7, align 4, !tbaa !9
  %90 = zext i32 %89 to i64
  %91 = load ptr, ptr %5, align 8, !tbaa !5
  %92 = getelementptr inbounds %struct.BrotliEncoderStateStruct, ptr %91, i32 0, i32 0
  %93 = getelementptr inbounds %struct.BrotliEncoderParams, ptr %92, i32 0, i32 4
  store i64 %90, ptr %93, align 8, !tbaa !37
  store i32 1, ptr %4, align 4
  br label %95

94:                                               ; preds = %13
  store i32 0, ptr %4, align 4
  br label %95

95:                                               ; preds = %94, %88, %87, %78, %72, %60, %54, %42, %41, %30, %25, %20, %15, %12
  %96 = load i32, ptr %4, align 4
  ret i32 %96
}

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

!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 = !{!"int", !7, i64 0}
!11 = !{!12, !10, i64 6972}
!12 = !{!"BrotliEncoderStateStruct", !13, i64 0, !23, i64 1400, !14, i64 1424, !24, i64 1432, !14, i64 1472, !6, i64 1480, !14, i64 1488, !14, i64 1496, !14, i64 1504, !14, i64 1512, !14, i64 1520, !7, i64 1528, !7, i64 1592, !25, i64 1608, !7, i64 1610, !7, i64 1611, !7, i64 1612, !7, i64 1613, !14, i64 1616, !6, i64 1624, !26, i64 1632, !7, i64 2768, !6, i64 6864, !14, i64 6872, !6, i64 6880, !6, i64 6888, !6, i64 6896, !6, i64 6904, !14, i64 6912, !6, i64 6920, !14, i64 6928, !14, i64 6936, !7, i64 6944, !10, i64 6960, !10, i64 6964, !10, i64 6968, !10, i64 6972}
!13 = !{!"BrotliEncoderParams", !10, i64 0, !10, i64 4, !10, i64 8, !10, i64 12, !14, i64 16, !14, i64 24, !10, i64 32, !10, i64 36, !15, i64 40, !16, i64 56, !17, i64 80}
!14 = !{!"long", !7, i64 0}
!15 = !{!"BrotliHasherParams", !10, i64 0, !10, i64 4, !10, i64 8, !10, i64 12}
!16 = !{!"BrotliDistanceParams", !10, i64 0, !10, i64 4, !10, i64 8, !10, i64 12, !14, i64 16}
!17 = !{!"SharedEncoderDictionary", !10, i64 0, !18, i64 8, !19, i64 544, !10, i64 1312}
!18 = !{!"CompoundDictionary", !14, i64 0, !14, i64 8, !7, i64 16, !7, i64 144, !7, i64 272, !14, i64 400, !7, i64 408}
!19 = !{!"ContextualEncoderDictionary", !10, i64 0, !7, i64 4, !7, i64 5, !7, i64 72, !14, i64 584, !20, i64 592, !6, i64 760}
!20 = !{!"BrotliEncoderDictionary", !6, i64 0, !10, i64 8, !10, i64 12, !14, i64 16, !6, i64 24, !6, i64 32, !6, i64 40, !6, i64 48, !21, i64 56, !10, i64 96, !6, i64 104, !6, i64 112, !6, i64 120, !14, i64 128, !6, i64 136, !14, i64 144, !6, i64 152, !6, i64 160}
!21 = !{!"BrotliTrie", !6, i64 0, !14, i64 8, !14, i64 16, !22, i64 24}
!22 = !{!"BrotliTrieNode", !7, i64 0, !7, i64 1, !7, i64 2, !10, i64 4, !10, i64 8}
!23 = !{!"MemoryManager", !6, i64 0, !6, i64 8, !6, i64 16}
!24 = !{!"RingBuffer", !10, i64 0, !10, i64 4, !10, i64 8, !10, i64 12, !10, i64 16, !10, i64 20, !6, i64 24, !6, i64 32}
!25 = !{!"short", !7, i64 0}
!26 = !{!"", !27, i64 0, !7, i64 80}
!27 = !{!"", !7, i64 0, !10, i64 32, !14, i64 40, !14, i64 48, !15, i64 56, !10, i64 72}
!28 = !{!12, !10, i64 0}
!29 = !{!12, !10, i64 4}
!30 = !{!12, !10, i64 8}
!31 = !{!12, !10, i64 12}
!32 = !{!12, !10, i64 32}
!33 = !{!12, !14, i64 24}
!34 = !{!12, !10, i64 36}
!35 = !{!12, !10, i64 56}
!36 = !{!12, !10, i64 60}
!37 = !{!12, !14, i64 16}


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

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
define dso_local range(i32 0, 2) i32 @BrotliEncoderSetParameter(ptr nocapture noundef %0, i32 noundef %1, i32 noundef %2) local_unnamed_addr #0 {
  %4 = getelementptr inbounds i8, ptr %0, i64 6972
  %5 = load i32, ptr %4, align 4, !tbaa !5
  %.not = icmp eq i32 %5, 0
  br i1 %.not, label %6, label %32

6:                                                ; preds = %3
  switch i32 %1, label %32 [
    i32 0, label %7
    i32 1, label %8
    i32 2, label %10
    i32 3, label %12
    i32 4, label %14
    i32 5, label %17
    i32 6, label %20
    i32 7, label %23
    i32 8, label %25
    i32 9, label %27
  ]

7:                                                ; preds = %6
  store i32 %2, ptr %0, align 8, !tbaa !26
  br label %32

8:                                                ; preds = %6
  %9 = getelementptr inbounds i8, ptr %0, i64 4
  store i32 %2, ptr %9, align 4, !tbaa !27
  br label %32

10:                                               ; preds = %6
  %11 = getelementptr inbounds i8, ptr %0, i64 8
  store i32 %2, ptr %11, align 8, !tbaa !28
  br label %32

12:                                               ; preds = %6
  %13 = getelementptr inbounds i8, ptr %0, i64 12
  store i32 %2, ptr %13, align 4, !tbaa !29
  br label %32

14:                                               ; preds = %6
  %or.cond = icmp ugt i32 %2, 1
  br i1 %or.cond, label %32, label %15

15:                                               ; preds = %14
  %16 = getelementptr inbounds i8, ptr %0, i64 32
  store i32 %2, ptr %16, align 8, !tbaa !30
  br label %32

17:                                               ; preds = %6
  %18 = zext i32 %2 to i64
  %19 = getelementptr inbounds i8, ptr %0, i64 24
  store i64 %18, ptr %19, align 8, !tbaa !31
  br label %32

20:                                               ; preds = %6
  %.not27 = icmp ne i32 %2, 0
  %21 = zext i1 %.not27 to i32
  %22 = getelementptr inbounds i8, ptr %0, i64 36
  store i32 %21, ptr %22, align 4, !tbaa !32
  br label %32

23:                                               ; preds = %6
  %24 = getelementptr inbounds i8, ptr %0, i64 56
  store i32 %2, ptr %24, align 8, !tbaa !33
  br label %32

25:                                               ; preds = %6
  %26 = getelementptr inbounds i8, ptr %0, i64 60
  store i32 %2, ptr %26, align 4, !tbaa !34
  br label %32

27:                                               ; preds = %6
  %28 = icmp ugt i32 %2, 1073741824
  br i1 %28, label %32, label %29

29:                                               ; preds = %27
  %30 = zext nneg i32 %2 to i64
  %31 = getelementptr inbounds i8, ptr %0, i64 16
  store i64 %30, ptr %31, align 8, !tbaa !35
  br label %32

32:                                               ; preds = %6, %27, %14, %3, %29, %25, %23, %20, %17, %15, %12, %10, %8, %7
  %.0 = phi i32 [ 1, %29 ], [ 1, %25 ], [ 1, %23 ], [ 1, %20 ], [ 1, %17 ], [ 1, %15 ], [ 1, %12 ], [ 1, %10 ], [ 1, %8 ], [ 1, %7 ], [ 0, %3 ], [ 0, %14 ], [ 0, %27 ], [ 0, %6 ]
  ret i32 %.0
}

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

!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, !8, i64 6972}
!6 = !{!"BrotliEncoderStateStruct", !7, i64 0, !21, i64 1400, !11, i64 1424, !22, i64 1432, !11, i64 1472, !18, i64 1480, !11, i64 1488, !11, i64 1496, !11, i64 1504, !11, i64 1512, !11, i64 1520, !9, i64 1528, !9, i64 1592, !23, i64 1608, !9, i64 1610, !9, i64 1611, !9, i64 1612, !9, i64 1613, !11, i64 1616, !18, i64 1624, !24, i64 1632, !9, i64 2768, !18, i64 6864, !11, i64 6872, !18, i64 6880, !18, i64 6888, !18, i64 6896, !18, i64 6904, !11, i64 6912, !18, i64 6920, !11, i64 6928, !11, i64 6936, !9, i64 6944, !8, i64 6960, !8, i64 6964, !8, i64 6968, !8, i64 6972}
!7 = !{!"BrotliEncoderParams", !8, i64 0, !8, i64 4, !8, i64 8, !8, i64 12, !11, i64 16, !11, i64 24, !8, i64 32, !8, i64 36, !12, i64 40, !13, i64 56, !14, i64 80}
!8 = !{!"int", !9, i64 0}
!9 = !{!"omnipotent char", !10, i64 0}
!10 = !{!"Simple C/C++ TBAA"}
!11 = !{!"long", !9, i64 0}
!12 = !{!"BrotliHasherParams", !8, i64 0, !8, i64 4, !8, i64 8, !8, i64 12}
!13 = !{!"BrotliDistanceParams", !8, i64 0, !8, i64 4, !8, i64 8, !8, i64 12, !11, i64 16}
!14 = !{!"SharedEncoderDictionary", !8, i64 0, !15, i64 8, !16, i64 544, !8, i64 1312}
!15 = !{!"CompoundDictionary", !11, i64 0, !11, i64 8, !9, i64 16, !9, i64 144, !9, i64 272, !11, i64 400, !9, i64 408}
!16 = !{!"ContextualEncoderDictionary", !8, i64 0, !9, i64 4, !9, i64 5, !9, i64 72, !11, i64 584, !17, i64 592, !18, i64 760}
!17 = !{!"BrotliEncoderDictionary", !18, i64 0, !8, i64 8, !8, i64 12, !11, i64 16, !18, i64 24, !18, i64 32, !18, i64 40, !18, i64 48, !19, i64 56, !8, i64 96, !18, i64 104, !18, i64 112, !18, i64 120, !11, i64 128, !18, i64 136, !11, i64 144, !18, i64 152, !18, i64 160}
!18 = !{!"any pointer", !9, i64 0}
!19 = !{!"BrotliTrie", !18, i64 0, !11, i64 8, !11, i64 16, !20, i64 24}
!20 = !{!"BrotliTrieNode", !9, i64 0, !9, i64 1, !9, i64 2, !8, i64 4, !8, i64 8}
!21 = !{!"MemoryManager", !18, i64 0, !18, i64 8, !18, i64 16}
!22 = !{!"RingBuffer", !8, i64 0, !8, i64 4, !8, i64 8, !8, i64 12, !8, i64 16, !8, i64 20, !18, i64 24, !18, i64 32}
!23 = !{!"short", !9, i64 0}
!24 = !{!"", !25, i64 0, !9, i64 80}
!25 = !{!"", !9, i64 0, !8, i64 32, !11, i64 40, !11, i64 48, !12, i64 56, !8, i64 72}
!26 = !{!6, !8, i64 0}
!27 = !{!6, !8, i64 4}
!28 = !{!6, !8, i64 8}
!29 = !{!6, !8, i64 12}
!30 = !{!6, !8, i64 32}
!31 = !{!6, !11, i64 24}
!32 = !{!6, !8, i64 36}
!33 = !{!6, !8, i64 56}
!34 = !{!6, !8, i64 60}
!35 = !{!6, !11, i64 16}


; Effective O3 passes: EarlyCSEPass,GlobalOptPass,IPSCCPPass,InstCombinePass,PostOrderFunctionAttrsPass,SROAPass,SimplifyCFGPass