#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 atan2(double, double);
double cos(double);
double approxU(double x, double y, int NRS, double Rmax, double *U0, double *U6,
               double *U12) {
  double r2 = x * x + y * y;
  double dr2 = Rmax * Rmax / ((double)NRS);
  double idr2 = 1.0 / dr2;
  double u, u0, u6, u12;
  int k = ((int)(r2 * idr2));
  double t = atan2(y, x);
  double c1, c2;
  if (k == 0) {
    c2 = r2 * idr2;
    u0 = c2 * U0[0];
    u6 = c2 * U6[0];
    u12 = c2 * U12[0];
  } else {
    if (k >= NRS)
      k = NRS - 1;
    double r21 = dr2 * ((double)k);
    double r22 = dr2 * ((double)(k + 1));
    c1 = (r22 - r2) * idr2;
    c2 = (r2 - r21) * idr2;
    u0 = c1 * U0[k - 1] + c2 * U0[k];
    u6 = c1 * U6[k - 1] + c2 * U6[k];
    u12 = c1 * U12[k - 1] + c2 * U12[k];
  }
  u = u0 + u6 * cos(6.0 * t) + u12 * cos(12.0 * t);
  return u;
}


x86 assembly (clang, -O0):
<approxU>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
movsd  %xmm2,-0x20(%rbp)
mov    %rsi,-0x28(%rbp)
mov    %rdx,-0x30(%rbp)
mov    %rcx,-0x38(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm2
movsd  -0x10(%rbp),%xmm1
mulsd  -0x10(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x20(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
cvtsi2sdl -0x14(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  0xe76(%rip),%xmm0
divsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x50(%rbp),%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x74(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm1
call   1030 <atan2@plt>
movsd  %xmm0,-0x80(%rbp)
cmpl   $0x0,-0x74(%rbp)
jne    1219 <approxU+0xf9>
movsd  -0x40(%rbp),%xmm0
mulsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x90(%rbp),%xmm0
ff
mov    -0x28(%rbp),%rax
mulsd  (%rax),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x90(%rbp),%xmm0
ff
mov    -0x30(%rbp),%rax
mulsd  (%rax),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x90(%rbp),%xmm0
ff
mov    -0x38(%rbp),%rax
mulsd  (%rax),%xmm0
movsd  %xmm0,-0x70(%rbp)
jmp    1347 <approxU+0x227>
mov    -0x74(%rbp),%eax
cmp    -0x14(%rbp),%eax
jl     122e <approxU+0x10e>
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x74(%rbp)
movsd  -0x48(%rbp),%xmm0
cvtsi2sdl -0x74(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
movsd  -0x48(%rbp),%xmm0
mov    -0x74(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  -0xa0(%rbp),%xmm0
ff
subsd  -0x40(%rbp),%xmm0
mulsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x40(%rbp),%xmm0
subsd  -0x98(%rbp),%xmm0
ff
mulsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x88(%rbp),%xmm0
ff
mov    -0x28(%rbp),%rax
mov    -0x74(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x90(%rbp),%xmm1
ff
mov    -0x28(%rbp),%rax
movslq -0x74(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x88(%rbp),%xmm0
ff
mov    -0x30(%rbp),%rax
mov    -0x74(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x90(%rbp),%xmm1
ff
mov    -0x30(%rbp),%rax
movslq -0x74(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x88(%rbp),%xmm0
ff
mov    -0x38(%rbp),%rax
mov    -0x74(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x90(%rbp),%xmm1
ff
mov    -0x38(%rbp),%rax
movslq -0x74(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0xc0(%rbp)
ff
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
movsd  0xca7(%rip),%xmm0
mulsd  -0x80(%rbp),%xmm0
call   1040 <cos@plt>
movsd  -0xc0(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0xb8(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
movsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  0xc5d(%rip),%xmm0
mulsd  -0x80(%rbp),%xmm0
call   1040 <cos@plt>
movsd  -0xb0(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0xa8(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<approxU>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x30,%rsp
mov    %rcx,%r15
mov    %rdx,%r14
mov    %rsi,%r12
mov    %edi,%ebx
movapd %xmm0,%xmm4
movapd %xmm1,%xmm0
mulsd  %xmm1,%xmm0
movapd %xmm4,%xmm3
mulsd  %xmm4,%xmm3
addsd  %xmm0,%xmm3
mulsd  %xmm2,%xmm2
xorps  %xmm0,%xmm0
cvtsi2sd %edi,%xmm0
divsd  %xmm0,%xmm2
movsd  0xe9a(%rip),%xmm0
movsd  %xmm2,(%rsp)
divsd  %xmm2,%xmm0
movapd %xmm3,0x10(%rsp)
movsd  %xmm0,0x8(%rsp)
mulsd  %xmm0,%xmm3
movapd %xmm3,0x20(%rsp)
cvttsd2si %xmm3,%ebp
movapd %xmm1,%xmm0
movapd %xmm4,%xmm1
call   1030 <atan2@plt>
movapd %xmm0,%xmm2
test   %ebp,%ebp
je     123a <approxU+0x11a>
lea    -0x1(%rbx),%eax
cmp    %ebx,%ebp
cmovl  %ebp,%eax
xorps  %xmm1,%xmm1
cvtsi2sd %eax,%xmm1
movsd  (%rsp),%xmm3
mulsd  %xmm3,%xmm1
lea    0x1(%rax),%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
mulsd  %xmm3,%xmm0
movapd 0x10(%rsp),%xmm3
subsd  %xmm3,%xmm0
movsd  0x8(%rsp),%xmm4
mulsd  %xmm4,%xmm0
subsd  %xmm1,%xmm3
mulsd  %xmm4,%xmm3
cltq
movsd  (%r12,%rax,8),%xmm1
mulsd  %xmm3,%xmm1
movsd  -0x8(%r12,%rax,8),%xmm4
mulsd  %xmm0,%xmm4
addsd  %xmm1,%xmm4
movsd  %xmm4,(%rsp)
unpcklpd %xmm3,%xmm3
movsd  -0x8(%r15,%rax,8),%xmm4
movsd  (%r15,%rax,8),%xmm1
movhpd (%r14,%rax,8),%xmm1
mulpd  %xmm3,%xmm1
unpcklpd %xmm0,%xmm0
movhpd -0x8(%r14,%rax,8),%xmm4
mulpd  %xmm0,%xmm4
addpd  %xmm1,%xmm4
movapd %xmm4,0x10(%rsp)
jmp    1267 <approxU+0x147>
movsd  (%r12),%xmm0
movapd 0x20(%rsp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,(%rsp)
unpcklpd %xmm1,%xmm1
movsd  (%r15),%xmm0
movhpd (%r14),%xmm0
mulpd  %xmm1,%xmm0
movapd %xmm0,0x10(%rsp)
movsd  0xd99(%rip),%xmm0
mulsd  %xmm2,%xmm0
movsd  %xmm2,0x8(%rsp)
call   1040 <cos@plt>
movapd 0x10(%rsp),%xmm1
unpckhpd %xmm1,%xmm1
mulsd  %xmm1,%xmm0
addsd  (%rsp),%xmm0
movsd  %xmm0,(%rsp)
movsd  0x8(%rsp),%xmm0
mulsd  0xd6c(%rip),%xmm0
call   1040 <cos@plt>
mulsd  0x10(%rsp),%xmm0
addsd  (%rsp),%xmm0
add    $0x30,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define double @approxU(double %0, double %1, i32 %2, double %3, double* nocapture %4, double* nocapture %5, double* nocapture %6) {
%8 = fmul double %1, %1
%9 = tail call double @llvm.fmuladd.f64(double %0, double %0, double %8)
%10 = fmul double %3, %3
%11 = sitofp i32 %2 to double
%12 = fdiv double %10, %11
%13 = fdiv double 1.000000e+00, %12
%14 = fmul double %9, %13
%15 = fptosi double %14 to i32
%16 = tail call double @atan2(double %1, double %0)
%17 = icmp eq i32 %15, 0
br i1 %17, label %18, label %28
18: ; preds = %7
%19 = load double, double* %4
%20 = fmul double %14, %19
%21 = load double, double* %5
%22 = load double, double* %6
%23 = insertelement <2 x double> poison, double %14, i64 0
%24 = shufflevector <2 x double> %23, <2 x double> poison, <2 x i32> zeroinitializer
%25 = insertelement <2 x double> poison, double %22, i64 0
%26 = insertelement <2 x double> %25, double %21, i64 1
%27 = fmul <2 x double> %24, %26
br label %68
28: ; preds = %7
%29 = icmp slt i32 %15, %2
%30 = add nsw i32 %2, -1
%31 = select i1 %29, i32 %15, i32 %30
%32 = sitofp i32 %31 to double
%33 = fmul double %12, %32
%34 = add nsw i32 %31, 1
%35 = sitofp i32 %34 to double
%36 = fmul double %12, %35
%37 = fsub double %36, %9
%38 = fmul double %13, %37
%39 = fsub double %9, %33
%40 = fmul double %13, %39
%41 = add nsw i32 %31, -1
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds double, double* %4, i64 %42
%44 = load double, double* %43
%45 = sext i32 %31 to i64
%46 = getelementptr inbounds double, double* %4, i64 %45
%47 = load double, double* %46
%48 = fmul double %40, %47
%49 = tail call double @llvm.fmuladd.f64(double %38, double %44, double %48)
%50 = getelementptr inbounds double, double* %5, i64 %42
%51 = load double, double* %50
%52 = getelementptr inbounds double, double* %5, i64 %45
%53 = load double, double* %52
%54 = getelementptr inbounds double, double* %6, i64 %42
%55 = load double, double* %54
%56 = getelementptr inbounds double, double* %6, i64 %45
%57 = load double, double* %56
%58 = insertelement <2 x double> poison, double %40, i64 0
%59 = shufflevector <2 x double> %58, <2 x double> poison, <2 x i32> zeroinitializer
%60 = insertelement <2 x double> poison, double %57, i64 0
%61 = insertelement <2 x double> %60, double %53, i64 1
%62 = fmul <2 x double> %59, %61
%63 = insertelement <2 x double> poison, double %38, i64 0
%64 = shufflevector <2 x double> %63, <2 x double> poison, <2 x i32> zeroinitializer
%65 = insertelement <2 x double> poison, double %55, i64 0
%66 = insertelement <2 x double> %65, double %51, i64 1
%67 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %64, <2 x double> %66, <2 x double> %62)
br label %68
68: ; preds = %28, %18
%69 = phi double [ %20, %18 ], [ %49, %28 ]
%70 = phi <2 x double> [ %27, %18 ], [ %67, %28 ]
%71 = fmul double %16, 6.000000e+00
%72 = tail call double @cos(double %71)
%73 = extractelement <2 x double> %70, i64 1
%74 = tail call double @llvm.fmuladd.f64(double %73, double %72, double %69)
%75 = fmul double %16, 1.200000e+01
%76 = tail call double @cos(double %75)
%77 = extractelement <2 x double> %70, i64 0
%78 = tail call double @llvm.fmuladd.f64(double %77, double %76, double %74)
ret double %78
}