aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-10-20 04:07:07 +0000
committerChris Lattner <sabre@nondot.org>2007-10-20 04:07:07 +0000
commitd20154c76286a750a0bcd270909190871e95c149 (patch)
treeb961b263aefc5abfd6b72412545eae8464036d75 /lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
parentb9d5e7cdc9ce587f27e0ea9ced35db60f2601d2e (diff)
Implement promote and expand for operands of memcpy and friends.
This fixes CodeGen/X86/mem*.ll. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43197 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
index e2905d0653..dca937d562 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
@@ -119,10 +119,20 @@ private:
}
void SetPromotedOp(SDOperand Op, SDOperand Result);
+ /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final
+ /// size.
+ SDOperand GetPromotedZExtOp(SDOperand Op) {
+ MVT::ValueType OldVT = Op.getValueType();
+ Op = GetPromotedOp(Op);
+ return DAG.getZeroExtendInReg(Op, OldVT);
+ }
+
void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi);
+ // Common routines.
SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT);
+ SDOperand HandleMemIntrinsic(SDNode *N);
// Result Promotion.
void PromoteResult(SDNode *N, unsigned ResNo);
@@ -440,6 +450,52 @@ SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op,
return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0);
}
+
+/// HandleMemIntrinsic - This handles memcpy/memset/memmove with invalid
+/// operands. This promotes or expands the operands as required.
+SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) {
+ // The chain and pointer [operands #0 and #1] are always valid types.
+ SDOperand Chain = N->getOperand(0);
+ SDOperand Ptr = N->getOperand(1);
+ SDOperand Op2 = N->getOperand(2);
+
+ // Op #2 is either a value (memset) or a pointer. Promote it if required.
+ switch (getTypeAction(Op2.getValueType())) {
+ default: assert(0 && "Unknown action for pointer/value operand");
+ case Legal: break;
+ case Promote: Op2 = GetPromotedOp(Op2); break;
+ }
+
+ // The length could have any action required.
+ SDOperand Length = N->getOperand(3);
+ switch (getTypeAction(Length.getValueType())) {
+ default: assert(0 && "Unknown action for memop operand");
+ case Legal: break;
+ case Promote: Length = GetPromotedZExtOp(Length); break;
+ case Expand:
+ SDOperand Dummy; // discard the high part.
+ GetExpandedOp(Length, Length, Dummy);
+ break;
+ }
+
+ SDOperand Align = N->getOperand(4);
+ switch (getTypeAction(Align.getValueType())) {
+ default: assert(0 && "Unknown action for memop operand");
+ case Legal: break;
+ case Promote: Align = GetPromotedZExtOp(Align); break;
+ }
+
+ SDOperand AlwaysInline = N->getOperand(5);
+ switch (getTypeAction(AlwaysInline.getValueType())) {
+ default: assert(0 && "Unknown action for memop operand");
+ case Legal: break;
+ case Promote: AlwaysInline = GetPromotedZExtOp(AlwaysInline); break;
+ }
+
+ SDOperand Ops[] = { Chain, Ptr, Op2, Length, Align, AlwaysInline };
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6);
+}
+
//===----------------------------------------------------------------------===//
// Result Promotion
//===----------------------------------------------------------------------===//
@@ -1249,6 +1305,9 @@ bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) {
case ISD::STORE: Res = PromoteOperand_STORE(cast<StoreSDNode>(N),
OpNo); break;
+ case ISD::MEMSET:
+ case ISD::MEMCPY:
+ case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break;
}
// If the result is null, the sub-method took care of registering results etc.
@@ -1447,6 +1506,9 @@ bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) {
case ISD::SETCC: Res = ExpandOperand_SETCC(N); break;
case ISD::STORE: Res = ExpandOperand_STORE(cast<StoreSDNode>(N), OpNo); break;
+ case ISD::MEMSET:
+ case ISD::MEMCPY:
+ case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break;
}
// If the result is null, the sub-method took care of registering results etc.