1*9880d681SAndroid Build Coastguard Worker //===-- ARMSelectionDAGInfo.cpp - ARM SelectionDAG Info -------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the ARMSelectionDAGInfo class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "ARMTargetMachine.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SelectionDAG.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
17*9880d681SAndroid Build Coastguard Worker using namespace llvm;
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "arm-selectiondag-info"
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker // Emit, if possible, a specialized version of the given Libcall. Typically this
22*9880d681SAndroid Build Coastguard Worker // means selecting the appropriately aligned version, but we also convert memset
23*9880d681SAndroid Build Coastguard Worker // of 0 into memclr.
EmitSpecializedLibcall(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,RTLIB::Libcall LC) const24*9880d681SAndroid Build Coastguard Worker SDValue ARMSelectionDAGInfo::EmitSpecializedLibcall(
25*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
26*9880d681SAndroid Build Coastguard Worker SDValue Size, unsigned Align, RTLIB::Libcall LC) const {
27*9880d681SAndroid Build Coastguard Worker const ARMSubtarget &Subtarget =
28*9880d681SAndroid Build Coastguard Worker DAG.getMachineFunction().getSubtarget<ARMSubtarget>();
29*9880d681SAndroid Build Coastguard Worker const ARMTargetLowering *TLI = Subtarget.getTargetLowering();
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker // Only use a specialized AEABI function if the default version of this
32*9880d681SAndroid Build Coastguard Worker // Libcall is an AEABI function.
33*9880d681SAndroid Build Coastguard Worker if (std::strncmp(TLI->getLibcallName(LC), "__aeabi", 7) != 0)
34*9880d681SAndroid Build Coastguard Worker return SDValue();
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker // Translate RTLIB::Libcall to AEABILibcall. We only do this in order to be
37*9880d681SAndroid Build Coastguard Worker // able to translate memset to memclr and use the value to index the function
38*9880d681SAndroid Build Coastguard Worker // name array.
39*9880d681SAndroid Build Coastguard Worker enum {
40*9880d681SAndroid Build Coastguard Worker AEABI_MEMCPY = 0,
41*9880d681SAndroid Build Coastguard Worker AEABI_MEMMOVE,
42*9880d681SAndroid Build Coastguard Worker AEABI_MEMSET,
43*9880d681SAndroid Build Coastguard Worker AEABI_MEMCLR
44*9880d681SAndroid Build Coastguard Worker } AEABILibcall;
45*9880d681SAndroid Build Coastguard Worker switch (LC) {
46*9880d681SAndroid Build Coastguard Worker case RTLIB::MEMCPY:
47*9880d681SAndroid Build Coastguard Worker AEABILibcall = AEABI_MEMCPY;
48*9880d681SAndroid Build Coastguard Worker break;
49*9880d681SAndroid Build Coastguard Worker case RTLIB::MEMMOVE:
50*9880d681SAndroid Build Coastguard Worker AEABILibcall = AEABI_MEMMOVE;
51*9880d681SAndroid Build Coastguard Worker break;
52*9880d681SAndroid Build Coastguard Worker case RTLIB::MEMSET:
53*9880d681SAndroid Build Coastguard Worker AEABILibcall = AEABI_MEMSET;
54*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *ConstantSrc = dyn_cast<ConstantSDNode>(Src))
55*9880d681SAndroid Build Coastguard Worker if (ConstantSrc->getZExtValue() == 0)
56*9880d681SAndroid Build Coastguard Worker AEABILibcall = AEABI_MEMCLR;
57*9880d681SAndroid Build Coastguard Worker break;
58*9880d681SAndroid Build Coastguard Worker default:
59*9880d681SAndroid Build Coastguard Worker return SDValue();
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker // Choose the most-aligned libcall variant that we can
63*9880d681SAndroid Build Coastguard Worker enum {
64*9880d681SAndroid Build Coastguard Worker ALIGN1 = 0,
65*9880d681SAndroid Build Coastguard Worker ALIGN4,
66*9880d681SAndroid Build Coastguard Worker ALIGN8
67*9880d681SAndroid Build Coastguard Worker } AlignVariant;
68*9880d681SAndroid Build Coastguard Worker if ((Align & 7) == 0)
69*9880d681SAndroid Build Coastguard Worker AlignVariant = ALIGN8;
70*9880d681SAndroid Build Coastguard Worker else if ((Align & 3) == 0)
71*9880d681SAndroid Build Coastguard Worker AlignVariant = ALIGN4;
72*9880d681SAndroid Build Coastguard Worker else
73*9880d681SAndroid Build Coastguard Worker AlignVariant = ALIGN1;
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker TargetLowering::ArgListTy Args;
76*9880d681SAndroid Build Coastguard Worker TargetLowering::ArgListEntry Entry;
77*9880d681SAndroid Build Coastguard Worker Entry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
78*9880d681SAndroid Build Coastguard Worker Entry.Node = Dst;
79*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
80*9880d681SAndroid Build Coastguard Worker if (AEABILibcall == AEABI_MEMCLR) {
81*9880d681SAndroid Build Coastguard Worker Entry.Node = Size;
82*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
83*9880d681SAndroid Build Coastguard Worker } else if (AEABILibcall == AEABI_MEMSET) {
84*9880d681SAndroid Build Coastguard Worker // Adjust parameters for memset, EABI uses format (ptr, size, value),
85*9880d681SAndroid Build Coastguard Worker // GNU library uses (ptr, value, size)
86*9880d681SAndroid Build Coastguard Worker // See RTABI section 4.3.4
87*9880d681SAndroid Build Coastguard Worker Entry.Node = Size;
88*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker // Extend or truncate the argument to be an i32 value for the call.
91*9880d681SAndroid Build Coastguard Worker if (Src.getValueType().bitsGT(MVT::i32))
92*9880d681SAndroid Build Coastguard Worker Src = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src);
93*9880d681SAndroid Build Coastguard Worker else if (Src.getValueType().bitsLT(MVT::i32))
94*9880d681SAndroid Build Coastguard Worker Src = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Src);
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker Entry.Node = Src;
97*9880d681SAndroid Build Coastguard Worker Entry.Ty = Type::getInt32Ty(*DAG.getContext());
98*9880d681SAndroid Build Coastguard Worker Entry.isSExt = false;
99*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
100*9880d681SAndroid Build Coastguard Worker } else {
101*9880d681SAndroid Build Coastguard Worker Entry.Node = Src;
102*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker Entry.Node = Size;
105*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker char const *FunctionNames[4][3] = {
109*9880d681SAndroid Build Coastguard Worker { "__aeabi_memcpy", "__aeabi_memcpy4", "__aeabi_memcpy8" },
110*9880d681SAndroid Build Coastguard Worker { "__aeabi_memmove", "__aeabi_memmove4", "__aeabi_memmove8" },
111*9880d681SAndroid Build Coastguard Worker { "__aeabi_memset", "__aeabi_memset4", "__aeabi_memset8" },
112*9880d681SAndroid Build Coastguard Worker { "__aeabi_memclr", "__aeabi_memclr4", "__aeabi_memclr8" }
113*9880d681SAndroid Build Coastguard Worker };
114*9880d681SAndroid Build Coastguard Worker TargetLowering::CallLoweringInfo CLI(DAG);
115*9880d681SAndroid Build Coastguard Worker CLI.setDebugLoc(dl)
116*9880d681SAndroid Build Coastguard Worker .setChain(Chain)
117*9880d681SAndroid Build Coastguard Worker .setCallee(
118*9880d681SAndroid Build Coastguard Worker TLI->getLibcallCallingConv(LC), Type::getVoidTy(*DAG.getContext()),
119*9880d681SAndroid Build Coastguard Worker DAG.getExternalSymbol(FunctionNames[AEABILibcall][AlignVariant],
120*9880d681SAndroid Build Coastguard Worker TLI->getPointerTy(DAG.getDataLayout())),
121*9880d681SAndroid Build Coastguard Worker std::move(Args))
122*9880d681SAndroid Build Coastguard Worker .setDiscardResult();
123*9880d681SAndroid Build Coastguard Worker std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI);
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker return CallResult.second;
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
EmitTargetCodeForMemcpy(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,bool isVolatile,bool AlwaysInline,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo) const128*9880d681SAndroid Build Coastguard Worker SDValue ARMSelectionDAGInfo::EmitTargetCodeForMemcpy(
129*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
130*9880d681SAndroid Build Coastguard Worker SDValue Size, unsigned Align, bool isVolatile, bool AlwaysInline,
131*9880d681SAndroid Build Coastguard Worker MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
132*9880d681SAndroid Build Coastguard Worker const ARMSubtarget &Subtarget =
133*9880d681SAndroid Build Coastguard Worker DAG.getMachineFunction().getSubtarget<ARMSubtarget>();
134*9880d681SAndroid Build Coastguard Worker // Do repeated 4-byte loads and stores. To be improved.
135*9880d681SAndroid Build Coastguard Worker // This requires 4-byte alignment.
136*9880d681SAndroid Build Coastguard Worker if ((Align & 3) != 0)
137*9880d681SAndroid Build Coastguard Worker return SDValue();
138*9880d681SAndroid Build Coastguard Worker // This requires the copy size to be a constant, preferably
139*9880d681SAndroid Build Coastguard Worker // within a subtarget-specific limit.
140*9880d681SAndroid Build Coastguard Worker ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
141*9880d681SAndroid Build Coastguard Worker if (!ConstantSize)
142*9880d681SAndroid Build Coastguard Worker return EmitSpecializedLibcall(DAG, dl, Chain, Dst, Src, Size, Align,
143*9880d681SAndroid Build Coastguard Worker RTLIB::MEMCPY);
144*9880d681SAndroid Build Coastguard Worker uint64_t SizeVal = ConstantSize->getZExtValue();
145*9880d681SAndroid Build Coastguard Worker if (!AlwaysInline && SizeVal > Subtarget.getMaxInlineSizeThreshold())
146*9880d681SAndroid Build Coastguard Worker return EmitSpecializedLibcall(DAG, dl, Chain, Dst, Src, Size, Align,
147*9880d681SAndroid Build Coastguard Worker RTLIB::MEMCPY);
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker unsigned BytesLeft = SizeVal & 3;
150*9880d681SAndroid Build Coastguard Worker unsigned NumMemOps = SizeVal >> 2;
151*9880d681SAndroid Build Coastguard Worker unsigned EmittedNumMemOps = 0;
152*9880d681SAndroid Build Coastguard Worker EVT VT = MVT::i32;
153*9880d681SAndroid Build Coastguard Worker unsigned VTSize = 4;
154*9880d681SAndroid Build Coastguard Worker unsigned i = 0;
155*9880d681SAndroid Build Coastguard Worker // Emit a maximum of 4 loads in Thumb1 since we have fewer registers
156*9880d681SAndroid Build Coastguard Worker const unsigned MaxLoadsInLDM = Subtarget.isThumb1Only() ? 4 : 6;
157*9880d681SAndroid Build Coastguard Worker SDValue TFOps[6];
158*9880d681SAndroid Build Coastguard Worker SDValue Loads[6];
159*9880d681SAndroid Build Coastguard Worker uint64_t SrcOff = 0, DstOff = 0;
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker // FIXME: We should invent a VMEMCPY pseudo-instruction that lowers to
162*9880d681SAndroid Build Coastguard Worker // VLDM/VSTM and make this code emit it when appropriate. This would reduce
163*9880d681SAndroid Build Coastguard Worker // pressure on the general purpose registers. However this seems harder to map
164*9880d681SAndroid Build Coastguard Worker // onto the register allocator's view of the world.
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker // The number of MEMCPY pseudo-instructions to emit. We use up to
167*9880d681SAndroid Build Coastguard Worker // MaxLoadsInLDM registers per mcopy, which will get lowered into ldm/stm
168*9880d681SAndroid Build Coastguard Worker // later on. This is a lower bound on the number of MEMCPY operations we must
169*9880d681SAndroid Build Coastguard Worker // emit.
170*9880d681SAndroid Build Coastguard Worker unsigned NumMEMCPYs = (NumMemOps + MaxLoadsInLDM - 1) / MaxLoadsInLDM;
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker // Code size optimisation: do not inline memcpy if expansion results in
173*9880d681SAndroid Build Coastguard Worker // more instructions than the libary call.
174*9880d681SAndroid Build Coastguard Worker if (NumMEMCPYs > 1 && DAG.getMachineFunction().getFunction()->optForMinSize()) {
175*9880d681SAndroid Build Coastguard Worker return SDValue();
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker SDVTList VTs = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other, MVT::Glue);
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0; I != NumMEMCPYs; ++I) {
181*9880d681SAndroid Build Coastguard Worker // Evenly distribute registers among MEMCPY operations to reduce register
182*9880d681SAndroid Build Coastguard Worker // pressure.
183*9880d681SAndroid Build Coastguard Worker unsigned NextEmittedNumMemOps = NumMemOps * (I + 1) / NumMEMCPYs;
184*9880d681SAndroid Build Coastguard Worker unsigned NumRegs = NextEmittedNumMemOps - EmittedNumMemOps;
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker Dst = DAG.getNode(ARMISD::MEMCPY, dl, VTs, Chain, Dst, Src,
187*9880d681SAndroid Build Coastguard Worker DAG.getConstant(NumRegs, dl, MVT::i32));
188*9880d681SAndroid Build Coastguard Worker Src = Dst.getValue(1);
189*9880d681SAndroid Build Coastguard Worker Chain = Dst.getValue(2);
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker DstPtrInfo = DstPtrInfo.getWithOffset(NumRegs * VTSize);
192*9880d681SAndroid Build Coastguard Worker SrcPtrInfo = SrcPtrInfo.getWithOffset(NumRegs * VTSize);
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker EmittedNumMemOps = NextEmittedNumMemOps;
195*9880d681SAndroid Build Coastguard Worker }
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker if (BytesLeft == 0)
198*9880d681SAndroid Build Coastguard Worker return Chain;
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker // Issue loads / stores for the trailing (1 - 3) bytes.
201*9880d681SAndroid Build Coastguard Worker unsigned BytesLeftSave = BytesLeft;
202*9880d681SAndroid Build Coastguard Worker i = 0;
203*9880d681SAndroid Build Coastguard Worker while (BytesLeft) {
204*9880d681SAndroid Build Coastguard Worker if (BytesLeft >= 2) {
205*9880d681SAndroid Build Coastguard Worker VT = MVT::i16;
206*9880d681SAndroid Build Coastguard Worker VTSize = 2;
207*9880d681SAndroid Build Coastguard Worker } else {
208*9880d681SAndroid Build Coastguard Worker VT = MVT::i8;
209*9880d681SAndroid Build Coastguard Worker VTSize = 1;
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker Loads[i] = DAG.getLoad(VT, dl, Chain,
213*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
214*9880d681SAndroid Build Coastguard Worker DAG.getConstant(SrcOff, dl, MVT::i32)),
215*9880d681SAndroid Build Coastguard Worker SrcPtrInfo.getWithOffset(SrcOff),
216*9880d681SAndroid Build Coastguard Worker false, false, false, 0);
217*9880d681SAndroid Build Coastguard Worker TFOps[i] = Loads[i].getValue(1);
218*9880d681SAndroid Build Coastguard Worker ++i;
219*9880d681SAndroid Build Coastguard Worker SrcOff += VTSize;
220*9880d681SAndroid Build Coastguard Worker BytesLeft -= VTSize;
221*9880d681SAndroid Build Coastguard Worker }
222*9880d681SAndroid Build Coastguard Worker Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
223*9880d681SAndroid Build Coastguard Worker makeArrayRef(TFOps, i));
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker i = 0;
226*9880d681SAndroid Build Coastguard Worker BytesLeft = BytesLeftSave;
227*9880d681SAndroid Build Coastguard Worker while (BytesLeft) {
228*9880d681SAndroid Build Coastguard Worker if (BytesLeft >= 2) {
229*9880d681SAndroid Build Coastguard Worker VT = MVT::i16;
230*9880d681SAndroid Build Coastguard Worker VTSize = 2;
231*9880d681SAndroid Build Coastguard Worker } else {
232*9880d681SAndroid Build Coastguard Worker VT = MVT::i8;
233*9880d681SAndroid Build Coastguard Worker VTSize = 1;
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
237*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
238*9880d681SAndroid Build Coastguard Worker DAG.getConstant(DstOff, dl, MVT::i32)),
239*9880d681SAndroid Build Coastguard Worker DstPtrInfo.getWithOffset(DstOff), false, false, 0);
240*9880d681SAndroid Build Coastguard Worker ++i;
241*9880d681SAndroid Build Coastguard Worker DstOff += VTSize;
242*9880d681SAndroid Build Coastguard Worker BytesLeft -= VTSize;
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
245*9880d681SAndroid Build Coastguard Worker makeArrayRef(TFOps, i));
246*9880d681SAndroid Build Coastguard Worker }
247*9880d681SAndroid Build Coastguard Worker
EmitTargetCodeForMemmove(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,bool isVolatile,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo) const248*9880d681SAndroid Build Coastguard Worker SDValue ARMSelectionDAGInfo::EmitTargetCodeForMemmove(
249*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
250*9880d681SAndroid Build Coastguard Worker SDValue Size, unsigned Align, bool isVolatile,
251*9880d681SAndroid Build Coastguard Worker MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
252*9880d681SAndroid Build Coastguard Worker return EmitSpecializedLibcall(DAG, dl, Chain, Dst, Src, Size, Align,
253*9880d681SAndroid Build Coastguard Worker RTLIB::MEMMOVE);
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker
EmitTargetCodeForMemset(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,bool isVolatile,MachinePointerInfo DstPtrInfo) const256*9880d681SAndroid Build Coastguard Worker SDValue ARMSelectionDAGInfo::EmitTargetCodeForMemset(
257*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
258*9880d681SAndroid Build Coastguard Worker SDValue Size, unsigned Align, bool isVolatile,
259*9880d681SAndroid Build Coastguard Worker MachinePointerInfo DstPtrInfo) const {
260*9880d681SAndroid Build Coastguard Worker return EmitSpecializedLibcall(DAG, dl, Chain, Dst, Src, Size, Align,
261*9880d681SAndroid Build Coastguard Worker RTLIB::MEMSET);
262*9880d681SAndroid Build Coastguard Worker }
263