double Mat_doubleSwap(double *a) {
  union {
    char a[8];
    double b;
  } tmp;
  tmp.b = *a;
  tmp.a[0] ^= tmp.a[7];
  tmp.a[7] ^= tmp.a[0];
  tmp.a[0] ^= tmp.a[7];
  tmp.a[1] ^= tmp.a[6];
  tmp.a[6] ^= tmp.a[1];
  tmp.a[1] ^= tmp.a[6];
  tmp.a[2] ^= tmp.a[5];
  tmp.a[5] ^= tmp.a[2];
  tmp.a[2] ^= tmp.a[5];
  tmp.a[3] ^= tmp.a[4];
  tmp.a[4] ^= tmp.a[3];
  tmp.a[3] ^= tmp.a[4];
  *a = tmp.b;
  return *a;
}


x86 assembly (clang, -O0):
<Mat_doubleSwap>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsbl -0x9(%rbp),%ecx
movsbl -0x10(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0x10(%rbp)
movsbl -0x10(%rbp),%ecx
movsbl -0x9(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0x9(%rbp)
movsbl -0x9(%rbp),%ecx
movsbl -0x10(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0x10(%rbp)
movsbl -0xa(%rbp),%ecx
movsbl -0xf(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xf(%rbp)
movsbl -0xf(%rbp),%ecx
movsbl -0xa(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xa(%rbp)
movsbl -0xa(%rbp),%ecx
movsbl -0xf(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xf(%rbp)
movsbl -0xb(%rbp),%ecx
movsbl -0xe(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xe(%rbp)
movsbl -0xe(%rbp),%ecx
movsbl -0xb(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xb(%rbp)
movsbl -0xb(%rbp),%ecx
movsbl -0xe(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xe(%rbp)
movsbl -0xc(%rbp),%ecx
movsbl -0xd(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xd(%rbp)
movsbl -0xd(%rbp),%ecx
movsbl -0xc(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xc(%rbp)
movsbl -0xc(%rbp),%ecx
movsbl -0xd(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xd(%rbp)
movsd  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<Mat_doubleSwap>:
mov    (%rdi),%r8
mov    %r8,%rcx
shr    $0x38,%rcx
movzbl %r8b,%edx
xor    %rcx,%rdx
mov    %rdx,%rcx
shl    $0x38,%rcx
movabs $0xff00000000000000,%rsi
and    %r8,%rsi
xor    %rcx,%rsi
mov    %rsi,%rax
shr    $0x38,%rax
xor    %rdx,%rax
or     %rsi,%rax
mov    %r8,%rdx
shr    $0x28,%rdx
xor    %r8,%rdx
mov    %edx,%esi
and    $0xff00,%esi
shl    $0x28,%rdx
xor    %r8,%rdx
movabs $0xff000000000000,%rcx
and    %rdx,%rcx
or     %rcx,%rax
shr    $0x28,%rcx
xor    %rsi,%rcx
or     %rax,%rcx
mov    %r8,%rax
shr    $0x18,%rax
xor    %r8,%rax
mov    %eax,%esi
and    $0xff0000,%esi
or     %ecx,%eax
shl    $0x18,%rax
xor    %r8,%rax
movabs $0xff0000000000,%rdx
and    %rax,%rdx
or     %rdx,%rcx
shr    $0x18,%rdx
xor    %rsi,%rdx
or     %rcx,%rdx
mov    %r8,%rax
shr    $0x8,%rax
xor    %r8,%rax
mov    %eax,%ecx
and    $0xff000000,%ecx
or     %edx,%eax
shl    $0x8,%rax
xor    %r8,%rax
movabs $0xff00000000,%rsi
and    %rax,%rsi
movabs $0xffffff0000ffffff,%rax
ff ff ff
and    %rdx,%rax
or     %rsi,%rax
shr    $0x8,%rsi
xor    %rcx,%rsi
or     %rax,%rsi
movq   %rsi,%xmm0
mov    %rsi,(%rdi)
ret

LLVM IR (-O0):
%union.anon = type { double }
define double @Mat_doubleSwap(double* %0) {
%2 = alloca double*
%3 = alloca %union.anon
store double* %0, double** %2
%4 = load double*, double** %2
%5 = load double, double* %4
%6 = bitcast %union.anon* %3 to double*
store double %5, double* %6
%7 = bitcast %union.anon* %3 to [8 x i8]*
%8 = getelementptr inbounds [8 x i8], [8 x i8]* %7, i64 0, i64 7
%9 = load i8, i8* %8
%10 = sext i8 %9 to i32
%11 = bitcast %union.anon* %3 to [8 x i8]*
%12 = getelementptr inbounds [8 x i8], [8 x i8]* %11, i64 0, i64 0
%13 = load i8, i8* %12
%14 = sext i8 %13 to i32
%15 = xor i32 %14, %10
%16 = trunc i32 %15 to i8
store i8 %16, i8* %12
%17 = bitcast %union.anon* %3 to [8 x i8]*
%18 = getelementptr inbounds [8 x i8], [8 x i8]* %17, i64 0, i64 0
%19 = load i8, i8* %18
%20 = sext i8 %19 to i32
%21 = bitcast %union.anon* %3 to [8 x i8]*
%22 = getelementptr inbounds [8 x i8], [8 x i8]* %21, i64 0, i64 7
%23 = load i8, i8* %22
%24 = sext i8 %23 to i32
%25 = xor i32 %24, %20
%26 = trunc i32 %25 to i8
store i8 %26, i8* %22
%27 = bitcast %union.anon* %3 to [8 x i8]*
%28 = getelementptr inbounds [8 x i8], [8 x i8]* %27, i64 0, i64 7
%29 = load i8, i8* %28
%30 = sext i8 %29 to i32
%31 = bitcast %union.anon* %3 to [8 x i8]*
%32 = getelementptr inbounds [8 x i8], [8 x i8]* %31, i64 0, i64 0
%33 = load i8, i8* %32
%34 = sext i8 %33 to i32
%35 = xor i32 %34, %30
%36 = trunc i32 %35 to i8
store i8 %36, i8* %32
%37 = bitcast %union.anon* %3 to [8 x i8]*
%38 = getelementptr inbounds [8 x i8], [8 x i8]* %37, i64 0, i64 6
%39 = load i8, i8* %38
%40 = sext i8 %39 to i32
%41 = bitcast %union.anon* %3 to [8 x i8]*
%42 = getelementptr inbounds [8 x i8], [8 x i8]* %41, i64 0, i64 1
%43 = load i8, i8* %42
%44 = sext i8 %43 to i32
%45 = xor i32 %44, %40
%46 = trunc i32 %45 to i8
store i8 %46, i8* %42
%47 = bitcast %union.anon* %3 to [8 x i8]*
%48 = getelementptr inbounds [8 x i8], [8 x i8]* %47, i64 0, i64 1
%49 = load i8, i8* %48
%50 = sext i8 %49 to i32
%51 = bitcast %union.anon* %3 to [8 x i8]*
%52 = getelementptr inbounds [8 x i8], [8 x i8]* %51, i64 0, i64 6
%53 = load i8, i8* %52
%54 = sext i8 %53 to i32
%55 = xor i32 %54, %50
%56 = trunc i32 %55 to i8
store i8 %56, i8* %52
%57 = bitcast %union.anon* %3 to [8 x i8]*
%58 = getelementptr inbounds [8 x i8], [8 x i8]* %57, i64 0, i64 6
%59 = load i8, i8* %58
%60 = sext i8 %59 to i32
%61 = bitcast %union.anon* %3 to [8 x i8]*
%62 = getelementptr inbounds [8 x i8], [8 x i8]* %61, i64 0, i64 1
%63 = load i8, i8* %62
%64 = sext i8 %63 to i32
%65 = xor i32 %64, %60
%66 = trunc i32 %65 to i8
store i8 %66, i8* %62
%67 = bitcast %union.anon* %3 to [8 x i8]*
%68 = getelementptr inbounds [8 x i8], [8 x i8]* %67, i64 0, i64 5
%69 = load i8, i8* %68
%70 = sext i8 %69 to i32
%71 = bitcast %union.anon* %3 to [8 x i8]*
%72 = getelementptr inbounds [8 x i8], [8 x i8]* %71, i64 0, i64 2
%73 = load i8, i8* %72
%74 = sext i8 %73 to i32
%75 = xor i32 %74, %70
%76 = trunc i32 %75 to i8
store i8 %76, i8* %72
%77 = bitcast %union.anon* %3 to [8 x i8]*
%78 = getelementptr inbounds [8 x i8], [8 x i8]* %77, i64 0, i64 2
%79 = load i8, i8* %78
%80 = sext i8 %79 to i32
%81 = bitcast %union.anon* %3 to [8 x i8]*
%82 = getelementptr inbounds [8 x i8], [8 x i8]* %81, i64 0, i64 5
%83 = load i8, i8* %82
%84 = sext i8 %83 to i32
%85 = xor i32 %84, %80
%86 = trunc i32 %85 to i8
store i8 %86, i8* %82
%87 = bitcast %union.anon* %3 to [8 x i8]*
%88 = getelementptr inbounds [8 x i8], [8 x i8]* %87, i64 0, i64 5
%89 = load i8, i8* %88
%90 = sext i8 %89 to i32
%91 = bitcast %union.anon* %3 to [8 x i8]*
%92 = getelementptr inbounds [8 x i8], [8 x i8]* %91, i64 0, i64 2
%93 = load i8, i8* %92
%94 = sext i8 %93 to i32
%95 = xor i32 %94, %90
%96 = trunc i32 %95 to i8
store i8 %96, i8* %92
%97 = bitcast %union.anon* %3 to [8 x i8]*
%98 = getelementptr inbounds [8 x i8], [8 x i8]* %97, i64 0, i64 4
%99 = load i8, i8* %98
%100 = sext i8 %99 to i32
%101 = bitcast %union.anon* %3 to [8 x i8]*
%102 = getelementptr inbounds [8 x i8], [8 x i8]* %101, i64 0, i64 3
%103 = load i8, i8* %102
%104 = sext i8 %103 to i32
%105 = xor i32 %104, %100
%106 = trunc i32 %105 to i8
store i8 %106, i8* %102
%107 = bitcast %union.anon* %3 to [8 x i8]*
%108 = getelementptr inbounds [8 x i8], [8 x i8]* %107, i64 0, i64 3
%109 = load i8, i8* %108
%110 = sext i8 %109 to i32
%111 = bitcast %union.anon* %3 to [8 x i8]*
%112 = getelementptr inbounds [8 x i8], [8 x i8]* %111, i64 0, i64 4
%113 = load i8, i8* %112
%114 = sext i8 %113 to i32
%115 = xor i32 %114, %110
%116 = trunc i32 %115 to i8
store i8 %116, i8* %112
%117 = bitcast %union.anon* %3 to [8 x i8]*
%118 = getelementptr inbounds [8 x i8], [8 x i8]* %117, i64 0, i64 4
%119 = load i8, i8* %118
%120 = sext i8 %119 to i32
%121 = bitcast %union.anon* %3 to [8 x i8]*
%122 = getelementptr inbounds [8 x i8], [8 x i8]* %121, i64 0, i64 3
%123 = load i8, i8* %122
%124 = sext i8 %123 to i32
%125 = xor i32 %124, %120
%126 = trunc i32 %125 to i8
store i8 %126, i8* %122
%127 = bitcast %union.anon* %3 to double*
%128 = load double, double* %127
%129 = load double*, double** %2
store double %128, double* %129
%130 = load double*, double** %2
%131 = load double, double* %130
ret double %131
}

LLVM IR (-O2):
define double @Mat_doubleSwap(double* nocapture %0) {
%2 = bitcast double* %0 to i64*
%3 = load i64, i64* %2
%4 = lshr i64 %3, 56
%5 = and i64 %3, 255
%6 = xor i64 %5, %4
%7 = shl nuw i64 %6, 56
%8 = and i64 %3, -72057594037927936
%9 = xor i64 %7, %8
%10 = lshr exact i64 %9, 56
%11 = xor i64 %10, %6
%12 = or i64 %9, %11
%13 = lshr i64 %3, 40
%14 = xor i64 %13, %3
%15 = and i64 %14, 65280
%16 = shl i64 %14, 40
%17 = xor i64 %16, %3
%18 = and i64 %17, 71776119061217280
%19 = or i64 %18, %12
%20 = lshr exact i64 %18, 40
%21 = xor i64 %20, %15
%22 = or i64 %19, %21
%23 = lshr i64 %3, 24
%24 = xor i64 %23, %3
%25 = and i64 %24, 16711680
%26 = or i64 %22, %24
%27 = shl i64 %26, 24
%28 = xor i64 %27, %3
%29 = and i64 %28, 280375465082880
%30 = and i64 %22, -280379759984641
%31 = or i64 %29, %30
%32 = lshr exact i64 %29, 24
%33 = xor i64 %32, %25
%34 = or i64 %31, %33
%35 = lshr i64 %3, 8
%36 = xor i64 %35, %3
%37 = and i64 %36, 4278190080
%38 = or i64 %34, %36
%39 = shl i64 %38, 8
%40 = xor i64 %39, %3
%41 = and i64 %40, 1095216660480
%42 = and i64 %34, -1099494850561
%43 = or i64 %41, %42
%44 = lshr exact i64 %41, 8
%45 = xor i64 %44, %37
%46 = or i64 %43, %45
%47 = bitcast i64 %46 to double
store i64 %46, i64* %2
ret double %47
}