Fix memcpy expansion so it won't generate invalid
authorDale Johannesen <dalej@apple.com>
Mon, 22 Jun 2009 20:59:07 +0000 (20:59 +0000)
committerDale Johannesen <dalej@apple.com>
Mon, 22 Jun 2009 20:59:07 +0000 (20:59 +0000)
types for the target (I think).  This was breaking
the PPC32 calling sequence.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73900 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index a9adce8fdc5d69c2841605c9e4eaae93a1d4d6c4..ce01d53d60e765a3e6190d8b5d0a3de2baeb3737 100644 (file)
@@ -3121,6 +3121,8 @@ bool MeetsMaxMemopRequirement(std::vector<MVT> &MemOps,
           VT = (MVT::SimpleValueType)(VT.getSimpleVT() - 1);
         VTSize = VT.getSizeInBits() / 8;
       } else {
+        // This can result in a type that is not legal on the target, e.g.
+        // 1 or 2 bytes on PPC.
         VT = (MVT::SimpleValueType)(VT.getSimpleVT() - 1);
         VTSize >>= 1;
       }
@@ -3177,12 +3179,29 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
                            getMemBasePlusOffset(Dst, DstOff, DAG),
                            DstSV, DstSVOff + DstOff, false, DstAlign);
     } else {
-      Value = DAG.getLoad(VT, dl, Chain,
-                          getMemBasePlusOffset(Src, SrcOff, DAG),
-                          SrcSV, SrcSVOff + SrcOff, false, Align);
-      Store = DAG.getStore(Chain, dl, Value,
-                           getMemBasePlusOffset(Dst, DstOff, DAG),
-                           DstSV, DstSVOff + DstOff, false, DstAlign);
+      // The type might not be legal for the target.  This should only happen
+      // if the type is smaller than a legal type, as on PPC, so the right
+      // thing to do is generate a LoadExt/StoreTrunc pair.
+      // FIXME does the case above also need this?
+      if (TLI.isTypeLegal(VT)) {
+        Value = DAG.getLoad(VT, dl, Chain,
+                            getMemBasePlusOffset(Src, SrcOff, DAG),
+                            SrcSV, SrcSVOff + SrcOff, false, Align);
+        Store = DAG.getStore(Chain, dl, Value,
+                             getMemBasePlusOffset(Dst, DstOff, DAG),
+                             DstSV, DstSVOff + DstOff, false, DstAlign);
+      } else {
+        MVT NVT = VT;
+        while (!TLI.isTypeLegal(NVT)) {
+          NVT = (MVT::SimpleValueType(NVT.getSimpleVT() + 1));
+        }
+        Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
+                               getMemBasePlusOffset(Src, SrcOff, DAG),
+                               SrcSV, SrcSVOff + SrcOff, VT, false, Align);
+        Store = DAG.getTruncStore(Chain, dl, Value,
+                               getMemBasePlusOffset(Dst, DstOff, DAG),
+                               DstSV, DstSVOff + DstOff, VT, false, DstAlign);
+      }
     }
     OutChains.push_back(Store);
     SrcOff += VTSize;