#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 M_PI;
double acos(double);
double matCalcDot(double *, double *);
double matCalcLen(double *);
float matfCalcAngle(float *v1, float *v2, float *v3, float *v4) {
  double d1[3], d2[3], l1, l2, r;
  d1[0] = (double)(v1[0] - v2[0]);
  d1[1] = (double)(v1[1] - v2[1]);
  d1[2] = (double)(v1[2] - v2[2]);
  d2[0] = (double)(v3[0] - v4[0]);
  d2[1] = (double)(v3[1] - v4[1]);
  d2[2] = (double)(v3[2] - v4[2]);
  l1 = matCalcLen(d1);
  l2 = matCalcLen(d2);
  if (l1 == 0.0 || l2 == 0.0) {
    return 0.0;
  }
  r = acos(matCalcDot(d1, d2) / (l1 * l2));
  return (float)(r * 180.0 / M_PI);
}


x86 assembly (clang, -O0):
<matfCalcAngle>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
subss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
subss  0x4(%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
subss  0x8(%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x28(%rbp),%rax
subss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x20(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x28(%rbp),%rax
subss  0x4(%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x20(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x28(%rbp),%rax
subss  0x8(%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
lea    -0x40(%rbp),%rdi
call   1030 <matCalcLen@plt>
movsd  %xmm0,-0x68(%rbp)
lea    -0x60(%rbp),%rdi
call   1030 <matCalcLen@plt>
movsd  %xmm0,-0x70(%rbp)
movsd  -0x68(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1222 <matfCalcAngle+0xf2>
jp     1222 <matfCalcAngle+0xf2>
jmp    123a <matfCalcAngle+0x10a>
movsd  -0x70(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1247 <matfCalcAngle+0x117>
jp     1247 <matfCalcAngle+0x117>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    128d <matfCalcAngle+0x15d>
lea    -0x40(%rbp),%rdi
lea    -0x60(%rbp),%rsi
call   1050 <matCalcDot@plt>
movsd  -0x68(%rbp),%xmm1
mulsd  -0x70(%rbp),%xmm1
divsd  %xmm1,%xmm0
call   1040 <acos@plt>
movsd  %xmm0,-0x78(%rbp)
movsd  0xd8c(%rip),%xmm0
mulsd  -0x78(%rbp),%xmm0
mov    0x2d68(%rip),%rax
divsd  (%rax),%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<matfCalcAngle>:
sub    $0x48,%rsp
movsd  (%rdi),%xmm0
movsd  (%rsi),%xmm1
subps  %xmm1,%xmm0
cvtps2pd %xmm0,%xmm0
movaps %xmm0,0x30(%rsp)
movss  0x8(%rdi),%xmm0
subss  0x8(%rsi),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,0x40(%rsp)
movsd  (%rdx),%xmm0
movsd  (%rcx),%xmm1
subps  %xmm1,%xmm0
cvtps2pd %xmm0,%xmm0
movaps %xmm0,0x10(%rsp)
movss  0x8(%rdx),%xmm0
subss  0x8(%rcx),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,0x20(%rsp)
lea    0x30(%rsp),%rdi
call   1030 <matCalcLen@plt>
movsd  %xmm0,(%rsp)
lea    0x10(%rsp),%rdi
call   1030 <matCalcLen@plt>
movaps %xmm0,%xmm2
xorps  %xmm1,%xmm1
movsd  (%rsp),%xmm0
ucomisd %xmm1,%xmm0
xorpd  %xmm0,%xmm0
jne    11b2 <matfCalcAngle+0x82>
jnp    11fa <matfCalcAngle+0xca>
ucomisd %xmm1,%xmm2
jne    11ba <matfCalcAngle+0x8a>
jnp    11fa <matfCalcAngle+0xca>
lea    0x30(%rsp),%rdi
lea    0x10(%rsp),%rsi
movsd  %xmm2,0x8(%rsp)
call   1050 <matCalcDot@plt>
movsd  (%rsp),%xmm1
mulsd  0x8(%rsp),%xmm1
divsd  %xmm1,%xmm0
call   1040 <acos@plt>
mulsd  0xe15(%rip),%xmm0
mov    0x2df6(%rip),%rax
divsd  (%rax),%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x48,%rsp
ret

LLVM IR (-O0):
@M_PI = global double 0.000000e+00
define float @matfCalcAngle(float* %0, float* %1, float* %2, float* %3) {
%5 = alloca float
%6 = alloca float*
%7 = alloca float*
%8 = alloca float*
%9 = alloca float*
%10 = alloca [3 x double]
%11 = alloca [3 x double]
%12 = alloca double
%13 = alloca double
%14 = alloca double
store float* %0, float** %6
store float* %1, float** %7
store float* %2, float** %8
store float* %3, float** %9
%15 = load float*, float** %6
%16 = getelementptr inbounds float, float* %15, i64 0
%17 = load float, float* %16
%18 = load float*, float** %7
%19 = getelementptr inbounds float, float* %18, i64 0
%20 = load float, float* %19
%21 = fsub float %17, %20
%22 = fpext float %21 to double
%23 = getelementptr inbounds [3 x double], [3 x double]* %10, i64 0, i64 0
store double %22, double* %23
%24 = load float*, float** %6
%25 = getelementptr inbounds float, float* %24, i64 1
%26 = load float, float* %25
%27 = load float*, float** %7
%28 = getelementptr inbounds float, float* %27, i64 1
%29 = load float, float* %28
%30 = fsub float %26, %29
%31 = fpext float %30 to double
%32 = getelementptr inbounds [3 x double], [3 x double]* %10, i64 0, i64 1
store double %31, double* %32
%33 = load float*, float** %6
%34 = getelementptr inbounds float, float* %33, i64 2
%35 = load float, float* %34
%36 = load float*, float** %7
%37 = getelementptr inbounds float, float* %36, i64 2
%38 = load float, float* %37
%39 = fsub float %35, %38
%40 = fpext float %39 to double
%41 = getelementptr inbounds [3 x double], [3 x double]* %10, i64 0, i64 2
store double %40, double* %41
%42 = load float*, float** %8
%43 = getelementptr inbounds float, float* %42, i64 0
%44 = load float, float* %43
%45 = load float*, float** %9
%46 = getelementptr inbounds float, float* %45, i64 0
%47 = load float, float* %46
%48 = fsub float %44, %47
%49 = fpext float %48 to double
%50 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
store double %49, double* %50
%51 = load float*, float** %8
%52 = getelementptr inbounds float, float* %51, i64 1
%53 = load float, float* %52
%54 = load float*, float** %9
%55 = getelementptr inbounds float, float* %54, i64 1
%56 = load float, float* %55
%57 = fsub float %53, %56
%58 = fpext float %57 to double
%59 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 1
store double %58, double* %59
%60 = load float*, float** %8
%61 = getelementptr inbounds float, float* %60, i64 2
%62 = load float, float* %61
%63 = load float*, float** %9
%64 = getelementptr inbounds float, float* %63, i64 2
%65 = load float, float* %64
%66 = fsub float %62, %65
%67 = fpext float %66 to double
%68 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 2
store double %67, double* %68
%69 = getelementptr inbounds [3 x double], [3 x double]* %10, i64 0, i64 0
%70 = call double @matCalcLen(double* %69)
store double %70, double* %12
%71 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%72 = call double @matCalcLen(double* %71)
store double %72, double* %13
%73 = load double, double* %12
%74 = fcmp oeq double %73, 0.000000e+00
br i1 %74, label %78, label %75
75: ; preds = %4
%76 = load double, double* %13
%77 = fcmp oeq double %76, 0.000000e+00
br i1 %77, label %78, label %79
78: ; preds = %75, %4
store float 0.000000e+00, float* %5
br label %93
79: ; preds = %75
%80 = getelementptr inbounds [3 x double], [3 x double]* %10, i64 0, i64 0
%81 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%82 = call double @matCalcDot(double* %80, double* %81)
%83 = load double, double* %12
%84 = load double, double* %13
%85 = fmul double %83, %84
%86 = fdiv double %82, %85
%87 = call double @acos(double %86)
store double %87, double* %14
%88 = load double, double* %14
%89 = fmul double %88, 1.800000e+02
%90 = load double, double* @M_PI
%91 = fdiv double %89, %90
%92 = fptrunc double %91 to float
store float %92, float* %5
br label %93
93: ; preds = %79, %78
%94 = load float, float* %5
ret float %94
}

LLVM IR (-O2):
@M_PI = global double 0.000000e+00
define float @matfCalcAngle(float* nocapture %0, float* nocapture %1, float* nocapture %2, float* nocapture %3) {
%5 = alloca [3 x double]
%6 = alloca [3 x double]
%7 = bitcast [3 x double]* %5 to i8*
%8 = bitcast [3 x double]* %6 to i8*
%9 = getelementptr inbounds [3 x double], [3 x double]* %5, i64 0, i64 0
%10 = bitcast float* %0 to <2 x float>*
%11 = load <2 x float>, <2 x float>* %10
%12 = bitcast float* %1 to <2 x float>*
%13 = load <2 x float>, <2 x float>* %12
%14 = fsub <2 x float> %11, %13
%15 = fpext <2 x float> %14 to <2 x double>
%16 = bitcast [3 x double]* %5 to <2 x double>*
store <2 x double> %15, <2 x double>* %16
%17 = getelementptr inbounds float, float* %0, i64 2
%18 = load float, float* %17
%19 = getelementptr inbounds float, float* %1, i64 2
%20 = load float, float* %19
%21 = fsub float %18, %20
%22 = fpext float %21 to double
%23 = getelementptr inbounds [3 x double], [3 x double]* %5, i64 0, i64 2
store double %22, double* %23
%24 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 0
%25 = bitcast float* %2 to <2 x float>*
%26 = load <2 x float>, <2 x float>* %25
%27 = bitcast float* %3 to <2 x float>*
%28 = load <2 x float>, <2 x float>* %27
%29 = fsub <2 x float> %26, %28
%30 = fpext <2 x float> %29 to <2 x double>
%31 = bitcast [3 x double]* %6 to <2 x double>*
store <2 x double> %30, <2 x double>* %31
%32 = getelementptr inbounds float, float* %2, i64 2
%33 = load float, float* %32
%34 = getelementptr inbounds float, float* %3, i64 2
%35 = load float, float* %34
%36 = fsub float %33, %35
%37 = fpext float %36 to double
%38 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 2
store double %37, double* %38
%39 = call double @matCalcLen(double* %9)
%40 = call double @matCalcLen(double* %24)
%41 = fcmp oeq double %39, 0.000000e+00
%42 = fcmp oeq double %40, 0.000000e+00
%43 = select i1 %41, i1 true, i1 %42
br i1 %43, label %53, label %44
44: ; preds = %4
%45 = call double @matCalcDot(double* %9, double* %24)
%46 = fmul double %39, %40
%47 = fdiv double %45, %46
%48 = call double @acos(double %47)
%49 = fmul double %48, 1.800000e+02
%50 = load double, double* @M_PI
%51 = fdiv double %49, %50
%52 = fptrunc double %51 to float
br label %53
53: ; preds = %4, %44
%54 = phi float [ %52, %44 ], [ 0.000000e+00, %4 ]
ret float %54
}