summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-12-05 15:45:27 +0000
committerSanjay Patel <spatel@rotateright.com>2016-12-05 15:45:27 +0000
commitf807f6a05fbaa06a2a37cf01dc1df7dc357648e9 (patch)
treed8c826a18103374ddd476febee64d433aa8db2e2
parentbfd6a758618a3c0d4dde6da044b38f3b9a3757d5 (diff)
downloadbcm5719-llvm-f807f6a05fbaa06a2a37cf01dc1df7dc357648e9.tar.gz
bcm5719-llvm-f807f6a05fbaa06a2a37cf01dc1df7dc357648e9.zip
[x86] fold fand (fxor X, -1) Y --> fandn X, Y
I noticed this gap in the scalar FP-logic matching with: D26712 and: rL287171 Differential Revision: https://reviews.llvm.org/D27385 llvm-svn: 288675
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp31
-rw-r--r--llvm/test/CodeGen/X86/fp-logic-replace.ll9
2 files changed, 34 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6b23b6187a9..128dbff1219 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -31764,6 +31764,34 @@ static SDValue getNullFPConstForNullVal(SDValue V, SelectionDAG &DAG,
return V;
}
+static SDValue combineFAndFNotToFAndn(SDNode *N, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ EVT VT = N->getValueType(0);
+ SDLoc DL(N);
+
+ // Vector types are handled in combineANDXORWithAllOnesIntoANDNP().
+ if (!((VT == MVT::f32 && Subtarget.hasSSE1()) ||
+ (VT == MVT::f64 && Subtarget.hasSSE2())))
+ return SDValue();
+
+ auto isAllOnesConstantFP = [](SDValue V) {
+ auto *C = dyn_cast<ConstantFPSDNode>(V);
+ return C && C->getConstantFPValue()->isAllOnesValue();
+ };
+
+ // fand (fxor X, -1), Y --> fandn X, Y
+ if (N0.getOpcode() == X86ISD::FXOR && isAllOnesConstantFP(N0.getOperand(1)))
+ return DAG.getNode(X86ISD::FANDN, DL, VT, N0.getOperand(0), N1);
+
+ // fand X, (fxor Y, -1) --> fandn Y, X
+ if (N1.getOpcode() == X86ISD::FXOR && isAllOnesConstantFP(N1.getOperand(1)))
+ return DAG.getNode(X86ISD::FANDN, DL, VT, N1.getOperand(0), N0);
+
+ return SDValue();
+}
+
/// Do target-specific dag combines on X86ISD::FAND nodes.
static SDValue combineFAnd(SDNode *N, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
@@ -31775,6 +31803,9 @@ static SDValue combineFAnd(SDNode *N, SelectionDAG &DAG,
if (SDValue V = getNullFPConstForNullVal(N->getOperand(1), DAG, Subtarget))
return V;
+ if (SDValue V = combineFAndFNotToFAndn(N, DAG, Subtarget))
+ return V;
+
return lowerX86FPLogicOp(N, DAG, Subtarget);
}
diff --git a/llvm/test/CodeGen/X86/fp-logic-replace.ll b/llvm/test/CodeGen/X86/fp-logic-replace.ll
index 50e2c1b2029..0a233fd9b64 100644
--- a/llvm/test/CodeGen/X86/fp-logic-replace.ll
+++ b/llvm/test/CodeGen/X86/fp-logic-replace.ll
@@ -29,16 +29,13 @@ define double @FsANDPSrr(double %x, double %y) {
define double @FsANDNPSrr(double %x, double %y) {
; SSE-LABEL: FsANDNPSrr:
; SSE: # BB#0:
-; SSE-NEXT: movsd {{.*#+}} xmm2 = mem[0],zero
-; SSE-NEXT: xorpd %xmm1, %xmm2
-; SSE-NEXT: andpd %xmm2, %xmm0
+; SSE-NEXT: andnps %xmm0, %xmm1
+; SSE-NEXT: movaps %xmm1, %xmm0
; SSE-NEXT: retq
;
; AVX-LABEL: FsANDNPSrr:
; AVX: # BB#0:
-; AVX-NEXT: vmovsd {{.*#+}} xmm2 = mem[0],zero
-; AVX-NEXT: vxorpd %xmm2, %xmm1, %xmm1
-; AVX-NEXT: vandpd %xmm1, %xmm0, %xmm0
+; AVX-NEXT: vandnps %xmm0, %xmm1, %xmm0
; AVX-NEXT: retq
;
%bc1 = bitcast double %x to i64
OpenPOWER on IntegriCloud