float double_reduc(float *i) {
  float l = 0;
  for (int a = 0; a < 8; a++)
    for (int b = 0; b < 16; b++) {
      l += i[b * 4];
      l += i[b * 4 + 1];
      l += i[b * 4 + 2];
      l += i[b * 4 + 3];
    }
  return l;
}


x86 assembly (clang, -O0):
<double_reduc>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0xc(%rbp)
movl   $0x0,-0x10(%rbp)
cmpl   $0x8,-0x10(%rbp)
jge    11cc <double_reduc+0xcc>
movl   $0x0,-0x14(%rbp)
cmpl   $0x10,-0x14(%rbp)
jge    11b9 <double_reduc+0xb9>
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x2,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
addss  -0xc(%rbp),%xmm0
movss  %xmm0,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x2,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
addss  -0xc(%rbp),%xmm0
movss  %xmm0,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x2,%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
addss  -0xc(%rbp),%xmm0
movss  %xmm0,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
shl    $0x2,%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
addss  -0xc(%rbp),%xmm0
movss  %xmm0,-0xc(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1128 <double_reduc+0x28>
jmp    11be <double_reduc+0xbe>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1117 <double_reduc+0x17>
movss  -0xc(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<double_reduc>:
xorps  %xmm0,%xmm0
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nop
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    1110 <double_reduc+0x10>
xor    %eax,%eax
nopl   (%rax)
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    1150 <double_reduc+0x50>
xor    %eax,%eax
nopl   (%rax)
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    1190 <double_reduc+0x90>
xor    %eax,%eax
nopl   (%rax)
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    11d0 <double_reduc+0xd0>
xor    %eax,%eax
nopl   (%rax)
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    1210 <double_reduc+0x110>
xor    %eax,%eax
nopl   (%rax)
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    1250 <double_reduc+0x150>
xor    %eax,%eax
nopl   (%rax)
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    1290 <double_reduc+0x190>
xor    %eax,%eax
nopl   (%rax)
addss  (%rdi,%rax,1),%xmm0
addss  0x4(%rdi,%rax,1),%xmm0
addss  0x8(%rdi,%rax,1),%xmm0
addss  0xc(%rdi,%rax,1),%xmm0
addss  0x10(%rdi,%rax,1),%xmm0
addss  0x14(%rdi,%rax,1),%xmm0
addss  0x18(%rdi,%rax,1),%xmm0
addss  0x1c(%rdi,%rax,1),%xmm0
add    $0x20,%rax
cmp    $0x100,%rax
jne    12d0 <double_reduc+0x1d0>
ret

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

LLVM IR (-O2):
define float @double_reduc(float* nocapture %0) {
br label %269
2: ; preds = %269, %2
%3 = phi i64 [ %38, %2 ], [ 0, %269 ]
%4 = phi float [ %37, %2 ], [ %304, %269 ]
%5 = shl nuw nsw i64 %3, 2
%6 = getelementptr inbounds float, float* %0, i64 %5
%7 = load float, float* %6
%8 = fadd float %4, %7
%9 = or i64 %5, 1
%10 = getelementptr inbounds float, float* %0, i64 %9
%11 = load float, float* %10
%12 = fadd float %8, %11
%13 = or i64 %5, 2
%14 = getelementptr inbounds float, float* %0, i64 %13
%15 = load float, float* %14
%16 = fadd float %12, %15
%17 = or i64 %5, 3
%18 = getelementptr inbounds float, float* %0, i64 %17
%19 = load float, float* %18
%20 = fadd float %16, %19
%21 = shl i64 %3, 2
%22 = or i64 %21, 4
%23 = getelementptr inbounds float, float* %0, i64 %22
%24 = load float, float* %23
%25 = fadd float %20, %24
%26 = or i64 %21, 5
%27 = getelementptr inbounds float, float* %0, i64 %26
%28 = load float, float* %27
%29 = fadd float %25, %28
%30 = or i64 %21, 6
%31 = getelementptr inbounds float, float* %0, i64 %30
%32 = load float, float* %31
%33 = fadd float %29, %32
%34 = or i64 %21, 7
%35 = getelementptr inbounds float, float* %0, i64 %34
%36 = load float, float* %35
%37 = fadd float %33, %36
%38 = add nuw nsw i64 %3, 2
%39 = icmp eq i64 %38, 16
br i1 %39, label %40, label %2
40: ; preds = %2, %40
%41 = phi i64 [ %76, %40 ], [ 0, %2 ]
%42 = phi float [ %75, %40 ], [ %37, %2 ]
%43 = shl nuw nsw i64 %41, 2
%44 = getelementptr inbounds float, float* %0, i64 %43
%45 = load float, float* %44
%46 = fadd float %42, %45
%47 = or i64 %43, 1
%48 = getelementptr inbounds float, float* %0, i64 %47
%49 = load float, float* %48
%50 = fadd float %46, %49
%51 = or i64 %43, 2
%52 = getelementptr inbounds float, float* %0, i64 %51
%53 = load float, float* %52
%54 = fadd float %50, %53
%55 = or i64 %43, 3
%56 = getelementptr inbounds float, float* %0, i64 %55
%57 = load float, float* %56
%58 = fadd float %54, %57
%59 = shl i64 %41, 2
%60 = or i64 %59, 4
%61 = getelementptr inbounds float, float* %0, i64 %60
%62 = load float, float* %61
%63 = fadd float %58, %62
%64 = or i64 %59, 5
%65 = getelementptr inbounds float, float* %0, i64 %64
%66 = load float, float* %65
%67 = fadd float %63, %66
%68 = or i64 %59, 6
%69 = getelementptr inbounds float, float* %0, i64 %68
%70 = load float, float* %69
%71 = fadd float %67, %70
%72 = or i64 %59, 7
%73 = getelementptr inbounds float, float* %0, i64 %72
%74 = load float, float* %73
%75 = fadd float %71, %74
%76 = add nuw nsw i64 %41, 2
%77 = icmp eq i64 %76, 16
br i1 %77, label %78, label %40
78: ; preds = %40, %78
%79 = phi i64 [ %114, %78 ], [ 0, %40 ]
%80 = phi float [ %113, %78 ], [ %75, %40 ]
%81 = shl nuw nsw i64 %79, 2
%82 = getelementptr inbounds float, float* %0, i64 %81
%83 = load float, float* %82
%84 = fadd float %80, %83
%85 = or i64 %81, 1
%86 = getelementptr inbounds float, float* %0, i64 %85
%87 = load float, float* %86
%88 = fadd float %84, %87
%89 = or i64 %81, 2
%90 = getelementptr inbounds float, float* %0, i64 %89
%91 = load float, float* %90
%92 = fadd float %88, %91
%93 = or i64 %81, 3
%94 = getelementptr inbounds float, float* %0, i64 %93
%95 = load float, float* %94
%96 = fadd float %92, %95
%97 = shl i64 %79, 2
%98 = or i64 %97, 4
%99 = getelementptr inbounds float, float* %0, i64 %98
%100 = load float, float* %99
%101 = fadd float %96, %100
%102 = or i64 %97, 5
%103 = getelementptr inbounds float, float* %0, i64 %102
%104 = load float, float* %103
%105 = fadd float %101, %104
%106 = or i64 %97, 6
%107 = getelementptr inbounds float, float* %0, i64 %106
%108 = load float, float* %107
%109 = fadd float %105, %108
%110 = or i64 %97, 7
%111 = getelementptr inbounds float, float* %0, i64 %110
%112 = load float, float* %111
%113 = fadd float %109, %112
%114 = add nuw nsw i64 %79, 2
%115 = icmp eq i64 %114, 16
br i1 %115, label %116, label %78
116: ; preds = %78, %116
%117 = phi i64 [ %152, %116 ], [ 0, %78 ]
%118 = phi float [ %151, %116 ], [ %113, %78 ]
%119 = shl nuw nsw i64 %117, 2
%120 = getelementptr inbounds float, float* %0, i64 %119
%121 = load float, float* %120
%122 = fadd float %118, %121
%123 = or i64 %119, 1
%124 = getelementptr inbounds float, float* %0, i64 %123
%125 = load float, float* %124
%126 = fadd float %122, %125
%127 = or i64 %119, 2
%128 = getelementptr inbounds float, float* %0, i64 %127
%129 = load float, float* %128
%130 = fadd float %126, %129
%131 = or i64 %119, 3
%132 = getelementptr inbounds float, float* %0, i64 %131
%133 = load float, float* %132
%134 = fadd float %130, %133
%135 = shl i64 %117, 2
%136 = or i64 %135, 4
%137 = getelementptr inbounds float, float* %0, i64 %136
%138 = load float, float* %137
%139 = fadd float %134, %138
%140 = or i64 %135, 5
%141 = getelementptr inbounds float, float* %0, i64 %140
%142 = load float, float* %141
%143 = fadd float %139, %142
%144 = or i64 %135, 6
%145 = getelementptr inbounds float, float* %0, i64 %144
%146 = load float, float* %145
%147 = fadd float %143, %146
%148 = or i64 %135, 7
%149 = getelementptr inbounds float, float* %0, i64 %148
%150 = load float, float* %149
%151 = fadd float %147, %150
%152 = add nuw nsw i64 %117, 2
%153 = icmp eq i64 %152, 16
br i1 %153, label %154, label %116
154: ; preds = %116, %154
%155 = phi i64 [ %190, %154 ], [ 0, %116 ]
%156 = phi float [ %189, %154 ], [ %151, %116 ]
%157 = shl nuw nsw i64 %155, 2
%158 = getelementptr inbounds float, float* %0, i64 %157
%159 = load float, float* %158
%160 = fadd float %156, %159
%161 = or i64 %157, 1
%162 = getelementptr inbounds float, float* %0, i64 %161
%163 = load float, float* %162
%164 = fadd float %160, %163
%165 = or i64 %157, 2
%166 = getelementptr inbounds float, float* %0, i64 %165
%167 = load float, float* %166
%168 = fadd float %164, %167
%169 = or i64 %157, 3
%170 = getelementptr inbounds float, float* %0, i64 %169
%171 = load float, float* %170
%172 = fadd float %168, %171
%173 = shl i64 %155, 2
%174 = or i64 %173, 4
%175 = getelementptr inbounds float, float* %0, i64 %174
%176 = load float, float* %175
%177 = fadd float %172, %176
%178 = or i64 %173, 5
%179 = getelementptr inbounds float, float* %0, i64 %178
%180 = load float, float* %179
%181 = fadd float %177, %180
%182 = or i64 %173, 6
%183 = getelementptr inbounds float, float* %0, i64 %182
%184 = load float, float* %183
%185 = fadd float %181, %184
%186 = or i64 %173, 7
%187 = getelementptr inbounds float, float* %0, i64 %186
%188 = load float, float* %187
%189 = fadd float %185, %188
%190 = add nuw nsw i64 %155, 2
%191 = icmp eq i64 %190, 16
br i1 %191, label %192, label %154
192: ; preds = %154, %192
%193 = phi i64 [ %228, %192 ], [ 0, %154 ]
%194 = phi float [ %227, %192 ], [ %189, %154 ]
%195 = shl nuw nsw i64 %193, 2
%196 = getelementptr inbounds float, float* %0, i64 %195
%197 = load float, float* %196
%198 = fadd float %194, %197
%199 = or i64 %195, 1
%200 = getelementptr inbounds float, float* %0, i64 %199
%201 = load float, float* %200
%202 = fadd float %198, %201
%203 = or i64 %195, 2
%204 = getelementptr inbounds float, float* %0, i64 %203
%205 = load float, float* %204
%206 = fadd float %202, %205
%207 = or i64 %195, 3
%208 = getelementptr inbounds float, float* %0, i64 %207
%209 = load float, float* %208
%210 = fadd float %206, %209
%211 = shl i64 %193, 2
%212 = or i64 %211, 4
%213 = getelementptr inbounds float, float* %0, i64 %212
%214 = load float, float* %213
%215 = fadd float %210, %214
%216 = or i64 %211, 5
%217 = getelementptr inbounds float, float* %0, i64 %216
%218 = load float, float* %217
%219 = fadd float %215, %218
%220 = or i64 %211, 6
%221 = getelementptr inbounds float, float* %0, i64 %220
%222 = load float, float* %221
%223 = fadd float %219, %222
%224 = or i64 %211, 7
%225 = getelementptr inbounds float, float* %0, i64 %224
%226 = load float, float* %225
%227 = fadd float %223, %226
%228 = add nuw nsw i64 %193, 2
%229 = icmp eq i64 %228, 16
br i1 %229, label %230, label %192
230: ; preds = %192, %230
%231 = phi i64 [ %266, %230 ], [ 0, %192 ]
%232 = phi float [ %265, %230 ], [ %227, %192 ]
%233 = shl nuw nsw i64 %231, 2
%234 = getelementptr inbounds float, float* %0, i64 %233
%235 = load float, float* %234
%236 = fadd float %232, %235
%237 = or i64 %233, 1
%238 = getelementptr inbounds float, float* %0, i64 %237
%239 = load float, float* %238
%240 = fadd float %236, %239
%241 = or i64 %233, 2
%242 = getelementptr inbounds float, float* %0, i64 %241
%243 = load float, float* %242
%244 = fadd float %240, %243
%245 = or i64 %233, 3
%246 = getelementptr inbounds float, float* %0, i64 %245
%247 = load float, float* %246
%248 = fadd float %244, %247
%249 = shl i64 %231, 2
%250 = or i64 %249, 4
%251 = getelementptr inbounds float, float* %0, i64 %250
%252 = load float, float* %251
%253 = fadd float %248, %252
%254 = or i64 %249, 5
%255 = getelementptr inbounds float, float* %0, i64 %254
%256 = load float, float* %255
%257 = fadd float %253, %256
%258 = or i64 %249, 6
%259 = getelementptr inbounds float, float* %0, i64 %258
%260 = load float, float* %259
%261 = fadd float %257, %260
%262 = or i64 %249, 7
%263 = getelementptr inbounds float, float* %0, i64 %262
%264 = load float, float* %263
%265 = fadd float %261, %264
%266 = add nuw nsw i64 %231, 2
%267 = icmp eq i64 %266, 16
br i1 %267, label %268, label %230
268: ; preds = %230
ret float %265
269: ; preds = %269, %1
%270 = phi i64 [ 0, %1 ], [ %305, %269 ]
%271 = phi float [ 0.000000e+00, %1 ], [ %304, %269 ]
%272 = shl nuw nsw i64 %270, 2
%273 = getelementptr inbounds float, float* %0, i64 %272
%274 = load float, float* %273
%275 = fadd float %271, %274
%276 = or i64 %272, 1
%277 = getelementptr inbounds float, float* %0, i64 %276
%278 = load float, float* %277
%279 = fadd float %275, %278
%280 = or i64 %272, 2
%281 = getelementptr inbounds float, float* %0, i64 %280
%282 = load float, float* %281
%283 = fadd float %279, %282
%284 = or i64 %272, 3
%285 = getelementptr inbounds float, float* %0, i64 %284
%286 = load float, float* %285
%287 = fadd float %283, %286
%288 = shl i64 %270, 2
%289 = or i64 %288, 4
%290 = getelementptr inbounds float, float* %0, i64 %289
%291 = load float, float* %290
%292 = fadd float %287, %291
%293 = or i64 %288, 5
%294 = getelementptr inbounds float, float* %0, i64 %293
%295 = load float, float* %294
%296 = fadd float %292, %295
%297 = or i64 %288, 6
%298 = getelementptr inbounds float, float* %0, i64 %297
%299 = load float, float* %298
%300 = fadd float %296, %299
%301 = or i64 %288, 7
%302 = getelementptr inbounds float, float* %0, i64 %301
%303 = load float, float* %302
%304 = fadd float %300, %303
%305 = add nuw nsw i64 %270, 2
%306 = icmp eq i64 %305, 16
br i1 %306, label %2, label %269
}