#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(double);
double sin(double);
double SBessy(int n, double x) {
  double y, y0, y1;
  int i;
  y0 = -cos(x) / x;
  if (n == 0)
    return y0;
  y1 = (y0 - sin(x)) / x;
  if (n == 1)
    return y1;
  for (i = 2; i <= n; i++) {
    y = (2 * i - 1) / x * y1 - y0;
    y0 = y1;
    y1 = y;
  }
  return y;
}


x86 assembly (clang, -O0):
<SBessy>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %edi,-0xc(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
call   1040 <cos@plt>
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    1174 <SBessy+0x54>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1236 <SBessy+0x116>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm0
call   1030 <sin@plt>
movaps %xmm0,%xmm1
movsd  -0x40(%rbp),%xmm0
subsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
cmpl   $0x1,-0xc(%rbp)
jne    11b7 <SBessy+0x97>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1236 <SBessy+0x116>
movl   $0x2,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0xc(%rbp),%eax
jg     122c <SBessy+0x10c>
mov    -0x34(%rbp),%eax
shl    $0x1,%eax
sub    $0x1,%eax
cvtsi2sd %eax,%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11be <SBessy+0x9e>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<SBessy>:
push   %rbx
sub    $0x20,%rsp
movsd  %xmm0,0x8(%rsp)
mov    %edi,%ebx
call   1040 <cos@plt>
movsd  0x8(%rsp),%xmm1
movapd %xmm0,%xmm2
xorpd  0xebc(%rip),%xmm2
divsd  %xmm1,%xmm2
test   %ebx,%ebx
je     1194 <SBessy+0x74>
movapd %xmm1,%xmm0
movapd %xmm2,0x10(%rsp)
call   1030 <sin@plt>
movapd 0x10(%rsp),%xmm4
movsd  0x8(%rsp),%xmm3
movapd %xmm0,%xmm1
movapd %xmm4,%xmm0
subsd  %xmm1,%xmm0
divsd  %xmm3,%xmm0
cmp    $0x1,%ebx
je     1198 <SBessy+0x78>
jle    1198 <SBessy+0x78>
lea    -0x1(%rbx),%eax
cmp    $0x2,%ebx
jne    119e <SBessy+0x7e>
movsd  0xe82(%rip),%xmm1
test   $0x1,%al
je     1198 <SBessy+0x78>
jmp    11f7 <SBessy+0xd7>
movapd %xmm2,%xmm0
add    $0x20,%rsp
pop    %rbx
ret
mov    %eax,%edx
and    $0xfffffffe,%edx
mov    $0x5,%ecx
nopl   0x0(%rax,%rax,1)
movapd %xmm4,%xmm1
movapd %xmm0,%xmm2
lea    -0x2(%rcx),%esi
xorps  %xmm4,%xmm4
cvtsi2sd %esi,%xmm4
divsd  %xmm3,%xmm4
mulsd  %xmm0,%xmm4
subsd  %xmm1,%xmm4
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
divsd  %xmm3,%xmm0
mulsd  %xmm4,%xmm0
subsd  %xmm2,%xmm0
add    $0x4,%ecx
add    $0xfffffffe,%edx
jne    11b0 <SBessy+0x90>
add    $0xfffffffe,%ecx
xorps  %xmm1,%xmm1
cvtsi2sd %ecx,%xmm1
test   $0x1,%al
je     1198 <SBessy+0x78>
divsd  %xmm3,%xmm1
mulsd  %xmm0,%xmm1
subsd  %xmm4,%xmm1
movapd %xmm1,%xmm0
jmp    1198 <SBessy+0x78>

LLVM IR (-O0):
define double @SBessy(i32 %0, double %1) {
%3 = alloca double
%4 = alloca i32
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca i32
store i32 %0, i32* %4
store double %1, double* %5
%10 = load double, double* %5
%11 = call double @cos(double %10)
%12 = fneg double %11
%13 = load double, double* %5
%14 = fdiv double %12, %13
store double %14, double* %7
%15 = load i32, i32* %4
%16 = icmp eq i32 %15, 0
br i1 %16, label %17, label %19
17: ; preds = %2
%18 = load double, double* %7
store double %18, double* %3
br label %53
19: ; preds = %2
%20 = load double, double* %7
%21 = load double, double* %5
%22 = call double @sin(double %21)
%23 = fsub double %20, %22
%24 = load double, double* %5
%25 = fdiv double %23, %24
store double %25, double* %8
%26 = load i32, i32* %4
%27 = icmp eq i32 %26, 1
br i1 %27, label %28, label %30
28: ; preds = %19
%29 = load double, double* %8
store double %29, double* %3
br label %53
30: ; preds = %19
store i32 2, i32* %9
br label %31
31: ; preds = %48, %30
%32 = load i32, i32* %9
%33 = load i32, i32* %4
%34 = icmp sle i32 %32, %33
br i1 %34, label %35, label %51
35: ; preds = %31
%36 = load i32, i32* %9
%37 = mul nsw i32 2, %36
%38 = sub nsw i32 %37, 1
%39 = sitofp i32 %38 to double
%40 = load double, double* %5
%41 = fdiv double %39, %40
%42 = load double, double* %8
%43 = load double, double* %7
%44 = fneg double %43
%45 = call double @llvm.fmuladd.f64(double %41, double %42, double %44)
store double %45, double* %6
%46 = load double, double* %8
store double %46, double* %7
%47 = load double, double* %6
store double %47, double* %8
br label %48
48: ; preds = %35
%49 = load i32, i32* %9
%50 = add nsw i32 %49, 1
store i32 %50, i32* %9
br label %31
51: ; preds = %31
%52 = load double, double* %6
store double %52, double* %3
br label %53
53: ; preds = %51, %28, %17
%54 = load double, double* %3
ret double %54
}

LLVM IR (-O2):
define double @SBessy(i32 %0, double %1) {
%3 = tail call double @cos(double %1)
%4 = fneg double %3
%5 = fdiv double %4, %1
%6 = icmp eq i32 %0, 0
br i1 %6, label %54, label %7
7: ; preds = %2
%8 = tail call double @sin(double %1)
%9 = fsub double %5, %8
%10 = fdiv double %9, %1
%11 = icmp eq i32 %0, 1
br i1 %11, label %54, label %12
12: ; preds = %7
%13 = icmp slt i32 %0, 2
br i1 %13, label %54, label %14
14: ; preds = %12
%15 = add i32 %0, -1
%16 = and i32 %15, 1
%17 = icmp eq i32 %0, 2
br i1 %17, label %44, label %18
18: ; preds = %14
%19 = and i32 %15, -2
br label %20
20: ; preds = %20, %18
%21 = phi i32 [ 2, %18 ], [ %37, %20 ]
%22 = phi double [ %10, %18 ], [ %36, %20 ]
%23 = phi double [ %5, %18 ], [ %30, %20 ]
%24 = phi i32 [ 0, %18 ], [ %38, %20 ]
%25 = shl nuw nsw i32 %21, 1
%26 = add nsw i32 %25, -1
%27 = sitofp i32 %26 to double
%28 = fdiv double %27, %1
%29 = fneg double %23
%30 = tail call double @llvm.fmuladd.f64(double %28, double %22, double %29)
%31 = shl i32 %21, 1
%32 = or i32 %31, 1
%33 = sitofp i32 %32 to double
%34 = fdiv double %33, %1
%35 = fneg double %22
%36 = tail call double @llvm.fmuladd.f64(double %34, double %30, double %35)
%37 = add nuw i32 %21, 2
%38 = add i32 %24, 2
%39 = icmp eq i32 %38, %19
br i1 %39, label %40, label %20
40: ; preds = %20
%41 = shl i32 %37, 1
%42 = add i32 %41, -1
%43 = sitofp i32 %42 to double
br label %44
44: ; preds = %40, %14
%45 = phi double [ undef, %14 ], [ %36, %40 ]
%46 = phi double [ 3.000000e+00, %14 ], [ %43, %40 ]
%47 = phi double [ %10, %14 ], [ %36, %40 ]
%48 = phi double [ %5, %14 ], [ %30, %40 ]
%49 = icmp eq i32 %16, 0
br i1 %49, label %54, label %50
50: ; preds = %44
%51 = fdiv double %46, %1
%52 = fneg double %48
%53 = tail call double @llvm.fmuladd.f64(double %51, double %47, double %52)
br label %54
54: ; preds = %50, %44, %12, %7, %2
%55 = phi double [ %5, %2 ], [ %10, %7 ], [ undef, %12 ], [ %45, %44 ], [ %53, %50 ]
ret double %55
}