diff options
author | Chris Lattner <sabre@nondot.org> | 2006-09-20 06:19:26 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-09-20 06:19:26 +0000 |
commit | 5f42a240ba5c6199d2d78fb1238938da2c073755 (patch) | |
tree | 96545cc2379adfa4da73258e9d51e06ccbbe5c9d /lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | ac924c8248c66ed643a342e8ac902ebe6148c4b8 (diff) |
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
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e098bd9843..4e3b572226 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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()); |