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);
 }
 
 //===----------------------------------------------------------------------===//