#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ memcpy(float *, float *, int);
void multiply4x4(float *m1, const float *m2) {
  float temp[16];
  int x, y;
  for (x = 0; x < 4; x++) {
    for (y = 0; y < 4; y++) {
      temp[y + (x * 4)] = (m1[x * 4] * m2[y]) + (m1[(x * 4) + 1] * m2[y + 4]) +
                          (m1[(x * 4) + 2] * m2[y + 8]) +
                          (m1[(x * 4) + 3] * m2[y + 12]);
    }
  }
  memcpy(m1, temp, sizeof(float) << 4);
}


x86 assembly (clang, -O0):
<multiply4x4>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x54(%rbp)
cmpl   $0x4,-0x54(%rbp)
jge    1222 <multiply4x4+0x112>
movl   $0x0,-0x58(%rbp)
cmpl   $0x4,-0x58(%rbp)
jge    120f <multiply4x4+0xff>
mov    -0x8(%rbp),%rax
mov    -0x54(%rbp),%ecx
shl    $0x2,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x58(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
mov    -0x8(%rbp),%rax
mov    -0x54(%rbp),%ecx
shl    $0x2,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x58(%rbp),%ecx
add    $0x4,%ecx
movslq %ecx,%rcx
mulss  (%rax,%rcx,4),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
mov    -0x54(%rbp),%ecx
shl    $0x2,%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x58(%rbp),%ecx
add    $0x8,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
mov    -0x54(%rbp),%ecx
shl    $0x2,%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x58(%rbp),%ecx
add    $0xc,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x58(%rbp),%eax
mov    -0x54(%rbp),%ecx
shl    $0x2,%ecx
add    %ecx,%eax
cltq
movss  %xmm0,-0x50(%rbp,%rax,4)
mov    -0x58(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x58(%rbp)
jmp    1138 <multiply4x4+0x28>
jmp    1214 <multiply4x4+0x104>
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
jmp    1127 <multiply4x4+0x17>
mov    -0x8(%rbp),%rdi
lea    -0x50(%rbp),%rsi
mov    $0x40,%edx
call   1030 <memcpy@plt>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<multiply4x4>:
sub    $0x48,%rsp
movups (%rdi),%xmm8
movups 0x10(%rdi),%xmm0
movups 0x20(%rdi),%xmm5
movups 0x30(%rdi),%xmm6
movaps %xmm6,%xmm3
movlhps %xmm5,%xmm3
movaps %xmm8,%xmm1
unpcklps %xmm0,%xmm1
shufps $0x24,%xmm3,%xmm1
movaps %xmm5,%xmm3
unpcklps %xmm6,%xmm3
movaps %xmm0,%xmm4
shufps $0x11,%xmm8,%xmm4
shufps $0xe2,%xmm3,%xmm4
movaps %xmm6,%xmm7
unpckhpd %xmm5,%xmm7
movaps %xmm8,%xmm3
unpckhps %xmm0,%xmm3
shufps $0x24,%xmm7,%xmm3
movss  (%rsi),%xmm7
unpckhps %xmm6,%xmm5
movss  0x4(%rsi),%xmm2
shufps $0x33,%xmm8,%xmm0
movss  0x8(%rsi),%xmm6
shufps $0x0,%xmm6,%xmm6
shufps $0x0,%xmm2,%xmm2
shufps $0x0,%xmm7,%xmm7
shufps $0xe2,%xmm5,%xmm0
movss  0x10(%rsi),%xmm5
shufps $0x0,%xmm5,%xmm5
mulps  %xmm4,%xmm5
mulps  %xmm1,%xmm7
addps  %xmm5,%xmm7
movss  0x20(%rsi),%xmm5
shufps $0x0,%xmm5,%xmm5
mulps  %xmm3,%xmm5
addps  %xmm7,%xmm5
movss  0x30(%rsi),%xmm8
shufps $0x0,%xmm8,%xmm8
mulps  %xmm0,%xmm8
addps  %xmm5,%xmm8
movss  0x14(%rsi),%xmm5
shufps $0x0,%xmm5,%xmm5
mulps  %xmm4,%xmm5
mulps  %xmm1,%xmm2
addps  %xmm5,%xmm2
movss  0x24(%rsi),%xmm7
shufps $0x0,%xmm7,%xmm7
mulps  %xmm3,%xmm7
addps  %xmm2,%xmm7
movss  0x34(%rsi),%xmm5
shufps $0x0,%xmm5,%xmm5
mulps  %xmm0,%xmm5
addps  %xmm7,%xmm5
movss  0x18(%rsi),%xmm2
shufps $0x0,%xmm2,%xmm2
mulps  %xmm4,%xmm2
mulps  %xmm1,%xmm6
addps  %xmm2,%xmm6
movss  0x28(%rsi),%xmm2
shufps $0x0,%xmm2,%xmm2
mulps  %xmm3,%xmm2
addps  %xmm6,%xmm2
movss  0x38(%rsi),%xmm6
shufps $0x0,%xmm6,%xmm6
mulps  %xmm0,%xmm6
addps  %xmm2,%xmm6
movss  0x1c(%rsi),%xmm2
shufps $0x0,%xmm2,%xmm2
mulps  %xmm2,%xmm4
movss  0xc(%rsi),%xmm2
shufps $0x0,%xmm2,%xmm2
mulps  %xmm2,%xmm1
movss  0x3c(%rsi),%xmm2
shufps $0x0,%xmm2,%xmm2
addps  %xmm4,%xmm1
movss  0x2c(%rsi),%xmm4
shufps $0x0,%xmm4,%xmm4
mulps  %xmm4,%xmm3
addps  %xmm1,%xmm3
mulps  %xmm2,%xmm0
addps  %xmm3,%xmm0
movaps %xmm0,%xmm1
movlhps %xmm6,%xmm1
movaps %xmm8,%xmm2
unpcklps %xmm5,%xmm2
shufps $0x24,%xmm1,%xmm2
movaps %xmm6,%xmm1
unpcklps %xmm0,%xmm1
movaps %xmm5,%xmm3
shufps $0x11,%xmm8,%xmm3
shufps $0xe2,%xmm1,%xmm3
movaps %xmm0,%xmm1
unpckhpd %xmm6,%xmm1
movaps %xmm8,%xmm4
unpckhps %xmm5,%xmm4
shufps $0x24,%xmm1,%xmm4
unpckhps %xmm0,%xmm6
shufps $0x33,%xmm8,%xmm5
shufps $0xe2,%xmm6,%xmm5
movaps %xmm5,0x30(%rsp)
movaps %xmm4,0x20(%rsp)
movaps %xmm3,0x10(%rsp)
movaps %xmm2,(%rsp)
mov    %rsp,%rsi
mov    $0x40,%edx
call   1030 <memcpy@plt>
add    $0x48,%rsp
ret

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

LLVM IR (-O2):
define void @multiply4x4(float* %0, float* nocapture %1) {
%3 = alloca <16 x float>
%4 = bitcast <16 x float>* %3 to i8*
%5 = getelementptr inbounds float, float* %1, i64 15
%6 = load float, float* %5
%7 = insertelement <4 x float> poison, float %6, i64 0
%8 = shufflevector <4 x float> %7, <4 x float> poison, <4 x i32> zeroinitializer
%9 = getelementptr inbounds float, float* %1, i64 11
%10 = load float, float* %9
%11 = insertelement <4 x float> poison, float %10, i64 0
%12 = shufflevector <4 x float> %11, <4 x float> poison, <4 x i32> zeroinitializer
%13 = getelementptr inbounds float, float* %1, i64 3
%14 = load float, float* %13
%15 = insertelement <4 x float> poison, float %14, i64 0
%16 = shufflevector <4 x float> %15, <4 x float> poison, <4 x i32> zeroinitializer
%17 = getelementptr inbounds float, float* %1, i64 7
%18 = load float, float* %17
%19 = insertelement <4 x float> poison, float %18, i64 0
%20 = shufflevector <4 x float> %19, <4 x float> poison, <4 x i32> zeroinitializer
%21 = getelementptr inbounds float, float* %1, i64 14
%22 = load float, float* %21
%23 = insertelement <4 x float> poison, float %22, i64 0
%24 = shufflevector <4 x float> %23, <4 x float> poison, <4 x i32> zeroinitializer
%25 = getelementptr inbounds float, float* %1, i64 10
%26 = load float, float* %25
%27 = insertelement <4 x float> poison, float %26, i64 0
%28 = shufflevector <4 x float> %27, <4 x float> poison, <4 x i32> zeroinitializer
%29 = getelementptr inbounds float, float* %1, i64 2
%30 = load float, float* %29
%31 = insertelement <4 x float> poison, float %30, i64 0
%32 = shufflevector <4 x float> %31, <4 x float> poison, <4 x i32> zeroinitializer
%33 = getelementptr inbounds float, float* %1, i64 6
%34 = load float, float* %33
%35 = insertelement <4 x float> poison, float %34, i64 0
%36 = shufflevector <4 x float> %35, <4 x float> poison, <4 x i32> zeroinitializer
%37 = getelementptr inbounds float, float* %1, i64 13
%38 = load float, float* %37
%39 = insertelement <4 x float> poison, float %38, i64 0
%40 = shufflevector <4 x float> %39, <4 x float> poison, <4 x i32> zeroinitializer
%41 = getelementptr inbounds float, float* %1, i64 9
%42 = load float, float* %41
%43 = insertelement <4 x float> poison, float %42, i64 0
%44 = shufflevector <4 x float> %43, <4 x float> poison, <4 x i32> zeroinitializer
%45 = getelementptr inbounds float, float* %1, i64 1
%46 = load float, float* %45
%47 = insertelement <4 x float> poison, float %46, i64 0
%48 = shufflevector <4 x float> %47, <4 x float> poison, <4 x i32> zeroinitializer
%49 = getelementptr inbounds float, float* %1, i64 5
%50 = load float, float* %49
%51 = insertelement <4 x float> poison, float %50, i64 0
%52 = shufflevector <4 x float> %51, <4 x float> poison, <4 x i32> zeroinitializer
%53 = getelementptr inbounds float, float* %1, i64 12
%54 = load float, float* %53
%55 = insertelement <4 x float> poison, float %54, i64 0
%56 = shufflevector <4 x float> %55, <4 x float> poison, <4 x i32> zeroinitializer
%57 = getelementptr inbounds float, float* %1, i64 8
%58 = load float, float* %57
%59 = insertelement <4 x float> poison, float %58, i64 0
%60 = shufflevector <4 x float> %59, <4 x float> poison, <4 x i32> zeroinitializer
%61 = load float, float* %1
%62 = insertelement <4 x float> poison, float %61, i64 0
%63 = shufflevector <4 x float> %62, <4 x float> poison, <4 x i32> zeroinitializer
%64 = getelementptr inbounds float, float* %1, i64 4
%65 = load float, float* %64
%66 = insertelement <4 x float> poison, float %65, i64 0
%67 = shufflevector <4 x float> %66, <4 x float> poison, <4 x i32> zeroinitializer
%68 = bitcast float* %0 to <16 x float>*
%69 = load <16 x float>, <16 x float>* %68
%70 = shufflevector <16 x float> %69, <16 x float> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
%71 = shufflevector <16 x float> %69, <16 x float> poison, <4 x i32> <i32 1, i32 5, i32 9, i32 13>
%72 = shufflevector <16 x float> %69, <16 x float> poison, <4 x i32> <i32 2, i32 6, i32 10, i32 14>
%73 = shufflevector <16 x float> %69, <16 x float> poison, <4 x i32> <i32 3, i32 7, i32 11, i32 15>
%74 = fmul <4 x float> %71, %67
%75 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %70, <4 x float> %63, <4 x float> %74)
%76 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %72, <4 x float> %60, <4 x float> %75)
%77 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %73, <4 x float> %56, <4 x float> %76)
%78 = fmul <4 x float> %71, %52
%79 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %70, <4 x float> %48, <4 x float> %78)
%80 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %72, <4 x float> %44, <4 x float> %79)
%81 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %73, <4 x float> %40, <4 x float> %80)
%82 = fmul <4 x float> %71, %36
%83 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %70, <4 x float> %32, <4 x float> %82)
%84 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %72, <4 x float> %28, <4 x float> %83)
%85 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %73, <4 x float> %24, <4 x float> %84)
%86 = fmul <4 x float> %71, %20
%87 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %70, <4 x float> %16, <4 x float> %86)
%88 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %72, <4 x float> %12, <4 x float> %87)
%89 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %73, <4 x float> %8, <4 x float> %88)
%90 = shufflevector <4 x float> %77, <4 x float> %81, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
%91 = shufflevector <4 x float> %85, <4 x float> %89, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
%92 = shufflevector <8 x float> %90, <8 x float> %91, <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 1, i32 5, i32 9, i32 13, i32 2, i32 6, i32 10, i32 14, i32 3, i32 7, i32 11, i32 15>
store <16 x float> %92, <16 x float>* %3
%93 = getelementptr inbounds <16 x float>, <16 x float>* %3, i64 0, i64 0
%94 = call i32 @memcpy(float* %0, float* %93, i32 64)
ret void
}