double power_recurse(double b, int e) {
  if (e == 0) {
    return 1;
  } else if (e == 1) {
    return b;
  } else if (e % 2 == 1) {
    double res = power_recurse(b, e / 2);
    return res * res * b;
  } else if (e % 2 == 0) {
    double res = power_recurse(b, e / 2);
    return res * res;
  }
  return -1.0;
}


x86 assembly (clang, -O0):
<power_recurse>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jne    113c <power_recurse+0x2c>
movsd  0xed6(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11fe <power_recurse+0xee>
cmpl   $0x1,-0x14(%rbp)
jne    1155 <power_recurse+0x45>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11fe <power_recurse+0xee>
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
cmp    $0x1,%edx
jne    119e <power_recurse+0x8e>
movsd  -0x10(%rbp),%xmm0
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%edi
call   1030 <power_recurse@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11fe <power_recurse+0xee>
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    11e2 <power_recurse+0xd2>
movsd  -0x10(%rbp),%xmm0
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%edi
call   1030 <power_recurse@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11fe <power_recurse+0xee>
jmp    11e7 <power_recurse+0xd7>
jmp    11ec <power_recurse+0xdc>
jmp    11f1 <power_recurse+0xe1>
movsd  0xe07(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<power_recurse>:
push   %rax
test   %edi,%edi
je     115b <power_recurse+0x4b>
cmp    $0x1,%edi
je     117a <power_recurse+0x6a>
mov    %edi,%ecx
shr    $0x1f,%ecx
add    %edi,%ecx
mov    %ecx,%eax
sar    %eax
and    $0xfffffffe,%ecx
sub    %ecx,%edi
je     1165 <power_recurse+0x55>
cmp    $0x1,%edi
jne    1172 <power_recurse+0x62>
movsd  %xmm0,(%rsp)
movsd  (%rsp),%xmm0
mov    %eax,%edi
call   1030 <power_recurse@plt>
mulsd  %xmm0,%xmm0
movsd  (%rsp),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
movsd  (%rsp),%xmm0
pop    %rax
ret
movsd  0xe9d(%rip),%xmm0
pop    %rax
ret
mov    %eax,%edi
call   1030 <power_recurse@plt>
mulsd  %xmm0,%xmm0
pop    %rax
ret
movsd  0xe8e(%rip),%xmm0
pop    %rax
ret

LLVM IR (-O0):
define double @power_recurse(double %0, i32 %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca i32
%6 = alloca double
%7 = alloca double
store double %0, double* %4
store i32 %1, i32* %5
%8 = load i32, i32* %5
%9 = icmp eq i32 %8, 0
br i1 %9, label %10, label %11
10: ; preds = %2
store double 1.000000e+00, double* %3
br label %46
11: ; preds = %2
%12 = load i32, i32* %5
%13 = icmp eq i32 %12, 1
br i1 %13, label %14, label %16
14: ; preds = %11
%15 = load double, double* %4
store double %15, double* %3
br label %46
16: ; preds = %11
%17 = load i32, i32* %5
%18 = srem i32 %17, 2
%19 = icmp eq i32 %18, 1
br i1 %19, label %20, label %30
20: ; preds = %16
%21 = load double, double* %4
%22 = load i32, i32* %5
%23 = sdiv i32 %22, 2
%24 = call double @power_recurse(double %21, i32 %23)
store double %24, double* %6
%25 = load double, double* %6
%26 = load double, double* %6
%27 = fmul double %25, %26
%28 = load double, double* %4
%29 = fmul double %27, %28
store double %29, double* %3
br label %46
30: ; preds = %16
%31 = load i32, i32* %5
%32 = srem i32 %31, 2
%33 = icmp eq i32 %32, 0
br i1 %33, label %34, label %42
34: ; preds = %30
%35 = load double, double* %4
%36 = load i32, i32* %5
%37 = sdiv i32 %36, 2
%38 = call double @power_recurse(double %35, i32 %37)
store double %38, double* %7
%39 = load double, double* %7
%40 = load double, double* %7
%41 = fmul double %39, %40
store double %41, double* %3
br label %46
42: ; preds = %30
br label %43
43: ; preds = %42
br label %44
44: ; preds = %43
br label %45
45: ; preds = %44
store double -1.000000e+00, double* %3
br label %46
46: ; preds = %45, %34, %20, %14, %10
%47 = load double, double* %3
ret double %47
}

LLVM IR (-O2):
define double @power_recurse(double %0, i32 %1) {
switch i32 %1, label %4 [
i32 0, label %7
i32 1, label %3
]
3: ; preds = %2
br label %7
4: ; preds = %2
%5 = srem i32 %1, 2
%6 = sdiv i32 %1, 2
switch i32 %5, label %7 [
i32 1, label %9
i32 0, label %14
]
7: ; preds = %3, %2, %4, %14, %9
%8 = phi double [ %13, %9 ], [ %16, %14 ], [ %0, %3 ], [ 1.000000e+00, %2 ], [ -1.000000e+00, %4 ]
ret double %8
9: ; preds = %4
%10 = sdiv i32 %1, 2
%11 = tail call double @power_recurse(double %0, i32 %10)
%12 = fmul double %11, %11
%13 = fmul double %12, %0
br label %7
14: ; preds = %4
%15 = tail call double @power_recurse(double %0, i32 %6)
%16 = fmul double %15, %15
br label %7
}