; LLVM IR from EntityFX/anybench :: src/benchmarks/generic/lloops (lloops)

; 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.Parameters = type { i64, i64, i64, double, [3 x [25 x double]], [3 x [25 x i64]], [3 x [25 x double]], [3 x [25 x double]], [3 x [25 x double]], [25 x i64], [3 x [25 x i64]], [3 x [25 x i64]], double, double, double, i64, i64, i64, [3 x [25 x i64]], i64, i64, i64, i64, i64, i64, double, i64 }

@as2 = external dso_local global %struct.Parameters, 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: nounwind uwtable
define dso_local void @check(i64 noundef %0) #1 {
  %2 = alloca i64, align 8
  %3 = alloca i64, align 8
  %4 = alloca double, align 8
  %5 = alloca double, align 8
  %6 = alloca double, align 8
  %7 = alloca double, align 8
  %8 = alloca double, align 8
  store i64 %0, ptr %2, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 8, ptr %3) #4
  store i64 16, ptr %3, align 8, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 8, ptr %4) #4
  call void @llvm.lifetime.start.p0(i64 8, ptr %5) #4
  call void @llvm.lifetime.start.p0(i64 8, ptr %6) #4
  call void @llvm.lifetime.start.p0(i64 8, ptr %7) #4
  call void @llvm.lifetime.start.p0(i64 8, ptr %8) #4
  %9 = load double, ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 25), align 8, !tbaa !9
  store double %9, ptr %4, align 8, !tbaa !12
  %10 = load i64, ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 23), align 8, !tbaa !13
  %11 = getelementptr inbounds [3 x [25 x double]], ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 4), i64 0, i64 %10
  %12 = load i64, ptr %2, align 8, !tbaa !5
  %13 = getelementptr inbounds [25 x double], ptr %11, i64 0, i64 %12
  %14 = load double, ptr %13, align 8, !tbaa !12
  store double %14, ptr %5, align 8, !tbaa !12
  %15 = load double, ptr %4, align 8, !tbaa !12
  %16 = load double, ptr %5, align 8, !tbaa !12
  %17 = fmul double %15, %16
  %18 = fcmp olt double %17, 0.000000e+00
  br i1 %18, label %19, label %24

19:                                               ; preds = %1
  %20 = load i64, ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 23), align 8, !tbaa !13
  %21 = getelementptr inbounds [3 x [25 x i64]], ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 5), i64 0, i64 %20
  %22 = load i64, ptr %2, align 8, !tbaa !5
  %23 = getelementptr inbounds [25 x i64], ptr %21, i64 0, i64 %22
  store i64 0, ptr %23, align 8, !tbaa !5
  br label %63

24:                                               ; preds = %1
  %25 = load double, ptr %4, align 8, !tbaa !12
  %26 = load double, ptr %5, align 8, !tbaa !12
  %27 = fcmp oeq double %25, %26
  br i1 %27, label %28, label %34

28:                                               ; preds = %24
  %29 = load i64, ptr %3, align 8, !tbaa !5
  %30 = load i64, ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 23), align 8, !tbaa !13
  %31 = getelementptr inbounds [3 x [25 x i64]], ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 5), i64 0, i64 %30
  %32 = load i64, ptr %2, align 8, !tbaa !5
  %33 = getelementptr inbounds [25 x i64], ptr %31, i64 0, i64 %32
  store i64 %29, ptr %33, align 8, !tbaa !5
  br label %62

34:                                               ; preds = %24
  %35 = load double, ptr %4, align 8, !tbaa !12
  %36 = call double @llvm.fabs.f64(double %35)
  store double %36, ptr %4, align 8, !tbaa !12
  %37 = load double, ptr %5, align 8, !tbaa !12
  %38 = call double @llvm.fabs.f64(double %37)
  store double %38, ptr %5, align 8, !tbaa !12
  %39 = load double, ptr %4, align 8, !tbaa !12
  store double %39, ptr %7, align 8, !tbaa !12
  %40 = load double, ptr %5, align 8, !tbaa !12
  store double %40, ptr %8, align 8, !tbaa !12
  %41 = load double, ptr %5, align 8, !tbaa !12
  %42 = load double, ptr %4, align 8, !tbaa !12
  %43 = fcmp olt double %41, %42
  br i1 %43, label %44, label %47

44:                                               ; preds = %34
  %45 = load double, ptr %5, align 8, !tbaa !12
  store double %45, ptr %7, align 8, !tbaa !12
  %46 = load double, ptr %4, align 8, !tbaa !12
  store double %46, ptr %8, align 8, !tbaa !12
  br label %47

47:                                               ; preds = %44, %34
  %48 = load double, ptr %7, align 8, !tbaa !12
  %49 = load double, ptr %8, align 8, !tbaa !12
  %50 = fdiv double %48, %49
  %51 = fsub double 1.000000e+00, %50
  store double %51, ptr %6, align 8, !tbaa !12
  %52 = load double, ptr %6, align 8, !tbaa !12
  %53 = call double @llvm.fabs.f64(double %52)
  %54 = call double @log10(double noundef %53) #4
  %55 = call double @llvm.fabs.f64(double %54)
  %56 = fadd double %55, 5.000000e-01
  %57 = fptosi double %56 to i64
  %58 = load i64, ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 23), align 8, !tbaa !13
  %59 = getelementptr inbounds [3 x [25 x i64]], ptr getelementptr inbounds (%struct.Parameters, ptr @as2, i32 0, i32 5), i64 0, i64 %58
  %60 = load i64, ptr %2, align 8, !tbaa !5
  %61 = getelementptr inbounds [25 x i64], ptr %59, i64 0, i64 %60
  store i64 %57, ptr %61, align 8, !tbaa !5
  br label %62

