char *ch_tostr(char *p, unsigned ch) {
  const char hex[] = "0123456789ABCDEF";
  if (ch == 0) {
    *p++ = '\\';
    *p++ = '0';
  } else if (ch == '-' || ch == '\\' || ch == ']') {
    *p++ = '\\';
    *p++ = ch;
  } else if (ch == '\n') {
    *p++ = '\\';
    *p++ = 'n';
  } else if (ch == '\r') {
    *p++ = '\\';
    *p++ = 'r';
  } else if (ch == '\t') {
    *p++ = '\\';
    *p++ = 't';
  } else if (ch < 0x20) {
    *p++ = '\\';
    *p++ = 'x';
    *p++ = hex[(ch >> 4) & 0xf];
    *p++ = hex[(ch >> 0) & 0xf];
  } else if (ch < 0x7f) {
    *p++ = ch;
  } else if (ch <= 0xffff) {
    *p++ = '\\';
    *p++ = 'u';
    *p++ = hex[(ch >> 12) & 0xf];
    *p++ = hex[(ch >> 8) & 0xf];
    *p++ = hex[(ch >> 4) & 0xf];
    *p++ = hex[(ch >> 0) & 0xf];
  } else {
    *p++ = '\\';
    *p++ = 'u';
    *p++ = '+';
    *p++ = hex[(ch >> 20) & 0xf];
    *p++ = hex[(ch >> 16) & 0xf];
    *p++ = hex[(ch >> 12) & 0xf];
    *p++ = hex[(ch >> 8) & 0xf];
    *p++ = hex[(ch >> 4) & 0xf];
    *p++ = hex[(ch >> 0) & 0xf];
  }
  return p;
}


