int DiagonalMatrixTimesDiagonalMatrix(x_p, y_p, z_p, nz_p)
double *x_p, *y_p, *z_p;
int *nz_p;
{
  register int i;
  for (i = 0; i < *nz_p; i++)
    *z_p++ = *x_p++ * *y_p++;
  return 0;
}


x86 assembly (clang, -O0):
<DiagonalMatrixTimesDiagonalMatrix>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    -0x20(%rbp),%rcx
cmp    (%rcx),%eax
jge    1171 <DiagonalMatrixTimesDiagonalMatrix+0x71>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x8(%rbp)
movsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x18(%rbp)
movsd  %xmm0,(%rax)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    111b <DiagonalMatrixTimesDiagonalMatrix+0x1b>
xor    %eax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<DiagonalMatrixTimesDiagonalMatrix>:
push   %rbp
push   %rbx
mov    (%rcx),%r11d
test   %r11d,%r11d
jle    12e3 <DiagonalMatrixTimesDiagonalMatrix+0x1e3>
lea    -0x1(%r11),%r9d
xor    %r8d,%r8d
cmp    $0x3,%r9d
jae    11d3 <DiagonalMatrixTimesDiagonalMatrix+0xd3>
mov    %r11d,%ecx
sub    %r8d,%ecx
mov    %r8d,%r9d
not    %r9d
add    %r11d,%r9d
and    $0x3,%ecx
je     1162 <DiagonalMatrixTimesDiagonalMatrix+0x62>
neg    %ecx
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
movsd  (%rdi),%xmm0
add    $0x8,%rdi
mulsd  (%rsi),%xmm0
add    $0x8,%rsi
movsd  %xmm0,(%rdx)
add    $0x8,%rdx
add    $0xffffffff,%eax
cmp    %eax,%ecx
jne    1140 <DiagonalMatrixTimesDiagonalMatrix+0x40>
sub    %eax,%r8d
cmp    $0x3,%r9d
jb     12e3 <DiagonalMatrixTimesDiagonalMatrix+0x1e3>
sub    %r8d,%r11d
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movsd  (%rdi,%rax,8),%xmm0
mulsd  (%rsi,%rax,8),%xmm0
movsd  %xmm0,(%rdx,%rax,8)
movsd  0x8(%rdi,%rax,8),%xmm0
mulsd  0x8(%rsi,%rax,8),%xmm0
movsd  %xmm0,0x8(%rdx,%rax,8)
movsd  0x10(%rdi,%rax,8),%xmm0
mulsd  0x10(%rsi,%rax,8),%xmm0
movsd  %xmm0,0x10(%rdx,%rax,8)
movsd  0x18(%rdi,%rax,8),%xmm0
mulsd  0x18(%rsi,%rax,8),%xmm0
movsd  %xmm0,0x18(%rdx,%rax,8)
add    $0x4,%rax
cmp    %eax,%r11d
jne    1180 <DiagonalMatrixTimesDiagonalMatrix+0x80>
jmp    12e3 <DiagonalMatrixTimesDiagonalMatrix+0x1e3>
lea    (%rdi,%r9,8),%rax
add    $0x8,%rax
cmp    %rdx,%rax
seta   %bpl
lea    (%rdx,%r9,8),%rcx
add    $0x8,%rcx
cmp    %rdi,%rcx
seta   %bl
lea    (%rsi,%r9,8),%rax
add    $0x8,%rax
cmp    %rdx,%rax
seta   %al
cmp    %rsi,%rcx
seta   %r10b
test   %bl,%bpl
jne    111f <DiagonalMatrixTimesDiagonalMatrix+0x1f>
and    %r10b,%al
jne    111f <DiagonalMatrixTimesDiagonalMatrix+0x1f>
add    $0x1,%r9
mov    %r9,%r8
and    $0xfffffffffffffffc,%r8
lea    -0x4(%r8),%rax
mov    %rax,%r10
shr    $0x2,%r10
add    $0x1,%r10
test   %rax,%rax
je     12f9 <DiagonalMatrixTimesDiagonalMatrix+0x1f9>
mov    %r10,%rax
and    $0xfffffffffffffffe,%rax
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movupd (%rdi,%rcx,8),%xmm0
movupd 0x10(%rdi,%rcx,8),%xmm1
movupd (%rsi,%rcx,8),%xmm2
mulpd  %xmm0,%xmm2
movupd 0x10(%rsi,%rcx,8),%xmm0
mulpd  %xmm1,%xmm0
movupd %xmm2,(%rdx,%rcx,8)
movupd %xmm0,0x10(%rdx,%rcx,8)
movupd 0x20(%rdi,%rcx,8),%xmm0
movupd 0x30(%rdi,%rcx,8),%xmm1
movupd 0x20(%rsi,%rcx,8),%xmm2
mulpd  %xmm0,%xmm2
movupd 0x30(%rsi,%rcx,8),%xmm0
mulpd  %xmm1,%xmm0
movupd %xmm2,0x20(%rdx,%rcx,8)
movupd %xmm0,0x30(%rdx,%rcx,8)
add    $0x8,%rcx
add    $0xfffffffffffffffe,%rax
jne    1250 <DiagonalMatrixTimesDiagonalMatrix+0x150>
test   $0x1,%r10b
je     12de <DiagonalMatrixTimesDiagonalMatrix+0x1de>
movupd (%rdi,%rcx,8),%xmm0
movupd 0x10(%rdi,%rcx,8),%xmm1
movupd (%rsi,%rcx,8),%xmm2
mulpd  %xmm0,%xmm2
movupd 0x10(%rsi,%rcx,8),%xmm0
mulpd  %xmm1,%xmm0
movupd %xmm2,(%rdx,%rcx,8)
movupd %xmm0,0x10(%rdx,%rcx,8)
cmp    %r8,%r9
jne    12e8 <DiagonalMatrixTimesDiagonalMatrix+0x1e8>
xor    %eax,%eax
pop    %rbx
pop    %rbp
ret
lea    (%rdi,%r8,8),%rdi
lea    (%rdx,%r8,8),%rdx
lea    (%rsi,%r8,8),%rsi
jmp    111f <DiagonalMatrixTimesDiagonalMatrix+0x1f>
xor    %ecx,%ecx
test   $0x1,%r10b
jne    12b5 <DiagonalMatrixTimesDiagonalMatrix+0x1b5>
jmp    12de <DiagonalMatrixTimesDiagonalMatrix+0x1de>

