#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 /*<<< orphan*/ buffer;

/* Variables and functions */
int /*<<< orphan*/ sprintf(char *, char *, int, ...);
scalar_t__ strlen(char *);
scalar_t__ strncat(char *, char *, scalar_t__);
scalar_t__ strncpy2(char *, char *, int);
char *bmap2units(unsigned int bmap) {
  static int invmap[] = {6, 14, 2, 10, 1, 9, 5, 13, 7, 15, 3, 11, 0, 8, 4, 12};
  static char buffer[128];
  char minbuf[8];
  unsigned int mask = 0x01;
  int j, count, nunits;
  int units[17];
  int first;
  if (bmap == 0) {
    (int)strncpy2(buffer, "0", sizeof(buffer) - 1);
    return buffer;
  }
  nunits = 0;
  for (j = 0; j < 16; j++) {
    mask = 0x01 << invmap[j];
    if (bmap & mask) {
      units[nunits++] = j + 1;
    }
  }
  units[nunits++] = 0;
  buffer[0] = buffer[1] = '\0';
  first = units[0];
  count = 1;
  for (j = 1; j < nunits; j++) {
    if (units[j] == units[j - 1] + 1) {
      count++;
      continue;
    }
    switch (count) {
    case 1:
      sprintf(minbuf, ",%d", first);
      break;
    case 2:
      sprintf(minbuf, ",%d,%d", first, units[j - 1]);
      break;
    default:
      sprintf(minbuf, ",%d-%d", first, units[j - 1]);
      break;
    }
    (int)strncat(buffer, minbuf, sizeof(buffer) - 1 - strlen(buffer));
    first = units[j];
    count = 1;
  }
  return buffer + 1;
}


