Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.270 -> 1.271 --- Log message: 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. --- Diffs of the changes: (+34 -10) DAGCombiner.cpp | 44 ++++++++++++++++++++++++++++++++++---------- 1 files changed, 34 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.270 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.271 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.270 Thu Feb 8 16:13:59 2007 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Feb 25 21:13:59 2007 @@ -1940,18 +1940,42 @@ if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)); - // fold (sext (truncate x)) -> (sextinreg x). - if (N0.getOpcode() == ISD::TRUNCATE && - (!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, - N0.getValueType()))) { + if (N0.getOpcode() == ISD::TRUNCATE) { + // See if the value being truncated is already sign extended. If so, just + // eliminate the trunc/sext pair. SDOperand Op = N0.getOperand(0); - if (Op.getValueType() < VT) { - Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op); - } else if (Op.getValueType() > VT) { - Op = DAG.getNode(ISD::TRUNCATE, VT, Op); + unsigned OpBits = MVT::getSizeInBits(Op.getValueType()); + unsigned MidBits = MVT::getSizeInBits(N0.getValueType()); + unsigned DestBits = MVT::getSizeInBits(VT); + 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))) _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits