#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 rtattr {
  unsigned short rta_type;
};

/* Variables and functions */
struct rtattr *RTA_NEXT(struct rtattr *, int);
scalar_t__ RTA_OK(struct rtattr *, int);
int /*<<< orphan*/ memset(struct rtattr **, int /*<<< orphan*/, int);
int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) {
  memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
  while (RTA_OK(rta, len)) {
    unsigned short type = rta->rta_type;
    if ((type <= max) && (!tb[type]))
      tb[type] = rta;
    rta = RTA_NEXT(rta, len);
  }
  return 0;
}


x86 assembly (clang, -O0):
<parse_rtattr>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0xc(%rbp),%eax
add    $0x1,%eax
cltq
shl    $0x3,%rax
mov    %eax,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x18(%rbp),%rdi
mov    -0x1c(%rbp),%esi
call   1040 <RTA_OK@plt>
cmp    $0x0,%rax
je     11c5 <parse_rtattr+0x95>
mov    -0x18(%rbp),%rax
mov    (%rax),%ax
mov    %ax,-0x1e(%rbp)
movzwl -0x1e(%rbp),%eax
cmp    -0xc(%rbp),%eax
jg     11b0 <parse_rtattr+0x80>
mov    -0x8(%rbp),%rax
movzwl -0x1e(%rbp),%ecx
cmpq   $0x0,(%rax,%rcx,8)
jne    11b0 <parse_rtattr+0x80>
mov    -0x18(%rbp),%rdx
mov    -0x8(%rbp),%rax
movzwl -0x1e(%rbp),%ecx
mov    %rdx,(%rax,%rcx,8)
mov    -0x18(%rbp),%rdi
mov    -0x1c(%rbp),%esi
call   1030 <RTA_NEXT@plt>
mov    %rax,-0x18(%rbp)
jmp    115f <parse_rtattr+0x2f>
xor    %eax,%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<parse_rtattr>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %ecx,%ebp
mov    %rdx,%rbx
mov    %esi,%r14d
mov    %rdi,%r15
lea    0x8(,%r14,8),%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    %rbx,%rdi
jmp    1170 <parse_rtattr+0x40>
cs nopw 0x0(%rax,%rax,1)
mov    %rbx,%rdi
mov    %ebp,%esi
call   1030 <RTA_NEXT@plt>
mov    %rax,%rbx
mov    %rax,%rdi
mov    %ebp,%esi
call   1040 <RTA_OK@plt>
test   %rax,%rax
je     1191 <parse_rtattr+0x61>
movzwl (%rbx),%eax
cmp    %r14d,%eax
jg     1160 <parse_rtattr+0x30>
cmpq   $0x0,(%r15,%rax,8)
jne    1160 <parse_rtattr+0x30>
mov    %rbx,(%r15,%rax,8)
jmp    1160 <parse_rtattr+0x30>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.rtattr = type { i16 }
define i32 @parse_rtattr(%struct.rtattr** %0, i32 %1, %struct.rtattr* %2, i32 %3) {
%5 = alloca %struct.rtattr**
%6 = alloca i32
%7 = alloca %struct.rtattr*
%8 = alloca i32
%9 = alloca i16
store %struct.rtattr** %0, %struct.rtattr*** %5
store i32 %1, i32* %6
store %struct.rtattr* %2, %struct.rtattr** %7
store i32 %3, i32* %8
%10 = load %struct.rtattr**, %struct.rtattr*** %5
%11 = load i32, i32* %6
%12 = add nsw i32 %11, 1
%13 = sext i32 %12 to i64
%14 = mul i64 8, %13
%15 = trunc i64 %14 to i32
%16 = call i32 @memset(%struct.rtattr** %10, i32 0, i32 %15)
br label %17
17: ; preds = %43, %4
%18 = load %struct.rtattr*, %struct.rtattr** %7
%19 = load i32, i32* %8
%20 = call i64 @RTA_OK(%struct.rtattr* %18, i32 %19)
%21 = icmp ne i64 %20, 0
br i1 %21, label %22, label %47
22: ; preds = %17
%23 = load %struct.rtattr*, %struct.rtattr** %7
%24 = getelementptr inbounds %struct.rtattr, %struct.rtattr* %23, i32 0, i32 0
%25 = load i16, i16* %24
store i16 %25, i16* %9
%26 = load i16, i16* %9
%27 = zext i16 %26 to i32
%28 = load i32, i32* %6
%29 = icmp sle i32 %27, %28
br i1 %29, label %30, label %43
30: ; preds = %22
%31 = load %struct.rtattr**, %struct.rtattr*** %5
%32 = load i16, i16* %9
%33 = zext i16 %32 to i64
%34 = getelementptr inbounds %struct.rtattr*, %struct.rtattr** %31, i64 %33
%35 = load %struct.rtattr*, %struct.rtattr** %34
%36 = icmp ne %struct.rtattr* %35, null
br i1 %36, label %43, label %37
37: ; preds = %30
%38 = load %struct.rtattr*, %struct.rtattr** %7
%39 = load %struct.rtattr**, %struct.rtattr*** %5
%40 = load i16, i16* %9
%41 = zext i16 %40 to i64
%42 = getelementptr inbounds %struct.rtattr*, %struct.rtattr** %39, i64 %41
store %struct.rtattr* %38, %struct.rtattr** %42
br label %43
43: ; preds = %37, %30, %22
%44 = load %struct.rtattr*, %struct.rtattr** %7
%45 = load i32, i32* %8
%46 = call %struct.rtattr* @RTA_NEXT(%struct.rtattr* %44, i32 %45)
store %struct.rtattr* %46, %struct.rtattr** %7
br label %17
47: ; preds = %17
ret i32 0
}

LLVM IR (-O2):
%struct.rtattr = type { i16 }
define i32 @parse_rtattr(%struct.rtattr** %0, i32 %1, %struct.rtattr* %2, i32 %3) {
%5 = shl i32 %1, 3
%6 = add i32 %5, 8
%7 = tail call i32 @memset(%struct.rtattr** %0, i32 0, i32 %6)
%8 = tail call i64 @RTA_OK(%struct.rtattr* %2, i32 %3)
%9 = icmp eq i64 %8, 0
br i1 %9, label %26, label %10
10: ; preds = %4, %22
%11 = phi %struct.rtattr* [ %23, %22 ], [ %2, %4 ]
%12 = getelementptr inbounds %struct.rtattr, %struct.rtattr* %11, i64 0, i32 0
%13 = load i16, i16* %12
%14 = zext i16 %13 to i32
%15 = icmp sgt i32 %14, %1
br i1 %15, label %22, label %16
16: ; preds = %10
%17 = zext i16 %13 to i64
%18 = getelementptr inbounds %struct.rtattr*, %struct.rtattr** %0, i64 %17
%19 = load %struct.rtattr*, %struct.rtattr** %18
%20 = icmp eq %struct.rtattr* %19, null
br i1 %20, label %21, label %22
21: ; preds = %16
store %struct.rtattr* %11, %struct.rtattr** %18
br label %22
22: ; preds = %21, %16, %10
%23 = tail call %struct.rtattr* @RTA_NEXT(%struct.rtattr* %11, i32 %3)
%24 = tail call i64 @RTA_OK(%struct.rtattr* %23, i32 %3)
%25 = icmp eq i64 %24, 0
br i1 %25, label %26, label %10
26: ; preds = %22, %4
ret i32 0
}