LLVM 20.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;
54 llvm_unreachable("Bitcast of a promotion-needing float should never need"
55 "expansion");
57 SplitInteger(GetSoftenedFloat(InOp), Lo, Hi);
58 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
59 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
60 return;
63 auto &DL = DAG.getDataLayout();
64 // Convert the expanded pieces of the input.
65 GetExpandedOp(InOp, Lo, Hi);
66 if (TLI.hasBigEndianPartOrdering(InVT, DL) !=
67 TLI.hasBigEndianPartOrdering(OutVT, DL))
68 std::swap(Lo, Hi);
69 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
70 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
71 return;
72 }
74 GetSplitVector(InOp, Lo, Hi);
75 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
76 std::swap(Lo, Hi);
77 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
78 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
79 return;
81 // Convert the element instead.
82 SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
83 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
84 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
85 return;
87 report_fatal_error("Scalarization of scalable vectors is not supported.");
89 assert(!(InVT.getVectorNumElements() & 1) && "Unsupported BITCAST");
90 InOp = GetWidenedVector(InOp);
91 EVT LoVT, HiVT;
92 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(InVT);
93 std::tie(Lo, Hi) = DAG.SplitVector(InOp, dl, LoVT, HiVT);
94 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
95 std::swap(Lo, Hi);
96 Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
97 Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
98 return;
99 }
100 }
101
102 if (InVT.isVector() && OutVT.isInteger()) {
103 // Handle cases like i64 = BITCAST v1i64 on x86, where the operand
104 // is legal but the result is not.
105 unsigned NumElems = 2;
106 EVT ElemVT = NOutVT;
107 EVT NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
108
109 // If <ElemVT * N> is not a legal type, try <ElemVT/2 * (N*2)>.
110 while (!isTypeLegal(NVT)) {
111 unsigned NewSizeInBits = ElemVT.getSizeInBits() / 2;
112 // If the element size is smaller than byte, bail.
113 if (NewSizeInBits < 8)
114 break;
115 NumElems *= 2;
116 ElemVT = EVT::getIntegerVT(*DAG.getContext(), NewSizeInBits);
117 NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
118 }
119
120 if (isTypeLegal(NVT)) {
121 SDValue CastInOp = DAG.getNode(ISD::BITCAST, dl, NVT, InOp);
122
124 for (unsigned i = 0; i < NumElems; ++i)
125 Vals.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ElemVT,
126 CastInOp, DAG.getVectorIdxConstant(i, dl)));
127
128 // Build Lo, Hi pair by pairing extracted elements if needed.
129 unsigned Slot = 0;
130 for (unsigned e = Vals.size(); e - Slot > 2; Slot += 2, e += 1) {
131 // Each iteration will BUILD_PAIR two nodes and append the result until
132 // there are only two nodes left, i.e. Lo and Hi.
133 SDValue LHS = Vals[Slot];
134 SDValue RHS = Vals[Slot + 1];
135
136 if (DAG.getDataLayout().isBigEndian())
137 std::swap(LHS, RHS);
138
139 Vals.push_back(DAG.getNode(
140 ISD::BUILD_PAIR, dl,
141 EVT::getIntegerVT(*DAG.getContext(), LHS.getValueSizeInBits() << 1),
142 LHS, RHS));
143 }
144 Lo = Vals[Slot++];
145 Hi = Vals[Slot++];
146
147 if (DAG.getDataLayout().isBigEndian())
148 std::swap(Lo, Hi);
149
150 return;
151 }
152 }
153
154 // Lower the bit-convert to a store/load from the stack.
155 assert(NOutVT.isByteSized() && "Expanded type not byte sized!");
156
157 // Create the stack frame object. Make sure it is aligned for both
158 // the source and expanded destination types.
159
160 // In cases where the vector is illegal it will be broken down into parts
161 // and stored in parts - we should use the alignment for the smallest part.
162 Align InAlign = DAG.getReducedAlign(InVT, /*UseABI=*/false);
163 Align NOutAlign = DAG.getReducedAlign(NOutVT, /*UseABI=*/false);
164 Align Align = std::max(InAlign, NOutAlign);
166 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
167 MachinePointerInfo PtrInfo =
169
170 // Emit a store to the stack slot.
171 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, PtrInfo);
172
173 // Load the first half from the stack slot.
174 Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, PtrInfo, NOutAlign);
175
176 // Increment the pointer to the other half.
177 unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
178 StackPtr =
179 DAG.getMemBasePlusOffset(StackPtr, TypeSize::getFixed(IncrementSize), dl);
180
181 // Load the second half from the stack slot.
182 Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr,
183 PtrInfo.getWithOffset(IncrementSize), NOutAlign);
184
185 // Handle endianness of the load.
186 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
187 std::swap(Lo, Hi);
188}
189
190void DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N, SDValue &Lo,
191 SDValue &Hi) {
192 // Return the operands.
193 Lo = N->getOperand(0);
194 Hi = N->getOperand(1);
195}
196
197void DAGTypeLegalizer::ExpandRes_EXTRACT_ELEMENT(SDNode *N, SDValue &Lo,
198 SDValue &Hi) {
199 GetExpandedOp(N->getOperand(0), Lo, Hi);
200 SDValue Part = N->getConstantOperandVal(1) ? Hi : Lo;
201
202 assert(Part.getValueType() == N->getValueType(0) &&
203 "Type twice as big as expanded type not itself expanded!");
204
205 GetPairElements(Part, Lo, Hi);
206}
207
208void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo,
209 SDValue &Hi) {
210 SDValue OldVec = N->getOperand(0);
211 ElementCount OldEltCount = OldVec.getValueType().getVectorElementCount();
212 EVT OldEltVT = OldVec.getValueType().getVectorElementType();
213 SDLoc dl(N);
214
215 // Convert to a vector of the expanded element type, for example
216 // <3 x i64> -> <6 x i32>.
217 EVT OldVT = N->getValueType(0);
218 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
219
220 if (OldVT != OldEltVT) {
221 // The result of EXTRACT_VECTOR_ELT may be larger than the element type of
222 // the input vector. If so, extend the elements of the input vector to the
223 // same bitwidth as the result before expanding.
224 assert(OldEltVT.bitsLT(OldVT) && "Result type smaller then element type!");
225 EVT NVecVT = EVT::getVectorVT(*DAG.getContext(), OldVT, OldEltCount);
226 OldVec = DAG.getNode(ISD::ANY_EXTEND, dl, NVecVT, N->getOperand(0));
227 }
228
229 SDValue NewVec = DAG.getNode(
230 ISD::BITCAST, dl,
231 EVT::getVectorVT(*DAG.getContext(), NewVT, OldEltCount * 2), OldVec);
232
233 // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
234 SDValue Idx = N->getOperand(1);
235
236 Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
237 Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
238
239 Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
240 DAG.getConstant(1, dl, Idx.getValueType()));
241 Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
242
243 if (DAG.getDataLayout().isBigEndian())
244 std::swap(Lo, Hi);
245}
246
247void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
248 SDValue &Hi) {
249 assert(ISD::isNormalLoad(N) && "This routine only for normal loads!");
250 SDLoc dl(N);
251
252 LoadSDNode *LD = cast<LoadSDNode>(N);
253 assert(!LD->isAtomic() && "Atomics can not be split");
254 EVT ValueVT = LD->getValueType(0);
255 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
256 SDValue Chain = LD->getChain();
257 SDValue Ptr = LD->getBasePtr();
258 AAMDNodes AAInfo = LD->getAAInfo();
259
260 assert(NVT.isByteSized() && "Expanded type not byte sized!");
261
262 Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getPointerInfo(),
263 LD->getOriginalAlign(), LD->getMemOperand()->getFlags(),
264 AAInfo);
265
266 // Increment the pointer to the other half.
267 unsigned IncrementSize = NVT.getSizeInBits() / 8;
268 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
269 Hi = DAG.getLoad(
270 NVT, dl, Chain, Ptr, LD->getPointerInfo().getWithOffset(IncrementSize),
271 LD->getOriginalAlign(), LD->getMemOperand()->getFlags(), AAInfo);
272
273 // Build a factor node to remember that this load is independent of the
274 // other one.
275 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
276 Hi.getValue(1));
277
278 // Handle endianness of the load.
279 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
280 std::swap(Lo, Hi);
281
282 // Modified the chain - switch anything that used the old chain to use
283 // the new one.
284 ReplaceValueWith(SDValue(N, 1), Chain);
285}
286
287void DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
288 EVT OVT = N->getValueType(0);
289 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
290 SDValue Chain = N->getOperand(0);
291 SDValue Ptr = N->getOperand(1);
292 SDLoc dl(N);
293 const unsigned Align = N->getConstantOperandVal(3);
294
295 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), Align);
296 Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, N->getOperand(2), 0);
297 Chain = Hi.getValue(1);
298
299 // Handle endianness of the load.
300 if (TLI.hasBigEndianPartOrdering(OVT, DAG.getDataLayout()))
301 std::swap(Lo, Hi);
302
303 // Modified the chain - switch anything that used the old chain to use
304 // the new one.
305 ReplaceValueWith(SDValue(N, 1), Chain);
306}
307
308
309//===--------------------------------------------------------------------===//
310// Generic Operand Expansion.
311//===--------------------------------------------------------------------===//
312
313void DAGTypeLegalizer::IntegerToVector(SDValue Op, unsigned NumElements,
315 EVT EltVT) {
316 assert(Op.getValueType().isInteger());
317 SDLoc DL(Op);
318 SDValue Parts[2];
319
320 if (NumElements > 1) {
321 NumElements >>= 1;
322 SplitInteger(Op, Parts[0], Parts[1]);
323 if (DAG.getDataLayout().isBigEndian())
324 std::swap(Parts[0], Parts[1]);
325 IntegerToVector(Parts[0], NumElements, Ops, EltVT);
326 IntegerToVector(Parts[1], NumElements, Ops, EltVT);
327 } else {
328 Ops.push_back(DAG.getNode(ISD::BITCAST, DL, EltVT, Op));
329 }
330}
331
332SDValue DAGTypeLegalizer::ExpandOp_BITCAST(SDNode *N) {
333 SDLoc dl(N);
334 if (N->getValueType(0).isVector() &&
335 N->getOperand(0).getValueType().isInteger()) {
336 // An illegal expanding type is being converted to a legal vector type.
337 // Make a two element vector out of the expanded parts and convert that
338 // instead, but only if the new vector type is legal (otherwise there
339 // is no point, and it might create expansion loops). For example, on
340 // x86 this turns v1i64 = BITCAST i64 into v1i64 = BITCAST v2i32.
341 //
342 // FIXME: I'm not sure why we are first trying to split the input into
343 // a 2 element vector, so I'm leaving it here to maintain the current
344 // behavior.
345 unsigned NumElts = 2;
346 EVT OVT = N->getOperand(0).getValueType();
347 EVT NVT = EVT::getVectorVT(*DAG.getContext(),
348 TLI.getTypeToTransformTo(*DAG.getContext(), OVT),
349 NumElts);
350 if (!isTypeLegal(NVT)) {
351 // If we can't find a legal type by splitting the integer in half,
352 // then we can use the node's value type.
353 NumElts = N->getValueType(0).getVectorNumElements();
354 NVT = N->getValueType(0);
355 }
356
358 IntegerToVector(N->getOperand(0), NumElts, Ops, NVT.getVectorElementType());
359
360 SDValue Vec = DAG.getBuildVector(NVT, dl, ArrayRef(Ops.data(), NumElts));
361 return DAG.getNode(ISD::BITCAST, dl, N->getValueType(0), Vec);
362 }
363
364 // Otherwise, store to a temporary and load out again as the new type.
365 return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
366}
367
368SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
369 // The vector type is legal but the element type needs expansion.
370 EVT VecVT = N->getValueType(0);
371 unsigned NumElts = VecVT.getVectorNumElements();
372 EVT OldVT = N->getOperand(0).getValueType();
373 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
374 SDLoc dl(N);
375
376 assert(OldVT == VecVT.getVectorElementType() &&
377 "BUILD_VECTOR operand type doesn't match vector element type!");
378
379 if (VecVT.isInteger() && TLI.isOperationLegal(ISD::SPLAT_VECTOR, VecVT) &&
381 if (SDValue V = cast<BuildVectorSDNode>(N)->getSplatValue()) {
382 SDValue Lo, Hi;
383 GetExpandedOp(V, Lo, Hi);
384 return DAG.getNode(ISD::SPLAT_VECTOR_PARTS, dl, VecVT, Lo, Hi);
385 }
386 }
387
388 // Build a vector of twice the length out of the expanded elements.
389 // For example <3 x i64> -> <6 x i32>.
391 NewElts.reserve(NumElts*2);
392
393 for (unsigned i = 0; i < NumElts; ++i) {
394 SDValue Lo, Hi;
395 GetExpandedOp(N->getOperand(i), Lo, Hi);
396 if (DAG.getDataLayout().isBigEndian())
397 std::swap(Lo, Hi);
398 NewElts.push_back(Lo);
399 NewElts.push_back(Hi);
400 }
401
402 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NewElts.size());
403 SDValue NewVec = DAG.getBuildVector(NewVecVT, dl, NewElts);
404
405 // Convert the new vector to the old vector type.
406 return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
407}
408
409SDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
410 SDValue Lo, Hi;
411 GetExpandedOp(N->getOperand(0), Lo, Hi);
412 return N->getConstantOperandVal(1) ? Hi : Lo;
413}
414
415// Split the integer operand in two and create a second FAKE_USE node for
416// the other half. The original SDNode is updated in place.
417SDValue DAGTypeLegalizer::ExpandOp_FAKE_USE(SDNode *N) {
418 SDValue Lo, Hi;
419 SDValue Chain = N->getOperand(0);
420 GetExpandedOp(N->getOperand(1), Lo, Hi);
421 SDValue LoUse = DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other, Chain, Lo);
422 DAG.UpdateNodeOperands(N, LoUse, Hi);
423 return SDValue(N, 0);
424}
425
426SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
427 // The vector type is legal but the element type needs expansion.
428 EVT VecVT = N->getValueType(0);
429 unsigned NumElts = VecVT.getVectorNumElements();
430 SDLoc dl(N);
431
432 SDValue Val = N->getOperand(1);
433 EVT OldEVT = Val.getValueType();
434 EVT NewEVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldEVT);
435
436 assert(OldEVT == VecVT.getVectorElementType() &&
437 "Inserted element type doesn't match vector element type!");
438
439 // Bitconvert to a vector of twice the length with elements of the expanded
440 // type, insert the expanded vector elements, and then convert back.
441 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEVT, NumElts*2);
442 SDValue NewVec = DAG.getNode(ISD::BITCAST, dl,
443 NewVecVT, N->getOperand(0));
444
445 SDValue Lo, Hi;
446 GetExpandedOp(Val, Lo, Hi);
447 if (DAG.getDataLayout().isBigEndian())
448 std::swap(Lo, Hi);
449
450 SDValue Idx = N->getOperand(2);
451 Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
452 NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx);
453 Idx = DAG.getNode(ISD::ADD, dl,
454 Idx.getValueType(), Idx,
455 DAG.getConstant(1, dl, Idx.getValueType()));
456 NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx);
457
458 // Convert the new vector to the old vector type.
459 return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
460}
461
462SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
463 SDLoc dl(N);
464 EVT VT = N->getValueType(0);
465 assert(VT.getVectorElementType() == N->getOperand(0).getValueType() &&
466 "SCALAR_TO_VECTOR operand type doesn't match vector element type!");
467 unsigned NumElts = VT.getVectorNumElements();
468 SmallVector<SDValue, 16> Ops(NumElts);
469 Ops[0] = N->getOperand(0);
470 SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType());
471 for (unsigned i = 1; i < NumElts; ++i)
472 Ops[i] = UndefVal;
473 return DAG.getBuildVector(VT, dl, Ops);
474}
475
476SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
477 assert(ISD::isNormalStore(N) && "This routine only for normal stores!");
478 assert(OpNo == 1 && "Can only expand the stored value so far");
479 SDLoc dl(N);
480
481 StoreSDNode *St = cast<StoreSDNode>(N);
482 assert(!St->isAtomic() && "Atomics can not be split");
483 EVT ValueVT = St->getValue().getValueType();
484 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
485 SDValue Chain = St->getChain();
486 SDValue Ptr = St->getBasePtr();
487 AAMDNodes AAInfo = St->getAAInfo();
488
489 assert(NVT.isByteSized() && "Expanded type not byte sized!");
490 unsigned IncrementSize = NVT.getSizeInBits() / 8;
491
492 SDValue Lo, Hi;
493 GetExpandedOp(St->getValue(), Lo, Hi);
494
495 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
496 std::swap(Lo, Hi);
497
498 Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getPointerInfo(),
500 AAInfo);
501
502 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
503 Hi = DAG.getStore(
504 Chain, dl, Hi, Ptr, St->getPointerInfo().getWithOffset(IncrementSize),
505 St->getOriginalAlign(), St->getMemOperand()->getFlags(), AAInfo);
506
507 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
508}
509
510
511//===--------------------------------------------------------------------===//
512// Generic Result Splitting.
513//===--------------------------------------------------------------------===//
514
515// Be careful to make no assumptions about which of Lo/Hi is stored first in
516// memory (for vectors it is always Lo first followed by Hi in the following
517// bytes; for integers and floats it is Lo first if and only if the machine is
518// little-endian).
519
520void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
521 SDValue &Lo, SDValue &Hi) {
522 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
523 GetSplitOp(Op, Lo, Hi);
524}
525
526void DAGTypeLegalizer::SplitRes_Select(SDNode *N, SDValue &Lo, SDValue &Hi) {
527 SDValue LL, LH, RL, RH, CL, CH;
528 SDLoc dl(N);
529 unsigned Opcode = N->getOpcode();
530 GetSplitOp(N->getOperand(1), LL, LH);
531 GetSplitOp(N->getOperand(2), RL, RH);
532
533 SDValue Cond = N->getOperand(0);
534 CL = CH = Cond;
535 if (Cond.getValueType().isVector()) {
536 if (SDValue Res = WidenVSELECTMask(N))
537 std::tie(CL, CH) = DAG.SplitVector(Res, dl);
538 // Check if there are already splitted versions of the vector available and
539 // use those instead of splitting the mask operand again.
540 else if (getTypeAction(Cond.getValueType()) ==
542 GetSplitVector(Cond, CL, CH);
543 // It seems to improve code to generate two narrow SETCCs as opposed to
544 // splitting a wide result vector.
545 else if (Cond.getOpcode() == ISD::SETCC) {
546 // If the condition is a vXi1 vector, and the LHS of the setcc is a legal
547 // type and the setcc result type is the same vXi1, then leave the setcc
548 // alone.
549 EVT CondLHSVT = Cond.getOperand(0).getValueType();
550 if (Cond.getValueType().getVectorElementType() == MVT::i1 &&
551 isTypeLegal(CondLHSVT) &&
552 getSetCCResultType(CondLHSVT) == Cond.getValueType())
553 std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
554 else
555 SplitVecRes_SETCC(Cond.getNode(), CL, CH);
556 } else
557 std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
558 }
559
560 if (Opcode != ISD::VP_SELECT && Opcode != ISD::VP_MERGE) {
561 Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL);
562 Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH);
563 return;
564 }
565
566 SDValue EVLLo, EVLHi;
567 std::tie(EVLLo, EVLHi) =
568 DAG.SplitEVL(N->getOperand(3), N->getValueType(0), dl);
569
570 Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL, EVLLo);
571 Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH, EVLHi);
572}
573
574void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
575 SDValue &Hi) {
576 SDValue LL, LH, RL, RH;
577 SDLoc dl(N);
578 GetSplitOp(N->getOperand(2), LL, LH);
579 GetSplitOp(N->getOperand(3), RL, RH);
580
581 Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0),
582 N->getOperand(1), LL, RL, N->getOperand(4));
583 Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0),
584 N->getOperand(1), LH, RH, N->getOperand(4));
585}
586
587void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
588 EVT LoVT, HiVT;
589 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
590 Lo = DAG.getUNDEF(LoVT);
591 Hi = DAG.getUNDEF(HiVT);
592}
593
594void DAGTypeLegalizer::SplitVecRes_AssertZext(SDNode *N, SDValue &Lo,
595 SDValue &Hi) {
596 SDValue L, H;
597 SDLoc dl(N);
598 GetSplitOp(N->getOperand(0), L, H);
599
600 Lo = DAG.getNode(ISD::AssertZext, dl, L.getValueType(), L, N->getOperand(1));
601 Hi = DAG.getNode(ISD::AssertZext, dl, H.getValueType(), H, N->getOperand(1));
602}
603
604void DAGTypeLegalizer::SplitRes_FREEZE(SDNode *N, SDValue &Lo, SDValue &Hi) {
605 SDValue L, H;
606 SDLoc dl(N);
607 GetSplitOp(N->getOperand(0), L, H);
608
609 Lo = DAG.getNode(ISD::FREEZE, dl, L.getValueType(), L);
610 Hi = DAG.getNode(ISD::FREEZE, dl, H.getValueType(), H);
611}
612
613void DAGTypeLegalizer::SplitRes_ARITH_FENCE(SDNode *N, SDValue &Lo,
614 SDValue &Hi) {
615 SDValue L, H;
616 SDLoc DL(N);
617 GetSplitOp(N->getOperand(0), L, H);
618
619 Lo = DAG.getNode(ISD::ARITH_FENCE, DL, L.getValueType(), L);
620 Hi = DAG.getNode(ISD::ARITH_FENCE, DL, H.getValueType(), H);
621}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define H(x, y, z)
Definition: MD5.cpp:57
const SmallVectorImpl< MachineOperand > & Cond
#define CH(x, y, z)
Definition: SHA256.cpp:34
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
Value * RHS
Value * LHS
support::ulittle16_t & Lo
Definition: aarch32.cpp:204
support::ulittle16_t & Hi
Definition: aarch32.cpp:203
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
This class represents an Operation in the Expression.
bool isBigEndian() const
Definition: DataLayout.h:198
This class is used to represent ISD::LOAD nodes.
Flags getFlags() const
Return the raw flags of the source value,.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
Align getOriginalAlign() const
Returns alignment and volatility of the memory access.
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.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
EVT getValueType() const
Return the ValueType of the referenced return value.
Align getReducedAlign(EVT VT, bool UseABI)
In most cases this function returns the ABI alignment for a given type, except for illegal vector typ...
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
std::pair< EVT, EVT > GetSplitDestVTs(const EVT &VT) const
Compute the VTs needed for the low/hi parts of a type which is split (or expanded) into two not neces...
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
Definition: SelectionDAG.h:854
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:495
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue SV, unsigned Align)
VAArg produces a result and token chain, and takes a pointer and a source value as input.
std::pair< SDValue, SDValue > SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the vector with EXTRACT_SUBVECTOR using the provided VTs and return the low/high part.
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
std::pair< SDValue, SDValue > SplitEVL(SDValue N, EVT VecVT, const SDLoc &DL)
Split the explicit vector length parameter of a VP operation.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:490
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
Definition: SelectionDAG.h:508
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:578
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void reserve(size_type N)
Definition: SmallVector.h:663
void push_back(const T &Elt)
Definition: SmallVector.h:413
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:286
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:345
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:780
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:814
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
Definition: ISDOpcodes.h:1383
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:954
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition: ISDOpcodes.h:236
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition: ISDOpcodes.h:642
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
Definition: ISDOpcodes.h:1296
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:550
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:772
@ SPLAT_VECTOR_PARTS
SPLAT_VECTOR_PARTS(SCALAR1, SCALAR2, ...) - Returns a vector with the scalar values joined together a...
Definition: ISDOpcodes.h:651
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
Definition: ISDOpcodes.h:223
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition: ISDOpcodes.h:539
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ AssertZext
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: AddressRanges.h:18
Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
#define N
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition: Metadata.h:760
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
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:390
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:295
ElementCount getVectorElementCount() const
Definition: ValueTypes.h:345
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
bool isByteSized() const
Return true if the bit size is a multiple of 8.
Definition: ValueTypes.h:238
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:323
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:331
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:152
This class contains a discriminated union of information about pointers in memory operands,...
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.