#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 ip6_rthdr0 {
  int ip6r0_len;
  int ip6r0_segleft;
  struct in6_addr *ip6r0_addr;
};
struct ip6_rthdr {
  int ip6r_type;
};
struct in6_addr {
  int dummy;
};

/* Variables and functions */
#define IPV6_RTHDR_TYPE_0 128
int /*<<< orphan*/ memmove(struct ip6_rthdr0 *, struct ip6_rthdr0 *, int);
int inet6_rth_reverse(const void *in, void *out) {
  struct ip6_rthdr *in_rthdr = (struct ip6_rthdr *)in;
  switch (in_rthdr->ip6r_type) {
    struct ip6_rthdr0 *in_rthdr0;
    struct ip6_rthdr0 *out_rthdr0;
  case IPV6_RTHDR_TYPE_0:
    in_rthdr0 = (struct ip6_rthdr0 *)in;
    out_rthdr0 = (struct ip6_rthdr0 *)out;
    memmove(out_rthdr0, in_rthdr0, sizeof(struct ip6_rthdr0));
    int total = in_rthdr0->ip6r0_len * 8 / sizeof(struct in6_addr);
    for (int i = 0; i < total / 2; ++i) {
      struct in6_addr temp = in_rthdr0->ip6r0_addr[i];
      out_rthdr0->ip6r0_addr[i] = in_rthdr0->ip6r0_addr[total - 1 - i];
      out_rthdr0->ip6r0_addr[total - 1 - i] = temp;
    }
    if (total % 2 != 0 && in != out)
      out_rthdr0->ip6r0_addr[total / 2] = in_rthdr0->ip6r0_addr[total / 2];
    out_rthdr0->ip6r0_segleft = total;
    return 0;
  }
  return -1;
}


