#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 */
double cos(float);
double sin(float);
void abgtomat(float *r, float alpha, float beta, float gamma) {
  double ca = cos(alpha), cb = cos(beta), cg = cos(gamma);
  double sa = sin(alpha), sb = sin(beta), sg = sin(gamma);
  r[0] = cg * ca - sg * cb * sa;
  r[1] = sg * ca + cg * cb * sa;
  r[2] = sb * sa;
  r[3] = -cg * sa - sg * cb * ca;
  r[4] = -sg * sa + cg * cb * ca;
  r[5] = sb * ca;
  r[6] = sg * sb;
  r[7] = -cg * sb;
  r[8] = cb;
}


x86 assembly (clang, -O0):
<abgtomat>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
movss  %xmm0,-0xc(%rbp)
movss  %xmm1,-0x10(%rbp)
movss  %xmm2,-0x14(%rbp)
movss  -0xc(%rbp),%xmm0
call   1040 <cos@plt>
movsd  %xmm0,-0x20(%rbp)
movss  -0x10(%rbp),%xmm0
call   1040 <cos@plt>
movsd  %xmm0,-0x28(%rbp)
movss  -0x14(%rbp),%xmm0
call   1040 <cos@plt>
movsd  %xmm0,-0x30(%rbp)
movss  -0xc(%rbp),%xmm0
call   1030 <sin@plt>
movsd  %xmm0,-0x38(%rbp)
movss  -0x10(%rbp),%xmm0
call   1030 <sin@plt>
movsd  %xmm0,-0x40(%rbp)
movss  -0x14(%rbp),%xmm0
call   1030 <sin@plt>
movsd  %xmm0,-0x48(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
movsd  -0x48(%rbp),%xmm1
mulsd  -0x28(%rbp),%xmm1
mulsd  -0x38(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movsd  -0x48(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
mulsd  -0x28(%rbp),%xmm1
mulsd  -0x38(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
movsd  -0x30(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  -0x48(%rbp),%xmm1
mulsd  -0x28(%rbp),%xmm1
mulsd  -0x20(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0xc(%rax)
movsd  -0x48(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
mulsd  -0x28(%rbp),%xmm1
mulsd  -0x20(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x10(%rax)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x14(%rax)
movsd  -0x48(%rbp),%xmm0
mulsd  -0x40(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x18(%rax)
movsd  -0x30(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x40(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x1c(%rax)
movsd  -0x28(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x20(%rax)
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<abgtomat>:
push   %rbx
sub    $0x60,%rsp
movss  %xmm2,0xc(%rsp)
movss  %xmm1,0x10(%rsp)
movss  %xmm0,0x20(%rsp)
mov    %rdi,%rbx
call   1040 <cos@plt>
movaps %xmm0,0x50(%rsp)
movss  0x10(%rsp),%xmm0
call   1040 <cos@plt>
movaps %xmm0,0x40(%rsp)
movss  0xc(%rsp),%xmm0
call   1040 <cos@plt>
movaps %xmm0,0x30(%rsp)
movss  0x20(%rsp),%xmm0
call   1030 <sin@plt>
movaps %xmm0,0x20(%rsp)
movss  0x10(%rsp),%xmm0
call   1030 <sin@plt>
movaps %xmm0,0x10(%rsp)
movss  0xc(%rsp),%xmm0
call   1030 <sin@plt>
movapd 0xe68(%rip),%xmm10
movapd %xmm0,%xmm1
xorpd  %xmm10,%xmm1
movapd 0x40(%rsp),%xmm8
movapd %xmm8,%xmm3
unpcklpd %xmm8,%xmm3
movapd 0x30(%rsp),%xmm2
unpcklpd %xmm2,%xmm1
mulpd  %xmm3,%xmm1
movapd 0x20(%rsp),%xmm6
movapd %xmm6,%xmm3
unpcklpd %xmm6,%xmm3
mulpd  %xmm1,%xmm3
movapd %xmm2,%xmm4
unpcklpd %xmm0,%xmm4
movapd 0x50(%rsp),%xmm7
movapd %xmm7,%xmm5
unpcklpd %xmm7,%xmm5
mulpd  %xmm4,%xmm5
addpd  %xmm3,%xmm5
movapd %xmm6,%xmm3
movapd 0x10(%rsp),%xmm9
mulsd  %xmm9,%xmm3
xorpd  %xmm2,%xmm10
movapd %xmm7,%xmm4
mulsd  %xmm1,%xmm4
mulsd  %xmm6,%xmm2
subsd  %xmm2,%xmm4
unpcklpd %xmm4,%xmm3
cvtpd2ps %xmm5,%xmm4
cvtpd2ps %xmm3,%xmm3
unpcklpd %xmm3,%xmm4
movupd %xmm4,(%rbx)
unpckhpd %xmm1,%xmm1
movapd %xmm7,%xmm3
mulsd  %xmm7,%xmm1
mulsd  %xmm0,%xmm6
subsd  %xmm6,%xmm1
movapd %xmm9,%xmm4
mulsd  %xmm9,%xmm3
unpcklpd %xmm3,%xmm1
unpcklpd %xmm9,%xmm4
unpcklpd %xmm10,%xmm0
cvtpd2ps %xmm1,%xmm1
mulpd  %xmm4,%xmm0
cvtpd2ps %xmm0,%xmm0
unpcklpd %xmm0,%xmm1
movupd %xmm1,0x10(%rbx)
xorps  %xmm0,%xmm0
cvtsd2ss %xmm8,%xmm0
movss  %xmm0,0x20(%rbx)
add    $0x60,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define void @abgtomat(float* %0, float %1, float %2, float %3) {
%5 = alloca float*
%6 = alloca float
%7 = alloca float
%8 = alloca float
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
store float* %0, float** %5
store float %1, float* %6
store float %2, float* %7
store float %3, float* %8
%15 = load float, float* %6
%16 = call double @cos(float %15)
store double %16, double* %9
%17 = load float, float* %7
%18 = call double @cos(float %17)
store double %18, double* %10
%19 = load float, float* %8
%20 = call double @cos(float %19)
store double %20, double* %11
%21 = load float, float* %6
%22 = call double @sin(float %21)
store double %22, double* %12
%23 = load float, float* %7
%24 = call double @sin(float %23)
store double %24, double* %13
%25 = load float, float* %8
%26 = call double @sin(float %25)
store double %26, double* %14
%27 = load double, double* %11
%28 = load double, double* %9
%29 = load double, double* %14
%30 = load double, double* %10
%31 = fmul double %29, %30
%32 = load double, double* %12
%33 = fmul double %31, %32
%34 = fneg double %33
%35 = call double @llvm.fmuladd.f64(double %27, double %28, double %34)
%36 = fptrunc double %35 to float
%37 = load float*, float** %5
%38 = getelementptr inbounds float, float* %37, i64 0
store float %36, float* %38
%39 = load double, double* %14
%40 = load double, double* %9
%41 = load double, double* %11
%42 = load double, double* %10
%43 = fmul double %41, %42
%44 = load double, double* %12
%45 = fmul double %43, %44
%46 = call double @llvm.fmuladd.f64(double %39, double %40, double %45)
%47 = fptrunc double %46 to float
%48 = load float*, float** %5
%49 = getelementptr inbounds float, float* %48, i64 1
store float %47, float* %49
%50 = load double, double* %13
%51 = load double, double* %12
%52 = fmul double %50, %51
%53 = fptrunc double %52 to float
%54 = load float*, float** %5
%55 = getelementptr inbounds float, float* %54, i64 2
store float %53, float* %55
%56 = load double, double* %11
%57 = fneg double %56
%58 = load double, double* %12
%59 = load double, double* %14
%60 = load double, double* %10
%61 = fmul double %59, %60
%62 = load double, double* %9
%63 = fmul double %61, %62
%64 = fneg double %63
%65 = call double @llvm.fmuladd.f64(double %57, double %58, double %64)
%66 = fptrunc double %65 to float
%67 = load float*, float** %5
%68 = getelementptr inbounds float, float* %67, i64 3
store float %66, float* %68
%69 = load double, double* %14
%70 = fneg double %69
%71 = load double, double* %12
%72 = load double, double* %11
%73 = load double, double* %10
%74 = fmul double %72, %73
%75 = load double, double* %9
%76 = fmul double %74, %75
%77 = call double @llvm.fmuladd.f64(double %70, double %71, double %76)
%78 = fptrunc double %77 to float
%79 = load float*, float** %5
%80 = getelementptr inbounds float, float* %79, i64 4
store float %78, float* %80
%81 = load double, double* %13
%82 = load double, double* %9
%83 = fmul double %81, %82
%84 = fptrunc double %83 to float
%85 = load float*, float** %5
%86 = getelementptr inbounds float, float* %85, i64 5
store float %84, float* %86
%87 = load double, double* %14
%88 = load double, double* %13
%89 = fmul double %87, %88
%90 = fptrunc double %89 to float
%91 = load float*, float** %5
%92 = getelementptr inbounds float, float* %91, i64 6
store float %90, float* %92
%93 = load double, double* %11
%94 = fneg double %93
%95 = load double, double* %13
%96 = fmul double %94, %95
%97 = fptrunc double %96 to float
%98 = load float*, float** %5
%99 = getelementptr inbounds float, float* %98, i64 7
store float %97, float* %99
%100 = load double, double* %10
%101 = fptrunc double %100 to float
%102 = load float*, float** %5
%103 = getelementptr inbounds float, float* %102, i64 8
store float %101, float* %103
ret void
}

LLVM IR (-O2):
define void @abgtomat(float* nocapture writeonly %0, float %1, float %2, float %3) {
%5 = tail call double @cos(float %1)
%6 = tail call double @cos(float %2)
%7 = tail call double @cos(float %3)
%8 = tail call double @sin(float %1)
%9 = tail call double @sin(float %2)
%10 = tail call double @sin(float %3)
%11 = fneg double %10
%12 = insertelement <2 x double> poison, double %6, i64 0
%13 = shufflevector <2 x double> %12, <2 x double> poison, <2 x i32> zeroinitializer
%14 = insertelement <2 x double> poison, double %11, i64 0
%15 = insertelement <2 x double> %14, double %7, i64 1
%16 = fmul <2 x double> %13, %15
%17 = insertelement <2 x double> poison, double %8, i64 0
%18 = shufflevector <2 x double> %17, <2 x double> poison, <2 x i32> zeroinitializer
%19 = fmul <2 x double> %18, %16
%20 = insertelement <2 x double> poison, double %7, i64 0
%21 = insertelement <2 x double> %20, double %10, i64 1
%22 = insertelement <2 x double> poison, double %5, i64 0
%23 = shufflevector <2 x double> %22, <2 x double> poison, <2 x i32> zeroinitializer
%24 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %21, <2 x double> %23, <2 x double> %19)
%25 = fmul double %8, %9
%26 = fneg double %7
%27 = extractelement <2 x double> %16, i64 0
%28 = fmul double %5, %27
%29 = tail call double @llvm.fmuladd.f64(double %26, double %8, double %28)
%30 = shufflevector <2 x double> %24, <2 x double> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%31 = insertelement <4 x double> %30, double %25, i64 2
%32 = insertelement <4 x double> %31, double %29, i64 3
%33 = fptrunc <4 x double> %32 to <4 x float>
%34 = bitcast float* %0 to <4 x float>*
store <4 x float> %33, <4 x float>* %34
%35 = extractelement <2 x double> %16, i64 1
%36 = fmul double %5, %35
%37 = tail call double @llvm.fmuladd.f64(double %11, double %8, double %36)
%38 = getelementptr inbounds float, float* %0, i64 4
%39 = fmul double %5, %9
%40 = insertelement <2 x double> poison, double %9, i64 0
%41 = shufflevector <2 x double> %40, <2 x double> poison, <2 x i32> zeroinitializer
%42 = insertelement <2 x double> poison, double %10, i64 0
%43 = insertelement <2 x double> %42, double %26, i64 1
%44 = fmul <2 x double> %41, %43
%45 = insertelement <4 x double> poison, double %37, i64 0
%46 = insertelement <4 x double> %45, double %39, i64 1
%47 = shufflevector <2 x double> %44, <2 x double> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%48 = shufflevector <4 x double> %46, <4 x double> %47, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
%49 = fptrunc <4 x double> %48 to <4 x float>
%50 = bitcast float* %38 to <4 x float>*
store <4 x float> %49, <4 x float>* %50
%51 = fptrunc double %6 to float
%52 = getelementptr inbounds float, float* %0, i64 8
store float %51, float* %52
ret void
}