void yar_remap(double *restrict dst_array, double missval, long dst_size,
               long num_links, double *restrict map_wts, long num_wts,
               const int *restrict dst_add, const int *restrict src_add,
               const double *restrict src_array) {
  long n;
  for (n = 0; n < dst_size; ++n)
    dst_array[n] = missval;
  for (n = 0; n < num_links; ++n)
    dst_array[dst_add[n]] = 0;
  for (n = 0; n < num_links; ++n) {
    dst_array[dst_add[n]] += src_array[src_add[n]] * map_wts[n];
  }
}


x86 assembly (clang, -O0):
<yar_remap>:
push   %rbp
mov    %rsp,%rbp
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    1162 <yar_remap+0x62>
movsd  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    1131 <yar_remap+0x31>
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x20(%rbp),%rax
jge    11a1 <yar_remap+0xa1>
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    -0x40(%rbp),%rdx
movslq (%rcx,%rdx,4),%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    116a <yar_remap+0x6a>
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x20(%rbp),%rax
jge    120c <yar_remap+0x10c>
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rcx
mov    -0x40(%rbp),%rdx
movslq (%rcx,%rdx,4),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    -0x40(%rbp),%rdx
movslq (%rcx,%rdx,4),%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    11a9 <yar_remap+0xa9>
pop    %rbp
ret

x86 assembly (clang, -O2):
<yar_remap>:
test   %rsi,%rsi
jle    121f <yar_remap+0x11f>
cmp    $0x4,%rsi
jae    1117 <yar_remap+0x17>
xor    %r11d,%r11d
jmp    1210 <yar_remap+0x110>
mov    %rsi,%r11
and    $0xfffffffffffffffc,%r11
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
lea    -0x4(%r11),%rax
mov    %rax,%r10
shr    $0x2,%r10
add    $0x1,%r10
mov    %r10d,%r8d
and    $0x7,%r8d
cmp    $0x1c,%rax
jae    1149 <yar_remap+0x49>
xor    %eax,%eax
jmp    11d5 <yar_remap+0xd5>
and    $0xfffffffffffffff8,%r10
xor    %eax,%eax
nop
movupd %xmm1,(%rdi,%rax,8)
movupd %xmm1,0x10(%rdi,%rax,8)
movupd %xmm1,0x20(%rdi,%rax,8)
movupd %xmm1,0x30(%rdi,%rax,8)
movupd %xmm1,0x40(%rdi,%rax,8)
movupd %xmm1,0x50(%rdi,%rax,8)
movupd %xmm1,0x60(%rdi,%rax,8)
movupd %xmm1,0x70(%rdi,%rax,8)
movupd %xmm1,0x80(%rdi,%rax,8)
movupd %xmm1,0x90(%rdi,%rax,8)
movupd %xmm1,0xa0(%rdi,%rax,8)
movupd %xmm1,0xb0(%rdi,%rax,8)
movupd %xmm1,0xc0(%rdi,%rax,8)
movupd %xmm1,0xd0(%rdi,%rax,8)
movupd %xmm1,0xe0(%rdi,%rax,8)
movupd %xmm1,0xf0(%rdi,%rax,8)
add    $0x20,%rax
add    $0xfffffffffffffff8,%r10
jne    1150 <yar_remap+0x50>
test   %r8,%r8
je     1206 <yar_remap+0x106>
lea    (%rdi,%rax,8),%r10
add    $0x10,%r10
shl    $0x5,%r8
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
movupd %xmm1,-0x10(%r10,%rax,1)
movupd %xmm1,(%r10,%rax,1)
add    $0x20,%rax
cmp    %rax,%r8
jne    11f0 <yar_remap+0xf0>
cmp    %rsi,%r11
je     121f <yar_remap+0x11f>
nopl   0x0(%rax,%rax,1)
movsd  %xmm0,(%rdi,%r11,8)
add    $0x1,%r11
cmp    %r11,%rsi
jne    1210 <yar_remap+0x110>
test   %rdx,%rdx
jle    1348 <yar_remap+0x248>
lea    -0x1(%rdx),%r8
mov    %edx,%r10d
and    $0x3,%r10d
cmp    $0x3,%r8
jae    123d <yar_remap+0x13d>
xor    %eax,%eax
jmp    128c <yar_remap+0x18c>
mov    %rdx,%r11
and    $0xfffffffffffffffc,%r11
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
movslq (%r9,%rax,4),%rsi
movq   $0x0,(%rdi,%rsi,8)
movslq 0x4(%r9,%rax,4),%rsi
movq   $0x0,(%rdi,%rsi,8)
movslq 0x8(%r9,%rax,4),%rsi
movq   $0x0,(%rdi,%rsi,8)
movslq 0xc(%r9,%rax,4),%rsi
movq   $0x0,(%rdi,%rsi,8)
add    $0x4,%rax
cmp    %rax,%r11
jne    1250 <yar_remap+0x150>
test   %r10,%r10
je     12b5 <yar_remap+0x1b5>
lea    (%r9,%rax,4),%r11
xor    %esi,%esi
nopw   0x0(%rax,%rax,1)
movslq (%r11,%rsi,4),%rax
movq   $0x0,(%rdi,%rax,8)
add    $0x1,%rsi
cmp    %rsi,%r10
jne    12a0 <yar_remap+0x1a0>
test   %rdx,%rdx
jle    1348 <yar_remap+0x248>
mov    0x10(%rsp),%r10
mov    0x8(%rsp),%r11
test   %r8,%r8
je     1349 <yar_remap+0x249>
mov    %rdx,%r8
and    $0xfffffffffffffffe,%r8
xor    %esi,%esi
nopw   0x0(%rax,%rax,1)
movslq (%r11,%rsi,4),%rax
movsd  (%r10,%rax,8),%xmm0
movslq (%r9,%rsi,4),%rax
mulsd  (%rcx,%rsi,8),%xmm0
addsd  (%rdi,%rax,8),%xmm0
movsd  %xmm0,(%rdi,%rax,8)
movslq 0x4(%r11,%rsi,4),%rax
movsd  (%r10,%rax,8),%xmm0
movslq 0x4(%r9,%rsi,4),%rax
mulsd  0x8(%rcx,%rsi,8),%xmm0
addsd  (%rdi,%rax,8),%xmm0
movsd  %xmm0,(%rdi,%rax,8)
add    $0x2,%rsi
cmp    %rsi,%r8
jne    12e0 <yar_remap+0x1e0>
test   $0x1,%dl
je     1348 <yar_remap+0x248>
movslq (%r11,%rsi,4),%rax
movsd  (%r10,%rax,8),%xmm0
mulsd  (%rcx,%rsi,8),%xmm0
movslq (%r9,%rsi,4),%rax
addsd  (%rdi,%rax,8),%xmm0
movsd  %xmm0,(%rdi,%rax,8)
ret
xor    %esi,%esi
test   $0x1,%dl
jne    132b <yar_remap+0x22b>
jmp    1348 <yar_remap+0x248>

