#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 */
float cos(float);
int /*<<< orphan*/ finn_vec3_normalize(float *, float *);
int /*<<< orphan*/ memset(float *, int /*<<< orphan*/, int);
float sin(float);
void finn_mat4_rotate(float *mat, float *axis, float rad) {
  float s = sin(rad);
  float c = cos(rad);
  float t = 1 - c;
  finn_vec3_normalize(axis, axis);
  memset(mat, 0, sizeof(float) * 16);
  mat[0] = axis[0] * axis[0] * t + c;
  mat[1] = axis[1] * axis[0] * t + axis[2] * s;
  mat[2] = axis[2] * axis[0] * t - axis[1] * s;
  mat[4] = axis[0] * axis[1] * t - axis[2] * s;
  mat[5] = axis[1] * axis[1] * t + c;
  mat[6] = axis[2] * axis[1] * t + axis[0] * s;
  mat[8] = axis[0] * axis[2] * t + axis[1] * s;
  mat[9] = axis[1] * axis[2] * t - axis[0] * s;
  mat[10] = axis[2] * axis[2] * t + c;
  mat[15] = 1.0f;
}


x86 assembly (clang, -O0):
<finn_mat4_rotate>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movss  %xmm0,-0x14(%rbp)
movss  -0x14(%rbp),%xmm0
call   1050 <sin@plt>
movss  %xmm0,-0x18(%rbp)
movss  -0x14(%rbp),%xmm0
call   1060 <cos@plt>
movss  %xmm0,-0x1c(%rbp)
movss  0xe85(%rip),%xmm0
subss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1030 <finn_vec3_normalize@plt>
mov    -0x8(%rbp),%rdi
xor    %esi,%esi
mov    $0x40,%edx
call   1040 <memset@plt>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  (%rax),%xmm0
movss  -0x20(%rbp),%xmm2
movss  -0x1c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  (%rax),%xmm0
movss  -0x20(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm1
mulss  -0x18(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  (%rax),%xmm0
movss  -0x20(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mulss  -0x18(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x4(%rax),%xmm0
movss  -0x20(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm1
mulss  -0x18(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x10(%rax)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x4(%rax),%xmm0
movss  -0x20(%rbp),%xmm2
movss  -0x1c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x14(%rax)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x4(%rax),%xmm0
movss  -0x20(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm1
mulss  -0x18(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x18(%rax)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x8(%rax),%xmm0
movss  -0x20(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mulss  -0x18(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x20(%rax)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x8(%rax),%xmm0
movss  -0x20(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm1
mulss  -0x18(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x24(%rax)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x8(%rax),%xmm0
movss  -0x20(%rbp),%xmm2
movss  -0x1c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x28(%rax)
mov    -0x8(%rbp),%rax
movss  0xc69(%rip),%xmm0
movss  %xmm0,0x3c(%rax)
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<finn_mat4_rotate>:
push   %r14
push   %rbx
sub    $0x18,%rsp
movss  %xmm0,0xc(%rsp)
mov    %rsi,%rbx
mov    %rdi,%r14
call   1050 <sin@plt>
movss  %xmm0,0x14(%rsp)
movss  0xc(%rsp),%xmm0
call   1060 <cos@plt>
movss  %xmm0,0xc(%rsp)
movss  0xe89(%rip),%xmm1
subss  %xmm0,%xmm1
movss  %xmm1,0x10(%rsp)
mov    %rbx,%rdi
mov    %rbx,%rsi
call   1030 <finn_vec3_normalize@plt>
mov    %r14,%rdi
xor    %esi,%esi
mov    $0x40,%edx
call   1040 <memset@plt>
movss  (%rbx),%xmm0
mulss  %xmm0,%xmm0
movss  0x10(%rsp),%xmm2
mulss  %xmm2,%xmm0
movss  0xc(%rsp),%xmm4
addss  %xmm4,%xmm0
movss  %xmm0,(%r14)
movss  0x4(%rbx),%xmm0
mulss  (%rbx),%xmm0
movss  0x8(%rbx),%xmm1
movss  0x14(%rsp),%xmm3
mulss  %xmm3,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,0x4(%r14)
movss  0x8(%rbx),%xmm0
mulss  (%rbx),%xmm0
movss  0x4(%rbx),%xmm1
mulss  %xmm3,%xmm1
mulss  %xmm2,%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,0x8(%r14)
movss  (%rbx),%xmm0
mulss  0x4(%rbx),%xmm0
movss  0x8(%rbx),%xmm1
mulss  %xmm3,%xmm1
mulss  %xmm2,%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,0x10(%r14)
movss  0x4(%rbx),%xmm0
mulss  %xmm0,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm4,%xmm0
movss  %xmm0,0x14(%r14)
movss  0x8(%rbx),%xmm0
mulss  0x4(%rbx),%xmm0
movss  (%rbx),%xmm1
mulss  %xmm3,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,0x18(%r14)
movss  (%rbx),%xmm0
mulss  0x8(%rbx),%xmm0
movss  0x4(%rbx),%xmm1
mulss  %xmm3,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,0x20(%r14)
movss  0x4(%rbx),%xmm0
mulss  0x8(%rbx),%xmm0
mulss  (%rbx),%xmm3
mulss  %xmm2,%xmm0
subss  %xmm3,%xmm0
movss  %xmm0,0x24(%r14)
movss  0x8(%rbx),%xmm0
mulss  %xmm0,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm4,%xmm0
movss  %xmm0,0x28(%r14)
movl   $0x3f800000,0x3c(%r14)
3f
add    $0x18,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @finn_mat4_rotate(float* %0, float* %1, float %2) {
%4 = alloca float*
%5 = alloca float*
%6 = alloca float
%7 = alloca float
%8 = alloca float
%9 = alloca float
store float* %0, float** %4
store float* %1, float** %5
store float %2, float* %6
%10 = load float, float* %6
%11 = call float @sin(float %10)
store float %11, float* %7
%12 = load float, float* %6
%13 = call float @cos(float %12)
store float %13, float* %8
%14 = load float, float* %8
%15 = fsub float 1.000000e+00, %14
store float %15, float* %9
%16 = load float*, float** %5
%17 = load float*, float** %5
%18 = call i32 @finn_vec3_normalize(float* %16, float* %17)
%19 = load float*, float** %4
%20 = call i32 @memset(float* %19, i32 0, i32 64)
%21 = load float*, float** %5
%22 = getelementptr inbounds float, float* %21, i64 0
%23 = load float, float* %22
%24 = load float*, float** %5
%25 = getelementptr inbounds float, float* %24, i64 0
%26 = load float, float* %25
%27 = fmul float %23, %26
%28 = load float, float* %9
%29 = load float, float* %8
%30 = call float @llvm.fmuladd.f32(float %27, float %28, float %29)
%31 = load float*, float** %4
%32 = getelementptr inbounds float, float* %31, i64 0
store float %30, float* %32
%33 = load float*, float** %5
%34 = getelementptr inbounds float, float* %33, i64 1
%35 = load float, float* %34
%36 = load float*, float** %5
%37 = getelementptr inbounds float, float* %36, i64 0
%38 = load float, float* %37
%39 = fmul float %35, %38
%40 = load float, float* %9
%41 = load float*, float** %5
%42 = getelementptr inbounds float, float* %41, i64 2
%43 = load float, float* %42
%44 = load float, float* %7
%45 = fmul float %43, %44
%46 = call float @llvm.fmuladd.f32(float %39, float %40, float %45)
%47 = load float*, float** %4
%48 = getelementptr inbounds float, float* %47, i64 1
store float %46, float* %48
%49 = load float*, float** %5
%50 = getelementptr inbounds float, float* %49, i64 2
%51 = load float, float* %50
%52 = load float*, float** %5
%53 = getelementptr inbounds float, float* %52, i64 0
%54 = load float, float* %53
%55 = fmul float %51, %54
%56 = load float, float* %9
%57 = load float*, float** %5
%58 = getelementptr inbounds float, float* %57, i64 1
%59 = load float, float* %58
%60 = load float, float* %7
%61 = fmul float %59, %60
%62 = fneg float %61
%63 = call float @llvm.fmuladd.f32(float %55, float %56, float %62)
%64 = load float*, float** %4
%65 = getelementptr inbounds float, float* %64, i64 2
store float %63, float* %65
%66 = load float*, float** %5
%67 = getelementptr inbounds float, float* %66, i64 0
%68 = load float, float* %67
%69 = load float*, float** %5
%70 = getelementptr inbounds float, float* %69, i64 1
%71 = load float, float* %70
%72 = fmul float %68, %71
%73 = load float, float* %9
%74 = load float*, float** %5
%75 = getelementptr inbounds float, float* %74, i64 2
%76 = load float, float* %75
%77 = load float, float* %7
%78 = fmul float %76, %77
%79 = fneg float %78
%80 = call float @llvm.fmuladd.f32(float %72, float %73, float %79)
%81 = load float*, float** %4
%82 = getelementptr inbounds float, float* %81, i64 4
store float %80, float* %82
%83 = load float*, float** %5
%84 = getelementptr inbounds float, float* %83, i64 1
%85 = load float, float* %84
%86 = load float*, float** %5
%87 = getelementptr inbounds float, float* %86, i64 1
%88 = load float, float* %87
%89 = fmul float %85, %88
%90 = load float, float* %9
%91 = load float, float* %8
%92 = call float @llvm.fmuladd.f32(float %89, float %90, float %91)
%93 = load float*, float** %4
%94 = getelementptr inbounds float, float* %93, i64 5
store float %92, float* %94
%95 = load float*, float** %5
%96 = getelementptr inbounds float, float* %95, i64 2
%97 = load float, float* %96
%98 = load float*, float** %5
%99 = getelementptr inbounds float, float* %98, i64 1
%100 = load float, float* %99
%101 = fmul float %97, %100
%102 = load float, float* %9
%103 = load float*, float** %5
%104 = getelementptr inbounds float, float* %103, i64 0
%105 = load float, float* %104
%106 = load float, float* %7
%107 = fmul float %105, %106
%108 = call float @llvm.fmuladd.f32(float %101, float %102, float %107)
%109 = load float*, float** %4
%110 = getelementptr inbounds float, float* %109, i64 6
store float %108, float* %110
%111 = load float*, float** %5
%112 = getelementptr inbounds float, float* %111, i64 0
%113 = load float, float* %112
%114 = load float*, float** %5
%115 = getelementptr inbounds float, float* %114, i64 2
%116 = load float, float* %115
%117 = fmul float %113, %116
%118 = load float, float* %9
%119 = load float*, float** %5
%120 = getelementptr inbounds float, float* %119, i64 1
%121 = load float, float* %120
%122 = load float, float* %7
%123 = fmul float %121, %122
%124 = call float @llvm.fmuladd.f32(float %117, float %118, float %123)
%125 = load float*, float** %4
%126 = getelementptr inbounds float, float* %125, i64 8
store float %124, float* %126
%127 = load float*, float** %5
%128 = getelementptr inbounds float, float* %127, i64 1
%129 = load float, float* %128
%130 = load float*, float** %5
%131 = getelementptr inbounds float, float* %130, i64 2
%132 = load float, float* %131
%133 = fmul float %129, %132
%134 = load float, float* %9
%135 = load float*, float** %5
%136 = getelementptr inbounds float, float* %135, i64 0
%137 = load float, float* %136
%138 = load float, float* %7
%139 = fmul float %137, %138
%140 = fneg float %139
%141 = call float @llvm.fmuladd.f32(float %133, float %134, float %140)
%142 = load float*, float** %4
%143 = getelementptr inbounds float, float* %142, i64 9
store float %141, float* %143
%144 = load float*, float** %5
%145 = getelementptr inbounds float, float* %144, i64 2
%146 = load float, float* %145
%147 = load float*, float** %5
%148 = getelementptr inbounds float, float* %147, i64 2
%149 = load float, float* %148
%150 = fmul float %146, %149
%151 = load float, float* %9
%152 = load float, float* %8
%153 = call float @llvm.fmuladd.f32(float %150, float %151, float %152)
%154 = load float*, float** %4
%155 = getelementptr inbounds float, float* %154, i64 10
store float %153, float* %155
%156 = load float*, float** %4
%157 = getelementptr inbounds float, float* %156, i64 15
store float 1.000000e+00, float* %157
ret void
}

LLVM IR (-O2):
define void @finn_mat4_rotate(float* %0, float* %1, float %2) {
%4 = tail call float @sin(float %2)
%5 = tail call float @cos(float %2)
%6 = fsub float 1.000000e+00, %5
%7 = tail call i32 @finn_vec3_normalize(float* %1, float* %1)
%8 = tail call i32 @memset(float* %0, i32 0, i32 64)
%9 = load float, float* %1
%10 = fmul float %9, %9
%11 = tail call float @llvm.fmuladd.f32(float %10, float %6, float %5)
store float %11, float* %0
%12 = getelementptr inbounds float, float* %1, i64 1
%13 = load float, float* %12
%14 = load float, float* %1
%15 = fmul float %13, %14
%16 = getelementptr inbounds float, float* %1, i64 2
%17 = load float, float* %16
%18 = fmul float %4, %17
%19 = tail call float @llvm.fmuladd.f32(float %15, float %6, float %18)
%20 = getelementptr inbounds float, float* %0, i64 1
store float %19, float* %20
%21 = load float, float* %16
%22 = load float, float* %1
%23 = fmul float %21, %22
%24 = load float, float* %12
%25 = fneg float %24
%26 = fmul float %4, %25
%27 = tail call float @llvm.fmuladd.f32(float %23, float %6, float %26)
%28 = getelementptr inbounds float, float* %0, i64 2
store float %27, float* %28
%29 = load float, float* %1
%30 = load float, float* %12
%31 = fmul float %29, %30
%32 = load float, float* %16
%33 = fneg float %32
%34 = fmul float %4, %33
%35 = tail call float @llvm.fmuladd.f32(float %31, float %6, float %34)
%36 = getelementptr inbounds float, float* %0, i64 4
store float %35, float* %36
%37 = load float, float* %12
%38 = fmul float %37, %37
%39 = tail call float @llvm.fmuladd.f32(float %38, float %6, float %5)
%40 = getelementptr inbounds float, float* %0, i64 5
store float %39, float* %40
%41 = load float, float* %16
%42 = load float, float* %12
%43 = fmul float %41, %42
%44 = load float, float* %1
%45 = fmul float %4, %44
%46 = tail call float @llvm.fmuladd.f32(float %43, float %6, float %45)
%47 = getelementptr inbounds float, float* %0, i64 6
store float %46, float* %47
%48 = load float, float* %1
%49 = load float, float* %16
%50 = fmul float %48, %49
%51 = load float, float* %12
%52 = fmul float %4, %51
%53 = tail call float @llvm.fmuladd.f32(float %50, float %6, float %52)
%54 = getelementptr inbounds float, float* %0, i64 8
store float %53, float* %54
%55 = load float, float* %12
%56 = load float, float* %16
%57 = fmul float %55, %56
%58 = load float, float* %1
%59 = fneg float %58
%60 = fmul float %4, %59
%61 = tail call float @llvm.fmuladd.f32(float %57, float %6, float %60)
%62 = getelementptr inbounds float, float* %0, i64 9
store float %61, float* %62
%63 = load float, float* %16
%64 = fmul float %63, %63
%65 = tail call float @llvm.fmuladd.f32(float %64, float %6, float %5)
%66 = getelementptr inbounds float, float* %0, i64 10
store float %65, float* %66
%67 = getelementptr inbounds float, float* %0, i64 15
store float 1.000000e+00, float* %67
ret void
}