#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 */
void memcpybwd(char *to, char *from, size_t n) {
  to += n;
  from += n;
  while (n-- > 0)
    *--to = *--from;
}


x86 assembly (clang, -O0):
<memcpybwd>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x18(%rbp),%rax
add    -0x8(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x18(%rbp),%rax
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x18(%rbp)
cmp    $0x0,%rax
jbe    116a <memcpybwd+0x6a>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x10(%rbp)
mov    -0x1(%rax),%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0xffffffffffffffff,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,-0x1(%rax)
jmp    1128 <memcpybwd+0x28>
pop    %rbp
ret

x86 assembly (clang, -O2):
<memcpybwd>:
push   %r14
push   %rbx
test   %rdx,%rdx
je     11d1 <memcpybwd+0xd1>
lea    (%rsi,%rdx,1),%r9
lea    (%rdi,%rdx,1),%r8
cmp    $0x4,%rdx
jb     112c <memcpybwd+0x2c>
cmp    %rdi,%r9
jbe    11d5 <memcpybwd+0xd5>
cmp    %rsi,%r8
jbe    11d5 <memcpybwd+0xd5>
mov    %rdx,%rsi
mov    %r9,%rdi
mov    %r8,%rcx
lea    -0x1(%rsi),%rax
mov    %rsi,%rdx
and    $0x7,%rdx
je     1169 <memcpybwd+0x69>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
add    $0xffffffffffffffff,%rsi
movzbl -0x1(%rdi),%ebx
add    $0xffffffffffffffff,%rdi
mov    %bl,-0x1(%rcx)
add    $0xffffffffffffffff,%rcx
add    $0xffffffffffffffff,%rdx
jne    1150 <memcpybwd+0x50>
cmp    $0x7,%rax
jb     11d1 <memcpybwd+0xd1>
neg    %rsi
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl -0x1(%rdi,%rax,1),%edx
mov    %dl,-0x1(%rcx,%rax,1)
movzbl -0x2(%rdi,%rax,1),%edx
mov    %dl,-0x2(%rcx,%rax,1)
movzbl -0x3(%rdi,%rax,1),%edx
mov    %dl,-0x3(%rcx,%rax,1)
movzbl -0x4(%rdi,%rax,1),%edx
mov    %dl,-0x4(%rcx,%rax,1)
movzbl -0x5(%rdi,%rax,1),%edx
mov    %dl,-0x5(%rcx,%rax,1)
movzbl -0x6(%rdi,%rax,1),%edx
mov    %dl,-0x6(%rcx,%rax,1)
movzbl -0x7(%rdi,%rax,1),%edx
mov    %dl,-0x7(%rcx,%rax,1)
movzbl -0x8(%rdi,%rax,1),%edx
mov    %dl,-0x8(%rcx,%rax,1)
add    $0xfffffffffffffff8,%rax
cmp    %rax,%rsi
jne    1180 <memcpybwd+0x80>
pop    %rbx
pop    %r14
ret
cmp    $0x10,%rdx
jae    11e2 <memcpybwd+0xe2>
xor    %eax,%eax
jmp    12a2 <memcpybwd+0x1a2>
mov    %rdx,%rax
and    $0xfffffffffffffff0,%rax
lea    -0x10(%rax),%rcx
mov    %rcx,%r11
shr    $0x4,%r11
add    $0x1,%r11
mov    %r11d,%r10d
and    $0x3,%r10d
cmp    $0x30,%rcx
jae    1209 <memcpybwd+0x109>
xor    %ecx,%ecx
jmp    1257 <memcpybwd+0x157>
and    $0xfffffffffffffffc,%r11
lea    -0x10(%r9),%r14
lea    -0x10(%r8),%rbx
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
movups (%r14,%rcx,1),%xmm0
movups %xmm0,(%rbx,%rcx,1)
movups -0x10(%r14,%rcx,1),%xmm0
movups %xmm0,-0x10(%rbx,%rcx,1)
movups -0x20(%r14,%rcx,1),%xmm0
movups %xmm0,-0x20(%rbx,%rcx,1)
movups -0x30(%r14,%rcx,1),%xmm0
movups %xmm0,-0x30(%rbx,%rcx,1)
add    $0xffffffffffffffc0,%rcx
add    $0xfffffffffffffffc,%r11
jne    1220 <memcpybwd+0x120>
neg    %rcx
test   %r10,%r10
je     1294 <memcpybwd+0x194>
mov    %rdx,%rbx
sub    %rcx,%rbx
lea    (%rdi,%rbx,1),%rcx
add    $0xfffffffffffffff0,%rcx
add    %rbx,%rsi
add    $0xfffffffffffffff0,%rsi
shl    $0x4,%r10
xor    %edi,%edi
nopw   0x0(%rax,%rax,1)
movups (%rsi,%rdi,1),%xmm0
movups %xmm0,(%rcx,%rdi,1)
add    $0xfffffffffffffff0,%rdi
mov    %r10,%rbx
add    %rdi,%rbx
jne    1280 <memcpybwd+0x180>
cmp    %rdx,%rax
je     11d1 <memcpybwd+0xd1>
test   $0xc,%dl
je     12f1 <memcpybwd+0x1f1>
mov    %rdx,%r10
and    $0xfffffffffffffffc,%r10
mov    %edx,%esi
and    $0x3,%esi
mov    %r10,%r11
neg    %r11
mov    %r9,%rdi
sub    %r10,%rdi
mov    %r8,%rcx
sub    %r10,%rcx
neg    %rax
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    -0x4(%r9,%rax,1),%ebx
mov    %ebx,-0x4(%r8,%rax,1)
add    $0xfffffffffffffffc,%rax
cmp    %rax,%r11
jne    12d0 <memcpybwd+0x1d0>
cmp    %rdx,%r10
jne    1135 <memcpybwd+0x35>
jmp    11d1 <memcpybwd+0xd1>
sub    %rax,%r8
sub    %rax,%r9
and    $0xf,%edx
jmp    112c <memcpybwd+0x2c>

LLVM IR (-O0):
define void @memcpybwd(i8* %0, i8* %1, i64 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
store i8* %0, i8** %4
store i8* %1, i8** %5
store i64 %2, i64* %6
%7 = load i64, i64* %6
%8 = load i8*, i8** %4
%9 = getelementptr inbounds i8, i8* %8, i64 %7
store i8* %9, i8** %4
%10 = load i64, i64* %6
%11 = load i8*, i8** %5
%12 = getelementptr inbounds i8, i8* %11, i64 %10
store i8* %12, i8** %5
br label %13
13: ; preds = %17, %3
%14 = load i64, i64* %6
%15 = add i64 %14, -1
store i64 %15, i64* %6
%16 = icmp ugt i64 %14, 0
br i1 %16, label %17, label %23
17: ; preds = %13
%18 = load i8*, i8** %5
%19 = getelementptr inbounds i8, i8* %18, i32 -1
store i8* %19, i8** %5
%20 = load i8, i8* %19
%21 = load i8*, i8** %4
%22 = getelementptr inbounds i8, i8* %21, i32 -1
store i8* %22, i8** %4
store i8 %20, i8* %22
br label %13
23: ; preds = %13
ret void
}

LLVM IR (-O2):
define void @memcpybwd(i8* nocapture writeonly %0, i8* nocapture %1, i64 %2) {
%4 = icmp eq i64 %2, 0
br i1 %4, label %183, label %5
5: ; preds = %3
%6 = getelementptr i8, i8* %1, i64 %2
%7 = getelementptr i8, i8* %0, i64 %2
%8 = icmp ult i64 %2, 4
br i1 %8, label %130, label %9
9: ; preds = %5
%10 = icmp ugt i8* %6, %0
%11 = icmp ugt i8* %7, %1
%12 = and i1 %10, %11
br i1 %12, label %130, label %13
13: ; preds = %9
%14 = icmp ult i64 %2, 16
br i1 %14, label %105, label %15
15: ; preds = %13
%16 = and i64 %2, -16
%17 = add i64 %16, -16
%18 = lshr exact i64 %17, 4
%19 = add nuw nsw i64 %18, 1
%20 = and i64 %19, 3
%21 = icmp ult i64 %17, 48
br i1 %21, label %74, label %22
22: ; preds = %15
%23 = and i64 %19, 2305843009213693948
%24 = getelementptr i8, i8* %6, i64 -1
%25 = getelementptr i8, i8* %7, i64 -1
%26 = getelementptr inbounds i8, i8* %24, i64 -15
%27 = getelementptr inbounds i8, i8* %25, i64 -15
%28 = getelementptr i8, i8* %6, i64 -1
%29 = getelementptr i8, i8* %7, i64 -1
%30 = getelementptr inbounds i8, i8* %28, i64 -15
%31 = getelementptr inbounds i8, i8* %29, i64 -15
%32 = getelementptr i8, i8* %6, i64 -1
%33 = getelementptr i8, i8* %7, i64 -1
%34 = getelementptr inbounds i8, i8* %32, i64 -15
%35 = getelementptr inbounds i8, i8* %33, i64 -15
%36 = getelementptr i8, i8* %6, i64 -1
%37 = getelementptr i8, i8* %7, i64 -1
%38 = getelementptr inbounds i8, i8* %36, i64 -15
%39 = getelementptr inbounds i8, i8* %37, i64 -15
br label %40
40: ; preds = %40, %22
%41 = phi i64 [ 0, %22 ], [ %71, %40 ]
%42 = phi i64 [ 0, %22 ], [ %72, %40 ]
%43 = sub i64 0, %41
%44 = sub i64 0, %41
%45 = getelementptr inbounds i8, i8* %26, i64 %43
%46 = bitcast i8* %45 to <16 x i8>*
%47 = load <16 x i8>, <16 x i8>* %46
%48 = getelementptr inbounds i8, i8* %27, i64 %44
%49 = bitcast i8* %48 to <16 x i8>*
store <16 x i8> %47, <16 x i8>* %49
%50 = sub nuw nsw i64 -16, %41
%51 = sub nuw nsw i64 -16, %41
%52 = getelementptr inbounds i8, i8* %30, i64 %50
%53 = bitcast i8* %52 to <16 x i8>*
%54 = load <16 x i8>, <16 x i8>* %53
%55 = getelementptr inbounds i8, i8* %31, i64 %51
%56 = bitcast i8* %55 to <16 x i8>*
store <16 x i8> %54, <16 x i8>* %56
%57 = sub nuw nsw i64 -32, %41
%58 = sub nuw nsw i64 -32, %41
%59 = getelementptr inbounds i8, i8* %34, i64 %57
%60 = bitcast i8* %59 to <16 x i8>*
%61 = load <16 x i8>, <16 x i8>* %60
%62 = getelementptr inbounds i8, i8* %35, i64 %58
%63 = bitcast i8* %62 to <16 x i8>*
store <16 x i8> %61, <16 x i8>* %63
%64 = sub nuw nsw i64 -48, %41
%65 = sub nuw nsw i64 -48, %41
%66 = getelementptr inbounds i8, i8* %38, i64 %64
%67 = bitcast i8* %66 to <16 x i8>*
%68 = load <16 x i8>, <16 x i8>* %67
%69 = getelementptr inbounds i8, i8* %39, i64 %65
%70 = bitcast i8* %69 to <16 x i8>*
store <16 x i8> %68, <16 x i8>* %70
%71 = add nuw i64 %41, 64
%72 = add i64 %42, 4
%73 = icmp eq i64 %72, %23
br i1 %73, label %74, label %40
74: ; preds = %40, %15
%75 = phi i64 [ 0, %15 ], [ %71, %40 ]
%76 = icmp eq i64 %20, 0
br i1 %76, label %95, label %77
77: ; preds = %74
%78 = getelementptr i8, i8* %6, i64 -1
%79 = getelementptr i8, i8* %7, i64 -1
%80 = getelementptr inbounds i8, i8* %78, i64 -15
%81 = getelementptr inbounds i8, i8* %79, i64 -15
br label %82
82: ; preds = %82, %77
%83 = phi i64 [ %75, %77 ], [ %92, %82 ]
%84 = phi i64 [ 0, %77 ], [ %93, %82 ]
%85 = sub i64 0, %83
%86 = sub i64 0, %83
%87 = getelementptr inbounds i8, i8* %80, i64 %85
%88 = bitcast i8* %87 to <16 x i8>*
%89 = load <16 x i8>, <16 x i8>* %88
%90 = getelementptr inbounds i8, i8* %81, i64 %86
%91 = bitcast i8* %90 to <16 x i8>*
store <16 x i8> %89, <16 x i8>* %91
%92 = add nuw i64 %83, 16
%93 = add i64 %84, 1
%94 = icmp eq i64 %93, %20
br i1 %94, label %95, label %82
95: ; preds = %82, %74
%96 = icmp eq i64 %16, %2
br i1 %96, label %183, label %97
97: ; preds = %95
%98 = sub i64 0, %16
%99 = getelementptr i8, i8* %7, i64 %98
%100 = sub i64 0, %16
%101 = getelementptr i8, i8* %6, i64 %100
%102 = and i64 %2, 15
%103 = and i64 %2, 12
%104 = icmp eq i64 %103, 0
br i1 %104, label %130, label %105
105: ; preds = %13, %97
%106 = phi i64 [ %16, %97 ], [ 0, %13 ]
%107 = and i64 %2, -4
%108 = and i64 %2, 3
%109 = sub i64 0, %107
%110 = getelementptr i8, i8* %6, i64 %109
%111 = sub i64 0, %107
%112 = getelementptr i8, i8* %7, i64 %111
%113 = getelementptr i8, i8* %6, i64 -1
%114 = getelementptr i8, i8* %7, i64 -1
%115 = getelementptr inbounds i8, i8* %113, i64 -3
%116 = getelementptr inbounds i8, i8* %114, i64 -3
br label %117
117: ; preds = %117, %105
%118 = phi i64 [ %106, %105 ], [ %126, %117 ]
%119 = sub i64 0, %118
%120 = sub i64 0, %118
%121 = getelementptr inbounds i8, i8* %115, i64 %119
%122 = bitcast i8* %121 to <4 x i8>*
%123 = load <4 x i8>, <4 x i8>* %122
%124 = getelementptr inbounds i8, i8* %116, i64 %120
%125 = bitcast i8* %124 to <4 x i8>*
store <4 x i8> %123, <4 x i8>* %125
%126 = add nuw i64 %118, 4
%127 = icmp eq i64 %126, %107
br i1 %127, label %128, label %117
128: ; preds = %117
%129 = icmp eq i64 %107, %2
br i1 %129, label %183, label %130
130: ; preds = %9, %5, %97, %128
%131 = phi i64 [ %2, %5 ], [ %2, %9 ], [ %102, %97 ], [ %108, %128 ]
%132 = phi i8* [ %6, %5 ], [ %6, %9 ], [ %101, %97 ], [ %110, %128 ]
%133 = phi i8* [ %7, %5 ], [ %7, %9 ], [ %99, %97 ], [ %112, %128 ]
%134 = add i64 %131, -1
%135 = and i64 %131, 7
%136 = icmp eq i64 %135, 0
br i1 %136, label %148, label %137
137: ; preds = %130, %137
%138 = phi i64 [ %142, %137 ], [ %131, %130 ]
%139 = phi i8* [ %143, %137 ], [ %132, %130 ]
%140 = phi i8* [ %145, %137 ], [ %133, %130 ]
%141 = phi i64 [ %146, %137 ], [ 0, %130 ]
%142 = add i64 %138, -1
%143 = getelementptr inbounds i8, i8* %139, i64 -1
%144 = load i8, i8* %143
%145 = getelementptr inbounds i8, i8* %140, i64 -1
store i8 %144, i8* %145
%146 = add i64 %141, 1
%147 = icmp eq i64 %146, %135
br i1 %147, label %148, label %137
148: ; preds = %137, %130
%149 = phi i64 [ %131, %130 ], [ %142, %137 ]
%150 = phi i8* [ %132, %130 ], [ %143, %137 ]
%151 = phi i8* [ %133, %130 ], [ %145, %137 ]
%152 = icmp ult i64 %134, 7
br i1 %152, label %183, label %153
153: ; preds = %148, %153
%154 = phi i64 [ %178, %153 ], [ %149, %148 ]
%155 = phi i8* [ %179, %153 ], [ %150, %148 ]
%156 = phi i8* [ %181, %153 ], [ %151, %148 ]
%157 = getelementptr inbounds i8, i8* %155, i64 -1
%158 = load i8, i8* %157
%159 = getelementptr inbounds i8, i8* %156, i64 -1
store i8 %158, i8* %159
%160 = getelementptr inbounds i8, i8* %155, i64 -2
%161 = load i8, i8* %160
%162 = getelementptr inbounds i8, i8* %156, i64 -2
store i8 %161, i8* %162
%163 = getelementptr inbounds i8, i8* %155, i64 -3
%164 = load i8, i8* %163
%165 = getelementptr inbounds i8, i8* %156, i64 -3
store i8 %164, i8* %165
%166 = getelementptr inbounds i8, i8* %155, i64 -4
%167 = load i8, i8* %166
%168 = getelementptr inbounds i8, i8* %156, i64 -4
store i8 %167, i8* %168
%169 = getelementptr inbounds i8, i8* %155, i64 -5
%170 = load i8, i8* %169
%171 = getelementptr inbounds i8, i8* %156, i64 -5
store i8 %170, i8* %171
%172 = getelementptr inbounds i8, i8* %155, i64 -6
%173 = load i8, i8* %172
%174 = getelementptr inbounds i8, i8* %156, i64 -6
store i8 %173, i8* %174
%175 = getelementptr inbounds i8, i8* %155, i64 -7
%176 = load i8, i8* %175
%177 = getelementptr inbounds i8, i8* %156, i64 -7
store i8 %176, i8* %177
%178 = add i64 %154, -8
%179 = getelementptr inbounds i8, i8* %155, i64 -8
%180 = load i8, i8* %179
%181 = getelementptr inbounds i8, i8* %156, i64 -8
store i8 %180, i8* %181
%182 = icmp eq i64 %178, 0
br i1 %182, label %183, label %153
183: ; preds = %148, %153, %95, %128, %3
ret void
}