void kernel4(int L, float *ai, float *ef) {
  float *p2 = ef;
  float *p1 = ai;
  double mag, t;
  int i;
  for (i = 0; i < L; i++) {
    t = *p2++;
    mag = t * t;
    t = *p2++;
    mag += t * t;
    *p1++ += mag;
  }
}


x86 assembly (clang, -O0):
<kernel4>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11cb <kernel4+0xcb>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x20(%rbp)
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x20(%rbp)
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm1
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x28(%rbp)
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%rax)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1126 <kernel4+0x26>
pop    %rbp
ret

x86 assembly (clang, -O2):
<kernel4>:
test   %edi,%edi
jle    12b7 <kernel4+0x1b7>
lea    -0x1(%rdi),%r9d
xor    %r8d,%r8d
cmp    $0x3,%r9d
jb     1137 <kernel4+0x37>
lea    (%rdx,%r9,8),%rax
add    $0x8,%rax
cmp    %rsi,%rax
jbe    1221 <kernel4+0x121>
lea    (%rsi,%r9,4),%rax
add    $0x4,%rax
cmp    %rdx,%rax
jbe    1221 <kernel4+0x121>
mov    %rdx,%r10
mov    %rsi,%rcx
mov    %edi,%edx
sub    %r8d,%edx
mov    %r8d,%eax
not    %eax
test   $0x1,%dl
je     118b <kernel4+0x8b>
movss  (%r10),%xmm0
movss  0x4(%r10),%xmm1
cvtss2sd %xmm0,%xmm0
mulsd  %xmm0,%xmm0
cvtss2sd %xmm1,%xmm1
mulsd  %xmm1,%xmm1
addsd  %xmm0,%xmm1
movss  (%rcx),%xmm0
cvtss2sd %xmm0,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x8,%r10
movss  %xmm0,(%rcx)
add    $0x4,%rcx
add    $0x1,%r8d
add    %edi,%eax
je     12b7 <kernel4+0x1b7>
sub    %r8d,%edi
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
movss  (%r10,%rax,8),%xmm0
movss  0x4(%r10,%rax,8),%xmm1
cvtss2sd %xmm0,%xmm0
mulsd  %xmm0,%xmm0
cvtss2sd %xmm1,%xmm1
mulsd  %xmm1,%xmm1
addsd  %xmm0,%xmm1
movss  (%rcx,%rax,4),%xmm0
movss  0x4(%rcx,%rax,4),%xmm2
cvtss2sd %xmm0,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%rcx,%rax,4)
movss  0x8(%r10,%rax,8),%xmm0
movss  0xc(%r10,%rax,8),%xmm1
cvtss2sd %xmm0,%xmm0
mulsd  %xmm0,%xmm0
cvtss2sd %xmm1,%xmm1
mulsd  %xmm1,%xmm1
addsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtss2sd %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x4(%rcx,%rax,4)
add    $0x2,%rax
cmp    %eax,%edi
jne    11a0 <kernel4+0xa0>
jmp    12b7 <kernel4+0x1b7>
add    $0x1,%r9
mov    %r9,%r8
and    $0xfffffffffffffffc,%r8
lea    (%rdx,%r8,8),%r10
lea    (%rsi,%r8,4),%rcx
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
movups (%rdx,%rax,8),%xmm0
movups 0x10(%rdx,%rax,8),%xmm1
movaps %xmm0,%xmm2
shufps $0x88,%xmm1,%xmm2
movaps %xmm1,%xmm3
shufps $0xe8,%xmm1,%xmm3
cvtps2pd %xmm3,%xmm3
shufps $0xdd,%xmm1,%xmm0
cvtps2pd %xmm2,%xmm2
mulpd  %xmm2,%xmm2
mulpd  %xmm3,%xmm3
cvtps2pd %xmm0,%xmm0
shufps $0xed,%xmm1,%xmm1
cvtps2pd %xmm1,%xmm1
mulpd  %xmm1,%xmm1
addpd  %xmm3,%xmm1
mulpd  %xmm0,%xmm0
addpd  %xmm2,%xmm0
cvtps2pd 0x8(%rsi,%rax,4),%xmm2
addpd  %xmm1,%xmm2
cvtps2pd (%rsi,%rax,4),%xmm1
addpd  %xmm0,%xmm1
cvtpd2ps %xmm2,%xmm0
cvtpd2ps %xmm1,%xmm1
unpcklpd %xmm0,%xmm1
movupd %xmm1,(%rsi,%rax,4)
add    $0x4,%rax
cmp    %rax,%r8
jne    1240 <kernel4+0x140>
cmp    %r8,%r9
jne    113d <kernel4+0x3d>
ret

