char power(int base, int exponent) {
  if (!exponent)
    return (char)1;
  return (char)base * power(base, exponent - 1);
}


x86 assembly (clang, -O0):
<power>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %edi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    1131 <power+0x21>
movb   $0x1,-0x1(%rbp)
jmp    1156 <power+0x46>
mov    -0x8(%rbp),%eax
movsbl %al,%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%edi
mov    -0xc(%rbp),%esi
sub    $0x1,%esi
call   1030 <power@plt>
mov    %al,%cl
mov    -0x10(%rbp),%eax
movsbl %cl,%ecx
imul   %ecx,%eax
mov    %al,-0x1(%rbp)
movsbl -0x1(%rbp),%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<power>:
mov    $0x1,%al
test   %esi,%esi
je     1428 <power+0x328>
cmp    $0x8,%esi
jae    1116 <power+0x16>
mov    %esi,%edx
jmp    1420 <power+0x320>
movzbl %dil,%r8d
cmp    $0x20,%esi
jae    1128 <power+0x28>
xor    %ecx,%ecx
mov    $0x1,%al
jmp    1389 <power+0x289>
mov    %esi,%ecx
and    $0xffffffe0,%ecx
movd   %r8d,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
pshufd $0x0,%xmm0,%xmm12
lea    -0x20(%rcx),%r9d
mov    %r9d,%eax
shr    $0x5,%eax
add    $0x1,%eax
mov    %eax,%edx
and    $0x7,%edx
cmp    $0xe0,%r9d
movdqa %xmm12,-0x28(%rsp)
jae    1175 <power+0x75>
movdqa 0xe95(%rip),%xmm2
movdqa %xmm2,%xmm9
jmp    12a8 <power+0x1a8>
and    $0xfffffff8,%eax
movdqa 0xe80(%rip),%xmm0
movdqa %xmm12,%xmm8
punpcklbw %xmm8,%xmm8
movdqa %xmm12,%xmm2
punpckhbw %xmm2,%xmm2
movdqa 0xe75(%rip),%xmm5
movdqa %xmm12,%xmm1
punpcklbw %xmm1,%xmm1
punpckhbw %xmm12,%xmm12
movdqa %xmm8,%xmm3
pmullw %xmm8,%xmm3
movdqa %xmm2,%xmm4
pmullw %xmm2,%xmm4
movdqa %xmm1,%xmm6
pmullw %xmm1,%xmm6
movdqa %xmm12,%xmm7
pmullw %xmm12,%xmm7
movdqa %xmm4,%xmm13
movdqa %xmm2,-0x18(%rsp)
pmullw %xmm2,%xmm13
movdqa %xmm3,%xmm14
movdqa %xmm8,%xmm10
pmullw %xmm8,%xmm14
movdqa %xmm7,%xmm15
pmullw %xmm12,%xmm15
movdqa %xmm6,%xmm8
movdqa %xmm1,%xmm11
pmullw %xmm1,%xmm8
movdqa %xmm0,%xmm1
movdqa %xmm0,%xmm2
movdqa %xmm0,%xmm9
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
punpcklbw %xmm2,%xmm2
pmullw %xmm10,%xmm2
punpckhbw %xmm0,%xmm0
pmullw -0x18(%rsp),%xmm0
punpcklbw %xmm9,%xmm9
pmullw %xmm11,%xmm9
punpckhbw %xmm1,%xmm1
pmullw %xmm12,%xmm1
pmullw %xmm3,%xmm2
pmullw %xmm14,%xmm2
pmullw %xmm4,%xmm0
pmullw %xmm13,%xmm0
pmullw %xmm6,%xmm9
pmullw %xmm8,%xmm9
pmullw %xmm7,%xmm1
pmullw %xmm15,%xmm1
pmullw %xmm4,%xmm0
pand   %xmm5,%xmm0
pmullw %xmm3,%xmm2
pand   %xmm5,%xmm2
packuswb %xmm0,%xmm2
pmullw %xmm7,%xmm1
pand   %xmm5,%xmm1
pmullw %xmm6,%xmm9
pand   %xmm5,%xmm9
packuswb %xmm1,%xmm9
movdqa %xmm2,%xmm0
movdqa %xmm9,%xmm1
add    $0xfffffff8,%eax
jne    1220 <power+0x120>
test   %edx,%edx
movdqa -0x28(%rsp),%xmm6
je     132a <power+0x22a>
movdqa %xmm6,%xmm0
punpckhbw %xmm0,%xmm0
movdqa 0xd4e(%rip),%xmm1
movdqa %xmm6,%xmm3
punpcklbw %xmm3,%xmm3
movdqa %xmm6,%xmm4
punpckhbw %xmm4,%xmm4
punpcklbw %xmm6,%xmm6
cs nopw 0x0(%rax,%rax,1)
movdqa %xmm2,%xmm5
punpckhbw %xmm5,%xmm5
pmullw %xmm0,%xmm5
pand   %xmm1,%xmm5
punpcklbw %xmm2,%xmm2
pmullw %xmm3,%xmm2
pand   %xmm1,%xmm2
packuswb %xmm5,%xmm2
movdqa %xmm9,%xmm5
punpckhbw %xmm5,%xmm5
pmullw %xmm4,%xmm5
pand   %xmm1,%xmm5
punpcklbw %xmm9,%xmm9
pmullw %xmm6,%xmm9
pand   %xmm1,%xmm9
packuswb %xmm5,%xmm9
add    $0xffffffff,%edx
jne    12e0 <power+0x1e0>
movdqa %xmm2,%xmm0
punpckhbw %xmm0,%xmm0
movdqa %xmm9,%xmm1
punpckhbw %xmm1,%xmm1
pmullw %xmm0,%xmm1
punpcklbw %xmm2,%xmm2
punpcklbw %xmm9,%xmm9
pmullw %xmm2,%xmm9
pmullw %xmm1,%xmm9
pshufd $0xee,%xmm9,%xmm0
pmullw %xmm9,%xmm0
pshufd $0x55,%xmm0,%xmm1
pmullw %xmm0,%xmm1
movdqa %xmm1,%xmm0
psrld  $0x10,%xmm0
pmullw %xmm1,%xmm0
movd   %xmm0,%eax
cmp    %esi,%ecx
je     1428 <power+0x328>
test   $0x18,%sil
je     1429 <power+0x329>
mov    %esi,%r9d
and    $0xfffffff8,%r9d
mov    %esi,%edx
and    $0x7,%edx
movzbl %al,%eax
movd   %eax,%xmm1
movdqa 0xc7c(%rip),%xmm0
pandn  %xmm1,%xmm0
por    0xc80(%rip),%xmm0
movd   %r8d,%xmm1
punpcklbw %xmm1,%xmm1
pshuflw $0x0,%xmm1,%xmm1
sub    %r9d,%ecx
punpcklbw %xmm1,%xmm1
movdqa 0xc43(%rip),%xmm2
nopl   (%rax)
punpcklbw %xmm0,%xmm0
pmullw %xmm1,%xmm0
pand   %xmm2,%xmm0
packuswb %xmm0,%xmm0
add    $0x8,%ecx
jne    13d0 <power+0x2d0>
punpcklbw %xmm0,%xmm0
pshufd $0xee,%xmm0,%xmm1
pmullw %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
pmullw %xmm1,%xmm0
movdqa %xmm0,%xmm1
psrld  $0x10,%xmm1
pmullw %xmm0,%xmm1
movd   %xmm1,%eax
cmp    %esi,%r9d
je     1428 <power+0x328>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mul    %dil
add    $0xffffffff,%edx
jne    1420 <power+0x320>
ret
and    $0x1f,%esi
jmp    110f <power+0xf>

