double pow_10(int p) {
  double sum = 1;
  while (p > 0) {
    sum *= 10;
    p--;
  }
  while (p < 0) {
    sum /= 10;
    p++;
  }
  return sum;
}


x86 assembly (clang, -O0):
<pow_10>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movsd  0xef1(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
cmpl   $0x0,-0x4(%rbp)
jle    113e <pow_10+0x3e>
movsd  0xee2(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0x4(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x4(%rbp)
jmp    1114 <pow_10+0x14>
jmp    1143 <pow_10+0x43>
cmpl   $0x0,-0x4(%rbp)
jge    1171 <pow_10+0x71>
movsd  -0x10(%rbp),%xmm0
movsd  0xeae(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    1143 <pow_10+0x43>
movsd  -0x10(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<pow_10>:
test   %edi,%edi
jle    1134 <pow_10+0x34>
lea    -0x1(%rdi),%eax
mov    %edi,%ecx
and    $0x7,%ecx
je     113f <pow_10+0x3f>
xor    %edx,%edx
movsd  0xee8(%rip),%xmm0
movsd  0xee8(%rip),%xmm1
mulsd  %xmm1,%xmm0
add    $0x1,%edx
cmp    %edx,%ecx
jne    1120 <pow_10+0x20>
sub    %edx,%edi
cmp    $0x7,%eax
jae    114c <pow_10+0x4c>
jmp    1188 <pow_10+0x88>
js     1189 <pow_10+0x89>
movsd  0xec2(%rip),%xmm0
ret
movsd  0xeb9(%rip),%xmm0
cmp    $0x7,%eax
jb     1188 <pow_10+0x88>
add    $0xffffffff,%edi
movsd  0xeb1(%rip),%xmm1
nopw   0x0(%rax,%rax,1)
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
add    $0xfffffff8,%edi
cmp    $0xfffffffe,%edi
jb     1160 <pow_10+0x60>
ret
mov    %edi,%eax
neg    %eax
and    $0x3,%eax
je     11c6 <pow_10+0xc6>
neg    %eax
movsd  0xe64(%rip),%xmm0
xor    %ecx,%ecx
movsd  0xe62(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
divsd  %xmm1,%xmm0
add    $0xffffffff,%ecx
cmp    %ecx,%eax
jne    11b0 <pow_10+0xb0>
mov    %edi,%eax
sub    %ecx,%eax
cmp    $0xfffffffc,%edi
ja     1188 <pow_10+0x88>
jmp    11d5 <pow_10+0xd5>
movsd  0xe32(%rip),%xmm0
mov    %edi,%eax
cmp    $0xfffffffc,%edi
ja     1188 <pow_10+0x88>
movsd  0xe2b(%rip),%xmm1
nopl   (%rax)
divsd  %xmm1,%xmm0
divsd  %xmm1,%xmm0
divsd  %xmm1,%xmm0
divsd  %xmm1,%xmm0
add    $0x4,%eax
jne    11e0 <pow_10+0xe0>
jmp    1188 <pow_10+0x88>

LLVM IR (-O0):
define double @pow_10(i32 %0) {
%2 = alloca i32
%3 = alloca double
store i32 %0, i32* %2
store double 1.000000e+00, double* %3
br label %4
4: ; preds = %7, %1
%5 = load i32, i32* %2
%6 = icmp sgt i32 %5, 0
br i1 %6, label %7, label %12
7: ; preds = %4
%8 = load double, double* %3
%9 = fmul double %8, 1.000000e+01
store double %9, double* %3
%10 = load i32, i32* %2
%11 = add nsw i32 %10, -1
store i32 %11, i32* %2
br label %4
12: ; preds = %4
br label %13
13: ; preds = %16, %12
%14 = load i32, i32* %2
%15 = icmp slt i32 %14, 0
br i1 %15, label %16, label %21
16: ; preds = %13
%17 = load double, double* %3
%18 = fdiv double %17, 1.000000e+01
store double %18, double* %3
%19 = load i32, i32* %2
%20 = add nsw i32 %19, 1
store i32 %20, i32* %2
br label %13
21: ; preds = %13
%22 = load double, double* %3
ret double %22
}

LLVM IR (-O2):
define double @pow_10(i32 %0) {
%2 = icmp sgt i32 %0, 0
br i1 %2, label %3, label %20
3: ; preds = %1
%4 = add i32 %0, -1
%5 = and i32 %0, 7
%6 = icmp eq i32 %5, 0
br i1 %6, label %15, label %7
7: ; preds = %3, %7
%8 = phi double [ %11, %7 ], [ 1.000000e+00, %3 ]
%9 = phi i32 [ %12, %7 ], [ %0, %3 ]
%10 = phi i32 [ %13, %7 ], [ 0, %3 ]
%11 = fmul double %8, 1.000000e+01
%12 = add nsw i32 %9, -1
%13 = add i32 %10, 1
%14 = icmp eq i32 %13, %5
br i1 %14, label %15, label %7
15: ; preds = %7, %3
%16 = phi double [ 1.000000e+00, %3 ], [ %11, %7 ]
%17 = phi i32 [ %0, %3 ], [ %12, %7 ]
%18 = phi double [ undef, %3 ], [ %11, %7 ]
%19 = icmp ult i32 %4, 7
br i1 %19, label %62, label %39
20: ; preds = %1
%21 = icmp slt i32 %0, 0
br i1 %21, label %22, label %62
22: ; preds = %20
%23 = sub i32 0, %0
%24 = and i32 %23, 3
%25 = icmp eq i32 %24, 0
br i1 %25, label %34, label %26
26: ; preds = %22, %26
%27 = phi double [ %30, %26 ], [ 1.000000e+00, %22 ]
%28 = phi i32 [ %31, %26 ], [ %0, %22 ]
%29 = phi i32 [ %32, %26 ], [ 0, %22 ]
%30 = fdiv double %27, 1.000000e+01
%31 = add i32 %28, 1
%32 = add i32 %29, 1
%33 = icmp eq i32 %32, %24
br i1 %33, label %34, label %26
34: ; preds = %26, %22
%35 = phi double [ undef, %22 ], [ %30, %26 ]
%36 = phi double [ 1.000000e+00, %22 ], [ %30, %26 ]
%37 = phi i32 [ %0, %22 ], [ %31, %26 ]
%38 = icmp ugt i32 %0, -4
br i1 %38, label %62, label %53
39: ; preds = %15, %39
%40 = phi double [ %49, %39 ], [ %16, %15 ]
%41 = phi i32 [ %50, %39 ], [ %17, %15 ]
%42 = fmul double %40, 1.000000e+01
%43 = fmul double %42, 1.000000e+01
%44 = fmul double %43, 1.000000e+01
%45 = fmul double %44, 1.000000e+01
%46 = fmul double %45, 1.000000e+01
%47 = fmul double %46, 1.000000e+01
%48 = fmul double %47, 1.000000e+01
%49 = fmul double %48, 1.000000e+01
%50 = add nsw i32 %41, -8
%51 = add i32 %41, -9
%52 = icmp ult i32 %51, -2
br i1 %52, label %39, label %62
53: ; preds = %34, %53
%54 = phi double [ %59, %53 ], [ %36, %34 ]
%55 = phi i32 [ %60, %53 ], [ %37, %34 ]
%56 = fdiv double %54, 1.000000e+01
%57 = fdiv double %56, 1.000000e+01
%58 = fdiv double %57, 1.000000e+01
%59 = fdiv double %58, 1.000000e+01
%60 = add i32 %55, 4
%61 = icmp eq i32 %60, 0
br i1 %61, label %62, label %53
62: ; preds = %34, %53, %15, %39, %20
%63 = phi double [ 1.000000e+00, %20 ], [ %18, %15 ], [ %49, %39 ], [ %35, %34 ], [ %59, %53 ]
ret double %63
}