#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 */
struct option {
  scalar_t__ has_arg;
  int /*<<< orphan*/ val;
  scalar_t__ name;
};

/* Variables and functions */
scalar_t__ isprint(int /*<<< orphan*/);
void get_short_opts(struct option *o, char *s) {
  *s++ = '+';
  while (o->name) {
    if (isprint(o->val)) {
      *s++ = o->val;
      if (o->has_arg)
        *s++ = ':';
    }
    o++;
  }
  *s = '\0';
}


x86 assembly (clang, -O0):
<get_short_opts>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x2b,(%rax)
mov    -0x8(%rbp),%rax
cmpq   $0x0,0x10(%rax)
je     11a7 <get_short_opts+0x97>
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%edi
call   1030 <isprint@plt>
cmp    $0x0,%rax
je     1196 <get_short_opts+0x86>
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%rax
cmpq   $0x0,(%rax)
je     1191 <get_short_opts+0x81>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x3a,(%rax)
jmp    1196 <get_short_opts+0x86>
mov    -0x8(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x8(%rbp)
jmp    1132 <get_short_opts+0x22>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_short_opts>:
push   %r14
push   %rbx
push   %rax
mov    %rsi,%r14
movb   $0x2b,(%rsi)
add    $0x1,%r14
cmpq   $0x0,0x10(%rdi)
je     1164 <get_short_opts+0x54>
mov    %rdi,%rbx
jmp    1144 <get_short_opts+0x34>
nopw   0x0(%rax,%rax,1)
movb   $0x3a,0x1(%r14)
add    $0x2,%r14
cmpq   $0x0,0x28(%rbx)
lea    0x18(%rbx),%rbx
je     1164 <get_short_opts+0x54>
mov    0x8(%rbx),%edi
call   1030 <isprint@plt>
test   %rax,%rax
je     1139 <get_short_opts+0x29>
movzbl 0x8(%rbx),%eax
mov    %al,(%r14)
cmpq   $0x0,(%rbx)
jne    1130 <get_short_opts+0x20>
add    $0x1,%r14
jmp    1139 <get_short_opts+0x29>
movb   $0x0,(%r14)
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%struct.option = type { i64, i32, i64 }
define void @get_short_opts(%struct.option* %0, i8* %1) {
%3 = alloca %struct.option*
%4 = alloca i8*
store %struct.option* %0, %struct.option** %3
store i8* %1, i8** %4
%5 = load i8*, i8** %4
%6 = getelementptr inbounds i8, i8* %5, i32 1
store i8* %6, i8** %4
store i8 43, i8* %5
br label %7
7: ; preds = %33, %2
%8 = load %struct.option*, %struct.option** %3
%9 = getelementptr inbounds %struct.option, %struct.option* %8, i32 0, i32 2
%10 = load i64, i64* %9
%11 = icmp ne i64 %10, 0
br i1 %11, label %12, label %36
12: ; preds = %7
%13 = load %struct.option*, %struct.option** %3
%14 = getelementptr inbounds %struct.option, %struct.option* %13, i32 0, i32 1
%15 = load i32, i32* %14
%16 = call i64 @isprint(i32 %15)
%17 = icmp ne i64 %16, 0
br i1 %17, label %18, label %33
18: ; preds = %12
%19 = load %struct.option*, %struct.option** %3
%20 = getelementptr inbounds %struct.option, %struct.option* %19, i32 0, i32 1
%21 = load i32, i32* %20
%22 = trunc i32 %21 to i8
%23 = load i8*, i8** %4
%24 = getelementptr inbounds i8, i8* %23, i32 1
store i8* %24, i8** %4
store i8 %22, i8* %23
%25 = load %struct.option*, %struct.option** %3
%26 = getelementptr inbounds %struct.option, %struct.option* %25, i32 0, i32 0
%27 = load i64, i64* %26
%28 = icmp ne i64 %27, 0
br i1 %28, label %29, label %32
29: ; preds = %18
%30 = load i8*, i8** %4
%31 = getelementptr inbounds i8, i8* %30, i32 1
store i8* %31, i8** %4
store i8 58, i8* %30
br label %32
32: ; preds = %29, %18
br label %33
33: ; preds = %32, %12
%34 = load %struct.option*, %struct.option** %3
%35 = getelementptr inbounds %struct.option, %struct.option* %34, i32 1
store %struct.option* %35, %struct.option** %3
br label %7
36: ; preds = %7
%37 = load i8*, i8** %4
store i8 0, i8* %37
ret void
}

LLVM IR (-O2):
%struct.option = type { i64, i32, i64 }
define void @get_short_opts(%struct.option* nocapture %0, i8* nocapture writeonly %1) {
%3 = getelementptr inbounds i8, i8* %1, i64 1
store i8 43, i8* %1
%4 = getelementptr inbounds %struct.option, %struct.option* %0, i64 0, i32 2
%5 = load i64, i64* %4
%6 = icmp eq i64 %5, 0
br i1 %6, label %29, label %7
7: ; preds = %2, %23
%8 = phi i8* [ %24, %23 ], [ %3, %2 ]
%9 = phi %struct.option* [ %25, %23 ], [ %0, %2 ]
%10 = getelementptr inbounds %struct.option, %struct.option* %9, i64 0, i32 1
%11 = load i32, i32* %10
%12 = tail call i64 @isprint(i32 %11)
%13 = icmp eq i64 %12, 0
br i1 %13, label %23, label %14
14: ; preds = %7
%15 = load i32, i32* %10
%16 = trunc i32 %15 to i8
%17 = getelementptr inbounds i8, i8* %8, i64 1
store i8 %16, i8* %8
%18 = getelementptr inbounds %struct.option, %struct.option* %9, i64 0, i32 0
%19 = load i64, i64* %18
%20 = icmp eq i64 %19, 0
br i1 %20, label %23, label %21
21: ; preds = %14
%22 = getelementptr inbounds i8, i8* %8, i64 2
store i8 58, i8* %17
br label %23
23: ; preds = %14, %21, %7
%24 = phi i8* [ %22, %21 ], [ %17, %14 ], [ %8, %7 ]
%25 = getelementptr inbounds %struct.option, %struct.option* %9, i64 1
%26 = getelementptr inbounds %struct.option, %struct.option* %9, i64 1, i32 2
%27 = load i64, i64* %26
%28 = icmp eq i64 %27, 0
br i1 %28, label %29, label %7
29: ; preds = %23, %2
%30 = phi i8* [ %3, %2 ], [ %24, %23 ]
store i8 0, i8* %30
ret void
}