teach selection dag mask tracking about the fact that select_cc operates like
authorChris Lattner <sabre@nondot.org>
Wed, 24 Aug 2005 16:46:55 +0000 (16:46 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 24 Aug 2005 16:46:55 +0000 (16:46 +0000)
select.  Also teach it that the bit count instructions can only set the low bits
of the result, depending on the size of the input.

This allows us to compile this:

int %eq0(int %a) {
        %tmp.1 = seteq int %a, 0                ; <bool> [#uses=1]
        %tmp.2 = cast bool %tmp.1 to int                ; <int> [#uses=1]
        ret int %tmp.2
}

To this:

_eq0:
        cntlzw r2, r3
        srwi r3, r2, 5
        blr

instead of this:

_eq0:
        cntlzw r2, r3
        rlwinm r3, r2, 27, 31, 31
        blr

when setcc is marked illegal on ppc (which restores parity to non-illegal
setcc).  Thanks to Nate for pointing this out.

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

lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 21f763a94627f27a5d1c80b2a3fd33a857b9769b..48dde8f95d9c3652d2df4759f820dac25584dbc7 100644 (file)
@@ -1026,7 +1026,9 @@ static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask,
   case ISD::SELECT:
     return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) &&
            MaskedValueIsZero(Op.getOperand(2), Mask, TLI);
-
+  case ISD::SELECT_CC:
+    return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) &&
+           MaskedValueIsZero(Op.getOperand(3), Mask, TLI);
   case ISD::SRL:
     // (ushr X, C1) & C2 == 0   iff  X & (C2 << C1) == 0
     if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
@@ -1043,6 +1045,13 @@ static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask,
       return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI);
     }
     return false;
+  case ISD::CTTZ:
+  case ISD::CTLZ:
+  case ISD::CTPOP:
+    // Bit counting instructions can not set the high bits of the result
+    // register.  The max number of bits sets depends on the input.
+    return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0;
+    
     // TODO we could handle some SRA cases here.
   default: break;
   }