mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Generalize (zext (truncate x)) and (sext (truncate x)) folding to work when
the src/dst are not the same size. This catches things like "truncate 32-bit X to 8 bits, then zext to 16", which happens a bit on X86. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30557 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1766,12 +1766,18 @@ 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) iff x size == sext size.
|
// fold (sext (truncate x)) -> (sextinreg x).
|
||||||
if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&&
|
if (N0.getOpcode() == ISD::TRUNCATE &&
|
||||||
(!AfterLegalize ||
|
(!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, VT))) {
|
||||||
TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, N0.getValueType())))
|
SDOperand Op = N0.getOperand(0);
|
||||||
return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, 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);
|
||||||
|
}
|
||||||
|
return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, Op,
|
||||||
DAG.getValueType(N0.getValueType()));
|
DAG.getValueType(N0.getValueType()));
|
||||||
|
}
|
||||||
|
|
||||||
// fold (sext (load x)) -> (sext (truncate (sextload x)))
|
// fold (sext (load x)) -> (sext (truncate (sextload x)))
|
||||||
if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
|
if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
|
||||||
@@ -1812,10 +1818,19 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
|
|||||||
// fold (zext (aext x)) -> (zext x)
|
// fold (zext (aext x)) -> (zext x)
|
||||||
if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
|
if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
|
||||||
return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0));
|
return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0));
|
||||||
// fold (zext (truncate x)) -> (zextinreg x) iff x size == zext size.
|
|
||||||
if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&&
|
// fold (zext (truncate x)) -> (and x, mask)
|
||||||
(!AfterLegalize || TLI.isOperationLegal(ISD::AND, N0.getValueType())))
|
if (N0.getOpcode() == ISD::TRUNCATE &&
|
||||||
return DAG.getZeroExtendInReg(N0.getOperand(0), N0.getValueType());
|
(!AfterLegalize || TLI.isOperationLegal(ISD::AND, VT))) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return DAG.getZeroExtendInReg(Op, N0.getValueType());
|
||||||
|
}
|
||||||
|
|
||||||
// fold (zext (load x)) -> (zext (truncate (zextload x)))
|
// fold (zext (load x)) -> (zext (truncate (zextload x)))
|
||||||
if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
|
if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
|
||||||
(!AfterLegalize||TLI.isOperationLegal(ISD::ZEXTLOAD, N0.getValueType()))){
|
(!AfterLegalize||TLI.isOperationLegal(ISD::ZEXTLOAD, N0.getValueType()))){
|
||||||
|
Reference in New Issue
Block a user