[llvm] r282546 - [x86] add folds for FP logic with vector zeros

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 27 15:28:14 PDT 2016


Author: spatel
Date: Tue Sep 27 17:28:13 2016
New Revision: 282546

URL: http://llvm.org/viewvc/llvm-project?rev=282546&view=rev
Log:
[x86] add folds for FP logic with vector zeros

The 'or' case shows up in copysign. The copysign code also had 
redundant checking for a scalar zero operand with 'and', so I 
removed that. 

I'm not sure how to test vector 'and', 'andn', and 'xor' yet, 
but it seems better to just include all of the logic ops since
we're fixing 'or' anyway.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/test/CodeGen/X86/copysign-constant-magnitude.ll

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=282546&r1=282545&r2=282546&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Sep 27 17:28:13 2016
@@ -14670,16 +14670,11 @@ static SDValue LowerFCOPYSIGN(SDValue Op
   SDValue MagMask = DAG.getConstantFP(
       APFloat(Sem, ~APInt::getSignBit(SizeInBits)), dl, LogicVT);
 
-  // FIXME: This check shouldn't be necessary. Logic instructions with constant
-  // operands should be folded!
+  // TODO: If we had general constant folding for FP logic ops, this check
+  // wouldn't be necessary.
   SDValue MagBits;
   if (ConstantFPSDNode *Op0CN = dyn_cast<ConstantFPSDNode>(Mag)) {
     APFloat APF = Op0CN->getValueAPF();
-    // If the magnitude is a positive zero, the sign bit alone is enough.
-    if (APF.isPosZero())
-      return IsF128 ? SignBit :
-          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, SignBit,
-                      DAG.getIntPtrConstant(0, dl));
     APF.clearSign();
     MagBits = DAG.getConstantFP(APF, dl, LogicVT);
   } else {
@@ -30495,30 +30490,52 @@ static SDValue combineXor(SDNode *N, Sel
   return SDValue();
 }
 
+
+static bool isNullFPScalarOrVectorConst(SDValue V) {
+  return isNullFPConstant(V) || ISD::isBuildVectorAllZeros(V.getNode());
+}
+
+/// If a value is a scalar FP zero or a vector FP zero (potentially including
+/// undefined elements), return a zero constant that may be used to fold away
+/// that value. In the case of a vector, the returned constant will not contain
+/// undefined elements even if the input parameter does. This makes it suitable
+/// to be used as a replacement operand with operations (eg, bitwise-and) where
+/// an undef should not propagate.
+static SDValue getNullFPConstForNullVal(SDValue V, SelectionDAG &DAG,
+                                        const X86Subtarget &Subtarget) {
+  if (!isNullFPScalarOrVectorConst(V))
+    return SDValue();
+
+  if (V.getValueType().isVector())
+    return getZeroVector(V.getSimpleValueType(), Subtarget, DAG, SDLoc(V));
+
+  return V;
+}
+
 /// Do target-specific dag combines on X86ISD::FAND nodes.
 static SDValue combineFAnd(SDNode *N, SelectionDAG &DAG,
                            const X86Subtarget &Subtarget) {
   // FAND(0.0, x) -> 0.0
-  if (isNullFPConstant(N->getOperand(0)))
-    return N->getOperand(0);
+  if (SDValue V = getNullFPConstForNullVal(N->getOperand(0), DAG, Subtarget))
+    return V;
 
   // FAND(x, 0.0) -> 0.0
-  if (isNullFPConstant(N->getOperand(1)))
-    return N->getOperand(1);
+  if (SDValue V = getNullFPConstForNullVal(N->getOperand(1), DAG, Subtarget))
+    return V;
 
   return lowerX86FPLogicOp(N, DAG, Subtarget);
 }
 
-/// Do target-specific dag combines on X86ISD::FANDN nodes
+/// Do target-specific dag combines on X86ISD::FANDN nodes.
 static SDValue combineFAndn(SDNode *N, SelectionDAG &DAG,
                             const X86Subtarget &Subtarget) {
   // FANDN(0.0, x) -> x
-  if (isNullFPConstant(N->getOperand(0)))
+  if (isNullFPScalarOrVectorConst(N->getOperand(0)))
     return N->getOperand(1);
 
   // FANDN(x, 0.0) -> 0.0
-  if (isNullFPConstant(N->getOperand(1)))
-    return N->getOperand(1);
+  if (SDValue V = getNullFPConstForNullVal(N->getOperand(1), DAG, Subtarget))
+    return V;
 
   return lowerX86FPLogicOp(N, DAG, Subtarget);
 }
@@ -30529,11 +30546,11 @@ static SDValue combineFOr(SDNode *N, Sel
   assert(N->getOpcode() == X86ISD::FOR || N->getOpcode() == X86ISD::FXOR);
 
   // F[X]OR(0.0, x) -> x
-  if (isNullFPConstant(N->getOperand(0)))
+  if (isNullFPScalarOrVectorConst(N->getOperand(0)))
     return N->getOperand(1);
 
   // F[X]OR(x, 0.0) -> x
-  if (isNullFPConstant(N->getOperand(1)))
+  if (isNullFPScalarOrVectorConst(N->getOperand(1)))
     return N->getOperand(0);
 
   if (isFNEG(N))

Modified: llvm/trunk/test/CodeGen/X86/copysign-constant-magnitude.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/copysign-constant-magnitude.ll?rev=282546&r1=282545&r2=282546&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/copysign-constant-magnitude.ll (original)
+++ llvm/trunk/test/CodeGen/X86/copysign-constant-magnitude.ll Tue Sep 27 17:28:13 2016
@@ -27,9 +27,7 @@ define double @mag_neg0_double(double %x
 ; CHECK:       ## BB#0:
 ; CHECK-NEXT:    movsd [[SIGNMASK2]](%rip), %xmm1
 ; CHECK-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0,0]
-; CHECK-NEXT:    andps %xmm0, %xmm1
-; CHECK-NEXT:    xorps %xmm0, %xmm0
-; CHECK-NEXT:    orps %xmm1, %xmm0
+; CHECK-NEXT:    andps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
 ;
   %y = call double @copysign(double -0.0, double %x)
@@ -95,9 +93,7 @@ define float @mag_neg0_float(float %x) n
 ; CHECK:       ## BB#0:
 ; CHECK-NEXT:    movss [[SIGNMASK6]](%rip), %xmm1
 ; CHECK-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0,0,0]
-; CHECK-NEXT:    andps %xmm0, %xmm1
-; CHECK-NEXT:    xorps %xmm0, %xmm0
-; CHECK-NEXT:    orps %xmm1, %xmm0
+; CHECK-NEXT:    andps %xmm1, %xmm0
 ; CHECK-NEXT:    retq
 ;
   %y = call float @copysignf(float -0.0, float %x)




More information about the llvm-commits mailing list