#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int tanf(float);
void tdPerspective(float fovy, float aspect, float zNear, float zFar,
                   float *out) {
  float f = 1. / tanf(fovy * 3.141592653589 / 360.0);
  out[0] = f / aspect;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = f;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = (zFar + zNear) / (zNear - zFar);
  out[11] = 2 * zFar * zNear / (zNear - zFar);
  out[12] = 0;
  out[13] = 0;
  out[14] = -1;
  out[15] = 0;
}


x86 assembly (clang, -O0):
<tdPerspective>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movss  %xmm0,-0x4(%rbp)
movss  %xmm1,-0x8(%rbp)
movss  %xmm2,-0xc(%rbp)
movss  %xmm3,-0x10(%rbp)
mov    %rdi,-0x18(%rbp)
movss  -0x4(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xed7(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xec3(%rip),%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
call   1030 <tanf@plt>
cvtsi2sd %eax,%xmm1
movsd  0xea2(%rip),%xmm0
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0x1c(%rbp),%xmm0
divss  -0x8(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x4(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x8(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0xc(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x10(%rax)
movss  -0x1c(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,0x14(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x18(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x1c(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x20(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x24(%rax)
movss  -0x10(%rbp),%xmm0
addss  -0xc(%rbp),%xmm0
movss  -0xc(%rbp),%xmm1
subss  -0x10(%rbp),%xmm1
divss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,0x28(%rax)
movss  0xde8(%rip),%xmm0
mulss  -0x10(%rbp),%xmm0
mulss  -0xc(%rbp),%xmm0
movss  -0xc(%rbp),%xmm1
subss  -0x10(%rbp),%xmm1
divss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,0x2c(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x30(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x34(%rax)
mov    -0x18(%rbp),%rax
movss  0xd9f(%rip),%xmm0
movss  %xmm0,0x38(%rax)
mov    -0x18(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x3c(%rax)
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<tdPerspective>:
push   %rbx
sub    $0x10,%rsp
mov    %rdi,%rbx
movss  %xmm3,0xc(%rsp)
movss  %xmm2,0x8(%rsp)
movss  %xmm1,0x4(%rsp)
cvtss2sd %xmm0,%xmm0
mulsd  0xeca(%rip),%xmm0
divsd  0xeca(%rip),%xmm0
cvtsd2ss %xmm0,%xmm0
call   1030 <tanf@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  0xeba(%rip),%xmm1
divsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
movaps %xmm0,%xmm1
divss  0x4(%rsp),%xmm1
movss  %xmm1,(%rbx)
xorps  %xmm1,%xmm1
movups %xmm1,0x4(%rbx)
movss  %xmm0,0x14(%rbx)
movss  0x8(%rsp),%xmm4
movaps %xmm4,%xmm0
movss  0xc(%rsp),%xmm3
addss  %xmm3,%xmm0
movaps %xmm4,%xmm2
subss  %xmm3,%xmm2
divss  %xmm2,%xmm0
movups %xmm1,0x18(%rbx)
movss  %xmm0,0x28(%rbx)
addss  %xmm3,%xmm3
mulss  %xmm4,%xmm3
divss  %xmm2,%xmm3
movss  %xmm3,0x2c(%rbx)
movaps 0xe67(%rip),%xmm0
movups %xmm0,0x30(%rbx)
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define void @tdPerspective(float %0, float %1, float %2, float %3, float* %4) {
%6 = alloca float
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float*
%11 = alloca float
store float %0, float* %6
store float %1, float* %7
store float %2, float* %8
store float %3, float* %9
store float* %4, float** %10
%12 = load float, float* %6
%13 = fpext float %12 to double
%14 = fmul double %13, 0x400921FB5444261E
%15 = fdiv double %14, 3.600000e+02
%16 = fptrunc double %15 to float
%17 = call i32 @tanf(float %16)
%18 = sitofp i32 %17 to double
%19 = fdiv double 1.000000e+00, %18
%20 = fptrunc double %19 to float
store float %20, float* %11
%21 = load float, float* %11
%22 = load float, float* %7
%23 = fdiv float %21, %22
%24 = load float*, float** %10
%25 = getelementptr inbounds float, float* %24, i64 0
store float %23, float* %25
%26 = load float*, float** %10
%27 = getelementptr inbounds float, float* %26, i64 1
store float 0.000000e+00, float* %27
%28 = load float*, float** %10
%29 = getelementptr inbounds float, float* %28, i64 2
store float 0.000000e+00, float* %29
%30 = load float*, float** %10
%31 = getelementptr inbounds float, float* %30, i64 3
store float 0.000000e+00, float* %31
%32 = load float*, float** %10
%33 = getelementptr inbounds float, float* %32, i64 4
store float 0.000000e+00, float* %33
%34 = load float, float* %11
%35 = load float*, float** %10
%36 = getelementptr inbounds float, float* %35, i64 5
store float %34, float* %36
%37 = load float*, float** %10
%38 = getelementptr inbounds float, float* %37, i64 6
store float 0.000000e+00, float* %38
%39 = load float*, float** %10
%40 = getelementptr inbounds float, float* %39, i64 7
store float 0.000000e+00, float* %40
%41 = load float*, float** %10
%42 = getelementptr inbounds float, float* %41, i64 8
store float 0.000000e+00, float* %42
%43 = load float*, float** %10
%44 = getelementptr inbounds float, float* %43, i64 9
store float 0.000000e+00, float* %44
%45 = load float, float* %9
%46 = load float, float* %8
%47 = fadd float %45, %46
%48 = load float, float* %8
%49 = load float, float* %9
%50 = fsub float %48, %49
%51 = fdiv float %47, %50
%52 = load float*, float** %10
%53 = getelementptr inbounds float, float* %52, i64 10
store float %51, float* %53
%54 = load float, float* %9
%55 = fmul float 2.000000e+00, %54
%56 = load float, float* %8
%57 = fmul float %55, %56
%58 = load float, float* %8
%59 = load float, float* %9
%60 = fsub float %58, %59
%61 = fdiv float %57, %60
%62 = load float*, float** %10
%63 = getelementptr inbounds float, float* %62, i64 11
store float %61, float* %63
%64 = load float*, float** %10
%65 = getelementptr inbounds float, float* %64, i64 12
store float 0.000000e+00, float* %65
%66 = load float*, float** %10
%67 = getelementptr inbounds float, float* %66, i64 13
store float 0.000000e+00, float* %67
%68 = load float*, float** %10
%69 = getelementptr inbounds float, float* %68, i64 14
store float -1.000000e+00, float* %69
%70 = load float*, float** %10
%71 = getelementptr inbounds float, float* %70, i64 15
store float 0.000000e+00, float* %71
ret void
}

LLVM IR (-O2):
define void @tdPerspective(float %0, float %1, float %2, float %3, float* nocapture writeonly %4) {
%6 = fpext float %0 to double
%7 = fmul double %6, 0x400921FB5444261E
%8 = fdiv double %7, 3.600000e+02
%9 = fptrunc double %8 to float
%10 = tail call i32 @tanf(float %9)
%11 = sitofp i32 %10 to double
%12 = fdiv double 1.000000e+00, %11
%13 = fptrunc double %12 to float
%14 = fdiv float %13, %1
store float %14, float* %4
%15 = getelementptr inbounds float, float* %4, i64 1
%16 = getelementptr inbounds float, float* %4, i64 5
%17 = bitcast float* %15 to i8*
store float %13, float* %16
%18 = getelementptr inbounds float, float* %4, i64 6
%19 = fadd float %2, %3
%20 = fsub float %2, %3
%21 = fdiv float %19, %20
%22 = getelementptr inbounds float, float* %4, i64 10
%23 = bitcast float* %18 to i8*
store float %21, float* %22
%24 = fmul float %3, 2.000000e+00
%25 = fmul float %24, %2
%26 = fdiv float %25, %20
%27 = getelementptr inbounds float, float* %4, i64 11
store float %26, float* %27
%28 = getelementptr inbounds float, float* %4, i64 12
%29 = bitcast float* %28 to <4 x float>*
store <4 x float> <float 0.000000e+00, float 0.000000e+00, float -1.000000e+00, float 0.000000e+00>, <4 x float>* %29
ret void
}