void trmv_opt(int n, double A[][n], double x[n], double y[n]) {
  int i, j;
  for (i = 0; i < n; i = i + 2) {
    for (j = 0; j < i + 1; j = j + 4) {
      y[j] = y[j] + A[i][j] * x[i];
      if (j + 1 < i + 1) {
        y[j + 1] = y[j + 1] + A[i][j + 1] * x[i];
      }
      if (j + 2 < i + 1) {
        y[j + 2] = y[j + 2] + A[i][j + 2] * x[i];
      }
      if (j + 3 < i + 1) {
        y[j + 3] = y[j + 3] + A[i][j + 3] * x[i];
      }
    }
    for (j = 0; j < i + 2; j = j + 4) {
      y[j] = y[j] + A[i + 1][j] * x[i + 1];
      if (j + 1 < i + 2) {
        y[j + 1] = y[j + 1] + A[i + 1][j + 1] * x[i + 1];
      }
      if (j + 2 < i + 2) {
        y[j + 2] = y[j + 2] + A[i + 1][j + 2] * x[i + 1];
      }
      if (j + 3 < i + 2) {
        y[j + 3] = y[j + 3] + A[i + 1][j + 3] * x[i + 1];
      }
    }
  }
}


x86 assembly (clang, -O0):
<trmv_opt>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x4(%rbp),%eax
mov    %rax,-0x30(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1508 <trmv_opt+0x408>
movl   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    12fd <trmv_opt+0x1fd>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    1206 <trmv_opt+0x106>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x2,%eax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    1278 <trmv_opt+0x178>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x28(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x3,%eax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    12ea <trmv_opt+0x1ea>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x28(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    12ef <trmv_opt+0x1ef>
mov    -0x28(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x28(%rbp)
jmp    1134 <trmv_opt+0x34>
movl   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
mov    -0x24(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
jge    14f5 <trmv_opt+0x3f5>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    -0x24(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
jge    13ea <trmv_opt+0x2ea>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x2,%eax
mov    -0x24(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
jge    1466 <trmv_opt+0x366>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x28(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x3,%eax
mov    -0x24(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
jge    14e2 <trmv_opt+0x3e2>
mov    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x28(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    14e7 <trmv_opt+0x3e7>
mov    -0x28(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x28(%rbp)
jmp    1304 <trmv_opt+0x204>
jmp    14fa <trmv_opt+0x3fa>
mov    -0x24(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x24(%rbp)
jmp    1121 <trmv_opt+0x21>
pop    %rbp
ret

x86 assembly (clang, -O2):
<trmv_opt>:
push   %rbx
test   %edi,%edi
jle    126d <trmv_opt+0x16d>
mov    %edi,%r8d
lea    (%rsi,%r8,8),%r10
mov    %r8,%r9
shl    $0x4,%r9
xor    %r11d,%r11d
jmp    112f <trmv_opt+0x2f>
nopl   0x0(%rax)
add    %r9,%rsi
add    %r9,%r10
cmp    %r8,%r11
jae    126d <trmv_opt+0x16d>
mov    %r11,%rax
or     $0x1,%rax
mov    $0x1,%edi
jmp    1154 <trmv_opt+0x54>
nopl   (%rax)
lea    0x4(%rdi),%rbx
add    $0x3,%rdi
cmp    %rax,%rdi
mov    %rbx,%rdi
jae    11d0 <trmv_opt+0xd0>
movsd  -0x8(%rsi,%rdi,8),%xmm0
mulsd  (%rdx,%r11,8),%xmm0
addsd  -0x8(%rcx,%rdi,8),%xmm0
movsd  %xmm0,-0x8(%rcx,%rdi,8)
cmp    %rax,%rdi
jae    1186 <trmv_opt+0x86>
movsd  (%rsi,%rdi,8),%xmm0
mulsd  (%rdx,%r11,8),%xmm0
addsd  (%rcx,%rdi,8),%xmm0
movsd  %xmm0,(%rcx,%rdi,8)
lea    0x1(%rdi),%rbx
cmp    %rax,%rbx
jae    11a7 <trmv_opt+0xa7>
movsd  0x8(%rsi,%rdi,8),%xmm0
mulsd  (%rdx,%r11,8),%xmm0
addsd  0x8(%rcx,%rdi,8),%xmm0
movsd  %xmm0,0x8(%rcx,%rdi,8)
lea    0x2(%rdi),%rbx
cmp    %rax,%rbx
jae    1140 <trmv_opt+0x40>
movsd  0x10(%rsi,%rdi,8),%xmm0
mulsd  (%rdx,%r11,8),%xmm0
addsd  0x10(%rcx,%rdi,8),%xmm0
movsd  %xmm0,0x10(%rcx,%rdi,8)
jmp    1140 <trmv_opt+0x40>
nopl   (%rax)
add    $0x2,%r11
mov    $0x1,%edi
jmp    11f4 <trmv_opt+0xf4>
nopl   0x0(%rax,%rax,1)
lea    0x4(%rdi),%rbx
add    $0x3,%rdi
cmp    %r11,%rdi
mov    %rbx,%rdi
jae    1120 <trmv_opt+0x20>
movsd  -0x8(%r10,%rdi,8),%xmm0
mulsd  (%rdx,%rax,8),%xmm0
addsd  -0x8(%rcx,%rdi,8),%xmm0
movsd  %xmm0,-0x8(%rcx,%rdi,8)
cmp    %r11,%rdi
jae    1226 <trmv_opt+0x126>
movsd  (%r10,%rdi,8),%xmm0
mulsd  (%rdx,%rax,8),%xmm0
addsd  (%rcx,%rdi,8),%xmm0
movsd  %xmm0,(%rcx,%rdi,8)
lea    0x1(%rdi),%rbx
cmp    %r11,%rbx
jae    1247 <trmv_opt+0x147>
movsd  0x8(%r10,%rdi,8),%xmm0
mulsd  (%rdx,%rax,8),%xmm0
addsd  0x8(%rcx,%rdi,8),%xmm0
movsd  %xmm0,0x8(%rcx,%rdi,8)
lea    0x2(%rdi),%rbx
cmp    %r11,%rbx
jae    11e0 <trmv_opt+0xe0>
movsd  0x10(%r10,%rdi,8),%xmm0
mulsd  (%rdx,%rax,8),%xmm0
addsd  0x10(%rcx,%rdi,8),%xmm0
movsd  %xmm0,0x10(%rcx,%rdi,8)
jmp    11e0 <trmv_opt+0xe0>
pop    %rbx
ret

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

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