x86 assembly (clang, -O0):
<bmap2units>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %edi,-0xc(%rbp)
movl   $0x1,-0x18(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    1187 <bmap2units+0x47>
lea    0x2f3a(%rip),%rdi
lea    0xe93(%rip),%rsi
mov    $0x7f,%edx
call   1050 <strncpy2@plt>
lea    0x2f22(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    1342 <bmap2units+0x202>
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x10,-0x1c(%rbp)
jge    11f0 <bmap2units+0xb0>
movslq -0x1c(%rbp),%rcx
lea    0x2ea6(%rip),%rax
mov    (%rax,%rcx,4),%ecx
mov    $0x1,%eax
shl    %cl,%eax
mov    %eax,-0x18(%rbp)
mov    -0xc(%rbp),%eax
and    -0x18(%rbp),%eax
cmp    $0x0,%eax
je     11dd <bmap2units+0x9d>
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
mov    -0x24(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x24(%rbp)
cltq
mov    %ecx,-0x70(%rbp,%rax,4)
jmp    11e2 <bmap2units+0xa2>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1195 <bmap2units+0x55>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x24(%rbp)
cltq
movl   $0x0,-0x70(%rbp,%rax,4)
movb   $0x0,0x2e95(%rip)
movb   $0x0,0x2e8d(%rip)
mov    -0x70(%rbp),%eax
mov    %eax,-0x74(%rbp)
movl   $0x1,-0x20(%rbp)
movl   $0x1,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    1333 <bmap2units+0x1f3>
movslq -0x1c(%rbp),%rax
mov    -0x70(%rbp,%rax,4),%eax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
mov    -0x70(%rbp,%rcx,4),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jne    1261 <bmap2units+0x121>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1325 <bmap2units+0x1e5>
mov    -0x20(%rbp),%eax
mov    %eax,-0x78(%rbp)
sub    $0x1,%eax
je     1286 <bmap2units+0x146>
jmp    1275 <bmap2units+0x135>
mov    -0x78(%rbp),%eax
sub    $0x2,%eax
je     12a0 <bmap2units+0x160>
jmp    12c6 <bmap2units+0x186>
lea    -0x14(%rbp),%rdi
mov    -0x74(%rbp),%edx
lea    0xd71(%rip),%rsi
mov    $0x0,%al
call   1060 <sprintf@plt>
jmp    12e7 <bmap2units+0x1a7>
lea    -0x14(%rbp),%rdi
mov    -0x74(%rbp),%edx
mov    -0x1c(%rbp),%eax
sub    $0x1,%eax
cltq
mov    -0x70(%rbp,%rax,4),%ecx
lea    0xd48(%rip),%rsi
mov    $0x0,%al
call   1060 <sprintf@plt>
jmp    12e7 <bmap2units+0x1a7>
lea    -0x14(%rbp),%rdi
mov    -0x74(%rbp),%edx
mov    -0x1c(%rbp),%eax
sub    $0x1,%eax
cltq
mov    -0x70(%rbp,%rax,4),%ecx
lea    0xd29(%rip),%rsi
mov    $0x0,%al
call   1060 <sprintf@plt>
lea    -0x14(%rbp),%rax
mov    %rax,-0x80(%rbp)
lea    0x2daa(%rip),%rdi
call   1030 <strlen@plt>
mov    -0x80(%rbp),%rsi
mov    $0x7f,%edx
sub    %rax,%rdx
lea    0x2d92(%rip),%rdi
call   1040 <strncat@plt>
movslq -0x1c(%rbp),%rax
mov    -0x70(%rbp,%rax,4),%eax
mov    %eax,-0x74(%rbp)
movl   $0x1,-0x20(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1227 <bmap2units+0xe7>
lea    0x2d66(%rip),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bmap2units>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x58,%rsp
test   %edi,%edi
je     1262 <bmap2units+0x122>
xor    %r14d,%r14d
mov    $0x1,%eax
mov    $0x2,%ecx
lea    0xe96(%rip),%rdx
jmp    117d <bmap2units+0x3d>
nopl   0x0(%rax)
add    $0x2,%rax
add    $0x2,%ecx
cmp    $0x11,%rax
je     11a6 <bmap2units+0x66>
mov    -0x4(%rdx,%rax,4),%esi
bt     %esi,%edi
jae    1191 <bmap2units+0x51>
movslq %r14d,%rsi
add    $0x1,%r14d
mov    %eax,0x10(%rsp,%rsi,4)
mov    (%rdx,%rax,4),%esi
bt     %esi,%edi
jae    1170 <bmap2units+0x30>
movslq %r14d,%rsi
add    $0x1,%r14d
mov    %ecx,0x10(%rsp,%rsi,4)
jmp    1170 <bmap2units+0x30>
movslq %r14d,%rax
movl   $0x0,0x10(%rsp,%rax,4)
lea    0x2e99(%rip),%r15
movw   $0x0,0x2e8f(%rip)
test   %eax,%eax
jle    127d <bmap2units+0x13d>
mov    0x10(%rsp),%ecx
add    $0x1,%r14d
mov    $0x1,%eax
mov    $0x1,%r13d
lea    0x8(%rsp),%r12
lea    0x2e68(%rip),%rbx
mov    %ecx,%edx
jmp    11fe <bmap2units+0xbe>
nopl   0x0(%rax)
add    $0x1,%eax
add    $0x1,%r13
mov    %ebp,%ecx
cmp    %r13,%r14
je     127d <bmap2units+0x13d>
mov    0x10(%rsp,%r13,4),%ebp
lea    0x1(%rcx),%esi
cmp    %esi,%ebp
je     11f0 <bmap2units+0xb0>
mov    %r12,%rdi
cmp    $0x2,%eax
je     1227 <bmap2units+0xe7>
cmp    $0x1,%eax
jne    1230 <bmap2units+0xf0>
lea    0xe27(%rip),%rsi
xor    %eax,%eax
call   1060 <sprintf@plt>
jmp    123e <bmap2units+0xfe>
lea    0xe14(%rip),%rsi
jmp    1237 <bmap2units+0xf7>
lea    0xe12(%rip),%rsi
xor    %eax,%eax
call   1060 <sprintf@plt>
mov    %rbx,%rdi
call   1030 <strlen@plt>
mov    $0x7f,%edx
sub    %rax,%rdx
mov    %rbx,%rdi
mov    %r12,%rsi
call   1040 <strncat@plt>
mov    $0x1,%eax
mov    %ebp,%edx
jmp    11f3 <bmap2units+0xb3>
lea    0x2de7(%rip),%r15
lea    0xdd0(%rip),%rsi
mov    %r15,%rdi
mov    $0x7f,%edx
call   1050 <strncpy2@plt>
mov    %r15,%rax
add    $0x58,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@bmap2units.invmap = internal global [16 x i32] [i32 6, i32 14, i32 2, i32 10, i32 1, i32 9, i32 5, i32 13, i32 7, i32 15, i32 3, i32 11, i32 0, i32 8, i32 4, i32 12]
@bmap2units.buffer = internal global [128 x i8] zeroinitializer
@.str = [2 x i8] c"0\00"
@.str.1 = [4 x i8] c",%d\00"
@.str.2 = [7 x i8] c",%d,%d\00"
@.str.3 = [7 x i8] c",%d-%d\00"
define i8* @bmap2units(i32 %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca [8 x i8]
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca [17 x i32]
%10 = alloca i32
store i32 %0, i32* %3
store i32 1, i32* %5
%11 = load i32, i32* %3
%12 = icmp eq i32 %11, 0
br i1 %12, label %13, label %16
13: ; preds = %1
%14 = call i64 @strncpy2(i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), i32 127)
%15 = trunc i64 %14 to i32
store i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0), i8** %2
br label %105
16: ; preds = %1
store i32 0, i32* %8
store i32 0, i32* %6
br label %17
17: ; preds = %38, %16
%18 = load i32, i32* %6
%19 = icmp slt i32 %18, 16
br i1 %19, label %20, label %41
20: ; preds = %17
%21 = load i32, i32* %6
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds [16 x i32], [16 x i32]* @bmap2units.invmap, i64 0, i64 %22
%24 = load i32, i32* %23
%25 = shl i32 1, %24
store i32 %25, i32* %5
%26 = load i32, i32* %3
%27 = load i32, i32* %5
%28 = and i32 %26, %27
%29 = icmp ne i32 %28, 0
br i1 %29, label %30, label %37
30: ; preds = %20
%31 = load i32, i32* %6
%32 = add nsw i32 %31, 1
%33 = load i32, i32* %8
%34 = add nsw i32 %33, 1
store i32 %34, i32* %8
%35 = sext i32 %33 to i64
%36 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 %35
store i32 %32, i32* %36
br label %37
37: ; preds = %30, %20
br label %38
38: ; preds = %37
%39 = load i32, i32* %6
%40 = add nsw i32 %39, 1
store i32 %40, i32* %6
br label %17
41: ; preds = %17
%42 = load i32, i32* %8
%43 = add nsw i32 %42, 1
store i32 %43, i32* %8
%44 = sext i32 %42 to i64
%45 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 %44
store i32 0, i32* %45
store i8 0, i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 1)
store i8 0, i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0)
%46 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 0
%47 = load i32, i32* %46
store i32 %47, i32* %10
store i32 1, i32* %7
store i32 1, i32* %6
br label %48
48: ; preds = %101, %41
%49 = load i32, i32* %6
%50 = load i32, i32* %8
%51 = icmp slt i32 %49, %50
br i1 %51, label %52, label %104
52: ; preds = %48
%53 = load i32, i32* %6
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 %54
%56 = load i32, i32* %55
%57 = load i32, i32* %6
%58 = sub nsw i32 %57, 1
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 %59
%61 = load i32, i32* %60
%62 = add nsw i32 %61, 1
%63 = icmp eq i32 %56, %62
br i1 %63, label %64, label %67
64: ; preds = %52
%65 = load i32, i32* %7
%66 = add nsw i32 %65, 1
store i32 %66, i32* %7
br label %101
67: ; preds = %52
%68 = load i32, i32* %7
switch i32 %68, label %82 [
i32 1, label %69
i32 2, label %73
]
69: ; preds = %67
%70 = getelementptr inbounds [8 x i8], [8 x i8]* %4, i64 0, i64 0
%71 = load i32, i32* %10
%72 = call i32 (i8*, i8*, i32, ...) @sprintf(i8* %70, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i32 %71)
br label %91
73: ; preds = %67
%74 = getelementptr inbounds [8 x i8], [8 x i8]* %4, i64 0, i64 0
%75 = load i32, i32* %10
%76 = load i32, i32* %6
%77 = sub nsw i32 %76, 1
%78 = sext i32 %77 to i64
%79 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 %78
%80 = load i32, i32* %79
%81 = call i32 (i8*, i8*, i32, ...) @sprintf(i8* %74, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0), i32 %75, i32 %80)
br label %91
82: ; preds = %67
%83 = getelementptr inbounds [8 x i8], [8 x i8]* %4, i64 0, i64 0
%84 = load i32, i32* %10
%85 = load i32, i32* %6
%86 = sub nsw i32 %85, 1
%87 = sext i32 %86 to i64
%88 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 %87
%89 = load i32, i32* %88
%90 = call i32 (i8*, i8*, i32, ...) @sprintf(i8* %83, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0), i32 %84, i32 %89)
br label %91
91: ; preds = %82, %73, %69
%92 = getelementptr inbounds [8 x i8], [8 x i8]* %4, i64 0, i64 0
%93 = call i64 @strlen(i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0))
%94 = sub i64 127, %93
%95 = call i64 @strncat(i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0), i8* %92, i64 %94)
%96 = trunc i64 %95 to i32
%97 = load i32, i32* %6
%98 = sext i32 %97 to i64
%99 = getelementptr inbounds [17 x i32], [17 x i32]* %9, i64 0, i64 %98
%100 = load i32, i32* %99
store i32 %100, i32* %10
store i32 1, i32* %7
br label %101
101: ; preds = %91, %64
%102 = load i32, i32* %6
%103 = add nsw i32 %102, 1
store i32 %103, i32* %6
br label %48
104: ; preds = %48
store i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 1), i8** %2
br label %105
105: ; preds = %104, %13
%106 = load i8*, i8** %2
ret i8* %106
}

