mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-19 04:29:21 +00:00
Remove all foldings of ZERO_EXTEND_INREG, moving them to work for AND nodes
instead. OVerall, this increases the amount of folding we can do. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21265 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1ccae666f5
commit
0f2287baa1
@ -235,7 +235,6 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
|
||||
break;
|
||||
case ISD::TRUNCSTORE:
|
||||
case ISD::SIGN_EXTEND_INREG:
|
||||
case ISD::ZERO_EXTEND_INREG:
|
||||
case ISD::FP_ROUND_INREG:
|
||||
case ISD::EXTLOAD:
|
||||
case ISD::SEXTLOAD:
|
||||
@ -286,6 +285,12 @@ SelectionDAG::~SelectionDAG() {
|
||||
delete AllNodes[i];
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getZeroExtendInReg(SDOperand Op, MVT::ValueType VT) {
|
||||
int64_t Imm = ~0ULL >> 64-MVT::getSizeInBits(VT);
|
||||
return getNode(ISD::AND, Op.getValueType(), Op,
|
||||
getConstant(Imm, Op.getValueType()));
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT) {
|
||||
assert(MVT::isInteger(VT) && "Cannot create FP integer constant!");
|
||||
// Mask out any bits that are not valid for this constant.
|
||||
@ -773,9 +778,8 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
// ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which
|
||||
// we don't have yet.
|
||||
|
||||
// and (zero_extend_inreg x:16:32), 1 -> and x, 1
|
||||
if (N1.getOpcode() == ISD::ZERO_EXTEND_INREG ||
|
||||
N1.getOpcode() == ISD::SIGN_EXTEND_INREG) {
|
||||
// and (sign_extend_inreg x:16:32), 1 -> and x, 1
|
||||
if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) {
|
||||
// If we are masking out the part of our input that was extended, just
|
||||
// mask the input to the extension directly.
|
||||
unsigned ExtendBits =
|
||||
@ -783,6 +787,31 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
if ((C2 & (~0ULL << ExtendBits)) == 0)
|
||||
return getNode(ISD::AND, VT, N1.getOperand(0), N2);
|
||||
}
|
||||
if (N1.getOpcode() == ISD::AND)
|
||||
if (ConstantSDNode *OpRHS = dyn_cast<ConstantSDNode>(N1.getOperand(1)))
|
||||
return getNode(ISD::AND, VT, N1.getOperand(0),
|
||||
getNode(ISD::AND, VT, N1.getOperand(1), N2));
|
||||
|
||||
// If we are anding the result of a setcc, and we know setcc always
|
||||
// returns 0 or 1, simplify the RHS to either be 0 or 1
|
||||
if (N1.getOpcode() == ISD::SETCC &&
|
||||
TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult)
|
||||
if (C2 & 1)
|
||||
return getNode(ISD::AND, VT, N1.getOperand(1), getConstant(1, VT));
|
||||
else
|
||||
return getConstant(0, VT);
|
||||
|
||||
if (N1.getOpcode() == ISD::ZEXTLOAD) {
|
||||
// If we are anding the result of a zext load, realize that the top bits
|
||||
// of the loaded value are already zero to simplify C2.
|
||||
unsigned SrcBits =
|
||||
MVT::getSizeInBits(cast<MVTSDNode>(N1)->getExtraValueType());
|
||||
uint64_t C3 = C2 & (~0ULL >> (64-SrcBits));
|
||||
if (C3 != C2)
|
||||
return getNode(ISD::AND, VT, N1, getConstant(C3, VT));
|
||||
else if (C2 == (~0ULL >> (64-SrcBits)))
|
||||
return N1; // Anding out just what is already masked.
|
||||
}
|
||||
break;
|
||||
case ISD::OR:
|
||||
if (!C2)return N1; // X or 0 -> X
|
||||
@ -1092,7 +1121,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
if (isa<ConstantFPSDNode>(N1))
|
||||
return getNode(ISD::FP_EXTEND, VT, getNode(ISD::FP_ROUND, EVT, N1));
|
||||
break;
|
||||
case ISD::ZERO_EXTEND_INREG:
|
||||
case ISD::SIGN_EXTEND_INREG:
|
||||
assert(VT == N1.getValueType() && "Not an inreg extend!");
|
||||
assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
|
||||
@ -1100,41 +1128,28 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
if (EVT == VT) return N1; // Not actually extending
|
||||
assert(EVT < VT && "Not extending!");
|
||||
|
||||
// Extending a constant? Just return the constant.
|
||||
// Extending a constant? Just return the extended constant.
|
||||
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
|
||||
SDOperand Tmp = getNode(ISD::TRUNCATE, EVT, N1);
|
||||
if (Opcode == ISD::ZERO_EXTEND_INREG)
|
||||
return getNode(ISD::ZERO_EXTEND, VT, Tmp);
|
||||
else
|
||||
return getNode(ISD::SIGN_EXTEND, VT, Tmp);
|
||||
return getNode(ISD::SIGN_EXTEND, VT, Tmp);
|
||||
}
|
||||
|
||||
// If we are sign extending an extension, use the original source.
|
||||
if (N1.getOpcode() == ISD::ZERO_EXTEND_INREG ||
|
||||
N1.getOpcode() == ISD::SIGN_EXTEND_INREG) {
|
||||
if (N1.getOpcode() == Opcode &&
|
||||
cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
|
||||
if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG)
|
||||
if (cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
|
||||
return N1;
|
||||
}
|
||||
|
||||
// If we are (zero|sign) extending a [zs]extload, return just the load.
|
||||
if ((N1.getOpcode() == ISD::ZEXTLOAD && Opcode == ISD::ZERO_EXTEND_INREG) ||
|
||||
(N1.getOpcode() == ISD::SEXTLOAD && Opcode == ISD::SIGN_EXTEND_INREG))
|
||||
// If we are sign extending a sextload, return just the load.
|
||||
if (N1.getOpcode() == ISD::SEXTLOAD && Opcode == ISD::SIGN_EXTEND_INREG)
|
||||
if (cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
|
||||
return N1;
|
||||
|
||||
// If we are extending the result of a setcc, and we already know the
|
||||
// contents of the top bits, eliminate the extension.
|
||||
if (N1.getOpcode() == ISD::SETCC)
|
||||
switch (TLI.getSetCCResultContents()) {
|
||||
case TargetLowering::UndefinedSetCCResult: break;
|
||||
case TargetLowering::ZeroOrOneSetCCResult:
|
||||
if (Opcode == ISD::ZERO_EXTEND_INREG) return N1;
|
||||
break;
|
||||
case TargetLowering::ZeroOrNegativeOneSetCCResult:
|
||||
if (Opcode == ISD::SIGN_EXTEND_INREG) return N1;
|
||||
break;
|
||||
}
|
||||
if (N1.getOpcode() == ISD::SETCC &&
|
||||
TLI.getSetCCResultContents() ==
|
||||
TargetLowering::ZeroOrNegativeOneSetCCResult)
|
||||
return N1;
|
||||
|
||||
// If we are sign extending the result of an (and X, C) operation, and we
|
||||
// know the extended bits are zeros already, don't do the extend.
|
||||
@ -1142,17 +1157,8 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
|
||||
uint64_t Mask = N1C->getValue();
|
||||
unsigned NumBits = MVT::getSizeInBits(EVT);
|
||||
if (Opcode == ISD::ZERO_EXTEND_INREG) {
|
||||
if ((Mask & (~0ULL << NumBits)) == 0)
|
||||
return N1;
|
||||
else
|
||||
return getNode(ISD::AND, VT, N1.getOperand(0),
|
||||
getConstant(Mask & (~0ULL >> (64-NumBits)), VT));
|
||||
} else {
|
||||
assert(Opcode == ISD::SIGN_EXTEND_INREG);
|
||||
if ((Mask & (~0ULL << (NumBits-1))) == 0)
|
||||
return N1;
|
||||
}
|
||||
if ((Mask & (~0ULL << (NumBits-1))) == 0)
|
||||
return N1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1177,7 +1183,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
case ISD::EXTLOAD:
|
||||
case ISD::SEXTLOAD:
|
||||
case ISD::ZEXTLOAD:
|
||||
// If they are asking for an extending loat from/to the same thing, return a
|
||||
// If they are asking for an extending load from/to the same thing, return a
|
||||
// normal load.
|
||||
if (VT == EVT)
|
||||
return getNode(ISD::LOAD, VT, N1, N2);
|
||||
@ -1325,7 +1331,6 @@ const char *SDNode::getOperationName() const {
|
||||
case ISD::SIGN_EXTEND: return "sign_extend";
|
||||
case ISD::ZERO_EXTEND: return "zero_extend";
|
||||
case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg";
|
||||
case ISD::ZERO_EXTEND_INREG: return "zero_extend_inreg";
|
||||
case ISD::TRUNCATE: return "truncate";
|
||||
case ISD::FP_ROUND: return "fp_round";
|
||||
case ISD::FP_ROUND_INREG: return "fp_round_inreg";
|
||||
|
Loading…
Reference in New Issue
Block a user