float *mat2_transpose(float *result, float *m) {
  float transposed[4];
  transposed[0] = m[0];
  transposed[1] = m[2];
  transposed[2] = m[1];
  transposed[3] = m[3];
  result[0] = transposed[0];
  result[1] = transposed[1];
  result[2] = transposed[2];
  result[3] = transposed[3];
  return result;
}


x86 assembly (clang, -O0):
<mat2_transpose>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  %xmm0,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movss  0xc(%rax),%xmm0
movss  %xmm0,-0x14(%rbp)
movss  -0x20(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x1c(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x18(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
movss  -0x14(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0xc(%rax)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<mat2_transpose>:
mov    %rdi,%rax
movups (%rsi),%xmm0
shufps $0xd8,%xmm0,%xmm0
movups %xmm0,(%rdi)
ret

LLVM IR (-O0):
define float* @mat2_transpose(float* %0, float* %1) {
%3 = alloca float*
%4 = alloca float*
%5 = alloca [4 x float]
store float* %0, float** %3
store float* %1, float** %4
%6 = load float*, float** %4
%7 = getelementptr inbounds float, float* %6, i64 0
%8 = load float, float* %7
%9 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 0
store float %8, float* %9
%10 = load float*, float** %4
%11 = getelementptr inbounds float, float* %10, i64 2
%12 = load float, float* %11
%13 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 1
store float %12, float* %13
%14 = load float*, float** %4
%15 = getelementptr inbounds float, float* %14, i64 1
%16 = load float, float* %15
%17 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 2
store float %16, float* %17
%18 = load float*, float** %4
%19 = getelementptr inbounds float, float* %18, i64 3
%20 = load float, float* %19
%21 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 3
store float %20, float* %21
%22 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 0
%23 = load float, float* %22
%24 = load float*, float** %3
%25 = getelementptr inbounds float, float* %24, i64 0
store float %23, float* %25
%26 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 1
%27 = load float, float* %26
%28 = load float*, float** %3
%29 = getelementptr inbounds float, float* %28, i64 1
store float %27, float* %29
%30 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 2
%31 = load float, float* %30
%32 = load float*, float** %3
%33 = getelementptr inbounds float, float* %32, i64 2
store float %31, float* %33
%34 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 3
%35 = load float, float* %34
%36 = load float*, float** %3
%37 = getelementptr inbounds float, float* %36, i64 3
store float %35, float* %37
%38 = load float*, float** %3
ret float* %38
}

LLVM IR (-O2):
define float* @mat2_transpose(float* returned writeonly %0, float* nocapture %1) {
%3 = bitcast float* %1 to <4 x float>*
%4 = load <4 x float>, <4 x float>* %3
%5 = shufflevector <4 x float> %4, <4 x float> poison, <4 x i32> <i32 0, i32 2, i32 1, i32 3>
%6 = bitcast float* %0 to <4 x float>*
store <4 x float> %5, <4 x float>* %6
ret float* %0
}