lower "X = seteq Y, Z" to '(shr (ctlz (xor Y, Z)), 5)' instead of

'(shr (ctlz (sub Y, Z)), 5)'.

The use of xor better exposes the operation to bit-twiddling logic in the
dag combiner.  For example, this:

typedef struct {
  unsigned prefix : 4;
  unsigned code : 4;
  unsigned unsigned_p : 4;
} tree_common;

int foo(tree_common *a, tree_common *b) {
  return a->code == b->code;
}

Now compiles to:

_foo:
        lwz r2, 0(r4)
        lwz r3, 0(r3)
        xor r2, r3, r2
        rlwinm r2, r2, 28, 28, 31
        cntlzw r2, r2
        srwi r3, r2, 5
        blr

instead of:

_foo:
        lbz r2, 3(r4)
        lbz r3, 3(r3)
        srwi r2, r2, 4
        srwi r3, r3, 4
        subf r2, r2, r3
        cntlzw r2, r2
        srwi r3, r2, 5
        blr

saving a cycle.

llvm-svn: 31725
This commit is contained in:
Chris Lattner 2006-11-14 05:28:08 +00:00
parent 0ad1e3845b
commit 97ff46b3cc
1 changed files with 5 additions and 3 deletions

View File

@ -1038,12 +1038,14 @@ static SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG) {
} }
// If we have an integer seteq/setne, turn it into a compare against zero // If we have an integer seteq/setne, turn it into a compare against zero
// by subtracting the rhs from the lhs, which is faster than setting a // by xor'ing the rhs with the lhs, which is faster than setting a
// condition register, reading it back out, and masking the correct bit. // condition register, reading it back out, and masking the correct bit. The
// normal approach here uses sub to do this instead of xor. Using xor exposes
// the result to other bit-twiddling opportunities.
MVT::ValueType LHSVT = Op.getOperand(0).getValueType(); MVT::ValueType LHSVT = Op.getOperand(0).getValueType();
if (MVT::isInteger(LHSVT) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { if (MVT::isInteger(LHSVT) && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
MVT::ValueType VT = Op.getValueType(); MVT::ValueType VT = Op.getValueType();
SDOperand Sub = DAG.getNode(ISD::SUB, LHSVT, Op.getOperand(0), SDOperand Sub = DAG.getNode(ISD::XOR, LHSVT, Op.getOperand(0),
Op.getOperand(1)); Op.getOperand(1));
return DAG.getSetCC(VT, Sub, DAG.getConstant(0, LHSVT), CC); return DAG.getSetCC(VT, Sub, DAG.getConstant(0, LHSVT), CC);
} }