void idct_row(short *row, int *dst) {
  int a0, a1, b0, b1;
  a0 = 22725 * row[0];
  a1 = a0;
  a0 += 21407 * row[2];
  a1 += 8867 * row[2];
  b0 = 22725 * row[1];
  b1 = 19266 * row[1];
  dst[0] = a0 + b0;
  dst[1] = a0 - b0;
  dst[2] = a1 + b1;
  dst[3] = a1 - b1;
}


x86 assembly (clang, -O0):
<idct_row>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movswl (%rax),%eax
imul   $0x58c5,%eax,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movswl 0x4(%rax),%eax
imul   $0x539f,%eax,%eax
add    -0x14(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rax
movswl 0x4(%rax),%eax
imul   $0x22a3,%eax,%eax
add    -0x18(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movswl 0x2(%rax),%eax
imul   $0x58c5,%eax,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movswl 0x2(%rax),%eax
imul   $0x4b42,%eax,%eax
mov    %eax,-0x20(%rbp)
mov    -0x14(%rbp),%ecx
add    -0x1c(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x14(%rbp),%ecx
sub    -0x1c(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x4(%rax)
mov    -0x18(%rbp),%ecx
add    -0x20(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x8(%rax)
mov    -0x18(%rbp),%ecx
sub    -0x20(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0xc(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<idct_row>:
movswl (%rdi),%eax
imul   $0x58c5,%eax,%eax
movzwl 0x4(%rdi),%ecx
movd   %ecx,%xmm0
pshufd $0x50,%xmm0,%xmm0
pmaddwd 0xee2(%rip),%xmm0
movd   %eax,%xmm1
pshufd $0x0,%xmm1,%xmm1
pshufd $0x50,%xmm0,%xmm0
movzwl 0x2(%rdi),%eax
movd   %eax,%xmm2
pshufd $0x50,%xmm2,%xmm2
pmaddwd 0xecf(%rip),%xmm2
paddd  %xmm1,%xmm0
pshufd $0x50,%xmm2,%xmm1
movdqa %xmm0,%xmm2
paddd  %xmm1,%xmm2
psubd  %xmm1,%xmm0
pshufd $0xed,%xmm0,%xmm0
pshufd $0xe8,%xmm2,%xmm1
punpckldq %xmm0,%xmm1
movdqu %xmm1,(%rsi)
ret

LLVM IR (-O0):
define void @idct_row(i16* %0, i32* %1) {
%3 = alloca i16*
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i16* %0, i16** %3
store i32* %1, i32** %4
%9 = load i16*, i16** %3
%10 = getelementptr inbounds i16, i16* %9, i64 0
%11 = load i16, i16* %10
%12 = sext i16 %11 to i32
%13 = mul nsw i32 22725, %12
store i32 %13, i32* %5
%14 = load i32, i32* %5
store i32 %14, i32* %6
%15 = load i16*, i16** %3
%16 = getelementptr inbounds i16, i16* %15, i64 2
%17 = load i16, i16* %16
%18 = sext i16 %17 to i32
%19 = mul nsw i32 21407, %18
%20 = load i32, i32* %5
%21 = add nsw i32 %20, %19
store i32 %21, i32* %5
%22 = load i16*, i16** %3
%23 = getelementptr inbounds i16, i16* %22, i64 2
%24 = load i16, i16* %23
%25 = sext i16 %24 to i32
%26 = mul nsw i32 8867, %25
%27 = load i32, i32* %6
%28 = add nsw i32 %27, %26
store i32 %28, i32* %6
%29 = load i16*, i16** %3
%30 = getelementptr inbounds i16, i16* %29, i64 1
%31 = load i16, i16* %30
%32 = sext i16 %31 to i32
%33 = mul nsw i32 22725, %32
store i32 %33, i32* %7
%34 = load i16*, i16** %3
%35 = getelementptr inbounds i16, i16* %34, i64 1
%36 = load i16, i16* %35
%37 = sext i16 %36 to i32
%38 = mul nsw i32 19266, %37
store i32 %38, i32* %8
%39 = load i32, i32* %5
%40 = load i32, i32* %7
%41 = add nsw i32 %39, %40
%42 = load i32*, i32** %4
%43 = getelementptr inbounds i32, i32* %42, i64 0
store i32 %41, i32* %43
%44 = load i32, i32* %5
%45 = load i32, i32* %7
%46 = sub nsw i32 %44, %45
%47 = load i32*, i32** %4
%48 = getelementptr inbounds i32, i32* %47, i64 1
store i32 %46, i32* %48
%49 = load i32, i32* %6
%50 = load i32, i32* %8
%51 = add nsw i32 %49, %50
%52 = load i32*, i32** %4
%53 = getelementptr inbounds i32, i32* %52, i64 2
store i32 %51, i32* %53
%54 = load i32, i32* %6
%55 = load i32, i32* %8
%56 = sub nsw i32 %54, %55
%57 = load i32*, i32** %4
%58 = getelementptr inbounds i32, i32* %57, i64 3
store i32 %56, i32* %58
ret void
}

LLVM IR (-O2):
define void @idct_row(i16* nocapture %0, i32* nocapture writeonly %1) {
%3 = load i16, i16* %0
%4 = sext i16 %3 to i32
%5 = mul nsw i32 %4, 22725
%6 = getelementptr inbounds i16, i16* %0, i64 2
%7 = load i16, i16* %6
%8 = sext i16 %7 to i32
%9 = insertelement <2 x i32> poison, i32 %8, i64 0
%10 = shufflevector <2 x i32> %9, <2 x i32> poison, <2 x i32> zeroinitializer
%11 = mul nsw <2 x i32> %10, <i32 21407, i32 8867>
%12 = insertelement <2 x i32> poison, i32 %5, i64 0
%13 = shufflevector <2 x i32> %12, <2 x i32> poison, <2 x i32> zeroinitializer
%14 = add nsw <2 x i32> %11, %13
%15 = shufflevector <2 x i32> %14, <2 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%16 = getelementptr inbounds i16, i16* %0, i64 1
%17 = load i16, i16* %16
%18 = sext i16 %17 to i32
%19 = insertelement <2 x i32> poison, i32 %18, i64 0
%20 = shufflevector <2 x i32> %19, <2 x i32> poison, <2 x i32> zeroinitializer
%21 = mul nsw <2 x i32> %20, <i32 22725, i32 19266>
%22 = shufflevector <2 x i32> %21, <2 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%23 = add nsw <4 x i32> %15, %22
%24 = sub nsw <4 x i32> %15, %22
%25 = shufflevector <4 x i32> %23, <4 x i32> %24, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
%26 = bitcast i32* %1 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %26
ret void
}