x86 assembly (clang, -O0):
<ch_tostr>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    0xeee(%rip),%rax
mov    %rax,-0x20(%rbp)
mov    0xeeb(%rip),%rax
mov    %rax,-0x18(%rbp)
mov    0xee9(%rip),%al
mov    %al,-0x10(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    115d <ch_tostr+0x5d>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x30,(%rax)
jmp    14a8 <ch_tostr+0x3a8>
cmpl   $0x2d,-0xc(%rbp)
je     117b <ch_tostr+0x7b>
cmpl   $0x5c,-0xc(%rbp)
je     117b <ch_tostr+0x7b>
cmpl   $0x5d,-0xc(%rbp)
jne    11a8 <ch_tostr+0xa8>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0xc(%rbp),%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
jmp    14a3 <ch_tostr+0x3a3>
cmpl   $0xa,-0xc(%rbp)
jne    11db <ch_tostr+0xdb>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x6e,(%rax)
jmp    149e <ch_tostr+0x39e>
cmpl   $0xd,-0xc(%rbp)
jne    120e <ch_tostr+0x10e>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x72,(%rax)
jmp    1499 <ch_tostr+0x399>
cmpl   $0x9,-0xc(%rbp)
jne    1241 <ch_tostr+0x141>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x74,(%rax)
jmp    1494 <ch_tostr+0x394>
cmpl   $0x20,-0xc(%rbp)
jae    12b4 <ch_tostr+0x1b4>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x78,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x4,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x0,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
jmp    148f <ch_tostr+0x38f>
cmpl   $0x7f,-0xc(%rbp)
jae    12d9 <ch_tostr+0x1d9>
mov    -0xc(%rbp),%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
jmp    148a <ch_tostr+0x38a>
cmpl   $0xffff,-0xc(%rbp)
ja     138f <ch_tostr+0x28f>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x75,(%rax)
mov    -0xc(%rbp),%eax
shr    $0xc,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x8,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x4,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x0,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
jmp    1485 <ch_tostr+0x385>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x5c,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x75,(%rax)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movb   $0x2b,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x14,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x10,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0xc,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x8,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x4,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
mov    -0xc(%rbp),%eax
shr    $0x0,%eax
and    $0xf,%eax
mov    %eax,%eax
mov    -0x20(%rbp,%rax,1),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
jmp    148a <ch_tostr+0x38a>
jmp    148f <ch_tostr+0x38f>
jmp    1494 <ch_tostr+0x394>
jmp    1499 <ch_tostr+0x399>
jmp    149e <ch_tostr+0x39e>
jmp    14a3 <ch_tostr+0x3a3>
jmp    14a8 <ch_tostr+0x3a8>
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ch_tostr>:
mov    %rdi,%rax
mov    %esi,%ecx
cmp    $0x2d,%esi
ja     1124 <ch_tostr+0x24>
lea    0xeef(%rip),%rdx
movslq (%rdx,%rcx,4),%rdi
add    %rdx,%rdi
jmp    *%rdi
movw   $0x305c,(%rax)
add    $0x2,%rax
ret
lea    -0x5c(%rsi),%edx
cmp    $0x2,%edx
jae    1138 <ch_tostr+0x38>
movb   $0x5c,(%rax)
mov    %sil,0x1(%rax)
add    $0x2,%rax
ret
cmp    $0x1f,%esi
ja     1182 <ch_tostr+0x82>
movw   $0x785c,(%rax)
mov    %rcx,%rdx
shr    $0x4,%rdx
lea    0xf70(%rip),%rsi
mov    (%rdx,%rsi,1),%dl
mov    %dl,0x2(%rax)
and    $0xf,%ecx
mov    (%rcx,%rsi,1),%cl
mov    %cl,0x3(%rax)
add    $0x4,%rax
ret
movw   $0x745c,(%rax)
add    $0x2,%rax
ret
movw   $0x6e5c,(%rax)
add    $0x2,%rax
ret
movw   $0x725c,(%rax)
add    $0x2,%rax
ret
cmp    $0x7e,%esi
ja     118f <ch_tostr+0x8f>
mov    %sil,(%rax)
add    $0x1,%rax
ret
movw   $0x755c,(%rax)
cmp    $0xffff,%esi
ja     11d8 <ch_tostr+0xd8>
mov    %rcx,%rdx
shr    $0xc,%rdx
lea    0xf16(%rip),%rdi
mov    (%rdx,%rdi,1),%dl
mov    %dl,0x2(%rax)
mov    %esi,%edx
shr    $0x8,%edx
and    $0xf,%edx
mov    (%rdx,%rdi,1),%dl
mov    %dl,0x3(%rax)
shr    $0x4,%esi
and    $0xf,%esi
mov    (%rsi,%rdi,1),%dl
mov    %dl,0x4(%rax)
and    $0xf,%ecx
mov    (%rcx,%rdi,1),%cl
mov    %cl,0x5(%rax)
add    $0x6,%rax
ret
movb   $0x2b,0x2(%rax)
mov    %esi,%edx
shr    $0x14,%edx
and    $0xf,%edx
lea    0xed5(%rip),%rcx
mov    (%rdx,%rcx,1),%dl
mov    %dl,0x3(%rax)
mov    %esi,%edx
shr    $0x10,%edx
and    $0xf,%edx
mov    (%rdx,%rcx,1),%dl
mov    %dl,0x4(%rax)
mov    %esi,%edx
shr    $0xc,%edx
and    $0xf,%edx
mov    (%rdx,%rcx,1),%dl
mov    %dl,0x5(%rax)
mov    %esi,%edx
shr    $0x8,%edx
and    $0xf,%edx
mov    (%rdx,%rcx,1),%dl
mov    %dl,0x6(%rax)
mov    %esi,%edx
shr    $0x4,%edx
and    $0xf,%edx
mov    (%rdx,%rcx,1),%dl
mov    %dl,0x7(%rax)
and    $0xf,%esi
mov    (%rsi,%rcx,1),%cl
mov    %cl,0x8(%rax)
add    $0x9,%rax
ret

LLVM IR (-O0):
@__const.ch_tostr.hex = [17 x i8] c"0123456789ABCDEF\00"
define i8* @ch_tostr(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca [17 x i8]
store i8* %0, i8** %3
store i32 %1, i32* %4
%6 = bitcast [17 x i8]* %5 to i8*
%7 = load i32, i32* %4
%8 = icmp eq i32 %7, 0
br i1 %8, label %9, label %14
9: ; preds = %2
%10 = load i8*, i8** %3
%11 = getelementptr inbounds i8, i8* %10, i32 1
store i8* %11, i8** %3
store i8 92, i8* %10
%12 = load i8*, i8** %3
%13 = getelementptr inbounds i8, i8* %12, i32 1
store i8* %13, i8** %3
store i8 48, i8* %12
br label %188
14: ; preds = %2
%15 = load i32, i32* %4
%16 = icmp eq i32 %15, 45
br i1 %16, label %23, label %17
17: ; preds = %14
%18 = load i32, i32* %4
%19 = icmp eq i32 %18, 92
br i1 %19, label %23, label %20
20: ; preds = %17
%21 = load i32, i32* %4
%22 = icmp eq i32 %21, 93
br i1 %22, label %23, label %30
23: ; preds = %20, %17, %14
%24 = load i8*, i8** %3
%25 = getelementptr inbounds i8, i8* %24, i32 1
store i8* %25, i8** %3
store i8 92, i8* %24
%26 = load i32, i32* %4
%27 = trunc i32 %26 to i8
%28 = load i8*, i8** %3
%29 = getelementptr inbounds i8, i8* %28, i32 1
store i8* %29, i8** %3
store i8 %27, i8* %28
br label %187
30: ; preds = %20
%31 = load i32, i32* %4
%32 = icmp eq i32 %31, 10
br i1 %32, label %33, label %38
33: ; preds = %30
%34 = load i8*, i8** %3
%35 = getelementptr inbounds i8, i8* %34, i32 1
store i8* %35, i8** %3
store i8 92, i8* %34
%36 = load i8*, i8** %3
%37 = getelementptr inbounds i8, i8* %36, i32 1
store i8* %37, i8** %3
store i8 110, i8* %36
br label %186
38: ; preds = %30
%39 = load i32, i32* %4
%40 = icmp eq i32 %39, 13
br i1 %40, label %41, label %46
41: ; preds = %38
%42 = load i8*, i8** %3
%43 = getelementptr inbounds i8, i8* %42, i32 1
store i8* %43, i8** %3
store i8 92, i8* %42
%44 = load i8*, i8** %3
%45 = getelementptr inbounds i8, i8* %44, i32 1
store i8* %45, i8** %3
store i8 114, i8* %44
br label %185
46: ; preds = %38
%47 = load i32, i32* %4
%48 = icmp eq i32 %47, 9
br i1 %48, label %49, label %54
49: ; preds = %46
%50 = load i8*, i8** %3
%51 = getelementptr inbounds i8, i8* %50, i32 1
store i8* %51, i8** %3
store i8 92, i8* %50
%52 = load i8*, i8** %3
%53 = getelementptr inbounds i8, i8* %52, i32 1
store i8* %53, i8** %3
store i8 116, i8* %52
br label %184
54: ; preds = %46
%55 = load i32, i32* %4
%56 = icmp ult i32 %55, 32
br i1 %56, label %57, label %78
57: ; preds = %54
%58 = load i8*, i8** %3
%59 = getelementptr inbounds i8, i8* %58, i32 1
store i8* %59, i8** %3
store i8 92, i8* %58
%60 = load i8*, i8** %3
%61 = getelementptr inbounds i8, i8* %60, i32 1
store i8* %61, i8** %3
store i8 120, i8* %60
%62 = load i32, i32* %4
%63 = lshr i32 %62, 4
%64 = and i32 %63, 15
%65 = zext i32 %64 to i64
%66 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %65
%67 = load i8, i8* %66
%68 = load i8*, i8** %3
%69 = getelementptr inbounds i8, i8* %68, i32 1
store i8* %69, i8** %3
store i8 %67, i8* %68
%70 = load i32, i32* %4
%71 = lshr i32 %70, 0
%72 = and i32 %71, 15
%73 = zext i32 %72 to i64
%74 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %73
%75 = load i8, i8* %74
%76 = load i8*, i8** %3
%77 = getelementptr inbounds i8, i8* %76, i32 1
store i8* %77, i8** %3
store i8 %75, i8* %76
br label %183
78: ; preds = %54
%79 = load i32, i32* %4
%80 = icmp ult i32 %79, 127
br i1 %80, label %81, label %86
81: ; preds = %78
%82 = load i32, i32* %4
%83 = trunc i32 %82 to i8
%84 = load i8*, i8** %3
%85 = getelementptr inbounds i8, i8* %84, i32 1
store i8* %85, i8** %3
store i8 %83, i8* %84
br label %182
86: ; preds = %78
%87 = load i32, i32* %4
%88 = icmp ule i32 %87, 65535
br i1 %88, label %89, label %126
89: ; preds = %86
%90 = load i8*, i8** %3
%91 = getelementptr inbounds i8, i8* %90, i32 1
store i8* %91, i8** %3
store i8 92, i8* %90
%92 = load i8*, i8** %3
%93 = getelementptr inbounds i8, i8* %92, i32 1
store i8* %93, i8** %3
store i8 117, i8* %92
%94 = load i32, i32* %4
%95 = lshr i32 %94, 12
%96 = and i32 %95, 15
%97 = zext i32 %96 to i64
%98 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %97
%99 = load i8, i8* %98
%100 = load i8*, i8** %3
%101 = getelementptr inbounds i8, i8* %100, i32 1
store i8* %101, i8** %3
store i8 %99, i8* %100
%102 = load i32, i32* %4
%103 = lshr i32 %102, 8
%104 = and i32 %103, 15
%105 = zext i32 %104 to i64
%106 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %105
%107 = load i8, i8* %106
%108 = load i8*, i8** %3
%109 = getelementptr inbounds i8, i8* %108, i32 1
store i8* %109, i8** %3
store i8 %107, i8* %108
%110 = load i32, i32* %4
%111 = lshr i32 %110, 4
%112 = and i32 %111, 15
%113 = zext i32 %112 to i64
%114 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %113
%115 = load i8, i8* %114
%116 = load i8*, i8** %3
%117 = getelementptr inbounds i8, i8* %116, i32 1
store i8* %117, i8** %3
store i8 %115, i8* %116
%118 = load i32, i32* %4
%119 = lshr i32 %118, 0
%120 = and i32 %119, 15
%121 = zext i32 %120 to i64
%122 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %121
%123 = load i8, i8* %122
%124 = load i8*, i8** %3
%125 = getelementptr inbounds i8, i8* %124, i32 1
store i8* %125, i8** %3
store i8 %123, i8* %124
br label %181
126: ; preds = %86
%127 = load i8*, i8** %3
%128 = getelementptr inbounds i8, i8* %127, i32 1
store i8* %128, i8** %3
store i8 92, i8* %127
%129 = load i8*, i8** %3
%130 = getelementptr inbounds i8, i8* %129, i32 1
store i8* %130, i8** %3
store i8 117, i8* %129
%131 = load i8*, i8** %3
%132 = getelementptr inbounds i8, i8* %131, i32 1
store i8* %132, i8** %3
store i8 43, i8* %131
%133 = load i32, i32* %4
%134 = lshr i32 %133, 20
%135 = and i32 %134, 15
%136 = zext i32 %135 to i64
%137 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %136
%138 = load i8, i8* %137
%139 = load i8*, i8** %3
%140 = getelementptr inbounds i8, i8* %139, i32 1
store i8* %140, i8** %3
store i8 %138, i8* %139
%141 = load i32, i32* %4
%142 = lshr i32 %141, 16
%143 = and i32 %142, 15
%144 = zext i32 %143 to i64
%145 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %144
%146 = load i8, i8* %145
%147 = load i8*, i8** %3
%148 = getelementptr inbounds i8, i8* %147, i32 1
store i8* %148, i8** %3
store i8 %146, i8* %147
%149 = load i32, i32* %4
%150 = lshr i32 %149, 12
%151 = and i32 %150, 15
%152 = zext i32 %151 to i64
%153 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %152
%154 = load i8, i8* %153
%155 = load i8*, i8** %3
%156 = getelementptr inbounds i8, i8* %155, i32 1
store i8* %156, i8** %3
store i8 %154, i8* %155
%157 = load i32, i32* %4
%158 = lshr i32 %157, 8
%159 = and i32 %158, 15
%160 = zext i32 %159 to i64
%161 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %160
%162 = load i8, i8* %161
%163 = load i8*, i8** %3
%164 = getelementptr inbounds i8, i8* %163, i32 1
store i8* %164, i8** %3
store i8 %162, i8* %163
%165 = load i32, i32* %4
%166 = lshr i32 %165, 4
%167 = and i32 %166, 15
%168 = zext i32 %167 to i64
%169 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %168
%170 = load i8, i8* %169
%171 = load i8*, i8** %3
%172 = getelementptr inbounds i8, i8* %171, i32 1
store i8* %172, i8** %3
store i8 %170, i8* %171
%173 = load i32, i32* %4
%174 = lshr i32 %173, 0
%175 = and i32 %174, 15
%176 = zext i32 %175 to i64
%177 = getelementptr inbounds [17 x i8], [17 x i8]* %5, i64 0, i64 %176
%178 = load i8, i8* %177
%179 = load i8*, i8** %3
%180 = getelementptr inbounds i8, i8* %179, i32 1
store i8* %180, i8** %3
store i8 %178, i8* %179
br label %181
181: ; preds = %126, %89
br label %182
182: ; preds = %181, %81
br label %183
183: ; preds = %182, %57
br label %184
184: ; preds = %183, %49
br label %185
185: ; preds = %184, %41
br label %186
186: ; preds = %185, %33
br label %187
187: ; preds = %186, %23
br label %188
188: ; preds = %187, %9
%189 = load i8*, i8** %3
ret i8* %189
}

LLVM IR (-O2):
@__const.ch_tostr.hex = [17 x i8] c"0123456789ABCDEF\00"
define i8* @ch_tostr(i8* writeonly %0, i32 %1) {
switch i32 %1, label %19 [
i32 0, label %3
i32 93, label %6
i32 92, label %6
i32 45, label %6
i32 10, label %10
i32 13, label %13
i32 9, label %16
]
3: ; preds = %2
%4 = getelementptr inbounds i8, i8* %0, i64 1
store i8 92, i8* %0
%5 = getelementptr inbounds i8, i8* %0, i64 2
store i8 48, i8* %4
br label %103
6: ; preds = %2, %2, %2
%7 = getelementptr inbounds i8, i8* %0, i64 1
store i8 92, i8* %0
%8 = trunc i32 %1 to i8
%9 = getelementptr inbounds i8, i8* %0, i64 2
store i8 %8, i8* %7
br label %103
10: ; preds = %2
%11 = getelementptr inbounds i8, i8* %0, i64 1
store i8 92, i8* %0
%12 = getelementptr inbounds i8, i8* %0, i64 2
store i8 110, i8* %11
br label %103
13: ; preds = %2
%14 = getelementptr inbounds i8, i8* %0, i64 1
store i8 92, i8* %0
%15 = getelementptr inbounds i8, i8* %0, i64 2
store i8 114, i8* %14
br label %103
16: ; preds = %2
%17 = getelementptr inbounds i8, i8* %0, i64 1
store i8 92, i8* %0
%18 = getelementptr inbounds i8, i8* %0, i64 2
store i8 116, i8* %17
br label %103
19: ; preds = %2
%20 = icmp ult i32 %1, 32
br i1 %20, label %21, label %34
21: ; preds = %19
%22 = getelementptr inbounds i8, i8* %0, i64 1
store i8 92, i8* %0
%23 = getelementptr inbounds i8, i8* %0, i64 2
store i8 120, i8* %22
%24 = lshr i32 %1, 4
%25 = zext i32 %24 to i64
%26 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %25
%27 = load i8, i8* %26
%28 = getelementptr inbounds i8, i8* %0, i64 3
store i8 %27, i8* %23
%29 = and i32 %1, 15
%30 = zext i32 %29 to i64
%31 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %30
%32 = load i8, i8* %31
%33 = getelementptr inbounds i8, i8* %0, i64 4
store i8 %32, i8* %28
br label %103
34: ; preds = %19
%35 = icmp ult i32 %1, 127
br i1 %35, label %36, label %39
36: ; preds = %34
%37 = trunc i32 %1 to i8
%38 = getelementptr inbounds i8, i8* %0, i64 1
store i8 %37, i8* %0
br label %103
39: ; preds = %34
%40 = icmp ult i32 %1, 65536
%41 = getelementptr inbounds i8, i8* %0, i64 1
store i8 92, i8* %0
%42 = getelementptr inbounds i8, i8* %0, i64 2
store i8 117, i8* %41
br i1 %40, label %43, label %66
43: ; preds = %39
%44 = lshr i32 %1, 12
%45 = zext i32 %44 to i64
%46 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %45
%47 = load i8, i8* %46
%48 = getelementptr inbounds i8, i8* %0, i64 3
store i8 %47, i8* %42
%49 = lshr i32 %1, 8
%50 = and i32 %49, 15
%51 = zext i32 %50 to i64
%52 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %51
%53 = load i8, i8* %52
%54 = getelementptr inbounds i8, i8* %0, i64 4
store i8 %53, i8* %48
%55 = lshr i32 %1, 4
%56 = and i32 %55, 15
%57 = zext i32 %56 to i64
%58 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %57
%59 = load i8, i8* %58
%60 = getelementptr inbounds i8, i8* %0, i64 5
store i8 %59, i8* %54
%61 = and i32 %1, 15
%62 = zext i32 %61 to i64
%63 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %62
%64 = load i8, i8* %63
%65 = getelementptr inbounds i8, i8* %0, i64 6
store i8 %64, i8* %60
br label %103
66: ; preds = %39
%67 = getelementptr inbounds i8, i8* %0, i64 3
store i8 43, i8* %42
%68 = lshr i32 %1, 20
%69 = and i32 %68, 15
%70 = zext i32 %69 to i64
%71 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %70
%72 = load i8, i8* %71
%73 = getelementptr inbounds i8, i8* %0, i64 4
store i8 %72, i8* %67
%74 = lshr i32 %1, 16
%75 = and i32 %74, 15
%76 = zext i32 %75 to i64
%77 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %76
%78 = load i8, i8* %77
%79 = getelementptr inbounds i8, i8* %0, i64 5
store i8 %78, i8* %73
%80 = lshr i32 %1, 12
%81 = and i32 %80, 15
%82 = zext i32 %81 to i64
%83 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %82
%84 = load i8, i8* %83
%85 = getelementptr inbounds i8, i8* %0, i64 6
store i8 %84, i8* %79
%86 = lshr i32 %1, 8
%87 = and i32 %86, 15
%88 = zext i32 %87 to i64
%89 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %88
%90 = load i8, i8* %89
%91 = getelementptr inbounds i8, i8* %0, i64 7
store i8 %90, i8* %85
%92 = lshr i32 %1, 4
%93 = and i32 %92, 15
%94 = zext i32 %93 to i64
%95 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %94
%96 = load i8, i8* %95
%97 = getelementptr inbounds i8, i8* %0, i64 8
store i8 %96, i8* %91
%98 = and i32 %1, 15
%99 = zext i32 %98 to i64
%100 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ch_tostr.hex, i64 0, i64 %99
%101 = load i8, i8* %100
%102 = getelementptr inbounds i8, i8* %0, i64 9
store i8 %101, i8* %97
br label %103
103: ; preds = %6, %13, %21, %43, %66, %36, %16, %10, %3
%104 = phi i8* [ %5, %3 ], [ %9, %6 ], [ %12, %10 ], [ %15, %13 ], [ %18, %16 ], [ %33, %21 ], [ %38, %36 ], [ %65, %43 ], [ %102, %66 ]
ret i8* %104
}