#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 */

/* Variables and functions */
int /*<<< orphan*/ memcpy(unsigned char *, unsigned char const *, size_t);
void strrev(const unsigned char *in, unsigned char *out, size_t len) {
  size_t trail = 0;
  for (const unsigned char *endp = &in [len - 1]; *endp == 0 || *endp == '\n';
       endp--)
    trail++;
  size_t end = len - trail;
  for (size_t i = 0; i < end; i++) {
    out[end - i - 1] = in[i];
  }
  memcpy(&out[end], &in[end], trail);
}


x86 assembly (clang, -O0):
<strrev>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
movzbl (%rax),%ecx
mov    $0x1,%al
cmp    $0x0,%ecx
mov    %al,-0x39(%rbp)
je     1164 <strrev+0x54>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xa,%eax
sete   %al
mov    %al,-0x39(%rbp)
mov    -0x39(%rbp),%al
test   $0x1,%al
jne    1174 <strrev+0x64>
jmp    1191 <strrev+0x81>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x28(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x28(%rbp)
jmp    113f <strrev+0x2f>
mov    -0x18(%rbp),%rax
sub    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x30(%rbp),%rax
jae    11e2 <strrev+0xd2>
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    -0x38(%rbp),%rcx
sub    $0x1,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    11a5 <strrev+0x95>
mov    -0x10(%rbp),%rdi
add    -0x30(%rbp),%rdi
mov    -0x8(%rbp),%rsi
add    -0x30(%rbp),%rsi
mov    -0x20(%rbp),%rdx
call   1030 <memcpy@plt>
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strrev>:
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %rsi,%r12
lea    -0x1(%rdx),%r10
lea    (%rdi,%rdx,1),%rsi
xor    %ecx,%ecx
jmp    1134 <strrev+0x24>
cs nopw 0x0(%rax,%rax,1)
add    $0xffffffffffffffff,%rcx
movzbl -0x1(%rsi,%rcx,1),%eax
test   %al,%al
je     1130 <strrev+0x20>
cmp    $0xa,%al
je     1130 <strrev+0x20>
lea    (%r12,%rdx,1),%r9
mov    %rcx,%r8
neg    %r8
mov    %rdx,%r11
add    %rcx,%r11
je     1194 <strrev+0x84>
cmp    $0x8,%r11
jb     116b <strrev+0x5b>
lea    (%rsi,%rcx,1),%rax
cmp    %r12,%rax
jbe    11ac <strrev+0x9c>
lea    (%r9,%rcx,1),%rax
cmp    %rdi,%rax
jbe    11ac <strrev+0x9c>
xor    %r14d,%r14d
neg    %rdx
mov    %rcx,%rax
sub    %r14,%rax
add    %r14,%rdi
add    %r10,%r12
nopl   (%rax)
movzbl (%rdi),%ebx
mov    %bl,(%r12,%rax,1)
add    $0xffffffffffffffff,%rax
add    $0x1,%rdi
cmp    %rax,%rdx
jne    1180 <strrev+0x70>
add    %rcx,%r9
add    %rcx,%rsi
mov    %r9,%rdi
mov    %r8,%rdx
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
jmp    1030 <memcpy@plt>
cmp    $0x20,%r11
jae    11ba <strrev+0xaa>
xor    %r14d,%r14d
jmp    1270 <strrev+0x160>
lea    (%rcx,%r9,1),%rbx
add    $0xfffffffffffffff0,%rbx
mov    %r11,%r14
and    $0xffffffffffffffe0,%r14
mov    %r11,%r15
and    $0xffffffffffffffe0,%r15
xor    %eax,%eax
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
movdqu (%rdi,%rax,1),%xmm1
movdqu 0x10(%rdi,%rax,1),%xmm2
movdqa %xmm1,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm3,%xmm1
movdqu %xmm1,(%rbx)
movdqa %xmm2,%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
punpckhbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm1,%xmm2
movdqu %xmm2,-0x10(%rbx)
add    $0x20,%rax
add    $0xffffffffffffffe0,%rbx
cmp    %rax,%r15
jne    11e0 <strrev+0xd0>
cmp    %r14,%r11
je     1194 <strrev+0x84>
test   $0x18,%r11b
je     116e <strrev+0x5e>
mov    %r14,%rax
mov    %r11,%r14
and    $0xfffffffffffffff8,%r14
mov    %r9,%rbx
sub    %rax,%rbx
add    %rcx,%rbx
add    $0xfffffffffffffff8,%rbx
mov    %r11,%r15
and    $0xfffffffffffffff8,%r15
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movq   (%rdi,%rax,1),%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm1,%xmm1
movq   %xmm1,(%rbx)
add    $0x8,%rax
add    $0xfffffffffffffff8,%rbx
cmp    %rax,%r15
jne    12a0 <strrev+0x190>
cmp    %r14,%r11
je     1194 <strrev+0x84>
jmp    116e <strrev+0x5e>

LLVM IR (-O0):
define void @strrev(i8* %0, i8* %1, i64 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i64
%8 = alloca i8*
%9 = alloca i64
%10 = alloca i64
store i8* %0, i8** %4
store i8* %1, i8** %5
store i64 %2, i64* %6
store i64 0, i64* %7
%11 = load i8*, i8** %4
%12 = load i64, i64* %6
%13 = sub i64 %12, 1
%14 = getelementptr inbounds i8, i8* %11, i64 %13
store i8* %14, i8** %8
br label %15
15: ; preds = %30, %3
%16 = load i8*, i8** %8
%17 = load i8, i8* %16
%18 = zext i8 %17 to i32
%19 = icmp eq i32 %18, 0
br i1 %19, label %25, label %20
20: ; preds = %15
%21 = load i8*, i8** %8
%22 = load i8, i8* %21
%23 = zext i8 %22 to i32
%24 = icmp eq i32 %23, 10
br label %25
25: ; preds = %20, %15
%26 = phi i1 [ true, %15 ], [ %24, %20 ]
br i1 %26, label %27, label %33
27: ; preds = %25
%28 = load i64, i64* %7
%29 = add i64 %28, 1
store i64 %29, i64* %7
br label %30
30: ; preds = %27
%31 = load i8*, i8** %8
%32 = getelementptr inbounds i8, i8* %31, i32 -1
store i8* %32, i8** %8
br label %15
33: ; preds = %25
%34 = load i64, i64* %6
%35 = load i64, i64* %7
%36 = sub i64 %34, %35
store i64 %36, i64* %9
store i64 0, i64* %10
br label %37
37: ; preds = %52, %33
%38 = load i64, i64* %10
%39 = load i64, i64* %9
%40 = icmp ult i64 %38, %39
br i1 %40, label %41, label %55
41: ; preds = %37
%42 = load i8*, i8** %4
%43 = load i64, i64* %10
%44 = getelementptr inbounds i8, i8* %42, i64 %43
%45 = load i8, i8* %44
%46 = load i8*, i8** %5
%47 = load i64, i64* %9
%48 = load i64, i64* %10
%49 = sub i64 %47, %48
%50 = sub i64 %49, 1
%51 = getelementptr inbounds i8, i8* %46, i64 %50
store i8 %45, i8* %51
br label %52
52: ; preds = %41
%53 = load i64, i64* %10
%54 = add i64 %53, 1
store i64 %54, i64* %10
br label %37
55: ; preds = %37
%56 = load i8*, i8** %5
%57 = load i64, i64* %9
%58 = getelementptr inbounds i8, i8* %56, i64 %57
%59 = load i8*, i8** %4
%60 = load i64, i64* %9
%61 = getelementptr inbounds i8, i8* %59, i64 %60
%62 = load i64, i64* %7
%63 = call i32 @memcpy(i8* %58, i8* %61, i64 %62)
ret void
}

LLVM IR (-O2):
define void @strrev(i8* %0, i8* %1, i64 %2) {
%4 = add i64 %2, -1
%5 = getelementptr inbounds i8, i8* %0, i64 %4
br label %6
6: ; preds = %70, %3
%7 = phi i8* [ %5, %3 ], [ %72, %70 ]
%8 = phi i64 [ 0, %3 ], [ %71, %70 ]
%9 = load i8, i8* %7
switch i8 %9, label %10 [
i8 0, label %70
i8 10, label %70
]
10: ; preds = %6
%11 = sub i64 %2, %8
%12 = icmp eq i64 %11, 0
br i1 %12, label %73, label %13
13: ; preds = %10
%14 = icmp ult i64 %11, 8
br i1 %14, label %68, label %15
15: ; preds = %13
%16 = getelementptr i8, i8* %1, i64 %11
%17 = getelementptr i8, i8* %0, i64 %11
%18 = icmp ugt i8* %17, %1
%19 = icmp ugt i8* %16, %0
%20 = and i1 %18, %19
br i1 %20, label %68, label %21
21: ; preds = %15
%22 = icmp ult i64 %11, 32
br i1 %22, label %50, label %23
23: ; preds = %21
%24 = and i64 %11, -32
br label %25
25: ; preds = %25, %23
%26 = phi i64 [ 0, %23 ], [ %43, %25 ]
%27 = getelementptr inbounds i8, i8* %0, i64 %26
%28 = bitcast i8* %27 to <16 x i8>*
%29 = load <16 x i8>, <16 x i8>* %28
%30 = getelementptr inbounds i8, i8* %27, i64 16
%31 = bitcast i8* %30 to <16 x i8>*
%32 = load <16 x i8>, <16 x i8>* %31
%33 = xor i64 %26, -1
%34 = add i64 %11, %33
%35 = getelementptr inbounds i8, i8* %1, i64 %34
%36 = shufflevector <16 x i8> %29, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%37 = getelementptr inbounds i8, i8* %35, i64 -15
%38 = bitcast i8* %37 to <16 x i8>*
store <16 x i8> %36, <16 x i8>* %38
%39 = shufflevector <16 x i8> %32, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%40 = getelementptr inbounds i8, i8* %35, i64 -16
%41 = getelementptr inbounds i8, i8* %40, i64 -15
%42 = bitcast i8* %41 to <16 x i8>*
store <16 x i8> %39, <16 x i8>* %42
%43 = add nuw i64 %26, 32
%44 = icmp eq i64 %43, %24
br i1 %44, label %45, label %25
45: ; preds = %25
%46 = icmp eq i64 %11, %24
br i1 %46, label %73, label %47
47: ; preds = %45
%48 = and i64 %11, 24
%49 = icmp eq i64 %48, 0
br i1 %49, label %68, label %50
50: ; preds = %21, %47
%51 = phi i64 [ %24, %47 ], [ 0, %21 ]
%52 = and i64 %11, -8
%53 = getelementptr inbounds i8, i8* %1, i64 -7
br label %54
54: ; preds = %54, %50
%55 = phi i64 [ %51, %50 ], [ %64, %54 ]
%56 = getelementptr inbounds i8, i8* %0, i64 %55
%57 = bitcast i8* %56 to <8 x i8>*
%58 = load <8 x i8>, <8 x i8>* %57
%59 = xor i64 %55, -1
%60 = add i64 %11, %59
%61 = shufflevector <8 x i8> %58, <8 x i8> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%62 = getelementptr inbounds i8, i8* %53, i64 %60
%63 = bitcast i8* %62 to <8 x i8>*
store <8 x i8> %61, <8 x i8>* %63
%64 = add nuw i64 %55, 8
%65 = icmp eq i64 %64, %52
br i1 %65, label %66, label %54
66: ; preds = %54
%67 = icmp eq i64 %11, %52
br i1 %67, label %73, label %68
68: ; preds = %15, %13, %47, %66
%69 = phi i64 [ 0, %13 ], [ 0, %15 ], [ %24, %47 ], [ %52, %66 ]
br label %77
70: ; preds = %6, %6
%71 = add i64 %8, 1
%72 = getelementptr inbounds i8, i8* %7, i64 -1
br label %6
73: ; preds = %77, %45, %66, %10
%74 = getelementptr inbounds i8, i8* %1, i64 %11
%75 = getelementptr inbounds i8, i8* %0, i64 %11
%76 = tail call i32 @memcpy(i8* %74, i8* %75, i64 %8)
ret void
77: ; preds = %68, %77
%78 = phi i64 [ %84, %77 ], [ %69, %68 ]
%79 = getelementptr inbounds i8, i8* %0, i64 %78
%80 = load i8, i8* %79
%81 = xor i64 %78, -1
%82 = add i64 %11, %81
%83 = getelementptr inbounds i8, i8* %1, i64 %82
store i8 %80, i8* %83
%84 = add nuw i64 %78, 1
%85 = icmp eq i64 %84, %11
br i1 %85, label %73, label %77
}