void ulong_strcnv(unsigned char *str, unsigned long int i) {
  unsigned char backstr[11], j = 0, l = 0, m = 0;
  do {
    backstr[j++] = (i % 10) + '0';
    i /= 10;
  } while (i);
  backstr[j] = '\0';
  for (l = j - 1; m < j; l--) {
    str[m++] = backstr[l];
  }
  str[j] = '\0';
}


x86 assembly (clang, -O0):
<ulong_strcnv>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movb   $0x0,-0x1c(%rbp)
movb   $0x0,-0x1d(%rbp)
movb   $0x0,-0x1e(%rbp)
mov    -0x10(%rbp),%rax
mov    $0xa,%ecx
xor    %edx,%edx
div    %rcx
add    $0x30,%rdx
mov    %dl,%cl
mov    -0x1c(%rbp),%al
mov    %al,%dl
add    $0x1,%dl
mov    %dl,-0x1c(%rbp)
movzbl %al,%eax
mov    %cl,-0x1b(%rbp,%rax,1)
mov    -0x10(%rbp),%rax
mov    $0xa,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,-0x10(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1118 <ulong_strcnv+0x18>
movzbl -0x1c(%rbp),%eax
movb   $0x0,-0x1b(%rbp,%rax,1)
movzbl -0x1c(%rbp),%eax
sub    $0x1,%eax
mov    %al,-0x1d(%rbp)
movzbl -0x1e(%rbp),%eax
movzbl -0x1c(%rbp),%ecx
cmp    %ecx,%eax
jge    11ab <ulong_strcnv+0xab>
movzbl -0x1d(%rbp),%eax
mov    -0x1b(%rbp,%rax,1),%dl
mov    -0x8(%rbp),%rax
mov    -0x1e(%rbp),%cl
mov    %cl,%sil
add    $0x1,%sil
mov    %sil,-0x1e(%rbp)
movzbl %cl,%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x1d(%rbp),%al
add    $0xff,%al
mov    %al,-0x1d(%rbp)
jmp    116e <ulong_strcnv+0x6e>
mov    -0x8(%rbp),%rax
movzbl -0x1c(%rbp),%ecx
movb   $0x0,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<ulong_strcnv>:
push   %r15
push   %r14
push   %rbx
mov    $0xfe,%r15b
xor    %r8d,%r8d
movabs $0xcccccccccccccccd,%r9
cc cc cc
cs nopw 0x0(%rax,%rax,1)
nop
lea    0x2(%r15),%ebx
mov    %rsi,%rax
mul    %r9
shr    $0x3,%rdx
lea    (%rdx,%rdx,1),%eax
lea    (%rax,%rax,4),%ecx
mov    %esi,%eax
sub    %ecx,%eax
or     $0x30,%al
add    $0x1,%r8b
movzbl %bl,%ecx
mov    %al,-0xb(%rsp,%rcx,1)
add    $0x1,%r15b
cmp    $0x9,%rsi
mov    %rdx,%rsi
ja     1120 <ulong_strcnv+0x20>
lea    0x2(%r15),%r9d
movzbl %r9b,%r11d
movb   $0x0,-0xb(%rsp,%r11,1)
cmp    $0xfe,%r15b
je     1214 <ulong_strcnv+0x114>
mov    %al,(%rdi)
cmp    $0xff,%r15b
je     1214 <ulong_strcnv+0x114>
lea    -0x1(%r11),%r10
mov    $0x1,%esi
cmp    $0x8,%r10
jae    121f <ulong_strcnv+0x11f>
mov    %r15d,%edx
mov    %r11d,%ecx
sub    %esi,%ecx
mov    %rsi,%rax
not    %rax
add    %r11,%rax
test   $0x3,%cl
je     11c8 <ulong_strcnv+0xc8>
sub    %sil,%r9b
movzbl %r9b,%ecx
and    $0x3,%ecx
nopl   0x0(%rax)
movzbl %dl,%edx
movzbl -0xb(%rsp,%rdx,1),%ebx
mov    %bl,(%rdi,%rsi,1)
add    $0x1,%rsi
add    $0xff,%dl
add    $0xffffffffffffffff,%rcx
jne    11b0 <ulong_strcnv+0xb0>
cmp    $0x3,%rax
jb     1214 <ulong_strcnv+0x114>
xchg   %ax,%ax
movzbl %dl,%edx
movzbl -0xb(%rsp,%rdx,1),%eax
mov    %al,(%rdi,%rsi,1)
lea    -0x1(%rdx),%eax
movzbl %al,%eax
movzbl -0xb(%rsp,%rax,1),%eax
mov    %al,0x1(%rdi,%rsi,1)
lea    -0x2(%rdx),%eax
movzbl %al,%eax
movzbl -0xb(%rsp,%rax,1),%eax
mov    %al,0x2(%rdi,%rsi,1)
lea    -0x3(%rdx),%eax
movzbl %al,%eax
movzbl -0xb(%rsp,%rax,1),%eax
mov    %al,0x3(%rdi,%rsi,1)
add    $0x4,%rsi
add    $0xfc,%dl
cmp    %rsi,%r11
jne    11d0 <ulong_strcnv+0xd0>
movb   $0x0,(%rdi,%r11,1)
pop    %rbx
pop    %r14
pop    %r15
ret
lea    -0x2(%r11),%rax
cmp    %al,%r15b
jb     1189 <ulong_strcnv+0x89>
cmp    $0xff,%rax
ja     1189 <ulong_strcnv+0x89>
cmp    $0x20,%r10
jae    1245 <ulong_strcnv+0x145>
xor    %eax,%eax
jmp    12f6 <ulong_strcnv+0x1f6>
mov    %r10,%rax
and    $0xffffffffffffffe0,%rax
lea    -0x1(%r11),%rdx
and    $0xffffffffffffffe0,%rdx
xor    %esi,%esi
pxor   %xmm0,%xmm0
mov    %r15d,%ebx
nopl   (%rax)
movzbl %bl,%ebx
movdqu -0x2a(%rsp,%rbx,1),%xmm1
movdqu -0x1a(%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,0x1(%rdi,%rsi,1)
movdqu %xmm1,0x11(%rdi,%rsi,1)
add    $0x20,%rsi
add    $0xe0,%bl
cmp    %rsi,%rdx
jne    1260 <ulong_strcnv+0x160>
cmp    %rax,%r10
je     1214 <ulong_strcnv+0x114>
test   $0x18,%r10b
je     1363 <ulong_strcnv+0x263>
mov    %r10,%r14
and    $0xfffffffffffffff8,%r14
add    $0xff,%r8b
and    $0xf8,%r8b
mov    %r15d,%edx
sub    %r8b,%dl
lea    0x1(%r14),%rsi
lea    -0x1(%r11),%rbx
and    $0xfffffffffffffff8,%rbx
sub    %al,%r15b
pxor   %xmm0,%xmm0
xchg   %ax,%ax
movzbl %r15b,%r15d
movq   -0x12(%rsp,%r15,1),%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm1,%xmm1
movq   %xmm1,0x1(%rdi,%rax,1)
add    $0x8,%rax
add    $0xf8,%r15b
cmp    %rax,%rbx
jne    1320 <ulong_strcnv+0x220>
cmp    %r14,%r10
jne    118c <ulong_strcnv+0x8c>
jmp    1214 <ulong_strcnv+0x114>
or     $0x1,%rax
add    $0xff,%r8b
and    $0xe0,%r8b
sub    %r8b,%r15b
mov    %r15d,%edx
mov    %rax,%rsi
jmp    118c <ulong_strcnv+0x8c>

LLVM IR (-O0):
define void @ulong_strcnv(i8* %0, i64 %1) {
%3 = alloca i8*
%4 = alloca i64
%5 = alloca [11 x i8]
%6 = alloca i8
%7 = alloca i8
%8 = alloca i8
store i8* %0, i8** %3
store i64 %1, i64* %4
store i8 0, i8* %6
store i8 0, i8* %7
store i8 0, i8* %8
br label %9
9: ; preds = %20, %2
%10 = load i64, i64* %4
%11 = urem i64 %10, 10
%12 = add i64 %11, 48
%13 = trunc i64 %12 to i8
%14 = load i8, i8* %6
%15 = add i8 %14, 1
store i8 %15, i8* %6
%16 = zext i8 %14 to i64
%17 = getelementptr inbounds [11 x i8], [11 x i8]* %5, i64 0, i64 %16
store i8 %13, i8* %17
%18 = load i64, i64* %4
%19 = udiv i64 %18, 10
store i64 %19, i64* %4
br label %20
20: ; preds = %9
%21 = load i64, i64* %4
%22 = icmp ne i64 %21, 0
br i1 %22, label %9, label %23
23: ; preds = %20
%24 = load i8, i8* %6
%25 = zext i8 %24 to i64
%26 = getelementptr inbounds [11 x i8], [11 x i8]* %5, i64 0, i64 %25
store i8 0, i8* %26
%27 = load i8, i8* %6
%28 = zext i8 %27 to i32
%29 = sub nsw i32 %28, 1
%30 = trunc i32 %29 to i8
store i8 %30, i8* %7
br label %31
31: ; preds = %47, %23
%32 = load i8, i8* %8
%33 = zext i8 %32 to i32
%34 = load i8, i8* %6
%35 = zext i8 %34 to i32
%36 = icmp slt i32 %33, %35
br i1 %36, label %37, label %50
37: ; preds = %31
%38 = load i8, i8* %7
%39 = zext i8 %38 to i64
%40 = getelementptr inbounds [11 x i8], [11 x i8]* %5, i64 0, i64 %39
%41 = load i8, i8* %40
%42 = load i8*, i8** %3
%43 = load i8, i8* %8
%44 = add i8 %43, 1
store i8 %44, i8* %8
%45 = zext i8 %43 to i64
%46 = getelementptr inbounds i8, i8* %42, i64 %45
store i8 %41, i8* %46
br label %47
47: ; preds = %37
%48 = load i8, i8* %7
%49 = add i8 %48, -1
store i8 %49, i8* %7
br label %31
50: ; preds = %31
%51 = load i8*, i8** %3
%52 = load i8, i8* %6
%53 = zext i8 %52 to i64
%54 = getelementptr inbounds i8, i8* %51, i64 %53
store i8 0, i8* %54
ret void
}

LLVM IR (-O2):
define void @ulong_strcnv(i8* nocapture writeonly %0, i64 %1) {
%3 = alloca [11 x i8]
%4 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 0
br label %5
5: ; preds = %5, %2
%6 = phi i64 [ %1, %2 ], [ %14, %5 ]
%7 = phi i8 [ 0, %2 ], [ %11, %5 ]
%8 = urem i64 %6, 10
%9 = trunc i64 %8 to i8
%10 = or i8 %9, 48
%11 = add i8 %7, 1
%12 = zext i8 %7 to i64
%13 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %12
store i8 %10, i8* %13
%14 = udiv i64 %6, 10
%15 = icmp ult i64 %6, 10
br i1 %15, label %16, label %5
16: ; preds = %5
%17 = zext i8 %11 to i64
%18 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %17
store i8 0, i8* %18
%19 = icmp eq i8 %11, 0
br i1 %19, label %141, label %20
20: ; preds = %16
store i8 %10, i8* %0
%21 = add i8 %7, -1
%22 = icmp eq i8 %7, 0
br i1 %22, label %141, label %23
23: ; preds = %20
%24 = add nsw i64 %17, -1
%25 = icmp ult i64 %24, 8
br i1 %25, label %89, label %26
26: ; preds = %23
%27 = add nsw i64 %17, -2
%28 = trunc i64 %27 to i8
%29 = icmp ult i8 %21, %28
%30 = icmp ugt i64 %27, 255
%31 = or i1 %29, %30
br i1 %31, label %89, label %32
32: ; preds = %26
%33 = icmp ult i64 %24, 32
br i1 %33, label %65, label %34
34: ; preds = %32
%35 = and i64 %24, -32
br label %36
36: ; preds = %36, %34
%37 = phi i64 [ 0, %34 ], [ %55, %36 ]
%38 = trunc i64 %37 to i8
%39 = sub i8 %21, %38
%40 = or i64 %37, 1
%41 = zext i8 %39 to i64
%42 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %41
%43 = getelementptr inbounds i8, i8* %42, i64 -15
%44 = bitcast i8* %43 to <16 x i8>*
%45 = load <16 x i8>, <16 x i8>* %44
%46 = shufflevector <16 x i8> %45, <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>
%47 = getelementptr inbounds i8, i8* %42, i64 -31
%48 = bitcast i8* %47 to <16 x i8>*
%49 = load <16 x i8>, <16 x i8>* %48
%50 = shufflevector <16 x i8> %49, <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>
%51 = getelementptr inbounds i8, i8* %0, i64 %40
%52 = bitcast i8* %51 to <16 x i8>*
store <16 x i8> %46, <16 x i8>* %52
%53 = getelementptr inbounds i8, i8* %51, i64 16
%54 = bitcast i8* %53 to <16 x i8>*
store <16 x i8> %50, <16 x i8>* %54
%55 = add nuw i64 %37, 32
%56 = icmp eq i64 %55, %35
br i1 %56, label %57, label %36
57: ; preds = %36
%58 = icmp eq i64 %24, %35
br i1 %58, label %141, label %59
59: ; preds = %57
%60 = or i64 %35, 1
%61 = trunc i64 %35 to i8
%62 = sub i8 %21, %61
%63 = and i64 %24, 24
%64 = icmp eq i64 %63, 0
br i1 %64, label %89, label %65
65: ; preds = %32, %59
%66 = phi i64 [ %35, %59 ], [ 0, %32 ]
%67 = add nsw i64 %17, -1
%68 = and i64 %67, -8
%69 = trunc i64 %68 to i8
%70 = sub i8 %21, %69
%71 = or i64 %68, 1
br label %72
72: ; preds = %72, %65
%73 = phi i64 [ %66, %65 ], [ %85, %72 ]
%74 = trunc i64 %73 to i8
%75 = sub i8 %21, %74
%76 = or i64 %73, 1
%77 = zext i8 %75 to i64
%78 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %77
%79 = getelementptr inbounds i8, i8* %78, i64 -7
%80 = bitcast i8* %79 to <8 x i8>*
%81 = load <8 x i8>, <8 x i8>* %80
%82 = shufflevector <8 x i8> %81, <8 x i8> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%83 = getelementptr inbounds i8, i8* %0, i64 %76
%84 = bitcast i8* %83 to <8 x i8>*
store <8 x i8> %82, <8 x i8>* %84
%85 = add nuw i64 %73, 8
%86 = icmp eq i64 %85, %68
br i1 %86, label %87, label %72
87: ; preds = %72
%88 = icmp eq i64 %67, %68
br i1 %88, label %141, label %89
89: ; preds = %26, %23, %59, %87
%90 = phi i8 [ %21, %23 ], [ %21, %26 ], [ %62, %59 ], [ %70, %87 ]
%91 = phi i64 [ 1, %23 ], [ 1, %26 ], [ %60, %59 ], [ %71, %87 ]
%92 = sub nsw i64 %17, %91
%93 = xor i64 %91, -1
%94 = add nsw i64 %93, %17
%95 = and i64 %92, 3
%96 = icmp eq i64 %95, 0
br i1 %96, label %109, label %97
97: ; preds = %89, %97
%98 = phi i8 [ %106, %97 ], [ %90, %89 ]
%99 = phi i64 [ %104, %97 ], [ %91, %89 ]
%100 = phi i64 [ %107, %97 ], [ 0, %89 ]
%101 = zext i8 %98 to i64
%102 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %101
%103 = load i8, i8* %102
%104 = add nuw nsw i64 %99, 1
%105 = getelementptr inbounds i8, i8* %0, i64 %99
store i8 %103, i8* %105
%106 = add i8 %98, -1
%107 = add i64 %100, 1
%108 = icmp eq i64 %107, %95
br i1 %108, label %109, label %97
109: ; preds = %97, %89
%110 = phi i8 [ %90, %89 ], [ %106, %97 ]
%111 = phi i64 [ %91, %89 ], [ %104, %97 ]
%112 = icmp ult i64 %94, 3
br i1 %112, label %141, label %113
113: ; preds = %109, %113
%114 = phi i8 [ %139, %113 ], [ %110, %109 ]
%115 = phi i64 [ %137, %113 ], [ %111, %109 ]
%116 = zext i8 %114 to i64
%117 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %116
%118 = load i8, i8* %117
%119 = add nuw nsw i64 %115, 1
%120 = getelementptr inbounds i8, i8* %0, i64 %115
store i8 %118, i8* %120
%121 = add i8 %114, -1
%122 = zext i8 %121 to i64
%123 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %122
%124 = load i8, i8* %123
%125 = add nuw nsw i64 %115, 2
%126 = getelementptr inbounds i8, i8* %0, i64 %119
store i8 %124, i8* %126
%127 = add i8 %114, -2
%128 = zext i8 %127 to i64
%129 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %128
%130 = load i8, i8* %129
%131 = add nuw nsw i64 %115, 3
%132 = getelementptr inbounds i8, i8* %0, i64 %125
store i8 %130, i8* %132
%133 = add i8 %114, -3
%134 = zext i8 %133 to i64
%135 = getelementptr inbounds [11 x i8], [11 x i8]* %3, i64 0, i64 %134
%136 = load i8, i8* %135
%137 = add nuw nsw i64 %115, 4
%138 = getelementptr inbounds i8, i8* %0, i64 %131
store i8 %136, i8* %138
%139 = add i8 %114, -4
%140 = icmp eq i64 %137, %17
br i1 %140, label %141, label %113
141: ; preds = %109, %113, %20, %87, %57, %16
%142 = getelementptr inbounds i8, i8* %0, i64 %17
store i8 0, i8* %142
ret void
}