#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 */
typedef int uint32_t;

/* Variables and functions */
const char *ultox(uint32_t value, char *buf) {
  static const char hex_array[] = "0123456789ABCDEF";
  buf[0] = '0';
  buf[1] = 'x';
  buf += 2;
  int num_digits = 0;
  do {
    buf[num_digits++] = hex_array[value % 16];
    value /= 16;
  } while (value > 0);
  int swap = 0;
  char tmp = 0;
  for (int i = 0; i < num_digits / 2; i++) {
    swap = num_digits - (i + 1);
    tmp = buf[i];
    buf[i] = buf[swap];
    buf[swap] = tmp;
  }
  buf[num_digits] = 0;
  return buf;
}


x86 assembly (clang, -O0):
<ultox>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movb   $0x30,(%rax)
mov    -0x10(%rbp),%rax
movb   $0x78,0x1(%rax)
mov    -0x10(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x4(%rbp),%eax
mov    $0x10,%ecx
cltd
idiv   %ecx
movslq %edx,%rcx
lea    0xebe(%rip),%rax
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x14(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x4(%rbp),%eax
mov    $0x10,%ecx
cltd
idiv   %ecx
mov    %eax,-0x4(%rbp)
cmpl   $0x0,-0x4(%rbp)
jg     112d <ultox+0x2d>
movl   $0x0,-0x18(%rbp)
movb   $0x0,-0x19(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x24(%rbp),%eax
cmp    %ecx,%eax
jge    11f0 <ultox+0xf0>
mov    -0x14(%rbp),%eax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
sub    %ecx,%eax
mov    %eax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x19(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x19(%rbp),%dl
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1184 <ultox+0x84>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ultox>:
push   %r15
push   %r14
push   %rbx
movw   $0x7830,(%rsi)
lea    0x2(%rsi),%rax
xor    %r14d,%r14d
lea    0xee8(%rip),%r8
movabs $0x100000000,%r9
xor    %r15d,%r15d
cs nopw 0x0(%rax,%rax,1)
nop
lea    0xf(%rdi),%edx
test   %edi,%edi
cmovns %edi,%edx
mov    %edx,%ebx
and    $0xfffffff0,%ebx
mov    %edi,%ecx
sub    %ebx,%ecx
movslq %ecx,%rcx
movzbl (%rcx,%r8,1),%ecx
mov    %cl,(%rax,%r15,1)
add    $0x1,%r15
sar    $0x4,%edx
add    %r9,%r14
cmp    $0xf,%edi
mov    %edx,%edi
jg     1130 <ultox+0x30>
cmp    $0x1,%r15d
je     1203 <ultox+0x103>
mov    %r15d,%r8d
shr    %r8d
cmp    $0x2,%r8d
mov    $0x1,%r9d
cmovb  %r9d,%r8d
cmp    $0x4,%r15d
jae    1187 <ultox+0x87>
xor    %r10d,%r10d
jmp    11e2 <ultox+0xe2>
movslq %r15d,%rcx
lea    (%rsi,%rcx,1),%r11
add    $0x1,%r11
shr    %ecx
cmp    $0x2,%ecx
cmovae %ecx,%r9d
and    $0xfffffffe,%r9d
xor    %edi,%edi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movzbl 0x2(%rsi,%rdi,1),%ecx
movzbl (%r11),%edx
mov    %dl,0x2(%rsi,%rdi,1)
mov    %cl,(%r11)
lea    0x2(%rdi),%r10
movzbl 0x3(%rsi,%rdi,1),%ecx
movzbl -0x1(%r11),%edx
mov    %dl,0x3(%rsi,%rdi,1)
mov    %cl,-0x1(%r11)
add    $0xfffffffffffffffe,%r11
mov    %r10,%rdi
cmp    %r10,%r9
jne    11b0 <ultox+0xb0>
test   $0x1,%r8b
je     1203 <ultox+0x103>
sar    $0x20,%r14
mov    %r10,%rcx
not    %rcx
add    %r14,%rcx
mov    (%rax,%r10,1),%dl
mov    (%rax,%rcx,1),%bl
mov    %bl,(%rax,%r10,1)
mov    %dl,(%rax,%rcx,1)
mov    %r15d,%ecx
movb   $0x0,(%rax,%rcx,1)
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@ultox.hex_array = internal constant [17 x i8] c"0123456789ABCDEF\00"
define i8* @ultox(i32 %0, i8* %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i8
%8 = alloca i32
store i32 %0, i32* %3
store i8* %1, i8** %4
%9 = load i8*, i8** %4
%10 = getelementptr inbounds i8, i8* %9, i64 0
store i8 48, i8* %10
%11 = load i8*, i8** %4
%12 = getelementptr inbounds i8, i8* %11, i64 1
store i8 120, i8* %12
%13 = load i8*, i8** %4
%14 = getelementptr inbounds i8, i8* %13, i64 2
store i8* %14, i8** %4
store i32 0, i32* %5
br label %15
15: ; preds = %28, %2
%16 = load i32, i32* %3
%17 = srem i32 %16, 16
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds [17 x i8], [17 x i8]* @ultox.hex_array, i64 0, i64 %18
%20 = load i8, i8* %19
%21 = load i8*, i8** %4
%22 = load i32, i32* %5
%23 = add nsw i32 %22, 1
store i32 %23, i32* %5
%24 = sext i32 %22 to i64
%25 = getelementptr inbounds i8, i8* %21, i64 %24
store i8 %20, i8* %25
%26 = load i32, i32* %3
%27 = sdiv i32 %26, 16
store i32 %27, i32* %3
br label %28
28: ; preds = %15
%29 = load i32, i32* %3
%30 = icmp sgt i32 %29, 0
br i1 %30, label %15, label %31
31: ; preds = %28
store i32 0, i32* %6
store i8 0, i8* %7
store i32 0, i32* %8
br label %32
32: ; preds = %61, %31
%33 = load i32, i32* %8
%34 = load i32, i32* %5
%35 = sdiv i32 %34, 2
%36 = icmp slt i32 %33, %35
br i1 %36, label %37, label %64
37: ; preds = %32
%38 = load i32, i32* %5
%39 = load i32, i32* %8
%40 = add nsw i32 %39, 1
%41 = sub nsw i32 %38, %40
store i32 %41, i32* %6
%42 = load i8*, i8** %4
%43 = load i32, i32* %8
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds i8, i8* %42, i64 %44
%46 = load i8, i8* %45
store i8 %46, i8* %7
%47 = load i8*, i8** %4
%48 = load i32, i32* %6
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds i8, i8* %47, i64 %49
%51 = load i8, i8* %50
%52 = load i8*, i8** %4
%53 = load i32, i32* %8
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds i8, i8* %52, i64 %54
store i8 %51, i8* %55
%56 = load i8, i8* %7
%57 = load i8*, i8** %4
%58 = load i32, i32* %6
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds i8, i8* %57, i64 %59
store i8 %56, i8* %60
br label %61
61: ; preds = %37
%62 = load i32, i32* %8
%63 = add nsw i32 %62, 1
store i32 %63, i32* %8
br label %32
64: ; preds = %32
%65 = load i8*, i8** %4
%66 = load i32, i32* %5
%67 = sext i32 %66 to i64
%68 = getelementptr inbounds i8, i8* %65, i64 %67
store i8 0, i8* %68
%69 = load i8*, i8** %4
ret i8* %69
}

LLVM IR (-O2):
@ultox.hex_array = internal unnamed_addr constant [17 x i8] c"0123456789ABCDEF\00"
define i8* @ultox(i32 %0, i8* %1) {
store i8 48, i8* %1
%3 = getelementptr inbounds i8, i8* %1, i64 1
store i8 120, i8* %3
%4 = getelementptr inbounds i8, i8* %1, i64 2
br label %5
5: ; preds = %5, %2
%6 = phi i64 [ %12, %5 ], [ 0, %2 ]
%7 = phi i32 [ %14, %5 ], [ %0, %2 ]
%8 = srem i32 %7, 16
%9 = sext i32 %8 to i64
%10 = getelementptr inbounds [17 x i8], [17 x i8]* @ultox.hex_array, i64 0, i64 %9
%11 = load i8, i8* %10
%12 = add nuw i64 %6, 1
%13 = getelementptr inbounds i8, i8* %4, i64 %6
store i8 %11, i8* %13
%14 = sdiv i32 %7, 16
%15 = icmp sgt i32 %7, 15
br i1 %15, label %5, label %16
16: ; preds = %5
%17 = trunc i64 %6 to i32
%18 = icmp eq i32 %17, 0
br i1 %18, label %40, label %19
19: ; preds = %16
%20 = trunc i64 %12 to i32
%21 = lshr i32 %20, 1
%22 = shl i64 %12, 32
%23 = ashr exact i64 %22, 32
%24 = call i32 @llvm.umax.i32(i32 %21, i32 1)
%25 = zext i32 %24 to i64
%26 = and i64 %25, 1
%27 = icmp ult i32 %20, 4
br i1 %27, label %30, label %28
28: ; preds = %19
%29 = and i64 %25, 2147483646
br label %43
30: ; preds = %43, %19
%31 = phi i64 [ 0, %19 ], [ %52, %43 ]
%32 = icmp eq i64 %26, 0
br i1 %32, label %40, label %33
33: ; preds = %30
%34 = xor i64 %31, -1
%35 = add i64 %23, %34
%36 = getelementptr inbounds i8, i8* %4, i64 %31
%37 = load i8, i8* %36
%38 = getelementptr inbounds i8, i8* %4, i64 %35
%39 = load i8, i8* %38
store i8 %39, i8* %36
store i8 %37, i8* %38
br label %40
40: ; preds = %33, %30, %16
%41 = and i64 %12, 4294967295
%42 = getelementptr inbounds i8, i8* %4, i64 %41
store i8 0, i8* %42
ret i8* %4
43: ; preds = %43, %28
%44 = phi i64 [ 0, %28 ], [ %52, %43 ]
%45 = phi i64 [ 0, %28 ], [ %58, %43 ]
%46 = or i64 %44, 1
%47 = sub nsw i64 %23, %46
%48 = getelementptr inbounds i8, i8* %4, i64 %44
%49 = load i8, i8* %48
%50 = getelementptr inbounds i8, i8* %4, i64 %47
%51 = load i8, i8* %50
store i8 %51, i8* %48
store i8 %49, i8* %50
%52 = add nuw nsw i64 %44, 2
%53 = sub nsw i64 %23, %52
%54 = getelementptr inbounds i8, i8* %4, i64 %46
%55 = load i8, i8* %54
%56 = getelementptr inbounds i8, i8* %4, i64 %53
%57 = load i8, i8* %56
store i8 %57, i8* %54
store i8 %55, i8* %56
%58 = add nuw i64 %45, 2
%59 = icmp eq i64 %58, %29
br i1 %59, label %30, label %43
}