#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 termios {
  int c_cflag;
  int c_lflag;
  int *c_cc;
  int /*<<< orphan*/ c_oflag;
};
typedef int /*<<< orphan*/ options;

/* Variables and functions */
int B115200;
int CLOCAL;
int CREAD;
int CS8;
int CSIZE;
int CSTOPB;
int ECHO;
int ECHOE;
int /*<<< orphan*/ FNDELAY;
int /*<<< orphan*/ F_SETFL;
int ICANON;
int ISIG;
int /*<<< orphan*/ OPOST;
int O_NDELAY;
int O_NOCTTY;
int O_RDWR;
int PARENB;
int /*<<< orphan*/ TCIOFLUSH;
int /*<<< orphan*/ TCSAFLUSH;
int /*<<< orphan*/ TIOCEXCL;
size_t VMIN;
size_t VTIME;
int /*<<< orphan*/ bzero(struct termios *, int);
int /*<<< orphan*/ cfsetspeed(struct termios *, int);
scalar_t__ fcntl(int, int /*<<< orphan*/, int /*<<< orphan*/);
scalar_t__ ioctl(int, int /*<<< orphan*/);
int open(char *, int);
int /*<<< orphan*/ tcflush(int, int /*<<< orphan*/);
scalar_t__ tcsetattr(int, int /*<<< orphan*/, struct termios *);
int open_port(char *device) {
  int fd;
  struct termios options;
  fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd >= 0) {
    if (ioctl(fd, TIOCEXCL) != 0)
      return (-1);
    if (fcntl(fd, F_SETFL, 0) != 0)
      return (-2);
    bzero(&options, sizeof(options));
    cfsetspeed(&options, B115200);
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag = B115200;
    options.c_cflag |= CS8;
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;
    options.c_cc[VMIN] = 1;
    options.c_cc[VTIME] = 0;
    tcflush(fd, TCIOFLUSH);
    if (tcsetattr(fd, TCSAFLUSH, &options) != 0)
      return (-4);
    fcntl(fd, F_SETFL, FNDELAY);
    fcntl(fd, F_SETFL, 0);
  }
  return (fd);
}


