; LLVM IR from Mithreindeir/VelocityRaptor :: VelocityRaptor/src (vrRigidBody)

; 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.vrVec2 = type { float, float }
%struct.vrRigidBody = type { %struct.vrVec2, %struct.vrVec2, %struct.vrVec2, %struct.vrVec2, float, float, float, float, %struct.vrCollisionGroup, %struct.vrMaterial, ptr, %struct.vrColor, %struct.vrVec2, %struct.vrOrientedBoundingBox, ptr, i32 }
%struct.vrCollisionGroup = type { i32, i32 }
%struct.vrMaterial = type { float, float, float, float, float, float, float, float }
%struct.vrColor = type { float, float, float }
%struct.vrOrientedBoundingBox = type { %struct.vrVec2, %struct.vrVec2 }

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

declare <2 x float> @vrVect(float noundef, float noundef) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #2

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

declare <2 x float> @vrAdd(<2 x float>, <2 x float>) #1

declare <2 x float> @vrScale(<2 x float>, float noundef) #1

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.fmuladd.f32(float, float, float) #3

; Function Attrs: nounwind uwtable
define dso_local void @vrBodyIntegrateForces(ptr noundef %0, float noundef %1) #4 {
  %3 = alloca ptr, align 8
  %4 = alloca float, align 4
  %5 = alloca %struct.vrVec2, align 4
  %6 = alloca %struct.vrVec2, align 4
  %7 = alloca %struct.vrVec2, align 4
  %8 = alloca %struct.vrVec2, align 4
  store ptr %0, ptr %3, align 8, !tbaa !5
  store float %1, ptr %4, align 4, !tbaa !9
  %9 = load ptr, ptr %3, align 8, !tbaa !5
  %10 = getelementptr inbounds %struct.vrRigidBody, ptr %9, i32 0, i32 1
  call void @llvm.lifetime.start.p0(i64 8, ptr %5) #6
  %11 = load ptr, ptr %3, align 8, !tbaa !5
  %12 = getelementptr inbounds %struct.vrRigidBody, ptr %11, i32 0, i32 1
  %13 = load ptr, ptr %3, align 8, !tbaa !5
  %14 = getelementptr inbounds %struct.vrRigidBody, ptr %13, i32 0, i32 9
  %15 = getelementptr inbounds %struct.vrMaterial, ptr %14, i32 0, i32 6
  %16 = load float, ptr %15, align 8, !tbaa !11
  %17 = fpext float %16 to double
  %18 = fsub double 1.000000e+00, %17
  %19 = load float, ptr %4, align 4, !tbaa !9
  %20 = fpext float %19 to double
  %21 = call double @pow(double noundef %18, double noundef %20) #6
  %22 = fptrunc double %21 to float
  %23 = load <2 x float>, ptr %12, align 8
  %24 = call <2 x float> @vrScale(<2 x float> %23, float noundef %22)
  store <2 x float> %24, ptr %5, align 4
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %10, ptr align 4 %5, i64 8, i1 false), !tbaa.struct !19
  call void @llvm.lifetime.end.p0(i64 8, ptr %5) #6
  %25 = load ptr, ptr %3, align 8, !tbaa !5
  %26 = getelementptr inbounds %struct.vrRigidBody, ptr %25, i32 0, i32 9
  %27 = getelementptr inbounds %struct.vrMaterial, ptr %26, i32 0, i32 7
  %28 = load float, ptr %27, align 4, !tbaa !20
  %29 = fpext float %28 to double
  %30 = fsub double 1.000000e+00, %29
  %31 = load float, ptr %4, align 4, !tbaa !9
  %32 = fpext float %31 to double
  %33 = call double @pow(double noundef %30, double noundef %32) #6
  %34 = load ptr, ptr %3, align 8, !tbaa !5
  %35 = getelementptr inbounds %struct.vrRigidBody, ptr %34, i32 0, i32 5
  %36 = load float, ptr %35, align 4, !tbaa !21
  %37 = fpext float %36 to double
  %38 = fmul double %37, %33
  %39 = fptrunc double %38 to float
  store float %39, ptr %35, align 4, !tbaa !21
  %40 = load ptr, ptr %3, align 8, !tbaa !5
  %41 = getelementptr inbounds %struct.vrRigidBody, ptr %40, i32 0, i32 1
  call void @llvm.lifetime.start.p0(i64 8, ptr %6) #6
  %42 = load ptr, ptr %3, align 8, !tbaa !5
  %43 = getelementptr inbounds %struct.vrRigidBody, ptr %42, i32 0, i32 1
  %44 = load ptr, ptr %3, align 8, !tbaa !5
  %45 = getelementptr inbounds %struct.vrRigidBody, ptr %44, i32 0, i32 2
  %46 = load float, ptr %4, align 4, !tbaa !9
  %47 = load ptr, ptr %3, align 8, !tbaa !5
  %48 = getelementptr inbounds %struct.vrRigidBody, ptr %47, i32 0, i32 9
  %49 = getelementptr inbounds %struct.vrMaterial, ptr %48, i32 0, i32 4
  %50 = load float, ptr %49, align 8, !tbaa !22
  %51 = fmul float %46, %50
  %52 = load <2 x float>, ptr %45, align 8
  %53 = call <2 x float> @vrScale(<2 x float> %52, float noundef %51)
  store <2 x float> %53, ptr %7, align 4
  %54 = load <2 x float>, ptr %43, align 8
  %55 = load <2 x float>, ptr %7, align 4
  %56 = call <2 x float> @vrAdd(<2 x float> %54, <2 x float> %55)
  store <2 x float> %56, ptr %6, align 4
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %41, ptr align 4 %6, i64 8, i1 false), !tbaa.struct !19
  call void @llvm.lifetime.end.p0(i64 8, ptr %6) #6
  %57 = load ptr, ptr %3, align 8, !tbaa !5
  %58 = getelementptr inbounds %struct.vrRigidBody, ptr %57, i32 0, i32 6
  %59 = load float, ptr %58, align 8, !tbaa !23
  %60 = load float, ptr %4, align 4, !tbaa !9
  %61 = load ptr, ptr %3, align 8, !tbaa !5
  %62 = getelementptr inbounds %struct.vrRigidBody, ptr %61, i32 0, i32 5
  %63 = load float, ptr %62, align 4, !tbaa !21
  %64 = call float @llvm.fmuladd.f32(float %59, float %60, float %63)
  store float %64, ptr %62, align 4, !tbaa !21
  %65 = load ptr, ptr %3, align 8, !tbaa !5
  %66 = getelementptr inbounds %struct.vrRigidBody, ptr %65, i32 0, i32 2
  call void @llvm.lifetime.start.p0(i64 8, ptr %8) #6
  %67 = call <2 x float> @vrVect(float noundef 0.000000e+00, float noundef 0.000000e+00)
  store <2 x float> %67, ptr %8, align 4
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %66, ptr align 4 %8, i64 8, i1 false), !tbaa.struct !19
  call void @llvm.lifetime.end.p0(i64 8, ptr %8) #6
  %68 = load ptr, ptr %3, align 8, !tbaa !5
  %69 = getelementptr inbounds %struct.vrRigidBody, ptr %68, i32 0, i32 6
  store float 0.000000e+00, ptr %69, align 8, !tbaa !23
  ret void
}

