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:
parent
ab5d0ac02c
commit
fce448f856
|
@ -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)))
|
||||||
|
|
Loading…
Reference in New Issue