LLVM IR (-O2):
@bmap2units.invmap = internal unnamed_addr constant [16 x i32] [i32 6, i32 14, i32 2, i32 10, i32 1, i32 9, i32 5, i32 13, i32 7, i32 15, i32 3, i32 11, i32 0, i32 8, i32 4, i32 12]
@bmap2units.buffer = internal global [128 x i8] zeroinitializer
@.str = [2 x i8] c"0\00"
@.str.1 = [4 x i8] c",%d\00"
@.str.2 = [7 x i8] c",%d,%d\00"
@.str.3 = [7 x i8] c",%d-%d\00"
define i8* @bmap2units(i32 %0) {
%2 = alloca [8 x i8]
%3 = alloca [17 x i32]
%4 = getelementptr inbounds [8 x i8], [8 x i8]* %2, i64 0, i64 0
%5 = bitcast [17 x i32]* %3 to i8*
%6 = icmp eq i32 %0, 0
br i1 %6, label %7, label %9
7: ; preds = %1
%8 = tail call i64 @strncpy2(i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), i32 127)
br label %75
9: ; preds = %1, %36
%10 = phi i64 [ %30, %36 ], [ 0, %1 ]
%11 = phi i32 [ %37, %36 ], [ 0, %1 ]
%12 = getelementptr inbounds [16 x i32], [16 x i32]* @bmap2units.invmap, i64 0, i64 %10
%13 = load i32, i32* %12
%14 = shl nuw i32 1, %13
%15 = and i32 %14, %0
%16 = icmp eq i32 %15, 0
%17 = or i64 %10, 1
br i1 %16, label %23, label %18
18: ; preds = %9
%19 = add nsw i32 %11, 1
%20 = sext i32 %11 to i64
%21 = getelementptr inbounds [17 x i32], [17 x i32]* %3, i64 0, i64 %20
%22 = trunc i64 %17 to i32
store i32 %22, i32* %21
br label %23
23: ; preds = %9, %18
%24 = phi i32 [ %19, %18 ], [ %11, %9 ]
%25 = getelementptr inbounds [16 x i32], [16 x i32]* @bmap2units.invmap, i64 0, i64 %17
%26 = load i32, i32* %25
%27 = shl nuw i32 1, %26
%28 = and i32 %27, %0
%29 = icmp eq i32 %28, 0
%30 = add nuw nsw i64 %10, 2
br i1 %29, label %36, label %31
31: ; preds = %23
%32 = add nsw i32 %24, 1
%33 = sext i32 %24 to i64
%34 = getelementptr inbounds [17 x i32], [17 x i32]* %3, i64 0, i64 %33
%35 = trunc i64 %30 to i32
store i32 %35, i32* %34
br label %36
36: ; preds = %31, %23
%37 = phi i32 [ %32, %31 ], [ %24, %23 ]
%38 = icmp eq i64 %30, 16
br i1 %38, label %39, label %9
39: ; preds = %36
%40 = sext i32 %37 to i64
%41 = getelementptr inbounds [17 x i32], [17 x i32]* %3, i64 0, i64 %40
store i32 0, i32* %41
store i8 0, i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 1)
store i8 0, i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0)
%42 = getelementptr inbounds [17 x i32], [17 x i32]* %3, i64 0, i64 0
%43 = load i32, i32* %42
%44 = icmp slt i32 %37, 1
br i1 %44, label %75, label %45
45: ; preds = %39
%46 = add nuw i32 %37, 1
%47 = zext i32 %46 to i64
br label %48
48: ; preds = %45, %70
%49 = phi i32 [ %43, %45 ], [ %54, %70 ]
%50 = phi i64 [ 1, %45 ], [ %73, %70 ]
%51 = phi i32 [ %43, %45 ], [ %72, %70 ]
%52 = phi i32 [ 1, %45 ], [ %71, %70 ]
%53 = getelementptr inbounds [17 x i32], [17 x i32]* %3, i64 0, i64 %50
%54 = load i32, i32* %53
%55 = add nsw i32 %49, 1
%56 = icmp eq i32 %54, %55
br i1 %56, label %57, label %59
57: ; preds = %48
%58 = add nsw i32 %52, 1
br label %70
59: ; preds = %48
switch i32 %52, label %64 [
i32 1, label %60
i32 2, label %62
]
60: ; preds = %59
%61 = call i32 (i8*, i8*, i32, ...) @sprintf(i8* %4, i8* dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i32 %51)
br label %66
62: ; preds = %59
%63 = call i32 (i8*, i8*, i32, ...) @sprintf(i8* %4, i8* dereferenceable(1) getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0), i32 %51, i32 %49)
br label %66
64: ; preds = %59
%65 = call i32 (i8*, i8*, i32, ...) @sprintf(i8* %4, i8* dereferenceable(1) getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0), i32 %51, i32 %49)
br label %66
66: ; preds = %64, %62, %60
%67 = call i64 @strlen(i8* dereferenceable(1) getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0))
%68 = sub i64 127, %67
%69 = call i64 @strncat(i8* getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0), i8* %4, i64 %68)
br label %70
70: ; preds = %66, %57
%71 = phi i32 [ %58, %57 ], [ 1, %66 ]
%72 = phi i32 [ %51, %57 ], [ %54, %66 ]
%73 = add nuw nsw i64 %50, 1
%74 = icmp eq i64 %73, %47
br i1 %74, label %75, label %48
75: ; preds = %70, %39, %7
%76 = phi i8* [ getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 0), %7 ], [ getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 1), %39 ], [ getelementptr inbounds ([128 x i8], [128 x i8]* @bmap2units.buffer, i64 0, i64 1), %70 ]
ret i8* %76
}