void LU_decomp(int const n, int const lda, double *const A) {
  int i, j, k;
  for (k = 0; k < n; k++) {
    double *const Ak = A + k * lda;
#pragma omp parallel for private(j)
    for (i = k + 1; i < n; i++) {
      double *const Ai = A + i * lda;
      Ai[k] /= Ak[k];
      for (j = k + 1; j < n; j++)
        Ai[j] -= Ai[k] * Ak[j];
    }
  }
}


x86 assembly (clang, -O0):
<LU_decomp>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %rdx,-0x10(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    121f <LU_decomp+0x11f>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
imul   -0x8(%rbp),%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    120c <LU_decomp+0x10c>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
imul   -0x8(%rbp),%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x30(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11f9 <LU_decomp+0xf9>
mov    -0x30(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x30(%rbp),%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movq   %xmm0,%rdx
movabs $0x8000000000000000,%rsi
xor    %rsi,%rdx
movq   %rdx,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1194 <LU_decomp+0x94>
jmp    11fe <LU_decomp+0xfe>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1143 <LU_decomp+0x43>
jmp    1211 <LU_decomp+0x111>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1115 <LU_decomp+0x15>
pop    %rbp
ret

x86 assembly (clang, -O2):
<LU_decomp>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x50,%rsp
test   %edi,%edi
jle    1496 <LU_decomp+0x396>
movslq %esi,%rax
mov    %edi,%ecx
lea    0x2(%rax),%rsi
mov    %rsi,0x10(%rsp)
lea    0x0(,%rax,8),%rsi
mov    %rsi,-0x38(%rsp)
lea    0x8(,%rax,8),%rsi
mov    %rsi,-0x48(%rsp)
lea    (%rax,%rcx,1),%rsi
mov    %rsi,-0x20(%rsp)
lea    0x1(%rax),%rsi
mov    %rsi,0x8(%rsp)
mov    %rdx,%r15
lea    0x10(%rdx),%rsi
mov    %rsi,-0x28(%rsp)
lea    -0x2(%rcx),%rsi
mov    %rcx,%rdi
neg    %rdi
mov    %rdi,0x40(%rsp)
lea    0x20(%rdx),%r12
lea    (%rdx,%rax,8),%rdi
add    $0x20,%rdi
mov    %rdi,-0x50(%rsp)
mov    %rax,-0x68(%rsp)
lea    (%rdx,%rax,8),%rax
mov    %rax,-0x58(%rsp)
mov    $0x1,%eax
mov    %rax,-0x70(%rsp)
xor    %r11d,%r11d
movapd 0xe61(%rip),%xmm0
mov    %rsi,-0x30(%rsp)
mov    %rsi,-0x60(%rsp)
jmp    11e4 <LU_decomp+0xe4>
nopl   0x0(%rax,%rax,1)
addq   $0x1,-0x70(%rsp)
addq   $0xffffffffffffffff,-0x60(%rsp)
mov    -0x48(%rsp),%rax
add    %rax,%r12
add    %rax,-0x50(%rsp)
mov    -0x38(%rsp),%rax
add    %rax,-0x58(%rsp)
add    %rax,%r15
mov    -0x18(%rsp),%r11
cmp    %rcx,%r11
je     1496 <LU_decomp+0x396>
lea    0x1(%r11),%rax
mov    %rax,-0x18(%rsp)
cmp    %rcx,%rax
jae    11b0 <LU_decomp+0xb0>
mov    -0x60(%rsp),%rax
and    $0xfffffffffffffffc,%rax
mov    %rax,(%rsp)
mov    -0x30(%rsp),%rbx
sub    %r11,%rbx
mov    -0x48(%rsp),%rdi
imul   %r11,%rdi
mov    %r11,%rax
imul   -0x68(%rsp),%rax
mov    -0x20(%rsp),%rsi
add    %rax,%rsi
mov    %rsi,0x30(%rsp)
mov    -0x28(%rsp),%rsi
mov    %rdi,0x38(%rsp)
lea    (%rsi,%rdi,1),%rsi
mov    %rsi,0x28(%rsp)
lea    (%rax,%rcx,1),%rdi
mov    %rdx,%rsi
lea    (%rdx,%rdi,8),%rdi
mov    %rdi,0x20(%rsp)
lea    (%rdx,%rax,8),%r14
mov    -0x70(%rsp),%rbp
lea    0x1(%rbp),%rax
mov    %rax,-0x80(%rsp)
mov    %rbx,-0x40(%rsp)
and    $0xfffffffffffffffc,%rbx
mov    %rbx,-0x8(%rsp)
lea    (%rbx,%rbp,1),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rsp)
mov    -0x58(%rsp),%r10
mov    -0x50(%rsp),%rbx
xor    %r8d,%r8d
mov    %r14,0x18(%rsp)
jmp    12ac <LU_decomp+0x1ac>
nopw   0x0(%rax,%rax,1)
add    $0x1,%rbp
add    $0x1,%r8
mov    -0x38(%rsp),%rax
add    %rax,%rbx
add    %rax,%r10
cmp    %rcx,%rbp
je     11b0 <LU_decomp+0xb0>
mov    %rbp,%rax
imul   -0x68(%rsp),%rax
lea    (%rdx,%rax,8),%rax
movsd  (%rax,%r11,8),%xmm1
divsd  (%r14,%r11,8),%xmm1
movsd  %xmm1,(%rax,%r11,8)
mov    -0x70(%rsp),%rsi
mulsd  (%r14,%rsi,8),%xmm1
movsd  (%rax,%rsi,8),%xmm2
subsd  %xmm1,%xmm2
movsd  %xmm2,(%rax,%rsi,8)
cmp    %rcx,-0x80(%rsp)
je     1290 <LU_decomp+0x190>
mov    -0x80(%rsp),%r9
cmpq   $0x4,-0x40(%rsp)
jae    1390 <LU_decomp+0x290>
mov    %ecx,%esi
sub    %r9d,%esi
mov    %r9,%r13
test   $0x1,%sil
je     132a <LU_decomp+0x22a>
movsd  (%rax,%r11,8),%xmm1
mulsd  (%r14,%r9,8),%xmm1
movsd  (%rax,%r9,8),%xmm2
subsd  %xmm1,%xmm2
movsd  %xmm2,(%rax,%r9,8)
lea    0x1(%r9),%r13
not    %r9
cmp    0x40(%rsp),%r9
je     1290 <LU_decomp+0x190>
nopl   0x0(%rax,%rax,1)
movsd  (%rax,%r11,8),%xmm1
mulsd  (%r15,%r13,8),%xmm1
movsd  (%r10,%r13,8),%xmm2
subsd  %xmm1,%xmm2
movsd  0x8(%r10,%r13,8),%xmm1
movsd  %xmm2,(%r10,%r13,8)
movsd  (%rax,%r11,8),%xmm2
mulsd  0x8(%r15,%r13,8),%xmm2
subsd  %xmm2,%xmm1
movsd  %xmm1,0x8(%r10,%r13,8)
add    $0x2,%r13
cmp    %r13,%rcx
jne    1340 <LU_decomp+0x240>
jmp    1290 <LU_decomp+0x190>
nopl   0x0(%rax)
mov    %r8,%rdi
mov    -0x68(%rsp),%r13
imul   %r13,%rdi
mov    0x10(%rsp),%rsi
add    %rdi,%rsi
lea    (%rdx,%rsi,8),%rsi
mov    %rsi,-0x78(%rsp)
mov    0x38(%rsp),%r14
add    %r14,%rsi
mov    %rsi,0x48(%rsp)
mov    0x30(%rsp),%rsi
add    %rdi,%rsi
lea    (%rdi,%r13,1),%r9
lea    (%rdx,%r9,8),%r9
add    %r14,%r9
mov    0x18(%rsp),%r14
add    0x8(%rsp),%rdi
lea    (%rdx,%rsi,8),%r13
lea    (%rdx,%rdi,8),%rdi
cmp    %rdi,-0x78(%rsp)
setb   -0x78(%rsp)
cmp    %r13,%r9
mov    %rdx,%rsi
setb   %dl
mov    0x48(%rsp),%rdi
cmp    0x20(%rsp),%rdi
setb   %dil
cmp    %r13,0x28(%rsp)
setb   %r13b
mov    -0x80(%rsp),%r9
test   %dl,-0x78(%rsp)
mov    %rsi,%rdx
jne    12fc <LU_decomp+0x1fc>
mov    -0x80(%rsp),%r9
and    %r13b,%dil
jne    12fc <LU_decomp+0x1fc>
movsd  (%rax,%r11,8),%xmm1
unpcklpd %xmm1,%xmm1
xorpd  %xmm0,%xmm1
xor    %edi,%edi
mov    (%rsp),%rsi
nopl   (%rax)
movupd -0x10(%r12,%rdi,8),%xmm2
movupd (%r12,%rdi,8),%xmm3
movupd -0x10(%rbx,%rdi,8),%xmm4
movupd (%rbx,%rdi,8),%xmm5
mulpd  %xmm1,%xmm2
addpd  %xmm4,%xmm2
mulpd  %xmm1,%xmm3
addpd  %xmm5,%xmm3
movupd %xmm2,-0x10(%rbx,%rdi,8)
movupd %xmm3,(%rbx,%rdi,8)
add    $0x4,%rdi
cmp    %rdi,%rsi
jne    1440 <LU_decomp+0x340>
mov    -0x10(%rsp),%r9
mov    -0x8(%rsp),%rsi
cmp    %rsi,-0x40(%rsp)
je     1290 <LU_decomp+0x190>
jmp    12fc <LU_decomp+0x1fc>
add    $0x50,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @LU_decomp(i32 %0, i32 %1, double* %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca double*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca double*
%11 = alloca double*
store i32 %0, i32* %4
store i32 %1, i32* %5
store double* %2, double** %6
store i32 0, i32* %9
br label %12
12: ; preds = %79, %3
%13 = load i32, i32* %9
%14 = load i32, i32* %4
%15 = icmp slt i32 %13, %14
br i1 %15, label %16, label %82
16: ; preds = %12
%17 = load double*, double** %6
%18 = load i32, i32* %9
%19 = load i32, i32* %5
%20 = mul nsw i32 %18, %19
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds double, double* %17, i64 %21
store double* %22, double** %10
%23 = load i32, i32* %9
%24 = add nsw i32 %23, 1
store i32 %24, i32* %7
br label %25
25: ; preds = %75, %16
%26 = load i32, i32* %7
%27 = load i32, i32* %4
%28 = icmp slt i32 %26, %27
br i1 %28, label %29, label %78
29: ; preds = %25
%30 = load double*, double** %6
%31 = load i32, i32* %7
%32 = load i32, i32* %5
%33 = mul nsw i32 %31, %32
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds double, double* %30, i64 %34
store double* %35, double** %11
%36 = load double*, double** %10
%37 = load i32, i32* %9
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds double, double* %36, i64 %38
%40 = load double, double* %39
%41 = load double*, double** %11
%42 = load i32, i32* %9
%43 = sext i32 %42 to i64
%44 = getelementptr inbounds double, double* %41, i64 %43
%45 = load double, double* %44
%46 = fdiv double %45, %40
store double %46, double* %44
%47 = load i32, i32* %9
%48 = add nsw i32 %47, 1
store i32 %48, i32* %8
br label %49
49: ; preds = %71, %29
%50 = load i32, i32* %8
%51 = load i32, i32* %4
%52 = icmp slt i32 %50, %51
br i1 %52, label %53, label %74
53: ; preds = %49
%54 = load double*, double** %11
%55 = load i32, i32* %9
%56 = sext i32 %55 to i64
%57 = getelementptr inbounds double, double* %54, i64 %56
%58 = load double, double* %57
%59 = load double*, double** %10
%60 = load i32, i32* %8
%61 = sext i32 %60 to i64
%62 = getelementptr inbounds double, double* %59, i64 %61
%63 = load double, double* %62
%64 = load double*, double** %11
%65 = load i32, i32* %8
%66 = sext i32 %65 to i64
%67 = getelementptr inbounds double, double* %64, i64 %66
%68 = load double, double* %67
%69 = fneg double %58
%70 = call double @llvm.fmuladd.f64(double %69, double %63, double %68)
store double %70, double* %67
br label %71
71: ; preds = %53
%72 = load i32, i32* %8
%73 = add nsw i32 %72, 1
store i32 %73, i32* %8
br label %49
74: ; preds = %49
br label %75
75: ; preds = %74
%76 = load i32, i32* %7
%77 = add nsw i32 %76, 1
store i32 %77, i32* %7
br label %25
78: ; preds = %25
br label %79
79: ; preds = %78
%80 = load i32, i32* %9
%81 = add nsw i32 %80, 1
store i32 %81, i32* %9
br label %12
82: ; preds = %12
ret void
}

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