#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 */
char const *spell_number(size_t n) {
  static char buf[128];
  static char const *numbers[] = {" zero", " one", " two",   " three", " four",
                                  " five", " six", " seven", " eight", " nine"};
  size_t tokens[32];
  size_t token_count;
  char const *tok;
  char *pos;
  token_count = 0;
  do {
    tokens[token_count] = n % 10;
    token_count += 1;
    n /= 10;
  } while (n);
  pos = buf;
  while (token_count) {
    token_count -= 1;
    tok = numbers[tokens[token_count]];
    while (tok[0])
      pos++[0] = tok++[0];
  }
  pos[0] = 0;
  return buf;
}


x86 assembly (clang, -O0):
<spell_number>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
mov    %rdi,-0x8(%rbp)
movq   $0x0,-0x118(%rbp)
mov    -0x8(%rbp),%rax
mov    $0xa,%ecx
xor    %edx,%edx
div    %rcx
mov    -0x118(%rbp),%rax
mov    %rdx,-0x110(%rbp,%rax,8)
ff
mov    -0x118(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x118(%rbp)
mov    -0x8(%rbp),%rax
mov    $0xa,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,-0x8(%rbp)
cmpq   $0x0,-0x8(%rbp)
jne    111a <spell_number+0x1a>
lea    0x2f23(%rip),%rax
mov    %rax,-0x128(%rbp)
cmpq   $0x0,-0x118(%rbp)
je     11fd <spell_number+0xfd>
mov    -0x118(%rbp),%rax
sub    $0x1,%rax
mov    %rax,-0x118(%rbp)
mov    -0x118(%rbp),%rax
mov    -0x110(%rbp,%rax,8),%rcx
ff
lea    0x2e86(%rip),%rax
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x120(%rbp)
mov    -0x120(%rbp),%rax
cmpb   $0x0,(%rax)
je     11f8 <spell_number+0xf8>
mov    -0x120(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x120(%rbp)
mov    (%rax),%cl
mov    -0x128(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x128(%rbp)
mov    %cl,(%rax)
jmp    11b5 <spell_number+0xb5>
jmp    1174 <spell_number+0x74>
mov    -0x128(%rbp),%rax
movb   $0x0,(%rax)
lea    0x2e82(%rip),%rax
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<spell_number>:
sub    $0x88,%rsp
mov    %rdi,%rcx
xor    %esi,%esi
movabs $0xcccccccccccccccd,%r8
cc cc cc
cs nopw 0x0(%rax,%rax,1)
mov    %rcx,%rax
mul    %r8
shr    $0x3,%rdx
lea    (%rdx,%rdx,1),%rax
lea    (%rax,%rax,4),%rax
mov    %rcx,%rdi
sub    %rax,%rdi
mov    %rdi,-0x80(%rsp,%rsi,8)
add    $0x1,%rsi
cmp    $0x9,%rcx
mov    %rdx,%rcx
ja     1120 <spell_number+0x20>
mov    %rsi,%rdi
sub    $0x1,%rdi
jae    115c <spell_number+0x5c>
lea    0x2ed6(%rip),%rcx
jmp    11b7 <spell_number+0xb7>
test   $0x1,%sil
jne    1174 <spell_number+0x74>
lea    0x2ec7(%rip),%rcx
mov    %rsi,%rdi
cmp    $0x1,%rsi
je     11b7 <spell_number+0xb7>
jmp    11d6 <spell_number+0xd6>
mov    -0x88(%rsp,%rsi,8),%rax
ff
lea    0x2c7d(%rip),%rcx
mov    (%rcx,%rax,8),%rdx
mov    (%rdx),%al
test   %al,%al
je     11c9 <spell_number+0xc9>
add    $0x1,%rdx
lea    0x2e98(%rip),%rcx
nopl   0x0(%rax,%rax,1)
mov    %al,(%rcx)
add    $0x1,%rcx
movzbl (%rdx),%eax
add    $0x1,%rdx
test   %al,%al
jne    11a0 <spell_number+0xa0>
cmp    $0x1,%rsi
jne    11d6 <spell_number+0xd6>
movb   $0x0,(%rcx)
lea    0x2e6f(%rip),%rax
add    $0x88,%rsp
ret
lea    0x2e60(%rip),%rcx
cmp    $0x1,%rsi
je     11b7 <spell_number+0xb7>
lea    0x2c23(%rip),%rax
jmp    11e5 <spell_number+0xe5>
nop
test   %rdi,%rdi
je     11b7 <spell_number+0xb7>
mov    -0x88(%rsp,%rdi,8),%rdx
ff
mov    (%rax,%rdx,8),%rsi
mov    (%rsi),%dl
test   %dl,%dl
je     1211 <spell_number+0x111>
add    $0x1,%rsi
nopl   0x0(%rax,%rax,1)
mov    %dl,(%rcx)
add    $0x1,%rcx
movzbl (%rsi),%edx
add    $0x1,%rsi
test   %dl,%dl
jne    1200 <spell_number+0x100>
mov    -0x90(%rsp,%rdi,8),%rdx
ff
add    $0xfffffffffffffffe,%rdi
mov    (%rax,%rdx,8),%rsi
mov    (%rsi),%dl
test   %dl,%dl
je     11e0 <spell_number+0xe0>
add    $0x1,%rsi
nopl   0x0(%rax,%rax,1)
mov    %dl,(%rcx)
add    $0x1,%rcx
movzbl (%rsi),%edx
add    $0x1,%rsi
test   %dl,%dl
jne    1230 <spell_number+0x130>
jmp    11e0 <spell_number+0xe0>

LLVM IR (-O0):
@spell_number.buf = internal global [128 x i8] zeroinitializer
@spell_number.numbers = internal global [10 x i8*] [i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.9, i32 0, i32 0)]
@.str = [6 x i8] c" zero\00"
@.str.1 = [5 x i8] c" one\00"
@.str.2 = [5 x i8] c" two\00"
@.str.3 = [7 x i8] c" three\00"
@.str.4 = [6 x i8] c" four\00"
@.str.5 = [6 x i8] c" five\00"
@.str.6 = [5 x i8] c" six\00"
@.str.7 = [7 x i8] c" seven\00"
@.str.8 = [7 x i8] c" eight\00"
@.str.9 = [6 x i8] c" nine\00"
define i8* @spell_number(i64 %0) {
%2 = alloca i64
%3 = alloca [32 x i64]
%4 = alloca i64
%5 = alloca i8*
%6 = alloca i8*
store i64 %0, i64* %2
store i64 0, i64* %4
br label %7
7: ; preds = %16, %1
%8 = load i64, i64* %2
%9 = urem i64 %8, 10
%10 = load i64, i64* %4
%11 = getelementptr inbounds [32 x i64], [32 x i64]* %3, i64 0, i64 %10
store i64 %9, i64* %11
%12 = load i64, i64* %4
%13 = add i64 %12, 1
store i64 %13, i64* %4
%14 = load i64, i64* %2
%15 = udiv i64 %14, 10
store i64 %15, i64* %2
br label %16
16: ; preds = %7
%17 = load i64, i64* %2
%18 = icmp ne i64 %17, 0
br i1 %18, label %7, label %19
19: ; preds = %16
store i8* getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0), i8** %6
br label %20
20: ; preds = %44, %19
%21 = load i64, i64* %4
%22 = icmp ne i64 %21, 0
br i1 %22, label %23, label %45
23: ; preds = %20
%24 = load i64, i64* %4
%25 = sub i64 %24, 1
store i64 %25, i64* %4
%26 = load i64, i64* %4
%27 = getelementptr inbounds [32 x i64], [32 x i64]* %3, i64 0, i64 %26
%28 = load i64, i64* %27
%29 = getelementptr inbounds [10 x i8*], [10 x i8*]* @spell_number.numbers, i64 0, i64 %28
%30 = load i8*, i8** %29
store i8* %30, i8** %5
br label %31
31: ; preds = %36, %23
%32 = load i8*, i8** %5
%33 = getelementptr inbounds i8, i8* %32, i64 0
%34 = load i8, i8* %33
%35 = icmp ne i8 %34, 0
br i1 %35, label %36, label %44
36: ; preds = %31
%37 = load i8*, i8** %5
%38 = getelementptr inbounds i8, i8* %37, i32 1
store i8* %38, i8** %5
%39 = getelementptr inbounds i8, i8* %37, i64 0
%40 = load i8, i8* %39
%41 = load i8*, i8** %6
%42 = getelementptr inbounds i8, i8* %41, i32 1
store i8* %42, i8** %6
%43 = getelementptr inbounds i8, i8* %41, i64 0
store i8 %40, i8* %43
br label %31
44: ; preds = %31
br label %20
45: ; preds = %20
%46 = load i8*, i8** %6
%47 = getelementptr inbounds i8, i8* %46, i64 0
store i8 0, i8* %47
ret i8* getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0)
}

