double pow(double base, double exponent) {
  int i;
  double result = 1;
  if (exponent == 0)
    return 1;
  if (exponent < 0)
    return 1.0 / pow(base, (-1) * exponent);
  for (i = 0; i < exponent; i++)
    result *= base;
  return result;
}


x86 assembly (clang, -O0):
<pow>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  0xed6(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1159 <pow+0x49>
jp     1159 <pow+0x49>
movsd  0xeb1(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d9 <pow+0xc9>
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    1197 <pow+0x87>
movsd  -0x10(%rbp),%xmm0
movsd  0xe94(%rip),%xmm1
mulsd  -0x18(%rbp),%xmm1
call   1030 <pow@plt>
movaps %xmm0,%xmm1
movsd  0xe77(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d9 <pow+0xc9>
movl   $0x0,-0x1c(%rbp)
cvtsi2sdl -0x1c(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11cf <pow+0xbf>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    119e <pow+0x8e>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pow>:
push   %rax
movapd %xmm0,%xmm2
movsd  0xee3(%rip),%xmm0
xorpd  %xmm3,%xmm3
ucomisd %xmm3,%xmm1
jne    112b <pow+0x1b>
jp     112b <pow+0x1b>
pop    %rax
ret
ucomisd %xmm1,%xmm3
jbe    1154 <pow+0x44>
xorpd  0xed7(%rip),%xmm1
movapd %xmm2,%xmm0
call   1030 <pow@plt>
movapd %xmm0,%xmm1
movsd  0xeb2(%rip),%xmm0
divsd  %xmm1,%xmm0
pop    %rax
ret
xorpd  %xmm3,%xmm3
ucomisd %xmm3,%xmm1
jbe    1129 <pow+0x19>
movsd  0xe9a(%rip),%xmm0
mov    $0x1,%eax
nopl   0x0(%rax,%rax,1)
xorps  %xmm3,%xmm3
cvtsi2sd %eax,%xmm3
mulsd  %xmm2,%xmm0
add    $0x1,%eax
ucomisd %xmm3,%xmm1
ja     1170 <pow+0x60>
jmp    1129 <pow+0x19>

LLVM IR (-O0):
define double @pow(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca i32
%7 = alloca double
store double %0, double* %4
store double %1, double* %5
store double 1.000000e+00, double* %7
%8 = load double, double* %5
%9 = fcmp oeq double %8, 0.000000e+00
br i1 %9, label %10, label %11
10: ; preds = %2
store double 1.000000e+00, double* %3
br label %35
11: ; preds = %2
%12 = load double, double* %5
%13 = fcmp olt double %12, 0.000000e+00
br i1 %13, label %14, label %20
14: ; preds = %11
%15 = load double, double* %4
%16 = load double, double* %5
%17 = fmul double -1.000000e+00, %16
%18 = call double @pow(double %15, double %17)
%19 = fdiv double 1.000000e+00, %18
store double %19, double* %3
br label %35
20: ; preds = %11
store i32 0, i32* %6
br label %21
21: ; preds = %30, %20
%22 = load i32, i32* %6
%23 = sitofp i32 %22 to double
%24 = load double, double* %5
%25 = fcmp olt double %23, %24
br i1 %25, label %26, label %33
26: ; preds = %21
%27 = load double, double* %4
%28 = load double, double* %7
%29 = fmul double %28, %27
store double %29, double* %7
br label %30
30: ; preds = %26
%31 = load i32, i32* %6
%32 = add nsw i32 %31, 1
store i32 %32, i32* %6
br label %21
33: ; preds = %21
%34 = load double, double* %7
store double %34, double* %3
br label %35
35: ; preds = %33, %14, %10
%36 = load double, double* %3
ret double %36
}

LLVM IR (-O2):
define double @pow(double %0, double %1) {
%3 = fcmp oeq double %1, 0.000000e+00
br i1 %3, label %8, label %4
4: ; preds = %2
%5 = fcmp olt double %1, 0.000000e+00
br i1 %5, label %10, label %6
6: ; preds = %4
%7 = fcmp ogt double %1, 0.000000e+00
br i1 %7, label %14, label %8
8: ; preds = %14, %6, %2, %10
%9 = phi double [ %13, %10 ], [ 1.000000e+00, %2 ], [ 1.000000e+00, %6 ], [ %17, %14 ]
ret double %9
10: ; preds = %4
%11 = fneg double %1
%12 = tail call double @pow(double %0, double %11)
%13 = fdiv double 1.000000e+00, %12
br label %8
14: ; preds = %6, %14
%15 = phi double [ %17, %14 ], [ 1.000000e+00, %6 ]
%16 = phi i32 [ %18, %14 ], [ 0, %6 ]
%17 = fmul double %15, %0
%18 = add nuw nsw i32 %16, 1
%19 = sitofp i32 %18 to double
%20 = fcmp olt double %19, %1
br i1 %20, label %14, label %8
}