Two things:

1. teach SimplifySetCC that '(srl (ctlz x), 5) == 0' is really x != 0.
2. Teach visitSELECT_CC to use SimplifySetCC instead of calling it and
   ignoring the result.  This allows us to compile:

bool %test(ulong %x) {
  %tmp = setlt ulong %x, 4294967296
  ret bool %tmp
}

to:

_test:
        cntlzw r2, r3
        cmplwi cr0, r3, 1
        srwi r2, r2, 5
        li r3, 0
        beq cr0, LBB1_2 ;
LBB1_1: ;
        mr r3, r2
LBB1_2: ;
        blr

instead of:

_test:
        addi r2, r3, -1
        cntlzw r2, r2
        cntlzw r3, r3
        srwi r2, r2, 5
        cmplwi cr0, r2, 0
        srwi r2, r3, 5
        li r3, 0
        bne cr0, LBB1_2 ;
LBB1_1: ;
        mr r3, r2
LBB1_2: ;
        blr

This isn't wonderful, but it's an improvement.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30513 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2006-09-20 06:19:26 +00:00
parent ac924c8248
commit 5f42a240ba

View File

@ -22,7 +22,6 @@
// FIXME: shr X, (and Y,31) -> shr X, Y (TRICKY!)
// FIXME: mul (x, const) -> shifts + adds
// FIXME: undef values
// FIXME: make truncate see through SIGN_EXTEND and AND
// FIXME: divide by zero is currently left unfolded. do we want to turn this
// into an undef?
// FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false
@ -1721,14 +1720,26 @@ SDOperand DAGCombiner::visitSELECT_CC(SDNode *N) {
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
ISD::CondCode CC = cast<CondCodeSDNode>(N4)->get();
// Determine if the condition we're dealing with is constant
SDOperand SCC = SimplifySetCC(TLI.getSetCCResultTy(), N0, N1, CC, false);
//ConstantSDNode *SCCC = dyn_cast_or_null<ConstantSDNode>(SCC.Val);
// fold select_cc lhs, rhs, x, x, cc -> x
if (N2 == N3)
return N2;
// Determine if the condition we're dealing with is constant
SDOperand SCC = SimplifySetCC(TLI.getSetCCResultTy(), N0, N1, CC, false);
if (ConstantSDNode *SCCC = dyn_cast_or_null<ConstantSDNode>(SCC.Val)) {
if (SCCC->getValue())
return N2; // cond always true -> true val
else
return N3; // cond always false -> false val
}
// Fold to a simpler select_cc
if (SCC.Val && SCC.getOpcode() == ISD::SETCC)
return DAG.getNode(ISD::SELECT_CC, N2.getValueType(),
SCC.getOperand(0), SCC.getOperand(1), N2, N3,
SCC.getOperand(2));
// If we can fold this based on the true/false value, do so.
if (SimplifySelectOps(N, N2, N3))
return SDOperand(N, 0); // Don't revisit N.
@ -3340,6 +3351,30 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0,
case ISD::SETGE: return DAG.getConstant((int64_t)C0 >= (int64_t)C1, VT);
}
} else {
// If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an
// equality comparison, then we're just comparing whether X itself is
// zero.
if (N0.getOpcode() == ISD::SRL && (C1 == 0 || C1 == 1) &&
N0.getOperand(0).getOpcode() == ISD::CTLZ &&
N0.getOperand(1).getOpcode() == ISD::Constant) {
unsigned ShAmt = cast<ConstantSDNode>(N0.getOperand(1))->getValue();
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
ShAmt == Log2_32(MVT::getSizeInBits(N0.getValueType()))) {
if ((C1 == 0) == (Cond == ISD::SETEQ)) {
// (srl (ctlz x), 5) == 0 -> X != 0
// (srl (ctlz x), 5) != 1 -> X != 0
Cond = ISD::SETNE;
} else {
// (srl (ctlz x), 5) != 0 -> X == 0
// (srl (ctlz x), 5) == 1 -> X == 0
Cond = ISD::SETEQ;
}
SDOperand Zero = DAG.getConstant(0, N0.getValueType());
return DAG.getSetCC(VT, N0.getOperand(0).getOperand(0),
Zero, Cond);
}
}
// If the LHS is a ZERO_EXTEND, perform the comparison on the input.
if (N0.getOpcode() == ISD::ZERO_EXTEND) {
unsigned InSize = MVT::getSizeInBits(N0.getOperand(0).getValueType());