#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 */
int M_PI;
double surface_area_sphere(int d) {
  switch (d) {
  case 0:
    return 2;
  case 1:
    return 2 * M_PI;
  case 2:
    return 4 * M_PI;
  case 3:
    return 2 * M_PI * M_PI;
  }
  return (2 * M_PI / ((double)d - 1)) * surface_area_sphere(d - 2);
}


x86 assembly (clang, -O0):
<surface_area_sphere>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %edi,-0xc(%rbp)
mov    -0xc(%rbp),%eax
mov    %rax,-0x18(%rbp)
sub    $0x3,%rax
ja     11aa <surface_area_sphere+0x9a>
mov    -0x18(%rbp),%rax
lea    0xed9(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movsd  0xeb8(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11f0 <surface_area_sphere+0xe0>
mov    0x2e8f(%rip),%rax
mov    (%rax),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11f0 <surface_area_sphere+0xe0>
mov    0x2e75(%rip),%rax
mov    (%rax),%eax
shl    $0x2,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11f0 <surface_area_sphere+0xe0>
mov    0x2e5b(%rip),%rax
mov    (%rax),%eax
shl    $0x1,%eax
mov    0x2e4f(%rip),%rcx
imul   (%rcx),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11f0 <surface_area_sphere+0xe0>
mov    0x2e37(%rip),%rax
mov    (%rax),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
movsd  0xe41(%rip),%xmm2
subsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0xc(%rbp),%edi
sub    $0x2,%edi
call   1030 <surface_area_sphere@plt>
movaps %xmm0,%xmm1
movsd  -0x20(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<surface_area_sphere>:
push   %rax
cmp    $0x3,%edi
ja     113b <surface_area_sphere+0x2b>
movsd  0xee2(%rip),%xmm0
mov    %edi,%eax
lea    0xee9(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    0x2eb1(%rip),%rax
mov    (%rax),%eax
jmp    1188 <surface_area_sphere+0x78>
mov    0x2ea6(%rip),%rax
mov    (%rax),%eax
add    %eax,%eax
cvtsi2sd %eax,%xmm1
cvtsi2sd %edi,%xmm0
addsd  0xeb2(%rip),%xmm0
divsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
add    $0xfffffffe,%edi
call   1030 <surface_area_sphere@plt>
mulsd  (%rsp),%xmm0
pop    %rax
ret
mov    0x2e73(%rip),%rax
mov    (%rax),%eax
shl    $0x2,%eax
jmp    118a <surface_area_sphere+0x7a>
mov    0x2e65(%rip),%rax
mov    (%rax),%eax
imul   %eax,%eax
add    %eax,%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
pop    %rax
ret

LLVM IR (-O0):
@M_PI = global i32 0
define double @surface_area_sphere(i32 %0) {
%2 = alloca double
%3 = alloca i32
store i32 %0, i32* %3
%4 = load i32, i32* %3
switch i32 %4, label %20 [
i32 0, label %5
i32 1, label %6
i32 2, label %10
i32 3, label %14
]
5: ; preds = %1
store double 2.000000e+00, double* %2
br label %32
6: ; preds = %1
%7 = load i32, i32* @M_PI
%8 = mul nsw i32 2, %7
%9 = sitofp i32 %8 to double
store double %9, double* %2
br label %32
10: ; preds = %1
%11 = load i32, i32* @M_PI
%12 = mul nsw i32 4, %11
%13 = sitofp i32 %12 to double
store double %13, double* %2
br label %32
14: ; preds = %1
%15 = load i32, i32* @M_PI
%16 = mul nsw i32 2, %15
%17 = load i32, i32* @M_PI
%18 = mul nsw i32 %16, %17
%19 = sitofp i32 %18 to double
store double %19, double* %2
br label %32
20: ; preds = %1
%21 = load i32, i32* @M_PI
%22 = mul nsw i32 2, %21
%23 = sitofp i32 %22 to double
%24 = load i32, i32* %3
%25 = sitofp i32 %24 to double
%26 = fsub double %25, 1.000000e+00
%27 = fdiv double %23, %26
%28 = load i32, i32* %3
%29 = sub nsw i32 %28, 2
%30 = call double @surface_area_sphere(i32 %29)
%31 = fmul double %27, %30
store double %31, double* %2
br label %32
32: ; preds = %20, %14, %10, %6, %5
%33 = load double, double* %2
ret double %33
}

LLVM IR (-O2):
@M_PI = global i32 0
define double @surface_area_sphere(i32 %0) {
switch i32 %0, label %17 [
i32 0, label %15
i32 1, label %2
i32 2, label %6
i32 3, label %10
]
2: ; preds = %1
%3 = load i32, i32* @M_PI
%4 = shl nsw i32 %3, 1
%5 = sitofp i32 %4 to double
br label %15
6: ; preds = %1
%7 = load i32, i32* @M_PI
%8 = shl nsw i32 %7, 2
%9 = sitofp i32 %8 to double
br label %15
10: ; preds = %1
%11 = load i32, i32* @M_PI
%12 = shl nsw i32 %11, 1
%13 = mul nsw i32 %12, %11
%14 = sitofp i32 %13 to double
br label %15
15: ; preds = %2, %6, %10, %1, %17
%16 = phi double [ %26, %17 ], [ %14, %10 ], [ %9, %6 ], [ %5, %2 ], [ 2.000000e+00, %1 ]
ret double %16
17: ; preds = %1
%18 = load i32, i32* @M_PI
%19 = shl nsw i32 %18, 1
%20 = sitofp i32 %19 to double
%21 = sitofp i32 %0 to double
%22 = fadd double %21, -1.000000e+00
%23 = fdiv double %20, %22
%24 = add nsw i32 %0, -2
%25 = tail call double @surface_area_sphere(i32 %24)
%26 = fmul double %25, %23
br label %15
}