[x86] Simplify vector selection if condition value type matches vselect value type and true value is all ones or false value is all zeros.

This transformation worked if selector is produced by SETCC, however SETCC is needed only if we consider to swap operands. So I replaced SETCC check for this case.
Added tests for vselect of <X x i1> values.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220777 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Robert Khasanov 2014-10-28 15:59:40 +00:00
parent 7435fa333d
commit edf556ec1f
3 changed files with 56 additions and 12 deletions

View File

@ -22479,22 +22479,22 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(Opc, DL, VT, LHS, RHS);
}
// Simplify vector selection if the selector will be produced by CMPP*/PCMP*.
if (N->getOpcode() == ISD::VSELECT && Cond.getOpcode() == ISD::SETCC &&
// Check if SETCC has already been promoted
TLI.getSetCCResultType(*DAG.getContext(), VT) == CondVT &&
// Check that condition value type matches vselect operand type
CondVT == VT) {
// Simplify vector selection if condition value type matches vselect
// operand type
if (N->getOpcode() == ISD::VSELECT && CondVT == VT) {
assert(Cond.getValueType().isVector() &&
"vector select expects a vector selector!");
bool TValIsAllOnes = ISD::isBuildVectorAllOnes(LHS.getNode());
bool FValIsAllZeros = ISD::isBuildVectorAllZeros(RHS.getNode());
if (!TValIsAllOnes && !FValIsAllZeros) {
// Try invert the condition if true value is not all 1s and false value
// is not all 0s.
// Try invert the condition if true value is not all 1s and false value
// is not all 0s.
if (!TValIsAllOnes && !FValIsAllZeros &&
// Check if the selector will be produced by CMPP*/PCMP*
Cond.getOpcode() == ISD::SETCC &&
// Check if SETCC has already been promoted
TLI.getSetCCResultType(*DAG.getContext(), VT) == CondVT) {
bool TValIsAllZeros = ISD::isBuildVectorAllZeros(LHS.getNode());
bool FValIsAllOnes = ISD::isBuildVectorAllOnes(RHS.getNode());

View File

@ -48,3 +48,47 @@ define <16 x double> @select04(<16 x double> %a, <16 x double> %b) {
%sel = select <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <16 x double> %a, <16 x double> %b
ret <16 x double> %sel
}
; CHECK-LABEL: select05
; CHECK: kmovw %esi, %k0
; CHECK-NEXT: kmovw %edi, %k1
; CHECK-NEXT: korw %k1, %k0, %k0
; CHECK-NEXT: kmovw %k0, %eax
define i8 @select05(i8 %a.0, i8 %m) {
%mask = bitcast i8 %m to <8 x i1>
%a = bitcast i8 %a.0 to <8 x i1>
%r = select <8 x i1> %mask, <8 x i1> <i1 -1, i1 -1, i1 -1, i1 -1, i1 -1, i1 -1, i1 -1, i1 -1>, <8 x i1> %a
%res = bitcast <8 x i1> %r to i8
ret i8 %res;
}
; CHECK-LABEL: select06
; CHECK: kmovw %esi, %k0
; CHECK-NEXT: kmovw %edi, %k1
; CHECK-NEXT: kandw %k1, %k0, %k0
; CHECK-NEXT: kmovw %k0, %eax
define i8 @select06(i8 %a.0, i8 %m) {
%mask = bitcast i8 %m to <8 x i1>
%a = bitcast i8 %a.0 to <8 x i1>
%r = select <8 x i1> %mask, <8 x i1> %a, <8 x i1> zeroinitializer
%res = bitcast <8 x i1> %r to i8
ret i8 %res;
}
; CHECK-LABEL: select07
; CHECK-DAG: kmovw %edx, %k0
; CHECK-DAG: kmovw %edi, %k1
; CHECK-DAG: kmovw %esi, %k2
; CHECK: kandw %k0, %k1, %k1
; CHECK-NEXT: knotw %k0, %k0
; CHECK-NEXT: kandw %k0, %k2, %k0
; CHECK-NEXT: korw %k0, %k1, %k0
; CHECK-NEXT: kmovw %k0, %eax
define i8 @select07(i8 %a.0, i8 %b.0, i8 %m) {
%mask = bitcast i8 %m to <8 x i1>
%a = bitcast i8 %a.0 to <8 x i1>
%b = bitcast i8 %b.0 to <8 x i1>
%r = select <8 x i1> %mask, <8 x i1> %a, <8 x i1> %b
%res = bitcast <8 x i1> %r to i8
ret i8 %res;
}

View File

@ -14,8 +14,8 @@ target triple = "x86_64-apple-macosx"
; <rdar://problem/18675020>
; CHECK-LABEL: test:
; CHECK: vmovdqa {{.*#+}} xmm1 = [65533,124,125,14807]
; CHECK: vmovdqa {{.*#+}} xmm1 = [65535,0,0,65535]
; CHECK: vmovdqa {{.*#+}} xmm0 = [65535,0,0,65535]
; CHECK: vmovdqa {{.*#+}} xmm2 = [65533,124,125,14807]
; CHECK: ret
define void @test(<4 x i16>* %a, <4 x i16>* %b) {
body: