#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 strlen(char const *);
void asciitohex(char *dest, const char *str) {
  int i, tmp, len;
  len = strlen(str);
  for (i = 0; i < len; i++) {
    tmp = ((unsigned char *)str)[i] / 16;
    if (tmp < 10) {
      dest[i * 2] = tmp + '0';
    } else {
      dest[i * 2] = tmp + 'a' - 10;
    }
    tmp = ((unsigned char *)str)[i] % 16;
    if (tmp < 10) {
      dest[(i * 2) + 1] = tmp + '0';
    } else {
      dest[(i * 2) + 1] = tmp + 'a' - 10;
    }
  }
  dest[i * 2] = 0;
}


x86 assembly (clang, -O0):
<asciitohex>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,-0x1c(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    120a <asciitohex+0xfa>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    $0x10,%ecx
cltd
idiv   %ecx
mov    %eax,-0x18(%rbp)
cmpl   $0xa,-0x18(%rbp)
jge    117d <asciitohex+0x6d>
mov    -0x18(%rbp),%eax
add    $0x30,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1198 <asciitohex+0x88>
mov    -0x18(%rbp),%eax
add    $0x61,%eax
sub    $0xa,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    $0x10,%ecx
cltd
idiv   %ecx
mov    %edx,-0x18(%rbp)
cmpl   $0xa,-0x18(%rbp)
jge    11d9 <asciitohex+0xc9>
mov    -0x18(%rbp),%eax
add    $0x30,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x1,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11f7 <asciitohex+0xe7>
mov    -0x18(%rbp),%eax
add    $0x61,%eax
sub    $0xa,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x1,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11fc <asciitohex+0xec>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1133 <asciitohex+0x23>
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x1,%ecx
movslq %ecx,%rcx
movb   $0x0,(%rax,%rcx,1)
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<asciitohex>:
push   %r14
push   %rbx
push   %rax
mov    %rsi,%rbx
mov    %rdi,%r14
mov    %rsi,%rdi
call   1030 <strlen@plt>
test   %eax,%eax
jle    1135 <asciitohex+0x25>
mov    %eax,%r8d
cmp    $0x8,%eax
jae    113c <asciitohex+0x2c>
xor    %edx,%edx
jmp    1210 <asciitohex+0x100>
xor    %eax,%eax
jmp    125e <asciitohex+0x14e>
lea    (%rbx,%r8,1),%rdx
cmp    %r14,%rdx
jbe    1155 <asciitohex+0x45>
lea    (%r14,%r8,2),%rdx
cmp    %rbx,%rdx
jbe    1155 <asciitohex+0x45>
xor    %edx,%edx
jmp    1210 <asciitohex+0x100>
mov    %r8d,%edx
and    $0xfffffff8,%edx
xor    %esi,%esi
movdqa 0xe9a(%rip),%xmm8
movdqa 0xea1(%rip),%xmm9
movdqa 0xea9(%rip),%xmm2
movdqa 0xeb1(%rip),%xmm3
movdqa 0xeb9(%rip),%xmm4
movdqa 0xec1(%rip),%xmm5
nop
movq   (%rbx,%rsi,1),%xmm6
movdqa %xmm6,%xmm7
psrlw  $0x4,%xmm7
pand   %xmm8,%xmm7
movdqa %xmm6,%xmm0
pmaxub %xmm9,%xmm0
pcmpeqb %xmm6,%xmm0
movdqa %xmm7,%xmm1
paddb  %xmm2,%xmm1
por    %xmm3,%xmm7
pand   %xmm0,%xmm1
pandn  %xmm7,%xmm0
por    %xmm1,%xmm0
pand   %xmm4,%xmm6
movdqa %xmm6,%xmm1
pmaxub %xmm5,%xmm1
pcmpeqb %xmm6,%xmm1
movdqa %xmm6,%xmm7
por    %xmm3,%xmm7
paddb  %xmm2,%xmm6
pand   %xmm1,%xmm6
pandn  %xmm7,%xmm1
por    %xmm6,%xmm1
punpcklbw %xmm1,%xmm0
movdqu %xmm0,(%r14,%rsi,2)
add    $0x8,%rsi
cmp    %rsi,%rdx
jne    1190 <asciitohex+0x80>
cmp    %r8,%rdx
je     125c <asciitohex+0x14c>
nopl   0x0(%rax,%rax,1)
movzbl (%rbx,%rdx,1),%ecx
mov    %ecx,%esi
shr    $0x4,%sil
lea    0x57(%rsi),%edi
or     $0x30,%sil
cmp    $0xa0,%cl
movzbl %sil,%ecx
movzbl %dil,%esi
cmovb  %ecx,%esi
mov    %sil,(%r14,%rdx,2)
movzbl (%rbx,%rdx,1),%ecx
and    $0xf,%cl
lea    0x30(%rcx),%esi
lea    0x57(%rcx),%edi
cmp    $0xa,%cl
movzbl %sil,%ecx
movzbl %dil,%esi
cmovb  %ecx,%esi
mov    %sil,0x1(%r14,%rdx,2)
add    $0x1,%rdx
cmp    %rdx,%r8
jne    1210 <asciitohex+0x100>
add    %eax,%eax
movb   $0x0,(%r14,%rax,1)
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @asciitohex(i8* %0, i8* %1) {
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i8* %0, i8** %3
store i8* %1, i8** %4
%8 = load i8*, i8** %4
%9 = call i32 @strlen(i8* %8)
store i32 %9, i32* %7
store i32 0, i32* %5
br label %10
10: ; preds = %75, %2
%11 = load i32, i32* %5
%12 = load i32, i32* %7
%13 = icmp slt i32 %11, %12
br i1 %13, label %14, label %78
14: ; preds = %10
%15 = load i8*, i8** %4
%16 = load i32, i32* %5
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %15, i64 %17
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = sdiv i32 %20, 16
store i32 %21, i32* %6
%22 = load i32, i32* %6
%23 = icmp slt i32 %22, 10
br i1 %23, label %24, label %33
24: ; preds = %14
%25 = load i32, i32* %6
%26 = add nsw i32 %25, 48
%27 = trunc i32 %26 to i8
%28 = load i8*, i8** %3
%29 = load i32, i32* %5
%30 = mul nsw i32 %29, 2
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds i8, i8* %28, i64 %31
store i8 %27, i8* %32
br label %43
33: ; preds = %14
%34 = load i32, i32* %6
%35 = add nsw i32 %34, 97
%36 = sub nsw i32 %35, 10
%37 = trunc i32 %36 to i8
%38 = load i8*, i8** %3
%39 = load i32, i32* %5
%40 = mul nsw i32 %39, 2
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %38, i64 %41
store i8 %37, i8* %42
br label %43
43: ; preds = %33, %24
%44 = load i8*, i8** %4
%45 = load i32, i32* %5
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds i8, i8* %44, i64 %46
%48 = load i8, i8* %47
%49 = zext i8 %48 to i32
%50 = srem i32 %49, 16
store i32 %50, i32* %6
%51 = load i32, i32* %6
%52 = icmp slt i32 %51, 10
br i1 %52, label %53, label %63
53: ; preds = %43
%54 = load i32, i32* %6
%55 = add nsw i32 %54, 48
%56 = trunc i32 %55 to i8
%57 = load i8*, i8** %3
%58 = load i32, i32* %5
%59 = mul nsw i32 %58, 2
%60 = add nsw i32 %59, 1
%61 = sext i32 %60 to i64
%62 = getelementptr inbounds i8, i8* %57, i64 %61
store i8 %56, i8* %62
br label %74
63: ; preds = %43
%64 = load i32, i32* %6
%65 = add nsw i32 %64, 97
%66 = sub nsw i32 %65, 10
%67 = trunc i32 %66 to i8
%68 = load i8*, i8** %3
%69 = load i32, i32* %5
%70 = mul nsw i32 %69, 2
%71 = add nsw i32 %70, 1
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds i8, i8* %68, i64 %72
store i8 %67, i8* %73
br label %74
74: ; preds = %63, %53
br label %75
75: ; preds = %74
%76 = load i32, i32* %5
%77 = add nsw i32 %76, 1
store i32 %77, i32* %5
br label %10
78: ; preds = %10
%79 = load i8*, i8** %3
%80 = load i32, i32* %5
%81 = mul nsw i32 %80, 2
%82 = sext i32 %81 to i64
%83 = getelementptr inbounds i8, i8* %79, i64 %82
store i8 0, i8* %83
ret void
}

LLVM IR (-O2):
define void @asciitohex(i8* nocapture writeonly %0, i8* %1) {
%3 = tail call i32 @strlen(i8* %1)
%4 = icmp sgt i32 %3, 0
br i1 %4, label %5, label %71
5: ; preds = %2
%6 = zext i32 %3 to i64
%7 = icmp ult i32 %3, 8
br i1 %7, label %44, label %8
8: ; preds = %5
%9 = shl nuw nsw i64 %6, 1
%10 = getelementptr i8, i8* %0, i64 %9
%11 = getelementptr i8, i8* %1, i64 %6
%12 = icmp ugt i8* %11, %0
%13 = icmp ugt i8* %10, %1
%14 = and i1 %12, %13
br i1 %14, label %44, label %15
15: ; preds = %8
%16 = and i64 %6, 4294967288
%17 = getelementptr inbounds i8, i8* %0, i64 -1
br label %18
18: ; preds = %18, %15
%19 = phi i64 [ 0, %15 ], [ %40, %18 ]
%20 = getelementptr inbounds i8, i8* %1, i64 %19
%21 = bitcast i8* %20 to <8 x i8>*
%22 = load <8 x i8>, <8 x i8>* %21
%23 = lshr <8 x i8> %22, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%24 = icmp ult <8 x i8> %22, <i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96>
%25 = add nuw nsw <8 x i8> %23, <i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87>
%26 = or <8 x i8> %23, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%27 = select <8 x i1> %24, <8 x i8> %26, <8 x i8> %25
%28 = bitcast i8* %20 to <8 x i8>*
%29 = load <8 x i8>, <8 x i8>* %28
%30 = and <8 x i8> %29, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%31 = icmp ult <8 x i8> %30, <i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10>
%32 = or <8 x i8> %30, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%33 = add nuw nsw <8 x i8> %30, <i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87>
%34 = select <8 x i1> %31, <8 x i8> %32, <8 x i8> %33
%35 = shl nuw nsw i64 %19, 1
%36 = or i64 %35, 1
%37 = getelementptr inbounds i8, i8* %17, i64 %36
%38 = bitcast i8* %37 to <16 x i8>*
%39 = shufflevector <8 x i8> %27, <8 x i8> %34, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
store <16 x i8> %39, <16 x i8>* %38
%40 = add nuw i64 %19, 8
%41 = icmp eq i64 %40, %16
br i1 %41, label %42, label %18
42: ; preds = %18
%43 = icmp eq i64 %16, %6
br i1 %43, label %68, label %44
44: ; preds = %8, %5, %42
%45 = phi i64 [ 0, %8 ], [ 0, %5 ], [ %16, %42 ]
br label %46
46: ; preds = %44, %46
%47 = phi i64 [ %66, %46 ], [ %45, %44 ]
%48 = getelementptr inbounds i8, i8* %1, i64 %47
%49 = load i8, i8* %48
%50 = lshr i8 %49, 4
%51 = icmp ult i8 %49, -96
%52 = add nuw nsw i8 %50, 87
%53 = or i8 %50, 48
%54 = select i1 %51, i8 %53, i8 %52
%55 = shl nuw nsw i64 %47, 1
%56 = getelementptr inbounds i8, i8* %0, i64 %55
store i8 %54, i8* %56
%57 = load i8, i8* %48
%58 = and i8 %57, 15
%59 = icmp ult i8 %58, 10
%60 = or i8 %58, 48
%61 = add nuw nsw i8 %58, 87
%62 = select i1 %59, i8 %60, i8 %61
%63 = shl nuw nsw i64 %47, 1
%64 = or i64 %63, 1
%65 = getelementptr inbounds i8, i8* %0, i64 %64
store i8 %62, i8* %65
%66 = add nuw nsw i64 %47, 1
%67 = icmp eq i64 %66, %6
br i1 %67, label %68, label %46
68: ; preds = %46, %42
%69 = shl i32 %3, 1
%70 = zext i32 %69 to i64
br label %71
71: ; preds = %68, %2
%72 = phi i64 [ 0, %2 ], [ %70, %68 ]
%73 = getelementptr inbounds i8, i8* %0, i64 %72
store i8 0, i8* %73
ret void
}