LLVM IR (-O0):
define i32 @DiagonalMatrixTimesDiagonalMatrix(double* %0, double* %1, double* %2, i32* %3) {
%5 = alloca double*
%6 = alloca double*
%7 = alloca double*
%8 = alloca i32*
%9 = alloca i32
store double* %0, double** %5
store double* %1, double** %6
store double* %2, double** %7
store i32* %3, i32** %8
store i32 0, i32* %9
br label %10
10: ; preds = %25, %4
%11 = load i32, i32* %9
%12 = load i32*, i32** %8
%13 = load i32, i32* %12
%14 = icmp slt i32 %11, %13
br i1 %14, label %15, label %28
15: ; preds = %10
%16 = load double*, double** %5
%17 = getelementptr inbounds double, double* %16, i32 1
store double* %17, double** %5
%18 = load double, double* %16
%19 = load double*, double** %6
%20 = getelementptr inbounds double, double* %19, i32 1
store double* %20, double** %6
%21 = load double, double* %19
%22 = fmul double %18, %21
%23 = load double*, double** %7
%24 = getelementptr inbounds double, double* %23, i32 1
store double* %24, double** %7
store double %22, double* %23
br label %25
25: ; preds = %15
%26 = load i32, i32* %9
%27 = add nsw i32 %26, 1
store i32 %27, i32* %9
br label %10
28: ; preds = %10
ret i32 0
}

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