aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h34
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp47
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp141
4 files changed, 135 insertions, 89 deletions
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index caa2703530..fb9a10ff95 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -100,6 +100,7 @@ public:
SDOperand getConstantPool(unsigned CPIdx, MVT::ValueType VT);
SDOperand getBasicBlock(MachineBasicBlock *MBB);
SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT);
+ SDOperand getValueType(MVT::ValueType);
SDOperand getCopyToReg(SDOperand Chain, SDOperand N, unsigned Reg) {
// Note: these are auto-CSE'd because the caller doesn't make requests that
@@ -225,6 +226,7 @@ private:
std::map<int, SDNode*> FrameIndices;
std::map<unsigned, SDNode*> ConstantPoolIndices;
std::map<MachineBasicBlock *, SDNode*> BBNodes;
+ std::vector<SDNode*> ValueTypeNodes;
std::map<std::pair<unsigned,
std::pair<MVT::ValueType, std::vector<SDOperand> > >,
SDNode*> OneResultNodes;
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 7c8d044eed..a289772ff0 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -55,7 +55,7 @@ namespace ISD {
// Various leaf nodes.
Constant, ConstantFP, GlobalAddress, FrameIndex, ConstantPool,
- BasicBlock, ExternalSymbol,
+ BasicBlock, ExternalSymbol, VALUETYPE,
// CopyToReg - This node has chain and child nodes, and an associated
// register number. The instruction selector must guarantee that the value
@@ -148,8 +148,8 @@ namespace ISD {
// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
// sign extend a small value in a large integer register (e.g. sign
// extending the low 8 bits of a 32-bit register to fill the top 24 bits
- // with the 7th bit). The size of the smaller type is indicated by the
- // ExtraValueType in the MVTSDNode for the operator.
+ // with the 7th bit). The size of the smaller type is indicated by the 1th
+ // operand, a ValueType node.
SIGN_EXTEND_INREG,
// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
@@ -164,8 +164,8 @@ namespace ISD {
// FP_ROUND_INREG - This operator takes a floating point register, and
// rounds it to a floating point value. It then promotes it and returns it
// in a register of the same size. This operation effectively just discards
- // excess precision. The type to round down to is specified by the
- // ExtraValueType in the MVTSDNode (currently always 64->32->64).
+ // excess precision. The type to round down to is specified by the 1th
+ // operation, a VTSDNode (currently always 64->32->64).
FP_ROUND_INREG,
// FP_EXTEND - Extend a smaller FP type into a larger FP type.
@@ -843,6 +843,25 @@ public:
}
};
+/// VTSDNode - This class is used to represent MVT::ValueType's, which are used
+/// to parameterize some operations.
+class VTSDNode : public SDNode {
+ MVT::ValueType ValueType;
+protected:
+ friend class SelectionDAG;
+ VTSDNode(MVT::ValueType VT)
+ : SDNode(ISD::VALUETYPE, MVT::Other), ValueType(VT) {}
+public:
+
+ MVT::ValueType getVT() const { return ValueType; }
+
+ static bool classof(const VTSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::VALUETYPE;
+ }
+};
+
+
/// MVTSDNode - This class is used for operators that require an extra
/// value-type to be kept with the node.
class MVTSDNode : public SDNode {
@@ -871,8 +890,6 @@ public:
static bool classof(const MVTSDNode *) { return true; }
static bool classof(const SDNode *N) {
return
- N->getOpcode() == ISD::SIGN_EXTEND_INREG ||
- N->getOpcode() == ISD::FP_ROUND_INREG ||
N->getOpcode() == ISD::EXTLOAD ||
N->getOpcode() == ISD::SEXTLOAD ||
N->getOpcode() == ISD::ZEXTLOAD ||
@@ -931,9 +948,6 @@ template <> struct GraphTraits<SDNode*> {
}
};
-
-
-
} // end llvm namespace
#endif
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index a9721e2e48..c6fc076ee2 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -539,7 +539,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
SDOperand ValRes;
if (Node->getOpcode() == ISD::SEXTLOAD)
ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
- Result, SrcVT);
+ Result, DAG.getValueType(SrcVT));
else
ValRes = DAG.getZeroExtendInReg(Result, SrcVT);
AddLegalizedOperand(SDOperand(Node, 0), ValRes);
@@ -808,8 +808,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case ISD::SETGT:
case ISD::SETLT:
case ISD::SETLE:
- Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, VT);
- Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, VT);
+ Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
+ DAG.getValueType(VT));
+ Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2,
+ DAG.getValueType(VT));
break;
}
@@ -1403,7 +1405,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
// NOTE: Any extend would work here...
Result = DAG.getNode(ISD::ZERO_EXTEND, Op.getValueType(), Result);
Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
- Result, Node->getOperand(0).getValueType());
+ Result,
+ DAG.getValueType(Node->getOperand(0).getValueType()));
break;
case ISD::TRUNCATE:
Result = PromoteOp(Node->getOperand(0));
@@ -1424,7 +1427,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case ISD::SINT_TO_FP:
Result = PromoteOp(Node->getOperand(0));
Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
- Result, Node->getOperand(0).getValueType());
+ Result,
+ DAG.getValueType(Node->getOperand(0).getValueType()));
Result = DAG.getNode(ISD::SINT_TO_FP, Op.getValueType(), Result);
break;
case ISD::UINT_TO_FP:
@@ -1439,7 +1443,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case ISD::FP_ROUND_INREG:
case ISD::SIGN_EXTEND_INREG: {
Tmp1 = LegalizeOp(Node->getOperand(0));
- MVT::ValueType ExtraVT = cast<MVTSDNode>(Node)->getExtraValueType();
+ MVT::ValueType ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
// If this operation is not supported, convert it to a shl/shr or load/store
// pair.
@@ -1593,7 +1597,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
// The high bits are not guaranteed to be anything. Insert an extend.
if (Node->getOpcode() == ISD::SIGN_EXTEND)
Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result,
- Node->getOperand(0).getValueType());
+ DAG.getValueType(Node->getOperand(0).getValueType()));
else
Result = DAG.getZeroExtendInReg(Result,
Node->getOperand(0).getValueType());
@@ -1610,7 +1614,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
case Legal:
// Input is legal? Do an FP_ROUND_INREG.
Result = LegalizeOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ DAG.getValueType(VT));
break;
}
break;
@@ -1628,7 +1633,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
Result = PromoteOp(Node->getOperand(0));
if (Node->getOpcode() == ISD::SINT_TO_FP)
Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
- Result, Node->getOperand(0).getValueType());
+ Result,
+ DAG.getValueType(Node->getOperand(0).getValueType()));
else
Result = DAG.getZeroExtendInReg(Result,
Node->getOperand(0).getValueType());
@@ -1640,7 +1646,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
Node->getOperand(0));
// Round if we cannot tolerate excess precision.
if (NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ DAG.getValueType(VT));
break;
}
break;
@@ -1679,7 +1686,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
assert(Tmp1.getValueType() == NVT);
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
if(NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ DAG.getValueType(VT));
break;
case ISD::AND:
@@ -1702,7 +1710,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
// FIXME: Why would we need to round FP ops more than integer ones?
// Is Round(Add(Add(A,B),C)) != Round(Add(Round(Add(A,B)), C))
if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ DAG.getValueType(VT));
break;
case ISD::SDIV:
@@ -1711,14 +1720,17 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
Tmp1 = PromoteOp(Node->getOperand(0));
Tmp2 = PromoteOp(Node->getOperand(1));
if (MVT::isInteger(NVT)) {
- Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, VT);
- Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, VT);
+ Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
+ DAG.getValueType(VT));
+ Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2,
+ DAG.getValueType(VT));
}
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
// Perform FP_ROUND: this is probably overly pessimistic.
if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ DAG.getValueType(VT));
break;
case ISD::UDIV:
@@ -1740,7 +1752,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
case ISD::SRA:
// The input value must be properly sign extended.
Tmp1 = PromoteOp(Node->getOperand(0));
- Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, VT);
+ Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
+ DAG.getValueType(VT));
Tmp2 = LegalizeOp(Node->getOperand(1));
Result = DAG.getNode(ISD::SRA, NVT, Tmp1, Tmp2);
break;
@@ -2520,7 +2533,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
In = PromoteOp(Node->getOperand(0));
// Emit the appropriate sign_extend_inreg to get the value we want.
In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), In,
- Node->getOperand(0).getValueType());
+ DAG.getValueType(Node->getOperand(0).getValueType()));
break;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 8a34a59a15..9cf6e0f3a6 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -220,7 +220,9 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
case ISD::ExternalSymbol:
ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
break;
-
+ case ISD::VALUETYPE:
+ ValueTypeNodes[cast<VTSDNode>(N)->getVT()] = 0;
+ break;
case ISD::LOAD:
Loads.erase(std::make_pair(N->getOperand(1),
std::make_pair(N->getOperand(0),
@@ -234,8 +236,6 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
N->getValueType(0))));
break;
case ISD::TRUNCSTORE:
- case ISD::SIGN_EXTEND_INREG:
- case ISD::FP_ROUND_INREG:
case ISD::EXTLOAD:
case ISD::SEXTLOAD:
case ISD::ZEXTLOAD: {
@@ -374,6 +374,17 @@ SDOperand SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
return SDOperand(N, 0);
}
+SDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
+ if ((unsigned)VT >= ValueTypeNodes.size())
+ ValueTypeNodes.resize(VT+1);
+ if (ValueTypeNodes[VT] == 0) {
+ ValueTypeNodes[VT] = new VTSDNode(VT);
+ AllNodes.push_back(ValueTypeNodes[VT]);
+ }
+
+ return SDOperand(ValueTypeNodes[VT], 0);
+}
+
SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) {
SDNode *&N = ExternalSymbols[Sym];
if (N) return SDOperand(N, 0);
@@ -864,6 +875,22 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
assert(MVT::isInteger(VT) && MVT::isInteger(N2.getValueType()) &&
VT != MVT::i1 && "Shifts only work on integers");
break;
+ case ISD::FP_ROUND_INREG: {
+ MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
+ assert(VT == N1.getValueType() && "Not an inreg round!");
+ assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
+ "Cannot FP_ROUND_INREG integer types");
+ assert(EVT <= VT && "Not rounding down!");
+ break;
+ }
+ case ISD::SIGN_EXTEND_INREG: {
+ MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
+ assert(VT == N1.getValueType() && "Not an inreg extend!");
+ assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
+ "Cannot *_EXTEND_INREG FP types");
+ assert(EVT <= VT && "Not extending!");
+ }
+
default: break;
}
#endif
@@ -918,6 +945,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
case ISD::SRA: // sra -1, X -> -1
if (N1C->isAllOnesValue()) return N1;
break;
+ case ISD::SIGN_EXTEND_INREG: // SIGN_EXTEND_INREG N1C, EVT
+ // Extending a constant? Just return the extended constant.
+ SDOperand Tmp = getNode(ISD::TRUNCATE, cast<VTSDNode>(N2)->getVT(), N1);
+ return getNode(ISD::SIGN_EXTEND, VT, Tmp);
}
}
@@ -1026,7 +1057,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
// If we are masking out the part of our input that was extended, just
// mask the input to the extension directly.
unsigned ExtendBits =
- MVT::getSizeInBits(cast<MVTSDNode>(N1)->getExtraValueType());
+ MVT::getSizeInBits(cast<VTSDNode>(N1.getOperand(1))->getVT());
if ((C2 & (~0ULL << ExtendBits)) == 0)
return getNode(ISD::AND, VT, N1.getOperand(0), N2);
}
@@ -1072,7 +1103,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2.Val);
- if (N1CFP)
+ if (N1CFP) {
if (N2CFP) {
double C1 = N1CFP->getValue(), C2 = N2CFP->getValue();
switch (Opcode) {
@@ -1095,6 +1126,11 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
}
}
+ if (Opcode == ISD::FP_ROUND_INREG)
+ return getNode(ISD::FP_EXTEND, VT,
+ getNode(ISD::FP_ROUND, cast<VTSDNode>(N2)->getVT(), N1));
+ }
+
// Finally, fold operations that do not require constants.
switch (Opcode) {
case ISD::TokenFactor:
@@ -1199,6 +1235,42 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B
return getNode(ISD::ADD, VT, N1, N2.getOperand(0));
break;
+ case ISD::FP_ROUND_INREG:
+ if (cast<VTSDNode>(N2)->getVT() == VT) return N1; // Not actually rounding.
+ break;
+ case ISD::SIGN_EXTEND_INREG: {
+ MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
+ if (EVT == VT) return N1; // Not actually extending
+
+ // If we are sign extending an extension, use the original source.
+ if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG)
+ if (cast<VTSDNode>(N1.getOperand(1))->getVT() <= EVT)
+ return N1;
+
+ // If we are sign extending a sextload, return just the load.
+ if (N1.getOpcode() == ISD::SEXTLOAD)
+ 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 &&
+ 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.
+ if (N1.getOpcode() == ISD::AND)
+ if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
+ uint64_t Mask = N1C->getValue();
+ unsigned NumBits = MVT::getSizeInBits(EVT);
+ if ((Mask & (~0ULL << (NumBits-1))) == 0)
+ return N1;
+ }
+ break;
+ }
+
// FIXME: figure out how to safely handle things like
// int foo(int x) { return 1 << (x & 255); }
// int bar() { return foo(256); }
@@ -1207,7 +1279,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
case ISD::SRL:
case ISD::SRA:
if (N2.getOpcode() == ISD::SIGN_EXTEND_INREG &&
- cast<MVTSDNode>(N2)->getExtraValueType() != MVT::i1)
+ cast<VTSDNode>(N2.getOperand(1))->getVT() != MVT::i1)
return getNode(Opcode, VT, N1, N2.getOperand(0));
else if (N2.getOpcode() == ISD::AND)
if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N2.getOperand(1))) {
@@ -1450,7 +1522,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode,
case ISD::SRL_PARTS:
case ISD::SHL_PARTS:
if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG &&
- cast<MVTSDNode>(N3)->getExtraValueType() != MVT::i1)
+ cast<VTSDNode>(N3.getOperand(1))->getVT() != MVT::i1)
return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
else if (N3.getOpcode() == ISD::AND)
if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N3.getOperand(1))) {
@@ -1477,61 +1549,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode,
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
MVT::ValueType EVT) {
-
- switch (Opcode) {
- default: assert(0 && "Bad opcode for this accessor!");
- case ISD::FP_ROUND_INREG:
- assert(VT == N1.getValueType() && "Not an inreg round!");
- assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
- "Cannot FP_ROUND_INREG integer types");
- if (EVT == VT) return N1; // Not actually rounding
- assert(EVT < VT && "Not rounding down!");
-
- if (isa<ConstantFPSDNode>(N1))
- return getNode(ISD::FP_EXTEND, VT, getNode(ISD::FP_ROUND, EVT, N1));
- break;
- case ISD::SIGN_EXTEND_INREG:
- assert(VT == N1.getValueType() && "Not an inreg extend!");
- assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
- "Cannot *_EXTEND_INREG FP types");
- if (EVT == VT) return N1; // Not actually extending
- assert(EVT < VT && "Not extending!");
-
- // Extending a constant? Just return the extended constant.
- if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
- SDOperand Tmp = getNode(ISD::TRUNCATE, EVT, N1);
- return getNode(ISD::SIGN_EXTEND, VT, Tmp);
- }
-
- // If we are sign extending an extension, use the original source.
- if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG)
- if (cast<MVTSDNode>(N1)->getExtraValueType() <= EVT)
- return N1;
-
- // 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 &&
- 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.
- if (N1.getOpcode() == ISD::AND)
- if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
- uint64_t Mask = N1C->getValue();
- unsigned NumBits = MVT::getSizeInBits(EVT);
- if ((Mask & (~0ULL << (NumBits-1))) == 0)
- return N1;
- }
- break;
- }
-
EVTStruct NN;
NN.Opcode = Opcode;
NN.VT = VT;