#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 */
void BinToHex(void *pData, size_t sizeData, char *HexString, size_t sizeOut) {
  int i, Length;
  unsigned char LeftHalf, RightHalf;
  const unsigned char *BinData = pData;
  Length = sizeOut / 2 - 1;
  if (sizeData < Length)
    Length = sizeData;
  for (i = 0; i < Length; i++) {
    LeftHalf = BinData[i];
    LeftHalf >>= 4;
    RightHalf = BinData[i] & 0xF;
    if (LeftHalf > 9)
      LeftHalf += 'a' - 10;
    else
      LeftHalf += '0';
    if (RightHalf > 9)
      RightHalf += 'a' - 10;
    else
      RightHalf += '0';
    *HexString++ = LeftHalf;
    *HexString++ = RightHalf;
  }
  *HexString = '\0';
}


x86 assembly (clang, -O0):
<BinToHex>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
shr    $0x1,%rax
sub    $0x1,%rax
mov    %eax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x28(%rbp),%rcx
cmp    %rcx,%rax
jae    1143 <BinToHex+0x43>
mov    -0x10(%rbp),%rax
mov    %eax,-0x28(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x28(%rbp),%eax
jge    1202 <BinToHex+0x102>
mov    -0x38(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x29(%rbp)
movzbl -0x29(%rbp),%eax
sar    $0x4,%eax
mov    %al,-0x29(%rbp)
mov    -0x38(%rbp),%rax
movslq -0x24(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0xf,%eax
mov    %al,-0x2a(%rbp)
movzbl -0x29(%rbp),%eax
cmp    $0x9,%eax
jle    119c <BinToHex+0x9c>
movzbl -0x29(%rbp),%eax
add    $0x57,%eax
mov    %al,-0x29(%rbp)
jmp    11a6 <BinToHex+0xa6>
movzbl -0x29(%rbp),%eax
add    $0x30,%eax
mov    %al,-0x29(%rbp)
movzbl -0x2a(%rbp),%eax
cmp    $0x9,%eax
jle    11c2 <BinToHex+0xc2>
movzbl -0x2a(%rbp),%eax
add    $0x57,%eax
mov    %al,-0x2a(%rbp)
jmp    11cc <BinToHex+0xcc>
movzbl -0x2a(%rbp),%eax
add    $0x30,%eax
mov    %al,-0x2a(%rbp)
mov    -0x29(%rbp),%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x2a(%rbp),%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    114a <BinToHex+0x4a>
mov    -0x18(%rbp),%rax
movb   $0x0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<BinToHex>:
shr    %rcx
add    $0xffffffff,%ecx
movslq %ecx,%rax
cmp    %rsi,%rax
cmova  %esi,%eax
test   %eax,%eax
jle    118d <BinToHex+0x8d>
mov    %eax,%r8d
cmp    $0x8,%eax
jb     112d <BinToHex+0x2d>
lea    (%rdi,%r8,1),%rax
cmp    %rdx,%rax
jbe    1191 <BinToHex+0x91>
lea    (%rdx,%r8,2),%rax
cmp    %rdi,%rax
jbe    1191 <BinToHex+0x91>
xor    %r10d,%r10d
mov    %rdx,%r9
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movzbl (%rdi,%r10,1),%eax
mov    %eax,%edx
shr    $0x4,%dl
mov    %eax,%esi
and    $0xf,%sil
lea    0x57(%rdx),%ecx
or     $0x30,%dl
cmp    $0xa0,%al
movzbl %cl,%eax
movzbl %dl,%ecx
cmovae %eax,%ecx
lea    0x57(%rsi),%eax
lea    0x30(%rsi),%edx
cmp    $0xa,%sil
movzbl %al,%eax
movzbl %dl,%edx
cmovae %eax,%edx
mov    %cl,(%r9)
mov    %dl,0x1(%r9)
add    $0x2,%r9
add    $0x1,%r10
cmp    %r10,%r8
jne    1140 <BinToHex+0x40>
movb   $0x0,(%r9)
ret
movb   $0x0,(%rdx)
ret
mov    %r8d,%r10d
and    $0xfffffff8,%r10d
lea    (%rdx,%r10,2),%r9
xor    %eax,%eax
movdqa 0xe59(%rip),%xmm8
movdqa 0xe60(%rip),%xmm9
movdqa 0xe68(%rip),%xmm2
movdqa 0xe70(%rip),%xmm3
movdqa 0xe78(%rip),%xmm4
movdqa 0xe80(%rip),%xmm5
movq   (%rdi,%rax,1),%xmm0
movdqa %xmm0,%xmm7
movdqa %xmm0,%xmm6
pminub %xmm2,%xmm6
pcmpeqb %xmm0,%xmm6
psrlw  $0x4,%xmm0
pand   %xmm8,%xmm0
pand   %xmm9,%xmm7
movdqa %xmm0,%xmm1
paddb  %xmm3,%xmm1
por    %xmm4,%xmm0
pand   %xmm6,%xmm0
pandn  %xmm1,%xmm6
por    %xmm0,%xmm6
movdqa %xmm7,%xmm0
pminub %xmm5,%xmm0
pcmpeqb %xmm7,%xmm0
movdqa %xmm7,%xmm1
paddb  %xmm3,%xmm1
por    %xmm4,%xmm7
pand   %xmm0,%xmm7
pandn  %xmm1,%xmm0
por    %xmm7,%xmm0
punpcklbw %xmm0,%xmm6
movdqu %xmm6,(%rdx,%rax,2)
add    $0x8,%rax
cmp    %rax,%r10
jne    11d0 <BinToHex+0xd0>
cmp    %r8,%r10
jne    1140 <BinToHex+0x40>
jmp    1188 <BinToHex+0x88>

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

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