void fir(const short array1[], const short coeff[], short output[]) {
  int i, j, sum;
  for (i = 0; i < 100 - 50; i++) {
    sum = 0;
    for (j = 0; j < 50; j++) {
      sum += array1[i + j] * coeff[j];
    }
    output[i] = sum >> 15;
  }
}


x86 assembly (clang, -O0):
<fir>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x32,-0x1c(%rbp)
jge    1190 <fir+0x90>
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x20(%rbp)
cmpl   $0x32,-0x20(%rbp)
jge    116d <fir+0x6d>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    -0x20(%rbp),%ecx
movslq %ecx,%rcx
movswl (%rax,%rcx,2),%eax
mov    -0x10(%rbp),%rcx
movslq -0x20(%rbp),%rdx
movswl (%rcx,%rdx,2),%ecx
imul   %ecx,%eax
add    -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    112f <fir+0x2f>
mov    -0x24(%rbp),%eax
sar    $0xf,%eax
mov    %ax,%dx
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1117 <fir+0x17>
pop    %rbp
ret

x86 assembly (clang, -O2):
<fir>:
xor    %r10d,%r10d
pxor   %xmm0,%xmm0
nopw   0x0(%rax,%rax,1)
movq   0x58(%rsi),%xmm1
punpcklwd %xmm1,%xmm1
movq   0x58(%rdi,%r10,2),%xmm2
punpcklwd %xmm0,%xmm2
pmaddwd %xmm1,%xmm2
movq   0x50(%rsi),%xmm1
punpcklwd %xmm1,%xmm1
movq   0x50(%rdi,%r10,2),%xmm3
punpcklwd %xmm0,%xmm3
pmaddwd %xmm1,%xmm3
movq   0x48(%rsi),%xmm1
punpcklwd %xmm1,%xmm1
movq   0x48(%rdi,%r10,2),%xmm4
punpcklwd %xmm0,%xmm4
pmaddwd %xmm1,%xmm4
movq   0x40(%rsi),%xmm5
punpcklwd %xmm5,%xmm5
movq   0x40(%rdi,%r10,2),%xmm1
punpcklwd %xmm0,%xmm1
pmaddwd %xmm5,%xmm1
paddd  %xmm4,%xmm1
paddd  %xmm3,%xmm1
paddd  %xmm2,%xmm1
movq   0x38(%rsi),%xmm2
punpcklwd %xmm2,%xmm2
movq   0x38(%rdi,%r10,2),%xmm3
punpcklwd %xmm0,%xmm3
pmaddwd %xmm2,%xmm3
movq   0x30(%rsi),%xmm2
punpcklwd %xmm2,%xmm2
movq   0x30(%rdi,%r10,2),%xmm4
punpcklwd %xmm0,%xmm4
pmaddwd %xmm2,%xmm4
movq   0x28(%rsi),%xmm5
punpcklwd %xmm5,%xmm5
movq   0x28(%rdi,%r10,2),%xmm2
punpcklwd %xmm0,%xmm2
pmaddwd %xmm5,%xmm2
paddd  %xmm4,%xmm2
paddd  %xmm3,%xmm2
movq   0x20(%rsi),%xmm3
punpcklwd %xmm3,%xmm3
movq   0x20(%rdi,%r10,2),%xmm4
punpcklwd %xmm0,%xmm4
pmaddwd %xmm3,%xmm4
movq   0x18(%rsi),%xmm3
punpcklwd %xmm3,%xmm3
movq   0x18(%rdi,%r10,2),%xmm5
punpcklwd %xmm0,%xmm5
pmaddwd %xmm3,%xmm5
paddd  %xmm4,%xmm5
movq   0x10(%rsi),%xmm3
punpcklwd %xmm3,%xmm3
movq   0x10(%rdi,%r10,2),%xmm4
punpcklwd %xmm0,%xmm4
pmaddwd %xmm3,%xmm4
movq   0x8(%rsi),%xmm3
movq   0x8(%rdi,%r10,2),%xmm6
movq   (%rsi),%xmm7
punpcklwd %xmm7,%xmm3
movq   (%rdi,%r10,2),%xmm7
punpcklwd %xmm7,%xmm6
pmaddwd %xmm3,%xmm6
paddd  %xmm4,%xmm6
paddd  %xmm5,%xmm6
paddd  %xmm2,%xmm6
paddd  %xmm1,%xmm6
pshufd $0xee,%xmm6,%xmm1
paddd  %xmm6,%xmm1
pshufd $0x55,%xmm1,%xmm2
paddd  %xmm1,%xmm2
movd   %xmm2,%r8d
movswl 0x60(%rdi,%r10,2),%r9d
movswl 0x60(%rsi),%ecx
imul   %r9d,%ecx
add    %r8d,%ecx
movswl 0x62(%rdi,%r10,2),%r8d
movswl 0x62(%rsi),%eax
imul   %r8d,%eax
add    %ecx,%eax
shr    $0xf,%eax
mov    %ax,(%rdx,%r10,2)
add    $0x1,%r10
cmp    $0x32,%r10
jne    1110 <fir+0x10>
ret

LLVM IR (-O0):
define void @fir(i16* %0, i16* %1, i16* %2) {
%4 = alloca i16*
%5 = alloca i16*
%6 = alloca i16*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i16* %0, i16** %4
store i16* %1, i16** %5
store i16* %2, i16** %6
store i32 0, i32* %7
br label %10
10: ; preds = %46, %3
%11 = load i32, i32* %7
%12 = icmp slt i32 %11, 50
br i1 %12, label %13, label %49
13: ; preds = %10
store i32 0, i32* %9
store i32 0, i32* %8
br label %14
14: ; preds = %35, %13
%15 = load i32, i32* %8
%16 = icmp slt i32 %15, 50
br i1 %16, label %17, label %38
17: ; preds = %14
%18 = load i16*, i16** %4
%19 = load i32, i32* %7
%20 = load i32, i32* %8
%21 = add nsw i32 %19, %20
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds i16, i16* %18, i64 %22
%24 = load i16, i16* %23
%25 = sext i16 %24 to i32
%26 = load i16*, i16** %5
%27 = load i32, i32* %8
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds i16, i16* %26, i64 %28
%30 = load i16, i16* %29
%31 = sext i16 %30 to i32
%32 = mul nsw i32 %25, %31
%33 = load i32, i32* %9
%34 = add nsw i32 %33, %32
store i32 %34, i32* %9
br label %35
35: ; preds = %17
%36 = load i32, i32* %8
%37 = add nsw i32 %36, 1
store i32 %37, i32* %8
br label %14
38: ; preds = %14
%39 = load i32, i32* %9
%40 = ashr i32 %39, 15
%41 = trunc i32 %40 to i16
%42 = load i16*, i16** %6
%43 = load i32, i32* %7
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds i16, i16* %42, i64 %44
store i16 %41, i16* %45
br label %46
46: ; preds = %38
%47 = load i32, i32* %7
%48 = add nsw i32 %47, 1
store i32 %48, i32* %7
br label %10
49: ; preds = %10
ret void
}

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