LLVM 23.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
235 Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
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 AAMDNodes AAInfo = LD->getAAInfo();
258
259 assert(NVT.isByteSized() && "Expanded type not byte sized!");
260
261 Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getPointerInfo(),
262 LD->getBaseAlign(), LD->getMemOperand()->getFlags(), AAInfo);
263
264 // Increment the pointer to the other half.
265 unsigned IncrementSize = NVT.getSizeInBits() / 8;
266 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
267 Hi = DAG.getLoad(NVT, dl, Chain, Ptr,
268 LD->getPointerInfo().getWithOffset(IncrementSize),
269 LD->getBaseAlign(), LD->getMemOperand()->getFlags(), AAInfo);
270
271 // Build a factor node to remember that this load is independent of the
272 // other one.
273 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
274 Hi.getValue(1));
275
276 // Handle endianness of the load.
277 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
278 std::swap(Lo, Hi);
279
280 // Modified the chain - switch anything that used the old chain to use
281 // the new one.
282 ReplaceValueWith(SDValue(N, 1), Chain);
283}
284
285void DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
286 EVT OVT = N->getValueType(0);
287 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
288 SDValue Chain = N->getOperand(0);
289 SDValue Ptr = N->getOperand(1);
290 SDLoc dl(N);
291 const unsigned Align = N->getConstantOperandVal(3);
292
293 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), Align);
294 Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, N->getOperand(2), 0);
295 Chain = Hi.getValue(1);
296
297 // Handle endianness of the load.
298 if (TLI.hasBigEndianPartOrdering(OVT, DAG.getDataLayout()))
299 std::swap(Lo, Hi);
300
301 // Modified the chain - switch anything that used the old chain to use
302 // the new one.
303 ReplaceValueWith(SDValue(N, 1), Chain);
304}
305
306
307//===--------------------------------------------------------------------===//
308// Generic Operand Expansion.
309//===--------------------------------------------------------------------===//
310
311void DAGTypeLegalizer::IntegerToVector(SDValue Op, unsigned NumElements,
313 EVT EltVT) {
314 assert(Op.getValueType().isInteger());
315 SDLoc DL(Op);
316 SDValue Parts[2];
317
318 if (NumElements > 1) {
319 NumElements >>= 1;
320 SplitInteger(Op, Parts[0], Parts[1]);
321 if (DAG.getDataLayout().isBigEndian())
322 std::swap(Parts[0], Parts[1]);
323 IntegerToVector(Parts[0], NumElements, Ops, EltVT);
324 IntegerToVector(Parts[1], NumElements, Ops, EltVT);
325 } else {
326 Ops.push_back(DAG.getNode(ISD::BITCAST, DL, EltVT, Op));
327 }
328}
329
330SDValue DAGTypeLegalizer::ExpandOp_BITCAST(SDNode *N) {
331 SDLoc dl(N);
332 if (N->getValueType(0).isVector() &&
333 N->getOperand(0).getValueType().isInteger()) {
334 // An illegal expanding type is being converted to a legal vector type.
335 // Make a two element vector out of the expanded parts and convert that
336 // instead, but only if the new vector type is legal (otherwise there
337 // is no point, and it might create expansion loops). For example, on
338 // x86 this turns v1i64 = BITCAST i64 into v1i64 = BITCAST v2i32.
339 //
340 // FIXME: I'm not sure why we are first trying to split the input into
341 // a 2 element vector, so I'm leaving it here to maintain the current
342 // behavior.
343 unsigned NumElts = 2;
344 EVT OVT = N->getOperand(0).getValueType();
345 EVT NVT = EVT::getVectorVT(*DAG.getContext(),
346 TLI.getTypeToTransformTo(*DAG.getContext(), OVT),
347 NumElts);
348 if (!isTypeLegal(NVT)) {
349 // If we can't find a legal type by splitting the integer in half,
350 // then we can use the node's value type.
351 NumElts = N->getValueType(0).getVectorNumElements();
352 NVT = N->getValueType(0);
353 }
354
356 IntegerToVector(N->getOperand(0), NumElts, Ops, NVT.getVectorElementType());
357
358 SDValue Vec = DAG.getBuildVector(NVT, dl, ArrayRef(Ops.data(), NumElts));
359 return DAG.getNode(ISD::BITCAST, dl, N->getValueType(0), Vec);
360 }
361
362 // Otherwise, store to a temporary and load out again as the new type.
363 return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
364}
365
366SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
367 // The vector type is legal but the element type needs expansion.
368 EVT VecVT = N->getValueType(0);
369 unsigned NumElts = VecVT.getVectorNumElements();
370 EVT OldVT = N->getOperand(0).getValueType();
371 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
372 SDLoc dl(N);
373
374 assert(OldVT == VecVT.getVectorElementType() &&
375 "BUILD_VECTOR operand type doesn't match vector element type!");
376
377 if (VecVT.isInteger() && TLI.isOperationLegal(ISD::SPLAT_VECTOR, VecVT) &&
378 TLI.isOperationLegalOrCustom(ISD::SPLAT_VECTOR_PARTS, VecVT)) {
380 SDValue Lo, Hi;
381 GetExpandedOp(V, Lo, Hi);
382 return DAG.getNode(ISD::SPLAT_VECTOR_PARTS, dl, VecVT, Lo, Hi);
383 }
384 }
385
386 // Build a vector of twice the length out of the expanded elements.
387 // For example <3 x i64> -> <6 x i32>.
389 NewElts.reserve(NumElts*2);
390
391 for (unsigned i = 0; i < NumElts; ++i) {
392 SDValue Lo, Hi;
393 GetExpandedOp(N->getOperand(i), Lo, Hi);
394 if (DAG.getDataLayout().isBigEndian())
395 std::swap(Lo, Hi);
396 NewElts.push_back(Lo);
397 NewElts.push_back(Hi);
398 }
399
400 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NewElts.size());
401 SDValue NewVec = DAG.getBuildVector(NewVecVT, dl, NewElts);
402
403 // Convert the new vector to the old vector type.
404 return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
405}
406
407SDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
408 SDValue Lo, Hi;
409 GetExpandedOp(N->getOperand(0), Lo, Hi);
410 return N->getConstantOperandVal(1) ? Hi : Lo;
411}
412
413// Split the integer operand in two and create a second FAKE_USE node for
414// the other half. The original SDNode is updated in place.
415SDValue DAGTypeLegalizer::ExpandOp_FAKE_USE(SDNode *N) {
416 SDValue Lo, Hi;
417 SDValue Chain = N->getOperand(0);
418 GetExpandedOp(N->getOperand(1), Lo, Hi);
419 SDValue LoUse = DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other, Chain, Lo);
420 DAG.UpdateNodeOperands(N, LoUse, Hi);
421 return SDValue(N, 0);
422}
423
424SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
425 // The vector type is legal but the element type needs expansion.
426 EVT VecVT = N->getValueType(0);
427 unsigned NumElts = VecVT.getVectorNumElements();
428 SDLoc dl(N);
429
430 SDValue Val = N->getOperand(1);
431 EVT OldEVT = Val.getValueType();
432 EVT NewEVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldEVT);
433
434 assert(OldEVT == VecVT.getVectorElementType() &&
435 "Inserted element type doesn't match vector element type!");
436
437 // Bitconvert to a vector of twice the length with elements of the expanded
438 // type, insert the expanded vector elements, and then convert back.
439 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEVT, NumElts*2);
440 SDValue NewVec = DAG.getNode(ISD::BITCAST, dl,
441 NewVecVT, N->getOperand(0));
442
443 SDValue Lo, Hi;
444 GetExpandedOp(Val, Lo, Hi);
445 if (DAG.getDataLayout().isBigEndian())
446 std::swap(Lo, Hi);
447
448 SDValue Idx = N->getOperand(2);
449 Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
450 NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx);
451 Idx = DAG.getNode(ISD::ADD, dl,
452 Idx.getValueType(), Idx,
453 DAG.getConstant(1, dl, Idx.getValueType()));
454 NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx);
455
456 // Convert the new vector to the old vector type.
457 return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
458}
459
460SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
461 SDLoc dl(N);
462 EVT VT = N->getValueType(0);
463 assert(VT.getVectorElementType() == N->getOperand(0).getValueType() &&
464 "SCALAR_TO_VECTOR operand type doesn't match vector element type!");
465 unsigned NumElts = VT.getVectorNumElements();
467 Ops[0] = N->getOperand(0);
468 SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType());
469 for (unsigned i = 1; i < NumElts; ++i)
470 Ops[i] = UndefVal;
471 return DAG.getBuildVector(VT, dl, Ops);
472}
473
474SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
475 assert(ISD::isNormalStore(N) && "This routine only for normal stores!");
476 assert(OpNo == 1 && "Can only expand the stored value so far");
477 SDLoc dl(N);
478
479 StoreSDNode *St = cast<StoreSDNode>(N);
480 assert(!St->isAtomic() && "Atomics can not be split");
481 EVT ValueVT = St->getValue().getValueType();
482 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
483 SDValue Chain = St->getChain();
484 SDValue Ptr = St->getBasePtr();
485 AAMDNodes AAInfo = St->getAAInfo();
486
487 assert(NVT.isByteSized() && "Expanded type not byte sized!");
488 unsigned IncrementSize = NVT.getSizeInBits() / 8;
489
490 SDValue Lo, Hi;
491 GetExpandedOp(St->getValue(), Lo, Hi);
492
493 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
494 std::swap(Lo, Hi);
495
496 Lo =
497 DAG.getStore(Chain, dl, Lo, Ptr, St->getPointerInfo(), St->getBaseAlign(),
498 St->getMemOperand()->getFlags(), AAInfo);
499
500 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
501 Hi = DAG.getStore(
502 Chain, dl, Hi, Ptr, St->getPointerInfo().getWithOffset(IncrementSize),
503 St->getBaseAlign(), St->getMemOperand()->getFlags(), AAInfo);
504
505 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
506}
507
508
509//===--------------------------------------------------------------------===//
510// Generic Result Splitting.
511//===--------------------------------------------------------------------===//
512
513// Be careful to make no assumptions about which of Lo/Hi is stored first in
514// memory (for vectors it is always Lo first followed by Hi in the following
515// bytes; for integers and floats it is Lo first if and only if the machine is
516// little-endian).
517
518void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
519 SDValue &Lo, SDValue &Hi) {
520 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
521 GetSplitOp(Op, Lo, Hi);
522}
523
524void DAGTypeLegalizer::SplitRes_Select(SDNode *N, SDValue &Lo, SDValue &Hi) {
525 SDValue LL, LH, RL, RH, CL, CH;
526 SDLoc dl(N);
527 unsigned Opcode = N->getOpcode();
528 GetSplitOp(N->getOperand(1), LL, LH);
529 GetSplitOp(N->getOperand(2), RL, RH);
530
531 SDValue Cond = N->getOperand(0);
532 CL = CH = Cond;
533 if (Cond.getValueType().isVector()) {
534 if (SDValue Res = WidenVSELECTMask(N))
535 std::tie(CL, CH) = DAG.SplitVector(Res, dl);
536 // Check if there are already splitted versions of the vector available and
537 // use those instead of splitting the mask operand again.
538 else if (getTypeAction(Cond.getValueType()) ==
540 GetSplitVector(Cond, CL, CH);
541 // It seems to improve code to generate two narrow SETCCs as opposed to
542 // splitting a wide result vector.
543 else if (Cond.getOpcode() == ISD::SETCC) {
544 // If the condition is a vXi1 vector, and the LHS of the setcc is a legal
545 // type and the setcc result type is the same vXi1, then leave the setcc
546 // alone.
547 EVT CondLHSVT = Cond.getOperand(0).getValueType();
548 if (Cond.getValueType().getVectorElementType() == MVT::i1 &&
549 isTypeLegal(CondLHSVT) &&
550 getSetCCResultType(CondLHSVT) == Cond.getValueType())
551 std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
552 else
553 SplitVecRes_SETCC(Cond.getNode(), CL, CH);
554 } else
555 std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
556 }
557
558 if (Opcode != ISD::VP_SELECT && Opcode != ISD::VP_MERGE) {
559 Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL);
560 Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH);
561 return;
562 }
563
564 SDValue EVLLo, EVLHi;
565 std::tie(EVLLo, EVLHi) =
566 DAG.SplitEVL(N->getOperand(3), N->getValueType(0), dl);
567
568 Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL, EVLLo);
569 Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH, EVLHi);
570}
571
572void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
573 SDValue &Hi) {
574 SDValue LL, LH, RL, RH;
575 SDLoc dl(N);
576 GetSplitOp(N->getOperand(2), LL, LH);
577 GetSplitOp(N->getOperand(3), RL, RH);
578
579 Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0),
580 N->getOperand(1), LL, RL, N->getOperand(4));
581 Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0),
582 N->getOperand(1), LH, RH, N->getOperand(4));
583}
584
585void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
586 EVT LoVT, HiVT;
587 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
588 Lo = DAG.getUNDEF(LoVT);
589 Hi = DAG.getUNDEF(HiVT);
590}
591
592void DAGTypeLegalizer::SplitVecRes_AssertZext(SDNode *N, SDValue &Lo,
593 SDValue &Hi) {
594 SDValue L, H;
595 SDLoc dl(N);
596 GetSplitOp(N->getOperand(0), L, H);
597
598 Lo = DAG.getNode(ISD::AssertZext, dl, L.getValueType(), L, N->getOperand(1));
599 Hi = DAG.getNode(ISD::AssertZext, dl, H.getValueType(), H, N->getOperand(1));
600}
601
602void DAGTypeLegalizer::SplitVecRes_AssertSext(SDNode *N, SDValue &Lo,
603 SDValue &Hi) {
604 SDValue L, H;
605 SDLoc dl(N);
606 GetSplitOp(N->getOperand(0), L, H);
607
608 Lo = DAG.getNode(ISD::AssertSext, dl, L.getValueType(), L, N->getOperand(1));
609 Hi = DAG.getNode(ISD::AssertSext, dl, H.getValueType(), H, N->getOperand(1));
610}
611
612void DAGTypeLegalizer::SplitRes_FREEZE(SDNode *N, SDValue &Lo, SDValue &Hi) {
613 SDValue L, H;
614 SDLoc dl(N);
615 GetSplitOp(N->getOperand(0), L, H);
616
617 Lo = DAG.getNode(ISD::FREEZE, dl, L.getValueType(), L);
618 Hi = DAG.getNode(ISD::FREEZE, dl, H.getValueType(), H);
619}
620
621void DAGTypeLegalizer::SplitRes_ARITH_FENCE(SDNode *N, SDValue &Lo,
622 SDValue &Hi) {
623 SDValue L, H;
624 SDLoc DL(N);
625 GetSplitOp(N->getOperand(0), L, H);
626
627 Lo = DAG.getNode(ISD::ARITH_FENCE, DL, L.getValueType(), L);
628 Hi = DAG.getNode(ISD::ARITH_FENCE, DL, H.getValueType(), H);
629}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
Value * RHS
Value * LHS
Flags getFlags() const
Return the raw flags of the source value,.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
bool isAtomic() const
Return true if the memory operation ordering is Unordered or higher.
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)
const SDValue & getBasePtr() const
const SDValue & getValue() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
#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:819
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:853
@ 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...
Definition ISDOpcodes.h:993
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:254
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition ISDOpcodes.h:672
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:576
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:811
@ SPLAT_VECTOR_PARTS
SPLAT_VECTOR_PARTS(SCALAR1, SCALAR2, ...) - Returns a vector with the scalar values joined together a...
Definition ISDOpcodes.h:681
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
Definition ISDOpcodes.h:241
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:565
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
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.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
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:872
#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:395
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:74
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
Definition ValueTypes.h:300
ElementCount getVectorElementCount() const
Definition ValueTypes.h:350
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:373
bool isByteSized() const
Return true if the bit size is a multiple of 8.
Definition ValueTypes.h:243
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition ValueTypes.h:65
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:168
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:328
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:336
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:152
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.