; LLVM IR from FrancesoM/Bisc8FX :: sdk_projects/bisc8_platform/ps7_cortexa9_0/standalone_domain/bsp/ps7_cortexa9_0_ (GetNumOfFreeRegions)

; 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.XMpuConfig = type { i32, i64, i64, i32 }

@Mpu_Config = external dso_local global [16 x %struct.XMpuConfig], section ".bootdata", align 16

; 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 i32 @Xil_GetNumOfFreeRegions() #1 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  call void @llvm.lifetime.start.p0(i64 4, ptr %1) #2
  store i32 0, ptr %1, align 4, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 4, ptr %2) #2
  store i32 0, ptr %2, align 4, !tbaa !5
  br label %3

3:                                                ; preds = %16, %0
  %4 = load i32, ptr %1, align 4, !tbaa !5
  %5 = icmp ult i32 %4, 16
  br i1 %5, label %6, label %19

6:                                                ; preds = %3
  %7 = load i32, ptr %1, align 4, !tbaa !5
  %8 = zext i32 %7 to i64
  %9 = getelementptr inbounds [16 x %struct.XMpuConfig], ptr @Mpu_Config, i64 0, i64 %8
  %10 = getelementptr inbounds %struct.XMpuConfig, ptr %9, i32 0, i32 0
  %11 = load i32, ptr %10, align 16, !tbaa !9
  %12 = icmp eq i32 0, %11
  br i1 %12, label %13, label %16

13:                                               ; preds = %6
  %14 = load i32, ptr %2, align 4, !tbaa !5
  %15 = add nsw i32 %14, 1
  store i32 %15, ptr %2, align 4, !tbaa !5
  br label %16

16:                                               ; preds = %13, %6
  %17 = load i32, ptr %1, align 4, !tbaa !5
  %18 = add i32 %17, 1
  store i32 %18, ptr %1, align 4, !tbaa !5
  br label %3, !llvm.loop !12

19:                                               ; preds = %3
  %20 = load i32, ptr %2, align 4, !tbaa !5
  call void @llvm.lifetime.end.p0(i64 4, ptr %2) #2
  call void @llvm.lifetime.end.p0(i64 4, ptr %1) #2
  ret i32 %20
}

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 = { 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, !6, i64 0}
!10 = !{!"XMpuConfig", !6, i64 0, !11, i64 8, !11, i64 16, !6, i64 24}
!11 = !{!"long", !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"

%struct.XMpuConfig = type { i32, i64, i64, i32 }

@Mpu_Config = external dso_local local_unnamed_addr global [16 x %struct.XMpuConfig], section ".bootdata", align 16

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none) uwtable
define dso_local i32 @Xil_GetNumOfFreeRegions() local_unnamed_addr #0 {
  %1 = load <4 x i32>, ptr @Mpu_Config, align 16
  %2 = shufflevector <4 x i32> %1, <4 x i32> poison, <16 x i32> <i32 0, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
  %3 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 32), align 16, !tbaa !5
  %4 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 64), align 16, !tbaa !5
  %5 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 96), align 16, !tbaa !5
  %6 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 128), align 16, !tbaa !5
  %7 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 160), align 16, !tbaa !5
  %8 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 192), align 16, !tbaa !5
  %9 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 224), align 16, !tbaa !5
  %10 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 256), align 16, !tbaa !5
  %11 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 288), align 16, !tbaa !5
  %12 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 320), align 16, !tbaa !5
  %13 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 352), align 16, !tbaa !5
  %14 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 384), align 16, !tbaa !5
  %15 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 416), align 16, !tbaa !5
  %16 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 448), align 16, !tbaa !5
  %17 = load i32, ptr getelementptr inbounds (i8, ptr @Mpu_Config, i64 480), align 16, !tbaa !5
  %18 = insertelement <16 x i32> %2, i32 %3, i64 1
  %19 = insertelement <16 x i32> %18, i32 %4, i64 2
  %20 = insertelement <16 x i32> %19, i32 %5, i64 3
  %21 = insertelement <16 x i32> %20, i32 %6, i64 4
  %22 = insertelement <16 x i32> %21, i32 %7, i64 5
  %23 = insertelement <16 x i32> %22, i32 %8, i64 6
  %24 = insertelement <16 x i32> %23, i32 %9, i64 7
  %25 = insertelement <16 x i32> %24, i32 %10, i64 8
  %26 = insertelement <16 x i32> %25, i32 %11, i64 9
  %27 = insertelement <16 x i32> %26, i32 %12, i64 10
  %28 = insertelement <16 x i32> %27, i32 %13, i64 11
  %29 = insertelement <16 x i32> %28, i32 %14, i64 12
  %30 = insertelement <16 x i32> %29, i32 %15, i64 13
  %31 = insertelement <16 x i32> %30, i32 %16, i64 14
  %32 = insertelement <16 x i32> %31, i32 %17, i64 15
  %33 = icmp eq <16 x i32> %32, zeroinitializer
  %34 = bitcast <16 x i1> %33 to i16
  %35 = tail call range(i16 0, 17) i16 @llvm.ctpop.i16(i16 %34)
  %36 = zext nneg i16 %35 to i32
  ret i32 %36
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i16 @llvm.ctpop.i16(i16) #1

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none) 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 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

!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, !7, i64 0}
!6 = !{!"XMpuConfig", !7, i64 0, !10, i64 8, !10, i64 16, !7, i64 24}
!7 = !{!"int", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C/C++ TBAA"}
!10 = !{!"long", !8, i64 0}


; Effective O3 passes: EarlyCSEPass,GVNPass,GlobalDCEPass,GlobalOptPass,IPSCCPPass,IndVarSimplifyPass,InferFunctionAttrsPass,InstCombinePass,LCSSAPass,LoopRotatePass,PostOrderFunctionAttrsPass,ReassociatePass,SLPVectorizerPass,SROAPass,SimplifyCFGPass,TailCallElimPass,VectorCombinePass