char matrixSubtract(float **output, char outRows, char outCols, float **inputA,
                    char rowsA, char colsA, float **inputB, char rowsB,
                    char colsB) {
  char i = 0;
  char j = 0;
  if (!(outRows == rowsA && outRows == rowsB && outCols == colsA &&
        outCols == colsB)) {
    return 0;
  }
  for (i = 0; i < outRows; i++) {
    for (j = 0; j < outCols; j++) {
      output[i][j] = inputA[i][j] - inputB[i][j];
    }
  }
  return 1;
}


x86 assembly (clang, -O0):
<matrixSubtract>:
push   %rbp
mov    %rsp,%rbp
mov    %r8d,-0x3c(%rbp)
mov    %rcx,%rax
mov    -0x3c(%rbp),%ecx
mov    %rax,-0x38(%rbp)
mov    %edx,%eax
mov    -0x38(%rbp),%rdx
mov    %eax,-0x2c(%rbp)
mov    %esi,%eax
mov    -0x2c(%rbp),%esi
mov    %eax,-0x28(%rbp)
mov    %rdi,%r8
mov    -0x28(%rbp),%edi
mov    %r9b,%al
mov    0x20(%rbp),%r9b
mov    0x18(%rbp),%r9b
mov    0x10(%rbp),%r9
mov    %r8,-0x10(%rbp)
mov    %dil,-0x11(%rbp)
mov    %sil,-0x12(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %cl,-0x21(%rbp)
mov    %al,-0x22(%rbp)
movb   $0x0,-0x23(%rbp)
movb   $0x0,-0x24(%rbp)
movsbl -0x11(%rbp),%eax
movsbl -0x21(%rbp),%ecx
cmp    %ecx,%eax
jne    1196 <matrixSubtract+0x96>
movsbl -0x11(%rbp),%eax
movsbl 0x18(%rbp),%ecx
cmp    %ecx,%eax
jne    1196 <matrixSubtract+0x96>
movsbl -0x12(%rbp),%eax
movsbl -0x22(%rbp),%ecx
cmp    %ecx,%eax
jne    1196 <matrixSubtract+0x96>
movsbl -0x12(%rbp),%eax
movsbl 0x20(%rbp),%ecx
cmp    %ecx,%eax
je     119f <matrixSubtract+0x9f>
movb   $0x0,-0x1(%rbp)
jmp    122f <matrixSubtract+0x12f>
movb   $0x0,-0x23(%rbp)
movsbl -0x23(%rbp),%eax
movsbl -0x11(%rbp),%ecx
cmp    %ecx,%eax
jge    122b <matrixSubtract+0x12b>
movb   $0x0,-0x24(%rbp)
movsbl -0x24(%rbp),%eax
movsbl -0x12(%rbp),%ecx
cmp    %ecx,%eax
jge    1219 <matrixSubtract+0x119>
mov    -0x20(%rbp),%rax
movsbq -0x23(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movsbq -0x24(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    0x10(%rbp),%rax
movsbq -0x23(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movsbq -0x24(%rbp),%rcx
subss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
movsbq -0x23(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movsbq -0x24(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x24(%rbp),%al
add    $0x1,%al
mov    %al,-0x24(%rbp)
jmp    11b7 <matrixSubtract+0xb7>
jmp    121e <matrixSubtract+0x11e>
mov    -0x23(%rbp),%al
add    $0x1,%al
mov    %al,-0x23(%rbp)
jmp    11a3 <matrixSubtract+0xa3>
movb   $0x1,-0x1(%rbp)
movsbl -0x1(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<matrixSubtract>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rcx,-0x8(%rsp)
mov    %rdi,-0x10(%rsp)
xor    %eax,%eax
cmp    0x48(%rsp),%dl
jne    1393 <matrixSubtract+0x293>
cmp    %r9b,%dl
jne    1393 <matrixSubtract+0x293>
cmp    %r8b,%sil
jne    1393 <matrixSubtract+0x293>
cmp    0x40(%rsp),%sil
jne    1393 <matrixSubtract+0x293>
mov    $0x1,%al
test   %sil,%sil
jle    1393 <matrixSubtract+0x293>
mov    0x38(%rsp),%rcx
movzbl %sil,%edi
movzbl %dl,%r14d
mov    %r14d,%eax
and    $0xfffffffc,%eax
mov    %rax,-0x18(%rsp)
add    $0xfffffffffffffffc,%rax
mov    %rax,-0x20(%rsp)
shr    $0x2,%rax
add    $0x1,%rax
mov    %eax,%r13d
and    $0x3,%r13d
and    $0xfffffffffffffffc,%rax
mov    %rax,-0x30(%rsp)
mov    %r14d,%r12d
and    $0x3,%r12d
mov    %r13,-0x28(%rsp)
shl    $0x4,%r13
xor    %r8d,%r8d
jmp    11ad <matrixSubtract+0xad>
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%r8
cmp    %rdi,%r8
je     1391 <matrixSubtract+0x291>
test   %dl,%dl
jle    11a0 <matrixSubtract+0xa0>
mov    -0x8(%rsp),%rax
mov    (%rax,%r8,8),%rbp
mov    (%rcx,%r8,8),%r11
mov    -0x10(%rsp),%rax
mov    (%rax,%r8,8),%rax
cmp    $0x4,%dl
jb     1220 <matrixSubtract+0x120>
lea    (%rax,%r14,4),%rsi
lea    0x0(,%r14,4),%rbx
add    %rbp,%rbx
lea    (%r11,%r14,4),%r10
cmp    %rbx,%rax
setb   %r15b
cmp    %rsi,%rbp
setb   %r9b
cmp    %r10,%rax
setb   %bl
cmp    %rsi,%r11
setb   %sil
test   %r9b,%r15b
jne    1220 <matrixSubtract+0x120>
mov    $0x0,%r10d
and    %sil,%bl
jne    1223 <matrixSubtract+0x123>
cmpq   $0xc,-0x20(%rsp)
jae    12d0 <matrixSubtract+0x1d0>
xor    %ebx,%ebx
jmp    1334 <matrixSubtract+0x234>
nopl   (%rax)
xor    %r10d,%r10d
mov    %r10,%rsi
not    %rsi
add    %r14,%rsi
test   %r12,%r12
je     125d <matrixSubtract+0x15d>
mov    %r12,%rbx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movss  0x0(%rbp,%r10,4),%xmm0
subss  (%r11,%r10,4),%xmm0
movss  %xmm0,(%rax,%r10,4)
add    $0x1,%r10
add    $0xffffffffffffffff,%rbx
jne    1240 <matrixSubtract+0x140>
cmp    $0x3,%rsi
jb     11a0 <matrixSubtract+0xa0>
nopw   0x0(%rax,%rax,1)
movss  0x0(%rbp,%r10,4),%xmm0
subss  (%r11,%r10,4),%xmm0
movss  %xmm0,(%rax,%r10,4)
movss  0x4(%rbp,%r10,4),%xmm0
subss  0x4(%r11,%r10,4),%xmm0
movss  %xmm0,0x4(%rax,%r10,4)
movss  0x8(%rbp,%r10,4),%xmm0
subss  0x8(%r11,%r10,4),%xmm0
movss  %xmm0,0x8(%rax,%r10,4)
movss  0xc(%rbp,%r10,4),%xmm0
subss  0xc(%r11,%r10,4),%xmm0
movss  %xmm0,0xc(%rax,%r10,4)
add    $0x4,%r10
cmp    %r10,%r14
jne    1270 <matrixSubtract+0x170>
jmp    11a0 <matrixSubtract+0xa0>
mov    -0x30(%rsp),%rsi
xor    %ebx,%ebx
nopw   0x0(%rax,%rax,1)
movups 0x0(%rbp,%rbx,4),%xmm0
movups (%r11,%rbx,4),%xmm1
subps  %xmm1,%xmm0
movups %xmm0,(%rax,%rbx,4)
movups 0x10(%rbp,%rbx,4),%xmm0
movups 0x10(%r11,%rbx,4),%xmm1
subps  %xmm1,%xmm0
movups %xmm0,0x10(%rax,%rbx,4)
movups 0x20(%rbp,%rbx,4),%xmm0
movups 0x20(%r11,%rbx,4),%xmm1
subps  %xmm1,%xmm0
movups %xmm0,0x20(%rax,%rbx,4)
movups 0x30(%rbp,%rbx,4),%xmm0
movups 0x30(%r11,%rbx,4),%xmm1
subps  %xmm1,%xmm0
movups %xmm0,0x30(%rax,%rbx,4)
add    $0x10,%rbx
add    $0xfffffffffffffffc,%rsi
jne    12e0 <matrixSubtract+0x1e0>
cmpq   $0x0,-0x28(%rsp)
je     137b <matrixSubtract+0x27b>
lea    (%rax,%rbx,4),%r10
lea    (%r11,%rbx,4),%rsi
lea    0x0(,%rbx,4),%rbx
add    %rbp,%rbx
xor    %r15d,%r15d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movups (%rbx,%r15,1),%xmm0
movups (%rsi,%r15,1),%xmm1
subps  %xmm1,%xmm0
movups %xmm0,(%r10,%r15,1)
add    $0x10,%r15
cmp    %r15,%r13
jne    1360 <matrixSubtract+0x260>
mov    -0x18(%rsp),%rsi
mov    %rsi,%r10
cmp    %r14,%rsi
je     11a0 <matrixSubtract+0xa0>
jmp    1223 <matrixSubtract+0x123>
mov    $0x1,%al
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define signext i8 @matrixSubtract(float** %0, i8 signext %1, i8 signext %2, float** %3, i8 signext %4, i8 signext %5, float** %6, i8 signext %7, i8 signext %8) {
%10 = alloca i8
%11 = alloca float**
%12 = alloca i8
%13 = alloca i8
%14 = alloca float**
%15 = alloca i8
%16 = alloca i8
%17 = alloca float**
%18 = alloca i8
%19 = alloca i8
%20 = alloca i8
%21 = alloca i8
store float** %0, float*** %11
store i8 %1, i8* %12
store i8 %2, i8* %13
store float** %3, float*** %14
store i8 %4, i8* %15
store i8 %5, i8* %16
store float** %6, float*** %17
store i8 %7, i8* %18
store i8 %8, i8* %19
store i8 0, i8* %20
store i8 0, i8* %21
%22 = load i8, i8* %12
%23 = sext i8 %22 to i32
%24 = load i8, i8* %15
%25 = sext i8 %24 to i32
%26 = icmp eq i32 %23, %25
br i1 %26, label %27, label %45
27: ; preds = %9
%28 = load i8, i8* %12
%29 = sext i8 %28 to i32
%30 = load i8, i8* %18
%31 = sext i8 %30 to i32
%32 = icmp eq i32 %29, %31
br i1 %32, label %33, label %45
33: ; preds = %27
%34 = load i8, i8* %13
%35 = sext i8 %34 to i32
%36 = load i8, i8* %16
%37 = sext i8 %36 to i32
%38 = icmp eq i32 %35, %37
br i1 %38, label %39, label %45
39: ; preds = %33
%40 = load i8, i8* %13
%41 = sext i8 %40 to i32
%42 = load i8, i8* %19
%43 = sext i8 %42 to i32
%44 = icmp eq i32 %41, %43
br i1 %44, label %46, label %45
45: ; preds = %39, %33, %27, %9
store i8 0, i8* %10
br label %96
46: ; preds = %39
store i8 0, i8* %20
br label %47
47: ; preds = %92, %46
%48 = load i8, i8* %20
%49 = sext i8 %48 to i32
%50 = load i8, i8* %12
%51 = sext i8 %50 to i32
%52 = icmp slt i32 %49, %51
br i1 %52, label %53, label %95
53: ; preds = %47
store i8 0, i8* %21
br label %54
54: ; preds = %88, %53
%55 = load i8, i8* %21
%56 = sext i8 %55 to i32
%57 = load i8, i8* %13
%58 = sext i8 %57 to i32
%59 = icmp slt i32 %56, %58
br i1 %59, label %60, label %91
60: ; preds = %54
%61 = load float**, float*** %14
%62 = load i8, i8* %20
%63 = sext i8 %62 to i64
%64 = getelementptr inbounds float*, float** %61, i64 %63
%65 = load float*, float** %64
%66 = load i8, i8* %21
%67 = sext i8 %66 to i64
%68 = getelementptr inbounds float, float* %65, i64 %67
%69 = load float, float* %68
%70 = load float**, float*** %17
%71 = load i8, i8* %20
%72 = sext i8 %71 to i64
%73 = getelementptr inbounds float*, float** %70, i64 %72
%74 = load float*, float** %73
%75 = load i8, i8* %21
%76 = sext i8 %75 to i64
%77 = getelementptr inbounds float, float* %74, i64 %76
%78 = load float, float* %77
%79 = fsub float %69, %78
%80 = load float**, float*** %11
%81 = load i8, i8* %20
%82 = sext i8 %81 to i64
%83 = getelementptr inbounds float*, float** %80, i64 %82
%84 = load float*, float** %83
%85 = load i8, i8* %21
%86 = sext i8 %85 to i64
%87 = getelementptr inbounds float, float* %84, i64 %86
store float %79, float* %87
br label %88
88: ; preds = %60
%89 = load i8, i8* %21
%90 = add i8 %89, 1
store i8 %90, i8* %21
br label %54
91: ; preds = %54
br label %92
92: ; preds = %91
%93 = load i8, i8* %20
%94 = add i8 %93, 1
store i8 %94, i8* %20
br label %47
95: ; preds = %47
store i8 1, i8* %10
br label %96
96: ; preds = %95, %45
%97 = load i8, i8* %10
ret i8 %97
}

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