void lin_hgN(const double *u, double *p, const int *inl, int len, double *A1,
             double *A2) {
  const double *s;
  double a[3], b[3];
  int i, j;
  a[2] = 1;
  b[2] = 1;
  for (i = 0; i < len; i++) {
    s = u + 6 * inl[i];
    a[0] = *(s)*A1[0] + A1[1];
    a[1] = *(s + 1) * A1[0] + A1[2];
    b[0] = *(s + 3) * A2[0] + A2[1];
    b[1] = *(s + 4) * A2[0] + A2[2];
    for (j = 0; j < 3; j++, p += 3)
      *p = b[j];
    p -= 8;
    for (j = 0; j < 3; j++, p += 3)
      *p = 0;
    p -= 8;
    for (j = 0; j < 3; j++, p += 3)
      *p = -a[0] * b[j];
    p -= 2;
    for (j = 0; j < 3; j++, p += 3)
      *p = 0;
    p -= 8;
    for (j = 0; j < 3; j++, p += 3)
      *p = b[j];
    p -= 8;
    for (j = 0; j < 3; j++, p += 3)
      *p = -a[1] * b[j];
    p -= 2;
  }
}


x86 assembly (clang, -O0):
<lin_hgN>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
movsd  0xedd(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xed0(%rip),%xmm0
movsd  %xmm0,-0x60(%rbp)
movl   $0x0,-0x74(%rbp)
mov    -0x74(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    13ef <lin_hgN+0x2ef>
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%rcx
movslq -0x74(%rbp),%rdx
imul   $0x6,(%rcx,%rdx,4),%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x38(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
movsd  0x10(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x38(%rbp),%rax
movsd  0x18(%rax),%xmm0
mov    -0x30(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x30(%rbp),%rax
movsd  0x8(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x38(%rbp),%rax
movsd  0x20(%rax),%xmm0
mov    -0x30(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x30(%rbp),%rax
movsd  0x10(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movl   $0x0,-0x78(%rbp)
cmpl   $0x3,-0x78(%rbp)
jge    123e <lin_hgN+0x13e>
movslq -0x78(%rbp),%rax
movsd  -0x70(%rbp,%rax,8),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x78(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x10(%rbp)
jmp    1208 <lin_hgN+0x108>
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffc0,%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x78(%rbp)
cmpl   $0x3,-0x78(%rbp)
jge    1280 <lin_hgN+0x180>
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax)
mov    -0x78(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x10(%rbp)
jmp    1251 <lin_hgN+0x151>
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffc0,%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x78(%rbp)
cmpl   $0x3,-0x78(%rbp)
jge    12e5 <lin_hgN+0x1e5>
movsd  -0x50(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movslq -0x78(%rbp),%rax
mulsd  -0x70(%rbp,%rax,8),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x78(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x10(%rbp)
jmp    1293 <lin_hgN+0x193>
mov    -0x10(%rbp),%rax
add    $0xfffffffffffffff0,%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x78(%rbp)
cmpl   $0x3,-0x78(%rbp)
jge    1327 <lin_hgN+0x227>
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax)
mov    -0x78(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x10(%rbp)
jmp    12f8 <lin_hgN+0x1f8>
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffc0,%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x78(%rbp)
cmpl   $0x3,-0x78(%rbp)
jge    1370 <lin_hgN+0x270>
movslq -0x78(%rbp),%rax
movsd  -0x70(%rbp,%rax,8),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x78(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x10(%rbp)
jmp    133a <lin_hgN+0x23a>
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffc0,%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x78(%rbp)
cmpl   $0x3,-0x78(%rbp)
jge    13d5 <lin_hgN+0x2d5>
movsd  -0x48(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movslq -0x78(%rbp),%rax
mulsd  -0x70(%rbp,%rax,8),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x78(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x10(%rbp)
jmp    1383 <lin_hgN+0x283>
mov    -0x10(%rbp),%rax
add    $0xfffffffffffffff0,%rax
mov    %rax,-0x10(%rbp)
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
jmp    113c <lin_hgN+0x3c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<lin_hgN>:
test   %ecx,%ecx
jle    120d <lin_hgN+0x10d>
mov    %ecx,%r10d
xor    %ecx,%ecx
movsd  0xeeb(%rip),%xmm0
movapd 0xef3(%rip),%xmm1
xorps  %xmm2,%xmm2
movhps 0xed9(%rip),%xmm2
nopw   0x0(%rax,%rax,1)
movslq (%rdx,%rcx,4),%rax
lea    (%rax,%rax,2),%rax
shl    $0x4,%rax
movsd  (%r8),%xmm3
movsd  (%r9),%xmm4
movsd  0x18(%rdi,%rax,1),%xmm5
mulsd  %xmm4,%xmm5
addsd  0x8(%r9),%xmm5
mulsd  0x20(%rdi,%rax,1),%xmm4
addsd  0x10(%r9),%xmm4
movsd  (%rdi,%rax,1),%xmm6
mulsd  %xmm3,%xmm6
addsd  0x8(%r8),%xmm6
mulsd  0x8(%rdi,%rax,1),%xmm3
addsd  0x10(%r8),%xmm3
movsd  %xmm5,(%rsi)
movsd  %xmm4,0x18(%rsi)
movq   $0x0,0x8(%rsi)
movq   $0x0,0x20(%rsi)
movups %xmm0,0x30(%rsi)
xorpd  %xmm1,%xmm6
movapd %xmm5,%xmm7
mulsd  %xmm6,%xmm7
movsd  %xmm7,0x10(%rsi)
movapd %xmm4,%xmm7
mulsd  %xmm6,%xmm7
movsd  %xmm7,0x28(%rsi)
movlpd %xmm6,0x40(%rsi)
movq   $0x0,0x48(%rsi)
movq   $0x0,0x60(%rsi)
movsd  %xmm5,0x50(%rsi)
movsd  %xmm4,0x68(%rsi)
movups %xmm2,0x78(%rsi)
xorpd  %xmm1,%xmm3
mulsd  %xmm3,%xmm5
movsd  %xmm5,0x58(%rsi)
mulsd  %xmm3,%xmm4
movsd  %xmm4,0x70(%rsi)
movlpd %xmm3,0x88(%rsi)
add    $0x1,%rcx
add    $0x90,%rsi
cmp    %rcx,%r10
jne    1130 <lin_hgN+0x30>
ret

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

LLVM IR (-O2):
define void @lin_hgN(double* nocapture %0, double* nocapture writeonly %1, i32* nocapture %2, i32 %3, double* nocapture %4, double* nocapture %5) {
%7 = icmp sgt i32 %3, 0
br i1 %7, label %8, label %65
8: ; preds = %6
%9 = getelementptr inbounds double, double* %4, i64 1
%10 = getelementptr inbounds double, double* %4, i64 2
%11 = getelementptr inbounds double, double* %5, i64 1
%12 = getelementptr inbounds double, double* %5, i64 2
%13 = zext i32 %3 to i64
br label %14
14: ; preds = %8, %14
%15 = phi i64 [ 0, %8 ], [ %63, %14 ]
%16 = phi double* [ %1, %8 ], [ %62, %14 ]
%17 = getelementptr inbounds i32, i32* %2, i64 %15
%18 = load i32, i32* %17
%19 = mul nsw i32 %18, 6
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds double, double* %0, i64 %20
%22 = load double, double* %21
%23 = load double, double* %4
%24 = load double, double* %9
%25 = getelementptr inbounds double, double* %21, i64 1
%26 = load double, double* %25
%27 = load double, double* %10
%28 = getelementptr inbounds double, double* %21, i64 3
%29 = load double, double* %28
%30 = load double, double* %5
%31 = load double, double* %11
%32 = tail call double @llvm.fmuladd.f64(double %29, double %30, double %31)
%33 = getelementptr inbounds double, double* %21, i64 4
%34 = load double, double* %33
%35 = load double, double* %12
%36 = tail call double @llvm.fmuladd.f64(double %34, double %30, double %35)
store double %32, double* %16
%37 = getelementptr inbounds double, double* %16, i64 3
store double %36, double* %37
%38 = getelementptr inbounds double, double* %16, i64 6
%39 = tail call double @llvm.fmuladd.f64(double %22, double %23, double %24)
%40 = getelementptr inbounds double, double* %16, i64 1
store double 0.000000e+00, double* %40
%41 = getelementptr inbounds double, double* %16, i64 4
store double 0.000000e+00, double* %41
%42 = bitcast double* %38 to <2 x double>*
store <2 x double> <double 1.000000e+00, double 0.000000e+00>, <2 x double>* %42
%43 = getelementptr inbounds double, double* %16, i64 2
%44 = fneg double %39
%45 = fmul double %32, %44
store double %45, double* %43
%46 = getelementptr inbounds double, double* %16, i64 5
%47 = fmul double %36, %44
store double %47, double* %46
%48 = getelementptr inbounds double, double* %16, i64 8
store double %44, double* %48
%49 = getelementptr inbounds double, double* %16, i64 9
store double 0.000000e+00, double* %49
%50 = getelementptr inbounds double, double* %16, i64 12
store double 0.000000e+00, double* %50
%51 = getelementptr inbounds double, double* %16, i64 15
%52 = getelementptr inbounds double, double* %16, i64 10
store double %32, double* %52
%53 = getelementptr inbounds double, double* %16, i64 13
store double %36, double* %53
%54 = bitcast double* %51 to <2 x double>*
store <2 x double> <double 0.000000e+00, double 1.000000e+00>, <2 x double>* %54
%55 = tail call double @llvm.fmuladd.f64(double %26, double %23, double %27)
%56 = getelementptr inbounds double, double* %16, i64 11
%57 = fneg double %55
%58 = fmul double %32, %57
store double %58, double* %56
%59 = getelementptr inbounds double, double* %16, i64 14
%60 = fmul double %36, %57
store double %60, double* %59
%61 = getelementptr inbounds double, double* %16, i64 17
store double %57, double* %61
%62 = getelementptr inbounds double, double* %16, i64 18
%63 = add nuw nsw i64 %15, 1
%64 = icmp eq i64 %63, %13
br i1 %64, label %65, label %14
65: ; preds = %14, %6
ret void
}