[llvm] r268932 - [TargetLowering] make helper function for SetCC + and optimizations (NFC)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 09:42:50 PDT 2016


Author: spatel
Date: Mon May  9 11:42:50 2016
New Revision: 268932

URL: http://llvm.org/viewvc/llvm-project?rev=268932&view=rev
Log:
[TargetLowering] make helper function for SetCC + and optimizations (NFC)

After looking at D19087 again, it occurred to me that we can do better. If we consolidate
the valueHasExactlyOneBitSet() transforms, we won't incur extra overhead from calling it a
2nd time, and we can shrink SimplifySetCC() a bit. No functional change intended.

Differential Revision: http://reviews.llvm.org/D20050


Modified:
    llvm/trunk/include/llvm/Target/TargetLowering.h
    llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=268932&r1=268931&r2=268932&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon May  9 11:42:50 2016
@@ -3018,6 +3018,11 @@ public:
   /// Lower TLS global address SDNode for target independent emulated TLS model.
   virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,
                                           SelectionDAG &DAG) const;
+
+private:
+  SDValue simplifySetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
+                               ISD::CondCode Cond, DAGCombinerInfo &DCI,
+                               SDLoc DL) const;
 };
 
 /// Given an LLVM IR type and return type attributes, compute the return value

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=268932&r1=268931&r2=268932&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Mon May  9 11:42:50 2016
@@ -1304,18 +1304,20 @@ bool TargetLowering::isExtendedTrueVal(c
   llvm_unreachable("Unexpected enumeration.");
 }
 
-/// If the target supports an 'and-not' or 'and-complement' logic operation,
-/// try to use that to make a comparison operation more efficient.
-static SDValue createAndNotSetCC(EVT VT, SDValue N0, SDValue N1,
-                                 ISD::CondCode Cond, SelectionDAG &DAG,
-                                 SDLoc dl) {
+/// This helper function of SimplifySetCC tries to optimize the comparison when
+/// either operand of the SetCC node is a bitwise-and instruction.
+SDValue TargetLowering::simplifySetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
+                                             ISD::CondCode Cond,
+                                             DAGCombinerInfo &DCI,
+                                             SDLoc DL) const {
   // Match these patterns in any of their permutations:
   // (X & Y) == Y
   // (X & Y) != Y
   if (N1.getOpcode() == ISD::AND && N0.getOpcode() != ISD::AND)
     std::swap(N0, N1);
 
-  if (N0.getOpcode() != ISD::AND || !N0.hasOneUse() ||
+  EVT OpVT = N0.getValueType();
+  if (N0.getOpcode() != ISD::AND || !OpVT.isInteger() ||
       (Cond != ISD::SETEQ && Cond != ISD::SETNE))
     return SDValue();
 
@@ -1330,24 +1332,37 @@ static SDValue createAndNotSetCC(EVT VT,
     return SDValue();
   }
 
-  // Bail out if the compare operand that we want to turn into a zero is already
-  // a zero (otherwise, infinite loop).
-  auto *YConst = dyn_cast<ConstantSDNode>(Y);
-  if (YConst && YConst->isNullValue())
-    return SDValue();
-
-  // We don't want to do this transform if the mask is a single bit because
-  // there are more efficient ways to deal with that case (for example, 'bt' on
-  // x86 or 'rlwinm' on PPC).
-  if (!DAG.getTargetLoweringInfo().hasAndNotCompare(Y) ||
-      valueHasExactlyOneBitSet(Y, DAG))
-    return SDValue();
+  SelectionDAG &DAG = DCI.DAG;
+  SDValue Zero = DAG.getConstant(0, DL, OpVT);
+  if (valueHasExactlyOneBitSet(Y, DAG)) {
+    // Simplify X & Y == Y to X & Y != 0 if Y has exactly one bit set.
+    // Note that where Y is variable and is known to have at most one bit set
+    // (for example, if it is Z & 1) we cannot do this; the expressions are not
+    // equivalent when Y == 0.
+    Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
+    if (DCI.isBeforeLegalizeOps() ||
+        isCondCodeLegal(Cond, N0.getSimpleValueType()))
+      return DAG.getSetCC(DL, VT, N0, Zero, Cond);
+  } else if (N0.hasOneUse() && hasAndNotCompare(Y)) {
+    // If the target supports an 'and-not' or 'and-complement' logic operation,
+    // try to use that to make a comparison operation more efficient.
+    // But don't do this transform if the mask is a single bit because there are
+    // more efficient ways to deal with that case (for example, 'bt' on x86 or
+    // 'rlwinm' on PPC).
+
+    // Bail out if the compare operand that we want to turn into a zero is
+    // already a zero (otherwise, infinite loop).
+    auto *YConst = dyn_cast<ConstantSDNode>(Y);
+    if (YConst && YConst->isNullValue())
+      return SDValue();
+
+    // Transform this into: ~X & Y == 0.
+    SDValue NotX = DAG.getNOT(SDLoc(X), X, OpVT);
+    SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, NotX, Y);
+    return DAG.getSetCC(DL, VT, NewAnd, Zero, Cond);
+  }
 
-  // Transform this into: ~X & Y == 0.
-  EVT OpVT = X.getValueType();
-  SDValue NotX = DAG.getNOT(SDLoc(X), X, OpVT);
-  SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, NotX, Y);
-  return DAG.getSetCC(dl, VT, NewAnd, DAG.getConstant(0, dl, OpVT), Cond);
+  return SDValue();
 }
 
 /// Try to simplify a setcc built with the specified operands and cc. If it is
@@ -2134,32 +2149,8 @@ TargetLowering::SimplifySetCC(EVT VT, SD
       }
     }
 
-    // Simplify x&y == y to x&y != 0 if y has exactly one bit set.
-    // Note that where y is variable and is known to have at most
-    // one bit set (for example, if it is z&1) we cannot do this;
-    // the expressions are not equivalent when y==0.
-    if (N0.getOpcode() == ISD::AND)
-      if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
-        if (valueHasExactlyOneBitSet(N1, DAG)) {
-          Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
-          if (DCI.isBeforeLegalizeOps() ||
-              isCondCodeLegal(Cond, N0.getSimpleValueType())) {
-            SDValue Zero = DAG.getConstant(0, dl, N1.getValueType());
-            return DAG.getSetCC(dl, VT, N0, Zero, Cond);
-          }
-        }
-      }
-    if (N1.getOpcode() == ISD::AND)
-      if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) {
-        if (valueHasExactlyOneBitSet(N0, DAG)) {
-          Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
-          if (DCI.isBeforeLegalizeOps() ||
-              isCondCodeLegal(Cond, N1.getSimpleValueType())) {
-            SDValue Zero = DAG.getConstant(0, dl, N0.getValueType());
-            return DAG.getSetCC(dl, VT, N1, Zero, Cond);
-          }
-        }
-      }
+    if (SDValue V = simplifySetCCWithAnd(VT, N0, N1, Cond, DCI, dl))
+      return V;
   }
 
   // Fold away ALL boolean setcc's.
@@ -2212,9 +2203,6 @@ TargetLowering::SimplifySetCC(EVT VT, SD
     return N0;
   }
 
-  if (SDValue AndNotCC = createAndNotSetCC(VT, N0, N1, Cond, DAG, dl))
-    return AndNotCC;
-
   // Could not fold it.
   return SDValue();
 }




More information about the llvm-commits mailing list