Fold (sext (truncate x)) more aggressively, by avoiding creation of a

sextinreg if not needed.   This is useful in two cases: before legalize,
it avoids creating a sextinreg that will be trivially removed.  After legalize
if the target doesn't support sextinreg, the trunc/sext would not have been
removed before.

llvm-svn: 34621
This commit is contained in:
Chris Lattner 2007-02-26 03:13:59 +00:00
parent ab5d0ac02c
commit fce448f856
1 changed files with 34 additions and 10 deletions

View File

@ -1940,18 +1940,42 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)); return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0));
// fold (sext (truncate x)) -> (sextinreg x). if (N0.getOpcode() == ISD::TRUNCATE) {
if (N0.getOpcode() == ISD::TRUNCATE && // See if the value being truncated is already sign extended. If so, just
(!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, // eliminate the trunc/sext pair.
N0.getValueType()))) {
SDOperand Op = N0.getOperand(0); SDOperand Op = N0.getOperand(0);
if (Op.getValueType() < VT) { unsigned OpBits = MVT::getSizeInBits(Op.getValueType());
Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op); unsigned MidBits = MVT::getSizeInBits(N0.getValueType());
} else if (Op.getValueType() > VT) { unsigned DestBits = MVT::getSizeInBits(VT);
Op = DAG.getNode(ISD::TRUNCATE, VT, Op); unsigned NumSignBits = TLI.ComputeNumSignBits(Op);
if (OpBits == DestBits) {
// Op is i32, Mid is i8, and Dest is i32. If Op has more than 24 sign
// bits, it is already ready.
if (NumSignBits > DestBits-MidBits)
return Op;
} else if (OpBits < DestBits) {
// Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
// bits, just sext from i32.
if (NumSignBits > OpBits-MidBits)
return DAG.getNode(ISD::SIGN_EXTEND, VT, Op);
} else {
// Op is i64, Mid is i8, and Dest is i32. If Op has more than 56 sign
// bits, just truncate to i32.
if (NumSignBits > OpBits-MidBits)
return DAG.getNode(ISD::TRUNCATE, VT, Op);
}
// fold (sext (truncate x)) -> (sextinreg x).
if (!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG,
N0.getValueType())) {
if (Op.getValueType() < VT)
Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op);
else if (Op.getValueType() > VT)
Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, Op,
DAG.getValueType(N0.getValueType()));
} }
return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, Op,
DAG.getValueType(N0.getValueType()));
} }
// fold (sext (load x)) -> (sext (truncate (sextload x))) // fold (sext (load x)) -> (sext (truncate (sextload x)))