#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 */
typedef int uint32_t;

/* Variables and functions */
void copy_fwd_rest_words_unaligned(uint32_t *d, const uint32_t *s, int sl,
                                   int sr, size_t l) {
  while (l > 0) {
    *d++ = ((*(s)) >> sl) | ((*(s + 1)) << sr);
    s++;
    l--;
  }
}


x86 assembly (clang, -O0):
<copy_fwd_rest_words_unaligned>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
jbe    116e <copy_fwd_rest_words_unaligned+0x6e>
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    -0x14(%rbp),%ecx
sar    %cl,%eax
mov    %eax,-0x24(%rbp)
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%eax
mov    -0x18(%rbp),%ecx
shl    %cl,%eax
mov    -0x24(%rbp),%ecx
or     %eax,%ecx
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x4,%rdx
mov    %rdx,-0x8(%rbp)
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x10(%rbp)
mov    -0x20(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x20(%rbp)
jmp    1116 <copy_fwd_rest_words_unaligned+0x16>
pop    %rbp
ret

x86 assembly (clang, -O2):
<copy_fwd_rest_words_unaligned>:
push   %rbp
push   %r14
push   %rbx
test   %r8,%r8
je     12d7 <copy_fwd_rest_words_unaligned+0x1d7>
mov    %ecx,%r11d
mov    %edx,%r14d
cmp    $0x8,%r8
jb     112f <copy_fwd_rest_words_unaligned+0x2f>
lea    (%rsi,%r8,4),%rax
add    $0x4,%rax
cmp    %rdi,%rax
jbe    114b <copy_fwd_rest_words_unaligned+0x4b>
lea    (%rdi,%r8,4),%rax
cmp    %rsi,%rax
jbe    114b <copy_fwd_rest_words_unaligned+0x4b>
test   $0x1,%r8b
jne    1279 <copy_fwd_rest_words_unaligned+0x179>
mov    %r8,%rax
cmp    $0x1,%r8
jne    129e <copy_fwd_rest_words_unaligned+0x19e>
jmp    12d7 <copy_fwd_rest_words_unaligned+0x1d7>
mov    %r8,%r9
and    $0xfffffffffffffff8,%r9
movd   %r14d,%xmm1
movd   %r11d,%xmm0
lea    -0x8(%r9),%rax
mov    %rax,%r10
shr    $0x3,%r10
add    $0x1,%r10
test   %rax,%rax
je     12dc <copy_fwd_rest_words_unaligned+0x1dc>
mov    %r10,%rax
and    $0xfffffffffffffffe,%rax
xor    %ecx,%ecx
xorps  %xmm2,%xmm2
xorps  %xmm3,%xmm3
movss  %xmm1,%xmm3
movss  %xmm0,%xmm2
nopl   0x0(%rax,%rax,1)
movdqu (%rsi,%rcx,4),%xmm4
movdqu 0x4(%rsi,%rcx,4),%xmm5
movdqu 0x10(%rsi,%rcx,4),%xmm6
movdqu 0x14(%rsi,%rcx,4),%xmm7
psrad  %xmm3,%xmm4
psrad  %xmm3,%xmm6
pslld  %xmm2,%xmm5
por    %xmm4,%xmm5
pslld  %xmm2,%xmm7
por    %xmm6,%xmm7
movdqu %xmm5,(%rdi,%rcx,4)
movdqu %xmm7,0x10(%rdi,%rcx,4)
movdqu 0x20(%rsi,%rcx,4),%xmm4
movdqu 0x24(%rsi,%rcx,4),%xmm5
movdqu 0x30(%rsi,%rcx,4),%xmm6
movdqu 0x34(%rsi,%rcx,4),%xmm7
psrad  %xmm3,%xmm4
psrad  %xmm3,%xmm6
pslld  %xmm2,%xmm5
por    %xmm4,%xmm5
pslld  %xmm2,%xmm7
por    %xmm6,%xmm7
movdqu %xmm5,0x20(%rdi,%rcx,4)
movdqu %xmm7,0x30(%rdi,%rcx,4)
add    $0x10,%rcx
add    $0xfffffffffffffffe,%rax
jne    1190 <copy_fwd_rest_words_unaligned+0x90>
test   $0x1,%r10b
je     125e <copy_fwd_rest_words_unaligned+0x15e>
xorps  %xmm2,%xmm2
xorps  %xmm3,%xmm3
movss  %xmm1,%xmm3
movdqu (%rsi,%rcx,4),%xmm1
movdqu 0x4(%rsi,%rcx,4),%xmm4
movdqu 0x10(%rsi,%rcx,4),%xmm5
psrad  %xmm3,%xmm1
movdqu 0x14(%rsi,%rcx,4),%xmm6
psrad  %xmm3,%xmm5
movss  %xmm0,%xmm2
pslld  %xmm2,%xmm4
pslld  %xmm2,%xmm6
por    %xmm1,%xmm4
por    %xmm5,%xmm6
movdqu %xmm4,(%rdi,%rcx,4)
movdqu %xmm6,0x10(%rdi,%rcx,4)
cmp    %r8,%r9
je     12d7 <copy_fwd_rest_words_unaligned+0x1d7>
and    $0x7,%r8d
lea    (%rdi,%r9,4),%rdi
lea    (%rsi,%r9,4),%rsi
test   $0x1,%r8b
je     1139 <copy_fwd_rest_words_unaligned+0x39>
mov    (%rsi),%eax
mov    0x4(%rsi),%edx
mov    %r14d,%ecx
sar    %cl,%eax
add    $0x4,%rsi
mov    %r11d,%ecx
shl    %cl,%edx
or     %eax,%edx
mov    %edx,(%rdi)
add    $0x4,%rdi
lea    -0x1(%r8),%rax
cmp    $0x1,%r8
je     12d7 <copy_fwd_rest_words_unaligned+0x1d7>
xor    %edx,%edx
mov    (%rsi,%rdx,4),%ebx
mov    %r14d,%ecx
sar    %cl,%ebx
mov    0x4(%rsi,%rdx,4),%ebp
mov    %r11d,%ecx
shl    %cl,%ebp
or     %ebx,%ebp
mov    %ebp,(%rdi,%rdx,4)
mov    0x4(%rsi,%rdx,4),%ebp
mov    %r14d,%ecx
sar    %cl,%ebp
mov    0x8(%rsi,%rdx,4),%ebx
mov    %r11d,%ecx
shl    %cl,%ebx
or     %ebp,%ebx
mov    %ebx,0x4(%rdi,%rdx,4)
add    $0x2,%rdx
cmp    %rdx,%rax
jne    12a0 <copy_fwd_rest_words_unaligned+0x1a0>
pop    %rbx
pop    %r14
pop    %rbp
ret
xor    %ecx,%ecx
test   $0x1,%r10b
jne    1216 <copy_fwd_rest_words_unaligned+0x116>
jmp    125e <copy_fwd_rest_words_unaligned+0x15e>

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

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