; LLVM IR from modlfo/AudioEngine :: AudioEngine/JuceLibraryCode/modules/juce_audio_formats/codecs/oggvorbis (fit)

; 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.vorbis_look_floor1 = type { [65 x i32], [65 x i32], [65 x i32], [63 x i32], [63 x i32], i32, i32, i32, ptr, i64, i64, i64 }

; 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

declare ptr @_vorbis_block_alloc(ptr noundef, i64 noundef) #1

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

20:                                               ; preds = %5
  %21 = load ptr, ptr %9, align 8, !tbaa !5
  %22 = icmp ne ptr %21, null
  br i1 %22, label %23, label %78

23:                                               ; preds = %20
  %24 = load ptr, ptr %6, align 8, !tbaa !5
  %25 = load i64, ptr %12, align 8, !tbaa !14
  %26 = mul i64 4, %25
  %27 = call ptr @_vorbis_block_alloc(ptr noundef %24, i64 noundef %26)
  store ptr %27, ptr %13, align 8, !tbaa !5
  store i64 0, ptr %11, align 8, !tbaa !14
  br label %28

28:                                               ; preds = %74, %23
  %29 = load i64, ptr %11, align 8, !tbaa !14
  %30 = load i64, ptr %12, align 8, !tbaa !14
  %31 = icmp slt i64 %29, %30
  br i1 %31, label %32, label %77

32:                                               ; preds = %28
  %33 = load i32, ptr %10, align 4, !tbaa !9
  %34 = sub nsw i32 65536, %33
  %35 = load ptr, ptr %8, align 8, !tbaa !5
  %36 = load i64, ptr %11, align 8, !tbaa !14
  %37 = getelementptr inbounds i32, ptr %35, i64 %36
  %38 = load i32, ptr %37, align 4, !tbaa !9
  %39 = and i32 %38, 32767
  %40 = mul nsw i32 %34, %39
  %41 = load i32, ptr %10, align 4, !tbaa !9
  %42 = load ptr, ptr %9, align 8, !tbaa !5
  %43 = load i64, ptr %11, align 8, !tbaa !14
  %44 = getelementptr inbounds i32, ptr %42, i64 %43
  %45 = load i32, ptr %44, align 4, !tbaa !9
  %46 = and i32 %45, 32767
  %47 = mul nsw i32 %41, %46
  %48 = add nsw i32 %40, %47
  %49 = add nsw i32 %48, 32768
  %50 = ashr i32 %49, 16
  %51 = load ptr, ptr %13, align 8, !tbaa !5
  %52 = load i64, ptr %11, align 8, !tbaa !14
  %53 = getelementptr inbounds i32, ptr %51, i64 %52
  store i32 %50, ptr %53, align 4, !tbaa !9
  %54 = load ptr, ptr %8, align 8, !tbaa !5
  %55 = load i64, ptr %11, align 8, !tbaa !14
  %56 = getelementptr inbounds i32, ptr %54, i64 %55
  %57 = load i32, ptr %56, align 4, !tbaa !9
  %58 = and i32 %57, 32768
  %59 = icmp ne i32 %58, 0
  br i1 %59, label %60, label %73

60:                                               ; preds = %32
  %61 = load ptr, ptr %9, align 8, !tbaa !5
  %62 = load i64, ptr %11, align 8, !tbaa !14
  %63 = getelementptr inbounds i32, ptr %61, i64 %62
  %64 = load i32, ptr %63, align 4, !tbaa !9
  %65 = and i32 %64, 32768
  %66 = icmp ne i32 %65, 0
  br i1 %66, label %67, label %73

67:                                               ; preds = %60
  %68 = load ptr, ptr %13, align 8, !tbaa !5
  %69 = load i64, ptr %11, align 8, !tbaa !14
  %70 = getelementptr inbounds i32, ptr %68, i64 %69
  %71 = load i32, ptr %70, align 4, !tbaa !9
  %72 = or i32 %71, 32768
  store i32 %72, ptr %70, align 4, !tbaa !9
  br label %73

73:                                               ; preds = %67, %60, %32
  br label %74