LLVM IR (-O0):
define void @kernel4(i32 %0, float* %1, float* %2) {
%4 = alloca i32
%5 = alloca float*
%6 = alloca float*
%7 = alloca float*
%8 = alloca float*
%9 = alloca double
%10 = alloca double
%11 = alloca i32
store i32 %0, i32* %4
store float* %1, float** %5
store float* %2, float** %6
%12 = load float*, float** %6
store float* %12, float** %7
%13 = load float*, float** %5
store float* %13, float** %8
store i32 0, i32* %11
br label %14
14: ; preds = %41, %3
%15 = load i32, i32* %11
%16 = load i32, i32* %4
%17 = icmp slt i32 %15, %16
br i1 %17, label %18, label %44
18: ; preds = %14
%19 = load float*, float** %7
%20 = getelementptr inbounds float, float* %19, i32 1
store float* %20, float** %7
%21 = load float, float* %19
%22 = fpext float %21 to double
store double %22, double* %10
%23 = load double, double* %10
%24 = load double, double* %10
%25 = fmul double %23, %24
store double %25, double* %9
%26 = load float*, float** %7
%27 = getelementptr inbounds float, float* %26, i32 1
store float* %27, float** %7
%28 = load float, float* %26
%29 = fpext float %28 to double
store double %29, double* %10
%30 = load double, double* %10
%31 = load double, double* %10
%32 = load double, double* %9
%33 = call double @llvm.fmuladd.f64(double %30, double %31, double %32)
store double %33, double* %9
%34 = load double, double* %9
%35 = load float*, float** %8
%36 = getelementptr inbounds float, float* %35, i32 1
store float* %36, float** %8
%37 = load float, float* %35
%38 = fpext float %37 to double
%39 = fadd double %38, %34
%40 = fptrunc double %39 to float
store float %40, float* %35
br label %41
41: ; preds = %18
%42 = load i32, i32* %11
%43 = add nsw i32 %42, 1
store i32 %43, i32* %11
br label %14
44: ; preds = %14
ret void
}

