__attribute__((no)) int main1(short *in, int off, short scale, int n) {
  int i;
  int sum = 0;
  for (i = 0; i < n; i++) {
    sum += ((int)in[i] * (int)in[i + off]) >> scale;
  }
  return sum;
}


x86 assembly (clang, -O0):
<main1>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %ax,-0xe(%rbp)
mov    %ecx,-0x14(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1169 <main1+0x69>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
movswl (%rax,%rcx,2),%eax
mov    -0x8(%rbp),%rcx
mov    -0x18(%rbp),%edx
add    -0xc(%rbp),%edx
movslq %edx,%rdx
movswl (%rcx,%rdx,2),%ecx
imul   %ecx,%eax
movswl -0xe(%rbp),%ecx
sar    %cl,%eax
add    -0x1c(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1123 <main1+0x23>
mov    -0x1c(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<main1>:
test   %ecx,%ecx
jle    111d <main1+0x1d>
mov    %ecx,%eax
movzwl %dx,%ecx
movslq %esi,%r9
mov    %eax,%r8d
cmp    $0x8,%eax
jae    1120 <main1+0x20>
xor    %esi,%esi
xor    %eax,%eax
jmp    11b7 <main1+0xb7>
xor    %eax,%eax
ret
mov    %r8d,%esi
and    $0xfffffff8,%esi
movd   %ecx,%xmm1
lea    0x8(%rdi),%rax
pxor   %xmm0,%xmm0
xorps  %xmm2,%xmm2
movss  %xmm1,%xmm2
mov    %rsi,%rdx
pxor   %xmm3,%xmm3
pxor   %xmm1,%xmm1
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movq   -0x8(%rax),%xmm4
punpcklwd %xmm4,%xmm4
movq   (%rax),%xmm5
punpcklwd %xmm5,%xmm5
movq   -0x8(%rax,%r9,2),%xmm6
movq   (%rax,%r9,2),%xmm7
punpcklwd %xmm0,%xmm6
pmaddwd %xmm4,%xmm6
punpcklwd %xmm0,%xmm7
pmaddwd %xmm5,%xmm7
psrad  %xmm2,%xmm6
psrad  %xmm2,%xmm7
paddd  %xmm6,%xmm3
paddd  %xmm7,%xmm1
add    $0x10,%rax
add    $0xfffffffffffffff8,%rdx
jne    1150 <main1+0x50>
paddd  %xmm3,%xmm1
pshufd $0xee,%xmm1,%xmm0
paddd  %xmm1,%xmm0
pshufd $0x55,%xmm0,%xmm1
paddd  %xmm0,%xmm1
movd   %xmm1,%eax
cmp    %r8,%rsi
je     11db <main1+0xdb>
lea    (%rdi,%r9,2),%r9
nopl   0x0(%rax,%rax,1)
movswl (%rdi,%rsi,2),%r10d
movswl (%r9,%rsi,2),%edx
imul   %r10d,%edx
sar    %cl,%edx
add    %edx,%eax
add    $0x1,%rsi
cmp    %rsi,%r8
jne    11c0 <main1+0xc0>
ret

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

LLVM IR (-O2):
define i32 @main1(i16* nocapture %0, i32 %1, i16 signext %2, i32 %3) {
%5 = icmp sgt i32 %3, 0
br i1 %5, label %6, label %68
6: ; preds = %4
%7 = zext i16 %2 to i32
%8 = sext i32 %1 to i64
%9 = zext i32 %3 to i64
%10 = icmp ult i32 %3, 8
br i1 %10, label %50, label %11
11: ; preds = %6
%12 = and i64 %9, 4294967288
%13 = insertelement <4 x i32> poison, i32 %7, i64 0
%14 = shufflevector <4 x i32> %13, <4 x i32> poison, <4 x i32> zeroinitializer
%15 = insertelement <4 x i32> poison, i32 %7, i64 0
%16 = shufflevector <4 x i32> %15, <4 x i32> poison, <4 x i32> zeroinitializer
br label %17
17: ; preds = %17, %11
%18 = phi i64 [ 0, %11 ], [ %44, %17 ]
%19 = phi <4 x i32> [ zeroinitializer, %11 ], [ %42, %17 ]
%20 = phi <4 x i32> [ zeroinitializer, %11 ], [ %43, %17 ]
%21 = getelementptr inbounds i16, i16* %0, i64 %18
%22 = bitcast i16* %21 to <4 x i16>*
%23 = load <4 x i16>, <4 x i16>* %22
%24 = getelementptr inbounds i16, i16* %21, i64 4
%25 = bitcast i16* %24 to <4 x i16>*
%26 = load <4 x i16>, <4 x i16>* %25
%27 = sext <4 x i16> %23 to <4 x i32>
%28 = sext <4 x i16> %26 to <4 x i32>
%29 = add nsw i64 %18, %8
%30 = getelementptr inbounds i16, i16* %0, i64 %29
%31 = bitcast i16* %30 to <4 x i16>*
%32 = load <4 x i16>, <4 x i16>* %31
%33 = getelementptr inbounds i16, i16* %30, i64 4
%34 = bitcast i16* %33 to <4 x i16>*
%35 = load <4 x i16>, <4 x i16>* %34
%36 = sext <4 x i16> %32 to <4 x i32>
%37 = sext <4 x i16> %35 to <4 x i32>
%38 = mul nsw <4 x i32> %36, %27
%39 = mul nsw <4 x i32> %37, %28
%40 = ashr <4 x i32> %38, %14
%41 = ashr <4 x i32> %39, %16
%42 = add <4 x i32> %40, %19
%43 = add <4 x i32> %41, %20
%44 = add nuw i64 %18, 8
%45 = icmp eq i64 %44, %12
br i1 %45, label %46, label %17
46: ; preds = %17
%47 = add <4 x i32> %43, %42
%48 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %47)
%49 = icmp eq i64 %12, %9
br i1 %49, label %68, label %50
50: ; preds = %6, %46
%51 = phi i64 [ 0, %6 ], [ %12, %46 ]
%52 = phi i32 [ 0, %6 ], [ %48, %46 ]
br label %53
53: ; preds = %50, %53
%54 = phi i64 [ %66, %53 ], [ %51, %50 ]
%55 = phi i32 [ %65, %53 ], [ %52, %50 ]
%56 = getelementptr inbounds i16, i16* %0, i64 %54
%57 = load i16, i16* %56
%58 = sext i16 %57 to i32
%59 = add nsw i64 %54, %8
%60 = getelementptr inbounds i16, i16* %0, i64 %59
%61 = load i16, i16* %60
%62 = sext i16 %61 to i32
%63 = mul nsw i32 %62, %58
%64 = ashr i32 %63, %7
%65 = add nsw i32 %64, %55
%66 = add nuw nsw i64 %54, 1
%67 = icmp eq i64 %66, %9
br i1 %67, label %68, label %53
68: ; preds = %53, %46, %4
%69 = phi i32 [ 0, %4 ], [ %48, %46 ], [ %65, %53 ]
ret i32 %69
}