#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 */
struct julian_date {
  int dummy;
};

/* Variables and functions */
double iau2000a_mean_obliquity(struct julian_date *);
int /*<<< orphan*/ iau2000a_nutation(struct julian_date *, double *, double *);
int /*<<< orphan*/ sincos(double, double *, double *);
void iau2000a_nutation_matrix(struct julian_date *tdb,
                              double nut_matrix[3][3]) {
  double epsilon, d_psi, d_epsilon, c1, c2, c3, s1, s2, s3;
  epsilon = iau2000a_mean_obliquity(tdb);
  iau2000a_nutation(tdb, &d_psi, &d_epsilon);
  sincos(epsilon, &s1, &c1);
  sincos(d_psi, &s2, &c2);
  s2 *= -1.0;
  sincos(epsilon + d_epsilon, &s3, &c3);
  s3 *= -1.0;
  nut_matrix[0][0] = (c2);
  nut_matrix[0][1] = (s2 * c1);
  nut_matrix[0][2] = (s2 * s1);
  nut_matrix[1][0] = -(s2 * c3);
  nut_matrix[1][1] = (c3 * c2 * c1) - (s1 * s3);
  nut_matrix[1][2] = (c3 * c2 * s1) + (c1 * s3);
  nut_matrix[2][0] = (s2 * s3);
  nut_matrix[2][1] = -(s3 * c2 * c1) - (s1 * c3);
  nut_matrix[2][2] = -(s3 * c2 * s1) + (c3 * c1);
}