LLVM IR (-O2):
define void @kernel4(i32 %0, float* nocapture %1, float* nocapture %2) {
%4 = icmp sgt i32 %0, 0
br i1 %4, label %5, label %111
5: ; preds = %3
%6 = add i32 %0, -1
%7 = zext i32 %6 to i64
%8 = add nuw nsw i64 %7, 1
%9 = icmp ult i32 %6, 3
br i1 %9, label %50, label %10
10: ; preds = %5
%11 = add i32 %0, -1
%12 = zext i32 %11 to i64
%13 = add nuw nsw i64 %12, 1
%14 = getelementptr float, float* %1, i64 %13
%15 = shl nuw nsw i64 %12, 1
%16 = add nuw nsw i64 %15, 2
%17 = getelementptr float, float* %2, i64 %16
%18 = icmp ugt float* %17, %1
%19 = icmp ugt float* %14, %2
%20 = and i1 %18, %19
br i1 %20, label %50, label %21
21: ; preds = %10
%22 = and i64 %8, 8589934588
%23 = trunc i64 %22 to i32
%24 = shl nuw nsw i64 %22, 1
%25 = getelementptr float, float* %2, i64 %24
%26 = getelementptr float, float* %1, i64 %22
br label %27
27: ; preds = %27, %21
%28 = phi i64 [ 0, %21 ], [ %46, %27 ]
%29 = shl i64 %28, 1
%30 = getelementptr float, float* %2, i64 %29
%31 = getelementptr float, float* %1, i64 %28
%32 = bitcast float* %30 to <8 x float>*
%33 = load <8 x float>, <8 x float>* %32
%34 = shufflevector <8 x float> %33, <8 x float> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
%35 = shufflevector <8 x float> %33, <8 x float> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
%36 = fpext <4 x float> %34 to <4 x double>
%37 = fmul <4 x double> %36, %36
%38 = fpext <4 x float> %35 to <4 x double>
%39 = call <4 x double> @llvm.fmuladd.v4f64(<4 x double> %38, <4 x double> %38, <4 x double> %37)
%40 = bitcast float* %31 to <4 x float>*
%41 = load <4 x float>, <4 x float>* %40
%42 = fpext <4 x float> %41 to <4 x double>
%43 = fadd <4 x double> %39, %42
%44 = fptrunc <4 x double> %43 to <4 x float>
%45 = bitcast float* %31 to <4 x float>*
store <4 x float> %44, <4 x float>* %45
%46 = add nuw i64 %28, 4
%47 = icmp eq i64 %46, %22
br i1 %47, label %48, label %27
48: ; preds = %27
%49 = icmp eq i64 %8, %22
br i1 %49, label %111, label %50
50: ; preds = %10, %5, %48
%51 = phi i32 [ 0, %10 ], [ 0, %5 ], [ %23, %48 ]
%52 = phi float* [ %2, %10 ], [ %2, %5 ], [ %25, %48 ]
%53 = phi float* [ %1, %10 ], [ %1, %5 ], [ %26, %48 ]
%54 = sub i32 %0, %51
%55 = xor i32 %51, -1
%56 = and i32 %54, 1
%57 = icmp eq i32 %56, 0
br i1 %57, label %73, label %58
58: ; preds = %50
%59 = getelementptr inbounds float, float* %52, i64 1
%60 = load float, float* %52
%61 = fpext float %60 to double
%62 = fmul double %61, %61
%63 = getelementptr inbounds float, float* %52, i64 2
%64 = load float, float* %59
%65 = fpext float %64 to double
%66 = tail call double @llvm.fmuladd.f64(double %65, double %65, double %62)
%67 = getelementptr inbounds float, float* %53, i64 1
%68 = load float, float* %53
%69 = fpext float %68 to double
%70 = fadd double %66, %69
%71 = fptrunc double %70 to float
store float %71, float* %53
%72 = add nuw nsw i32 %51, 1
br label %73
73: ; preds = %58, %50
%74 = phi i32 [ %51, %50 ], [ %72, %58 ]
%75 = phi float* [ %52, %50 ], [ %63, %58 ]
%76 = phi float* [ %53, %50 ], [ %67, %58 ]
%77 = sub i32 0, %0
%78 = icmp eq i32 %55, %77
br i1 %78, label %111, label %79
79: ; preds = %73, %79
%80 = phi i32 [ %109, %79 ], [ %74, %73 ]
%81 = phi float* [ %100, %79 ], [ %75, %73 ]
%82 = phi float* [ %104, %79 ], [ %76, %73 ]
%83 = getelementptr inbounds float, float* %81, i64 1
%84 = load float, float* %81
%85 = fpext float %84 to double
%86 = fmul double %85, %85
%87 = getelementptr inbounds float, float* %81, i64 2
%88 = load float, float* %83
%89 = fpext float %88 to double
%90 = tail call double @llvm.fmuladd.f64(double %89, double %89, double %86)
%91 = getelementptr inbounds float, float* %82, i64 1
%92 = load float, float* %82
%93 = fpext float %92 to double
%94 = fadd double %90, %93
%95 = fptrunc double %94 to float
store float %95, float* %82
%96 = getelementptr inbounds float, float* %81, i64 3
%97 = load float, float* %87
%98 = fpext float %97 to double
%99 = fmul double %98, %98
%100 = getelementptr inbounds float, float* %81, i64 4
%101 = load float, float* %96
%102 = fpext float %101 to double
%103 = tail call double @llvm.fmuladd.f64(double %102, double %102, double %99)
%104 = getelementptr inbounds float, float* %82, i64 2
%105 = load float, float* %91
%106 = fpext float %105 to double
%107 = fadd double %103, %106
%108 = fptrunc double %107 to float
store float %108, float* %91
%109 = add nuw nsw i32 %80, 2
%110 = icmp eq i32 %109, %0
br i1 %110, label %111, label %79
111: ; preds = %73, %79, %48, %3
ret void
}