x86 assembly (clang, -O0):
<open_port>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
mov    0x2e61(%rip),%rax
mov    (%rax),%esi
mov    0x2df0(%rip),%rax
or     (%rax),%esi
mov    0x2dd7(%rip),%rax
or     (%rax),%esi
call   1080 <open@plt>
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jl     1358 <open_port+0x1e8>
mov    -0x14(%rbp),%edi
mov    0x2e29(%rip),%rax
mov    (%rax),%esi
call   1060 <ioctl@plt>
cmp    $0x0,%rax
je     11d4 <open_port+0x64>
movl   $0xffffffff,-0x4(%rbp)
jmp    135e <open_port+0x1ee>
mov    -0x14(%rbp),%edi
mov    0x2d9a(%rip),%rax
mov    (%rax),%esi
xor    %edx,%edx
call   1030 <fcntl@plt>
cmp    $0x0,%rax
je     11fd <open_port+0x8d>
movl   $0xfffffffe,-0x4(%rbp)
jmp    135e <open_port+0x1ee>
lea    -0x30(%rbp),%rdi
mov    $0x18,%esi
call   1090 <bzero@plt>
mov    0x2d46(%rip),%rax
mov    (%rax),%esi
lea    -0x30(%rbp),%rdi
call   1050 <cfsetspeed@plt>
mov    0x2da4(%rip),%rax
mov    (%rax),%eax
xor    $0xffffffff,%eax
and    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    0x2d02(%rip),%rax
mov    (%rax),%eax
xor    $0xffffffff,%eax
and    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    0x2d48(%rip),%rax
mov    (%rax),%eax
xor    $0xffffffff,%eax
and    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    0x2cfe(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x30(%rbp)
mov    0x2d3a(%rip),%rax
mov    (%rax),%eax
or     -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    0x2cbb(%rip),%rax
mov    (%rax),%eax
mov    0x2d2a(%rip),%rcx
or     (%rcx),%eax
or     -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    0x2cbb(%rip),%rax
mov    (%rax),%eax
mov    0x2d2a(%rip),%rcx
or     (%rcx),%eax
mov    0x2d19(%rip),%rcx
or     (%rcx),%eax
mov    0x2d08(%rip),%rcx
or     (%rcx),%eax
xor    $0xffffffff,%eax
and    -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    0x2d16(%rip),%rax
mov    (%rax),%eax
xor    $0xffffffff,%eax
and    -0x20(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x28(%rbp),%rax
mov    0x2cc8(%rip),%rcx
mov    (%rcx),%rcx
movl   $0x1,(%rax,%rcx,4)
mov    -0x28(%rbp),%rax
mov    0x2c6b(%rip),%rcx
mov    (%rcx),%rcx
movl   $0x0,(%rax,%rcx,4)
mov    -0x14(%rbp),%edi
mov    0x2c6f(%rip),%rax
mov    (%rax),%esi
call   1040 <tcflush@plt>
mov    -0x14(%rbp),%edi
mov    0x2cce(%rip),%rax
mov    (%rax),%esi
lea    -0x30(%rbp),%rdx
call   1070 <tcsetattr@plt>
cmp    $0x0,%rax
je     132b <open_port+0x1bb>
movl   $0xfffffffc,-0x4(%rbp)
jmp    135e <open_port+0x1ee>
mov    -0x14(%rbp),%edi
mov    0x2c43(%rip),%rax
mov    (%rax),%esi
mov    0x2c22(%rip),%rax
mov    (%rax),%edx
call   1030 <fcntl@plt>
mov    -0x14(%rbp),%edi
mov    0x2c29(%rip),%rax
mov    (%rax),%esi
xor    %edx,%edx
call   1030 <fcntl@plt>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<open_port>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    0x2e66(%rip),%rax
mov    0x2e07(%rip),%rcx
mov    (%rcx),%esi
or     (%rax),%esi
mov    0x2dec(%rip),%rax
or     (%rax),%esi
call   1080 <open@plt>
mov    %eax,%ebx
test   %eax,%eax
js     12de <open_port+0x16e>
mov    0x2e34(%rip),%rax
mov    (%rax),%esi
mov    %ebx,%edi
call   1060 <ioctl@plt>
mov    %rax,%rcx
mov    $0xffffffff,%eax
test   %rcx,%rcx
jne    12e0 <open_port+0x170>
mov    0x2dbb(%rip),%r15
mov    (%r15),%esi
mov    %ebx,%edi
xor    %edx,%edx
call   1030 <fcntl@plt>
mov    %rax,%rcx
mov    $0xfffffffe,%eax
test   %rcx,%rcx
jne    12e0 <open_port+0x170>
mov    %rsp,%r14
mov    %r14,%rdi
mov    $0x18,%esi
call   1090 <bzero@plt>
mov    0x2d67(%rip),%r12
mov    (%r12),%esi
mov    %r14,%rdi
call   1050 <cfsetspeed@plt>
mov    0x2d94(%rip),%rax
mov    (%rax),%eax
or     (%r12),%eax
mov    0x2d27(%rip),%rcx
or     (%rcx),%eax
mov    0x2d86(%rip),%rcx
or     (%rcx),%eax
mov    0x2d25(%rip),%rcx
mov    0x2d8e(%rip),%rdx
mov    (%rdx),%edx
or     (%rcx),%edx
mov    0x2d7b(%rip),%rcx
or     (%rcx),%edx
mov    %eax,(%rsp)
mov    0x2d67(%rip),%rax
or     (%rax),%edx
not    %edx
and    %edx,0x4(%rsp)
mov    0x2d70(%rip),%rax
mov    (%rax),%eax
not    %eax
and    %eax,0x10(%rsp)
mov    0x8(%rsp),%rax
mov    0x2d2c(%rip),%rcx
mov    (%rcx),%rcx
movl   $0x1,(%rax,%rcx,4)
mov    0x2cdb(%rip),%rcx
mov    (%rcx),%rcx
movl   $0x0,(%rax,%rcx,4)
mov    0x2ce2(%rip),%rax
mov    (%rax),%esi
mov    %ebx,%edi
call   1040 <tcflush@plt>
mov    0x2d32(%rip),%rax
mov    (%rax),%esi
mov    %ebx,%edi
mov    %r14,%rdx
call   1070 <tcsetattr@plt>
mov    %rax,%rcx
mov    $0xfffffffc,%eax
test   %rcx,%rcx
jne    12e0 <open_port+0x170>
mov    (%r15),%esi
mov    0x2ca7(%rip),%rax
mov    (%rax),%edx
mov    %ebx,%edi
call   1030 <fcntl@plt>
mov    (%r15),%esi
mov    %ebx,%edi
xor    %edx,%edx
call   1030 <fcntl@plt>
mov    %ebx,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.termios = type { i32, i32, i32*, i32 }
@O_RDWR = global i32 0
@O_NOCTTY = global i32 0
@O_NDELAY = global i32 0
@TIOCEXCL = global i32 0
@F_SETFL = global i32 0
@B115200 = global i32 0
@PARENB = global i32 0
@CSTOPB = global i32 0
@CSIZE = global i32 0
@CS8 = global i32 0
@CLOCAL = global i32 0
@CREAD = global i32 0
@ICANON = global i32 0
@ECHO = global i32 0
@ECHOE = global i32 0
@ISIG = global i32 0
@OPOST = global i32 0
@VMIN = global i64 0
@VTIME = global i64 0
@TCIOFLUSH = global i32 0
@TCSAFLUSH = global i32 0
@FNDELAY = global i32 0
define i32 @open_port(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i32
%5 = alloca %struct.termios
store i8* %0, i8** %3
%6 = load i8*, i8** %3
%7 = load i32, i32* @O_RDWR
%8 = load i32, i32* @O_NOCTTY
%9 = or i32 %7, %8
%10 = load i32, i32* @O_NDELAY
%11 = or i32 %9, %10
%12 = call i32 @open(i8* %6, i32 %11)
store i32 %12, i32* %4
%13 = load i32, i32* %4
%14 = icmp sge i32 %13, 0
br i1 %14, label %15, label %98
15: ; preds = %1
%16 = load i32, i32* %4
%17 = load i32, i32* @TIOCEXCL
%18 = call i64 @ioctl(i32 %16, i32 %17)
%19 = icmp ne i64 %18, 0
br i1 %19, label %20, label %21
20: ; preds = %15
store i32 -1, i32* %2
br label %100
21: ; preds = %15
%22 = load i32, i32* %4
%23 = load i32, i32* @F_SETFL
%24 = call i64 @fcntl(i32 %22, i32 %23, i32 0)
%25 = icmp ne i64 %24, 0
br i1 %25, label %26, label %27
26: ; preds = %21
store i32 -2, i32* %2
br label %100
27: ; preds = %21
%28 = call i32 @bzero(%struct.termios* %5, i32 24)
%29 = load i32, i32* @B115200
%30 = call i32 @cfsetspeed(%struct.termios* %5, i32 %29)
%31 = load i32, i32* @PARENB
%32 = xor i32 %31, -1
%33 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 0
%34 = load i32, i32* %33
%35 = and i32 %34, %32
store i32 %35, i32* %33
%36 = load i32, i32* @CSTOPB
%37 = xor i32 %36, -1
%38 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 0
%39 = load i32, i32* %38
%40 = and i32 %39, %37
store i32 %40, i32* %38
%41 = load i32, i32* @CSIZE
%42 = xor i32 %41, -1
%43 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 0
%44 = load i32, i32* %43
%45 = and i32 %44, %42
store i32 %45, i32* %43
%46 = load i32, i32* @B115200
%47 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 0
store i32 %46, i32* %47
%48 = load i32, i32* @CS8
%49 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 0
%50 = load i32, i32* %49
%51 = or i32 %50, %48
store i32 %51, i32* %49
%52 = load i32, i32* @CLOCAL
%53 = load i32, i32* @CREAD
%54 = or i32 %52, %53
%55 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 0
%56 = load i32, i32* %55
%57 = or i32 %56, %54
store i32 %57, i32* %55
%58 = load i32, i32* @ICANON
%59 = load i32, i32* @ECHO
%60 = or i32 %58, %59
%61 = load i32, i32* @ECHOE
%62 = or i32 %60, %61
%63 = load i32, i32* @ISIG
%64 = or i32 %62, %63
%65 = xor i32 %64, -1
%66 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 1
%67 = load i32, i32* %66
%68 = and i32 %67, %65
store i32 %68, i32* %66
%69 = load i32, i32* @OPOST
%70 = xor i32 %69, -1
%71 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 3
%72 = load i32, i32* %71
%73 = and i32 %72, %70
store i32 %73, i32* %71
%74 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 2
%75 = load i32*, i32** %74
%76 = load i64, i64* @VMIN
%77 = getelementptr inbounds i32, i32* %75, i64 %76
store i32 1, i32* %77
%78 = getelementptr inbounds %struct.termios, %struct.termios* %5, i32 0, i32 2
%79 = load i32*, i32** %78
%80 = load i64, i64* @VTIME
%81 = getelementptr inbounds i32, i32* %79, i64 %80
store i32 0, i32* %81
%82 = load i32, i32* %4
%83 = load i32, i32* @TCIOFLUSH
%84 = call i32 @tcflush(i32 %82, i32 %83)
%85 = load i32, i32* %4
%86 = load i32, i32* @TCSAFLUSH
%87 = call i64 @tcsetattr(i32 %85, i32 %86, %struct.termios* %5)
%88 = icmp ne i64 %87, 0
br i1 %88, label %89, label %90
89: ; preds = %27
store i32 -4, i32* %2
br label %100
90: ; preds = %27
%91 = load i32, i32* %4
%92 = load i32, i32* @F_SETFL
%93 = load i32, i32* @FNDELAY
%94 = call i64 @fcntl(i32 %91, i32 %92, i32 %93)
%95 = load i32, i32* %4
%96 = load i32, i32* @F_SETFL
%97 = call i64 @fcntl(i32 %95, i32 %96, i32 0)
br label %98
98: ; preds = %90, %1
%99 = load i32, i32* %4
store i32 %99, i32* %2
br label %100
100: ; preds = %98, %89, %26, %20
%101 = load i32, i32* %2
ret i32 %101
}

LLVM IR (-O2):
%struct.termios = type { i32, i32, i32*, i32 }
@O_RDWR = global i32 0
@O_NOCTTY = global i32 0
@O_NDELAY = global i32 0
@TIOCEXCL = global i32 0
@F_SETFL = global i32 0
@B115200 = global i32 0
@PARENB = global i32 0
@CSTOPB = global i32 0
@CSIZE = global i32 0
@CS8 = global i32 0
@CLOCAL = global i32 0
@CREAD = global i32 0
@ICANON = global i32 0
@ECHO = global i32 0
@ECHOE = global i32 0
@ISIG = global i32 0
@OPOST = global i32 0
@VMIN = global i64 0
@VTIME = global i64 0
@TCIOFLUSH = global i32 0
@TCSAFLUSH = global i32 0
@FNDELAY = global i32 0
define i32 @open_port(i8* nocapture %0) {
%2 = alloca %struct.termios
%3 = bitcast %struct.termios* %2 to i8*
%4 = load i32, i32* @O_RDWR
%5 = load i32, i32* @O_NOCTTY
%6 = or i32 %5, %4
%7 = load i32, i32* @O_NDELAY
%8 = or i32 %6, %7
%9 = tail call i32 @open(i8* %0, i32 %8)
%10 = icmp sgt i32 %9, -1
br i1 %10, label %11, label %64
11: ; preds = %1
%12 = load i32, i32* @TIOCEXCL
%13 = tail call i64 @ioctl(i32 %9, i32 %12)
%14 = icmp eq i64 %13, 0
br i1 %14, label %15, label %64
15: ; preds = %11
%16 = load i32, i32* @F_SETFL
%17 = tail call i64 @fcntl(i32 %9, i32 %16, i32 0)
%18 = icmp eq i64 %17, 0
br i1 %18, label %19, label %64
19: ; preds = %15
%20 = call i32 @bzero(%struct.termios* %2, i32 24)
%21 = load i32, i32* @B115200
%22 = call i32 @cfsetspeed(%struct.termios* %2, i32 %21)
%23 = getelementptr inbounds %struct.termios, %struct.termios* %2, i64 0, i32 0
%24 = load i32, i32* @B115200
%25 = load i32, i32* @CS8
%26 = or i32 %25, %24
%27 = load i32, i32* @CLOCAL
%28 = load i32, i32* @CREAD
%29 = or i32 %27, %26
%30 = or i32 %29, %28
store i32 %30, i32* %23
%31 = load i32, i32* @ICANON
%32 = load i32, i32* @ECHO
%33 = or i32 %32, %31
%34 = load i32, i32* @ECHOE
%35 = or i32 %33, %34
%36 = load i32, i32* @ISIG
%37 = or i32 %35, %36
%38 = xor i32 %37, -1
%39 = getelementptr inbounds %struct.termios, %struct.termios* %2, i64 0, i32 1
%40 = load i32, i32* %39
%41 = and i32 %40, %38
store i32 %41, i32* %39
%42 = load i32, i32* @OPOST
%43 = xor i32 %42, -1
%44 = getelementptr inbounds %struct.termios, %struct.termios* %2, i64 0, i32 3
%45 = load i32, i32* %44
%46 = and i32 %45, %43
store i32 %46, i32* %44
%47 = getelementptr inbounds %struct.termios, %struct.termios* %2, i64 0, i32 2
%48 = load i32*, i32** %47
%49 = load i64, i64* @VMIN
%50 = getelementptr inbounds i32, i32* %48, i64 %49
store i32 1, i32* %50
%51 = load i64, i64* @VTIME
%52 = getelementptr inbounds i32, i32* %48, i64 %51
store i32 0, i32* %52
%53 = load i32, i32* @TCIOFLUSH
%54 = call i32 @tcflush(i32 %9, i32 %53)
%55 = load i32, i32* @TCSAFLUSH
%56 = call i64 @tcsetattr(i32 %9, i32 %55, %struct.termios* %2)
%57 = icmp eq i64 %56, 0
br i1 %57, label %58, label %64
58: ; preds = %19
%59 = load i32, i32* @F_SETFL
%60 = load i32, i32* @FNDELAY
%61 = call i64 @fcntl(i32 %9, i32 %59, i32 %60)
%62 = load i32, i32* @F_SETFL
%63 = call i64 @fcntl(i32 %9, i32 %62, i32 0)
br label %64
64: ; preds = %1, %58, %19, %15, %11
%65 = phi i32 [ -1, %11 ], [ -2, %15 ], [ -4, %19 ], [ %9, %58 ], [ %9, %1 ]
ret i32 %65
}