LLVM IR (-O0):
define void @yar_remap(double* noalias %0, double %1, i64 %2, i64 %3, double* noalias %4, i64 %5, i32* noalias %6, i32* noalias %7, double* noalias %8) {
%10 = alloca double*
%11 = alloca double
%12 = alloca i64
%13 = alloca i64
%14 = alloca double*
%15 = alloca i64
%16 = alloca i32*
%17 = alloca i32*
%18 = alloca double*
%19 = alloca i64
store double* %0, double** %10
store double %1, double* %11
store i64 %2, i64* %12
store i64 %3, i64* %13
store double* %4, double** %14
store i64 %5, i64* %15
store i32* %6, i32** %16
store i32* %7, i32** %17
store double* %8, double** %18
store i64 0, i64* %19
br label %20
20: ; preds = %29, %9
%21 = load i64, i64* %19
%22 = load i64, i64* %12
%23 = icmp slt i64 %21, %22
br i1 %23, label %24, label %32
24: ; preds = %20
%25 = load double, double* %11
%26 = load double*, double** %10
%27 = load i64, i64* %19
%28 = getelementptr inbounds double, double* %26, i64 %27
store double %25, double* %28
br label %29
29: ; preds = %24
%30 = load i64, i64* %19
%31 = add nsw i64 %30, 1
store i64 %31, i64* %19
br label %20
32: ; preds = %20
store i64 0, i64* %19
br label %33
33: ; preds = %45, %32
%34 = load i64, i64* %19
%35 = load i64, i64* %13
%36 = icmp slt i64 %34, %35
br i1 %36, label %37, label %48
37: ; preds = %33
%38 = load double*, double** %10
%39 = load i32*, i32** %16
%40 = load i64, i64* %19
%41 = getelementptr inbounds i32, i32* %39, i64 %40
%42 = load i32, i32* %41
%43 = sext i32 %42 to i64
%44 = getelementptr inbounds double, double* %38, i64 %43
store double 0.000000e+00, double* %44
br label %45
45: ; preds = %37
%46 = load i64, i64* %19
%47 = add nsw i64 %46, 1
store i64 %47, i64* %19
br label %33
48: ; preds = %33
store i64 0, i64* %19
br label %49
49: ; preds = %75, %48
%50 = load i64, i64* %19
%51 = load i64, i64* %13
%52 = icmp slt i64 %50, %51
br i1 %52, label %53, label %78
53: ; preds = %49
%54 = load double*, double** %18
%55 = load i32*, i32** %17
%56 = load i64, i64* %19
%57 = getelementptr inbounds i32, i32* %55, i64 %56
%58 = load i32, i32* %57
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds double, double* %54, i64 %59
%61 = load double, double* %60
%62 = load double*, double** %14
%63 = load i64, i64* %19
%64 = getelementptr inbounds double, double* %62, i64 %63
%65 = load double, double* %64
%66 = load double*, double** %10
%67 = load i32*, i32** %16
%68 = load i64, i64* %19
%69 = getelementptr inbounds i32, i32* %67, i64 %68
%70 = load i32, i32* %69
%71 = sext i32 %70 to i64
%72 = getelementptr inbounds double, double* %66, i64 %71
%73 = load double, double* %72
%74 = call double @llvm.fmuladd.f64(double %61, double %65, double %73)
store double %74, double* %72
br label %75
75: ; preds = %53
%76 = load i64, i64* %19
%77 = add nsw i64 %76, 1
store i64 %77, i64* %19
br label %49
78: ; preds = %49
ret void
}

