#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 size_t uint8_t;
typedef int /*<<< orphan*/ int32_t;

/* Variables and functions */
int /*<<< orphan*/ itoa(int /*<<< orphan*/, char *, int);
int /*<<< orphan*/ strcat(char *, char const *);
int strlen(char *);
int /*<<< orphan*/ strncpy(char *, char *, size_t);
char *ftoa(float x, char *floatString) {
  int32_t value;
  char intString1[12];
  char intString2[12] = {
      0,
  };
  const char *decimalPoint = ".";
  uint8_t dpLocation;
  if (x > 0)
    x += 0.0005f;
  else
    x -= 0.0005f;
  value = (int32_t)(x * 1000.0f);
  itoa(((value) > 0 ? (value) : -(value)), intString1, 10);
  if (value >= 0)
    intString2[0] = ' ';
  else
    intString2[0] = '-';
  if (strlen(intString1) == 1) {
    intString2[1] = '0';
    intString2[2] = '0';
    intString2[3] = '0';
    strcat(intString2, intString1);
  } else if (strlen(intString1) == 2) {
    intString2[1] = '0';
    intString2[2] = '0';
    strcat(intString2, intString1);
  } else if (strlen(intString1) == 3) {
    intString2[1] = '0';
    strcat(intString2, intString1);
  } else {
    strcat(intString2, intString1);
  }
  dpLocation = strlen(intString2) - 3;
  strncpy(floatString, intString2, dpLocation);
  floatString[dpLocation] = '\0';
  strcat(floatString, decimalPoint);
  strcat(floatString, intString2 + dpLocation);
  return floatString;
}


