[X86][SSE] Detect AVG pattern during instruction combine for SSE2/AVX2/AVX512BW.
authorCong Hou <congh@google.com>
Tue, 24 Nov 2015 05:44:19 +0000 (05:44 +0000)
committerCong Hou <congh@google.com>
Tue, 24 Nov 2015 05:44:19 +0000 (05:44 +0000)
commitb5b07c36862e772571fcbfa459fa9780615ec42b
tree4ae18659be262804fa7b132ad046dc71da046e01
parent505dc6c8637d700985ec928edd8cb70b58f3fd38
[X86][SSE] Detect AVG pattern during instruction combine for SSE2/AVX2/AVX512BW.

This patch detects the AVG pattern in vectorized code, which is simply
c = (a + b + 1) / 2, where a, b, and c have the same type which are vectors of
either unsigned i8 or unsigned i16. In the IR, i8/i16 will be promoted to
i32 before any arithmetic operations. The following IR shows such an example:

%1 = zext <N x i8> %a to <N x i32>
%2 = zext <N x i8> %b to <N x i32>
%3 = add nuw nsw <N x i32> %1, <i32 1 x N>
%4 = add nuw nsw <N x i32> %3, %2
%5 = lshr <N x i32> %N, <i32 1 x N>
%6 = trunc <N x i32> %5 to <N x i8>

and with this patch it will be converted to a X86ISD::AVG instruction.

The pattern recognition is done when combining instructions just before type
legalization during instruction selection. We do it here because after type
legalization, it is much more difficult to do pattern recognition based
on many instructions that are doing type conversions. Therefore, for
target-specific instructions (like X86ISD::AVG), we need to take care of type
legalization by ourselves. However, as X86ISD::AVG behaves similarly to
ISD::ADD, I am wondering if there is a way to legalize operands and result
types of X86ISD::AVG together with ISD::ADD. It seems that the current design
doesn't support this idea.

Tests are added for SSE2, AVX2, and AVX512BW and both i8 and i16 types of
variant vector sizes.

Differential revision: http://reviews.llvm.org/D14761

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253952 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86InstrSSE.td
lib/Target/X86/X86IntrinsicsInfo.h
test/CodeGen/X86/avg.ll [new file with mode: 0644]