double dpow(double d, int n) {
  if (n < 0)
    return dpow(1 / d, -n);
  else if (n == 0)
    return 1;
  else if (n == 1)
    return d;
  else if (n % 2 == 0)
    return dpow(d * d, n / 2);
  else
    return d * dpow(d * d, (n - 1) / 2);
}


x86 assembly (clang, -O0):
<dpow>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movsd  %xmm0,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jge    114b <dpow+0x3b>
movsd  0xece(%rip),%xmm0
divsd  -0x10(%rbp),%xmm0
xor    %edi,%edi
sub    -0x14(%rbp),%edi
call   1030 <dpow@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    11f4 <dpow+0xe4>
cmpl   $0x0,-0x14(%rbp)
jne    1167 <dpow+0x57>
movsd  0xea3(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11f4 <dpow+0xe4>
cmpl   $0x1,-0x14(%rbp)
jne    1180 <dpow+0x70>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11f4 <dpow+0xe4>
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    11ba <dpow+0xaa>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%edi
call   1030 <dpow@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    11f4 <dpow+0xe4>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x10(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%edi
call   1030 <dpow@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):
<dpow>:
push   %rax
movapd %xmm0,%xmm2
movsd  0xee3(%rip),%xmm0
test   %edi,%edi
jns    1142 <dpow+0x32>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movapd %xmm0,%xmm1
divsd  %xmm2,%xmm1
neg    %edi
movapd %xmm1,%xmm2
test   %edi,%edi
js     1130 <dpow+0x20>
je     1167 <dpow+0x57>
cmp    $0x1,%edi
je     1163 <dpow+0x53>
movapd %xmm2,%xmm1
mulsd  %xmm2,%xmm1
test   $0x1,%dil
jne    1169 <dpow+0x59>
shr    %edi
movapd %xmm1,%xmm2
test   %edi,%edi
jns    1142 <dpow+0x32>
jmp    1130 <dpow+0x20>
movapd %xmm2,%xmm0
pop    %rax
ret
add    $0xffffffff,%edi
shr    %edi
movapd %xmm1,%xmm0
movsd  %xmm2,(%rsp)
call   1030 <dpow@plt>
movsd  (%rsp),%xmm1
mulsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
pop    %rax
ret

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

LLVM IR (-O2):
define double @dpow(double %0, i32 %1) {
br label %3
3: ; preds = %10, %2
%4 = phi double [ %0, %2 ], [ %11, %10 ]
%5 = phi i32 [ %1, %2 ], [ %12, %10 ]
%6 = icmp slt i32 %5, 0
br i1 %6, label %7, label %13
7: ; preds = %3
%8 = fdiv double 1.000000e+00, %4
%9 = sub nsw i32 0, %5
br label %10
10: ; preds = %7, %18
%11 = phi double [ %8, %7 ], [ %17, %18 ]
%12 = phi i32 [ %9, %7 ], [ %19, %18 ]
br label %3
13: ; preds = %3
switch i32 %5, label %14 [
i32 0, label %20
i32 1, label %21
]
14: ; preds = %13
%15 = and i32 %5, 1
%16 = icmp eq i32 %15, 0
%17 = fmul double %4, %4
br i1 %16, label %18, label %23
18: ; preds = %14
%19 = lshr i32 %5, 1
br label %10
20: ; preds = %13
br label %21
21: ; preds = %13, %20, %23
%22 = phi double [ %27, %23 ], [ 1.000000e+00, %20 ], [ %4, %13 ]
ret double %22
23: ; preds = %14
%24 = add nsw i32 %5, -1
%25 = lshr i32 %24, 1
%26 = tail call double @dpow(double %17, i32 %25)
%27 = fmul double %4, %26
br label %21
}