Add support for byval function whose argument is not 32 bit aligned.
To do this it is necessary to add a "always inline" argument to the
memcpy node. For completeness I have also added this node to memmove
and memset. I have also added getMem* functions, because the extra
argument makes it cumbersome to use getNode and because I get confused
by it :-)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43172 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 9516dff..1ad8e80 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -2506,18 +2506,31 @@
break;
}
+ SDOperand Tmp6;
+ switch (getTypeAction(Node->getOperand(5).getValueType())) { // bool
+ case Expand: assert(0 && "Cannot expand this yet!");
+ case Legal:
+ Tmp6 = LegalizeOp(Node->getOperand(5));
+ break;
+ case Promote:
+ Tmp6 = PromoteOp(Node->getOperand(5));
+ break;
+ }
+
switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
default: assert(0 && "This action not implemented for this operation!");
case TargetLowering::Custom:
isCustom = true;
// FALLTHROUGH
- case TargetLowering::Legal:
- Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5);
+ case TargetLowering::Legal: {
+ SDOperand Ops[] = { Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6 };
+ Result = DAG.UpdateNodeOperands(Result, Ops, 6);
if (isCustom) {
Tmp1 = TLI.LowerOperation(Result, DAG);
if (Tmp1.Val) Result = Tmp1;
}
break;
+ }
case TargetLowering::Expand: {
// Otherwise, the target does not support this operation. Lower the
// operation to an explicit libcall as appropriate.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e6ce2eb..09e8b57 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2269,6 +2269,30 @@
return getNode(Opcode, VT, Ops, 5);
}
+SDOperand SelectionDAG::getMemcpy(SDOperand Chain, SDOperand Dest,
+ SDOperand Src, SDOperand Size,
+ SDOperand Align,
+ SDOperand AlwaysInline) {
+ SDOperand Ops[] = { Chain, Dest, Src, Size, Align, AlwaysInline };
+ return getNode(ISD::MEMCPY, MVT::Other, Ops, 6);
+}
+
+SDOperand SelectionDAG::getMemmove(SDOperand Chain, SDOperand Dest,
+ SDOperand Src, SDOperand Size,
+ SDOperand Align,
+ SDOperand AlwaysInline) {
+ SDOperand Ops[] = { Chain, Dest, Src, Size, Align, AlwaysInline };
+ return getNode(ISD::MEMMOVE, MVT::Other, Ops, 6);
+}
+
+SDOperand SelectionDAG::getMemset(SDOperand Chain, SDOperand Dest,
+ SDOperand Src, SDOperand Size,
+ SDOperand Align,
+ SDOperand AlwaysInline) {
+ SDOperand Ops[] = { Chain, Dest, Src, Size, Align, AlwaysInline };
+ return getNode(ISD::MEMSET, MVT::Other, Ops, 6);
+}
+
SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
SDOperand Chain, SDOperand Ptr,
const Value *SV, int SVOffset,
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index a5b6300..f69b095 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -4367,7 +4367,22 @@
}
}
- DAG.setRoot(DAG.getNode(Op, MVT::Other, getRoot(), Op1, Op2, Op3, Op4));
+ SDOperand AlwaysInline = DAG.getConstant(0, MVT::i1);
+ SDOperand Node;
+ switch(Op) {
+ default:
+ assert(0 && "Unknown Op");
+ case ISD::MEMCPY:
+ Node = DAG.getMemcpy(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline);
+ break;
+ case ISD::MEMMOVE:
+ Node = DAG.getMemmove(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline);
+ break;
+ case ISD::MEMSET:
+ Node = DAG.getMemset(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline);
+ break;
+ }
+ DAG.setRoot(Node);
}
//===----------------------------------------------------------------------===//