LLVM IR (-O2):
define void @yar_remap(double* noalias nocapture %0, double %1, i64 %2, i64 %3, double* noalias nocapture %4, i64 %5, i32* noalias nocapture %6, i32* noalias nocapture %7, double* noalias nocapture %8) {
%10 = icmp sgt i64 %2, 0
br i1 %10, label %11, label %88
11: ; preds = %9
%12 = icmp ult i64 %2, 4
br i1 %12, label %86, label %13
13: ; preds = %11
%14 = and i64 %2, -4
%15 = insertelement <2 x double> poison, double %1, i64 0
%16 = shufflevector <2 x double> %15, <2 x double> poison, <2 x i32> zeroinitializer
%17 = insertelement <2 x double> poison, double %1, i64 0
%18 = shufflevector <2 x double> %17, <2 x double> poison, <2 x i32> zeroinitializer
%19 = add i64 %14, -4
%20 = lshr exact i64 %19, 2
%21 = add nuw nsw i64 %20, 1
%22 = and i64 %21, 7
%23 = icmp ult i64 %19, 28
br i1 %23, label %71, label %24
24: ; preds = %13
%25 = and i64 %21, 9223372036854775800
br label %26
26: ; preds = %26, %24
%27 = phi i64 [ 0, %24 ], [ %68, %26 ]
%28 = phi i64 [ 0, %24 ], [ %69, %26 ]
%29 = getelementptr inbounds double, double* %0, i64 %27
%30 = bitcast double* %29 to <2 x double>*
store <2 x double> %16, <2 x double>* %30
%31 = getelementptr inbounds double, double* %29, i64 2
%32 = bitcast double* %31 to <2 x double>*
store <2 x double> %18, <2 x double>* %32
%33 = or i64 %27, 4
%34 = getelementptr inbounds double, double* %0, i64 %33
%35 = bitcast double* %34 to <2 x double>*
store <2 x double> %16, <2 x double>* %35
%36 = getelementptr inbounds double, double* %34, i64 2
%37 = bitcast double* %36 to <2 x double>*
store <2 x double> %18, <2 x double>* %37
%38 = or i64 %27, 8
%39 = getelementptr inbounds double, double* %0, i64 %38
%40 = bitcast double* %39 to <2 x double>*
store <2 x double> %16, <2 x double>* %40
%41 = getelementptr inbounds double, double* %39, i64 2
%42 = bitcast double* %41 to <2 x double>*
store <2 x double> %18, <2 x double>* %42
%43 = or i64 %27, 12
%44 = getelementptr inbounds double, double* %0, i64 %43
%45 = bitcast double* %44 to <2 x double>*
store <2 x double> %16, <2 x double>* %45
%46 = getelementptr inbounds double, double* %44, i64 2
%47 = bitcast double* %46 to <2 x double>*
store <2 x double> %18, <2 x double>* %47
%48 = or i64 %27, 16
%49 = getelementptr inbounds double, double* %0, i64 %48
%50 = bitcast double* %49 to <2 x double>*
store <2 x double> %16, <2 x double>* %50
%51 = getelementptr inbounds double, double* %49, i64 2
%52 = bitcast double* %51 to <2 x double>*
store <2 x double> %18, <2 x double>* %52
%53 = or i64 %27, 20
%54 = getelementptr inbounds double, double* %0, i64 %53
%55 = bitcast double* %54 to <2 x double>*
store <2 x double> %16, <2 x double>* %55
%56 = getelementptr inbounds double, double* %54, i64 2
%57 = bitcast double* %56 to <2 x double>*
store <2 x double> %18, <2 x double>* %57
%58 = or i64 %27, 24
%59 = getelementptr inbounds double, double* %0, i64 %58
%60 = bitcast double* %59 to <2 x double>*
store <2 x double> %16, <2 x double>* %60
%61 = getelementptr inbounds double, double* %59, i64 2
%62 = bitcast double* %61 to <2 x double>*
store <2 x double> %18, <2 x double>* %62
%63 = or i64 %27, 28
%64 = getelementptr inbounds double, double* %0, i64 %63
%65 = bitcast double* %64 to <2 x double>*
store <2 x double> %16, <2 x double>* %65
%66 = getelementptr inbounds double, double* %64, i64 2
%67 = bitcast double* %66 to <2 x double>*
store <2 x double> %18, <2 x double>* %67
%68 = add nuw i64 %27, 32
%69 = add i64 %28, 8
%70 = icmp eq i64 %69, %25
br i1 %70, label %71, label %26
71: ; preds = %26, %13
%72 = phi i64 [ 0, %13 ], [ %68, %26 ]
%73 = icmp eq i64 %22, 0
br i1 %73, label %84, label %74
74: ; preds = %71, %74
%75 = phi i64 [ %81, %74 ], [ %72, %71 ]
%76 = phi i64 [ %82, %74 ], [ 0, %71 ]
%77 = getelementptr inbounds double, double* %0, i64 %75
%78 = bitcast double* %77 to <2 x double>*
store <2 x double> %16, <2 x double>* %78
%79 = getelementptr inbounds double, double* %77, i64 2
%80 = bitcast double* %79 to <2 x double>*
store <2 x double> %18, <2 x double>* %80
%81 = add nuw i64 %75, 4
%82 = add i64 %76, 1
%83 = icmp eq i64 %82, %22
br i1 %83, label %84, label %74
84: ; preds = %74, %71
%85 = icmp eq i64 %14, %2
br i1 %85, label %88, label %86
86: ; preds = %11, %84
%87 = phi i64 [ 0, %11 ], [ %14, %84 ]
br label %96
88: ; preds = %96, %84, %9
%89 = icmp sgt i64 %3, 0
br i1 %89, label %90, label %195
90: ; preds = %88
%91 = add i64 %3, -1
%92 = and i64 %3, 3
%93 = icmp ult i64 %91, 3
br i1 %93, label %101, label %94
94: ; preds = %90
%95 = and i64 %3, -4
br label %120
96: ; preds = %86, %96
%97 = phi i64 [ %99, %96 ], [ %87, %86 ]
%98 = getelementptr inbounds double, double* %0, i64 %97
store double %1, double* %98
%99 = add nuw nsw i64 %97, 1
%100 = icmp eq i64 %99, %2
br i1 %100, label %88, label %96
101: ; preds = %120, %90
%102 = phi i64 [ 0, %90 ], [ %142, %120 ]
%103 = icmp eq i64 %92, 0
br i1 %103, label %114, label %104
104: ; preds = %101, %104
%105 = phi i64 [ %111, %104 ], [ %102, %101 ]
%106 = phi i64 [ %112, %104 ], [ 0, %101 ]
%107 = getelementptr inbounds i32, i32* %6, i64 %105
%108 = load i32, i32* %107
%109 = sext i32 %108 to i64
%110 = getelementptr inbounds double, double* %0, i64 %109
store double 0.000000e+00, double* %110
%111 = add nuw nsw i64 %105, 1
%112 = add i64 %106, 1
%113 = icmp eq i64 %112, %92
br i1 %113, label %114, label %104
114: ; preds = %104, %101
br i1 %89, label %115, label %195
115: ; preds = %114
%116 = and i64 %3, 1
%117 = icmp eq i64 %91, 0
br i1 %117, label %178, label %118
118: ; preds = %115
%119 = and i64 %3, -2
br label %145
120: ; preds = %120, %94
%121 = phi i64 [ 0, %94 ], [ %142, %120 ]
%122 = phi i64 [ 0, %94 ], [ %143, %120 ]
%123 = getelementptr inbounds i32, i32* %6, i64 %121
%124 = load i32, i32* %123
%125 = sext i32 %124 to i64
%126 = getelementptr inbounds double, double* %0, i64 %125
store double 0.000000e+00, double* %126
%127 = or i64 %121, 1
%128 = getelementptr inbounds i32, i32* %6, i64 %127
%129 = load i32, i32* %128
%130 = sext i32 %129 to i64
%131 = getelementptr inbounds double, double* %0, i64 %130
store double 0.000000e+00, double* %131
%132 = or i64 %121, 2
%133 = getelementptr inbounds i32, i32* %6, i64 %132
%134 = load i32, i32* %133
%135 = sext i32 %134 to i64
%136 = getelementptr inbounds double, double* %0, i64 %135
store double 0.000000e+00, double* %136
%137 = or i64 %121, 3
%138 = getelementptr inbounds i32, i32* %6, i64 %137
%139 = load i32, i32* %138
%140 = sext i32 %139 to i64
%141 = getelementptr inbounds double, double* %0, i64 %140
store double 0.000000e+00, double* %141
%142 = add nuw nsw i64 %121, 4
%143 = add i64 %122, 4
%144 = icmp eq i64 %143, %95
br i1 %144, label %101, label %120
145: ; preds = %145, %118
%146 = phi i64 [ 0, %118 ], [ %175, %145 ]
%147 = phi i64 [ 0, %118 ], [ %176, %145 ]
%148 = getelementptr inbounds i32, i32* %7, i64 %146
%149 = load i32, i32* %148
%150 = sext i32 %149 to i64
%151 = getelementptr inbounds double, double* %8, i64 %150
%152 = load double, double* %151
%153 = getelementptr inbounds double, double* %4, i64 %146
%154 = load double, double* %153
%155 = getelementptr inbounds i32, i32* %6, i64 %146
%156 = load i32, i32* %155
%157 = sext i32 %156 to i64
%158 = getelementptr inbounds double, double* %0, i64 %157
%159 = load double, double* %158
%160 = tail call double @llvm.fmuladd.f64(double %152, double %154, double %159)
store double %160, double* %158
%161 = or i64 %146, 1
%162 = getelementptr inbounds i32, i32* %7, i64 %161
%163 = load i32, i32* %162
%164 = sext i32 %163 to i64
%165 = getelementptr inbounds double, double* %8, i64 %164
%166 = load double, double* %165
%167 = getelementptr inbounds double, double* %4, i64 %161
%168 = load double, double* %167
%169 = getelementptr inbounds i32, i32* %6, i64 %161
%170 = load i32, i32* %169
%171 = sext i32 %170 to i64
%172 = getelementptr inbounds double, double* %0, i64 %171
%173 = load double, double* %172
%174 = tail call double @llvm.fmuladd.f64(double %166, double %168, double %173)
store double %174, double* %172
%175 = add nuw nsw i64 %146, 2
%176 = add i64 %147, 2
%177 = icmp eq i64 %176, %119
br i1 %177, label %178, label %145
178: ; preds = %145, %115
%179 = phi i64 [ 0, %115 ], [ %175, %145 ]
%180 = icmp eq i64 %116, 0
br i1 %180, label %195, label %181
181: ; preds = %178
%182 = getelementptr inbounds i32, i32* %7, i64 %179
%183 = load i32, i32* %182
%184 = sext i32 %183 to i64
%185 = getelementptr inbounds double, double* %8, i64 %184
%186 = load double, double* %185
%187 = getelementptr inbounds double, double* %4, i64 %179
%188 = load double, double* %187
%189 = getelementptr inbounds i32, i32* %6, i64 %179
%190 = load i32, i32* %189
%191 = sext i32 %190 to i64
%192 = getelementptr inbounds double, double* %0, i64 %191
%193 = load double, double* %192
%194 = tail call double @llvm.fmuladd.f64(double %186, double %188, double %193)
store double %194, double* %192
br label %195
195: ; preds = %181, %178, %88, %114
ret void
}