LLVM 19.0.0git
LegalizeVectorOps.cpp
Go to the documentation of this file.
1//===- LegalizeVectorOps.cpp - Implement SelectionDAG::LegalizeVectors ----===//
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 the SelectionDAG::LegalizeVectors method.
10//
11// The vector legalizer looks for vector operations which might need to be
12// scalarized and legalizes them. This is a separate step from Legalize because
13// scalarizing can introduce illegal types. For example, suppose we have an
14// ISD::SDIV of type v2i64 on x86-32. The type is legal (for example, addition
15// on a v2i64 is legal), but ISD::SDIV isn't legal, so we have to unroll the
16// operation, which introduces nodes with the illegal type i64 which must be
17// expanded. Similarly, suppose we have an ISD::SRA of type v16i8 on PowerPC;
18// the operation must be unrolled, which introduces nodes with the illegal
19// type i8 which must be promoted.
20//
21// This does not legalize vector manipulations like ISD::BUILD_VECTOR,
22// or operations that happen to take a vector which are custom-lowered;
23// the legalization for such operations never produces nodes
24// with illegal types, so it's okay to put off legalizing them until
25// SelectionDAG::Legalize runs.
26//
27//===----------------------------------------------------------------------===//
28
29#include "llvm/ADT/DenseMap.h"
39#include "llvm/IR/DataLayout.h"
42#include "llvm/Support/Debug.h"
44#include <cassert>
45#include <cstdint>
46#include <iterator>
47#include <utility>
48
49using namespace llvm;
50
51#define DEBUG_TYPE "legalizevectorops"
52
53namespace {
54
55class VectorLegalizer {
56 SelectionDAG& DAG;
57 const TargetLowering &TLI;
58 bool Changed = false; // Keep track of whether anything changed
59
60 /// For nodes that are of legal width, and that have more than one use, this
61 /// map indicates what regularized operand to use. This allows us to avoid
62 /// legalizing the same thing more than once.
64
65 /// Adds a node to the translation cache.
66 void AddLegalizedOperand(SDValue From, SDValue To) {
67 LegalizedNodes.insert(std::make_pair(From, To));
68 // If someone requests legalization of the new node, return itself.
69 if (From != To)
70 LegalizedNodes.insert(std::make_pair(To, To));
71 }
72
73 /// Legalizes the given node.
74 SDValue LegalizeOp(SDValue Op);
75
76 /// Assuming the node is legal, "legalize" the results.
77 SDValue TranslateLegalizeResults(SDValue Op, SDNode *Result);
78
79 /// Make sure Results are legal and update the translation cache.
80 SDValue RecursivelyLegalizeResults(SDValue Op,
82
83 /// Wrapper to interface LowerOperation with a vector of Results.
84 /// Returns false if the target wants to use default expansion. Otherwise
85 /// returns true. If return is true and the Results are empty, then the
86 /// target wants to keep the input node as is.
87 bool LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results);
88
89 /// Implements unrolling a VSETCC.
90 SDValue UnrollVSETCC(SDNode *Node);
91
92 /// Implement expand-based legalization of vector operations.
93 ///
94 /// This is just a high-level routine to dispatch to specific code paths for
95 /// operations to legalize them.
97
98 /// Implements expansion for FP_TO_UINT; falls back to UnrollVectorOp if
99 /// FP_TO_SINT isn't legal.
100 void ExpandFP_TO_UINT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
101
102 /// Implements expansion for UINT_TO_FLOAT; falls back to UnrollVectorOp if
103 /// SINT_TO_FLOAT and SHR on vectors isn't legal.
104 void ExpandUINT_TO_FLOAT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
105
106 /// Implement expansion for SIGN_EXTEND_INREG using SRL and SRA.
107 SDValue ExpandSEXTINREG(SDNode *Node);
108
109 /// Implement expansion for ANY_EXTEND_VECTOR_INREG.
110 ///
111 /// Shuffles the low lanes of the operand into place and bitcasts to the proper
112 /// type. The contents of the bits in the extended part of each element are
113 /// undef.
114 SDValue ExpandANY_EXTEND_VECTOR_INREG(SDNode *Node);
115
116 /// Implement expansion for SIGN_EXTEND_VECTOR_INREG.
117 ///
118 /// Shuffles the low lanes of the operand into place, bitcasts to the proper
119 /// type, then shifts left and arithmetic shifts right to introduce a sign
120 /// extension.
121 SDValue ExpandSIGN_EXTEND_VECTOR_INREG(SDNode *Node);
122
123 /// Implement expansion for ZERO_EXTEND_VECTOR_INREG.
124 ///
125 /// Shuffles the low lanes of the operand into place and blends zeros into
126 /// the remaining lanes, finally bitcasting to the proper type.
127 SDValue ExpandZERO_EXTEND_VECTOR_INREG(SDNode *Node);
128
129 /// Expand bswap of vectors into a shuffle if legal.
130 SDValue ExpandBSWAP(SDNode *Node);
131
132 /// Implement vselect in terms of XOR, AND, OR when blend is not
133 /// supported by the target.
134 SDValue ExpandVSELECT(SDNode *Node);
135 SDValue ExpandVP_SELECT(SDNode *Node);
136 SDValue ExpandVP_MERGE(SDNode *Node);
137 SDValue ExpandVP_REM(SDNode *Node);
138 SDValue ExpandSELECT(SDNode *Node);
139 std::pair<SDValue, SDValue> ExpandLoad(SDNode *N);
140 SDValue ExpandStore(SDNode *N);
141 SDValue ExpandFNEG(SDNode *Node);
142 void ExpandFSUB(SDNode *Node, SmallVectorImpl<SDValue> &Results);
143 void ExpandSETCC(SDNode *Node, SmallVectorImpl<SDValue> &Results);
144 void ExpandBITREVERSE(SDNode *Node, SmallVectorImpl<SDValue> &Results);
145 void ExpandUADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
146 void ExpandSADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
147 void ExpandMULO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
148 void ExpandFixedPointDiv(SDNode *Node, SmallVectorImpl<SDValue> &Results);
149 void ExpandStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);
150 void ExpandREM(SDNode *Node, SmallVectorImpl<SDValue> &Results);
151
152 bool tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall LC,
154 bool tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall Call_F32,
155 RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80,
156 RTLIB::Libcall Call_F128,
157 RTLIB::Libcall Call_PPCF128,
159
160 void UnrollStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);
161
162 /// Implements vector promotion.
163 ///
164 /// This is essentially just bitcasting the operands to a different type and
165 /// bitcasting the result back to the original type.
167
168 /// Implements [SU]INT_TO_FP vector promotion.
169 ///
170 /// This is a [zs]ext of the input operand to a larger integer type.
171 void PromoteINT_TO_FP(SDNode *Node, SmallVectorImpl<SDValue> &Results);
172
173 /// Implements FP_TO_[SU]INT vector promotion of the result type.
174 ///
175 /// It is promoted to a larger integer type. The result is then
176 /// truncated back to the original type.
177 void PromoteFP_TO_INT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
178
179 /// Implements vector reduce operation promotion.
180 ///
181 /// All vector operands are promoted to a vector type with larger element
182 /// type, and the start value is promoted to a larger scalar type. Then the
183 /// result is truncated back to the original scalar type.
184 void PromoteReduction(SDNode *Node, SmallVectorImpl<SDValue> &Results);
185
186 /// Implements vector setcc operation promotion.
187 ///
188 /// All vector operands are promoted to a vector type with larger element
189 /// type.
190 void PromoteSETCC(SDNode *Node, SmallVectorImpl<SDValue> &Results);
191
192 void PromoteSTRICT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
193
194public:
195 VectorLegalizer(SelectionDAG& dag) :
196 DAG(dag), TLI(dag.getTargetLoweringInfo()) {}
197
198 /// Begin legalizer the vector operations in the DAG.
199 bool Run();
200};
201
202} // end anonymous namespace
203
204bool VectorLegalizer::Run() {
205 // Before we start legalizing vector nodes, check if there are any vectors.
206 bool HasVectors = false;
207 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
208 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I) {
209 // Check if the values of the nodes contain vectors. We don't need to check
210 // the operands because we are going to check their values at some point.
211 HasVectors = llvm::any_of(I->values(), [](EVT T) { return T.isVector(); });
212
213 // If we found a vector node we can start the legalization.
214 if (HasVectors)
215 break;
216 }
217
218 // If this basic block has no vectors then no need to legalize vectors.
219 if (!HasVectors)
220 return false;
221
222 // The legalize process is inherently a bottom-up recursive process (users
223 // legalize their uses before themselves). Given infinite stack space, we
224 // could just start legalizing on the root and traverse the whole graph. In
225 // practice however, this causes us to run out of stack space on large basic
226 // blocks. To avoid this problem, compute an ordering of the nodes where each
227 // node is only legalized after all of its operands are legalized.
228 DAG.AssignTopologicalOrder();
229 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
230 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I)
231 LegalizeOp(SDValue(&*I, 0));
232
233 // Finally, it's possible the root changed. Get the new root.
234 SDValue OldRoot = DAG.getRoot();
235 assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?");
236 DAG.setRoot(LegalizedNodes[OldRoot]);
237
238 LegalizedNodes.clear();
239
240 // Remove dead nodes now.
241 DAG.RemoveDeadNodes();
242
243 return Changed;
244}
245
246SDValue VectorLegalizer::TranslateLegalizeResults(SDValue Op, SDNode *Result) {
247 assert(Op->getNumValues() == Result->getNumValues() &&
248 "Unexpected number of results");
249 // Generic legalization: just pass the operand through.
250 for (unsigned i = 0, e = Op->getNumValues(); i != e; ++i)
251 AddLegalizedOperand(Op.getValue(i), SDValue(Result, i));
252 return SDValue(Result, Op.getResNo());
253}
254
256VectorLegalizer::RecursivelyLegalizeResults(SDValue Op,
258 assert(Results.size() == Op->getNumValues() &&
259 "Unexpected number of results");
260 // Make sure that the generated code is itself legal.
261 for (unsigned i = 0, e = Results.size(); i != e; ++i) {
262 Results[i] = LegalizeOp(Results[i]);
263 AddLegalizedOperand(Op.getValue(i), Results[i]);
264 }
265
266 return Results[Op.getResNo()];
267}
268
269SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
270 // Note that LegalizeOp may be reentered even from single-use nodes, which
271 // means that we always must cache transformed nodes.
272 DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op);
273 if (I != LegalizedNodes.end()) return I->second;
274
275 // Legalize the operands
277 for (const SDValue &Oper : Op->op_values())
278 Ops.push_back(LegalizeOp(Oper));
279
280 SDNode *Node = DAG.UpdateNodeOperands(Op.getNode(), Ops);
281
282 bool HasVectorValueOrOp =
283 llvm::any_of(Node->values(), [](EVT T) { return T.isVector(); }) ||
284 llvm::any_of(Node->op_values(),
285 [](SDValue O) { return O.getValueType().isVector(); });
286 if (!HasVectorValueOrOp)
287 return TranslateLegalizeResults(Op, Node);
288
289 TargetLowering::LegalizeAction Action = TargetLowering::Legal;
290 EVT ValVT;
291 switch (Op.getOpcode()) {
292 default:
293 return TranslateLegalizeResults(Op, Node);
294 case ISD::LOAD: {
295 LoadSDNode *LD = cast<LoadSDNode>(Node);
296 ISD::LoadExtType ExtType = LD->getExtensionType();
297 EVT LoadedVT = LD->getMemoryVT();
298 if (LoadedVT.isVector() && ExtType != ISD::NON_EXTLOAD)
299 Action = TLI.getLoadExtAction(ExtType, LD->getValueType(0), LoadedVT);
300 break;
301 }
302 case ISD::STORE: {
303 StoreSDNode *ST = cast<StoreSDNode>(Node);
304 EVT StVT = ST->getMemoryVT();
305 MVT ValVT = ST->getValue().getSimpleValueType();
306 if (StVT.isVector() && ST->isTruncatingStore())
307 Action = TLI.getTruncStoreAction(ValVT, StVT);
308 break;
309 }
311 Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
312 // This operation lies about being legal: when it claims to be legal,
313 // it should actually be expanded.
314 if (Action == TargetLowering::Legal)
315 Action = TargetLowering::Expand;
316 break;
317#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
318 case ISD::STRICT_##DAGN:
319#include "llvm/IR/ConstrainedOps.def"
320 ValVT = Node->getValueType(0);
321 if (Op.getOpcode() == ISD::STRICT_SINT_TO_FP ||
322 Op.getOpcode() == ISD::STRICT_UINT_TO_FP)
323 ValVT = Node->getOperand(1).getValueType();
324 if (Op.getOpcode() == ISD::STRICT_FSETCC ||
325 Op.getOpcode() == ISD::STRICT_FSETCCS) {
326 MVT OpVT = Node->getOperand(1).getSimpleValueType();
327 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(3))->get();
328 Action = TLI.getCondCodeAction(CCCode, OpVT);
329 if (Action == TargetLowering::Legal)
330 Action = TLI.getOperationAction(Node->getOpcode(), OpVT);
331 } else {
332 Action = TLI.getOperationAction(Node->getOpcode(), ValVT);
333 }
334 // If we're asked to expand a strict vector floating-point operation,
335 // by default we're going to simply unroll it. That is usually the
336 // best approach, except in the case where the resulting strict (scalar)
337 // operations would themselves use the fallback mutation to non-strict.
338 // In that specific case, just do the fallback on the vector op.
339 if (Action == TargetLowering::Expand && !TLI.isStrictFPEnabled() &&
340 TLI.getStrictFPOperationAction(Node->getOpcode(), ValVT) ==
341 TargetLowering::Legal) {
342 EVT EltVT = ValVT.getVectorElementType();
343 if (TLI.getOperationAction(Node->getOpcode(), EltVT)
344 == TargetLowering::Expand &&
345 TLI.getStrictFPOperationAction(Node->getOpcode(), EltVT)
346 == TargetLowering::Legal)
347 Action = TargetLowering::Legal;
348 }
349 break;
350 case ISD::ADD:
351 case ISD::SUB:
352 case ISD::MUL:
353 case ISD::MULHS:
354 case ISD::MULHU:
355 case ISD::SDIV:
356 case ISD::UDIV:
357 case ISD::SREM:
358 case ISD::UREM:
359 case ISD::SDIVREM:
360 case ISD::UDIVREM:
361 case ISD::FADD:
362 case ISD::FSUB:
363 case ISD::FMUL:
364 case ISD::FDIV:
365 case ISD::FREM:
366 case ISD::AND:
367 case ISD::OR:
368 case ISD::XOR:
369 case ISD::SHL:
370 case ISD::SRA:
371 case ISD::SRL:
372 case ISD::FSHL:
373 case ISD::FSHR:
374 case ISD::ROTL:
375 case ISD::ROTR:
376 case ISD::ABS:
377 case ISD::BSWAP:
378 case ISD::BITREVERSE:
379 case ISD::CTLZ:
380 case ISD::CTTZ:
383 case ISD::CTPOP:
384 case ISD::SELECT:
385 case ISD::VSELECT:
386 case ISD::SELECT_CC:
387 case ISD::ZERO_EXTEND:
388 case ISD::ANY_EXTEND:
389 case ISD::TRUNCATE:
390 case ISD::SIGN_EXTEND:
391 case ISD::FP_TO_SINT:
392 case ISD::FP_TO_UINT:
393 case ISD::FNEG:
394 case ISD::FABS:
395 case ISD::FMINNUM:
396 case ISD::FMAXNUM:
399 case ISD::FMINIMUM:
400 case ISD::FMAXIMUM:
401 case ISD::FCOPYSIGN:
402 case ISD::FSQRT:
403 case ISD::FSIN:
404 case ISD::FCOS:
405 case ISD::FLDEXP:
406 case ISD::FPOWI:
407 case ISD::FPOW:
408 case ISD::FLOG:
409 case ISD::FLOG2:
410 case ISD::FLOG10:
411 case ISD::FEXP:
412 case ISD::FEXP2:
413 case ISD::FEXP10:
414 case ISD::FCEIL:
415 case ISD::FTRUNC:
416 case ISD::FRINT:
417 case ISD::FNEARBYINT:
418 case ISD::FROUND:
419 case ISD::FROUNDEVEN:
420 case ISD::FFLOOR:
421 case ISD::FP_ROUND:
422 case ISD::FP_EXTEND:
423 case ISD::FMA:
428 case ISD::SMIN:
429 case ISD::SMAX:
430 case ISD::UMIN:
431 case ISD::UMAX:
432 case ISD::SMUL_LOHI:
433 case ISD::UMUL_LOHI:
434 case ISD::SADDO:
435 case ISD::UADDO:
436 case ISD::SSUBO:
437 case ISD::USUBO:
438 case ISD::SMULO:
439 case ISD::UMULO:
441 case ISD::FFREXP:
442 case ISD::SADDSAT:
443 case ISD::UADDSAT:
444 case ISD::SSUBSAT:
445 case ISD::USUBSAT:
446 case ISD::SSHLSAT:
447 case ISD::USHLSAT:
450 case ISD::MGATHER:
451 Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
452 break;
453 case ISD::SMULFIX:
454 case ISD::SMULFIXSAT:
455 case ISD::UMULFIX:
456 case ISD::UMULFIXSAT:
457 case ISD::SDIVFIX:
458 case ISD::SDIVFIXSAT:
459 case ISD::UDIVFIX:
460 case ISD::UDIVFIXSAT: {
461 unsigned Scale = Node->getConstantOperandVal(2);
462 Action = TLI.getFixedPointOperationAction(Node->getOpcode(),
463 Node->getValueType(0), Scale);
464 break;
465 }
466 case ISD::LRINT:
467 case ISD::LLRINT:
468 case ISD::SINT_TO_FP:
469 case ISD::UINT_TO_FP:
485 Action = TLI.getOperationAction(Node->getOpcode(),
486 Node->getOperand(0).getValueType());
487 break;
490 Action = TLI.getOperationAction(Node->getOpcode(),
491 Node->getOperand(1).getValueType());
492 break;
493 case ISD::SETCC: {
494 MVT OpVT = Node->getOperand(0).getSimpleValueType();
495 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get();
496 Action = TLI.getCondCodeAction(CCCode, OpVT);
497 if (Action == TargetLowering::Legal)
498 Action = TLI.getOperationAction(Node->getOpcode(), OpVT);
499 break;
500 }
501
502#define BEGIN_REGISTER_VP_SDNODE(VPID, LEGALPOS, ...) \
503 case ISD::VPID: { \
504 EVT LegalizeVT = LEGALPOS < 0 ? Node->getValueType(-(1 + LEGALPOS)) \
505 : Node->getOperand(LEGALPOS).getValueType(); \
506 if (ISD::VPID == ISD::VP_SETCC) { \
507 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get(); \
508 Action = TLI.getCondCodeAction(CCCode, LegalizeVT.getSimpleVT()); \
509 if (Action != TargetLowering::Legal) \
510 break; \
511 } \
512 Action = TLI.getOperationAction(Node->getOpcode(), LegalizeVT); \
513 } break;
514#include "llvm/IR/VPIntrinsics.def"
515 }
516
517 LLVM_DEBUG(dbgs() << "\nLegalizing vector op: "; Node->dump(&DAG));
518
519 SmallVector<SDValue, 8> ResultVals;
520 switch (Action) {
521 default: llvm_unreachable("This action is not supported yet!");
522 case TargetLowering::Promote:
523 assert((Op.getOpcode() != ISD::LOAD && Op.getOpcode() != ISD::STORE) &&
524 "This action is not supported yet!");
525 LLVM_DEBUG(dbgs() << "Promoting\n");
526 Promote(Node, ResultVals);
527 assert(!ResultVals.empty() && "No results for promotion?");
528 break;
529 case TargetLowering::Legal:
530 LLVM_DEBUG(dbgs() << "Legal node: nothing to do\n");
531 break;
532 case TargetLowering::Custom:
533 LLVM_DEBUG(dbgs() << "Trying custom legalization\n");
534 if (LowerOperationWrapper(Node, ResultVals))
535 break;
536 LLVM_DEBUG(dbgs() << "Could not custom legalize node\n");
537 [[fallthrough]];
538 case TargetLowering::Expand:
539 LLVM_DEBUG(dbgs() << "Expanding\n");
540 Expand(Node, ResultVals);
541 break;
542 }
543
544 if (ResultVals.empty())
545 return TranslateLegalizeResults(Op, Node);
546
547 Changed = true;
548 return RecursivelyLegalizeResults(Op, ResultVals);
549}
550
551// FIXME: This is very similar to TargetLowering::LowerOperationWrapper. Can we
552// merge them somehow?
553bool VectorLegalizer::LowerOperationWrapper(SDNode *Node,
555 SDValue Res = TLI.LowerOperation(SDValue(Node, 0), DAG);
556
557 if (!Res.getNode())
558 return false;
559
560 if (Res == SDValue(Node, 0))
561 return true;
562
563 // If the original node has one result, take the return value from
564 // LowerOperation as is. It might not be result number 0.
565 if (Node->getNumValues() == 1) {
566 Results.push_back(Res);
567 return true;
568 }
569
570 // If the original node has multiple results, then the return node should
571 // have the same number of results.
572 assert((Node->getNumValues() == Res->getNumValues()) &&
573 "Lowering returned the wrong number of results!");
574
575 // Places new result values base on N result number.
576 for (unsigned I = 0, E = Node->getNumValues(); I != E; ++I)
577 Results.push_back(Res.getValue(I));
578
579 return true;
580}
581
582void VectorLegalizer::PromoteReduction(SDNode *Node,
584 MVT VecVT = Node->getOperand(1).getSimpleValueType();
585 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
586 MVT ScalarVT = Node->getSimpleValueType(0);
587 MVT NewScalarVT = NewVecVT.getVectorElementType();
588
589 SDLoc DL(Node);
590 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
591
592 // promote the initial value.
593 if (Node->getOperand(0).getValueType().isFloatingPoint())
594 Operands[0] =
595 DAG.getNode(ISD::FP_EXTEND, DL, NewScalarVT, Node->getOperand(0));
596 else
597 Operands[0] =
598 DAG.getNode(ISD::ANY_EXTEND, DL, NewScalarVT, Node->getOperand(0));
599
600 for (unsigned j = 1; j != Node->getNumOperands(); ++j)
601 if (Node->getOperand(j).getValueType().isVector() &&
602 !(ISD::isVPOpcode(Node->getOpcode()) &&
603 ISD::getVPMaskIdx(Node->getOpcode()) == j)) // Skip mask operand.
604 // promote the vector operand.
605 if (Node->getOperand(j).getValueType().isFloatingPoint())
606 Operands[j] =
607 DAG.getNode(ISD::FP_EXTEND, DL, NewVecVT, Node->getOperand(j));
608 else
609 Operands[j] =
610 DAG.getNode(ISD::ANY_EXTEND, DL, NewVecVT, Node->getOperand(j));
611 else
612 Operands[j] = Node->getOperand(j); // Skip VL operand.
613
614 SDValue Res = DAG.getNode(Node->getOpcode(), DL, NewScalarVT, Operands,
615 Node->getFlags());
616
617 if (ScalarVT.isFloatingPoint())
618 Res = DAG.getNode(ISD::FP_ROUND, DL, ScalarVT, Res,
619 DAG.getIntPtrConstant(0, DL, /*isTarget=*/true));
620 else
621 Res = DAG.getNode(ISD::TRUNCATE, DL, ScalarVT, Res);
622
623 Results.push_back(Res);
624}
625
626void VectorLegalizer::PromoteSETCC(SDNode *Node,
628 MVT VecVT = Node->getOperand(0).getSimpleValueType();
629 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
630
631 unsigned ExtOp = VecVT.isFloatingPoint() ? ISD::FP_EXTEND : ISD::ANY_EXTEND;
632
633 SDLoc DL(Node);
634 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
635
636 Operands[0] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(0));
637 Operands[1] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(1));
638 Operands[2] = Node->getOperand(2);
639
640 if (Node->getOpcode() == ISD::VP_SETCC) {
641 Operands[3] = Node->getOperand(3); // mask
642 Operands[4] = Node->getOperand(4); // evl
643 }
644
645 SDValue Res = DAG.getNode(Node->getOpcode(), DL, Node->getSimpleValueType(0),
646 Operands, Node->getFlags());
647
648 Results.push_back(Res);
649}
650
651void VectorLegalizer::PromoteSTRICT(SDNode *Node,
653 MVT VecVT = Node->getOperand(1).getSimpleValueType();
654 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
655
656 assert(VecVT.isFloatingPoint());
657
658 SDLoc DL(Node);
659 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
661
662 for (unsigned j = 1; j != Node->getNumOperands(); ++j)
663 if (Node->getOperand(j).getValueType().isVector() &&
664 !(ISD::isVPOpcode(Node->getOpcode()) &&
665 ISD::getVPMaskIdx(Node->getOpcode()) == j)) // Skip mask operand.
666 {
667 // promote the vector operand.
668 SDValue Ext =
669 DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {NewVecVT, MVT::Other},
670 {Node->getOperand(0), Node->getOperand(j)});
671 Operands[j] = Ext.getValue(0);
672 Chains.push_back(Ext.getValue(1));
673 } else
674 Operands[j] = Node->getOperand(j); // Skip no vector operand.
675
676 SDVTList VTs = DAG.getVTList(NewVecVT, Node->getValueType(1));
677
678 Operands[0] = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
679
680 SDValue Res =
681 DAG.getNode(Node->getOpcode(), DL, VTs, Operands, Node->getFlags());
682
683 SDValue Round =
684 DAG.getNode(ISD::STRICT_FP_ROUND, DL, {VecVT, MVT::Other},
685 {Res.getValue(1), Res.getValue(0),
686 DAG.getIntPtrConstant(0, DL, /*isTarget=*/true)});
687
688 Results.push_back(Round.getValue(0));
689 Results.push_back(Round.getValue(1));
690}
691
692void VectorLegalizer::Promote(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
693 // For a few operations there is a specific concept for promotion based on
694 // the operand's type.
695 switch (Node->getOpcode()) {
696 case ISD::SINT_TO_FP:
697 case ISD::UINT_TO_FP:
700 // "Promote" the operation by extending the operand.
701 PromoteINT_TO_FP(Node, Results);
702 return;
703 case ISD::FP_TO_UINT:
704 case ISD::FP_TO_SINT:
707 // Promote the operation by extending the operand.
708 PromoteFP_TO_INT(Node, Results);
709 return;
710 case ISD::VP_REDUCE_ADD:
711 case ISD::VP_REDUCE_MUL:
712 case ISD::VP_REDUCE_AND:
713 case ISD::VP_REDUCE_OR:
714 case ISD::VP_REDUCE_XOR:
715 case ISD::VP_REDUCE_SMAX:
716 case ISD::VP_REDUCE_SMIN:
717 case ISD::VP_REDUCE_UMAX:
718 case ISD::VP_REDUCE_UMIN:
719 case ISD::VP_REDUCE_FADD:
720 case ISD::VP_REDUCE_FMUL:
721 case ISD::VP_REDUCE_FMAX:
722 case ISD::VP_REDUCE_FMIN:
723 case ISD::VP_REDUCE_SEQ_FADD:
724 // Promote the operation by extending the operand.
725 PromoteReduction(Node, Results);
726 return;
727 case ISD::VP_SETCC:
728 case ISD::SETCC:
729 // Promote the operation by extending the operand.
730 PromoteSETCC(Node, Results);
731 return;
732 case ISD::STRICT_FADD:
733 case ISD::STRICT_FSUB:
734 case ISD::STRICT_FMUL:
735 case ISD::STRICT_FDIV:
737 case ISD::STRICT_FMA:
738 PromoteSTRICT(Node, Results);
739 return;
740 case ISD::FP_ROUND:
741 case ISD::FP_EXTEND:
742 // These operations are used to do promotion so they can't be promoted
743 // themselves.
744 llvm_unreachable("Don't know how to promote this operation!");
745 }
746
747 // There are currently two cases of vector promotion:
748 // 1) Bitcasting a vector of integers to a different type to a vector of the
749 // same overall length. For example, x86 promotes ISD::AND v2i32 to v1i64.
750 // 2) Extending a vector of floats to a vector of the same number of larger
751 // floats. For example, AArch64 promotes ISD::FADD on v4f16 to v4f32.
752 assert(Node->getNumValues() == 1 &&
753 "Can't promote a vector with multiple results!");
754 MVT VT = Node->getSimpleValueType(0);
755 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
756 SDLoc dl(Node);
757 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
758
759 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
760 // Do not promote the mask operand of a VP OP.
761 bool SkipPromote = ISD::isVPOpcode(Node->getOpcode()) &&
762 ISD::getVPMaskIdx(Node->getOpcode()) == j;
763 if (Node->getOperand(j).getValueType().isVector() && !SkipPromote)
764 if (Node->getOperand(j)
765 .getValueType()
766 .getVectorElementType()
767 .isFloatingPoint() &&
769 Operands[j] = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(j));
770 else
771 Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(j));
772 else
773 Operands[j] = Node->getOperand(j);
774 }
775
776 SDValue Res =
777 DAG.getNode(Node->getOpcode(), dl, NVT, Operands, Node->getFlags());
778
779 if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
782 Res = DAG.getNode(ISD::FP_ROUND, dl, VT, Res,
783 DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
784 else
785 Res = DAG.getNode(ISD::BITCAST, dl, VT, Res);
786
787 Results.push_back(Res);
788}
789
790void VectorLegalizer::PromoteINT_TO_FP(SDNode *Node,
792 // INT_TO_FP operations may require the input operand be promoted even
793 // when the type is otherwise legal.
794 bool IsStrict = Node->isStrictFPOpcode();
795 MVT VT = Node->getOperand(IsStrict ? 1 : 0).getSimpleValueType();
796 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
798 "Vectors have different number of elements!");
799
800 SDLoc dl(Node);
801 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
802
803 unsigned Opc = (Node->getOpcode() == ISD::UINT_TO_FP ||
804 Node->getOpcode() == ISD::STRICT_UINT_TO_FP)
807 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
808 if (Node->getOperand(j).getValueType().isVector())
809 Operands[j] = DAG.getNode(Opc, dl, NVT, Node->getOperand(j));
810 else
811 Operands[j] = Node->getOperand(j);
812 }
813
814 if (IsStrict) {
815 SDValue Res = DAG.getNode(Node->getOpcode(), dl,
816 {Node->getValueType(0), MVT::Other}, Operands);
817 Results.push_back(Res);
818 Results.push_back(Res.getValue(1));
819 return;
820 }
821
822 SDValue Res =
823 DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Operands);
824 Results.push_back(Res);
825}
826
827// For FP_TO_INT we promote the result type to a vector type with wider
828// elements and then truncate the result. This is different from the default
829// PromoteVector which uses bitcast to promote thus assumning that the
830// promoted vector type has the same overall size.
831void VectorLegalizer::PromoteFP_TO_INT(SDNode *Node,
833 MVT VT = Node->getSimpleValueType(0);
834 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
835 bool IsStrict = Node->isStrictFPOpcode();
837 "Vectors have different number of elements!");
838
839 unsigned NewOpc = Node->getOpcode();
840 // Change FP_TO_UINT to FP_TO_SINT if possible.
841 // TODO: Should we only do this if FP_TO_UINT itself isn't legal?
842 if (NewOpc == ISD::FP_TO_UINT &&
843 TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
844 NewOpc = ISD::FP_TO_SINT;
845
846 if (NewOpc == ISD::STRICT_FP_TO_UINT &&
847 TLI.isOperationLegalOrCustom(ISD::STRICT_FP_TO_SINT, NVT))
848 NewOpc = ISD::STRICT_FP_TO_SINT;
849
850 SDLoc dl(Node);
851 SDValue Promoted, Chain;
852 if (IsStrict) {
853 Promoted = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
854 {Node->getOperand(0), Node->getOperand(1)});
855 Chain = Promoted.getValue(1);
856 } else
857 Promoted = DAG.getNode(NewOpc, dl, NVT, Node->getOperand(0));
858
859 // Assert that the converted value fits in the original type. If it doesn't
860 // (eg: because the value being converted is too big), then the result of the
861 // original operation was undefined anyway, so the assert is still correct.
862 if (Node->getOpcode() == ISD::FP_TO_UINT ||
863 Node->getOpcode() == ISD::STRICT_FP_TO_UINT)
864 NewOpc = ISD::AssertZext;
865 else
866 NewOpc = ISD::AssertSext;
867
868 Promoted = DAG.getNode(NewOpc, dl, NVT, Promoted,
869 DAG.getValueType(VT.getScalarType()));
870 Promoted = DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted);
871 Results.push_back(Promoted);
872 if (IsStrict)
873 Results.push_back(Chain);
874}
875
876std::pair<SDValue, SDValue> VectorLegalizer::ExpandLoad(SDNode *N) {
877 LoadSDNode *LD = cast<LoadSDNode>(N);
878 return TLI.scalarizeVectorLoad(LD, DAG);
879}
880
881SDValue VectorLegalizer::ExpandStore(SDNode *N) {
882 StoreSDNode *ST = cast<StoreSDNode>(N);
883 SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
884 return TF;
885}
886
887void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
888 switch (Node->getOpcode()) {
889 case ISD::LOAD: {
890 std::pair<SDValue, SDValue> Tmp = ExpandLoad(Node);
891 Results.push_back(Tmp.first);
892 Results.push_back(Tmp.second);
893 return;
894 }
895 case ISD::STORE:
896 Results.push_back(ExpandStore(Node));
897 return;
899 for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
900 Results.push_back(Node->getOperand(i));
901 return;
903 Results.push_back(ExpandSEXTINREG(Node));
904 return;
906 Results.push_back(ExpandANY_EXTEND_VECTOR_INREG(Node));
907 return;
909 Results.push_back(ExpandSIGN_EXTEND_VECTOR_INREG(Node));
910 return;
912 Results.push_back(ExpandZERO_EXTEND_VECTOR_INREG(Node));
913 return;
914 case ISD::BSWAP:
915 Results.push_back(ExpandBSWAP(Node));
916 return;
917 case ISD::VP_BSWAP:
918 Results.push_back(TLI.expandVPBSWAP(Node, DAG));
919 return;
920 case ISD::VSELECT:
921 Results.push_back(ExpandVSELECT(Node));
922 return;
923 case ISD::VP_SELECT:
924 Results.push_back(ExpandVP_SELECT(Node));
925 return;
926 case ISD::VP_SREM:
927 case ISD::VP_UREM:
928 if (SDValue Expanded = ExpandVP_REM(Node)) {
929 Results.push_back(Expanded);
930 return;
931 }
932 break;
933 case ISD::SELECT:
934 Results.push_back(ExpandSELECT(Node));
935 return;
936 case ISD::SELECT_CC: {
937 if (Node->getValueType(0).isScalableVector()) {
938 EVT CondVT = TLI.getSetCCResultType(
939 DAG.getDataLayout(), *DAG.getContext(), Node->getValueType(0));
940 SDValue SetCC =
941 DAG.getNode(ISD::SETCC, SDLoc(Node), CondVT, Node->getOperand(0),
942 Node->getOperand(1), Node->getOperand(4));
943 Results.push_back(DAG.getSelect(SDLoc(Node), Node->getValueType(0), SetCC,
944 Node->getOperand(2),
945 Node->getOperand(3)));
946 return;
947 }
948 break;
949 }
950 case ISD::FP_TO_UINT:
951 ExpandFP_TO_UINT(Node, Results);
952 return;
953 case ISD::UINT_TO_FP:
954 ExpandUINT_TO_FLOAT(Node, Results);
955 return;
956 case ISD::FNEG:
957 Results.push_back(ExpandFNEG(Node));
958 return;
959 case ISD::FSUB:
960 ExpandFSUB(Node, Results);
961 return;
962 case ISD::SETCC:
963 case ISD::VP_SETCC:
964 ExpandSETCC(Node, Results);
965 return;
966 case ISD::ABS:
967 if (SDValue Expanded = TLI.expandABS(Node, DAG)) {
968 Results.push_back(Expanded);
969 return;
970 }
971 break;
972 case ISD::ABDS:
973 case ISD::ABDU:
974 if (SDValue Expanded = TLI.expandABD(Node, DAG)) {
975 Results.push_back(Expanded);
976 return;
977 }
978 break;
979 case ISD::BITREVERSE:
980 ExpandBITREVERSE(Node, Results);
981 return;
982 case ISD::VP_BITREVERSE:
983 if (SDValue Expanded = TLI.expandVPBITREVERSE(Node, DAG)) {
984 Results.push_back(Expanded);
985 return;
986 }
987 break;
988 case ISD::CTPOP:
989 if (SDValue Expanded = TLI.expandCTPOP(Node, DAG)) {
990 Results.push_back(Expanded);
991 return;
992 }
993 break;
994 case ISD::VP_CTPOP:
995 if (SDValue Expanded = TLI.expandVPCTPOP(Node, DAG)) {
996 Results.push_back(Expanded);
997 return;
998 }
999 break;
1000 case ISD::CTLZ:
1002 if (SDValue Expanded = TLI.expandCTLZ(Node, DAG)) {
1003 Results.push_back(Expanded);
1004 return;
1005 }
1006 break;
1007 case ISD::VP_CTLZ:
1008 case ISD::VP_CTLZ_ZERO_UNDEF:
1009 if (SDValue Expanded = TLI.expandVPCTLZ(Node, DAG)) {
1010 Results.push_back(Expanded);
1011 return;
1012 }
1013 break;
1014 case ISD::CTTZ:
1016 if (SDValue Expanded = TLI.expandCTTZ(Node, DAG)) {
1017 Results.push_back(Expanded);
1018 return;
1019 }
1020 break;
1021 case ISD::VP_CTTZ:
1022 case ISD::VP_CTTZ_ZERO_UNDEF:
1023 if (SDValue Expanded = TLI.expandVPCTTZ(Node, DAG)) {
1024 Results.push_back(Expanded);
1025 return;
1026 }
1027 break;
1028 case ISD::FSHL:
1029 case ISD::VP_FSHL:
1030 case ISD::FSHR:
1031 case ISD::VP_FSHR:
1032 if (SDValue Expanded = TLI.expandFunnelShift(Node, DAG)) {
1033 Results.push_back(Expanded);
1034 return;
1035 }
1036 break;
1037 case ISD::ROTL:
1038 case ISD::ROTR:
1039 if (SDValue Expanded = TLI.expandROT(Node, false /*AllowVectorOps*/, DAG)) {
1040 Results.push_back(Expanded);
1041 return;
1042 }
1043 break;
1044 case ISD::FMINNUM:
1045 case ISD::FMAXNUM:
1046 if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG)) {
1047 Results.push_back(Expanded);
1048 return;
1049 }
1050 break;
1051 case ISD::SMIN:
1052 case ISD::SMAX:
1053 case ISD::UMIN:
1054 case ISD::UMAX:
1055 if (SDValue Expanded = TLI.expandIntMINMAX(Node, DAG)) {
1056 Results.push_back(Expanded);
1057 return;
1058 }
1059 break;
1060 case ISD::UADDO:
1061 case ISD::USUBO:
1062 ExpandUADDSUBO(Node, Results);
1063 return;
1064 case ISD::SADDO:
1065 case ISD::SSUBO:
1066 ExpandSADDSUBO(Node, Results);
1067 return;
1068 case ISD::UMULO:
1069 case ISD::SMULO:
1070 ExpandMULO(Node, Results);
1071 return;
1072 case ISD::USUBSAT:
1073 case ISD::SSUBSAT:
1074 case ISD::UADDSAT:
1075 case ISD::SADDSAT:
1076 if (SDValue Expanded = TLI.expandAddSubSat(Node, DAG)) {
1077 Results.push_back(Expanded);
1078 return;
1079 }
1080 break;
1081 case ISD::USHLSAT:
1082 case ISD::SSHLSAT:
1083 if (SDValue Expanded = TLI.expandShlSat(Node, DAG)) {
1084 Results.push_back(Expanded);
1085 return;
1086 }
1087 break;
1090 // Expand the fpsosisat if it is scalable to prevent it from unrolling below.
1091 if (Node->getValueType(0).isScalableVector()) {
1092 if (SDValue Expanded = TLI.expandFP_TO_INT_SAT(Node, DAG)) {
1093 Results.push_back(Expanded);
1094 return;
1095 }
1096 }
1097 break;
1098 case ISD::SMULFIX:
1099 case ISD::UMULFIX:
1100 if (SDValue Expanded = TLI.expandFixedPointMul(Node, DAG)) {
1101 Results.push_back(Expanded);
1102 return;
1103 }
1104 break;
1105 case ISD::SMULFIXSAT:
1106 case ISD::UMULFIXSAT:
1107 // FIXME: We do not expand SMULFIXSAT/UMULFIXSAT here yet, not sure exactly
1108 // why. Maybe it results in worse codegen compared to the unroll for some
1109 // targets? This should probably be investigated. And if we still prefer to
1110 // unroll an explanation could be helpful.
1111 break;
1112 case ISD::SDIVFIX:
1113 case ISD::UDIVFIX:
1114 ExpandFixedPointDiv(Node, Results);
1115 return;
1116 case ISD::SDIVFIXSAT:
1117 case ISD::UDIVFIXSAT:
1118 break;
1119#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1120 case ISD::STRICT_##DAGN:
1121#include "llvm/IR/ConstrainedOps.def"
1122 ExpandStrictFPOp(Node, Results);
1123 return;
1124 case ISD::VECREDUCE_ADD:
1125 case ISD::VECREDUCE_MUL:
1126 case ISD::VECREDUCE_AND:
1127 case ISD::VECREDUCE_OR:
1128 case ISD::VECREDUCE_XOR:
1139 Results.push_back(TLI.expandVecReduce(Node, DAG));
1140 return;
1143 Results.push_back(TLI.expandVecReduceSeq(Node, DAG));
1144 return;
1145 case ISD::SREM:
1146 case ISD::UREM:
1147 ExpandREM(Node, Results);
1148 return;
1149 case ISD::VP_MERGE:
1150 Results.push_back(ExpandVP_MERGE(Node));
1151 return;
1152 case ISD::FREM:
1153 if (tryExpandVecMathCall(Node, RTLIB::REM_F32, RTLIB::REM_F64,
1154 RTLIB::REM_F80, RTLIB::REM_F128,
1155 RTLIB::REM_PPCF128, Results))
1156 return;
1157
1158 break;
1159 }
1160
1161 SDValue Unrolled = DAG.UnrollVectorOp(Node);
1162 if (Node->getNumValues() == 1) {
1163 Results.push_back(Unrolled);
1164 } else {
1165 assert(Node->getNumValues() == Unrolled->getNumValues() &&
1166 "VectorLegalizer Expand returned wrong number of results!");
1167 for (unsigned I = 0, E = Unrolled->getNumValues(); I != E; ++I)
1168 Results.push_back(Unrolled.getValue(I));
1169 }
1170}
1171
1172SDValue VectorLegalizer::ExpandSELECT(SDNode *Node) {
1173 // Lower a select instruction where the condition is a scalar and the
1174 // operands are vectors. Lower this select to VSELECT and implement it
1175 // using XOR AND OR. The selector bit is broadcasted.
1176 EVT VT = Node->getValueType(0);
1177 SDLoc DL(Node);
1178
1179 SDValue Mask = Node->getOperand(0);
1180 SDValue Op1 = Node->getOperand(1);
1181 SDValue Op2 = Node->getOperand(2);
1182
1183 assert(VT.isVector() && !Mask.getValueType().isVector()
1184 && Op1.getValueType() == Op2.getValueType() && "Invalid type");
1185
1186 // If we can't even use the basic vector operations of
1187 // AND,OR,XOR, we will have to scalarize the op.
1188 // Notice that the operation may be 'promoted' which means that it is
1189 // 'bitcasted' to another type which is handled.
1190 // Also, we need to be able to construct a splat vector using either
1191 // BUILD_VECTOR or SPLAT_VECTOR.
1192 // FIXME: Should we also permit fixed-length SPLAT_VECTOR as a fallback to
1193 // BUILD_VECTOR?
1194 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1195 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1196 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
1197 TLI.getOperationAction(VT.isFixedLengthVector() ? ISD::BUILD_VECTOR
1199 VT) == TargetLowering::Expand)
1200 return DAG.UnrollVectorOp(Node);
1201
1202 // Generate a mask operand.
1204
1205 // What is the size of each element in the vector mask.
1206 EVT BitTy = MaskTy.getScalarType();
1207
1208 Mask = DAG.getSelect(DL, BitTy, Mask, DAG.getAllOnesConstant(DL, BitTy),
1209 DAG.getConstant(0, DL, BitTy));
1210
1211 // Broadcast the mask so that the entire vector is all one or all zero.
1212 Mask = DAG.getSplat(MaskTy, DL, Mask);
1213
1214 // Bitcast the operands to be the same type as the mask.
1215 // This is needed when we select between FP types because
1216 // the mask is a vector of integers.
1217 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1);
1218 Op2 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op2);
1219
1220 SDValue NotMask = DAG.getNOT(DL, Mask, MaskTy);
1221
1222 Op1 = DAG.getNode(ISD::AND, DL, MaskTy, Op1, Mask);
1223 Op2 = DAG.getNode(ISD::AND, DL, MaskTy, Op2, NotMask);
1224 SDValue Val = DAG.getNode(ISD::OR, DL, MaskTy, Op1, Op2);
1225 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1226}
1227
1228SDValue VectorLegalizer::ExpandSEXTINREG(SDNode *Node) {
1229 EVT VT = Node->getValueType(0);
1230
1231 // Make sure that the SRA and SHL instructions are available.
1232 if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Expand ||
1233 TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Expand)
1234 return DAG.UnrollVectorOp(Node);
1235
1236 SDLoc DL(Node);
1237 EVT OrigTy = cast<VTSDNode>(Node->getOperand(1))->getVT();
1238
1239 unsigned BW = VT.getScalarSizeInBits();
1240 unsigned OrigBW = OrigTy.getScalarSizeInBits();
1241 SDValue ShiftSz = DAG.getConstant(BW - OrigBW, DL, VT);
1242
1243 SDValue Op = DAG.getNode(ISD::SHL, DL, VT, Node->getOperand(0), ShiftSz);
1244 return DAG.getNode(ISD::SRA, DL, VT, Op, ShiftSz);
1245}
1246
1247// Generically expand a vector anyext in register to a shuffle of the relevant
1248// lanes into the appropriate locations, with other lanes left undef.
1249SDValue VectorLegalizer::ExpandANY_EXTEND_VECTOR_INREG(SDNode *Node) {
1250 SDLoc DL(Node);
1251 EVT VT = Node->getValueType(0);
1252 int NumElements = VT.getVectorNumElements();
1253 SDValue Src = Node->getOperand(0);
1254 EVT SrcVT = Src.getValueType();
1255 int NumSrcElements = SrcVT.getVectorNumElements();
1256
1257 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1258 // into a larger vector type.
1259 if (SrcVT.bitsLE(VT)) {
1260 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1261 "ANY_EXTEND_VECTOR_INREG vector size mismatch");
1262 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1263 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1264 NumSrcElements);
1265 Src = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, SrcVT, DAG.getUNDEF(SrcVT),
1266 Src, DAG.getVectorIdxConstant(0, DL));
1267 }
1268
1269 // Build a base mask of undef shuffles.
1270 SmallVector<int, 16> ShuffleMask;
1271 ShuffleMask.resize(NumSrcElements, -1);
1272
1273 // Place the extended lanes into the correct locations.
1274 int ExtLaneScale = NumSrcElements / NumElements;
1275 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1276 for (int i = 0; i < NumElements; ++i)
1277 ShuffleMask[i * ExtLaneScale + EndianOffset] = i;
1278
1279 return DAG.getNode(
1280 ISD::BITCAST, DL, VT,
1281 DAG.getVectorShuffle(SrcVT, DL, Src, DAG.getUNDEF(SrcVT), ShuffleMask));
1282}
1283
1284SDValue VectorLegalizer::ExpandSIGN_EXTEND_VECTOR_INREG(SDNode *Node) {
1285 SDLoc DL(Node);
1286 EVT VT = Node->getValueType(0);
1287 SDValue Src = Node->getOperand(0);
1288 EVT SrcVT = Src.getValueType();
1289
1290 // First build an any-extend node which can be legalized above when we
1291 // recurse through it.
1292 SDValue Op = DAG.getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, VT, Src);
1293
1294 // Now we need sign extend. Do this by shifting the elements. Even if these
1295 // aren't legal operations, they have a better chance of being legalized
1296 // without full scalarization than the sign extension does.
1297 unsigned EltWidth = VT.getScalarSizeInBits();
1298 unsigned SrcEltWidth = SrcVT.getScalarSizeInBits();
1299 SDValue ShiftAmount = DAG.getConstant(EltWidth - SrcEltWidth, DL, VT);
1300 return DAG.getNode(ISD::SRA, DL, VT,
1301 DAG.getNode(ISD::SHL, DL, VT, Op, ShiftAmount),
1302 ShiftAmount);
1303}
1304
1305// Generically expand a vector zext in register to a shuffle of the relevant
1306// lanes into the appropriate locations, a blend of zero into the high bits,
1307// and a bitcast to the wider element type.
1308SDValue VectorLegalizer::ExpandZERO_EXTEND_VECTOR_INREG(SDNode *Node) {
1309 SDLoc DL(Node);
1310 EVT VT = Node->getValueType(0);
1311 int NumElements = VT.getVectorNumElements();
1312 SDValue Src = Node->getOperand(0);
1313 EVT SrcVT = Src.getValueType();
1314 int NumSrcElements = SrcVT.getVectorNumElements();
1315
1316 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1317 // into a larger vector type.
1318 if (SrcVT.bitsLE(VT)) {
1319 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1320 "ZERO_EXTEND_VECTOR_INREG vector size mismatch");
1321 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1322 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1323 NumSrcElements);
1324 Src = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, SrcVT, DAG.getUNDEF(SrcVT),
1325 Src, DAG.getVectorIdxConstant(0, DL));
1326 }
1327
1328 // Build up a zero vector to blend into this one.
1329 SDValue Zero = DAG.getConstant(0, DL, SrcVT);
1330
1331 // Shuffle the incoming lanes into the correct position, and pull all other
1332 // lanes from the zero vector.
1333 auto ShuffleMask = llvm::to_vector<16>(llvm::seq<int>(0, NumSrcElements));
1334
1335 int ExtLaneScale = NumSrcElements / NumElements;
1336 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1337 for (int i = 0; i < NumElements; ++i)
1338 ShuffleMask[i * ExtLaneScale + EndianOffset] = NumSrcElements + i;
1339
1340 return DAG.getNode(ISD::BITCAST, DL, VT,
1341 DAG.getVectorShuffle(SrcVT, DL, Zero, Src, ShuffleMask));
1342}
1343
1344static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) {
1345 int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;
1346 for (int I = 0, E = VT.getVectorNumElements(); I != E; ++I)
1347 for (int J = ScalarSizeInBytes - 1; J >= 0; --J)
1348 ShuffleMask.push_back((I * ScalarSizeInBytes) + J);
1349}
1350
1351SDValue VectorLegalizer::ExpandBSWAP(SDNode *Node) {
1352 EVT VT = Node->getValueType(0);
1353
1354 // Scalable vectors can't use shuffle expansion.
1355 if (VT.isScalableVector())
1356 return TLI.expandBSWAP(Node, DAG);
1357
1358 // Generate a byte wise shuffle mask for the BSWAP.
1359 SmallVector<int, 16> ShuffleMask;
1360 createBSWAPShuffleMask(VT, ShuffleMask);
1361 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, ShuffleMask.size());
1362
1363 // Only emit a shuffle if the mask is legal.
1364 if (TLI.isShuffleMaskLegal(ShuffleMask, ByteVT)) {
1365 SDLoc DL(Node);
1366 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1367 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getUNDEF(ByteVT), ShuffleMask);
1368 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
1369 }
1370
1371 // If we have the appropriate vector bit operations, it is better to use them
1372 // than unrolling and expanding each component.
1373 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1374 TLI.isOperationLegalOrCustom(ISD::SRL, VT) &&
1375 TLI.isOperationLegalOrCustomOrPromote(ISD::AND, VT) &&
1376 TLI.isOperationLegalOrCustomOrPromote(ISD::OR, VT))
1377 return TLI.expandBSWAP(Node, DAG);
1378
1379 // Otherwise unroll.
1380 return DAG.UnrollVectorOp(Node);
1381}
1382
1383void VectorLegalizer::ExpandBITREVERSE(SDNode *Node,
1385 EVT VT = Node->getValueType(0);
1386
1387 // We can't unroll or use shuffles for scalable vectors.
1388 if (VT.isScalableVector()) {
1389 Results.push_back(TLI.expandBITREVERSE(Node, DAG));
1390 return;
1391 }
1392
1393 // If we have the scalar operation, it's probably cheaper to unroll it.
1394 if (TLI.isOperationLegalOrCustom(ISD::BITREVERSE, VT.getScalarType())) {
1395 SDValue Tmp = DAG.UnrollVectorOp(Node);
1396 Results.push_back(Tmp);
1397 return;
1398 }
1399
1400 // If the vector element width is a whole number of bytes, test if its legal
1401 // to BSWAP shuffle the bytes and then perform the BITREVERSE on the byte
1402 // vector. This greatly reduces the number of bit shifts necessary.
1403 unsigned ScalarSizeInBits = VT.getScalarSizeInBits();
1404 if (ScalarSizeInBits > 8 && (ScalarSizeInBits % 8) == 0) {
1405 SmallVector<int, 16> BSWAPMask;
1406 createBSWAPShuffleMask(VT, BSWAPMask);
1407
1408 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, BSWAPMask.size());
1409 if (TLI.isShuffleMaskLegal(BSWAPMask, ByteVT) &&
1410 (TLI.isOperationLegalOrCustom(ISD::BITREVERSE, ByteVT) ||
1411 (TLI.isOperationLegalOrCustom(ISD::SHL, ByteVT) &&
1412 TLI.isOperationLegalOrCustom(ISD::SRL, ByteVT) &&
1413 TLI.isOperationLegalOrCustomOrPromote(ISD::AND, ByteVT) &&
1414 TLI.isOperationLegalOrCustomOrPromote(ISD::OR, ByteVT)))) {
1415 SDLoc DL(Node);
1416 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1417 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getUNDEF(ByteVT),
1418 BSWAPMask);
1419 Op = DAG.getNode(ISD::BITREVERSE, DL, ByteVT, Op);
1420 Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
1421 Results.push_back(Op);
1422 return;
1423 }
1424 }
1425
1426 // If we have the appropriate vector bit operations, it is better to use them
1427 // than unrolling and expanding each component.
1428 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1429 TLI.isOperationLegalOrCustom(ISD::SRL, VT) &&
1430 TLI.isOperationLegalOrCustomOrPromote(ISD::AND, VT) &&
1431 TLI.isOperationLegalOrCustomOrPromote(ISD::OR, VT)) {
1432 Results.push_back(TLI.expandBITREVERSE(Node, DAG));
1433 return;
1434 }
1435
1436 // Otherwise unroll.
1437 SDValue Tmp = DAG.UnrollVectorOp(Node);
1438 Results.push_back(Tmp);
1439}
1440
1441SDValue VectorLegalizer::ExpandVSELECT(SDNode *Node) {
1442 // Implement VSELECT in terms of XOR, AND, OR
1443 // on platforms which do not support blend natively.
1444 SDLoc DL(Node);
1445
1446 SDValue Mask = Node->getOperand(0);
1447 SDValue Op1 = Node->getOperand(1);
1448 SDValue Op2 = Node->getOperand(2);
1449
1450 EVT VT = Mask.getValueType();
1451
1452 // If we can't even use the basic vector operations of
1453 // AND,OR,XOR, we will have to scalarize the op.
1454 // Notice that the operation may be 'promoted' which means that it is
1455 // 'bitcasted' to another type which is handled.
1456 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1457 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1458 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand)
1459 return DAG.UnrollVectorOp(Node);
1460
1461 // This operation also isn't safe with AND, OR, XOR when the boolean type is
1462 // 0/1 and the select operands aren't also booleans, as we need an all-ones
1463 // vector constant to mask with.
1464 // FIXME: Sign extend 1 to all ones if that's legal on the target.
1465 auto BoolContents = TLI.getBooleanContents(Op1.getValueType());
1466 if (BoolContents != TargetLowering::ZeroOrNegativeOneBooleanContent &&
1467 !(BoolContents == TargetLowering::ZeroOrOneBooleanContent &&
1468 Op1.getValueType().getVectorElementType() == MVT::i1))
1469 return DAG.UnrollVectorOp(Node);
1470
1471 // If the mask and the type are different sizes, unroll the vector op. This
1472 // can occur when getSetCCResultType returns something that is different in
1473 // size from the operand types. For example, v4i8 = select v4i32, v4i8, v4i8.
1474 if (VT.getSizeInBits() != Op1.getValueSizeInBits())
1475 return DAG.UnrollVectorOp(Node);
1476
1477 // Bitcast the operands to be the same type as the mask.
1478 // This is needed when we select between FP types because
1479 // the mask is a vector of integers.
1480 Op1 = DAG.getNode(ISD::BITCAST, DL, VT, Op1);
1481 Op2 = DAG.getNode(ISD::BITCAST, DL, VT, Op2);
1482
1483 SDValue NotMask = DAG.getNOT(DL, Mask, VT);
1484
1485 Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask);
1486 Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask);
1487 SDValue Val = DAG.getNode(ISD::OR, DL, VT, Op1, Op2);
1488 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1489}
1490
1491SDValue VectorLegalizer::ExpandVP_SELECT(SDNode *Node) {
1492 // Implement VP_SELECT in terms of VP_XOR, VP_AND and VP_OR on platforms which
1493 // do not support it natively.
1494 SDLoc DL(Node);
1495
1496 SDValue Mask = Node->getOperand(0);
1497 SDValue Op1 = Node->getOperand(1);
1498 SDValue Op2 = Node->getOperand(2);
1499 SDValue EVL = Node->getOperand(3);
1500
1501 EVT VT = Mask.getValueType();
1502
1503 // If we can't even use the basic vector operations of
1504 // VP_AND,VP_OR,VP_XOR, we will have to scalarize the op.
1505 if (TLI.getOperationAction(ISD::VP_AND, VT) == TargetLowering::Expand ||
1506 TLI.getOperationAction(ISD::VP_XOR, VT) == TargetLowering::Expand ||
1507 TLI.getOperationAction(ISD::VP_OR, VT) == TargetLowering::Expand)
1508 return DAG.UnrollVectorOp(Node);
1509
1510 // This operation also isn't safe when the operands aren't also booleans.
1511 if (Op1.getValueType().getVectorElementType() != MVT::i1)
1512 return DAG.UnrollVectorOp(Node);
1513
1514 SDValue Ones = DAG.getAllOnesConstant(DL, VT);
1515 SDValue NotMask = DAG.getNode(ISD::VP_XOR, DL, VT, Mask, Ones, Ones, EVL);
1516
1517 Op1 = DAG.getNode(ISD::VP_AND, DL, VT, Op1, Mask, Ones, EVL);
1518 Op2 = DAG.getNode(ISD::VP_AND, DL, VT, Op2, NotMask, Ones, EVL);
1519 return DAG.getNode(ISD::VP_OR, DL, VT, Op1, Op2, Ones, EVL);
1520}
1521
1522SDValue VectorLegalizer::ExpandVP_MERGE(SDNode *Node) {
1523 // Implement VP_MERGE in terms of VSELECT. Construct a mask where vector
1524 // indices less than the EVL/pivot are true. Combine that with the original
1525 // mask for a full-length mask. Use a full-length VSELECT to select between
1526 // the true and false values.
1527 SDLoc DL(Node);
1528
1529 SDValue Mask = Node->getOperand(0);
1530 SDValue Op1 = Node->getOperand(1);
1531 SDValue Op2 = Node->getOperand(2);
1532 SDValue EVL = Node->getOperand(3);
1533
1534 EVT MaskVT = Mask.getValueType();
1535 bool IsFixedLen = MaskVT.isFixedLengthVector();
1536
1537 EVT EVLVecVT = EVT::getVectorVT(*DAG.getContext(), EVL.getValueType(),
1538 MaskVT.getVectorElementCount());
1539
1540 // If we can't construct the EVL mask efficiently, it's better to unroll.
1541 if ((IsFixedLen &&
1542 !TLI.isOperationLegalOrCustom(ISD::BUILD_VECTOR, EVLVecVT)) ||
1543 (!IsFixedLen &&
1544 (!TLI.isOperationLegalOrCustom(ISD::STEP_VECTOR, EVLVecVT) ||
1545 !TLI.isOperationLegalOrCustom(ISD::SPLAT_VECTOR, EVLVecVT))))
1546 return DAG.UnrollVectorOp(Node);
1547
1548 // If using a SETCC would result in a different type than the mask type,
1549 // unroll.
1550 if (TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
1551 EVLVecVT) != MaskVT)
1552 return DAG.UnrollVectorOp(Node);
1553
1554 SDValue StepVec = DAG.getStepVector(DL, EVLVecVT);
1555 SDValue SplatEVL = DAG.getSplat(EVLVecVT, DL, EVL);
1556 SDValue EVLMask =
1557 DAG.getSetCC(DL, MaskVT, StepVec, SplatEVL, ISD::CondCode::SETULT);
1558
1559 SDValue FullMask = DAG.getNode(ISD::AND, DL, MaskVT, Mask, EVLMask);
1560 return DAG.getSelect(DL, Node->getValueType(0), FullMask, Op1, Op2);
1561}
1562
1563SDValue VectorLegalizer::ExpandVP_REM(SDNode *Node) {
1564 // Implement VP_SREM/UREM in terms of VP_SDIV/VP_UDIV, VP_MUL, VP_SUB.
1565 EVT VT = Node->getValueType(0);
1566
1567 unsigned DivOpc = Node->getOpcode() == ISD::VP_SREM ? ISD::VP_SDIV : ISD::VP_UDIV;
1568
1569 if (!TLI.isOperationLegalOrCustom(DivOpc, VT) ||
1570 !TLI.isOperationLegalOrCustom(ISD::VP_MUL, VT) ||
1571 !TLI.isOperationLegalOrCustom(ISD::VP_SUB, VT))
1572 return SDValue();
1573
1574 SDLoc DL(Node);
1575
1576 SDValue Dividend = Node->getOperand(0);
1577 SDValue Divisor = Node->getOperand(1);
1578 SDValue Mask = Node->getOperand(2);
1579 SDValue EVL = Node->getOperand(3);
1580
1581 // X % Y -> X-X/Y*Y
1582 SDValue Div = DAG.getNode(DivOpc, DL, VT, Dividend, Divisor, Mask, EVL);
1583 SDValue Mul = DAG.getNode(ISD::VP_MUL, DL, VT, Divisor, Div, Mask, EVL);
1584 return DAG.getNode(ISD::VP_SUB, DL, VT, Dividend, Mul, Mask, EVL);
1585}
1586
1587void VectorLegalizer::ExpandFP_TO_UINT(SDNode *Node,
1589 // Attempt to expand using TargetLowering.
1590 SDValue Result, Chain;
1591 if (TLI.expandFP_TO_UINT(Node, Result, Chain, DAG)) {
1592 Results.push_back(Result);
1593 if (Node->isStrictFPOpcode())
1594 Results.push_back(Chain);
1595 return;
1596 }
1597
1598 // Otherwise go ahead and unroll.
1599 if (Node->isStrictFPOpcode()) {
1600 UnrollStrictFPOp(Node, Results);
1601 return;
1602 }
1603
1604 Results.push_back(DAG.UnrollVectorOp(Node));
1605}
1606
1607void VectorLegalizer::ExpandUINT_TO_FLOAT(SDNode *Node,
1609 bool IsStrict = Node->isStrictFPOpcode();
1610 unsigned OpNo = IsStrict ? 1 : 0;
1611 SDValue Src = Node->getOperand(OpNo);
1612 EVT VT = Src.getValueType();
1613 SDLoc DL(Node);
1614
1615 // Attempt to expand using TargetLowering.
1617 SDValue Chain;
1618 if (TLI.expandUINT_TO_FP(Node, Result, Chain, DAG)) {
1619 Results.push_back(Result);
1620 if (IsStrict)
1621 Results.push_back(Chain);
1622 return;
1623 }
1624
1625 // Make sure that the SINT_TO_FP and SRL instructions are available.
1626 if (((!IsStrict && TLI.getOperationAction(ISD::SINT_TO_FP, VT) ==
1627 TargetLowering::Expand) ||
1628 (IsStrict && TLI.getOperationAction(ISD::STRICT_SINT_TO_FP, VT) ==
1629 TargetLowering::Expand)) ||
1630 TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Expand) {
1631 if (IsStrict) {
1632 UnrollStrictFPOp(Node, Results);
1633 return;
1634 }
1635
1636 Results.push_back(DAG.UnrollVectorOp(Node));
1637 return;
1638 }
1639
1640 unsigned BW = VT.getScalarSizeInBits();
1641 assert((BW == 64 || BW == 32) &&
1642 "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide");
1643
1644 SDValue HalfWord = DAG.getConstant(BW / 2, DL, VT);
1645
1646 // Constants to clear the upper part of the word.
1647 // Notice that we can also use SHL+SHR, but using a constant is slightly
1648 // faster on x86.
1649 uint64_t HWMask = (BW == 64) ? 0x00000000FFFFFFFF : 0x0000FFFF;
1650 SDValue HalfWordMask = DAG.getConstant(HWMask, DL, VT);
1651
1652 // Two to the power of half-word-size.
1653 SDValue TWOHW =
1654 DAG.getConstantFP(1ULL << (BW / 2), DL, Node->getValueType(0));
1655
1656 // Clear upper part of LO, lower HI
1657 SDValue HI = DAG.getNode(ISD::SRL, DL, VT, Src, HalfWord);
1658 SDValue LO = DAG.getNode(ISD::AND, DL, VT, Src, HalfWordMask);
1659
1660 if (IsStrict) {
1661 // Convert hi and lo to floats
1662 // Convert the hi part back to the upper values
1663 // TODO: Can any fast-math-flags be set on these nodes?
1665 {Node->getValueType(0), MVT::Other},
1666 {Node->getOperand(0), HI});
1667 fHI = DAG.getNode(ISD::STRICT_FMUL, DL, {Node->getValueType(0), MVT::Other},
1668 {fHI.getValue(1), fHI, TWOHW});
1670 {Node->getValueType(0), MVT::Other},
1671 {Node->getOperand(0), LO});
1672
1673 SDValue TF = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, fHI.getValue(1),
1674 fLO.getValue(1));
1675
1676 // Add the two halves
1677 SDValue Result =
1678 DAG.getNode(ISD::STRICT_FADD, DL, {Node->getValueType(0), MVT::Other},
1679 {TF, fHI, fLO});
1680
1681 Results.push_back(Result);
1682 Results.push_back(Result.getValue(1));
1683 return;
1684 }
1685
1686 // Convert hi and lo to floats
1687 // Convert the hi part back to the upper values
1688 // TODO: Can any fast-math-flags be set on these nodes?
1689 SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, Node->getValueType(0), HI);
1690 fHI = DAG.getNode(ISD::FMUL, DL, Node->getValueType(0), fHI, TWOHW);
1691 SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, Node->getValueType(0), LO);
1692
1693 // Add the two halves
1694 Results.push_back(
1695 DAG.getNode(ISD::FADD, DL, Node->getValueType(0), fHI, fLO));
1696}
1697
1698SDValue VectorLegalizer::ExpandFNEG(SDNode *Node) {
1699 if (TLI.isOperationLegalOrCustom(ISD::FSUB, Node->getValueType(0))) {
1700 SDLoc DL(Node);
1701 SDValue Zero = DAG.getConstantFP(-0.0, DL, Node->getValueType(0));
1702 // TODO: If FNEG had fast-math-flags, they'd get propagated to this FSUB.
1703 return DAG.getNode(ISD::FSUB, DL, Node->getValueType(0), Zero,
1704 Node->getOperand(0));
1705 }
1706 return DAG.UnrollVectorOp(Node);
1707}
1708
1709void VectorLegalizer::ExpandFSUB(SDNode *Node,
1711 // For floating-point values, (a-b) is the same as a+(-b). If FNEG is legal,
1712 // we can defer this to operation legalization where it will be lowered as
1713 // a+(-b).
1714 EVT VT = Node->getValueType(0);
1715 if (TLI.isOperationLegalOrCustom(ISD::FNEG, VT) &&
1716 TLI.isOperationLegalOrCustom(ISD::FADD, VT))
1717 return; // Defer to LegalizeDAG
1718
1719 SDValue Tmp = DAG.UnrollVectorOp(Node);
1720 Results.push_back(Tmp);
1721}
1722
1723void VectorLegalizer::ExpandSETCC(SDNode *Node,
1725 bool NeedInvert = false;
1726 bool IsVP = Node->getOpcode() == ISD::VP_SETCC;
1727 bool IsStrict = Node->getOpcode() == ISD::STRICT_FSETCC ||
1728 Node->getOpcode() == ISD::STRICT_FSETCCS;
1729 bool IsSignaling = Node->getOpcode() == ISD::STRICT_FSETCCS;
1730 unsigned Offset = IsStrict ? 1 : 0;
1731
1732 SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
1733 SDValue LHS = Node->getOperand(0 + Offset);
1734 SDValue RHS = Node->getOperand(1 + Offset);
1735 SDValue CC = Node->getOperand(2 + Offset);
1736
1737 MVT OpVT = LHS.getSimpleValueType();
1738 ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
1739
1740 if (TLI.getCondCodeAction(CCCode, OpVT) != TargetLowering::Expand) {
1741 if (IsStrict) {
1742 UnrollStrictFPOp(Node, Results);
1743 return;
1744 }
1745 Results.push_back(UnrollVSETCC(Node));
1746 return;
1747 }
1748
1749 SDValue Mask, EVL;
1750 if (IsVP) {
1751 Mask = Node->getOperand(3 + Offset);
1752 EVL = Node->getOperand(4 + Offset);
1753 }
1754
1755 SDLoc dl(Node);
1756 bool Legalized =
1757 TLI.LegalizeSetCCCondCode(DAG, Node->getValueType(0), LHS, RHS, CC, Mask,
1758 EVL, NeedInvert, dl, Chain, IsSignaling);
1759
1760 if (Legalized) {
1761 // If we expanded the SETCC by swapping LHS and RHS, or by inverting the
1762 // condition code, create a new SETCC node.
1763 if (CC.getNode()) {
1764 if (IsStrict) {
1765 LHS = DAG.getNode(Node->getOpcode(), dl, Node->getVTList(),
1766 {Chain, LHS, RHS, CC}, Node->getFlags());
1767 Chain = LHS.getValue(1);
1768 } else if (IsVP) {
1769 LHS = DAG.getNode(ISD::VP_SETCC, dl, Node->getValueType(0),
1770 {LHS, RHS, CC, Mask, EVL}, Node->getFlags());
1771 } else {
1772 LHS = DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), LHS, RHS, CC,
1773 Node->getFlags());
1774 }
1775 }
1776
1777 // If we expanded the SETCC by inverting the condition code, then wrap
1778 // the existing SETCC in a NOT to restore the intended condition.
1779 if (NeedInvert) {
1780 if (!IsVP)
1781 LHS = DAG.getLogicalNOT(dl, LHS, LHS->getValueType(0));
1782 else
1783 LHS = DAG.getVPLogicalNOT(dl, LHS, Mask, EVL, LHS->getValueType(0));
1784 }
1785 } else {
1786 assert(!IsStrict && "Don't know how to expand for strict nodes.");
1787
1788 // Otherwise, SETCC for the given comparison type must be completely
1789 // illegal; expand it into a SELECT_CC.
1790 EVT VT = Node->getValueType(0);
1791 LHS =
1792 DAG.getNode(ISD::SELECT_CC, dl, VT, LHS, RHS,
1793 DAG.getBoolConstant(true, dl, VT, LHS.getValueType()),
1794 DAG.getBoolConstant(false, dl, VT, LHS.getValueType()), CC);
1795 LHS->setFlags(Node->getFlags());
1796 }
1797
1798 Results.push_back(LHS);
1799 if (IsStrict)
1800 Results.push_back(Chain);
1801}
1802
1803void VectorLegalizer::ExpandUADDSUBO(SDNode *Node,
1805 SDValue Result, Overflow;
1806 TLI.expandUADDSUBO(Node, Result, Overflow, DAG);
1807 Results.push_back(Result);
1808 Results.push_back(Overflow);
1809}
1810
1811void VectorLegalizer::ExpandSADDSUBO(SDNode *Node,
1813 SDValue Result, Overflow;
1814 TLI.expandSADDSUBO(Node, Result, Overflow, DAG);
1815 Results.push_back(Result);
1816 Results.push_back(Overflow);
1817}
1818
1819void VectorLegalizer::ExpandMULO(SDNode *Node,
1821 SDValue Result, Overflow;
1822 if (!TLI.expandMULO(Node, Result, Overflow, DAG))
1823 std::tie(Result, Overflow) = DAG.UnrollVectorOverflowOp(Node);
1824
1825 Results.push_back(Result);
1826 Results.push_back(Overflow);
1827}
1828
1829void VectorLegalizer::ExpandFixedPointDiv(SDNode *Node,
1831 SDNode *N = Node;
1832 if (SDValue Expanded = TLI.expandFixedPointDiv(N->getOpcode(), SDLoc(N),
1833 N->getOperand(0), N->getOperand(1), N->getConstantOperandVal(2), DAG))
1834 Results.push_back(Expanded);
1835}
1836
1837void VectorLegalizer::ExpandStrictFPOp(SDNode *Node,
1839 if (Node->getOpcode() == ISD::STRICT_UINT_TO_FP) {
1840 ExpandUINT_TO_FLOAT(Node, Results);
1841 return;
1842 }
1843 if (Node->getOpcode() == ISD::STRICT_FP_TO_UINT) {
1844 ExpandFP_TO_UINT(Node, Results);
1845 return;
1846 }
1847
1848 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
1849 Node->getOpcode() == ISD::STRICT_FSETCCS) {
1850 ExpandSETCC(Node, Results);
1851 return;
1852 }
1853
1854 UnrollStrictFPOp(Node, Results);
1855}
1856
1857void VectorLegalizer::ExpandREM(SDNode *Node,
1859 assert((Node->getOpcode() == ISD::SREM || Node->getOpcode() == ISD::UREM) &&
1860 "Expected REM node");
1861
1863 if (!TLI.expandREM(Node, Result, DAG))
1864 Result = DAG.UnrollVectorOp(Node);
1865 Results.push_back(Result);
1866}
1867
1868// Try to expand libm nodes into vector math routine calls. Callers provide the
1869// LibFunc equivalent of the passed in Node, which is used to lookup mappings
1870// within TargetLibraryInfo. The only mappings considered are those where the
1871// result and all operands are the same vector type. While predicated nodes are
1872// not supported, we will emit calls to masked routines by passing in an all
1873// true mask.
1874bool VectorLegalizer::tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall LC,
1876 // Chain must be propagated but currently strict fp operations are down
1877 // converted to their none strict counterpart.
1878 assert(!Node->isStrictFPOpcode() && "Unexpected strict fp operation!");
1879
1880 const char *LCName = TLI.getLibcallName(LC);
1881 if (!LCName)
1882 return false;
1883 LLVM_DEBUG(dbgs() << "Looking for vector variant of " << LCName << "\n");
1884
1885 EVT VT = Node->getValueType(0);
1887
1888 // Lookup a vector function equivalent to the specified libcall. Prefer
1889 // unmasked variants but we will generate a mask if need be.
1890 const TargetLibraryInfo &TLibInfo = DAG.getLibInfo();
1891 const VecDesc *VD = TLibInfo.getVectorMappingInfo(LCName, VL, false);
1892 if (!VD)
1893 VD = TLibInfo.getVectorMappingInfo(LCName, VL, /*Masked=*/true);
1894 if (!VD)
1895 return false;
1896
1897 LLVMContext *Ctx = DAG.getContext();
1898 Type *Ty = VT.getTypeForEVT(*Ctx);
1899 Type *ScalarTy = Ty->getScalarType();
1900
1901 // Construct a scalar function type based on Node's operands.
1903 for (unsigned i = 0; i < Node->getNumOperands(); ++i) {
1904 assert(Node->getOperand(i).getValueType() == VT &&
1905 "Expected matching vector types!");
1906 ArgTys.push_back(ScalarTy);
1907 }
1908 FunctionType *ScalarFTy = FunctionType::get(ScalarTy, ArgTys, false);
1909
1910 // Generate call information for the vector function.
1911 const std::string MangledName = VD->getVectorFunctionABIVariantString();
1912 auto OptVFInfo = VFABI::tryDemangleForVFABI(MangledName, ScalarFTy);
1913 if (!OptVFInfo)
1914 return false;
1915
1916 LLVM_DEBUG(dbgs() << "Found vector variant " << VD->getVectorFnName()
1917 << "\n");
1918
1919 // Sanity check just in case OptVFInfo has unexpected parameters.
1920 if (OptVFInfo->Shape.Parameters.size() !=
1921 Node->getNumOperands() + VD->isMasked())
1922 return false;
1923
1924 // Collect vector call operands.
1925
1926 SDLoc DL(Node);
1929 Entry.IsSExt = false;
1930 Entry.IsZExt = false;
1931
1932 unsigned OpNum = 0;
1933 for (auto &VFParam : OptVFInfo->Shape.Parameters) {
1934 if (VFParam.ParamKind == VFParamKind::GlobalPredicate) {
1935 EVT MaskVT = TLI.getSetCCResultType(DAG.getDataLayout(), *Ctx, VT);
1936 Entry.Node = DAG.getBoolConstant(true, DL, MaskVT, VT);
1937 Entry.Ty = MaskVT.getTypeForEVT(*Ctx);
1938 Args.push_back(Entry);
1939 continue;
1940 }
1941
1942 // Only vector operands are supported.
1943 if (VFParam.ParamKind != VFParamKind::Vector)
1944 return false;
1945
1946 Entry.Node = Node->getOperand(OpNum++);
1947 Entry.Ty = Ty;
1948 Args.push_back(Entry);
1949 }
1950
1951 // Emit a call to the vector function.
1952 SDValue Callee = DAG.getExternalSymbol(VD->getVectorFnName().data(),
1953 TLI.getPointerTy(DAG.getDataLayout()));
1955 CLI.setDebugLoc(DL)
1956 .setChain(DAG.getEntryNode())
1957 .setLibCallee(CallingConv::C, Ty, Callee, std::move(Args));
1958
1959 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
1960 Results.push_back(CallResult.first);
1961 return true;
1962}
1963
1964/// Try to expand the node to a vector libcall based on the result type.
1965bool VectorLegalizer::tryExpandVecMathCall(
1966 SDNode *Node, RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64,
1967 RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128,
1970 Node->getValueType(0).getVectorElementType(), Call_F32, Call_F64,
1971 Call_F80, Call_F128, Call_PPCF128);
1972
1973 if (LC == RTLIB::UNKNOWN_LIBCALL)
1974 return false;
1975
1976 return tryExpandVecMathCall(Node, LC, Results);
1977}
1978
1979void VectorLegalizer::UnrollStrictFPOp(SDNode *Node,
1981 EVT VT = Node->getValueType(0);
1982 EVT EltVT = VT.getVectorElementType();
1983 unsigned NumElems = VT.getVectorNumElements();
1984 unsigned NumOpers = Node->getNumOperands();
1985 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1986
1987 EVT TmpEltVT = EltVT;
1988 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
1989 Node->getOpcode() == ISD::STRICT_FSETCCS)
1990 TmpEltVT = TLI.getSetCCResultType(DAG.getDataLayout(),
1991 *DAG.getContext(), TmpEltVT);
1992
1993 EVT ValueVTs[] = {TmpEltVT, MVT::Other};
1994 SDValue Chain = Node->getOperand(0);
1995 SDLoc dl(Node);
1996
1997 SmallVector<SDValue, 32> OpValues;
1998 SmallVector<SDValue, 32> OpChains;
1999 for (unsigned i = 0; i < NumElems; ++i) {
2001 SDValue Idx = DAG.getVectorIdxConstant(i, dl);
2002
2003 // The Chain is the first operand.
2004 Opers.push_back(Chain);
2005
2006 // Now process the remaining operands.
2007 for (unsigned j = 1; j < NumOpers; ++j) {
2008 SDValue Oper = Node->getOperand(j);
2009 EVT OperVT = Oper.getValueType();
2010
2011 if (OperVT.isVector())
2012 Oper = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2013 OperVT.getVectorElementType(), Oper, Idx);
2014
2015 Opers.push_back(Oper);
2016 }
2017
2018 SDValue ScalarOp = DAG.getNode(Node->getOpcode(), dl, ValueVTs, Opers);
2019 SDValue ScalarResult = ScalarOp.getValue(0);
2020 SDValue ScalarChain = ScalarOp.getValue(1);
2021
2022 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2023 Node->getOpcode() == ISD::STRICT_FSETCCS)
2024 ScalarResult = DAG.getSelect(dl, EltVT, ScalarResult,
2025 DAG.getAllOnesConstant(dl, EltVT),
2026 DAG.getConstant(0, dl, EltVT));
2027
2028 OpValues.push_back(ScalarResult);
2029 OpChains.push_back(ScalarChain);
2030 }
2031
2032 SDValue Result = DAG.getBuildVector(VT, dl, OpValues);
2033 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OpChains);
2034
2035 Results.push_back(Result);
2036 Results.push_back(NewChain);
2037}
2038
2039SDValue VectorLegalizer::UnrollVSETCC(SDNode *Node) {
2040 EVT VT = Node->getValueType(0);
2041 unsigned NumElems = VT.getVectorNumElements();
2042 EVT EltVT = VT.getVectorElementType();
2043 SDValue LHS = Node->getOperand(0);
2044 SDValue RHS = Node->getOperand(1);
2045 SDValue CC = Node->getOperand(2);
2046 EVT TmpEltVT = LHS.getValueType().getVectorElementType();
2047 SDLoc dl(Node);
2048 SmallVector<SDValue, 8> Ops(NumElems);
2049 for (unsigned i = 0; i < NumElems; ++i) {
2050 SDValue LHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
2051 DAG.getVectorIdxConstant(i, dl));
2052 SDValue RHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
2053 DAG.getVectorIdxConstant(i, dl));
2054 Ops[i] = DAG.getNode(ISD::SETCC, dl,
2055 TLI.getSetCCResultType(DAG.getDataLayout(),
2056 *DAG.getContext(), TmpEltVT),
2057 LHSElem, RHSElem, CC);
2058 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i], DAG.getAllOnesConstant(dl, EltVT),
2059 DAG.getConstant(0, dl, EltVT));
2060 }
2061 return DAG.getBuildVector(VT, dl, Ops);
2062}
2063
2065 return VectorLegalizer(*this).Run();
2066}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
BlockVerifier::State From
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 LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines the DenseMap class.
static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl< int > &ShuffleMask)
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
Value * RHS
Value * LHS
BinaryOperator * Mul
DEMANGLE_DUMP_METHOD void dump() const
This class represents an Operation in the Expression.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
size_t size() const
Definition: Function.h:804
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
This class is used to represent ISD::LOAD nodes.
Machine Value Type.
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
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.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:225
bool LegalizeVectors()
This transforms the SelectionDAG into a SelectionDAG that only uses vector math operations supported ...
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:477
ilist< SDNode >::iterator allnodes_iterator
Definition: SelectionDAG.h:533
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void resize(size_type N)
Definition: SmallVector.h:651
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
This class is used to represent ISD::STORE nodes.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
Provides information about what library functions are available for the current target.
const VecDesc * getVectorMappingInfo(StringRef F, const ElementCount &VF, bool Masked) const
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
std::vector< ArgListEntry > ArgListTy
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:348
Provides info so a possible vectorization of a function can be computed.
bool isMasked() const
std::string getVectorFunctionABIVariantString() const
Returns a vector function ABI variant string on the form: ZGV<isa><mask><vlen><vparams><scalarname>(<...
StringRef getVectorFnName() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:121
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:750
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition: ISDOpcodes.h:236
@ CTLZ_ZERO_UNDEF
Definition: ISDOpcodes.h:723
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition: ISDOpcodes.h:476
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
Definition: ISDOpcodes.h:1339
@ VECREDUCE_SMIN
Definition: ISDOpcodes.h:1370
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition: ISDOpcodes.h:559
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:714
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
Definition: ISDOpcodes.h:367
@ FMAXNUM_IEEE
Definition: ISDOpcodes.h:979
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1031
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
Definition: ISDOpcodes.h:373
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:783
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:483
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:790
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
Definition: ISDOpcodes.h:1355
@ FADD
Simple binary floating point operators.
Definition: ISDOpcodes.h:390
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
Definition: ISDOpcodes.h:1359
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:688
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
Definition: ISDOpcodes.h:820
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
@ VECREDUCE_SMAX
Definition: ISDOpcodes.h:1369
@ STRICT_FSETCCS
Definition: ISDOpcodes.h:477
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:903
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
Definition: ISDOpcodes.h:939
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
Definition: ISDOpcodes.h:380
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition: ISDOpcodes.h:411
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:774
@ STRICT_UINT_TO_FP
Definition: ISDOpcodes.h:450
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
Definition: ISDOpcodes.h:1352
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
Definition: ISDOpcodes.h:722
@ VECREDUCE_FMIN
Definition: ISDOpcodes.h:1356
@ FNEG
Perform various unary floating-point operations inspired by libm.
Definition: ISDOpcodes.h:930
@ SSUBO
Same for subtraction.
Definition: ISDOpcodes.h:327
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
Definition: ISDOpcodes.h:646
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
Definition: ISDOpcodes.h:500
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition: ISDOpcodes.h:349
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:727
@ VECREDUCE_UMAX
Definition: ISDOpcodes.h:1371
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition: ISDOpcodes.h:627
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition: ISDOpcodes.h:323
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
Definition: ISDOpcodes.h:1364
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:651
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:705
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on two values,...
Definition: ISDOpcodes.h:978
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:535
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:780
@ FP_TO_UINT_SAT
Definition: ISDOpcodes.h:856
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:742
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
Definition: ISDOpcodes.h:971
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
Definition: ISDOpcodes.h:359
@ SMULO
Same for multiplication.
Definition: ISDOpcodes.h:331
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
Definition: ISDOpcodes.h:809
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:798
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition: ISDOpcodes.h:674
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
Definition: ISDOpcodes.h:386
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition: ISDOpcodes.h:888
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition: ISDOpcodes.h:736
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition: ISDOpcodes.h:449
@ VECREDUCE_UMIN
Definition: ISDOpcodes.h:1372
@ STRICT_FP_TO_UINT
Definition: ISDOpcodes.h:443
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition: ISDOpcodes.h:465
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:442
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
Definition: ISDOpcodes.h:984
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:836
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition: ISDOpcodes.h:470
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:680
@ VECREDUCE_FMUL
Definition: ISDOpcodes.h:1353
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition: ISDOpcodes.h:400
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
Definition: ISDOpcodes.h:944
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition: ISDOpcodes.h:869
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
Definition: ISDOpcodes.h:831
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
Definition: ISDOpcodes.h:855
@ VECREDUCE_FMINIMUM
Definition: ISDOpcodes.h:1360
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:786
@ VECREDUCE_SEQ_FMUL
Definition: ISDOpcodes.h:1340
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:493
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition: ISDOpcodes.h:340
@ AssertZext
Definition: ISDOpcodes.h:62
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:515
std::optional< unsigned > getVPMaskIdx(unsigned Opcode)
The operand position of the vector mask.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1523
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1503
bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Libcall getFPLibCall(EVT VT, Libcall Call_F32, Libcall Call_F64, Libcall Call_F80, Libcall Call_F128, Libcall Call_PPCF128)
GetFPLibCall - Helper to return the right libcall for the given floating point type,...
ManagedStatic< cl::opt< FnT >, OptCreatorT > Action
std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy)
Function to construct a VFInfo out of a mangled names in the following format:
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
#define N
Extended Value Type.
Definition: ValueTypes.h:34
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:93
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:73
ElementCount getVectorElementCount() const
Definition: ValueTypes.h:340
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:358
uint64_t getScalarSizeInBits() const
Definition: ValueTypes.h:370
bool isFixedLengthVector() const
Definition: ValueTypes.h:177
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:167
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition: ValueTypes.h:313
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:202
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
Definition: ValueTypes.h:173
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:318
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:326
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition: ValueTypes.h:298
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.