; LLVM IR from fast-pack/simdcomp :: src (simdcomputil)

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

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

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_loadu_si128(ptr noundef) #1

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_or_si128(<2 x i64> noundef, <2 x i64> 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 i32 @maxbitas32int(<2 x i64> noundef) #2

; Function Attrs: nounwind uwtable
define dso_local i32 @simdmaxbitsd1(i32 noundef %0, ptr noundef %1) #2 {
  %3 = alloca i32, align 4
  %4 = alloca ptr, align 8
  %5 = alloca <2 x i64>, align 16
  %6 = alloca ptr, align 8
  %7 = alloca <2 x i64>, align 16
  %8 = alloca <2 x i64>, align 16
  %9 = alloca <2 x i64>, align 16
  %10 = alloca i32, align 4
  store i32 %0, ptr %3, align 4, !tbaa !5
  store ptr %1, ptr %4, align 8, !tbaa !9
  call void @llvm.lifetime.start.p0(i64 16, ptr %5) #3
  %11 = load i32, ptr %3, align 4, !tbaa !5
  %12 = call <2 x i64> @_mm_set1_epi32(i32 noundef %11)
  store <2 x i64> %12, ptr %5, align 16, !tbaa !11
  call void @llvm.lifetime.start.p0(i64 8, ptr %6) #3
  %13 = load ptr, ptr %4, align 8, !tbaa !9
  store ptr %13, ptr %6, align 8, !tbaa !9
  call void @llvm.lifetime.start.p0(i64 16, ptr %7) #3
  %14 = load ptr, ptr %6, align 8, !tbaa !9
  %15 = call <2 x i64> @_mm_loadu_si128(ptr noundef %14)
  store <2 x i64> %15, ptr %7, align 16, !tbaa !11
  call void @llvm.lifetime.start.p0(i64 16, ptr %8) #3
  %16 = load <2 x i64>, ptr %7, align 16, !tbaa !11
  %17 = load <2 x i64>, ptr %7, align 16, !tbaa !11
  %18 = bitcast <2 x i64> %17 to <16 x i8>
  %19 = shufflevector <16 x i8> zeroinitializer, <16 x i8> %18, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %20 = bitcast <16 x i8> %19 to <2 x i64>
  %21 = load <2 x i64>, ptr %5, align 16, !tbaa !11
  %22 = bitcast <2 x i64> %21 to <16 x i8>
  %23 = shufflevector <16 x i8> %22, <16 x i8> zeroinitializer, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %24 = bitcast <16 x i8> %23 to <2 x i64>
  %25 = call <2 x i64> @_mm_or_si128(<2 x i64> noundef %20, <2 x i64> noundef %24)
  %26 = call <2 x i64> @_mm_sub_epi32(<2 x i64> noundef %16, <2 x i64> noundef %25)
  store <2 x i64> %26, ptr %8, align 16, !tbaa !11
  call void @llvm.lifetime.start.p0(i64 16, ptr %9) #3
  %27 = load <2 x i64>, ptr %7, align 16, !tbaa !11
  store <2 x i64> %27, ptr %9, align 16, !tbaa !11
  call void @llvm.lifetime.start.p0(i64 4, ptr %10) #3
  store i32 1, ptr %10, align 4, !tbaa !5
  br label %28

28:                                               ; preds = %52, %2
  %29 = load i32, ptr %10, align 4, !tbaa !5
  %30 = mul i32 4, %29
  %31 = icmp ult i32 %30, 128
  br i1 %31, label %32, label %55

32:                                               ; preds = %28
  %33 = load ptr, ptr %6, align 8, !tbaa !9
  %34 = load i32, ptr %10, align 4, !tbaa !5
  %35 = zext i32 %34 to i64
  %36 = getelementptr inbounds <2 x i64>, ptr %33, i64 %35
  %37 = call <2 x i64> @_mm_loadu_si128(ptr noundef %36)
  store <2 x i64> %37, ptr %7, align 16, !tbaa !11
  %38 = load <2 x i64>, ptr %8, align 16, !tbaa !11
  %39 = load <2 x i64>, ptr %7, align 16, !tbaa !11
  %40 = load <2 x i64>, ptr %7, align 16, !tbaa !11
  %41 = bitcast <2 x i64> %40 to <16 x i8>
  %42 = shufflevector <16 x i8> zeroinitializer, <16 x i8> %41, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %43 = bitcast <16 x i8> %42 to <2 x i64>
  %44 = load <2 x i64>, ptr %9, align 16, !tbaa !11
  %45 = bitcast <2 x i64> %44 to <16 x i8>
  %46 = shufflevector <16 x i8> %45, <16 x i8> zeroinitializer, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %47 = bitcast <16 x i8> %46 to <2 x i64>
  %48 = call <2 x i64> @_mm_or_si128(<2 x i64> noundef %43, <2 x i64> noundef %47)
  %49 = call <2 x i64> @_mm_sub_epi32(<2 x i64> noundef %39, <2 x i64> noundef %48)
  %50 = call <2 x i64> @_mm_or_si128(<2 x i64> noundef %38, <2 x i64> noundef %49)
  store <2 x i64> %50, ptr %8, align 16, !tbaa !11
  %51 = load <2 x i64>, ptr %7, align 16, !tbaa !11
  store <2 x i64> %51, ptr %9, align 16, !tbaa !11
  br label %52

52:                                               ; preds = %32
  %53 = load i32, ptr %10, align 4, !tbaa !5
  %54 = add i32 %53, 1
  store i32 %54, ptr %10, align 4, !tbaa !5
  br label %28, !llvm.loop !12

55:                                               ; preds = %28
  %56 = load <2 x i64>, ptr %9, align 16, !tbaa !11
  store <2 x i64> %56, ptr %5, align 16, !tbaa !11
  %57 = load <2 x i64>, ptr %8, align 16, !tbaa !11
  %58 = call i32 @maxbitas32int(<2 x i64> noundef %57)
  call void @llvm.lifetime.end.p0(i64 4, ptr %10) #3
  call void @llvm.lifetime.end.p0(i64 16, ptr %9) #3
  call void @llvm.lifetime.end.p0(i64 16, ptr %8) #3
  call void @llvm.lifetime.end.p0(i64 16, ptr %7) #3
  call void @llvm.lifetime.end.p0(i64 8, ptr %6) #3
  call void @llvm.lifetime.end.p0(i64 16, ptr %5) #3
  ret i32 %58
}

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_set1_epi32(i32 noundef) #1

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_sub_epi32(<2 x i64> noundef, <2 x i64> noundef) #1

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { alwaysinline nounwind uwtable "min-legal-vector-width"="128" "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"="128" "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 = !{!"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 = !{!7, !7, i64 0}
!12 = distinct !{!12, !13}
!13 = !{!"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"

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_loadu_si128(ptr noundef) local_unnamed_addr #0

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_or_si128(<2 x i64> noundef, <2 x i64> noundef) local_unnamed_addr #0

; Function Attrs: nounwind uwtable
declare hidden i32 @maxbitas32int(<2 x i64> noundef) local_unnamed_addr #1

; Function Attrs: nounwind uwtable
define dso_local i32 @simdmaxbitsd1(i32 noundef %0, ptr noundef %1) local_unnamed_addr #1 {
  %3 = tail call <2 x i64> @_mm_set1_epi32(i32 noundef %0)
  %4 = tail call <2 x i64> @_mm_loadu_si128(ptr noundef %1)
  %5 = bitcast <2 x i64> %4 to <16 x i8>
  %6 = shufflevector <16 x i8> <i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 0, i8 0, i8 0, i8 0>, <16 x i8> %5, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %7 = bitcast <16 x i8> %6 to <2 x i64>
  %8 = bitcast <2 x i64> %3 to <16 x i8>
  %9 = shufflevector <16 x i8> %8, <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 poison, i8 poison, i8 poison, i8 poison>, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %10 = bitcast <16 x i8> %9 to <2 x i64>
  %11 = tail call <2 x i64> @_mm_or_si128(<2 x i64> noundef %7, <2 x i64> noundef %10)
  %12 = tail call <2 x i64> @_mm_sub_epi32(<2 x i64> noundef %4, <2 x i64> noundef %11)
  br label %13

13:                                               ; preds = %2, %13
  %indvars.iv = phi i64 [ 1, %2 ], [ %indvars.iv.next, %13 ]
  %.01720 = phi <2 x i64> [ %4, %2 ], [ %15, %13 ]
  %.01819 = phi <2 x i64> [ %12, %2 ], [ %24, %13 ]
  %14 = getelementptr inbounds <2 x i64>, ptr %1, i64 %indvars.iv
  %15 = tail call <2 x i64> @_mm_loadu_si128(ptr noundef nonnull %14)
  %16 = bitcast <2 x i64> %15 to <16 x i8>
  %17 = shufflevector <16 x i8> <i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 0, i8 0, i8 0, i8 0>, <16 x i8> %16, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %18 = bitcast <16 x i8> %17 to <2 x i64>
  %19 = bitcast <2 x i64> %.01720 to <16 x i8>
  %20 = shufflevector <16 x i8> %19, <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 poison, i8 poison, i8 poison, i8 poison>, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27>
  %21 = bitcast <16 x i8> %20 to <2 x i64>
  %22 = tail call <2 x i64> @_mm_or_si128(<2 x i64> noundef %18, <2 x i64> noundef %21)
  %23 = tail call <2 x i64> @_mm_sub_epi32(<2 x i64> noundef %15, <2 x i64> noundef %22)
  %24 = tail call <2 x i64> @_mm_or_si128(<2 x i64> noundef %.01819, <2 x i64> noundef %23)
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %exitcond.not = icmp eq i64 %indvars.iv.next, 32
  br i1 %exitcond.not, label %25, label %13, !llvm.loop !5

25:                                               ; preds = %13
  %26 = tail call i32 @maxbitas32int(<2 x i64> noundef %24)
  ret i32 %26
}

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_set1_epi32(i32 noundef) local_unnamed_addr #0

; Function Attrs: alwaysinline nounwind uwtable
declare hidden <2 x i64> @_mm_sub_epi32(<2 x i64> noundef, <2 x i64> noundef) local_unnamed_addr #0

attributes #0 = { alwaysinline nounwind uwtable "min-legal-vector-width"="128" "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"="128" "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 = distinct !{!5, !6}
!6 = !{!"llvm.loop.mustprogress"}


; Effective O3 passes: CorrelatedValuePropagationPass,GVNPass,GlobalOptPass,IndVarSimplifyPass,InferFunctionAttrsPass,InstCombinePass,InstSimplifyPass,LCSSAPass,LoopRotatePass,LoopUnrollPass,SROAPass,SimplifyCFGPass,TailCallElimPass