; Function Attrs: nounwind
declare double @pow(double noundef, double noundef) #5

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 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #4 = { nounwind uwtable "min-legal-vector-width"="64" "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 #5 = { 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 #6 = { 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 = !{!"float", !7, i64 0}
!11 = !{!12, !10, i64 80}
!12 = !{!"vrRigidBody", !13, i64 0, !13, i64 8, !13, i64 16, !13, i64 24, !10, i64 32, !10, i64 36, !10, i64 40, !10, i64 44, !14, i64 48, !16, i64 56, !6, i64 88, !17, i64 96, !13, i64 108, !18, i64 116, !6, i64 136, !15, i64 144}
!13 = !{!"vrVec2", !10, i64 0, !10, i64 4}
!14 = !{!"vrCollisionGroup", !15, i64 0, !15, i64 4}
!15 = !{!"int", !7, i64 0}
!16 = !{!"vrMaterial", !10, i64 0, !10, i64 4, !10, i64 8, !10, i64 12, !10, i64 16, !10, i64 20, !10, i64 24, !10, i64 28}
!17 = !{!"vrColor", !10, i64 0, !10, i64 4, !10, i64 8}
!18 = !{!"vrOrientedBoundingBox", !13, i64 0, !13, i64 8}
!19 = !{i64 0, i64 4, !9, i64 4, i64 4, !9}
!20 = !{!12, !10, i64 84}
!21 = !{!12, !10, i64 36}
!22 = !{!12, !10, i64 72}
!23 = !{!12, !10, i64 40}


; 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 <2 x float> @vrVect(float noundef, float noundef) local_unnamed_addr #0

declare <2 x float> @vrAdd(<2 x float>, <2 x float>) local_unnamed_addr #0

