void kernel_dgecp_1_0_lib4(int tri, int kmax, double *A, double *B) {
  if (tri == 1) {
    kmax += 1;
  }
  if (kmax <= 0)
    return;
  const int bs = 4;
  int k;
  for (k = 0; k < kmax - 3; k += 4) {
    B[0 + bs * 0] = A[0 + bs * 0];
    B[0 + bs * 1] = A[0 + bs * 1];
    B[0 + bs * 2] = A[0 + bs * 2];
    B[0 + bs * 3] = A[0 + bs * 3];
    A += 16;
    B += 16;
  }
  for (; k < kmax; k++) {
    B[0 + bs * 0] = A[0 + bs * 0];
    A += 4;
    B += 4;
  }
}


x86 assembly (clang, -O0):
<kernel_dgecp_1_0_lib4>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %rdx,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
cmpl   $0x1,-0x4(%rbp)
jne    1125 <kernel_dgecp_1_0_lib4+0x25>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
cmpl   $0x0,-0x8(%rbp)
jg     1134 <kernel_dgecp_1_0_lib4+0x34>
jmp    120a <kernel_dgecp_1_0_lib4+0x10a>
movl   $0x4,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    -0x8(%rbp),%ecx
sub    $0x3,%ecx
cmp    %ecx,%eax
jge    11c3 <kernel_dgecp_1_0_lib4+0xc3>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x10(%rbp),%rax
movsd  0x20(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x20(%rax)
mov    -0x10(%rbp),%rax
movsd  0x40(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x40(%rax)
mov    -0x10(%rbp),%rax
movsd  0x60(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x60(%rax)
mov    -0x10(%rbp),%rax
add    $0x80,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x80,%rax
mov    %rax,-0x18(%rbp)
mov    -0x20(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x20(%rbp)
jmp    1142 <kernel_dgecp_1_0_lib4+0x42>
jmp    11c8 <kernel_dgecp_1_0_lib4+0xc8>
mov    -0x20(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    120a <kernel_dgecp_1_0_lib4+0x10a>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x10(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x18(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    11c8 <kernel_dgecp_1_0_lib4+0xc8>
pop    %rbp
ret

x86 assembly (clang, -O2):
<kernel_dgecp_1_0_lib4>:
xor    %eax,%eax
cmp    $0x1,%edi
sete   %al
add    %esi,%eax
test   %eax,%eax
jle    1236 <kernel_dgecp_1_0_lib4+0x136>
xor    %esi,%esi
cmp    $0x4,%eax
jb     1155 <kernel_dgecp_1_0_lib4+0x55>
lea    -0x3(%rax),%edi
xor    %esi,%esi
xchg   %ax,%ax
movsd  (%rdx),%xmm0
movsd  %xmm0,(%rcx)
movsd  0x20(%rdx),%xmm0
movsd  %xmm0,0x20(%rcx)
movsd  0x40(%rdx),%xmm0
movsd  %xmm0,0x40(%rcx)
movsd  0x60(%rdx),%xmm0
movsd  %xmm0,0x60(%rcx)
sub    $0xffffffffffffff80,%rdx
sub    $0xffffffffffffff80,%rcx
add    $0x4,%esi
cmp    %edi,%esi
jl     1120 <kernel_dgecp_1_0_lib4+0x20>
cmp    %eax,%esi
jge    1236 <kernel_dgecp_1_0_lib4+0x136>
mov    %eax,%r9d
sub    %esi,%r9d
mov    %esi,%r8d
not    %r8d
add    %eax,%r8d
and    $0x7,%r9d
je     119a <kernel_dgecp_1_0_lib4+0x9a>
neg    %r9d
xor    %edi,%edi
nopw   0x0(%rax,%rax,1)
movsd  (%rdx),%xmm0
movsd  %xmm0,(%rcx)
add    $0x20,%rdx
add    $0x20,%rcx
add    $0xffffffff,%edi
cmp    %edi,%r9d
jne    1180 <kernel_dgecp_1_0_lib4+0x80>
sub    %edi,%esi
cmp    $0x7,%r8d
jb     1236 <kernel_dgecp_1_0_lib4+0x136>
sub    %esi,%eax
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
movsd  (%rdx,%rsi,1),%xmm0
movsd  %xmm0,(%rcx,%rsi,1)
movsd  0x20(%rdx,%rsi,1),%xmm0
movsd  %xmm0,0x20(%rcx,%rsi,1)
movsd  0x40(%rdx,%rsi,1),%xmm0
movsd  %xmm0,0x40(%rcx,%rsi,1)
movsd  0x60(%rdx,%rsi,1),%xmm0
movsd  %xmm0,0x60(%rcx,%rsi,1)
movsd  0x80(%rdx,%rsi,1),%xmm0
movsd  %xmm0,0x80(%rcx,%rsi,1)
movsd  0xa0(%rdx,%rsi,1),%xmm0
movsd  %xmm0,0xa0(%rcx,%rsi,1)
movsd  0xc0(%rdx,%rsi,1),%xmm0
movsd  %xmm0,0xc0(%rcx,%rsi,1)
movsd  0xe0(%rdx,%rsi,1),%xmm0
movsd  %xmm0,0xe0(%rcx,%rsi,1)
add    $0x100,%rsi
add    $0xfffffff8,%eax
jne    11b0 <kernel_dgecp_1_0_lib4+0xb0>
ret

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

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