ISD::CondCode CC = cast<CondCodeSDNode>(Match.getOperand(2))->get();
if ((BinOp == ISD::AND && CC == ISD::CondCode::SETEQ) ||
(BinOp == ISD::OR && CC == ISD::CondCode::SETNE)) {
- // If representable as a scalar integer:
// For all_of(setcc(x,y,eq)) - use (iX)x == (iX)y.
// For any_of(setcc(x,y,ne)) - use (iX)x != (iX)y.
- EVT VecVT = Match.getOperand(0).getValueType();
- EVT IntVT = EVT::getIntegerVT(Ctx, VecVT.getSizeInBits());
- if (TLI.isTypeLegal(IntVT)) {
- SDValue LHS = DAG.getFreeze(Match.getOperand(0));
- SDValue RHS = DAG.getFreeze(Match.getOperand(1));
- return DAG.getSetCC(DL, ExtractVT, DAG.getBitcast(IntVT, LHS),
- DAG.getBitcast(IntVT, RHS), CC);
- }
+ X86::CondCode X86CC;
+ SDValue LHS = DAG.getFreeze(Match.getOperand(0));
+ SDValue RHS = DAG.getFreeze(Match.getOperand(1));
+ APInt Mask = APInt::getAllOnes(LHS.getScalarValueSizeInBits());
+ if (SDValue V = LowerVectorAllEqual(DL, LHS, RHS, CC, Mask, Subtarget,
+ DAG, X86CC))
+ return DAG.getNode(ISD::TRUNCATE, DL, ExtractVT,
+ getSETCC(X86CC, V, DL, DAG));
}
}
if (TLI.isTypeLegal(MatchVT)) {
EVT MovmskVT = EVT::getIntegerVT(Ctx, NumElts);
Movmsk = DAG.getBitcast(MovmskVT, Match);
} else {
- // For all_of(setcc(x,y,eq)) - use PMOVMSKB(PCMPEQB()).
- // For any_of(setcc(x,y,ne)) - use PMOVMSKB(NOT(PCMPEQB())).
- if (Match.getOpcode() == ISD::SETCC) {
- ISD::CondCode CC = cast<CondCodeSDNode>(Match.getOperand(2))->get();
- if ((BinOp == ISD::AND && CC == ISD::CondCode::SETEQ) ||
- (BinOp == ISD::OR && CC == ISD::CondCode::SETNE)) {
- EVT VecSVT = Match.getOperand(0).getValueType().getScalarType();
- if (VecSVT != MVT::i8 && (VecSVT.getSizeInBits() % 8) == 0) {
- NumElts *= VecSVT.getSizeInBits() / 8;
- EVT CmpVT = EVT::getVectorVT(Ctx, MVT::i8, NumElts);
- MatchVT = EVT::getVectorVT(Ctx, MVT::i1, NumElts);
- Match = DAG.getSetCC(
- DL, MatchVT, DAG.getBitcast(CmpVT, Match.getOperand(0)),
- DAG.getBitcast(CmpVT, Match.getOperand(1)), CC);
- }
- }
- }
-
// Use combineBitcastvxi1 to create the MOVMSK.
while (NumElts > MaxElts) {
SDValue Lo, Hi;
; SSE2-NEXT: pcmpeqb %xmm2, %xmm0
; SSE2-NEXT: pand %xmm1, %xmm0
; SSE2-NEXT: pmovmskb %xmm0, %eax
-; SSE2-NEXT: cmpw $-1, %ax
+; SSE2-NEXT: xorl $65535, %eax # imm = 0xFFFF
; SSE2-NEXT: sete %al
; SSE2-NEXT: retq
;
;
; AVX1-LABEL: bool_reduction_v16i16:
; AVX1: # %bb.0:
-; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
-; AVX1-NEXT: vpxor %xmm2, %xmm3, %xmm2
-; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0
-; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0
-; AVX1-NEXT: vptest %xmm0, %xmm0
+; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0
+; AVX1-NEXT: vptest %ymm0, %ymm0
; AVX1-NEXT: sete %al
; AVX1-NEXT: vzeroupper
; AVX1-NEXT: retq
; SSE2-NEXT: pcmpeqb %xmm2, %xmm0
; SSE2-NEXT: pand %xmm1, %xmm0
; SSE2-NEXT: pmovmskb %xmm0, %eax
-; SSE2-NEXT: cmpw $-1, %ax
+; SSE2-NEXT: xorl $65535, %eax # imm = 0xFFFF
; SSE2-NEXT: sete %al
; SSE2-NEXT: retq
;
;
; AVX1-LABEL: bool_reduction_v32i8:
; AVX1: # %bb.0:
-; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
-; AVX1-NEXT: vpxor %xmm2, %xmm3, %xmm2
-; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0
-; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0
-; AVX1-NEXT: vptest %xmm0, %xmm0
+; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0
+; AVX1-NEXT: vptest %ymm0, %ymm0
; AVX1-NEXT: sete %al
; AVX1-NEXT: vzeroupper
; AVX1-NEXT: retq
define i1 @bool_reduction_v2i64(<2 x i64> %x, <2 x i64> %y) {
; SSE2-LABEL: bool_reduction_v2i64:
; SSE2: # %bb.0:
-; SSE2-NEXT: pcmpeqb %xmm1, %xmm0
-; SSE2-NEXT: pmovmskb %xmm0, %eax
-; SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
+; SSE2-NEXT: pcmpeqd %xmm1, %xmm0
+; SSE2-NEXT: movmskps %xmm0, %eax
+; SSE2-NEXT: xorl $15, %eax
; SSE2-NEXT: setne %al
; SSE2-NEXT: retq
;
; SSE42-NEXT: setne %al
; SSE42-NEXT: retq
;
-; AVX1OR2-LABEL: bool_reduction_v2i64:
-; AVX1OR2: # %bb.0:
-; AVX1OR2-NEXT: vpxor %xmm1, %xmm0, %xmm0
-; AVX1OR2-NEXT: vptest %xmm0, %xmm0
-; AVX1OR2-NEXT: setne %al
-; AVX1OR2-NEXT: retq
-;
-; AVX512-LABEL: bool_reduction_v2i64:
-; AVX512: # %bb.0:
-; AVX512-NEXT: vpcmpneqq %xmm1, %xmm0, %k0
-; AVX512-NEXT: kmovd %k0, %eax
-; AVX512-NEXT: testb %al, %al
-; AVX512-NEXT: setne %al
-; AVX512-NEXT: retq
+; AVX-LABEL: bool_reduction_v2i64:
+; AVX: # %bb.0:
+; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0
+; AVX-NEXT: vptest %xmm0, %xmm0
+; AVX-NEXT: setne %al
+; AVX-NEXT: retq
%a = icmp ne <2 x i64> %x, %y
%b = shufflevector <2 x i1> %a, <2 x i1> undef, <2 x i32> <i32 1, i32 undef>
%c = or <2 x i1> %a, %b