x86 assembly (clang, -O0):
<ftoa>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movss  %xmm0,-0x4(%rbp)
mov    %rdi,-0x10(%rbp)
lea    -0x2c(%rbp),%rdi
xor    %esi,%esi
mov    $0xc,%edx
call   1050 <memset@plt>
lea    0xe90(%rip),%rax
mov    %rax,-0x38(%rbp)
movss  -0x4(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jbe    11a4 <ftoa+0x54>
movss  0xe6b(%rip),%xmm0
addss  -0x4(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    11ba <ftoa+0x6a>
movss  -0x4(%rbp),%xmm0
movss  0xe4f(%rip),%xmm1
subss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
movss  0xe42(%rip),%xmm0
mulss  -0x4(%rbp),%xmm0
cvttss2si %xmm0,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jle    11e3 <ftoa+0x93>
mov    -0x14(%rbp),%eax
mov    %eax,-0x44(%rbp)
jmp    11eb <ftoa+0x9b>
xor    %eax,%eax
sub    -0x14(%rbp),%eax
mov    %eax,-0x44(%rbp)
mov    -0x44(%rbp),%edi
lea    -0x20(%rbp),%rsi
mov    $0xa,%edx
call   1070 <itoa@plt>
cmpl   $0x0,-0x14(%rbp)
jl     120f <ftoa+0xbf>
movb   $0x20,-0x2c(%rbp)
jmp    1213 <ftoa+0xc3>
movb   $0x2d,-0x2c(%rbp)
lea    -0x20(%rbp),%rdi
call   1040 <strlen@plt>
cmp    $0x1,%eax
jne    1243 <ftoa+0xf3>
movb   $0x30,-0x2b(%rbp)
movb   $0x30,-0x2a(%rbp)
movb   $0x30,-0x29(%rbp)
lea    -0x2c(%rbp),%rdi
lea    -0x20(%rbp),%rsi
call   1060 <strcat@plt>
jmp    12ae <ftoa+0x15e>
lea    -0x20(%rbp),%rdi
call   1040 <strlen@plt>
cmp    $0x2,%eax
jne    126f <ftoa+0x11f>
movb   $0x30,-0x2b(%rbp)
movb   $0x30,-0x2a(%rbp)
lea    -0x2c(%rbp),%rdi
lea    -0x20(%rbp),%rsi
call   1060 <strcat@plt>
jmp    12a9 <ftoa+0x159>
lea    -0x20(%rbp),%rdi
call   1040 <strlen@plt>
cmp    $0x3,%eax
jne    1297 <ftoa+0x147>
movb   $0x30,-0x2b(%rbp)
lea    -0x2c(%rbp),%rdi
lea    -0x20(%rbp),%rsi
call   1060 <strcat@plt>
jmp    12a4 <ftoa+0x154>
lea    -0x2c(%rbp),%rdi
lea    -0x20(%rbp),%rsi
call   1060 <strcat@plt>
jmp    12a9 <ftoa+0x159>
jmp    12ae <ftoa+0x15e>
lea    -0x2c(%rbp),%rdi
call   1040 <strlen@plt>
sub    $0x3,%eax
cltq
mov    %rax,-0x40(%rbp)
mov    -0x10(%rbp),%rdi
lea    -0x2c(%rbp),%rsi
mov    -0x40(%rbp),%rdx
call   1030 <strncpy@plt>
mov    -0x10(%rbp),%rax
mov    -0x40(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x10(%rbp),%rdi
mov    -0x38(%rbp),%rsi
call   1060 <strcat@plt>
mov    -0x10(%rbp),%rdi
lea    -0x2c(%rbp),%rsi
add    -0x40(%rbp),%rsi
call   1060 <strcat@plt>
mov    -0x10(%rbp),%rax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ftoa>:
push   %r15
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %rdi,%r15
xorps  %xmm1,%xmm1
xor    %eax,%eax
ucomiss %xmm1,%xmm0
seta   %al
movl   $0x0,0x10(%rsp)
lea    0xe9a(%rip),%rcx
addss  (%rcx,%rax,4),%xmm0
mulss  0xe95(%rip),%xmm0
cvttss2si %xmm0,%ebx
movq   $0x0,0x9(%rsp)
mov    %ebx,%edi
neg    %edi
cmovs  %ebx,%edi
lea    0x14(%rsp),%r14
mov    %r14,%rsi
mov    $0xa,%edx
call   1060 <itoa@plt>
test   %ebx,%ebx
mov    $0x20,%eax
mov    $0x2d,%ecx
cmovns %eax,%ecx
mov    %cl,0x8(%rsp)
mov    %r14,%rdi
call   1040 <strlen@plt>
cmp    $0x1,%eax
jne    11ca <ftoa+0x8a>
movb   $0x30,0x9(%rsp)
mov    $0x3,%ecx
mov    $0x2,%eax
jmp    11e3 <ftoa+0xa3>
lea    0x14(%rsp),%rdi
call   1040 <strlen@plt>
cmp    $0x2,%eax
jne    124b <ftoa+0x10b>
mov    $0x2,%ecx
mov    $0x1,%eax
movb   $0x30,0x8(%rsp,%rax,1)
movb   $0x30,0x8(%rsp,%rcx,1)
lea    0x8(%rsp),%r14
lea    0x14(%rsp),%rsi
mov    %r14,%rdi
call   1050 <strcat@plt>
mov    %r14,%rdi
call   1040 <strlen@plt>
movslq %eax,%rbx
lea    -0x3(%rbx),%rdx
mov    %r15,%rdi
mov    %r14,%rsi
call   1030 <strncpy@plt>
movb   $0x0,-0x3(%r15,%rbx,1)
lea    0xde6(%rip),%rsi
mov    %r15,%rdi
call   1050 <strcat@plt>
lea    (%rsp,%rbx,1),%rsi
add    $0x5,%rsi
mov    %r15,%rdi
call   1050 <strcat@plt>
mov    %r15,%rax
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret
lea    0x14(%rsp),%rdi
call   1040 <strlen@plt>
mov    $0x1,%ecx
cmp    $0x3,%eax
je     11e8 <ftoa+0xa8>
jmp    11ed <ftoa+0xad>

LLVM IR (-O0):
@.str = [2 x i8] c".\00"
define i8* @ftoa(float %0, i8* %1) {
%3 = alloca float
%4 = alloca i8*
%5 = alloca i32
%6 = alloca [12 x i8]
%7 = alloca [12 x i8]
%8 = alloca i8*
%9 = alloca i64
store float %0, float* %3
store i8* %1, i8** %4
%10 = bitcast [12 x i8]* %7 to i8*
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), i8** %8
%11 = load float, float* %3
%12 = fcmp ogt float %11, 0.000000e+00
br i1 %12, label %13, label %16
13: ; preds = %2
%14 = load float, float* %3
%15 = fadd float %14, 0x3F40624DE0000000
store float %15, float* %3
br label %19
16: ; preds = %2
%17 = load float, float* %3
%18 = fsub float %17, 0x3F40624DE0000000
store float %18, float* %3
br label %19
19: ; preds = %16, %13
%20 = load float, float* %3
%21 = fmul float %20, 1.000000e+03
%22 = fptosi float %21 to i32
store i32 %22, i32* %5
%23 = load i32, i32* %5
%24 = icmp sgt i32 %23, 0
br i1 %24, label %25, label %27
25: ; preds = %19
%26 = load i32, i32* %5
br label %30
27: ; preds = %19
%28 = load i32, i32* %5
%29 = sub nsw i32 0, %28
br label %30
30: ; preds = %27, %25
%31 = phi i32 [ %26, %25 ], [ %29, %27 ]
%32 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%33 = call i32 @itoa(i32 %31, i8* %32, i32 10)
%34 = load i32, i32* %5
%35 = icmp sge i32 %34, 0
br i1 %35, label %36, label %38
36: ; preds = %30
%37 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
store i8 32, i8* %37
br label %40
38: ; preds = %30
%39 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
store i8 45, i8* %39
br label %40
40: ; preds = %38, %36
%41 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%42 = call i32 @strlen(i8* %41)
%43 = icmp eq i32 %42, 1
br i1 %43, label %44, label %51
44: ; preds = %40
%45 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 1
store i8 48, i8* %45
%46 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 2
store i8 48, i8* %46
%47 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 3
store i8 48, i8* %47
%48 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
%49 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%50 = call i32 @strcat(i8* %48, i8* %49)
br label %76
51: ; preds = %40
%52 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%53 = call i32 @strlen(i8* %52)
%54 = icmp eq i32 %53, 2
br i1 %54, label %55, label %61
55: ; preds = %51
%56 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 1
store i8 48, i8* %56
%57 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 2
store i8 48, i8* %57
%58 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
%59 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%60 = call i32 @strcat(i8* %58, i8* %59)
br label %75
61: ; preds = %51
%62 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%63 = call i32 @strlen(i8* %62)
%64 = icmp eq i32 %63, 3
br i1 %64, label %65, label %70
65: ; preds = %61
%66 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 1
store i8 48, i8* %66
%67 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
%68 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%69 = call i32 @strcat(i8* %67, i8* %68)
br label %74
70: ; preds = %61
%71 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
%72 = getelementptr inbounds [12 x i8], [12 x i8]* %6, i64 0, i64 0
%73 = call i32 @strcat(i8* %71, i8* %72)
br label %74
74: ; preds = %70, %65
br label %75
75: ; preds = %74, %55
br label %76
76: ; preds = %75, %44
%77 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
%78 = call i32 @strlen(i8* %77)
%79 = sub nsw i32 %78, 3
%80 = sext i32 %79 to i64
store i64 %80, i64* %9
%81 = load i8*, i8** %4
%82 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
%83 = load i64, i64* %9
%84 = call i32 @strncpy(i8* %81, i8* %82, i64 %83)
%85 = load i8*, i8** %4
%86 = load i64, i64* %9
%87 = getelementptr inbounds i8, i8* %85, i64 %86
store i8 0, i8* %87
%88 = load i8*, i8** %4
%89 = load i8*, i8** %8
%90 = call i32 @strcat(i8* %88, i8* %89)
%91 = load i8*, i8** %4
%92 = getelementptr inbounds [12 x i8], [12 x i8]* %7, i64 0, i64 0
%93 = load i64, i64* %9
%94 = getelementptr inbounds i8, i8* %92, i64 %93
%95 = call i32 @strcat(i8* %91, i8* %94)
%96 = load i8*, i8** %4
ret i8* %96
}

LLVM IR (-O2):
@.str = [2 x i8] c".\00"
define i8* @ftoa(float %0, i8* returned %1) {
%3 = alloca [12 x i8]
%4 = alloca [12 x i8]
%5 = getelementptr inbounds [12 x i8], [12 x i8]* %3, i64 0, i64 0
%6 = getelementptr inbounds [12 x i8], [12 x i8]* %4, i64 0, i64 0
%7 = getelementptr inbounds [12 x i8], [12 x i8]* %4, i64 0, i64 1
%8 = fcmp ogt float %0, 0.000000e+00
%9 = select i1 %8, float 0x3F40624DE0000000, float 0xBF40624DE0000000
%10 = fadd float %9, %0
%11 = fmul float %10, 1.000000e+03
%12 = fptosi float %11 to i32
%13 = tail call i32 @llvm.abs.i32(i32 %12, i1 true)
%14 = call i32 @itoa(i32 %13, i8* %5, i32 10)
%15 = icmp sgt i32 %12, -1
%16 = select i1 %15, i8 32, i8 45
store i8 %16, i8* %6
%17 = call i32 @strlen(i8* %5)
%18 = icmp eq i32 %17, 1
br i1 %18, label %19, label %21
19: ; preds = %2
%20 = getelementptr inbounds [12 x i8], [12 x i8]* %4, i64 0, i64 1
store i8 48, i8* %20
br label %27
21: ; preds = %2
%22 = call i32 @strlen(i8* %5)
%23 = icmp eq i32 %22, 2
br i1 %23, label %27, label %24
24: ; preds = %21
%25 = call i32 @strlen(i8* %5)
%26 = icmp eq i32 %25, 3
br i1 %26, label %31, label %34
27: ; preds = %21, %19
%28 = phi i64 [ 2, %19 ], [ 1, %21 ]
%29 = phi i64 [ 3, %19 ], [ 2, %21 ]
%30 = getelementptr inbounds [12 x i8], [12 x i8]* %4, i64 0, i64 %28
store i8 48, i8* %30
br label %31
31: ; preds = %27, %24
%32 = phi i64 [ 1, %24 ], [ %29, %27 ]
%33 = getelementptr inbounds [12 x i8], [12 x i8]* %4, i64 0, i64 %32
store i8 48, i8* %33
br label %34
34: ; preds = %31, %24
%35 = call i32 @strcat(i8* %6, i8* %5)
%36 = call i32 @strlen(i8* %6)
%37 = add nsw i32 %36, -3
%38 = sext i32 %37 to i64
%39 = call i32 @strncpy(i8* %1, i8* %6, i64 %38)
%40 = getelementptr inbounds i8, i8* %1, i64 %38
store i8 0, i8* %40
%41 = call i32 @strcat(i8* %1, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%42 = getelementptr inbounds [12 x i8], [12 x i8]* %4, i64 0, i64 %38
%43 = call i32 @strcat(i8* %1, i8* %42)
ret i8* %1
}