[llvm] r364302 - [SDAG] improve expansion of ctpop+setcc

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 25 05:49:35 PDT 2019


Author: spatel
Date: Tue Jun 25 05:49:35 2019
New Revision: 364302

URL: http://llvm.org/viewvc/llvm-project?rev=364302&view=rev
Log:
[SDAG] improve expansion of ctpop+setcc

This should not cause any visible change in output, but it's
more efficient because we were producing non-canonical 'sub x, 1'
and 'setcc ugt x, 0'. As mentioned in the TODO, we should also
be handling the inverse predicate.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=364302&r1=364301&r2=364302&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Tue Jun 25 05:49:35 2019
@@ -2700,17 +2700,20 @@ SDValue TargetLowering::SimplifySetCC(EV
         return DAG.getSetCC(dl, VT, And, DAG.getConstant(0, dl, CTVT), CC);
       }
 
-      // (ctpop x) == 1 -> x && (x & x-1) == 0 iff ctpop is illegal.
-      if (Cond == ISD::SETEQ && C1 == 1 &&
-          !isOperationLegalOrCustom(ISD::CTPOP, CTVT)) {
-        SDValue Sub =
-            DAG.getNode(ISD::SUB, dl, CTVT, CTOp, DAG.getConstant(1, dl, CTVT));
-        SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Sub);
-        SDValue LHS = DAG.getSetCC(dl, VT, CTOp, DAG.getConstant(0, dl, CTVT),
-                                   ISD::SETUGT);
-        SDValue RHS =
-            DAG.getSetCC(dl, VT, And, DAG.getConstant(0, dl, CTVT), ISD::SETEQ);
-        return DAG.getNode(ISD::AND, dl, VT, LHS, RHS);
+      // If ctpop is not supported, expand a power-of-2 comparison based on it.
+      if (C1 == 1 && !isOperationLegalOrCustom(ISD::CTPOP, CTVT)) {
+        // (ctpop x) == 1 --> (x != 0) && ((x & x-1) == 0)
+        if (Cond == ISD::SETEQ) {
+          SDValue Zero = DAG.getConstant(0, dl, CTVT);
+          SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT);
+          SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, CTOp, NegOne);
+          SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Add);
+          SDValue LHS = DAG.getSetCC(dl, VT, CTOp, Zero, ISD::SETNE);
+          SDValue RHS = DAG.getSetCC(dl, VT, And, Zero, ISD::SETEQ);
+          return DAG.getNode(ISD::AND, dl, VT, LHS, RHS);
+        }
+        // TODO:
+        // (ctpop x) != 1 --> (x == 0) || ((x & x-1) != 0)
       }
     }
 




More information about the llvm-commits mailing list