mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 22:50:47 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34621 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ddf53e45b2
commit
2255887574
@ -1940,18 +1940,42 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
|
||||
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)))
|
||||
|
Loading…
Reference in New Issue
Block a user