int int_to_str(char *mem, int max_len, int number) {
  int pos = 0;
  char temp[max_len];
  while ((number > 0) && (pos < max_len)) {
    short digit = number % 10;
    number /= 10;
    temp[pos++] = (char)(digit + 48);
  }
  for (int i = (pos - 1); i > -1; --i) {
    mem[(pos - i) - 1] = temp[i];
  }
  return pos;
}


x86 assembly (clang, -O0):
<int_to_str>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0xc(%rbp),%eax
mov    %rsp,%rcx
mov    %rcx,-0x20(%rbp)
mov    %rax,%rdx
add    $0xf,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x38(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x28(%rbp)
xor    %eax,%eax
cmpl   $0x0,-0x10(%rbp)
mov    %al,-0x39(%rbp)
jle    115a <int_to_str+0x5a>
mov    -0x14(%rbp),%eax
cmp    -0xc(%rbp),%eax
setl   %al
mov    %al,-0x39(%rbp)
mov    -0x39(%rbp),%al
test   $0x1,%al
jne    116a <int_to_str+0x6a>
jmp    11af <int_to_str+0xaf>
mov    -0x10(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
mov    %dx,%ax
mov    %ax,-0x2a(%rbp)
mov    -0x10(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x38(%rbp),%rax
mov    %ecx,-0x10(%rbp)
movswl -0x2a(%rbp),%ecx
add    $0x30,%ecx
mov    %cl,%dl
mov    -0x14(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x14(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    113f <int_to_str+0x3f>
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x30(%rbp)
cmpl   $0xffffffff,-0x30(%rbp)
jle    11ee <int_to_str+0xee>
mov    -0x38(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    -0x30(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x30(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x30(%rbp)
jmp    11b8 <int_to_str+0xb8>
mov    -0x14(%rbp),%eax
mov    -0x20(%rbp),%rcx
mov    %rcx,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<int_to_str>:
push   %rbp
mov    %rsp,%rbp
mov    %esi,%r10d
mov    %rsp,%r9
lea    0xf(%r10),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r9
mov    %r9,%rsp
xor    %eax,%eax
test   %edx,%edx
jle    12d6 <int_to_str+0x1d6>
test   %esi,%esi
jle    12d6 <int_to_str+0x1d6>
xor    %eax,%eax
mov    $0xcccccccd,%r8d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %edx,%r11d
mov    %edx,%edx
imul   %r8,%rdx
shr    $0x23,%rdx
lea    (%rdx,%rdx,1),%ecx
lea    (%rcx,%rcx,4),%ecx
mov    %r11d,%esi
sub    %ecx,%esi
or     $0x30,%sil
mov    %sil,(%r9,%rax,1)
add    $0x1,%rax
cmp    $0xa,%r11d
jb     116f <int_to_str+0x6f>
cmp    %r10,%rax
jb     1140 <int_to_str+0x40>
test   %eax,%eax
jle    12d6 <int_to_str+0x1d6>
lea    -0x1(%rax),%rcx
mov    %rax,%rdx
cmp    $0x7,%rcx
jb     12a9 <int_to_str+0x1a9>
movabs $0x7fffffffffffffe0,%r8
ff ff 7f
cmp    $0x1f,%rcx
jae    119f <int_to_str+0x9f>
xor    %esi,%esi
jmp    124a <int_to_str+0x14a>
lea    (%r9,%rax,1),%rcx
add    $0xfffffffffffffff0,%rcx
mov    %rax,%rsi
and    %r8,%rsi
mov    %rax,%r10
and    $0xffffffffffffffe0,%r10
xor    %edx,%edx
pxor   %xmm0,%xmm0
nopw   0x0(%rax,%rax,1)
movdqu -0x10(%rcx),%xmm1
movdqu (%rcx),%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,(%rdi,%rdx,1)
movdqu %xmm1,0x10(%rdi,%rdx,1)
add    $0x20,%rdx
add    $0xffffffffffffffe0,%rcx
cmp    %rdx,%r10
jne    11c0 <int_to_str+0xc0>
cmp    %rsi,%rax
je     12d6 <int_to_str+0x1d6>
test   $0x18,%al
je     12a4 <int_to_str+0x1a4>
add    $0x18,%r8
and    %rax,%r8
mov    %rax,%r10
and    $0xfffffffffffffff8,%r10
mov    %eax,%edx
and    $0x7,%edx
mov    %r9,%rcx
sub    %rsi,%rcx
add    %rax,%rcx
add    $0xfffffffffffffff8,%rcx
pxor   %xmm0,%xmm0
xchg   %ax,%ax
movq   (%rcx),%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm1,%xmm1
movq   %xmm1,(%rdi,%rsi,1)
add    $0x8,%rsi
add    $0xfffffffffffffff8,%rcx
cmp    %rsi,%r10
jne    1270 <int_to_str+0x170>
cmp    %r8,%rax
jne    12a9 <int_to_str+0x1a9>
jmp    12d6 <int_to_str+0x1d6>
mov    %eax,%edx
and    $0x1f,%edx
sub    %rdx,%rdi
add    $0x1,%rdx
add    %rax,%rdi
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movzbl -0x2(%r9,%rdx,1),%ecx
mov    %cl,(%rdi)
add    $0xffffffffffffffff,%rdx
add    $0x1,%rdi
cmp    $0x1,%rdx
ja     12c0 <int_to_str+0x1c0>
mov    %rbp,%rsp
pop    %rbp
ret

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

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