declare <2 x float> @vrScale(<2 x float>, float noundef) local_unnamed_addr #0

; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.fmuladd.f32(float, float, float) #1

; Function Attrs: nounwind uwtable
define dso_local void @vrBodyIntegrateForces(ptr nocapture noundef %0, float noundef %1) local_unnamed_addr #2 {
  %3 = getelementptr inbounds i8, ptr %0, i64 8
  %4 = getelementptr inbounds i8, ptr %0, i64 80
  %5 = load float, ptr %4, align 8, !tbaa !5
  %6 = fpext float %5 to double
  %7 = fsub double 1.000000e+00, %6
  %8 = fpext float %1 to double
  %9 = tail call double @pow(double noundef %7, double noundef %8) #4
  %10 = fptrunc double %9 to float
  %11 = load <2 x float>, ptr %3, align 8
  %12 = tail call <2 x float> @vrScale(<2 x float> %11, float noundef %10) #4
  store <2 x float> %12, ptr %3, align 8
  %13 = getelementptr inbounds i8, ptr %0, i64 84
  %14 = load float, ptr %13, align 4, !tbaa !17
  %15 = fpext float %14 to double
  %16 = fsub double 1.000000e+00, %15
  %17 = tail call double @pow(double noundef %16, double noundef %8) #4
  %18 = getelementptr inbounds i8, ptr %0, i64 36
  %19 = load float, ptr %18, align 4, !tbaa !18
  %20 = fpext float %19 to double
  %21 = fmul double %17, %20
  %22 = fptrunc double %21 to float
  store float %22, ptr %18, align 4, !tbaa !18
  %23 = getelementptr inbounds i8, ptr %0, i64 16
  %24 = getelementptr inbounds i8, ptr %0, i64 72
  %25 = load float, ptr %24, align 8, !tbaa !19
  %26 = fmul float %25, %1
  %27 = load <2 x float>, ptr %23, align 8
  %28 = tail call <2 x float> @vrScale(<2 x float> %27, float noundef %26) #4
  %29 = load <2 x float>, ptr %3, align 8
  %30 = tail call <2 x float> @vrAdd(<2 x float> %29, <2 x float> %28) #4
  store <2 x float> %30, ptr %3, align 8
  %31 = getelementptr inbounds i8, ptr %0, i64 40
  %32 = load float, ptr %31, align 8, !tbaa !20
  %33 = load float, ptr %18, align 4, !tbaa !18
  %34 = tail call float @llvm.fmuladd.f32(float %32, float %1, float %33)
  store float %34, ptr %18, align 4, !tbaa !18
  %35 = tail call <2 x float> @vrVect(float noundef 0.000000e+00, float noundef 0.000000e+00) #4
  store <2 x float> %35, ptr %23, align 8
  store float 0.000000e+00, ptr %31, align 8, !tbaa !20
  ret void
}

; Function Attrs: mustprogress nofree nounwind willreturn memory(write)
declare double @pow(double noundef, double noundef) local_unnamed_addr #3

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 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #2 = { nounwind uwtable "min-legal-vector-width"="64" "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 = { 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 #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, !8, i64 80}
!6 = !{!"vrRigidBody", !7, i64 0, !7, i64 8, !7, i64 16, !7, i64 24, !8, i64 32, !8, i64 36, !8, i64 40, !8, i64 44, !11, i64 48, !13, i64 56, !14, i64 88, !15, i64 96, !7, i64 108, !16, i64 116, !14, i64 136, !12, i64 144}
!7 = !{!"vrVec2", !8, i64 0, !8, i64 4}
!8 = !{!"float", !9, i64 0}
!9 = !{!"omnipotent char", !10, i64 0}
!10 = !{!"Simple C/C++ TBAA"}
!11 = !{!"vrCollisionGroup", !12, i64 0, !12, i64 4}
!12 = !{!"int", !9, i64 0}
!13 = !{!"vrMaterial", !8, i64 0, !8, i64 4, !8, i64 8, !8, i64 12, !8, i64 16, !8, i64 20, !8, i64 24, !8, i64 28}
!14 = !{!"any pointer", !9, i64 0}
!15 = !{!"vrColor", !8, i64 0, !8, i64 4, !8, i64 8}
!16 = !{!"vrOrientedBoundingBox", !7, i64 0, !7, i64 8}
!17 = !{!6, !8, i64 84}
!18 = !{!6, !8, i64 36}
!19 = !{!6, !8, i64 72}
!20 = !{!6, !8, i64 40}


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