LLVM IR (-O2):
@spell_number.buf = internal global [128 x i8] zeroinitializer
@spell_number.numbers = internal unnamed_addr constant [10 x i8*] [i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.9, i32 0, i32 0)]
@.str = [6 x i8] c" zero\00"
@.str.1 = [5 x i8] c" one\00"
@.str.2 = [5 x i8] c" two\00"
@.str.3 = [7 x i8] c" three\00"
@.str.4 = [6 x i8] c" four\00"
@.str.5 = [6 x i8] c" five\00"
@.str.6 = [5 x i8] c" six\00"
@.str.7 = [7 x i8] c" seven\00"
@.str.8 = [7 x i8] c" eight\00"
@.str.9 = [6 x i8] c" nine\00"
define i8* @spell_number(i64 %0) {
%2 = alloca [32 x i64]
%3 = bitcast [32 x i64]* %2 to i8*
br label %4
4: ; preds = %4, %1
%5 = phi i64 [ %0, %1 ], [ %10, %4 ]
%6 = phi i64 [ 0, %1 ], [ %9, %4 ]
%7 = urem i64 %5, 10
%8 = getelementptr inbounds [32 x i64], [32 x i64]* %2, i64 0, i64 %6
store i64 %7, i64* %8
%9 = add i64 %6, 1
%10 = udiv i64 %5, 10
%11 = icmp ult i64 %5, 10
br i1 %11, label %12, label %4
12: ; preds = %4
%13 = icmp eq i64 %9, 0
br i1 %13, label %75, label %14
14: ; preds = %12
%15 = and i64 %9, 1
%16 = icmp eq i64 %15, 0
br i1 %16, label %32, label %17
17: ; preds = %14
%18 = getelementptr inbounds [32 x i64], [32 x i64]* %2, i64 0, i64 %6
%19 = load i64, i64* %18
%20 = getelementptr inbounds [10 x i8*], [10 x i8*]* @spell_number.numbers, i64 0, i64 %19
%21 = load i8*, i8** %20
%22 = load i8, i8* %21
%23 = icmp eq i8 %22, 0
br i1 %23, label %32, label %24
24: ; preds = %17, %24
%25 = phi i8 [ %30, %24 ], [ %22, %17 ]
%26 = phi i8* [ %29, %24 ], [ getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0), %17 ]
%27 = phi i8* [ %28, %24 ], [ %21, %17 ]
%28 = getelementptr inbounds i8, i8* %27, i64 1
%29 = getelementptr inbounds i8, i8* %26, i64 1
store i8 %25, i8* %26
%30 = load i8, i8* %28
%31 = icmp eq i8 %30, 0
br i1 %31, label %32, label %24
32: ; preds = %17, %24, %14
%33 = phi i8* [ undef, %14 ], [ getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0), %17 ], [ %29, %24 ]
%34 = phi i8* [ getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0), %14 ], [ getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0), %17 ], [ %29, %24 ]
%35 = phi i64 [ %9, %14 ], [ %6, %24 ], [ %6, %17 ]
%36 = icmp eq i64 %6, 0
br i1 %36, label %75, label %57
37: ; preds = %67, %57
%38 = phi i8* [ %58, %57 ], [ %72, %67 ]
%39 = add i64 %59, -2
%40 = getelementptr inbounds [32 x i64], [32 x i64]* %2, i64 0, i64 %39
%41 = load i64, i64* %40
%42 = getelementptr inbounds [10 x i8*], [10 x i8*]* @spell_number.numbers, i64 0, i64 %41
%43 = load i8*, i8** %42
%44 = load i8, i8* %43
%45 = icmp eq i8 %44, 0
br i1 %45, label %54, label %46
46: ; preds = %37, %46
%47 = phi i8 [ %52, %46 ], [ %44, %37 ]
%48 = phi i8* [ %51, %46 ], [ %38, %37 ]
%49 = phi i8* [ %50, %46 ], [ %43, %37 ]
%50 = getelementptr inbounds i8, i8* %49, i64 1
%51 = getelementptr inbounds i8, i8* %48, i64 1
store i8 %47, i8* %48
%52 = load i8, i8* %50
%53 = icmp eq i8 %52, 0
br i1 %53, label %54, label %46
54: ; preds = %46, %37
%55 = phi i8* [ %38, %37 ], [ %51, %46 ]
%56 = icmp eq i64 %39, 0
br i1 %56, label %75, label %57
57: ; preds = %32, %54
%58 = phi i8* [ %55, %54 ], [ %34, %32 ]
%59 = phi i64 [ %39, %54 ], [ %35, %32 ]
%60 = add i64 %59, -1
%61 = getelementptr inbounds [32 x i64], [32 x i64]* %2, i64 0, i64 %60
%62 = load i64, i64* %61
%63 = getelementptr inbounds [10 x i8*], [10 x i8*]* @spell_number.numbers, i64 0, i64 %62
%64 = load i8*, i8** %63
%65 = load i8, i8* %64
%66 = icmp eq i8 %65, 0
br i1 %66, label %37, label %67
67: ; preds = %57, %67
%68 = phi i8 [ %73, %67 ], [ %65, %57 ]
%69 = phi i8* [ %72, %67 ], [ %58, %57 ]
%70 = phi i8* [ %71, %67 ], [ %64, %57 ]
%71 = getelementptr inbounds i8, i8* %70, i64 1
%72 = getelementptr inbounds i8, i8* %69, i64 1
store i8 %68, i8* %69
%73 = load i8, i8* %71
%74 = icmp eq i8 %73, 0
br i1 %74, label %37, label %67
75: ; preds = %32, %54, %12
%76 = phi i8* [ getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0), %12 ], [ %33, %32 ], [ %55, %54 ]
store i8 0, i8* %76
ret i8* getelementptr inbounds ([128 x i8], [128 x i8]* @spell_number.buf, i64 0, i64 0)
}