[llvm-commits] [llvm] r43197 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Chris Lattner
sabre at nondot.org
Fri Oct 19 21:07:07 PDT 2007
Author: lattner
Date: Fri Oct 19 23:07:07 2007
New Revision: 43197
URL: http://llvm.org/viewvc/llvm-project?rev=43197&view=rev
Log:
Implement promote and expand for operands of memcpy and friends.
This fixes CodeGen/X86/mem*.ll.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=43197&r1=43196&r2=43197&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Fri Oct 19 23:07:07 2007
@@ -119,10 +119,20 @@
}
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 @@
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 @@
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 @@
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.
More information about the llvm-commits
mailing list