mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-13 17:20:28 +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;
|
break;
|
||||||
case ISD::TRUNCSTORE:
|
case ISD::TRUNCSTORE:
|
||||||
case ISD::SIGN_EXTEND_INREG:
|
case ISD::SIGN_EXTEND_INREG:
|
||||||
case ISD::ZERO_EXTEND_INREG:
|
|
||||||
case ISD::FP_ROUND_INREG:
|
case ISD::FP_ROUND_INREG:
|
||||||
case ISD::EXTLOAD:
|
case ISD::EXTLOAD:
|
||||||
case ISD::SEXTLOAD:
|
case ISD::SEXTLOAD:
|
||||||
@ -286,6 +285,12 @@ SelectionDAG::~SelectionDAG() {
|
|||||||
delete AllNodes[i];
|
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) {
|
SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT) {
|
||||||
assert(MVT::isInteger(VT) && "Cannot create FP integer constant!");
|
assert(MVT::isInteger(VT) && "Cannot create FP integer constant!");
|
||||||
// Mask out any bits that are not valid for this 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
|
// ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which
|
||||||
// we don't have yet.
|
// we don't have yet.
|
||||||
|
|
||||||
// and (zero_extend_inreg x:16:32), 1 -> and x, 1
|
// and (sign_extend_inreg x:16:32), 1 -> and x, 1
|
||||||
if (N1.getOpcode() == ISD::ZERO_EXTEND_INREG ||
|
if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) {
|
||||||
N1.getOpcode() == ISD::SIGN_EXTEND_INREG) {
|
|
||||||
// If we are masking out the part of our input that was extended, just
|
// If we are masking out the part of our input that was extended, just
|
||||||
// mask the input to the extension directly.
|
// mask the input to the extension directly.
|
||||||
unsigned ExtendBits =
|
unsigned ExtendBits =
|
||||||
@ -783,6 +787,31 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
|||||||
if ((C2 & (~0ULL << ExtendBits)) == 0)
|
if ((C2 & (~0ULL << ExtendBits)) == 0)
|
||||||
return getNode(ISD::AND, VT, N1.getOperand(0), N2);
|
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;
|
break;
|
||||||
case ISD::OR:
|
case ISD::OR:
|
||||||
if (!C2)return N1; // X or 0 -> X
|
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))
|
if (isa<ConstantFPSDNode>(N1))
|
||||||
return getNode(ISD::FP_EXTEND, VT, getNode(ISD::FP_ROUND, EVT, N1));
|
return getNode(ISD::FP_EXTEND, VT, getNode(ISD::FP_ROUND, EVT, N1));
|
||||||
break;
|
break;
|
||||||
case ISD::ZERO_EXTEND_INREG:
|
|
||||||
case ISD::SIGN_EXTEND_INREG:
|
case ISD::SIGN_EXTEND_INREG:
|
||||||
assert(VT == N1.getValueType() && "Not an inreg extend!");
|
assert(VT == N1.getValueType() && "Not an inreg extend!");
|
||||||
assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
|
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
|
if (EVT == VT) return N1; // Not actually extending
|
||||||
assert(EVT < VT && "Not 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)) {
|
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
|
||||||
SDOperand Tmp = getNode(ISD::TRUNCATE, EVT, N1);
|
SDOperand Tmp = getNode(ISD::TRUNCATE, EVT, N1);
|
||||||
if (Opcode == ISD::ZERO_EXTEND_INREG)
|
return getNode(ISD::SIGN_EXTEND, VT, Tmp);
|
||||||
return getNode(ISD::ZERO_EXTEND, VT, Tmp);
|
|
||||||
else
|
|
||||||
return getNode(ISD::SIGN_EXTEND, VT, Tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are sign extending an extension, use the original source.
|
// If we are sign extending an extension, use the original source.
|
||||||
if (N1.getOpcode() == ISD::ZERO_EXTEND_INREG ||
|
if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG)
|
||||||
N1.getOpcode() == ISD::SIGN_EXTEND_INREG) {
|
if (cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
|
||||||
if (N1.getOpcode() == Opcode &&
|
|
||||||
cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
|
|
||||||
return N1;
|
return N1;
|
||||||
}
|
|
||||||
|
|
||||||
// If we are (zero|sign) extending a [zs]extload, return just the load.
|
// If we are sign extending a sextload, return just the load.
|
||||||
if ((N1.getOpcode() == ISD::ZEXTLOAD && Opcode == ISD::ZERO_EXTEND_INREG) ||
|
if (N1.getOpcode() == ISD::SEXTLOAD && Opcode == ISD::SIGN_EXTEND_INREG)
|
||||||
(N1.getOpcode() == ISD::SEXTLOAD && Opcode == ISD::SIGN_EXTEND_INREG))
|
|
||||||
if (cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
|
if (cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
|
||||||
return N1;
|
return N1;
|
||||||
|
|
||||||
// If we are extending the result of a setcc, and we already know the
|
// If we are extending the result of a setcc, and we already know the
|
||||||
// contents of the top bits, eliminate the extension.
|
// contents of the top bits, eliminate the extension.
|
||||||
if (N1.getOpcode() == ISD::SETCC)
|
if (N1.getOpcode() == ISD::SETCC &&
|
||||||
switch (TLI.getSetCCResultContents()) {
|
TLI.getSetCCResultContents() ==
|
||||||
case TargetLowering::UndefinedSetCCResult: break;
|
TargetLowering::ZeroOrNegativeOneSetCCResult)
|
||||||
case TargetLowering::ZeroOrOneSetCCResult:
|
return N1;
|
||||||
if (Opcode == ISD::ZERO_EXTEND_INREG) return N1;
|
|
||||||
break;
|
|
||||||
case TargetLowering::ZeroOrNegativeOneSetCCResult:
|
|
||||||
if (Opcode == ISD::SIGN_EXTEND_INREG) return N1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are sign extending the result of an (and X, C) operation, and we
|
// 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.
|
// 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))) {
|
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
|
||||||
uint64_t Mask = N1C->getValue();
|
uint64_t Mask = N1C->getValue();
|
||||||
unsigned NumBits = MVT::getSizeInBits(EVT);
|
unsigned NumBits = MVT::getSizeInBits(EVT);
|
||||||
if (Opcode == ISD::ZERO_EXTEND_INREG) {
|
if ((Mask & (~0ULL << (NumBits-1))) == 0)
|
||||||
if ((Mask & (~0ULL << NumBits)) == 0)
|
return N1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1177,7 +1183,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
|||||||
case ISD::EXTLOAD:
|
case ISD::EXTLOAD:
|
||||||
case ISD::SEXTLOAD:
|
case ISD::SEXTLOAD:
|
||||||
case ISD::ZEXTLOAD:
|
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.
|
// normal load.
|
||||||
if (VT == EVT)
|
if (VT == EVT)
|
||||||
return getNode(ISD::LOAD, VT, N1, N2);
|
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::SIGN_EXTEND: return "sign_extend";
|
||||||
case ISD::ZERO_EXTEND: return "zero_extend";
|
case ISD::ZERO_EXTEND: return "zero_extend";
|
||||||
case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg";
|
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::TRUNCATE: return "truncate";
|
||||||
case ISD::FP_ROUND: return "fp_round";
|
case ISD::FP_ROUND: return "fp_round";
|
||||||
case ISD::FP_ROUND_INREG: return "fp_round_inreg";
|
case ISD::FP_ROUND_INREG: return "fp_round_inreg";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user