aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-10-17 13:49:58 +0000
committerDuncan Sands <baldrick@free.fr>2007-10-17 13:49:58 +0000
commitf411b83c8c6853c2a922b692e782566353153f08 (patch)
tree3793516c2009fa295c5fb2c1a1894cdfe38c72b5 /lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
parentafc407ea5196b6ce638c25bd21569270504bb604 (diff)
Return Expand from getOperationAction for all extended
types. This is needed for SIGN_EXTEND_INREG at least. It is not clear if this is correct for other operations. On the other hand, for the various load/store actions it seems to correct to return the type action, as is currently done. Also, it seems that SelectionDAG::getValueType can be called for extended value types; introduce a map for holding these, since we don't really want to extend the vector to be 2^32 pointers long! Generalize DAGTypeLegalizer::PromoteResult_TRUNCATE and DAGTypeLegalizer::PromoteResult_INT_EXTEND to handle the various funky possibilities that apints introduce, for example that you can promote to a type that needs to be expanded. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43071 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp72
1 files changed, 39 insertions, 33 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
index 8752698098..8c87f644b3 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
@@ -390,7 +390,6 @@ void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) {
OpEntry = Result;
}
-
void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo,
SDOperand &Hi) {
std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op];
@@ -479,46 +478,53 @@ SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) {
}
SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) {
- MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ SDOperand Res;
+
switch (getTypeAction(N->getOperand(0).getValueType())) {
default: assert(0 && "Unknown type action!");
- case Legal: {
- SDOperand Res = N->getOperand(0);
- assert(Res.getValueType() >= NVT && "Truncation doesn't make sense!");
- if (Res.getValueType() > NVT) // Truncate to NVT instead of VT
- return DAG.getNode(ISD::TRUNCATE, NVT, Res);
- return Res;
- }
- case Promote:
- // The truncation is not required, because we don't guarantee anything
- // about high bits anyway.
- return GetPromotedOp(N->getOperand(0));
+ case Legal:
case Expand:
- // Truncate the low part of the expanded value to the result type
- SDOperand Lo, Hi;
- GetExpandedOp(N->getOperand(0), Lo, Hi);
- return DAG.getNode(ISD::TRUNCATE, NVT, Lo);
+ Res = N->getOperand(0);
+ break;
+ case Promote:
+ Res = GetPromotedOp(N->getOperand(0));
+ break;
}
+
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ assert(MVT::getSizeInBits(Res.getValueType()) >= MVT::getSizeInBits(NVT) &&
+ "Truncation doesn't make sense!");
+ if (Res.getValueType() == NVT)
+ return Res;
+
+ // Truncate to NVT instead of VT
+ return DAG.getNode(ISD::TRUNCATE, NVT, Res);
}
+
SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) {
MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- switch (getTypeAction(N->getOperand(0).getValueType())) {
- default: assert(0 && "BUG: Smaller reg should have been promoted!");
- case Legal:
- // Input is legal? Just do extend all the way to the larger type.
- return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
- case Promote:
- // Get promoted operand if it is smaller.
+
+ if (getTypeAction(N->getOperand(0).getValueType()) == Promote) {
SDOperand Res = GetPromotedOp(N->getOperand(0));
- // The high bits are not guaranteed to be anything. Insert an extend.
- if (N->getOpcode() == ISD::SIGN_EXTEND)
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
- DAG.getValueType(N->getOperand(0).getValueType()));
- if (N->getOpcode() == ISD::ZERO_EXTEND)
- return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
- assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
- return Res;
+ assert(MVT::getSizeInBits(Res.getValueType()) <= MVT::getSizeInBits(NVT) &&
+ "Extension doesn't make sense!");
+
+ // If the result and operand types are the same after promotion, simplify
+ // to an in-register extension.
+ if (NVT == Res.getValueType()) {
+ // The high bits are not guaranteed to be anything. Insert an extend.
+ if (N->getOpcode() == ISD::SIGN_EXTEND)
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
+ DAG.getValueType(N->getOperand(0).getValueType()));
+ if (N->getOpcode() == ISD::ZERO_EXTEND)
+ return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
+ assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
+ return Res;
+ }
}
+
+ // Otherwise, just extend the original operand all the way to the larger type.
+ return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
}
SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
@@ -527,7 +533,6 @@ SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
N->getOperand(0), DAG.getValueType(N->getValueType(0)));
}
-
SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) {
assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??");
return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0),
@@ -1198,6 +1203,7 @@ SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) {
Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
}
+
SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) {
SDOperand Op = GetPromotedOp(N->getOperand(0));
Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);