shear(a, dir, u, v) double a[4][4], u, v;
char dir;
{
  if (dir == 'x') {
    a[0][1] += u * a[0][0];
    a[1][1] += u * a[1][0];
    a[2][1] += u * a[2][0];
    a[3][1] += u * a[3][0];
    a[0][2] += v * a[0][0];
    a[1][2] += v * a[1][0];
    a[2][2] += v * a[2][0];
    a[3][2] += v * a[3][0];
  } else if (dir == 'y') {
    a[0][0] += u * a[0][1];
    a[1][0] += u * a[1][1];
    a[2][0] += u * a[2][1];
    a[3][0] += u * a[3][1];
    a[0][2] += v * a[0][1];
    a[1][2] += v * a[1][1];
    a[2][2] += v * a[2][1];
    a[3][2] += v * a[3][1];
  } else {
    a[0][0] += u * a[0][2];
    a[1][0] += u * a[1][2];
    a[2][0] += u * a[2][2];
    a[3][0] += u * a[3][2];
    a[0][1] += v * a[0][2];
    a[1][1] += v * a[1][2];
    a[2][1] += v * a[2][2];
    a[3][1] += v * a[3][2];
  }
}


x86 assembly (clang, -O0):
<shear>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %rdi,-0x10(%rbp)
mov    %al,-0x11(%rbp)
movsd  %xmm0,-0x20(%rbp)
movsd  %xmm1,-0x28(%rbp)
movsbl -0x11(%rbp),%eax
cmp    $0x78,%eax
jne    1248 <shear+0x148>
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x20(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x28(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x28(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x40(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x48(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x48(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x60(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x68(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x68(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x10(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x20(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x30(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x30(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x40(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x50(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x50(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x60(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x70(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x70(%rax)
jmp    149b <shear+0x39b>
movsbl -0x11(%rbp),%eax
cmp    $0x79,%eax
jne    1378 <shear+0x278>
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x28(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x20(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x20(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x48(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x40(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x40(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x68(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x60(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x60(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x10(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x28(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x30(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x30(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x48(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x50(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x50(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x68(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x70(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x70(%rax)
jmp    1496 <shear+0x396>
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x30(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x20(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x20(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x50(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x40(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x40(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x70(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x60(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x60(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x30(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x28(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x28(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x50(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x48(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x48(%rax)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x70(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  0x68(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x68(%rax)
jmp    149b <shear+0x39b>
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<shear>:
shl    $0x18,%esi
mov    $0x2,%eax
cmp    $0x78000000,%esi
je     111f <shear+0x1f>
cmp    $0x79000000,%esi
jne    1128 <shear+0x28>
mov    $0x1,%edx
jmp    1132 <shear+0x32>
mov    $0x1,%ecx
xor    %edx,%edx
jmp    1134 <shear+0x34>
mov    $0x1,%eax
mov    $0x2,%edx
xor    %ecx,%ecx
movsd  (%rdi,%rdx,8),%xmm2
movapd %xmm0,%xmm3
mulsd  %xmm2,%xmm3
addsd  (%rdi,%rcx,8),%xmm3
movsd  %xmm3,(%rdi,%rcx,8)
movsd  0x20(%rdi,%rdx,8),%xmm3
movapd %xmm0,%xmm4
mulsd  %xmm3,%xmm4
addsd  0x20(%rdi,%rcx,8),%xmm4
movsd  %xmm4,0x20(%rdi,%rcx,8)
movsd  0x40(%rdi,%rdx,8),%xmm4
movapd %xmm0,%xmm5
mulsd  %xmm4,%xmm5
addsd  0x40(%rdi,%rcx,8),%xmm5
movsd  %xmm5,0x40(%rdi,%rcx,8)
movsd  0x60(%rdi,%rdx,8),%xmm5
mulsd  %xmm5,%xmm0
addsd  0x60(%rdi,%rcx,8),%xmm0
movsd  %xmm0,0x60(%rdi,%rcx,8)
mulsd  %xmm1,%xmm2
addsd  (%rdi,%rax,8),%xmm2
movsd  %xmm2,(%rdi,%rax,8)
mulsd  %xmm1,%xmm3
addsd  0x20(%rdi,%rax,8),%xmm3
movsd  %xmm3,0x20(%rdi,%rax,8)
mulsd  %xmm1,%xmm4
addsd  0x40(%rdi,%rax,8),%xmm4
movsd  %xmm4,0x40(%rdi,%rax,8)
mulsd  %xmm5,%xmm1
addsd  0x60(%rdi,%rax,8),%xmm1
movsd  %xmm1,0x60(%rdi,%rax,8)
ret

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

LLVM IR (-O2):
define i32 @shear([4 x double]* %0, i32 %1, double %2, double %3) {
%5 = shl i32 %1, 24
switch i32 %5, label %7 [
i32 2013265920, label %8
i32 2030043136, label %6
]
6: ; preds = %4
br label %8
7: ; preds = %4
br label %8
8: ; preds = %4, %6, %7
%9 = phi i64 [ 1, %6 ], [ 2, %7 ], [ 0, %4 ]
%10 = phi i64 [ 0, %6 ], [ 0, %7 ], [ 1, %4 ]
%11 = phi i64 [ 2, %6 ], [ 1, %7 ], [ 2, %4 ]
%12 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 0, i64 %9
%13 = load double, double* %12
%14 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 0, i64 %10
%15 = load double, double* %14
%16 = tail call double @llvm.fmuladd.f64(double %2, double %13, double %15)
store double %16, double* %14
%17 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 1, i64 %9
%18 = load double, double* %17
%19 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 1, i64 %10
%20 = load double, double* %19
%21 = tail call double @llvm.fmuladd.f64(double %2, double %18, double %20)
store double %21, double* %19
%22 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 2, i64 %9
%23 = load double, double* %22
%24 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 2, i64 %10
%25 = load double, double* %24
%26 = tail call double @llvm.fmuladd.f64(double %2, double %23, double %25)
store double %26, double* %24
%27 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 3, i64 %9
%28 = load double, double* %27
%29 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 3, i64 %10
%30 = load double, double* %29
%31 = tail call double @llvm.fmuladd.f64(double %2, double %28, double %30)
store double %31, double* %29
%32 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 0, i64 %11
%33 = load double, double* %32
%34 = tail call double @llvm.fmuladd.f64(double %3, double %13, double %33)
store double %34, double* %32
%35 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 1, i64 %11
%36 = load double, double* %35
%37 = tail call double @llvm.fmuladd.f64(double %3, double %18, double %36)
store double %37, double* %35
%38 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 2, i64 %11
%39 = load double, double* %38
%40 = tail call double @llvm.fmuladd.f64(double %3, double %23, double %39)
store double %40, double* %38
%41 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 3, i64 %11
%42 = load double, double* %41
%43 = tail call double @llvm.fmuladd.f64(double %3, double %28, double %42)
store double %43, double* %41
ret i32 undef
}