x86 assembly (clang, -O0):
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <iau2000a_mean_obliquity@plt>
movsd  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x20(%rbp),%rsi
lea    -0x28(%rbp),%rdx
call   1050 <iau2000a_nutation@plt>
movsd  -0x18(%rbp),%xmm0
lea    -0x48(%rbp),%rdi
lea    -0x30(%rbp),%rsi
call   1030 <sincos@plt>
movsd  -0x20(%rbp),%xmm0
lea    -0x50(%rbp),%rdi
lea    -0x38(%rbp),%rsi
call   1030 <sincos@plt>
movsd  0xe75(%rip),%xmm0
mulsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x18(%rbp),%xmm0
addsd  -0x28(%rbp),%xmm0
lea    -0x58(%rbp),%rdi
lea    -0x40(%rbp),%rsi
call   1030 <sincos@plt>
movsd  0xe4c(%rip),%xmm0
mulsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x38(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x50(%rbp),%xmm0
mulsd  -0x30(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x50(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x10(%rax)
movsd  -0x50(%rbp),%xmm0
mulsd  -0x40(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x18(%rax)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm2
movsd  -0x48(%rbp),%xmm1
mulsd  -0x58(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x20(%rax)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
mulsd  -0x58(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x28(%rax)
movsd  -0x50(%rbp),%xmm0
mulsd  -0x58(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x30(%rax)
movsd  -0x58(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
mulsd  -0x30(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
movsd  -0x48(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x38(%rax)
movsd  -0x58(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
movsd  -0x40(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x40(%rax)
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
push   %r14
push   %rbx
sub    $0x48,%rsp
mov    %rsi,%r14
mov    %rdi,%rbx
call   1040 <iau2000a_mean_obliquity@plt>
movsd  %xmm0,0x8(%rsp)
lea    0x40(%rsp),%rsi
lea    0x38(%rsp),%rdx
mov    %rbx,%rdi
call   1050 <iau2000a_nutation@plt>
lea    0x18(%rsp),%rdi
lea    0x30(%rsp),%rsi
movsd  0x8(%rsp),%xmm0
call   1030 <sincos@plt>
movsd  0x40(%rsp),%xmm0
mov    %rsp,%rdi
lea    0x28(%rsp),%rsi
call   1030 <sincos@plt>
movsd  (%rsp),%xmm0
xorps  0xe72(%rip),%xmm0
movlps %xmm0,(%rsp)
movsd  0x8(%rsp),%xmm0
addsd  0x38(%rsp),%xmm0
lea    0x10(%rsp),%rdi
lea    0x20(%rsp),%rsi
call   1030 <sincos@plt>
movsd  0x10(%rsp),%xmm0
movapd %xmm0,%xmm1
movapd 0xe40(%rip),%xmm8
xorpd  %xmm8,%xmm1
movsd  0x28(%rsp),%xmm3
movsd  %xmm3,(%r14)
movsd  (%rsp),%xmm6
movsd  0x18(%rsp),%xmm5
movsd  0x30(%rsp),%xmm2
movapd %xmm2,%xmm4
unpcklpd %xmm5,%xmm4
movapd %xmm6,%xmm7
xorpd  %xmm8,%xmm7
xorpd  %xmm5,%xmm8
unpcklpd %xmm1,%xmm5
mulsd  %xmm6,%xmm1
unpcklpd %xmm6,%xmm6
mulpd  %xmm4,%xmm6
movupd %xmm6,0x8(%r14)
movsd  0x20(%rsp),%xmm6
mulsd  %xmm6,%xmm7
movsd  %xmm7,0x18(%r14)
movapd %xmm0,%xmm7
mulsd  %xmm3,%xmm0
mulsd  %xmm6,%xmm3
unpcklpd %xmm2,%xmm7
mulpd  %xmm7,%xmm5
unpcklpd %xmm3,%xmm3
mulpd  %xmm4,%xmm3
addpd  %xmm5,%xmm3
movupd %xmm3,0x20(%r14)
movsd  %xmm1,0x30(%r14)
unpcklpd %xmm0,%xmm0
mulpd  %xmm4,%xmm0
movapd %xmm8,%xmm1
unpcklpd %xmm6,%xmm1
unpcklpd %xmm2,%xmm6
mulpd  %xmm1,%xmm6
addpd  %xmm0,%xmm6
movupd %xmm6,0x38(%r14)
add    $0x48,%rsp
pop    %rbx
pop    %r14
ret

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

LLVM IR (-O2):
%struct.julian_date = type { i32 }
define void @iau2000a_nutation_matrix(%struct.julian_date* %0, [3 x double]* nocapture writeonly %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = bitcast double* %3 to i8*
%12 = bitcast double* %4 to i8*
%13 = bitcast double* %5 to i8*
%14 = bitcast double* %6 to i8*
%15 = bitcast double* %7 to i8*
%16 = bitcast double* %8 to i8*
%17 = bitcast double* %9 to i8*
%18 = bitcast double* %10 to i8*
%19 = tail call double @iau2000a_mean_obliquity(%struct.julian_date* %0)
%20 = call i32 @iau2000a_nutation(%struct.julian_date* %0, double* %3, double* %4)
%21 = call i32 @sincos(double %19, double* %8, double* %5)
%22 = load double, double* %3
%23 = call i32 @sincos(double %22, double* %9, double* %6)
%24 = load double, double* %9
%25 = fneg double %24
store double %25, double* %9
%26 = load double, double* %4
%27 = fadd double %19, %26
%28 = call i32 @sincos(double %27, double* %10, double* %7)
%29 = load double, double* %10
%30 = fneg double %29
%31 = load double, double* %6
%32 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 0, i64 0
store double %31, double* %32
%33 = load double, double* %9
%34 = load double, double* %5
%35 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 0, i64 1
%36 = load double, double* %8
%37 = insertelement <2 x double> poison, double %33, i64 0
%38 = shufflevector <2 x double> %37, <2 x double> poison, <2 x i32> zeroinitializer
%39 = insertelement <2 x double> poison, double %34, i64 0
%40 = insertelement <2 x double> %39, double %36, i64 1
%41 = fmul <2 x double> %38, %40
%42 = bitcast double* %35 to <2 x double>*
store <2 x double> %41, <2 x double>* %42
%43 = load double, double* %7
%44 = fneg double %33
%45 = fmul double %43, %44
%46 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 1, i64 0
store double %45, double* %46
%47 = fmul double %31, %43
%48 = fneg double %36
%49 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 1, i64 1
%50 = insertelement <2 x double> poison, double %29, i64 0
%51 = insertelement <2 x double> %50, double %34, i64 1
%52 = insertelement <2 x double> poison, double %36, i64 0
%53 = insertelement <2 x double> %52, double %30, i64 1
%54 = fmul <2 x double> %51, %53
%55 = insertelement <2 x double> poison, double %47, i64 0
%56 = shufflevector <2 x double> %55, <2 x double> poison, <2 x i32> zeroinitializer
%57 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %56, <2 x double> %40, <2 x double> %54)
%58 = bitcast double* %49 to <2 x double>*
store <2 x double> %57, <2 x double>* %58
%59 = fmul double %33, %30
%60 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 2, i64 0
store double %59, double* %60
%61 = fmul double %29, %31
%62 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 2, i64 1
%63 = insertelement <2 x double> poison, double %61, i64 0
%64 = shufflevector <2 x double> %63, <2 x double> poison, <2 x i32> zeroinitializer
%65 = fmul <2 x double> %64, %40
%66 = insertelement <2 x double> poison, double %48, i64 0
%67 = insertelement <2 x double> %66, double %43, i64 1
%68 = insertelement <2 x double> poison, double %43, i64 0
%69 = insertelement <2 x double> %68, double %34, i64 1
%70 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %67, <2 x double> %69, <2 x double> %65)
%71 = bitcast double* %62 to <2 x double>*
store <2 x double> %70, <2 x double>* %71
ret void
}