summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-04-13 02:38:18 +0000
committerChris Lattner <sabre@nondot.org>2005-04-13 02:38:18 +0000
commit0f2287baa18fb1c6a7e8ba42ba5163c2845b8654 (patch)
treead238f0d978642a53cb6d1671bf99a9f8591e17f /lib
parent1ccae666f596d5aeca5c9942995763600b622062 (diff)
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
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp87
1 files changed, 46 insertions, 41 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 31289464577..08b702f4a33 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -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";