Make promoteOp work for CT*
authorAndrew Lenharth <andrewl@lenharth.org>
Wed, 4 May 2005 19:11:05 +0000 (19:11 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Wed, 4 May 2005 19:11:05 +0000 (19:11 +0000)
Proof?

ubyte %bar(ubyte %x) {
entry:
        %tmp.1 = call ubyte %llvm.ctlz( ubyte %x )
        ret ubyte %tmp.1
}

==>

zapnot $16,1,$0
CTLZ $0,$0
subq $0,56,$0
zapnot $0,1,$0
ret $31,($26),1

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21691 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

index adb88bf9b1874fb6fb3221cab59a7de6937671a6..020a373844c6c79599ac63eb36c8887bde1c77d4 100644 (file)
@@ -1534,6 +1534,34 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
     break;
   }
+  case ISD::CTPOP:
+  case ISD::CTTZ:
+  case ISD::CTLZ:
+    Tmp1 = Node->getOperand(0);
+    //Zero extend the argument
+    Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
+    // Perform the larger operation, then subtract if needed.
+    Tmp1 = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+    switch(Node->getOpcode())
+    {
+    case ISD::CTPOP:
+      Result = Tmp1;
+      break;
+    case ISD::CTTZ:
+      //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
+      Tmp2 = DAG.getSetCC(ISD::SETEQ, MVT::i1, Tmp1, 
+                          DAG.getConstant(getSizeInBits(NVT), NVT));
+      Result = DAG.getNode(ISD::SELECT, NVT, Tmp2, 
+                           DAG.getConstant(getSizeInBits(VT),NVT), Tmp1);
+      break;
+    case ISD::CTLZ:
+      //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
+      Result = DAG.getNode(ISD::SUB, NVT, Tmp1, 
+                           DAG.getConstant(getSizeInBits(NVT) - 
+                                           getSizeInBits(VT), NVT));
+      break;
+    }
+    break;
   }
 
   assert(Result.Val && "Didn't set a result!");