void mat4_translate(const float m[4][4], float x, float y, float z,
                    float out[4][4]) {
  float tmp[4][4];
  int i;
  mat4_copy(m, tmp);
  for (i = 0; i < 4; i++) {
    tmp[(4 - 1)][(i)] +=
        tmp[(0)][(i)] * x + tmp[(1)][(i)] * y + tmp[(2)][(i)] * z;
  }
  mat4_copy(tmp, out);
}


x86 assembly (clang, -O0):
<mat4_translate>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
movss  %xmm0,-0xc(%rbp)
movss  %xmm1,-0x10(%rbp)
movss  %xmm2,-0x14(%rbp)
mov    %rsi,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x60(%rbp),%rsi
mov    $0x0,%al
call   1030 <mat4_copy@plt>
movl   $0x0,-0x64(%rbp)
cmpl   $0x4,-0x64(%rbp)
jge    11aa <mat4_translate+0x9a>
movslq -0x64(%rbp),%rax
movss  -0x60(%rbp,%rax,4),%xmm1
movss  -0xc(%rbp),%xmm2
movslq -0x64(%rbp),%rax
movss  -0x50(%rbp,%rax,4),%xmm0
mulss  -0x10(%rbp),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movslq -0x64(%rbp),%rax
movss  -0x40(%rbp,%rax,4),%xmm0
movss  -0x14(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movslq -0x64(%rbp),%rax
addss  -0x30(%rbp,%rax,4),%xmm0
movss  %xmm0,-0x30(%rbp,%rax,4)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    1145 <mat4_translate+0x35>
lea    -0x60(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    $0x0,%al
call   1030 <mat4_copy@plt>
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mat4_translate>:
push   %r14
push   %rbx
sub    $0x78,%rsp
mov    %rsi,%rbx
movaps %xmm2,0x20(%rsp)
movaps %xmm1,(%rsp)
movaps %xmm0,0x10(%rsp)
lea    0x30(%rsp),%r14
mov    %r14,%rsi
xor    %eax,%eax
call   1030 <mat4_copy@plt>
movaps (%rsp),%xmm0
shufps $0x0,%xmm0,%xmm0
mulps  0x40(%rsp),%xmm0
movaps %xmm0,%xmm1
movaps 0x10(%rsp),%xmm0
shufps $0x0,%xmm0,%xmm0
mulps  0x30(%rsp),%xmm0
addps  %xmm1,%xmm0
movaps %xmm0,%xmm1
movaps 0x20(%rsp),%xmm0
shufps $0x0,%xmm0,%xmm0
mulps  0x50(%rsp),%xmm0
addps  %xmm1,%xmm0
addps  0x60(%rsp),%xmm0
movaps %xmm0,0x60(%rsp)
mov    %r14,%rdi
mov    %rbx,%rsi
xor    %eax,%eax
call   1030 <mat4_copy@plt>
add    $0x78,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @mat4_translate([4 x float]* %0, float %1, float %2, float %3, [4 x float]* %4) {
%6 = alloca [4 x float]*
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca [4 x float]*
%11 = alloca [4 x [4 x float]]
%12 = alloca i32
store [4 x float]* %0, [4 x float]** %6
store float %1, float* %7
store float %2, float* %8
store float %3, float* %9
store [4 x float]* %4, [4 x float]** %10
%13 = load [4 x float]*, [4 x float]** %6
%14 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %11, i64 0, i64 0
%15 = call i32 ([4 x float]*, [4 x float]*, ...) bitcast (i32 (...)* @mat4_copy to i32 ([4 x float]*, [4 x float]*, ...)*)([4 x float]* %13, [4 x float]* %14)
store i32 0, i32* %12
br label %16
16: ; preds = %47, %5
%17 = load i32, i32* %12
%18 = icmp slt i32 %17, 4
br i1 %18, label %19, label %50
19: ; preds = %16
%20 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %11, i64 0, i64 0
%21 = load i32, i32* %12
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds [4 x float], [4 x float]* %20, i64 0, i64 %22
%24 = load float, float* %23
%25 = load float, float* %7
%26 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %11, i64 0, i64 1
%27 = load i32, i32* %12
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds [4 x float], [4 x float]* %26, i64 0, i64 %28
%30 = load float, float* %29
%31 = load float, float* %8
%32 = fmul float %30, %31
%33 = call float @llvm.fmuladd.f32(float %24, float %25, float %32)
%34 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %11, i64 0, i64 2
%35 = load i32, i32* %12
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds [4 x float], [4 x float]* %34, i64 0, i64 %36
%38 = load float, float* %37
%39 = load float, float* %9
%40 = call float @llvm.fmuladd.f32(float %38, float %39, float %33)
%41 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %11, i64 0, i64 3
%42 = load i32, i32* %12
%43 = sext i32 %42 to i64
%44 = getelementptr inbounds [4 x float], [4 x float]* %41, i64 0, i64 %43
%45 = load float, float* %44
%46 = fadd float %45, %40
store float %46, float* %44
br label %47
47: ; preds = %19
%48 = load i32, i32* %12
%49 = add nsw i32 %48, 1
store i32 %49, i32* %12
br label %16
50: ; preds = %16
%51 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %11, i64 0, i64 0
%52 = load [4 x float]*, [4 x float]** %10
%53 = call i32 ([4 x float]*, [4 x float]*, ...) bitcast (i32 (...)* @mat4_copy to i32 ([4 x float]*, [4 x float]*, ...)*)([4 x float]* %51, [4 x float]* %52)
ret void
}

LLVM IR (-O2):
define void @mat4_translate([4 x float]* %0, float %1, float %2, float %3, [4 x float]* %4) {
%6 = alloca [4 x [4 x float]]
%7 = bitcast [4 x [4 x float]]* %6 to i8*
%8 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %6, i64 0, i64 0
%9 = call i32 ([4 x float]*, [4 x float]*, ...) bitcast (i32 (...)* @mat4_copy to i32 ([4 x float]*, [4 x float]*, ...)*)([4 x float]* %0, [4 x float]* %8)
%10 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %6, i64 0, i64 1, i64 0
%11 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %6, i64 0, i64 2, i64 0
%12 = getelementptr inbounds [4 x [4 x float]], [4 x [4 x float]]* %6, i64 0, i64 3, i64 0
%13 = bitcast [4 x [4 x float]]* %6 to <4 x float>*
%14 = load <4 x float>, <4 x float>* %13
%15 = bitcast float* %10 to <4 x float>*
%16 = load <4 x float>, <4 x float>* %15
%17 = insertelement <4 x float> poison, float %2, i64 0
%18 = shufflevector <4 x float> %17, <4 x float> poison, <4 x i32> zeroinitializer
%19 = fmul <4 x float> %16, %18
%20 = insertelement <4 x float> poison, float %1, i64 0
%21 = shufflevector <4 x float> %20, <4 x float> poison, <4 x i32> zeroinitializer
%22 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %14, <4 x float> %21, <4 x float> %19)
%23 = bitcast float* %11 to <4 x float>*
%24 = load <4 x float>, <4 x float>* %23
%25 = insertelement <4 x float> poison, float %3, i64 0
%26 = shufflevector <4 x float> %25, <4 x float> poison, <4 x i32> zeroinitializer
%27 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %24, <4 x float> %26, <4 x float> %22)
%28 = bitcast float* %12 to <4 x float>*
%29 = load <4 x float>, <4 x float>* %28
%30 = fadd <4 x float> %29, %27
%31 = bitcast float* %12 to <4 x float>*
store <4 x float> %30, <4 x float>* %31
%32 = call i32 ([4 x float]*, [4 x float]*, ...) bitcast (i32 (...)* @mat4_copy to i32 ([4 x float]*, [4 x float]*, ...)*)([4 x float]* %8, [4 x float]* %4)
ret void
}