void _memcpy4x(void *d, void *s, unsigned long c) {
  unsigned long *dd = d, *ss = s;
  for (; c > 0; --c)
    *dd++ = *ss++;
}


x86 assembly (clang, -O0):
<_memcpy4x>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x18(%rbp)
jbe    1160 <_memcpy4x+0x60>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
mov    (%rax),%rcx
mov    -0x20(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x20(%rbp)
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
jmp    1120 <_memcpy4x+0x20>
pop    %rbp
ret

x86 assembly (clang, -O2):
<_memcpy4x>:
test   %rdx,%rdx
je     12a7 <_memcpy4x+0x1a7>
cmp    $0x4,%rdx
jb     1211 <_memcpy4x+0x111>
lea    (%rsi,%rdx,8),%rax
cmp    %rdi,%rax
jbe    1129 <_memcpy4x+0x29>
lea    (%rdi,%rdx,8),%rax
cmp    %rsi,%rax
ja     1211 <_memcpy4x+0x111>
mov    %rdx,%r8
and    $0xfffffffffffffffc,%r8
lea    -0x4(%r8),%rax
mov    %rax,%rcx
shr    $0x2,%rcx
add    $0x1,%rcx
mov    %ecx,%r9d
and    $0x3,%r9d
cmp    $0xc,%rax
jae    1150 <_memcpy4x+0x50>
xor    %eax,%eax
jmp    11b8 <_memcpy4x+0xb8>
and    $0xfffffffffffffffc,%rcx
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
movups (%rsi,%rax,8),%xmm0
movups 0x10(%rsi,%rax,8),%xmm1
movups %xmm0,(%rdi,%rax,8)
movups %xmm1,0x10(%rdi,%rax,8)
movups 0x20(%rsi,%rax,8),%xmm0
movups 0x30(%rsi,%rax,8),%xmm1
movups %xmm0,0x20(%rdi,%rax,8)
movups %xmm1,0x30(%rdi,%rax,8)
movups 0x40(%rsi,%rax,8),%xmm0
movups 0x50(%rsi,%rax,8),%xmm1
movups %xmm0,0x40(%rdi,%rax,8)
movups %xmm1,0x50(%rdi,%rax,8)
movups 0x60(%rsi,%rax,8),%xmm0
movups 0x70(%rsi,%rax,8),%xmm1
movups %xmm0,0x60(%rdi,%rax,8)
movups %xmm1,0x70(%rdi,%rax,8)
add    $0x10,%rax
add    $0xfffffffffffffffc,%rcx
jne    1160 <_memcpy4x+0x60>
test   %r9,%r9
je     11fd <_memcpy4x+0xfd>
lea    (%rdi,%rax,8),%r10
add    $0x10,%r10
lea    (%rsi,%rax,8),%rax
add    $0x10,%rax
shl    $0x5,%r9
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movups -0x10(%rax,%rcx,1),%xmm0
movups (%rax,%rcx,1),%xmm1
movups %xmm0,-0x10(%r10,%rcx,1)
movups %xmm1,(%r10,%rcx,1)
add    $0x20,%rcx
cmp    %rcx,%r9
jne    11e0 <_memcpy4x+0xe0>
cmp    %rdx,%r8
je     12a7 <_memcpy4x+0x1a7>
and    $0x3,%edx
lea    (%rsi,%r8,8),%rsi
lea    (%rdi,%r8,8),%rdi
lea    -0x1(%rdx),%r8
mov    %rdx,%r9
and    $0x7,%r9
je     123a <_memcpy4x+0x13a>
xor    %eax,%eax
mov    (%rsi),%rcx
add    $0x8,%rsi
mov    %rcx,(%rdi)
add    $0x8,%rdi
add    $0x1,%rax
cmp    %rax,%r9
jne    1220 <_memcpy4x+0x120>
sub    %rax,%rdx
cmp    $0x7,%r8
jb     12a7 <_memcpy4x+0x1a7>
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    (%rsi,%rax,8),%rcx
mov    %rcx,(%rdi,%rax,8)
mov    0x8(%rsi,%rax,8),%rcx
mov    %rcx,0x8(%rdi,%rax,8)
mov    0x10(%rsi,%rax,8),%rcx
mov    %rcx,0x10(%rdi,%rax,8)
mov    0x18(%rsi,%rax,8),%rcx
mov    %rcx,0x18(%rdi,%rax,8)
mov    0x20(%rsi,%rax,8),%rcx
mov    %rcx,0x20(%rdi,%rax,8)
mov    0x28(%rsi,%rax,8),%rcx
mov    %rcx,0x28(%rdi,%rax,8)
mov    0x30(%rsi,%rax,8),%rcx
mov    %rcx,0x30(%rdi,%rax,8)
mov    0x38(%rsi,%rax,8),%rcx
mov    %rcx,0x38(%rdi,%rax,8)
add    $0x8,%rax
cmp    %rax,%rdx
jne    1250 <_memcpy4x+0x150>
ret

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

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