#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 */
int /*<<< orphan*/ strcat(char *, char *);
int strlen(char *);
void itoa(char *str, long val) {
  if (0 == val) {
    strcat(str, "0");
  } else {
    char digs[20];
    int len = 0, pos;
    if (val < 0) {
      strcat(str, "-");
      val = -val;
    }
    while (val > 0) {
      digs[len++] = '0' + (val % 10);
      val /= 10;
    }
    pos = strlen(str);
    while (--len >= 0) {
      str[pos++] = digs[len];
    }
    str[pos] = '\0';
  }
}


x86 assembly (clang, -O0):
<itoa>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
xor    %eax,%eax
cmp    -0x10(%rbp),%rax
jne    1151 <itoa+0x31>
mov    -0x8(%rbp),%rdi
lea    0xeb9(%rip),%rsi
call   1040 <strcat@plt>
jmp    1215 <itoa+0xf5>
movl   $0x0,-0x34(%rbp)
cmpq   $0x0,-0x10(%rbp)
jge    117d <itoa+0x5d>
mov    -0x8(%rbp),%rdi
lea    0xe94(%rip),%rsi
call   1040 <strcat@plt>
xor    %eax,%eax
sub    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
jmp    1182 <itoa+0x62>
cmpq   $0x0,-0x10(%rbp)
jle    11c9 <itoa+0xa9>
mov    -0x10(%rbp),%rax
mov    $0xa,%ecx
cqto
idiv   %rcx
add    $0x30,%rdx
mov    %dl,%cl
mov    -0x34(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x34(%rbp)
cltq
mov    %cl,-0x30(%rbp,%rax,1)
mov    -0x10(%rbp),%rax
mov    $0xa,%ecx
cqto
idiv   %rcx
mov    %rax,-0x10(%rbp)
jmp    1182 <itoa+0x62>
mov    -0x8(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,-0x38(%rbp)
mov    -0x34(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x34(%rbp)
cmp    $0x0,%eax
jl     1209 <itoa+0xe9>
movslq -0x34(%rbp),%rax
mov    -0x30(%rbp,%rax,1),%dl
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x38(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11d5 <itoa+0xb5>
mov    -0x8(%rbp),%rax
movslq -0x38(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<itoa>:
push   %r15
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %rdi,%r14
test   %rsi,%rsi
je     127d <itoa+0x15d>
mov    %rsi,%rbx
jns    114c <itoa+0x2c>
lea    0xec1(%rip),%rsi
mov    %r14,%rdi
call   1040 <strcat@plt>
neg    %rbx
xor    %r15d,%r15d
movabs $0xcccccccccccccccd,%rcx
cc cc cc
nopl   0x0(%rax)
mov    %rbx,%rax
mul    %rcx
shr    $0x3,%rdx
lea    (%rdx,%rdx,1),%eax
lea    (%rax,%rax,4),%eax
mov    %ebx,%esi
sub    %eax,%esi
or     $0x30,%sil
mov    %sil,(%rsp,%r15,1)
add    $0x1,%r15
cmp    $0x9,%rbx
mov    %rdx,%rbx
ja     1160 <itoa+0x40>
mov    %r14,%rdi
call   1030 <strlen@plt>
test   %r15d,%r15d
jle    12ba <itoa+0x19a>
mov    %r15d,%esi
movslq %eax,%rdi
cmp    $0x20,%rsi
jb     1295 <itoa+0x175>
lea    -0x1(%rsi),%rax
lea    -0x1(%r15),%ecx
cmp    %eax,%ecx
jb     1295 <itoa+0x175>
shr    $0x20,%rax
jne    1295 <itoa+0x175>
lea    -0x1(%r15),%rcx
mov    %r15d,%edx
and    $0x1f,%r15d
sub    %r15,%rsi
mov    %rsi,%rax
add    %rdi,%rax
sub    %r15,%rdx
lea    (%rdi,%r14,1),%rsi
add    $0x10,%rsi
xor    %edi,%edi
pxor   %xmm0,%xmm0
nopl   0x0(%rax)
mov    %ecx,%ebx
movdqu -0x1f(%rsp,%rbx,1),%xmm1
movdqu -0xf(%rsp,%rbx,1),%xmm2
movdqa %xmm2,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm3,%xmm2
movdqa %xmm1,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm3,%xmm1
movdqu %xmm2,-0x10(%rsi,%rdi,1)
movdqu %xmm1,(%rsi,%rdi,1)
add    $0x20,%rdi
add    $0xffffffffffffffe0,%rcx
cmp    %rdi,%rdx
jne    11f0 <itoa+0xd0>
test   %r15,%r15
jne    129b <itoa+0x17b>
jmp    12ba <itoa+0x19a>
lea    0xd7c(%rip),%rsi
mov    %r14,%rdi
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %r15
jmp    1040 <strcat@plt>
mov    %rdi,%rax
mov    %rsi,%r15
add    $0x1,%r15
nop
lea    -0x2(%r15),%ecx
movzbl (%rsp,%rcx,1),%ecx
mov    %cl,(%r14,%rax,1)
add    $0x1,%rax
add    $0xffffffffffffffff,%r15
cmp    $0x1,%r15
ja     12a0 <itoa+0x180>
cltq
movb   $0x0,(%r14,%rax,1)
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@.str = [2 x i8] c"0\00"
@.str.1 = [2 x i8] c"-\00"
define void @itoa(i8* %0, i64 %1) {
%3 = alloca i8*
%4 = alloca i64
%5 = alloca [20 x i8]
%6 = alloca i32
%7 = alloca i32
store i8* %0, i8** %3
store i64 %1, i64* %4
%8 = load i64, i64* %4
%9 = icmp eq i64 0, %8
br i1 %9, label %10, label %13
10: ; preds = %2
%11 = load i8*, i8** %3
%12 = call i32 @strcat(i8* %11, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
br label %58
13: ; preds = %2
store i32 0, i32* %6
%14 = load i64, i64* %4
%15 = icmp slt i64 %14, 0
br i1 %15, label %16, label %21
16: ; preds = %13
%17 = load i8*, i8** %3
%18 = call i32 @strcat(i8* %17, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0))
%19 = load i64, i64* %4
%20 = sub nsw i64 0, %19
store i64 %20, i64* %4
br label %21
21: ; preds = %16, %13
br label %22
22: ; preds = %25, %21
%23 = load i64, i64* %4
%24 = icmp sgt i64 %23, 0
br i1 %24, label %25, label %36
25: ; preds = %22
%26 = load i64, i64* %4
%27 = srem i64 %26, 10
%28 = add nsw i64 48, %27
%29 = trunc i64 %28 to i8
%30 = load i32, i32* %6
%31 = add nsw i32 %30, 1
store i32 %31, i32* %6
%32 = sext i32 %30 to i64
%33 = getelementptr inbounds [20 x i8], [20 x i8]* %5, i64 0, i64 %32
store i8 %29, i8* %33
%34 = load i64, i64* %4
%35 = sdiv i64 %34, 10
store i64 %35, i64* %4
br label %22
36: ; preds = %22
%37 = load i8*, i8** %3
%38 = call i32 @strlen(i8* %37)
store i32 %38, i32* %7
br label %39
39: ; preds = %43, %36
%40 = load i32, i32* %6
%41 = add nsw i32 %40, -1
store i32 %41, i32* %6
%42 = icmp sge i32 %41, 0
br i1 %42, label %43, label %53
43: ; preds = %39
%44 = load i32, i32* %6
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [20 x i8], [20 x i8]* %5, i64 0, i64 %45
%47 = load i8, i8* %46
%48 = load i8*, i8** %3
%49 = load i32, i32* %7
%50 = add nsw i32 %49, 1
store i32 %50, i32* %7
%51 = sext i32 %49 to i64
%52 = getelementptr inbounds i8, i8* %48, i64 %51
store i8 %47, i8* %52
br label %39
53: ; preds = %39
%54 = load i8*, i8** %3
%55 = load i32, i32* %7
%56 = sext i32 %55 to i64
%57 = getelementptr inbounds i8, i8* %54, i64 %56
store i8 0, i8* %57
br label %58
58: ; preds = %53, %10
ret void
}

LLVM IR (-O2):
@.str = [2 x i8] c"0\00"
@.str.1 = [2 x i8] c"-\00"
define void @itoa(i8* %0, i64 %1) {
%3 = alloca [20 x i8]
%4 = icmp eq i64 %1, 0
br i1 %4, label %5, label %7
5: ; preds = %2
%6 = tail call i32 @strcat(i8* %0, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
br label %86
7: ; preds = %2
%8 = getelementptr inbounds [20 x i8], [20 x i8]* %3, i64 0, i64 0
%9 = icmp slt i64 %1, 0
br i1 %9, label %10, label %13
10: ; preds = %7
%11 = tail call i32 @strcat(i8* %0, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0))
%12 = sub nsw i64 0, %1
br label %13
13: ; preds = %7, %10
%14 = phi i64 [ %12, %10 ], [ %1, %7 ]
br label %15
15: ; preds = %13, %15
%16 = phi i64 [ %21, %15 ], [ 0, %13 ]
%17 = phi i64 [ %23, %15 ], [ %14, %13 ]
%18 = urem i64 %17, 10
%19 = trunc i64 %18 to i8
%20 = or i8 %19, 48
%21 = add nuw i64 %16, 1
%22 = getelementptr inbounds [20 x i8], [20 x i8]* %3, i64 0, i64 %16
store i8 %20, i8* %22
%23 = udiv i64 %17, 10
%24 = icmp ult i64 %17, 10
br i1 %24, label %25, label %15
25: ; preds = %15
%26 = trunc i64 %21 to i32
%27 = tail call i32 @strlen(i8* %0)
%28 = icmp sgt i32 %26, 0
br i1 %28, label %29, label %82
29: ; preds = %25
%30 = and i64 %21, 4294967295
%31 = sext i32 %27 to i64
%32 = icmp ult i64 %30, 32
br i1 %32, label %66, label %33
33: ; preds = %29
%34 = add nsw i64 %30, -1
%35 = add i32 %26, -1
%36 = trunc i64 %34 to i32
%37 = icmp ult i32 %35, %36
%38 = icmp ugt i64 %34, 4294967295
%39 = or i1 %37, %38
br i1 %39, label %66, label %40
40: ; preds = %33
%41 = and i64 %21, 31
%42 = sub nsw i64 %30, %41
%43 = add nsw i64 %42, %31
br label %44
44: ; preds = %44, %40
%45 = phi i64 [ 0, %40 ], [ %62, %44 ]
%46 = add i64 %45, %31
%47 = sub i64 %16, %45
%48 = and i64 %47, 4294967295
%49 = getelementptr inbounds [20 x i8], [20 x i8]* %3, i64 0, i64 %48
%50 = getelementptr inbounds i8, i8* %49, i64 -15
%51 = bitcast i8* %50 to <16 x i8>*
%52 = load <16 x i8>, <16 x i8>* %51
%53 = shufflevector <16 x i8> %52, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%54 = getelementptr inbounds i8, i8* %49, i64 -31
%55 = bitcast i8* %54 to <16 x i8>*
%56 = load <16 x i8>, <16 x i8>* %55
%57 = shufflevector <16 x i8> %56, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%58 = getelementptr inbounds i8, i8* %0, i64 %46
%59 = bitcast i8* %58 to <16 x i8>*
store <16 x i8> %53, <16 x i8>* %59
%60 = getelementptr inbounds i8, i8* %58, i64 16
%61 = bitcast i8* %60 to <16 x i8>*
store <16 x i8> %57, <16 x i8>* %61
%62 = add nuw i64 %45, 32
%63 = icmp eq i64 %62, %42
br i1 %63, label %64, label %44
64: ; preds = %44
%65 = icmp eq i64 %41, 0
br i1 %65, label %79, label %66
66: ; preds = %33, %29, %64
%67 = phi i64 [ %31, %33 ], [ %31, %29 ], [ %43, %64 ]
%68 = phi i64 [ %30, %33 ], [ %30, %29 ], [ %41, %64 ]
br label %69
69: ; preds = %66, %69
%70 = phi i64 [ %76, %69 ], [ %67, %66 ]
%71 = phi i64 [ %72, %69 ], [ %68, %66 ]
%72 = add nsw i64 %71, -1
%73 = and i64 %72, 4294967295
%74 = getelementptr inbounds [20 x i8], [20 x i8]* %3, i64 0, i64 %73
%75 = load i8, i8* %74
%76 = add nsw i64 %70, 1
%77 = getelementptr inbounds i8, i8* %0, i64 %70
store i8 %75, i8* %77
%78 = icmp ugt i64 %71, 1
br i1 %78, label %69, label %79
79: ; preds = %69, %64
%80 = phi i64 [ %43, %64 ], [ %76, %69 ]
%81 = trunc i64 %80 to i32
br label %82
82: ; preds = %79, %25
%83 = phi i32 [ %27, %25 ], [ %81, %79 ]
%84 = sext i32 %83 to i64
%85 = getelementptr inbounds i8, i8* %0, i64 %84
store i8 0, i8* %85
br label %86
86: ; preds = %82, %5
ret void
}