x86 assembly (clang, -O0):
<inet6_rth_reverse>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
sub    $0x80,%eax
jne    1273 <inet6_rth_reverse+0x163>
jmp    113e <inet6_rth_reverse+0x2e>
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rdi
mov    -0x28(%rbp),%rsi
mov    $0x10,%edx
call   1030 <memmove@plt>
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
shl    $0x3,%eax
cltq
shr    $0x2,%rax
mov    %eax,-0x34(%rbp)
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    %eax,-0x44(%rbp)
mov    -0x34(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x44(%rbp),%eax
cmp    %ecx,%eax
jge    11f7 <inet6_rth_reverse+0xe7>
mov    -0x28(%rbp),%rax
mov    0x8(%rax),%rax
movslq -0x38(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x40(%rbp)
mov    -0x30(%rbp),%rax
mov    0x8(%rax),%rax
movslq -0x38(%rbp),%rcx
mov    -0x28(%rbp),%rdx
mov    0x8(%rdx),%rdx
mov    -0x34(%rbp),%esi
sub    $0x1,%esi
sub    -0x38(%rbp),%esi
movslq %esi,%rsi
mov    (%rdx,%rsi,4),%edx
mov    %edx,(%rax,%rcx,4)
mov    -0x30(%rbp),%rax
mov    0x8(%rax),%rax
mov    -0x34(%rbp),%ecx
sub    $0x1,%ecx
sub    -0x38(%rbp),%ecx
movslq %ecx,%rcx
mov    -0x40(%rbp),%edx
mov    %edx,(%rax,%rcx,4)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    1179 <inet6_rth_reverse+0x69>
mov    -0x34(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
je     125d <inet6_rth_reverse+0x14d>
mov    -0x10(%rbp),%rax
cmp    -0x18(%rbp),%rax
je     125d <inet6_rth_reverse+0x14d>
mov    -0x30(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x50(%rbp)
mov    -0x34(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
movslq %eax,%rcx
mov    -0x28(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x58(%rbp)
mov    -0x34(%rbp),%eax
mov    $0x2,%esi
cltd
idiv   %esi
mov    -0x58(%rbp),%rdx
mov    %eax,%esi
mov    -0x50(%rbp),%rax
movslq %esi,%rsi
mov    (%rdx,%rsi,4),%edx
mov    %edx,(%rax,%rcx,4)
mov    -0x34(%rbp),%ecx
mov    -0x30(%rbp),%rax
mov    %ecx,0x4(%rax)
movl   $0x0,-0x4(%rbp)
jmp    127a <inet6_rth_reverse+0x16a>
movl   $0xffffffff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<inet6_rth_reverse>:
push   %r15
push   %r14
push   %rbx
mov    $0xffffffff,%eax
cmpl   $0x80,(%rdi)
jne    11c9 <inet6_rth_reverse+0xb9>
mov    %rsi,%r14
mov    %rdi,%r15
mov    %rsi,%rdi
mov    %r15,%rsi
mov    $0x10,%edx
call   1030 <memmove@plt>
mov    (%r15),%r9d
lea    (%r9,%r9,1),%r8d
test   %r9d,%r9d
jle    11c3 <inet6_rth_reverse+0xb3>
cmp    $0x1,%r9d
jne    1152 <inet6_rth_reverse+0x42>
xor    %edx,%edx
jmp    119f <inet6_rth_reverse+0x8f>
mov    %r9d,%r10d
and    $0xfffffffe,%r10d
lea    -0x2(%r8),%edi
xor    %edx,%edx
nop
mov    0x8(%r15),%rax
mov    (%rax,%rdx,4),%ecx
mov    0x8(%r14),%rsi
lea    0x1(%rdi),%ebx
movslq %ebx,%rbx
mov    (%rax,%rbx,4),%eax
mov    %eax,(%rsi,%rdx,4)
mov    %ecx,(%rsi,%rbx,4)
mov    0x8(%r15),%rax
mov    0x4(%rax,%rdx,4),%ecx
mov    0x8(%r14),%rsi
movslq %edi,%rdi
mov    (%rax,%rdi,4),%eax
mov    %eax,0x4(%rsi,%rdx,4)
mov    %ecx,(%rsi,%rdi,4)
add    $0x2,%rdx
add    $0xfffffffe,%edi
cmp    %rdx,%r10
jne    1160 <inet6_rth_reverse+0x50>
test   $0x1,%r9b
je     11c3 <inet6_rth_reverse+0xb3>
mov    0x8(%r15),%rax
mov    (%rax,%rdx,4),%ecx
mov    0x8(%r14),%rsi
mov    %edx,%edi
not    %edi
add    %r8d,%edi
movslq %edi,%rdi
mov    (%rax,%rdi,4),%eax
mov    %eax,(%rsi,%rdx,4)
mov    %ecx,(%rsi,%rdi,4)
mov    %r8d,0x4(%r14)
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %r15
ret

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

LLVM IR (-O2):
%struct.ip6_rthdr0 = type { i32, i32, %struct.in6_addr* }
%struct.in6_addr = type { i32 }
define i32 @inet6_rth_reverse(i8* %0, i8* %1) {
%3 = bitcast i8* %0 to i32*
%4 = load i32, i32* %3
%5 = icmp eq i32 %4, 128
br i1 %5, label %6, label %73
6: ; preds = %2
%7 = bitcast i8* %0 to %struct.ip6_rthdr0*
%8 = bitcast i8* %1 to %struct.ip6_rthdr0*
%9 = tail call i32 @memmove(%struct.ip6_rthdr0* %8, %struct.ip6_rthdr0* %7, i32 16)
%10 = load i32, i32* %3
%11 = shl nsw i32 %10, 1
%12 = icmp sgt i32 %10, 0
br i1 %12, label %13, label %70
13: ; preds = %6
%14 = getelementptr inbounds i8, i8* %0, i64 8
%15 = bitcast i8* %14 to %struct.in6_addr**
%16 = getelementptr inbounds i8, i8* %1, i64 8
%17 = bitcast i8* %16 to %struct.in6_addr**
%18 = zext i32 %10 to i64
%19 = and i64 %18, 1
%20 = icmp eq i32 %10, 1
br i1 %20, label %54, label %21
21: ; preds = %13
%22 = and i64 %18, 4294967294
br label %23
23: ; preds = %23, %21
%24 = phi i64 [ 0, %21 ], [ %51, %23 ]
%25 = phi i64 [ 0, %21 ], [ %52, %23 ]
%26 = load %struct.in6_addr*, %struct.in6_addr** %15
%27 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %26, i64 %24, i32 0
%28 = load i32, i32* %27
%29 = load %struct.in6_addr*, %struct.in6_addr** %17
%30 = trunc i64 %24 to i32
%31 = xor i32 %30, -1
%32 = add i32 %11, %31
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %26, i64 %33, i32 0
%35 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %29, i64 %24, i32 0
%36 = load i32, i32* %34
store i32 %36, i32* %35
%37 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %29, i64 %33, i32 0
store i32 %28, i32* %37
%38 = or i64 %24, 1
%39 = load %struct.in6_addr*, %struct.in6_addr** %15
%40 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %39, i64 %38, i32 0
%41 = load i32, i32* %40
%42 = load %struct.in6_addr*, %struct.in6_addr** %17
%43 = trunc i64 %38 to i32
%44 = xor i32 %43, -1
%45 = add i32 %11, %44
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %39, i64 %46, i32 0
%48 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %42, i64 %38, i32 0
%49 = load i32, i32* %47
store i32 %49, i32* %48
%50 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %42, i64 %46, i32 0
store i32 %41, i32* %50
%51 = add nuw nsw i64 %24, 2
%52 = add i64 %25, 2
%53 = icmp eq i64 %52, %22
br i1 %53, label %54, label %23
54: ; preds = %23, %13
%55 = phi i64 [ 0, %13 ], [ %51, %23 ]
%56 = icmp eq i64 %19, 0
br i1 %56, label %70, label %57
57: ; preds = %54
%58 = load %struct.in6_addr*, %struct.in6_addr** %15
%59 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %58, i64 %55, i32 0
%60 = load i32, i32* %59
%61 = load %struct.in6_addr*, %struct.in6_addr** %17
%62 = trunc i64 %55 to i32
%63 = xor i32 %62, -1
%64 = add i32 %11, %63
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %58, i64 %65, i32 0
%67 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %61, i64 %55, i32 0
%68 = load i32, i32* %66
store i32 %68, i32* %67
%69 = getelementptr inbounds %struct.in6_addr, %struct.in6_addr* %61, i64 %65, i32 0
store i32 %60, i32* %69
br label %70
70: ; preds = %57, %54, %6
%71 = getelementptr inbounds i8, i8* %1, i64 4
%72 = bitcast i8* %71 to i32*
store i32 %11, i32* %72
br label %73
73: ; preds = %2, %70
%74 = phi i32 [ 0, %70 ], [ -1, %2 ]
ret i32 %74
}