74:                                               ; preds = %73
  %75 = load i64, ptr %11, align 8, !tbaa !14
  %76 = add nsw i64 %75, 1
  store i64 %76, ptr %11, align 8, !tbaa !14
  br label %28, !llvm.loop !15

77:                                               ; preds = %28
  br label %78

78:                                               ; preds = %77, %20, %5
  %79 = load ptr, ptr %13, align 8, !tbaa !5
  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
  ret ptr %79
}

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 = !{!"int", !7, i64 0}
!11 = !{!12, !10, i64 1284}
!12 = !{!"", !7, i64 0, !7, i64 260, !7, i64 520, !7, i64 780, !7, i64 1032, !10, i64 1284, !10, i64 1288, !10, i64 1292, !6, i64 1296, !13, i64 1304, !13, i64 1312, !13, i64 1320}
!13 = !{!"long", !7, i64 0}
!14 = !{!13, !13, i64 0}
!15 = distinct !{!15, !16}
!16 = !{!"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"

declare ptr @_vorbis_block_alloc(ptr noundef, i64 noundef) local_unnamed_addr #0

; Function Attrs: nounwind uwtable
define dso_local ptr @floor1_interpolate_fit(ptr noundef %0, ptr nocapture noundef readonly %1, ptr noundef readonly %2, ptr noundef readonly %3, i32 noundef %4) local_unnamed_addr #1 {
  %6 = getelementptr inbounds i8, ptr %1, i64 1284
  %7 = load i32, ptr %6, align 4, !tbaa !5
  %8 = sext i32 %7 to i64
  %9 = icmp ne ptr %2, null
  %10 = icmp ne ptr %3, null
  %or.cond = and i1 %9, %10
  br i1 %or.cond, label %11, label %.loopexit

11:                                               ; preds = %5
  %12 = shl nsw i64 %8, 2
  %13 = tail call ptr @_vorbis_block_alloc(ptr noundef %0, i64 noundef %12) #2
  %14 = icmp sgt i32 %7, 0
  br i1 %14, label %.lr.ph, label %.loopexit

.lr.ph:                                           ; preds = %11
  %15 = sub nsw i32 65536, %4
  %min.iters.check = icmp ult i32 %7, 8
  br i1 %min.iters.check, label %scalar.ph.preheader, label %vector.memcheck

vector.memcheck:                                  ; preds = %.lr.ph
  %16 = shl nuw nsw i64 %8, 2
  %scevgep = getelementptr i8, ptr %13, i64 %16
  %scevgep28 = getelementptr i8, ptr %2, i64 %16
  %scevgep29 = getelementptr i8, ptr %3, i64 %16
  %bound0 = icmp ult ptr %13, %scevgep28
  %bound1 = icmp ugt ptr %scevgep, %2
  %found.conflict = and i1 %bound0, %bound1
  %bound030 = icmp ult ptr %13, %scevgep29
  %bound131 = icmp ugt ptr %scevgep, %3
  %found.conflict32 = and i1 %bound030, %bound131
  %conflict.rdx = or i1 %found.conflict, %found.conflict32
  br i1 %conflict.rdx, label %scalar.ph.preheader, label %vector.ph

vector.ph:                                        ; preds = %vector.memcheck
  %n.vec = and i64 %8, 2147483644
  %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %15, i64 0
  %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer
  %broadcast.splatinsert34 = insertelement <4 x i32> poison, i32 %4, i64 0
  %broadcast.splat35 = shufflevector <4 x i32> %broadcast.splatinsert34, <4 x i32> poison, <4 x i32> zeroinitializer
  br label %vector.body

vector.body:                                      ; preds = %pred.store.continue43, %vector.ph
  %index = phi i64 [ 0, %vector.ph ], [ %index.next, %pred.store.continue43 ]
  %17 = getelementptr inbounds i32, ptr %2, i64 %index
  %wide.load = load <4 x i32>, ptr %17, align 4, !tbaa !12, !alias.scope !13
  %18 = and <4 x i32> %wide.load, <i32 32767, i32 32767, i32 32767, i32 32767>
  %19 = mul nsw <4 x i32> %18, %broadcast.splat
  %20 = getelementptr i32, ptr %3, i64 %index
  %wide.load33 = load <4 x i32>, ptr %20, align 4, !tbaa !12, !alias.scope !16
  %21 = and <4 x i32> %wide.load33, <i32 32767, i32 32767, i32 32767, i32 32767>
  %22 = mul nsw <4 x i32> %21, %broadcast.splat35
  %23 = add <4 x i32> %19, <i32 32768, i32 32768, i32 32768, i32 32768>
  %24 = add <4 x i32> %23, %22
  %25 = ashr <4 x i32> %24, <i32 16, i32 16, i32 16, i32 16>
  %26 = getelementptr inbounds i32, ptr %13, i64 %index
  store <4 x i32> %25, ptr %26, align 4, !tbaa !12, !alias.scope !18, !noalias !20
  %wide.load36 = load <4 x i32>, ptr %17, align 4, !tbaa !12, !alias.scope !13
  %27 = and <4 x i32> %wide.load36, <i32 32768, i32 32768, i32 32768, i32 32768>
  %28 = icmp ne <4 x i32> %27, zeroinitializer
  %wide.load37 = load <4 x i32>, ptr %20, align 4, !tbaa !12, !alias.scope !16
  %29 = and <4 x i32> %wide.load37, <i32 32768, i32 32768, i32 32768, i32 32768>
  %30 = icmp ne <4 x i32> %29, zeroinitializer
  %31 = select <4 x i1> %28, <4 x i1> %30, <4 x i1> zeroinitializer
  %32 = extractelement <4 x i1> %31, i64 0
  br i1 %32, label %pred.store.if, label %pred.store.continue

pred.store.if:                                    ; preds = %vector.body
  %33 = getelementptr inbounds i32, ptr %13, i64 %index
  %34 = extractelement <4 x i32> %25, i64 0
  %35 = or i32 %34, 32768
  store i32 %35, ptr %33, align 4, !tbaa !12, !alias.scope !18, !noalias !20
  br label %pred.store.continue

pred.store.continue:                              ; preds = %pred.store.if, %vector.body
  %36 = extractelement <4 x i1> %31, i64 1
  br i1 %36, label %pred.store.if38, label %pred.store.continue39

pred.store.if38:                                  ; preds = %pred.store.continue
  %37 = or disjoint i64 %index, 1
  %38 = getelementptr inbounds i32, ptr %13, i64 %37
  %39 = extractelement <4 x i32> %25, i64 1
  %40 = or i32 %39, 32768
  store i32 %40, ptr %38, align 4, !tbaa !12, !alias.scope !18, !noalias !20
  br label %pred.store.continue39

pred.store.continue39:                            ; preds = %pred.store.if38, %pred.store.continue
  %41 = extractelement <4 x i1> %31, i64 2
  br i1 %41, label %pred.store.if40, label %pred.store.continue41

pred.store.if40:                                  ; preds = %pred.store.continue39
  %42 = or disjoint i64 %index, 2
  %43 = getelementptr inbounds i32, ptr %13, i64 %42
  %44 = extractelement <4 x i32> %25, i64 2
  %45 = or i32 %44, 32768
  store i32 %45, ptr %43, align 4, !tbaa !12, !alias.scope !18, !noalias !20
  br label %pred.store.continue41

pred.store.continue41:                            ; preds = %pred.store.if40, %pred.store.continue39
  %46 = extractelement <4 x i1> %31, i64 3
  br i1 %46, label %pred.store.if42, label %pred.store.continue43

pred.store.if42:                                  ; preds = %pred.store.continue41
  %47 = or disjoint i64 %index, 3
  %48 = getelementptr inbounds i32, ptr %13, i64 %47
  %49 = extractelement <4 x i32> %25, i64 3
  %50 = or i32 %49, 32768
  store i32 %50, ptr %48, align 4, !tbaa !12, !alias.scope !18, !noalias !20
  br label %pred.store.continue43

pred.store.continue43:                            ; preds = %pred.store.if42, %pred.store.continue41
  %index.next = add nuw i64 %index, 4
  %51 = icmp eq i64 %index.next, %n.vec
  br i1 %51, label %middle.block, label %vector.body, !llvm.loop !21

middle.block:                                     ; preds = %pred.store.continue43
  %cmp.n = icmp eq i64 %n.vec, %8
  br i1 %cmp.n, label %.loopexit, label %scalar.ph.preheader

scalar.ph.preheader:                              ; preds = %middle.block, %vector.memcheck, %.lr.ph
  %.02327.ph = phi i64 [ 0, %vector.memcheck ], [ 0, %.lr.ph ], [ %n.vec, %middle.block ]
  br label %scalar.ph

scalar.ph:                                        ; preds = %scalar.ph.preheader, %71
  %.02327 = phi i64 [ %72, %71 ], [ %.02327.ph, %scalar.ph.preheader ]
  %52 = getelementptr inbounds i32, ptr %2, i64 %.02327
  %53 = load i32, ptr %52, align 4, !tbaa !12
  %54 = and i32 %53, 32767
  %55 = mul nsw i32 %54, %15
  %56 = getelementptr inbounds i32, ptr %3, i64 %.02327
  %57 = load i32, ptr %56, align 4, !tbaa !12
  %58 = and i32 %57, 32767
  %59 = mul nsw i32 %58, %4
  %60 = add i32 %55, 32768
  %61 = add i32 %60, %59
  %62 = ashr i32 %61, 16
  %63 = getelementptr inbounds i32, ptr %13, i64 %.02327
  store i32 %62, ptr %63, align 4, !tbaa !12
  %64 = load i32, ptr %52, align 4, !tbaa !12
  %65 = and i32 %64, 32768
  %.not = icmp eq i32 %65, 0
  br i1 %.not, label %71, label %66

66:                                               ; preds = %scalar.ph
  %67 = load i32, ptr %56, align 4, !tbaa !12
  %68 = and i32 %67, 32768
  %.not26 = icmp eq i32 %68, 0
  br i1 %.not26, label %71, label %69

69:                                               ; preds = %66
  %70 = or i32 %62, 32768
  store i32 %70, ptr %63, align 4, !tbaa !12
  br label %71

71:                                               ; preds = %scalar.ph, %66, %69
  %72 = add nuw nsw i64 %.02327, 1
  %exitcond.not = icmp eq i64 %72, %8
  br i1 %exitcond.not, label %.loopexit, label %scalar.ph, !llvm.loop !25

.loopexit:                                        ; preds = %71, %middle.block, %11, %5
  %.0 = phi ptr [ null, %5 ], [ %13, %11 ], [ %13, %middle.block ], [ %13, %71 ]
  ret ptr %.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 = { 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 1284}
!6 = !{!"", !7, i64 0, !7, i64 260, !7, i64 520, !7, i64 780, !7, i64 1032, !9, i64 1284, !9, i64 1288, !9, i64 1292, !10, i64 1296, !11, i64 1304, !11, i64 1312, !11, i64 1320}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}
!9 = !{!"int", !7, i64 0}
!10 = !{!"any pointer", !7, i64 0}
!11 = !{!"long", !7, i64 0}
!12 = !{!9, !9, i64 0}
!13 = !{!14}
!14 = distinct !{!14, !15}
!15 = distinct !{!15, !"LVerDomain"}
!16 = !{!17}
!17 = distinct !{!17, !15}
!18 = !{!19}
!19 = distinct !{!19, !15}
!20 = !{!14, !17}
!21 = distinct !{!21, !22, !23, !24}
!22 = !{!"llvm.loop.mustprogress"}
!23 = !{!"llvm.loop.isvectorized", i32 1}
!24 = !{!"llvm.loop.unroll.runtime.disable"}
!25 = distinct !{!25, !22, !23}


; Effective O3 passes: EarlyCSEPass,GlobalOptPass,IPSCCPPass,IndVarSimplifyPass,InferFunctionAttrsPass,InstCombinePass,JumpThreadingPass,LICMPass,LoopLoadEliminationPass,LoopRotatePass,LoopSimplifyPass,LoopUnrollPass,LoopVectorizePass,PostOrderFunctionAttrsPass,ReassociatePass,SROAPass,SimplifyCFGPass,TailCallElimPass