LLVM 24.0.0git
LegalizeTypesGeneric.cpp
Go to the documentation of this file.
1//===-------- LegalizeTypesGeneric.cpp - Generic type legalization --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements generic type expansion and splitting for LegalizeTypes.
10// The routines here perform legalization when the details of the type (such as
11// whether it is an integer or a float) do not matter.
12// Expansion is the act of changing a computation in an illegal type to be a
13// computation in two identical registers of a smaller type. The Lo/Hi part
14// is required to be stored first in memory on little/big-endian machines.
15// Splitting is the act of changing a computation in an illegal type to be a
16// computation in two not necessarily identical registers of a smaller type.
17// There are no requirements on how the type is represented in memory.
18//
19//===----------------------------------------------------------------------===//
20
21#include "LegalizeTypes.h"
22#include "llvm/IR/DataLayout.h"
23using namespace llvm;
24
25#define DEBUG_TYPE "legalize-types"
26
27//===----------------------------------------------------------------------===//
28// Generic Result Expansion.
29//===----------------------------------------------------------------------===//
30
31// These routines assume that the Lo/Hi part is stored first in memory on
32// little/big-endian machines, followed by the Hi/Lo part. This means that
33// they cannot be used as is on vectors, for which Lo is always stored first.
34void DAGTypeLegalizer::ExpandRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
35 SDValue &Lo, SDValue &Hi) {
36 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
37 GetExpandedOp(Op, Lo, Hi);
38}
39
40void DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) {
41 EVT OutVT = N->getValueType(0);
42 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
43 SDValue InOp = N->getOperand(0);
44 EVT InVT = InOp.getValueType();
45 SDLoc dl(N);
46
47 // Handle some special cases efficiently.
48 switch (getTypeAction(InVT)) {
51 break;
53 llvm_unreachable("Bitcast of a promotion-needing float should never need"
54 "expansion");
56 SplitInteger(GetSoftenedFloat(InOp), Lo, Hi);
57 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
58 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
59 return;
62 auto &DL = DAG.getDataLayout();
63 // Convert the expanded pieces of the input.
64 GetExpandedOp(InOp, Lo, Hi);
65 if (TLI.hasBigEndianPartOrdering(InVT, DL) !=
66 TLI.hasBigEndianPartOrdering(OutVT, DL))
67 std::swap(Lo, Hi);
68 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
69 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
70 return;
71 }
73 GetSplitVector(InOp, Lo, Hi);
74 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
75 std::swap(Lo, Hi);
76 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
77 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
78 return;
80 // Convert the element instead.
81 SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
82 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
83 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
84 return;
86 report_fatal_error("scalarization of scalable vectors is not supported");
88 assert(!(InVT.getVectorNumElements() & 1) && "Unsupported BITCAST");
89 InOp = GetWidenedVector(InOp);
90 EVT LoVT, HiVT;
91 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(InVT);
92 std::tie(Lo, Hi) = DAG.SplitVector(InOp, dl, LoVT, HiVT);
93 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
94 std::swap(Lo, Hi);
95 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
96 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
97 return;
98 }
99 }
100
101 if (InVT.isVector() && OutVT.isInteger()) {
102 // Handle cases like i64 = BITCAST v1i64 on x86, where the operand
103 // is legal but the result is not.
104 unsigned NumElems = 2;
105 EVT ElemVT = NOutVT;
106 EVT NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
107
108 // If <ElemVT * N> is not a legal type, try <ElemVT/2 * (N*2)>.
109 while (!isTypeLegal(NVT)) {
110 unsigned NewSizeInBits = ElemVT.getSizeInBits() / 2;
111 // If the element size is smaller than byte, bail.
112 if (NewSizeInBits < 8)
113 break;
114 NumElems *= 2;
115 ElemVT = EVT::getIntegerVT(*DAG.getContext(), NewSizeInBits);
116 NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
117 }
118
119 if (isTypeLegal(NVT)) {
120 SDValue CastInOp = DAG.getNode(ISD::BITCAST, dl, NVT, InOp);
121
123 for (unsigned i = 0; i < NumElems; ++i)
124 Vals.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ElemVT,
125 CastInOp, DAG.getVectorIdxConstant(i, dl)));
126
127 // Build Lo, Hi pair by pairing extracted elements if needed.
128 unsigned Slot = 0;
129 for (unsigned e = Vals.size(); e - Slot > 2; Slot += 2, e += 1) {
130 // Each iteration will BUILD_PAIR two nodes and append the result until
131 // there are only two nodes left, i.e. Lo and Hi.
132 SDValue LHS = Vals[Slot];
133 SDValue RHS = Vals[Slot + 1];
134
135 if (DAG.getDataLayout().isBigEndian())
136 std::swap(LHS, RHS);
137
138 Vals.push_back(DAG.getNode(
139 ISD::BUILD_PAIR, dl,
140 EVT::getIntegerVT(*DAG.getContext(), LHS.getValueSizeInBits() << 1),
141 LHS, RHS));
142 }
143 Lo = Vals[Slot++];
144 Hi = Vals[Slot++];
145
146 if (DAG.getDataLayout().isBigEndian())
147 std::swap(Lo, Hi);
148
149 return;
150 }
151 }
152
153 // Lower the bit-convert to a store/load from the stack.
154 assert(NOutVT.isByteSized() && "Expanded type not byte sized!");
155
156 // Create the stack frame object. Make sure it is aligned for both
157 // the source and expanded destination types.
158
159 // In cases where the vector is illegal it will be broken down into parts
160 // and stored in parts - we should use the alignment for the smallest part.
161 Align InAlign = DAG.getReducedAlign(InVT, /*UseABI=*/false);
162 Align NOutAlign = DAG.getReducedAlign(NOutVT, /*UseABI=*/false);
163 Align Align = std::max(InAlign, NOutAlign);
164 SDValue StackPtr = DAG.CreateStackTemporary(InVT.getStoreSize(), Align);
165 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
166 MachinePointerInfo PtrInfo =
167 MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
168
169 // Emit a store to the stack slot.
170 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, PtrInfo);
171
172 // Load the first half from the stack slot.
173 Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, PtrInfo, NOutAlign);
174
175 // Increment the pointer to the other half.
176 unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
177 StackPtr =
178 DAG.getMemBasePlusOffset(StackPtr, TypeSize::getFixed(IncrementSize), dl);
179
180 // Load the second half from the stack slot.
181 Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr,
182 PtrInfo.getWithOffset(IncrementSize), NOutAlign);
183
184 // Handle endianness of the load.
185 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
186 std::swap(Lo, Hi);
187}
188
189void DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N, SDValue &Lo,
190 SDValue &Hi) {
191 // Return the operands.
192 Lo = N->getOperand(0);
193 Hi = N->getOperand(1);
194}
195
196void DAGTypeLegalizer::ExpandRes_EXTRACT_ELEMENT(SDNode *N, SDValue &Lo,
197 SDValue &Hi) {
198 GetExpandedOp(N->getOperand(0), Lo, Hi);
199 SDValue Part = N->getConstantOperandVal(1) ? Hi : Lo;
200
201 assert(Part.getValueType() == N->getValueType(0) &&
202 "Type twice as big as expanded type not itself expanded!");
203
204 GetPairElements(Part, Lo, Hi);
205}
206
207void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo,
208 SDValue &Hi) {
209 SDValue OldVec = N->getOperand(0);
210 ElementCount OldEltCount = OldVec.getValueType().getVectorElementCount();
211 EVT OldEltVT = OldVec.getValueType().getVectorElementType();
212 SDLoc dl(N);
213
214 // Convert to a vector of the expanded element type, for example
215 // <3 x i64> -> <6 x i32>.
216 EVT OldVT = N->getValueType(0);
217 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
218
219 if (OldVT != OldEltVT) {
220 // The result of EXTRACT_VECTOR_ELT may be larger than the element type of
221 // the input vector. If so, extend the elements of the input vector to the
222 // same bitwidth as the result before expanding.
223 assert(OldEltVT.bitsLT(OldVT) && "Result type smaller then element type!");
224 EVT NVecVT = EVT::getVectorVT(*DAG.getContext(), OldVT, OldEltCount);
225 OldVec = DAG.getNode(ISD::ANY_EXTEND, dl, NVecVT, N->getOperand(0));
226 }
227
228 SDValue NewVec = DAG.getNode(
229 ISD::BITCAST, dl,
230 EVT::getVectorVT(*DAG.getContext(), NewVT, OldEltCount * 2), OldVec);
231
232 // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
233 SDValue Idx = N->getOperand(1);
234 Idx = DAG.getNode(ISD::SHL, dl, Idx.getValueType(), Idx,
235 DAG.getShiftAmountConstant(1, Idx.getValueType(), dl));
236 Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
237
238 Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
239 DAG.getConstant(1, dl, Idx.getValueType()));
240 Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
241
242 if (DAG.getDataLayout().isBigEndian())
243 std::swap(Lo, Hi);
244}
245
246void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
247 SDValue &Hi) {
248 assert(ISD::isNormalLoad(N) && "This routine only for normal loads!");
249 SDLoc dl(N);
250
251 LoadSDNode *LD = cast<LoadSDNode>(N);
252 assert(!LD->isAtomic() && "Atomics can not be split");
253 EVT ValueVT = LD->getValueType(0);
254 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
255 SDValue Chain = LD->getChain();
256 SDValue Ptr = LD->getBasePtr();
257 MMOMetadata Metadata = LD->getMMOMetadataForSubAccess();
258
259 assert(NVT.isByteSized() && "Expanded type not byte sized!");
260
261 Lo =
262 DAG.getLoad(NVT, dl, Chain, Ptr, LD->getPointerInfo(), LD->getBaseAlign(),
263 LD->getMemOperand()->getFlags(), Metadata);
264
265 // Increment the pointer to the other half.
266 unsigned IncrementSize = NVT.getSizeInBits() / 8;
267 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
268 Hi = DAG.getLoad(
269 NVT, dl, Chain, Ptr, LD->getPointerInfo().getWithOffset(IncrementSize),
270 LD->getBaseAlign(), LD->getMemOperand()->getFlags(), Metadata);
271
272 // Build a factor node to remember that this load is independent of the
273 // other one.
274 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
275 Hi.getValue(1));
276
277 // Handle endianness of the load.
278 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
279 std::swap(Lo, Hi);
280
281 // Modified the chain - switch anything that used the old chain to use
282 // the new one.
283 ReplaceValueWith(SDValue(N, 1), Chain);
284}
285
286void DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
287 EVT OVT = N->getValueType(0);
288 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
289 SDValue Chain = N->getOperand(0);
290 SDValue Ptr = N->getOperand(1);
291 SDLoc dl(N);
292 const unsigned Align = N->getConstantOperandVal(3);
293
294 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), Align);
295 Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, N->getOperand(2), 0);
296 Chain = Hi.getValue(1);
297
298 // Handle endianness of the load.
299 if (TLI.hasBigEndianPartOrdering(OVT, DAG.getDataLayout()))
300 std::swap(Lo, Hi);
301
302 // Modified the chain - switch anything that used the old chain to use
303 // the new one.
304 ReplaceValueWith(SDValue(N, 1), Chain);
305}
306
307
308//===--------------------------------------------------------------------===//
309// Generic Operand Expansion.
310//===--------------------------------------------------------------------===//
311
312void DAGTypeLegalizer::IntegerToVector(SDValue Op, unsigned NumElements,
314 EVT EltVT) {
315 assert(Op.getValueType().isInteger());
316 SDLoc DL(Op);
317 SDValue Parts[2];
318
319 if (NumElements > 1) {
320 NumElements >>= 1;
321 SplitInteger(Op, Parts[0], Parts[1]);
322 if (DAG.getDataLayout().isBigEndian())
323 std::swap(Parts[0], Parts[1]);
324 IntegerToVector(Parts[0], NumElements, Ops, EltVT);
325 IntegerToVector(Parts[1], NumElements, Ops, EltVT);
326 } else {
327 Ops.push_back(DAG.getNode(ISD::BITCAST, DL, EltVT, Op));
328 }
329}
330
331SDValue DAGTypeLegalizer::ExpandOp_BITCAST(SDNode *N) {
332 SDLoc dl(N);
333 if (N->getValueType(0).isVector() &&
334 N->getOperand(0).getValueType().isInteger()) {
335 // An illegal expanding type is being converted to a legal vector type.
336 // Make a two element vector out of the expanded parts and convert that
337 // instead, but only if the new vector type is legal (otherwise there
338 // is no point, and it might create expansion loops). For example, on
339 // x86 this turns v1i64 = BITCAST i64 into v1i64 = BITCAST v2i32.
340 //
341 // FIXME: I'm not sure why we are first trying to split the input into
342 // a 2 element vector, so I'm leaving it here to maintain the current
343 // behavior.
344 unsigned NumElts = 2;
345 EVT OVT = N->getOperand(0).getValueType();
346 EVT NVT = EVT::getVectorVT(*DAG.getContext(),
347 TLI.getTypeToTransformTo(*DAG.getContext(), OVT),
348 NumElts);
349 if (!isTypeLegal(NVT)) {
350 // If we can't find a legal type by splitting the integer in half,
351 // then we can use the node's value type.
352 NumElts = N->getValueType(0).getVectorNumElements();
353 NVT = N->getValueType(0);
354 }
355
357 IntegerToVector(N->getOperand(0), NumElts, Ops, NVT.getVectorElementType());
358
359 SDValue Vec = DAG.getBuildVector(NVT, dl, ArrayRef(Ops.data(), NumElts));
360 return DAG.getNode(ISD::BITCAST, dl, N->getValueType(0), Vec);
361 }
362
363 // Otherwise, store to a temporary and load out again as the new type.
364 return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
365}
366
367SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
368 // The vector type is legal but the element type needs expansion.
369 EVT VecVT = N->getValueType(0);
370 unsigned NumElts = VecVT.getVectorNumElements();
371 EVT OldVT = N->getOperand(0).getValueType();
372 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
373 SDLoc dl(N);
374
375 assert(OldVT == VecVT.getVectorElementType() &&
376 "BUILD_VECTOR operand type doesn't match vector element type!");
377
378 if (VecVT.isInteger() && TLI.isOperationLegal(ISD::SPLAT_VECTOR, VecVT) &&
379 TLI.isOperationLegalOrCustom(ISD::SPLAT_VECTOR_PARTS, VecVT)) {
380 if (SDValue V = cast<BuildVectorSDNode>(N)->getSplatValue()) {
381 SDValue Lo, Hi;
382 GetExpandedOp(V, Lo, Hi);
383 return DAG.getNode(ISD::SPLAT_VECTOR_PARTS, dl, VecVT, Lo, Hi);
384 }
385 }
386
387 // Build a vector of twice the length out of the expanded elements.
388 // For example <3 x i64> -> <6 x i32>.
390 NewElts.reserve(NumElts*2);
391
392 for (unsigned i = 0; i < NumElts; ++i) {
393 SDValue Lo, Hi;
394 GetExpandedOp(N->getOperand(i), Lo, Hi);
395 if (DAG.getDataLayout().isBigEndian())
396 std::swap(Lo, Hi);
397 NewElts.push_back(Lo);
398 NewElts.push_back(Hi);
399 }
400
401 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NewElts.size());
402 SDValue NewVec = DAG.getBuildVector(NewVecVT, dl, NewElts);
403
404 // Convert the new vector to the old vector type.
405 return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
406}
407
408SDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
409 SDValue Lo, Hi;
410 GetExpandedOp(N->getOperand(0), Lo, Hi);
411 return N->getConstantOperandVal(1) ? Hi : Lo;
412}
413
414// Split the integer operand in two and create a second FAKE_USE node for
415// the other half. The original SDNode is updated in place.
416SDValue DAGTypeLegalizer::ExpandOp_FAKE_USE(SDNode *N) {
417 SDValue Lo, Hi;
418 SDValue Chain = N->getOperand(0);
419 GetExpandedOp(N->getOperand(1), Lo, Hi);
420 SDValue LoUse = DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other, Chain, Lo);
421 DAG.UpdateNodeOperands(N, LoUse, Hi);
422 return SDValue(N, 0);
423}
424
425SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
426 // The vector type is legal but the element type needs expansion.
427 EVT VecVT = N->getValueType(0);
428 unsigned NumElts = VecVT.getVectorNumElements();
429 SDLoc dl(N);
430
431 SDValue Val = N->getOperand(1);
432 EVT OldEVT = Val.getValueType();
433 EVT NewEVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldEVT);
434
435 assert(OldEVT == VecVT.getVectorElementType() &&
436 "Inserted element type doesn't match vector element type!");
437
438 // Bitconvert to a vector of twice the length with elements of the expanded
439 // type, insert the expanded vector elements, and then convert back.
440 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEVT, NumElts*2);
441 SDValue NewVec = DAG.getNode(ISD::BITCAST, dl,
442 NewVecVT, N->getOperand(0));
443
444 SDValue Lo, Hi;
445 GetExpandedOp(Val, Lo, Hi);
446 if (DAG.getDataLayout().isBigEndian())
447 std::swap(Lo, Hi);
448
449 SDValue Idx = N->getOperand(2);
450 Idx = DAG.getNode(ISD::SHL, dl, Idx.getValueType(), Idx,
451 DAG.getShiftAmountConstant(1, Idx.getValueType(), dl));
452 NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx);
453 Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
454 DAG.getConstant(1, dl, Idx.getValueType()));
455 NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx);
456
457 // Convert the new vector to the old vector type.
458 return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
459}
460
461SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
462 SDLoc dl(N);
463 EVT VT = N->getValueType(0);
464 assert(VT.getVectorElementType() == N->getOperand(0).getValueType() &&
465 "SCALAR_TO_VECTOR operand type doesn't match vector element type!");
466 unsigned NumElts = VT.getVectorNumElements();
468 Ops[0] = N->getOperand(0);
469 SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType());
470 for (unsigned i = 1; i < NumElts; ++i)
471 Ops[i] = UndefVal;
472 return DAG.getBuildVector(VT, dl, Ops);
473}
474
475SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
476 assert(ISD::isNormalStore(N) && "This routine only for normal stores!");
477 assert(OpNo == 1 && "Can only expand the stored value so far");
478 SDLoc dl(N);
479
480 StoreSDNode *St = cast<StoreSDNode>(N);
481 assert(!St->isAtomic() && "Atomics can not be split");
482 EVT ValueVT = St->getValue().getValueType();
483 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
484 SDValue Chain = St->getChain();
485 SDValue Ptr = St->getBasePtr();
486 MMOMetadata Metadata = St->getMMOMetadataForSubAccess();
487
488 assert(NVT.isByteSized() && "Expanded type not byte sized!");
489 unsigned IncrementSize = NVT.getSizeInBits() / 8;
490
491 SDValue Lo, Hi;
492 GetExpandedOp(St->getValue(), Lo, Hi);
493
494 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
495 std::swap(Lo, Hi);
496
497 Lo =
498 DAG.getStore(Chain, dl, Lo, Ptr, St->getPointerInfo(), St->getBaseAlign(),
499 St->getMemOperand()->getFlags(), Metadata);
500
501 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
502 Hi = DAG.getStore(
503 Chain, dl, Hi, Ptr, St->getPointerInfo().getWithOffset(IncrementSize),
504 St->getBaseAlign(), St->getMemOperand()->getFlags(), Metadata);
505
506 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
507}
508
509
510//===--------------------------------------------------------------------===//
511// Generic Result Splitting.
512//===--------------------------------------------------------------------===//
513
514// Be careful to make no assumptions about which of Lo/Hi is stored first in
515// memory (for vectors it is always Lo first followed by Hi in the following
516// bytes; for integers and floats it is Lo first if and only if the machine is
517// little-endian).
518
519void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
520 SDValue &Lo, SDValue &Hi) {
521 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
522 GetSplitOp(Op, Lo, Hi);
523}
524
525void DAGTypeLegalizer::SplitRes_Select(SDNode *N, SDValue &Lo, SDValue &Hi) {
526 SDValue LL, LH, RL, RH, CL, CH;
527 SDLoc dl(N);
528 unsigned Opcode = N->getOpcode();
529 GetSplitOp(N->getOperand(1), LL, LH);
530 GetSplitOp(N->getOperand(2), RL, RH);
531
532 SDValue Cond = N->getOperand(0);
533 CL = CH = Cond;
534 if (Cond.getValueType().isVector()) {
535 if (SDValue Res = WidenVSELECTMask(N))
536 std::tie(CL, CH) = DAG.SplitVector(Res, dl);
537 // Check if there are already splitted versions of the vector available and
538 // use those instead of splitting the mask operand again.
539 else if (getTypeAction(Cond.getValueType()) ==
541 GetSplitVector(Cond, CL, CH);
542 // It seems to improve code to generate two narrow SETCCs as opposed to
543 // splitting a wide result vector.
544 else if (Cond.getOpcode() == ISD::SETCC) {
545 // If the condition is a vXi1 vector, and the LHS of the setcc is a legal
546 // type and the setcc result type is the same vXi1, then leave the setcc
547 // alone.
548 EVT CondLHSVT = Cond.getOperand(0).getValueType();
549 if (Cond.getValueType().getVectorElementType() == MVT::i1 &&
550 isTypeLegal(CondLHSVT) &&
551 getSetCCResultType(CondLHSVT) == Cond.getValueType())
552 std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
553 else
554 SplitVecRes_SETCC(Cond.getNode(), CL, CH);
555 } else
556 std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
557 }
558
559 if (Opcode != ISD::VP_MERGE) {
560 Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL);
561 Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH);
562 return;
563 }
564
565 SDValue EVLLo, EVLHi;
566 std::tie(EVLLo, EVLHi) =
567 DAG.SplitEVL(N->getOperand(3), N->getValueType(0), dl);
568
569 Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL, EVLLo);
570 Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH, EVLHi);
571}
572
573void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
574 SDValue &Hi) {
575 SDValue LL, LH, RL, RH;
576 SDLoc dl(N);
577 GetSplitOp(N->getOperand(2), LL, LH);
578 GetSplitOp(N->getOperand(3), RL, RH);
579
580 Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0),
581 N->getOperand(1), LL, RL, N->getOperand(4));
582 Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0),
583 N->getOperand(1), LH, RH, N->getOperand(4));
584}
585
586void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
587 EVT LoVT, HiVT;
588 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
589 Lo = DAG.getUNDEF(LoVT);
590 Hi = DAG.getUNDEF(HiVT);
591}
592
593void DAGTypeLegalizer::SplitVecRes_AssertZext(SDNode *N, SDValue &Lo,
594 SDValue &Hi) {
595 SDValue L, H;
596 SDLoc dl(N);
597 GetSplitOp(N->getOperand(0), L, H);
598
599 Lo = DAG.getNode(ISD::AssertZext, dl, L.getValueType(), L, N->getOperand(1));
600 Hi = DAG.getNode(ISD::AssertZext, dl, H.getValueType(), H, N->getOperand(1));
601}
602
603void DAGTypeLegalizer::SplitVecRes_AssertSext(SDNode *N, SDValue &Lo,
604 SDValue &Hi) {
605 SDValue L, H;
606 SDLoc dl(N);
607 GetSplitOp(N->getOperand(0), L, H);
608
609 Lo = DAG.getNode(ISD::AssertSext, dl, L.getValueType(), L, N->getOperand(1));
610 Hi = DAG.getNode(ISD::AssertSext, dl, H.getValueType(), H, N->getOperand(1));
611}
612
613void DAGTypeLegalizer::SplitRes_FREEZE(SDNode *N, SDValue &Lo, SDValue &Hi) {
614 SDValue L, H;
615 SDLoc dl(N);
616 GetSplitOp(N->getOperand(0), L, H);
617
618 Lo = DAG.getNode(ISD::FREEZE, dl, L.getValueType(), L);
619 Hi = DAG.getNode(ISD::FREEZE, dl, H.getValueType(), H);
620}
621
622void DAGTypeLegalizer::SplitRes_ARITH_FENCE(SDNode *N, SDValue &Lo,
623 SDValue &Hi) {
624 SDValue L, H;
625 SDLoc DL(N);
626 GetSplitOp(N->getOperand(0), L, H);
627
628 Lo = DAG.getNode(ISD::ARITH_FENCE, DL, L.getValueType(), L);
629 Hi = DAG.getNode(ISD::ARITH_FENCE, DL, H.getValueType(), H);
630}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
dxil translate DXIL Translate Metadata
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define H(x, y, z)
Definition MD5.cpp:56
const SmallVectorImpl< MachineOperand > & Cond
#define CH(x, y, z)
Definition SHA256.cpp:34
Value * RHS
Value * LHS
Represents one node in the SelectionDAG.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:837
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:871
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:256
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition ISDOpcodes.h:682
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:779
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:581
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:829
@ SPLAT_VECTOR_PARTS
SPLAT_VECTOR_PARTS(SCALAR1, SCALAR2, ...) - Returns a vector with the scalar values joined together a...
Definition ISDOpcodes.h:691
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
Definition ISDOpcodes.h:243
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:570
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:64
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
This is an optimization pass for GlobalISel generic memory operations.
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition ValueTypes.h:418
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:70
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
Definition ValueTypes.h:323
ElementCount getVectorElementCount() const
Definition ValueTypes.h:373
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
bool isByteSized() const
Return true if the bit size is a multiple of 8.
Definition ValueTypes.h:266
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition ValueTypes.h:61
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:351
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:359
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.