if (CC != ISD::SETEQ && CC != ISD::SETNE)
return false;
- // See if we're comparing against zero. This should have been canonicalized
- // to RHS during lowering.
+ // See if we're comparing against zero.
+ // FIXME: Handle all zeros on LHS.
if (!ISD::isBuildVectorAllZeros(Setcc.getOperand(1).getNode()))
return false;
ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
- // If this is a seteq make sure any build vectors of all zeros are on the RHS.
- // This helps with vptestm matching.
- // TODO: Should we just canonicalize the setcc during DAG combine?
- if ((SetCCOpcode == ISD::SETEQ || SetCCOpcode == ISD::SETNE) &&
- ISD::isBuildVectorAllZeros(Op0.getNode()))
- std::swap(Op0, Op1);
-
// Prefer SETGT over SETLT.
if (SetCCOpcode == ISD::SETLT) {
SetCCOpcode = ISD::getSetCCSwappedOperands(SetCCOpcode);
ret i16 %4
}
+define <2 x i64> @setcc_commute(<2 x i64> %a) {
+; X64-LABEL: setcc_commute:
+; X64: # %bb.0:
+; X64-NEXT: # kill: def $xmm0 killed $xmm0 def $zmm0
+; X64-NEXT: vpxor %xmm1, %xmm1, %xmm1
+; X64-NEXT: vpsubq %xmm0, %xmm1, %xmm1
+; X64-NEXT: vptestnmq %zmm0, %zmm0, %k1
+; X64-NEXT: vmovdqa64 %zmm0, %zmm1 {%k1}
+; X64-NEXT: vmovdqa %xmm1, %xmm0
+; X64-NEXT: vzeroupper
+; X64-NEXT: retq
+;
+; X86-LABEL: setcc_commute:
+; X86: # %bb.0:
+; X86-NEXT: # kill: def $xmm0 killed $xmm0 def $zmm0
+; X86-NEXT: vpxor %xmm2, %xmm2, %xmm2
+; X86-NEXT: vpsubq %xmm0, %xmm2, %xmm1
+; X86-NEXT: vpcmpeqq %zmm0, %zmm2, %k1
+; X86-NEXT: vmovdqa64 %zmm0, %zmm1 {%k1}
+; X86-NEXT: vmovdqa %xmm1, %xmm0
+; X86-NEXT: vzeroupper
+; X86-NEXT: retl
+ %1 = sub <2 x i64> zeroinitializer, %a
+ %2 = icmp eq <2 x i64> %a, zeroinitializer
+ %3 = select <2 x i1> %2, <2 x i64> %a, <2 x i64> %1
+ ret <2 x i64> %3
+}