#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
float expf(float);
float logf(float);
float powf(float x, float y) {
  if (y == 0.0)
    return 1.0;
  if (y == 1.0)
    return x;
  if (x <= 0.0)
    return 0.0;
  return expf(logf(x) * y);
}


x86 assembly (clang, -O0):
<powf>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movss  %xmm0,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1160 <powf+0x40>
jp     1160 <powf+0x40>
movss  0xeb2(%rip),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    11cc <powf+0xac>
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe8f(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1190 <powf+0x70>
jp     1190 <powf+0x70>
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    11cc <powf+0xac>
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
xorps  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jb     11b3 <powf+0x93>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    11cc <powf+0xac>
movss  -0x8(%rbp),%xmm0
call   1030 <logf@plt>
mulss  -0xc(%rbp),%xmm0
call   1040 <expf@plt>
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<powf>:
push   %rax
xorps  %xmm2,%xmm2
ucomiss %xmm2,%xmm1
jne    1135 <powf+0x15>
jp     1135 <powf+0x15>
movss  0xecd(%rip),%xmm2
jmp    1164 <powf+0x44>
ucomiss 0xec4(%rip),%xmm1
jne    1145 <powf+0x25>
jp     1145 <powf+0x25>
movaps %xmm0,%xmm2
jmp    1164 <powf+0x44>
xorps  %xmm2,%xmm2
ucomiss %xmm0,%xmm2
jae    1164 <powf+0x44>
movss  %xmm1,0x4(%rsp)
call   1030 <logf@plt>
mulss  0x4(%rsp),%xmm0
pop    %rax
jmp    1040 <expf@plt>
movaps %xmm2,%xmm0
pop    %rax
ret

LLVM IR (-O0):
define float @powf(float %0, float %1) {
%3 = alloca float
%4 = alloca float
%5 = alloca float
store float %0, float* %4
store float %1, float* %5
%6 = load float, float* %5
%7 = fpext float %6 to double
%8 = fcmp oeq double %7, 0.000000e+00
br i1 %8, label %9, label %10
9: ; preds = %2
store float 1.000000e+00, float* %3
br label %27
10: ; preds = %2
%11 = load float, float* %5
%12 = fpext float %11 to double
%13 = fcmp oeq double %12, 1.000000e+00
br i1 %13, label %14, label %16
14: ; preds = %10
%15 = load float, float* %4
store float %15, float* %3
br label %27
16: ; preds = %10
%17 = load float, float* %4
%18 = fpext float %17 to double
%19 = fcmp ole double %18, 0.000000e+00
br i1 %19, label %20, label %21
20: ; preds = %16
store float 0.000000e+00, float* %3
br label %27
21: ; preds = %16
%22 = load float, float* %4
%23 = call float @logf(float %22)
%24 = load float, float* %5
%25 = fmul float %23, %24
%26 = call float @expf(float %25)
store float %26, float* %3
br label %27
27: ; preds = %21, %20, %14, %9
%28 = load float, float* %3
ret float %28
}

LLVM IR (-O2):
define float @powf(float %0, float %1) {
%3 = fcmp oeq float %1, 0.000000e+00
br i1 %3, label %12, label %4
4: ; preds = %2
%5 = fcmp oeq float %1, 1.000000e+00
br i1 %5, label %12, label %6
6: ; preds = %4
%7 = fcmp ugt float %0, 0.000000e+00
br i1 %7, label %8, label %12
8: ; preds = %6
%9 = tail call float @logf(float %0)
%10 = fmul float %9, %1
%11 = tail call float @expf(float %10)
br label %12
12: ; preds = %6, %4, %2, %8
%13 = phi float [ %11, %8 ], [ 1.000000e+00, %2 ], [ %0, %4 ], [ 0.000000e+00, %6 ]
ret float %13
}