LLVM IR (-O0):
define signext i8 @power(i32 %0, i32 %1) {
%3 = alloca i8
%4 = alloca i32
%5 = alloca i32
store i32 %0, i32* %4
store i32 %1, i32* %5
%6 = load i32, i32* %5
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8
8: ; preds = %2
store i8 1, i8* %3
br label %20
9: ; preds = %2
%10 = load i32, i32* %4
%11 = trunc i32 %10 to i8
%12 = sext i8 %11 to i32
%13 = load i32, i32* %4
%14 = load i32, i32* %5
%15 = sub nsw i32 %14, 1
%16 = call signext i8 @power(i32 %13, i32 %15)
%17 = sext i8 %16 to i32
%18 = mul nsw i32 %12, %17
%19 = trunc i32 %18 to i8
store i8 %19, i8* %3
br label %20
20: ; preds = %9, %8
%21 = load i8, i8* %3
ret i8 %21
}

LLVM IR (-O2):
define signext i8 @power(i32 %0, i32 %1) {
%3 = icmp eq i32 %1, 0
br i1 %3, label %94, label %4
4: ; preds = %2
%5 = trunc i32 %0 to i8
%6 = icmp ult i32 %1, 8
br i1 %6, label %85, label %7
7: ; preds = %4
%8 = icmp ult i32 %1, 32
br i1 %8, label %68, label %9
9: ; preds = %7
%10 = and i32 %1, -32
%11 = insertelement <16 x i8> poison, i8 %5, i64 0
%12 = shufflevector <16 x i8> %11, <16 x i8> poison, <16 x i32> zeroinitializer
%13 = insertelement <16 x i8> poison, i8 %5, i64 0
%14 = shufflevector <16 x i8> %13, <16 x i8> poison, <16 x i32> zeroinitializer
%15 = add i32 %10, -32
%16 = lshr exact i32 %15, 5
%17 = add nuw nsw i32 %16, 1
%18 = and i32 %17, 7
%19 = icmp ult i32 %15, 224
br i1 %19, label %44, label %20
20: ; preds = %9
%21 = and i32 %17, 268435448
br label %22
22: ; preds = %22, %20
%23 = phi <16 x i8> [ <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, %20 ], [ %40, %22 ]
%24 = phi <16 x i8> [ <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, %20 ], [ %41, %22 ]
%25 = phi i32 [ 0, %20 ], [ %42, %22 ]
%26 = mul <16 x i8> %23, %12
%27 = mul <16 x i8> %24, %14
%28 = mul <16 x i8> %26, %12
%29 = mul <16 x i8> %27, %14
%30 = mul <16 x i8> %28, %12
%31 = mul <16 x i8> %29, %14
%32 = mul <16 x i8> %30, %12
%33 = mul <16 x i8> %31, %14
%34 = mul <16 x i8> %32, %12
%35 = mul <16 x i8> %33, %14
%36 = mul <16 x i8> %34, %12
%37 = mul <16 x i8> %35, %14
%38 = mul <16 x i8> %36, %12
%39 = mul <16 x i8> %37, %14
%40 = mul <16 x i8> %38, %12
%41 = mul <16 x i8> %39, %14
%42 = add i32 %25, 8
%43 = icmp eq i32 %42, %21
br i1 %43, label %44, label %22
44: ; preds = %22, %9
%45 = phi <16 x i8> [ undef, %9 ], [ %40, %22 ]
%46 = phi <16 x i8> [ undef, %9 ], [ %41, %22 ]
%47 = phi <16 x i8> [ <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, %9 ], [ %40, %22 ]
%48 = phi <16 x i8> [ <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, %9 ], [ %41, %22 ]
%49 = icmp eq i32 %18, 0
br i1 %49, label %58, label %50
50: ; preds = %44, %50
%51 = phi <16 x i8> [ %54, %50 ], [ %47, %44 ]
%52 = phi <16 x i8> [ %55, %50 ], [ %48, %44 ]
%53 = phi i32 [ %56, %50 ], [ 0, %44 ]
%54 = mul <16 x i8> %51, %12
%55 = mul <16 x i8> %52, %14
%56 = add i32 %53, 1
%57 = icmp eq i32 %56, %18
br i1 %57, label %58, label %50
58: ; preds = %50, %44
%59 = phi <16 x i8> [ %45, %44 ], [ %54, %50 ]
%60 = phi <16 x i8> [ %46, %44 ], [ %55, %50 ]
%61 = mul <16 x i8> %60, %59
%62 = call i8 @llvm.vector.reduce.mul.v16i8(<16 x i8> %61)
%63 = icmp eq i32 %10, %1
br i1 %63, label %94, label %64
64: ; preds = %58
%65 = and i32 %1, 31
%66 = and i32 %1, 24
%67 = icmp eq i32 %66, 0
br i1 %67, label %85, label %68
68: ; preds = %7, %64
%69 = phi i8 [ 1, %7 ], [ %62, %64 ]
%70 = phi i32 [ 0, %7 ], [ %10, %64 ]
%71 = and i32 %1, -8
%72 = and i32 %1, 7
%73 = insertelement <8 x i8> <i8 poison, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, i8 %69, i64 0
%74 = insertelement <8 x i8> poison, i8 %5, i64 0
%75 = shufflevector <8 x i8> %74, <8 x i8> poison, <8 x i32> zeroinitializer
br label %76
76: ; preds = %76, %68
%77 = phi i32 [ %70, %68 ], [ %80, %76 ]
%78 = phi <8 x i8> [ %73, %68 ], [ %79, %76 ]
%79 = mul <8 x i8> %78, %75
%80 = add nuw i32 %77, 8
%81 = icmp eq i32 %80, %71
br i1 %81, label %82, label %76
82: ; preds = %76
%83 = call i8 @llvm.vector.reduce.mul.v8i8(<8 x i8> %79)
%84 = icmp eq i32 %71, %1
br i1 %84, label %94, label %85
85: ; preds = %4, %64, %82
%86 = phi i32 [ %1, %4 ], [ %65, %64 ], [ %72, %82 ]
%87 = phi i8 [ 1, %4 ], [ %62, %64 ], [ %83, %82 ]
br label %88
88: ; preds = %85, %88
%89 = phi i32 [ %91, %88 ], [ %86, %85 ]
%90 = phi i8 [ %92, %88 ], [ %87, %85 ]
%91 = add nsw i32 %89, -1
%92 = mul i8 %90, %5
%93 = icmp eq i32 %91, 0
br i1 %93, label %94, label %88
94: ; preds = %88, %58, %82, %2
%95 = phi i8 [ 1, %2 ], [ %62, %58 ], [ %83, %82 ], [ %92, %88 ]
ret i8 %95
}