62:                                               ; preds = %47, %28
  br label %63

63:                                               ; preds = %62, %19
  call void @llvm.lifetime.end.p0(i64 8, ptr %8) #4
  call void @llvm.lifetime.end.p0(i64 8, ptr %7) #4
  call void @llvm.lifetime.end.p0(i64 8, ptr %6) #4
  call void @llvm.lifetime.end.p0(i64 8, ptr %5) #4
  call void @llvm.lifetime.end.p0(i64 8, ptr %4) #4
  call void @llvm.lifetime.end.p0(i64 8, ptr %3) #4
  ret void
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare double @llvm.fabs.f64(double) #2

; Function Attrs: nounwind
declare double @log10(double noundef) #3

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
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 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #3 = { nounwind "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"}
!9 = !{!10, !11, i64 5128}
!10 = !{!"Parameters", !6, i64 0, !6, i64 8, !6, i64 16, !11, i64 24, !7, i64 32, !7, i64 632, !7, i64 1232, !7, i64 1832, !7, i64 2432, !7, i64 3032, !7, i64 3232, !7, i64 3832, !11, i64 4432, !11, i64 4440, !11, i64 4448, !6, i64 4456, !6, i64 4464, !6, i64 4472, !7, i64 4480, !6, i64 5080, !6, i64 5088, !6, i64 5096, !6, i64 5104, !6, i64 5112, !6, i64 5120, !11, i64 5128, !6, i64 5136}
!11 = !{!"double", !7, i64 0}
!12 = !{!11, !11, i64 0}
!13 = !{!10, !6, i64 5112}


; 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.Parameters = type { i64, i64, i64, double, [3 x [25 x double]], [3 x [25 x i64]], [3 x [25 x double]], [3 x [25 x double]], [3 x [25 x double]], [25 x i64], [3 x [25 x i64]], [3 x [25 x i64]], double, double, double, i64, i64, i64, [3 x [25 x i64]], i64, i64, i64, i64, i64, i64, double, i64 }

@as2 = external dso_local local_unnamed_addr global %struct.Parameters, align 8

; Function Attrs: mustprogress nofree nounwind willreturn memory(readwrite, argmem: write, inaccessiblemem: write) uwtable
define dso_local void @check(i64 noundef %0) local_unnamed_addr #0 {
  %2 = load double, ptr getelementptr inbounds (i8, ptr @as2, i64 5128), align 8, !tbaa !5
  %3 = load i64, ptr getelementptr inbounds (i8, ptr @as2, i64 5112), align 8, !tbaa !11
  %4 = getelementptr inbounds [3 x [25 x double]], ptr getelementptr inbounds (i8, ptr @as2, i64 32), i64 0, i64 %3, i64 %0
  %5 = load double, ptr %4, align 8, !tbaa !12
  %6 = fmul double %2, %5
  %7 = fcmp olt double %6, 0.000000e+00
  br i1 %7, label %22, label %8

8:                                                ; preds = %1
  %9 = fcmp oeq double %2, %5
  br i1 %9, label %22, label %10

10:                                               ; preds = %8
  %11 = tail call double @llvm.fabs.f64(double %2)
  %12 = tail call double @llvm.fabs.f64(double %5)
  %13 = fcmp olt double %12, %11
  %.019 = select i1 %13, double %12, double %11
  %.0 = select i1 %13, double %11, double %12
  %14 = fdiv double %.019, %.0
  %15 = fsub double 1.000000e+00, %14
  %16 = tail call double @llvm.fabs.f64(double %15)
  %17 = tail call double @log10(double noundef %16) #3
  %18 = tail call double @llvm.fabs.f64(double %17)
  %19 = fadd double %18, 5.000000e-01
  %20 = fptosi double %19 to i64
  %21 = load i64, ptr getelementptr inbounds (i8, ptr @as2, i64 5112), align 8, !tbaa !11
  br label %22

22:                                               ; preds = %8, %1, %10
  %.sink26 = phi i64 [ %21, %10 ], [ %3, %1 ], [ %3, %8 ]
  %.sink = phi i64 [ %20, %10 ], [ 0, %1 ], [ 16, %8 ]
  %23 = getelementptr inbounds [3 x [25 x i64]], ptr getelementptr inbounds (i8, ptr @as2, i64 632), i64 0, i64 %.sink26, i64 %0
  store i64 %.sink, ptr %23, align 8, !tbaa !13
  ret void
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare double @llvm.fabs.f64(double) #1

; Function Attrs: mustprogress nofree nounwind willreturn memory(write)
declare double @log10(double noundef) local_unnamed_addr #2

attributes #0 = { mustprogress nofree nounwind willreturn memory(readwrite, argmem: write, inaccessiblemem: write) 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 #1 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #2 = { mustprogress nofree nounwind willreturn memory(write) "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, !10, i64 5128}
!6 = !{!"Parameters", !7, i64 0, !7, i64 8, !7, i64 16, !10, i64 24, !8, i64 32, !8, i64 632, !8, i64 1232, !8, i64 1832, !8, i64 2432, !8, i64 3032, !8, i64 3232, !8, i64 3832, !10, i64 4432, !10, i64 4440, !10, i64 4448, !7, i64 4456, !7, i64 4464, !7, i64 4472, !8, i64 4480, !7, i64 5080, !7, i64 5088, !7, i64 5096, !7, i64 5104, !7, i64 5112, !7, i64 5120, !10, i64 5128, !7, i64 5136}
!7 = !{!"long", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C/C++ TBAA"}
!10 = !{!"double", !8, i64 0}
!11 = !{!6, !7, i64 5112}
!12 = !{!10, !10, i64 0}
!13 = !{!7, !7, i64 0}


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