#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 */
typedef int uint8_t;
typedef int uint64_t;

/* Variables and functions */
int /*<<< orphan*/ powl(long double, long double);
uint64_t geohex_pow3(uint8_t y) {
  if (y > 18) {
    return (uint64_t)powl(3.0L, (long double)y);
  } else {
    static const uint64_t GEOHEX3_CALCED_POW3[] = {
        (1),
        ((3ULL)),
        ((3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL)),
        ((3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) * (3ULL) *
         (3ULL) * (3ULL))};
    return GEOHEX3_CALCED_POW3[y];
  }
}


x86 assembly (clang, -O0):
<geohex_pow3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x8(%rbp)
cmpl   $0x12,-0x8(%rbp)
jle    1149 <geohex_pow3+0x39>
mov    -0x8(%rbp),%eax
mov    %eax,-0xc(%rbp)
fildl  -0xc(%rbp)
mov    %rsp,%rax
fstpt  0x10(%rax)
flds   0xec6(%rip)
fstpt  (%rax)
call   1030 <powl@plt>
mov    %eax,-0x4(%rbp)
jmp    115a <geohex_pow3+0x4a>
movslq -0x8(%rbp),%rcx
lea    0xebc(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<geohex_pow3>:
sub    $0x28,%rsp
cmp    $0x13,%edi
jl     1138 <geohex_pow3+0x28>
mov    %edi,0x24(%rsp)
fildl  0x24(%rsp)
flds   0xed9(%rip)
fstpt  (%rsp)
fstpt  0x10(%rsp)
call   1030 <powl@plt>
add    $0x28,%rsp
ret
movslq %edi,%rax
lea    0xece(%rip),%rcx
mov    (%rcx,%rax,4),%eax
add    $0x28,%rsp
ret

LLVM IR (-O0):
@geohex_pow3.GEOHEX3_CALCED_POW3 = internal constant [19 x i32] [i32 1, i32 3, i32 9, i32 27, i32 81, i32 243, i32 729, i32 2187, i32 6561, i32 19683, i32 59049, i32 177147, i32 531441, i32 1594323, i32 4782969, i32 14348907, i32 43046721, i32 129140163, i32 387420489]
define i32 @geohex_pow3(i32 %0) {
%2 = alloca i32
%3 = alloca i32
store i32 %0, i32* %3
%4 = load i32, i32* %3
%5 = icmp sgt i32 %4, 18
br i1 %5, label %6, label %10
6: ; preds = %1
%7 = load i32, i32* %3
%8 = sitofp i32 %7 to x86_fp80
%9 = call i32 @powl(x86_fp80 0xK4000C000000000000000, x86_fp80 %8)
store i32 %9, i32* %2
br label %15
10: ; preds = %1
%11 = load i32, i32* %3
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds [19 x i32], [19 x i32]* @geohex_pow3.GEOHEX3_CALCED_POW3, i64 0, i64 %12
%14 = load i32, i32* %13
store i32 %14, i32* %2
br label %15
15: ; preds = %10, %6
%16 = load i32, i32* %2
ret i32 %16
}

LLVM IR (-O2):
@geohex_pow3.GEOHEX3_CALCED_POW3 = internal unnamed_addr constant [19 x i32] [i32 1, i32 3, i32 9, i32 27, i32 81, i32 243, i32 729, i32 2187, i32 6561, i32 19683, i32 59049, i32 177147, i32 531441, i32 1594323, i32 4782969, i32 14348907, i32 43046721, i32 129140163, i32 387420489]
define i32 @geohex_pow3(i32 %0) {
%2 = icmp sgt i32 %0, 18
br i1 %2, label %3, label %6
3: ; preds = %1
%4 = sitofp i32 %0 to x86_fp80
%5 = tail call i32 @powl(x86_fp80 0xK4000C000000000000000, x86_fp80 %4)
br label %10
6: ; preds = %1
%7 = sext i32 %0 to i64
%8 = getelementptr inbounds [19 x i32], [19 x i32]* @geohex_pow3.GEOHEX3_CALCED_POW3, i64 0, i64 %7
%9 = load i32, i32* %8
br label %10
10: ; preds = %6, %3
%11 = phi i32 [ %5, %3 ], [ %9, %6 ]
ret i32 %11
}