@@ -31764,6 +31764,34 @@ static SDValue getNullFPConstForNullVal(SDValue V, SelectionDAG &DAG,
31764
31764
return V;
31765
31765
}
31766
31766
31767
+ static SDValue combineFAndFNotToFAndn(SDNode *N, SelectionDAG &DAG,
31768
+ const X86Subtarget &Subtarget) {
31769
+ SDValue N0 = N->getOperand(0);
31770
+ SDValue N1 = N->getOperand(1);
31771
+ EVT VT = N->getValueType(0);
31772
+ SDLoc DL(N);
31773
+
31774
+ // Vector types are handled in combineANDXORWithAllOnesIntoANDNP().
31775
+ if (!((VT == MVT::f32 && Subtarget.hasSSE1()) ||
31776
+ (VT == MVT::f64 && Subtarget.hasSSE2())))
31777
+ return SDValue();
31778
+
31779
+ auto isAllOnesConstantFP = [](SDValue V) {
31780
+ auto *C = dyn_cast<ConstantFPSDNode>(V);
31781
+ return C && C->getConstantFPValue()->isAllOnesValue();
31782
+ };
31783
+
31784
+ // fand (fxor X, -1), Y --> fandn X, Y
31785
+ if (N0.getOpcode() == X86ISD::FXOR && isAllOnesConstantFP(N0.getOperand(1)))
31786
+ return DAG.getNode(X86ISD::FANDN, DL, VT, N0.getOperand(0), N1);
31787
+
31788
+ // fand X, (fxor Y, -1) --> fandn Y, X
31789
+ if (N1.getOpcode() == X86ISD::FXOR && isAllOnesConstantFP(N1.getOperand(1)))
31790
+ return DAG.getNode(X86ISD::FANDN, DL, VT, N1.getOperand(0), N0);
31791
+
31792
+ return SDValue();
31793
+ }
31794
+
31767
31795
/// Do target-specific dag combines on X86ISD::FAND nodes.
31768
31796
static SDValue combineFAnd(SDNode *N, SelectionDAG &DAG,
31769
31797
const X86Subtarget &Subtarget) {
@@ -31775,6 +31803,9 @@ static SDValue combineFAnd(SDNode *N, SelectionDAG &DAG,
31775
31803
if (SDValue V = getNullFPConstForNullVal(N->getOperand(1), DAG, Subtarget))
31776
31804
return V;
31777
31805
31806
+ if (SDValue V = combineFAndFNotToFAndn(N, DAG, Subtarget))
31807
+ return V;
31808
+
31778
31809
return lowerX86FPLogicOp(N, DAG, Subtarget);
31779
31810
}
31780
31811
0 commit comments