diff options
| author | Ed Schouten <ed@FreeBSD.org> | 2009-06-23 14:50:01 +0000 |
|---|---|---|
| committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-23 14:50:01 +0000 |
| commit | 0408e1d309a743aca4ed4592cf2c712a71537901 (patch) | |
| tree | 6be075b410677415707e0987e3a49123130cef22 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
| parent | b2f21fb044b6b5c52cff6227f9f79ca4ed42b18f (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a9adce8fdc5d..ce01d53d60e7 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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; |
