void fb_image_convert_32to32(const unsigned char *src, unsigned char *dest,
                             int w) {
  unsigned int *d = (unsigned int *)dest;
  unsigned int c;
  for (; w; w--) {
    c = *(unsigned int *)src;
    *d++ = (c >> 16) | (c & 0xFF00FF00) | (c << 16);
    src += sizeof(unsigned int);
  }
}


x86 assembly (clang, -O0):
<fb_image_convert_32to32>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
cmpl   $0x0,-0x14(%rbp)
je     116d <fb_image_convert_32to32+0x6d>
mov    -0x8(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%ecx
shr    $0x10,%ecx
mov    -0x24(%rbp),%eax
and    $0xff00ff00,%eax
or     %eax,%ecx
mov    -0x24(%rbp),%eax
shl    $0x10,%eax
or     %eax,%ecx
mov    -0x20(%rbp),%rax
mov    %rax,%rdx
add    $0x4,%rdx
mov    %rdx,-0x20(%rbp)
mov    %ecx,(%rax)
mov    -0x8(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    1117 <fb_image_convert_32to32+0x17>
pop    %rbp
ret

x86 assembly (clang, -O2):
<fb_image_convert_32to32>:
test   %edx,%edx
je     1254 <fb_image_convert_32to32+0x154>
lea    -0x1(%rdx),%r8d
cmp    $0x7,%r8d
jb     1134 <fb_image_convert_32to32+0x34>
lea    (%rdi,%r8,4),%rax
add    $0x4,%rax
cmp    %rsi,%rax
jbe    11c7 <fb_image_convert_32to32+0xc7>
lea    (%rsi,%r8,4),%rax
add    $0x4,%rax
cmp    %rdi,%rax
jbe    11c7 <fb_image_convert_32to32+0xc7>
mov    %rdi,%r10
mov    %rsi,%r11
test   $0x1,%dl
jne    114b <fb_image_convert_32to32+0x4b>
mov    %edx,%eax
cmp    $0x1,%edx
jne    1179 <fb_image_convert_32to32+0x79>
jmp    1254 <fb_image_convert_32to32+0x154>
mov    (%r10),%eax
mov    %eax,%esi
shr    $0x10,%esi
mov    %eax,%edi
and    $0xff00ff00,%edi
or     %esi,%edi
shl    $0x10,%eax
or     %edi,%eax
mov    %eax,(%r11)
add    $0x4,%r11
add    $0x4,%r10
lea    -0x1(%rdx),%eax
cmp    $0x1,%edx
je     1254 <fb_image_convert_32to32+0x154>
mov    %eax,%edx
xor    %esi,%esi
nopl   (%rax)
mov    (%r10,%rsi,4),%eax
mov    %eax,%edi
shr    $0x10,%edi
mov    %eax,%ecx
and    $0xff00ff00,%ecx
or     %edi,%ecx
shl    $0x10,%eax
or     %ecx,%eax
mov    %eax,(%r11,%rsi,4)
mov    0x4(%r10,%rsi,4),%eax
mov    %eax,%ecx
shr    $0x10,%ecx
mov    %eax,%edi
and    $0xff00ff00,%edi
or     %ecx,%edi
shl    $0x10,%eax
or     %edi,%eax
mov    %eax,0x4(%r11,%rsi,4)
add    $0x2,%rsi
cmp    %esi,%edx
jne    1180 <fb_image_convert_32to32+0x80>
jmp    1254 <fb_image_convert_32to32+0x154>
add    $0x1,%r8
mov    %r8,%r9
and    $0xfffffffffffffff8,%r9
lea    (%rdi,%r9,4),%r10
lea    (%rsi,%r9,4),%r11
sub    %r9d,%edx
xor    %eax,%eax
movdqa 0xe19(%rip),%xmm0
nopw   0x0(%rax,%rax,1)
movdqu (%rdi,%rax,4),%xmm1
movdqu 0x10(%rdi,%rax,4),%xmm2
movdqa %xmm1,%xmm3
psrld  $0x10,%xmm3
movdqa %xmm2,%xmm4
psrld  $0x10,%xmm4
movdqa %xmm1,%xmm5
pand   %xmm0,%xmm5
por    %xmm3,%xmm5
movdqa %xmm2,%xmm3
pand   %xmm0,%xmm3
por    %xmm4,%xmm3
pslld  $0x10,%xmm1
por    %xmm5,%xmm1
pslld  $0x10,%xmm2
por    %xmm3,%xmm2
movdqu %xmm1,(%rsi,%rax,4)
movdqu %xmm2,0x10(%rsi,%rax,4)
add    $0x8,%rax
cmp    %rax,%r9
jne    11f0 <fb_image_convert_32to32+0xf0>
cmp    %r9,%r8
jne    113a <fb_image_convert_32to32+0x3a>
ret

LLVM IR (-O0):
define void @fb_image_convert_32to32(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32*
%8 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%9 = load i8*, i8** %5
%10 = bitcast i8* %9 to i32*
store i32* %10, i32** %7
br label %11
11: ; preds = %30, %3
%12 = load i32, i32* %6
%13 = icmp ne i32 %12, 0
br i1 %13, label %14, label %33
14: ; preds = %11
%15 = load i8*, i8** %4
%16 = bitcast i8* %15 to i32*
%17 = load i32, i32* %16
store i32 %17, i32* %8
%18 = load i32, i32* %8
%19 = lshr i32 %18, 16
%20 = load i32, i32* %8
%21 = and i32 %20, -16711936
%22 = or i32 %19, %21
%23 = load i32, i32* %8
%24 = shl i32 %23, 16
%25 = or i32 %22, %24
%26 = load i32*, i32** %7
%27 = getelementptr inbounds i32, i32* %26, i32 1
store i32* %27, i32** %7
store i32 %25, i32* %26
%28 = load i8*, i8** %4
%29 = getelementptr inbounds i8, i8* %28, i64 4
store i8* %29, i8** %4
br label %30
30: ; preds = %14
%31 = load i32, i32* %6
%32 = add nsw i32 %31, -1
store i32 %32, i32* %6
br label %11
33: ; preds = %11
ret void
}

LLVM IR (-O2):
define void @fb_image_convert_32to32(i8* nocapture %0, i8* nocapture writeonly %1, i32 %2) {
%4 = icmp eq i32 %2, 0
br i1 %4, label %101, label %5
5: ; preds = %3
%6 = bitcast i8* %1 to i32*
%7 = add i32 %2, -1
%8 = zext i32 %7 to i64
%9 = add nuw nsw i64 %8, 1
%10 = icmp ult i32 %7, 7
br i1 %10, label %55, label %11
11: ; preds = %5
%12 = add i32 %2, -1
%13 = zext i32 %12 to i64
%14 = shl nuw nsw i64 %13, 2
%15 = add nuw nsw i64 %14, 4
%16 = getelementptr i8, i8* %1, i64 %15
%17 = getelementptr i8, i8* %0, i64 %15
%18 = icmp ugt i8* %17, %1
%19 = icmp ugt i8* %16, %0
%20 = and i1 %18, %19
br i1 %20, label %55, label %21
21: ; preds = %11
%22 = and i64 %9, 8589934584
%23 = shl nuw nsw i64 %22, 2
%24 = getelementptr i8, i8* %0, i64 %23
%25 = getelementptr i32, i32* %6, i64 %22
%26 = trunc i64 %22 to i32
%27 = sub i32 %2, %26
br label %28
28: ; preds = %28, %21
%29 = phi i64 [ 0, %21 ], [ %51, %28 ]
%30 = shl i64 %29, 2
%31 = getelementptr i8, i8* %0, i64 %30
%32 = getelementptr i32, i32* %6, i64 %29
%33 = bitcast i8* %31 to <4 x i32>*
%34 = load <4 x i32>, <4 x i32>* %33
%35 = getelementptr i8, i8* %31, i64 16
%36 = bitcast i8* %35 to <4 x i32>*
%37 = load <4 x i32>, <4 x i32>* %36
%38 = lshr <4 x i32> %34, <i32 16, i32 16, i32 16, i32 16>
%39 = lshr <4 x i32> %37, <i32 16, i32 16, i32 16, i32 16>
%40 = and <4 x i32> %34, <i32 -16711936, i32 -16711936, i32 -16711936, i32 -16711936>
%41 = and <4 x i32> %37, <i32 -16711936, i32 -16711936, i32 -16711936, i32 -16711936>
%42 = or <4 x i32> %38, %40
%43 = or <4 x i32> %39, %41
%44 = shl <4 x i32> %34, <i32 16, i32 16, i32 16, i32 16>
%45 = shl <4 x i32> %37, <i32 16, i32 16, i32 16, i32 16>
%46 = or <4 x i32> %42, %44
%47 = or <4 x i32> %43, %45
%48 = bitcast i32* %32 to <4 x i32>*
store <4 x i32> %46, <4 x i32>* %48
%49 = getelementptr i32, i32* %32, i64 4
%50 = bitcast i32* %49 to <4 x i32>*
store <4 x i32> %47, <4 x i32>* %50
%51 = add nuw i64 %29, 8
%52 = icmp eq i64 %51, %22
br i1 %52, label %53, label %28
53: ; preds = %28
%54 = icmp eq i64 %9, %22
br i1 %54, label %101, label %55
55: ; preds = %11, %5, %53
%56 = phi i8* [ %0, %11 ], [ %0, %5 ], [ %24, %53 ]
%57 = phi i32* [ %6, %11 ], [ %6, %5 ], [ %25, %53 ]
%58 = phi i32 [ %2, %11 ], [ %2, %5 ], [ %27, %53 ]
%59 = and i32 %58, 1
%60 = icmp eq i32 %59, 0
br i1 %60, label %72, label %61
61: ; preds = %55
%62 = bitcast i8* %56 to i32*
%63 = load i32, i32* %62
%64 = lshr i32 %63, 16
%65 = and i32 %63, -16711936
%66 = or i32 %64, %65
%67 = shl i32 %63, 16
%68 = or i32 %66, %67
%69 = getelementptr inbounds i32, i32* %57, i64 1
store i32 %68, i32* %57
%70 = getelementptr inbounds i8, i8* %56, i64 4
%71 = add nsw i32 %58, -1
br label %72
72: ; preds = %61, %55
%73 = phi i8* [ %56, %55 ], [ %70, %61 ]
%74 = phi i32* [ %57, %55 ], [ %69, %61 ]
%75 = phi i32 [ %58, %55 ], [ %71, %61 ]
%76 = icmp eq i32 %58, 1
br i1 %76, label %101, label %77
77: ; preds = %72, %77
%78 = phi i8* [ %98, %77 ], [ %73, %72 ]
%79 = phi i32* [ %97, %77 ], [ %74, %72 ]
%80 = phi i32 [ %99, %77 ], [ %75, %72 ]
%81 = bitcast i8* %78 to i32*
%82 = load i32, i32* %81
%83 = lshr i32 %82, 16
%84 = and i32 %82, -16711936
%85 = or i32 %83, %84
%86 = shl i32 %82, 16
%87 = or i32 %85, %86
%88 = getelementptr inbounds i32, i32* %79, i64 1
store i32 %87, i32* %79
%89 = getelementptr inbounds i8, i8* %78, i64 4
%90 = bitcast i8* %89 to i32*
%91 = load i32, i32* %90
%92 = lshr i32 %91, 16
%93 = and i32 %91, -16711936
%94 = or i32 %92, %93
%95 = shl i32 %91, 16
%96 = or i32 %94, %95
%97 = getelementptr inbounds i32, i32* %79, i64 2
store i32 %96, i32* %88
%98 = getelementptr inbounds i8, i8* %78, i64 8
%99 = add nsw i32 %80, -2
%100 = icmp eq i32 %99, 0
br i1 %100, label %101, label %77
101: ; preds = %72, %77, %53, %3
ret void
}