#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*/ abort();
void foo(short *__restrict__ dst, short *__restrict__ src, int h, int stride,
         int dummy) {
  int i;
  h /= 16;
  for (i = 0; i < h; i++) {
    dst[0] = 3 * src[0] + 4 * src[1];
    dst[1] = 3 * src[1] + 4 * src[2];
    dst[2] = 3 * src[2] + 4 * src[3];
    dst[3] = 3 * src[3] + 4 * src[4];
    dst[4] = 3 * src[4] + 4 * src[5];
    dst[5] = 3 * src[5] + 4 * src[6];
    dst[6] = 3 * src[6] + 4 * src[7];
    dst[7] = 3 * src[7] + 4 * src[8];
    dst += stride;
    src += stride;
    if (dummy == 32)
      abort();
  }
}


x86 assembly (clang, -O0):
<foo>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    %r8d,-0x1c(%rbp)
mov    -0x14(%rbp),%eax
mov    $0x10,%ecx
cltd
idiv   %ecx
mov    %eax,-0x14(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    12af <foo+0x19f>
mov    -0x10(%rbp),%rax
movswl (%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0x2(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,(%rax)
mov    -0x10(%rbp),%rax
movswl 0x2(%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0x4(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,0x2(%rax)
mov    -0x10(%rbp),%rax
movswl 0x4(%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0x6(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,0x4(%rax)
mov    -0x10(%rbp),%rax
movswl 0x6(%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0x8(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,0x6(%rax)
mov    -0x10(%rbp),%rax
movswl 0x8(%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0xa(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,0x8(%rax)
mov    -0x10(%rbp),%rax
movswl 0xa(%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0xc(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,0xa(%rax)
mov    -0x10(%rbp),%rax
movswl 0xc(%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0xe(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,0xc(%rax)
mov    -0x10(%rbp),%rax
movswl 0xe(%rax),%eax
imul   $0x3,%eax,%eax
mov    -0x10(%rbp),%rcx
movswl 0x10(%rcx),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
mov    %ax,%cx
mov    -0x8(%rbp),%rax
mov    %cx,0xe(%rax)
mov    -0x18(%rbp),%ecx
mov    -0x8(%rbp),%rax
movslq %ecx,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x8(%rbp)
mov    -0x18(%rbp),%ecx
mov    -0x10(%rbp),%rax
movslq %ecx,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x10(%rbp)
cmpl   $0x20,-0x1c(%rbp)
jne    129c <foo+0x18c>
mov    $0x0,%al
call   1030 <abort@plt>
jmp    12a1 <foo+0x191>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    113f <foo+0x2f>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<foo>:
push   %rax
lea    0xf(%rdx),%eax
test   %edx,%edx
cmovns %edx,%eax
cmp    $0x10,%edx
jl     1182 <foo+0x72>
sar    $0x4,%eax
movslq %ecx,%rcx
add    %rcx,%rcx
xor    %edx,%edx
movdqa 0xecf(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movdqu 0x2(%rsi,%rdx,1),%xmm1
movdqa %xmm1,%xmm2
pinsrw $0x7,(%rsi,%rdx,1),%xmm2
pmullw %xmm0,%xmm2
movdqa %xmm2,%xmm3
psrldq $0xe,%xmm3
pslldq $0x2,%xmm2
por    %xmm3,%xmm2
psllw  $0x2,%xmm1
paddw  %xmm2,%xmm1
movdqu %xmm1,(%rdi,%rdx,1)
cmp    $0x20,%r8d
je     1184 <foo+0x74>
add    %rcx,%rdx
add    $0xffffffff,%eax
jne    1140 <foo+0x30>
pop    %rax
ret
xor    %eax,%eax
call   1030 <abort@plt>

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

LLVM IR (-O2):
define void @foo(i16* noalias nocapture writeonly %0, i16* noalias nocapture %1, i32 %2, i32 %3, i32 %4) {
%6 = sdiv i32 %2, 16
%7 = icmp sgt i32 %2, 15
br i1 %7, label %8, label %32
8: ; preds = %5
%9 = sext i32 %3 to i64
%10 = icmp eq i32 %4, 32
br label %11
11: ; preds = %8, %27
%12 = phi i32 [ 0, %8 ], [ %30, %27 ]
%13 = phi i16* [ %0, %8 ], [ %29, %27 ]
%14 = phi i16* [ %1, %8 ], [ %28, %27 ]
%15 = load i16, i16* %14
%16 = getelementptr inbounds i16, i16* %14, i64 1
%17 = bitcast i16* %16 to <8 x i16>*
%18 = load <8 x i16>, <8 x i16>* %17
%19 = insertelement <8 x i16> %18, i16 %15, i64 7
%20 = mul <8 x i16> %19, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
%21 = shufflevector <8 x i16> %20, <8 x i16> poison, <8 x i32> <i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6>
%22 = shl <8 x i16> %18, <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>
%23 = add <8 x i16> %22, %21
%24 = bitcast i16* %13 to <8 x i16>*
store <8 x i16> %23, <8 x i16>* %24
br i1 %10, label %25, label %27
25: ; preds = %11
%26 = tail call i32 (...) @abort()
unreachable
27: ; preds = %11
%28 = getelementptr inbounds i16, i16* %14, i64 %9
%29 = getelementptr inbounds i16, i16* %13, i64 %9
%30 = add nuw nsw i32 %12, 1
%31 = icmp eq i32 %30, %6
br i1 %31, label %32, label %11
32: ; preds = %27, %5
ret void
}