LLVM 23.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 ExpandVP_FNEG(SDNode *Node);
139 SDValue ExpandVP_FABS(SDNode *Node);
140 SDValue ExpandVP_FCOPYSIGN(SDNode *Node);
141 SDValue ExpandLOOP_DEPENDENCE_MASK(SDNode *N);
142 SDValue ExpandMaskedBinOp(SDNode *N);
143 SDValue ExpandSELECT(SDNode *Node);
144 std::pair<SDValue, SDValue> ExpandLoad(SDNode *N);
145 SDValue ExpandStore(SDNode *N);
146 SDValue ExpandFNEG(SDNode *Node);
147 SDValue ExpandFABS(SDNode *Node);
148 SDValue ExpandFCOPYSIGN(SDNode *Node);
149 void ExpandFSUB(SDNode *Node, SmallVectorImpl<SDValue> &Results);
150 void ExpandSETCC(SDNode *Node, SmallVectorImpl<SDValue> &Results);
151 SDValue ExpandBITREVERSE(SDNode *Node);
152 void ExpandUADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
153 void ExpandSADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
154 void ExpandMULO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
155 void ExpandFixedPointDiv(SDNode *Node, SmallVectorImpl<SDValue> &Results);
156 void ExpandStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);
157 void ExpandREM(SDNode *Node, SmallVectorImpl<SDValue> &Results);
158
159 bool tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall LC,
161
162 void UnrollStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);
163
164 /// Implements vector promotion.
165 ///
166 /// This is essentially just bitcasting the operands to a different type and
167 /// bitcasting the result back to the original type.
169
170 /// Implements [SU]INT_TO_FP vector promotion.
171 ///
172 /// This is a [zs]ext of the input operand to a larger integer type.
173 void PromoteINT_TO_FP(SDNode *Node, SmallVectorImpl<SDValue> &Results);
174
175 /// Implements FP_TO_[SU]INT vector promotion of the result type.
176 ///
177 /// It is promoted to a larger integer type. The result is then
178 /// truncated back to the original type.
179 void PromoteFP_TO_INT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
180
181 /// Implements vector setcc operation promotion.
182 ///
183 /// All vector operands are promoted to a vector type with larger element
184 /// type.
185 void PromoteSETCC(SDNode *Node, SmallVectorImpl<SDValue> &Results);
186
187 void PromoteSTRICT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
188
189 /// Calculate the reduction using a type of higher precision and round the
190 /// result to match the original type. Setting NonArithmetic signifies the
191 /// rounding of the result does not affect its value.
192 void PromoteFloatVECREDUCE(SDNode *Node, SmallVectorImpl<SDValue> &Results,
193 bool NonArithmetic);
194
195 void PromoteVECTOR_COMPRESS(SDNode *Node, SmallVectorImpl<SDValue> &Results);
196
197public:
198 VectorLegalizer(SelectionDAG& dag) :
199 DAG(dag), TLI(dag.getTargetLoweringInfo()) {}
200
201 /// Begin legalizer the vector operations in the DAG.
202 bool Run();
203};
204
205} // end anonymous namespace
206
207bool VectorLegalizer::Run() {
208 // Before we start legalizing vector nodes, check if there are any vectors.
209 bool HasVectors = false;
211 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I) {
212 // Check if the values of the nodes contain vectors. We don't need to check
213 // the operands because we are going to check their values at some point.
214 HasVectors = llvm::any_of(I->values(), [](EVT T) { return T.isVector(); });
215
216 // If we found a vector node we can start the legalization.
217 if (HasVectors)
218 break;
219 }
220
221 // If this basic block has no vectors then no need to legalize vectors.
222 if (!HasVectors)
223 return false;
224
225 // The legalize process is inherently a bottom-up recursive process (users
226 // legalize their uses before themselves). Given infinite stack space, we
227 // could just start legalizing on the root and traverse the whole graph. In
228 // practice however, this causes us to run out of stack space on large basic
229 // blocks. To avoid this problem, compute an ordering of the nodes where each
230 // node is only legalized after all of its operands are legalized.
233 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I)
234 LegalizeOp(SDValue(&*I, 0));
235
236 // Finally, it's possible the root changed. Get the new root.
237 SDValue OldRoot = DAG.getRoot();
238 assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?");
239 DAG.setRoot(LegalizedNodes[OldRoot]);
240
241 LegalizedNodes.clear();
242
243 // Remove dead nodes now.
244 DAG.RemoveDeadNodes();
245
246 return Changed;
247}
248
249SDValue VectorLegalizer::TranslateLegalizeResults(SDValue Op, SDNode *Result) {
250 assert(Op->getNumValues() == Result->getNumValues() &&
251 "Unexpected number of results");
252 // Generic legalization: just pass the operand through.
253 for (unsigned i = 0, e = Op->getNumValues(); i != e; ++i)
254 AddLegalizedOperand(Op.getValue(i), SDValue(Result, i));
255 return SDValue(Result, Op.getResNo());
256}
257
259VectorLegalizer::RecursivelyLegalizeResults(SDValue Op,
261 assert(Results.size() == Op->getNumValues() &&
262 "Unexpected number of results");
263 // Make sure that the generated code is itself legal.
264 for (unsigned i = 0, e = Results.size(); i != e; ++i) {
265 Results[i] = LegalizeOp(Results[i]);
266 AddLegalizedOperand(Op.getValue(i), Results[i]);
267 }
268
269 return Results[Op.getResNo()];
270}
271
272SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
273 // Note that LegalizeOp may be reentered even from single-use nodes, which
274 // means that we always must cache transformed nodes.
275 auto I = LegalizedNodes.find(Op);
276 if (I != LegalizedNodes.end()) return I->second;
277
278 // Legalize the operands
280 for (const SDValue &Oper : Op->op_values())
281 Ops.push_back(LegalizeOp(Oper));
282
283 SDNode *Node = DAG.UpdateNodeOperands(Op.getNode(), Ops);
284
285 bool HasVectorValueOrOp =
286 llvm::any_of(Node->values(), [](EVT T) { return T.isVector(); }) ||
287 llvm::any_of(Node->op_values(),
288 [](SDValue O) { return O.getValueType().isVector(); });
289 if (!HasVectorValueOrOp)
290 return TranslateLegalizeResults(Op, Node);
291
292 TargetLowering::LegalizeAction Action = TargetLowering::Legal;
293 EVT ValVT;
294 switch (Op.getOpcode()) {
295 default:
296 return TranslateLegalizeResults(Op, Node);
297 case ISD::LOAD: {
298 LoadSDNode *LD = cast<LoadSDNode>(Node);
299 ISD::LoadExtType ExtType = LD->getExtensionType();
300 EVT LoadedVT = LD->getMemoryVT();
301 if (LoadedVT.isVector() && ExtType != ISD::NON_EXTLOAD)
302 Action = TLI.getLoadAction(LD->getValueType(0), LoadedVT, LD->getAlign(),
303 LD->getAddressSpace(), ExtType, false);
304 break;
305 }
306 case ISD::STORE: {
307 StoreSDNode *ST = cast<StoreSDNode>(Node);
308 EVT StVT = ST->getMemoryVT();
309 MVT ValVT = ST->getValue().getSimpleValueType();
310 if (StVT.isVector() && ST->isTruncatingStore())
311 Action = TLI.getTruncStoreAction(ValVT, StVT, ST->getAlign(),
312 ST->getAddressSpace());
313 break;
314 }
316 Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
317 // This operation lies about being legal: when it claims to be legal,
318 // it should actually be expanded.
319 if (Action == TargetLowering::Legal)
320 Action = TargetLowering::Expand;
321 break;
322#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
323 case ISD::STRICT_##DAGN:
324#include "llvm/IR/ConstrainedOps.def"
325 ValVT = Node->getValueType(0);
326 if (Op.getOpcode() == ISD::STRICT_SINT_TO_FP ||
327 Op.getOpcode() == ISD::STRICT_UINT_TO_FP)
328 ValVT = Node->getOperand(1).getValueType();
329 if (Op.getOpcode() == ISD::STRICT_FSETCC ||
330 Op.getOpcode() == ISD::STRICT_FSETCCS) {
331 MVT OpVT = Node->getOperand(1).getSimpleValueType();
332 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(3))->get();
333 Action = TLI.getCondCodeAction(CCCode, OpVT);
334 if (Action == TargetLowering::Legal)
335 Action = TLI.getOperationAction(Node->getOpcode(), OpVT);
336 } else {
337 Action = TLI.getOperationAction(Node->getOpcode(), ValVT);
338 }
339 // If we're asked to expand a strict vector floating-point operation,
340 // by default we're going to simply unroll it. That is usually the
341 // best approach, except in the case where the resulting strict (scalar)
342 // operations would themselves use the fallback mutation to non-strict.
343 // In that specific case, just do the fallback on the vector op.
344 if (Action == TargetLowering::Expand && !TLI.isStrictFPEnabled() &&
345 TLI.getStrictFPOperationAction(Node->getOpcode(), ValVT) ==
346 TargetLowering::Legal) {
347 EVT EltVT = ValVT.getVectorElementType();
348 if (TLI.getOperationAction(Node->getOpcode(), EltVT)
349 == TargetLowering::Expand &&
350 TLI.getStrictFPOperationAction(Node->getOpcode(), EltVT)
351 == TargetLowering::Legal)
352 Action = TargetLowering::Legal;
353 }
354 break;
355 case ISD::ADD:
356 case ISD::SUB:
357 case ISD::MUL:
358 case ISD::MULHS:
359 case ISD::MULHU:
360 case ISD::SDIV:
361 case ISD::UDIV:
362 case ISD::SREM:
363 case ISD::UREM:
364 case ISD::SDIVREM:
365 case ISD::UDIVREM:
366 case ISD::FADD:
367 case ISD::FSUB:
368 case ISD::FMUL:
369 case ISD::FDIV:
370 case ISD::FREM:
371 case ISD::AND:
372 case ISD::OR:
373 case ISD::XOR:
374 case ISD::SHL:
375 case ISD::SRA:
376 case ISD::SRL:
377 case ISD::FSHL:
378 case ISD::FSHR:
379 case ISD::ROTL:
380 case ISD::ROTR:
381 case ISD::ABS:
383 case ISD::ABDS:
384 case ISD::ABDU:
385 case ISD::AVGCEILS:
386 case ISD::AVGCEILU:
387 case ISD::AVGFLOORS:
388 case ISD::AVGFLOORU:
389 case ISD::BSWAP:
390 case ISD::BITREVERSE:
391 case ISD::CTLZ:
392 case ISD::CTTZ:
395 case ISD::CTPOP:
396 case ISD::CLMUL:
397 case ISD::CLMULH:
398 case ISD::CLMULR:
399 case ISD::SELECT:
400 case ISD::VSELECT:
401 case ISD::SELECT_CC:
402 case ISD::ZERO_EXTEND:
403 case ISD::ANY_EXTEND:
404 case ISD::TRUNCATE:
405 case ISD::SIGN_EXTEND:
406 case ISD::FP_TO_SINT:
407 case ISD::FP_TO_UINT:
408 case ISD::FNEG:
409 case ISD::FABS:
410 case ISD::FMINNUM:
411 case ISD::FMAXNUM:
414 case ISD::FMINIMUM:
415 case ISD::FMAXIMUM:
416 case ISD::FMINIMUMNUM:
417 case ISD::FMAXIMUMNUM:
418 case ISD::FCOPYSIGN:
419 case ISD::FSQRT:
420 case ISD::FSIN:
421 case ISD::FCOS:
422 case ISD::FTAN:
423 case ISD::FASIN:
424 case ISD::FACOS:
425 case ISD::FATAN:
426 case ISD::FATAN2:
427 case ISD::FSINH:
428 case ISD::FCOSH:
429 case ISD::FTANH:
430 case ISD::FLDEXP:
431 case ISD::FPOWI:
432 case ISD::FPOW:
433 case ISD::FCBRT:
434 case ISD::FLOG:
435 case ISD::FLOG2:
436 case ISD::FLOG10:
437 case ISD::FEXP:
438 case ISD::FEXP2:
439 case ISD::FEXP10:
440 case ISD::FCEIL:
441 case ISD::FTRUNC:
442 case ISD::FRINT:
443 case ISD::FNEARBYINT:
444 case ISD::FROUND:
445 case ISD::FROUNDEVEN:
446 case ISD::FFLOOR:
447 case ISD::FP_ROUND:
448 case ISD::FP_EXTEND:
450 case ISD::FMA:
455 case ISD::SMIN:
456 case ISD::SMAX:
457 case ISD::UMIN:
458 case ISD::UMAX:
459 case ISD::SMUL_LOHI:
460 case ISD::UMUL_LOHI:
461 case ISD::SADDO:
462 case ISD::UADDO:
463 case ISD::SSUBO:
464 case ISD::USUBO:
465 case ISD::SMULO:
466 case ISD::UMULO:
470 case ISD::FFREXP:
471 case ISD::FMODF:
472 case ISD::FSINCOS:
473 case ISD::FSINCOSPI:
474 case ISD::SADDSAT:
475 case ISD::UADDSAT:
476 case ISD::SSUBSAT:
477 case ISD::USUBSAT:
478 case ISD::SSHLSAT:
479 case ISD::USHLSAT:
482 case ISD::MGATHER:
484 case ISD::SCMP:
485 case ISD::UCMP:
488 case ISD::MASKED_UDIV:
489 case ISD::MASKED_SDIV:
490 case ISD::MASKED_UREM:
491 case ISD::MASKED_SREM:
492 Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
493 break;
494 case ISD::SMULFIX:
495 case ISD::SMULFIXSAT:
496 case ISD::UMULFIX:
497 case ISD::UMULFIXSAT:
498 case ISD::SDIVFIX:
499 case ISD::SDIVFIXSAT:
500 case ISD::UDIVFIX:
501 case ISD::UDIVFIXSAT: {
502 unsigned Scale = Node->getConstantOperandVal(2);
503 Action = TLI.getFixedPointOperationAction(Node->getOpcode(),
504 Node->getValueType(0), Scale);
505 break;
506 }
507 case ISD::LROUND:
508 case ISD::LLROUND:
509 case ISD::LRINT:
510 case ISD::LLRINT:
511 case ISD::SINT_TO_FP:
512 case ISD::UINT_TO_FP:
528 case ISD::CTTZ_ELTS:
531 Action = TLI.getOperationAction(Node->getOpcode(),
532 Node->getOperand(0).getValueType());
533 break;
536 Action = TLI.getOperationAction(Node->getOpcode(),
537 Node->getOperand(1).getValueType());
538 break;
539 case ISD::SETCC: {
540 MVT OpVT = Node->getOperand(0).getSimpleValueType();
541 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get();
542 Action = TLI.getCondCodeAction(CCCode, OpVT);
543 if (Action == TargetLowering::Legal)
544 Action = TLI.getOperationAction(Node->getOpcode(), OpVT);
545 break;
546 }
551 Action =
552 TLI.getPartialReduceMLAAction(Op.getOpcode(), Node->getValueType(0),
553 Node->getOperand(1).getValueType());
554 break;
555
556#define BEGIN_REGISTER_VP_SDNODE(VPID, LEGALPOS, ...) \
557 case ISD::VPID: { \
558 EVT LegalizeVT = LEGALPOS < 0 ? Node->getValueType(-(1 + LEGALPOS)) \
559 : Node->getOperand(LEGALPOS).getValueType(); \
560 if (ISD::VPID == ISD::VP_SETCC) { \
561 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get(); \
562 Action = TLI.getCondCodeAction(CCCode, LegalizeVT.getSimpleVT()); \
563 if (Action != TargetLowering::Legal) \
564 break; \
565 } \
566 /* Defer non-vector results to LegalizeDAG. */ \
567 if (!Node->getValueType(0).isVector() && \
568 Node->getValueType(0) != MVT::Other) { \
569 Action = TargetLowering::Legal; \
570 break; \
571 } \
572 Action = TLI.getOperationAction(Node->getOpcode(), LegalizeVT); \
573 } break;
574#include "llvm/IR/VPIntrinsics.def"
575 }
576
577 LLVM_DEBUG(dbgs() << "\nLegalizing vector op: "; Node->dump(&DAG));
578
579 SmallVector<SDValue, 8> ResultVals;
580 switch (Action) {
581 default: llvm_unreachable("This action is not supported yet!");
582 case TargetLowering::Promote:
583 assert((Op.getOpcode() != ISD::LOAD && Op.getOpcode() != ISD::STORE) &&
584 "This action is not supported yet!");
585 LLVM_DEBUG(dbgs() << "Promoting\n");
586 Promote(Node, ResultVals);
587 assert(!ResultVals.empty() && "No results for promotion?");
588 break;
589 case TargetLowering::Legal:
590 LLVM_DEBUG(dbgs() << "Legal node: nothing to do\n");
591 break;
592 case TargetLowering::Custom:
593 LLVM_DEBUG(dbgs() << "Trying custom legalization\n");
594 if (LowerOperationWrapper(Node, ResultVals))
595 break;
596 LLVM_DEBUG(dbgs() << "Could not custom legalize node\n");
597 [[fallthrough]];
598 case TargetLowering::Expand:
599 LLVM_DEBUG(dbgs() << "Expanding\n");
600 Expand(Node, ResultVals);
601 break;
602 }
603
604 if (ResultVals.empty())
605 return TranslateLegalizeResults(Op, Node);
606
607 Changed = true;
608 return RecursivelyLegalizeResults(Op, ResultVals);
609}
610
611// FIXME: This is very similar to TargetLowering::LowerOperationWrapper. Can we
612// merge them somehow?
613bool VectorLegalizer::LowerOperationWrapper(SDNode *Node,
614 SmallVectorImpl<SDValue> &Results) {
615 SDValue Res = TLI.LowerOperation(SDValue(Node, 0), DAG);
616
617 if (!Res.getNode())
618 return false;
619
620 if (Res == SDValue(Node, 0))
621 return true;
622
623 // If the original node has one result, take the return value from
624 // LowerOperation as is. It might not be result number 0.
625 if (Node->getNumValues() == 1) {
626 Results.push_back(Res);
627 return true;
628 }
629
630 // If the original node has multiple results, then the return node should
631 // have the same number of results.
632 assert((Node->getNumValues() == Res->getNumValues()) &&
633 "Lowering returned the wrong number of results!");
634
635 // Places new result values base on N result number.
636 for (unsigned I = 0, E = Node->getNumValues(); I != E; ++I)
637 Results.push_back(Res.getValue(I));
638
639 return true;
640}
641
642void VectorLegalizer::PromoteSETCC(SDNode *Node,
643 SmallVectorImpl<SDValue> &Results) {
644 MVT VecVT = Node->getOperand(0).getSimpleValueType();
645 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
646
647 unsigned ExtOp = VecVT.isFloatingPoint() ? ISD::FP_EXTEND : ISD::ANY_EXTEND;
648
649 SDLoc DL(Node);
650 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
651
652 Operands[0] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(0));
653 Operands[1] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(1));
654 Operands[2] = Node->getOperand(2);
655
656 if (Node->getOpcode() == ISD::VP_SETCC) {
657 Operands[3] = Node->getOperand(3); // mask
658 Operands[4] = Node->getOperand(4); // evl
659 }
660
661 EVT ResVT =
662 TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), NewVecVT);
663 SDValue Res =
664 DAG.getNode(Node->getOpcode(), DL, ResVT, Operands, Node->getFlags());
665 if (ResVT != Node->getValueType(0))
666 Res = DAG.getBoolExtOrTrunc(Res, DL, Node->getValueType(0), NewVecVT);
667 Results.push_back(Res);
668}
669
670void VectorLegalizer::PromoteSTRICT(SDNode *Node,
671 SmallVectorImpl<SDValue> &Results) {
672 MVT VecVT = Node->getOperand(1).getSimpleValueType();
673 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
674
675 assert(VecVT.isFloatingPoint());
676
677 SDLoc DL(Node);
678 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
680
681 for (unsigned j = 1; j != Node->getNumOperands(); ++j)
682 if (Node->getOperand(j).getValueType().isVector() &&
683 !(ISD::isVPOpcode(Node->getOpcode()) &&
684 ISD::getVPMaskIdx(Node->getOpcode()) == j)) // Skip mask operand.
685 {
686 // promote the vector operand.
687 SDValue Ext =
688 DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {NewVecVT, MVT::Other},
689 {Node->getOperand(0), Node->getOperand(j)});
690 Operands[j] = Ext.getValue(0);
691 Chains.push_back(Ext.getValue(1));
692 } else
693 Operands[j] = Node->getOperand(j); // Skip no vector operand.
694
695 SDVTList VTs = DAG.getVTList(NewVecVT, Node->getValueType(1));
696
697 Operands[0] = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
698
699 SDValue Res =
700 DAG.getNode(Node->getOpcode(), DL, VTs, Operands, Node->getFlags());
701
702 SDValue Round =
703 DAG.getNode(ISD::STRICT_FP_ROUND, DL, {VecVT, MVT::Other},
704 {Res.getValue(1), Res.getValue(0),
705 DAG.getIntPtrConstant(0, DL, /*isTarget=*/true)});
706
707 Results.push_back(Round.getValue(0));
708 Results.push_back(Round.getValue(1));
709}
710
711void VectorLegalizer::PromoteFloatVECREDUCE(SDNode *Node,
712 SmallVectorImpl<SDValue> &Results,
713 bool NonArithmetic) {
714 MVT OpVT = Node->getOperand(0).getSimpleValueType();
715 assert(OpVT.isFloatingPoint() && "Expected floating point reduction!");
716 MVT NewOpVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OpVT);
717
718 SDLoc DL(Node);
719 SDValue NewOp = DAG.getNode(ISD::FP_EXTEND, DL, NewOpVT, Node->getOperand(0));
720 SDValue Rdx =
721 DAG.getNode(Node->getOpcode(), DL, NewOpVT.getVectorElementType(), NewOp,
722 Node->getFlags());
723 SDValue Res =
724 DAG.getNode(ISD::FP_ROUND, DL, Node->getValueType(0), Rdx,
725 DAG.getIntPtrConstant(NonArithmetic, DL, /*isTarget=*/true));
726 Results.push_back(Res);
727}
728
729void VectorLegalizer::PromoteVECTOR_COMPRESS(
730 SDNode *Node, SmallVectorImpl<SDValue> &Results) {
731 SDLoc DL(Node);
732 EVT VT = Node->getValueType(0);
733 MVT PromotedVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT.getSimpleVT());
734 assert((VT.isInteger() || VT.getSizeInBits() == PromotedVT.getSizeInBits()) &&
735 "Only integer promotion or bitcasts between types is supported");
736
737 SDValue Vec = Node->getOperand(0);
738 SDValue Mask = Node->getOperand(1);
739 SDValue Passthru = Node->getOperand(2);
740 if (VT.isInteger()) {
741 Vec = DAG.getNode(ISD::ANY_EXTEND, DL, PromotedVT, Vec);
742 Mask = TLI.promoteTargetBoolean(DAG, Mask, PromotedVT);
743 Passthru = DAG.getNode(ISD::ANY_EXTEND, DL, PromotedVT, Passthru);
744 } else {
745 Vec = DAG.getBitcast(PromotedVT, Vec);
746 Passthru = DAG.getBitcast(PromotedVT, Passthru);
747 }
748
750 DAG.getNode(ISD::VECTOR_COMPRESS, DL, PromotedVT, Vec, Mask, Passthru);
751 Result = VT.isInteger() ? DAG.getNode(ISD::TRUNCATE, DL, VT, Result)
752 : DAG.getBitcast(VT, Result);
753 Results.push_back(Result);
754}
755
756void VectorLegalizer::Promote(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
757 // For a few operations there is a specific concept for promotion based on
758 // the operand's type.
759 switch (Node->getOpcode()) {
760 case ISD::SINT_TO_FP:
761 case ISD::UINT_TO_FP:
764 // "Promote" the operation by extending the operand.
765 PromoteINT_TO_FP(Node, Results);
766 return;
767 case ISD::FP_TO_UINT:
768 case ISD::FP_TO_SINT:
771 // Promote the operation by extending the operand.
772 PromoteFP_TO_INT(Node, Results);
773 return;
774 case ISD::VP_SETCC:
775 case ISD::SETCC:
776 // Promote the operation by extending the operand.
777 PromoteSETCC(Node, Results);
778 return;
779 case ISD::STRICT_FADD:
780 case ISD::STRICT_FSUB:
781 case ISD::STRICT_FMUL:
782 case ISD::STRICT_FDIV:
784 case ISD::STRICT_FMA:
785 PromoteSTRICT(Node, Results);
786 return;
789 PromoteFloatVECREDUCE(Node, Results, /*NonArithmetic=*/false);
790 return;
795 PromoteFloatVECREDUCE(Node, Results, /*NonArithmetic=*/true);
796 return;
798 PromoteVECTOR_COMPRESS(Node, Results);
799 return;
800
801 case ISD::FP_ROUND:
802 case ISD::FP_EXTEND:
803 // These operations are used to do promotion so they can't be promoted
804 // themselves.
805 llvm_unreachable("Don't know how to promote this operation!");
806 case ISD::VP_FABS:
807 case ISD::VP_FCOPYSIGN:
808 case ISD::VP_FNEG:
809 // Promoting fabs, fneg, and fcopysign changes their semantics.
810 llvm_unreachable("These operations should not be promoted");
811 }
812
813 // There are currently two cases of vector promotion:
814 // 1) Bitcasting a vector of integers to a different type to a vector of the
815 // same overall length. For example, x86 promotes ISD::AND v2i32 to v1i64.
816 // 2) Extending a vector of floats to a vector of the same number of larger
817 // floats. For example, AArch64 promotes ISD::FADD on v4f16 to v4f32.
818 assert(Node->getNumValues() == 1 &&
819 "Can't promote a vector with multiple results!");
820 MVT VT = Node->getSimpleValueType(0);
821 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
822 SDLoc dl(Node);
823 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
824
825 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
826 // Do not promote the mask operand of a VP OP.
827 bool SkipPromote = ISD::isVPOpcode(Node->getOpcode()) &&
828 ISD::getVPMaskIdx(Node->getOpcode()) == j;
829 if (Node->getOperand(j).getValueType().isVector() && !SkipPromote)
830 if (Node->getOperand(j)
831 .getValueType()
832 .getVectorElementType()
833 .isFloatingPoint() &&
835 if (ISD::isVPOpcode(Node->getOpcode())) {
836 unsigned EVLIdx =
838 unsigned MaskIdx = *ISD::getVPMaskIdx(Node->getOpcode());
839 Operands[j] =
840 DAG.getNode(ISD::VP_FP_EXTEND, dl, NVT, Node->getOperand(j),
841 Node->getOperand(MaskIdx), Node->getOperand(EVLIdx));
842 } else {
843 Operands[j] =
844 DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(j));
845 }
846 else
847 Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(j));
848 else
849 Operands[j] = Node->getOperand(j);
850 }
851
852 SDValue Res =
853 DAG.getNode(Node->getOpcode(), dl, NVT, Operands, Node->getFlags());
854
855 if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
858 if (ISD::isVPOpcode(Node->getOpcode())) {
859 unsigned EVLIdx = *ISD::getVPExplicitVectorLengthIdx(Node->getOpcode());
860 unsigned MaskIdx = *ISD::getVPMaskIdx(Node->getOpcode());
861 Res = DAG.getNode(ISD::VP_FP_ROUND, dl, VT, Res,
862 Node->getOperand(MaskIdx), Node->getOperand(EVLIdx));
863 } else {
864 Res = DAG.getNode(ISD::FP_ROUND, dl, VT, Res,
865 DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
866 }
867 else
868 Res = DAG.getNode(ISD::BITCAST, dl, VT, Res);
869
870 Results.push_back(Res);
871}
872
873void VectorLegalizer::PromoteINT_TO_FP(SDNode *Node,
874 SmallVectorImpl<SDValue> &Results) {
875 // INT_TO_FP operations may require the input operand be promoted even
876 // when the type is otherwise legal.
877 bool IsStrict = Node->isStrictFPOpcode();
878 MVT VT = Node->getOperand(IsStrict ? 1 : 0).getSimpleValueType();
879 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
881 "Vectors have different number of elements!");
882
883 SDLoc dl(Node);
884 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
885
886 unsigned Opc = (Node->getOpcode() == ISD::UINT_TO_FP ||
887 Node->getOpcode() == ISD::STRICT_UINT_TO_FP)
890 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
891 if (Node->getOperand(j).getValueType().isVector())
892 Operands[j] = DAG.getNode(Opc, dl, NVT, Node->getOperand(j));
893 else
894 Operands[j] = Node->getOperand(j);
895 }
896
897 if (IsStrict) {
898 SDValue Res = DAG.getNode(Node->getOpcode(), dl,
899 {Node->getValueType(0), MVT::Other}, Operands);
900 Results.push_back(Res);
901 Results.push_back(Res.getValue(1));
902 return;
903 }
904
905 SDValue Res =
906 DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Operands);
907 Results.push_back(Res);
908}
909
910// For FP_TO_INT we promote the result type to a vector type with wider
911// elements and then truncate the result. This is different from the default
912// PromoteVector which uses bitcast to promote thus assumning that the
913// promoted vector type has the same overall size.
914void VectorLegalizer::PromoteFP_TO_INT(SDNode *Node,
915 SmallVectorImpl<SDValue> &Results) {
916 MVT VT = Node->getSimpleValueType(0);
917 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
918 bool IsStrict = Node->isStrictFPOpcode();
920 "Vectors have different number of elements!");
921
922 unsigned NewOpc = Node->getOpcode();
923 // Change FP_TO_UINT to FP_TO_SINT if possible.
924 // TODO: Should we only do this if FP_TO_UINT itself isn't legal?
925 if (NewOpc == ISD::FP_TO_UINT &&
927 NewOpc = ISD::FP_TO_SINT;
928
929 if (NewOpc == ISD::STRICT_FP_TO_UINT &&
931 NewOpc = ISD::STRICT_FP_TO_SINT;
932
933 SDLoc dl(Node);
934 SDValue Promoted, Chain;
935 if (IsStrict) {
936 Promoted = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
937 {Node->getOperand(0), Node->getOperand(1)});
938 Chain = Promoted.getValue(1);
939 } else
940 Promoted = DAG.getNode(NewOpc, dl, NVT, Node->getOperand(0));
941
942 // Assert that the converted value fits in the original type. If it doesn't
943 // (eg: because the value being converted is too big), then the result of the
944 // original operation was undefined anyway, so the assert is still correct.
945 if (Node->getOpcode() == ISD::FP_TO_UINT ||
946 Node->getOpcode() == ISD::STRICT_FP_TO_UINT)
947 NewOpc = ISD::AssertZext;
948 else
949 NewOpc = ISD::AssertSext;
950
951 Promoted = DAG.getNode(NewOpc, dl, NVT, Promoted,
952 DAG.getValueType(VT.getScalarType()));
953 Promoted = DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted);
954 Results.push_back(Promoted);
955 if (IsStrict)
956 Results.push_back(Chain);
957}
958
959std::pair<SDValue, SDValue> VectorLegalizer::ExpandLoad(SDNode *N) {
960 LoadSDNode *LD = cast<LoadSDNode>(N);
961 return TLI.scalarizeVectorLoad(LD, DAG);
962}
963
964SDValue VectorLegalizer::ExpandStore(SDNode *N) {
965 StoreSDNode *ST = cast<StoreSDNode>(N);
966 SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
967 return TF;
968}
969
970void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
971 switch (Node->getOpcode()) {
972 case ISD::LOAD: {
973 std::pair<SDValue, SDValue> Tmp = ExpandLoad(Node);
974 Results.push_back(Tmp.first);
975 Results.push_back(Tmp.second);
976 return;
977 }
978 case ISD::STORE:
979 Results.push_back(ExpandStore(Node));
980 return;
982 for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
983 Results.push_back(Node->getOperand(i));
984 return;
986 if (SDValue Expanded = ExpandSEXTINREG(Node)) {
987 Results.push_back(Expanded);
988 return;
989 }
990 break;
992 Results.push_back(ExpandANY_EXTEND_VECTOR_INREG(Node));
993 return;
995 Results.push_back(ExpandSIGN_EXTEND_VECTOR_INREG(Node));
996 return;
998 Results.push_back(ExpandZERO_EXTEND_VECTOR_INREG(Node));
999 return;
1000 case ISD::BSWAP:
1001 if (SDValue Expanded = ExpandBSWAP(Node)) {
1002 Results.push_back(Expanded);
1003 return;
1004 }
1005 break;
1006 case ISD::VP_BSWAP:
1007 Results.push_back(TLI.expandVPBSWAP(Node, DAG));
1008 return;
1009 case ISD::VSELECT:
1010 if (SDValue Expanded = ExpandVSELECT(Node)) {
1011 Results.push_back(Expanded);
1012 return;
1013 }
1014 break;
1015 case ISD::VP_SELECT:
1016 if (SDValue Expanded = ExpandVP_SELECT(Node)) {
1017 Results.push_back(Expanded);
1018 return;
1019 }
1020 break;
1021 case ISD::VP_SREM:
1022 case ISD::VP_UREM:
1023 if (SDValue Expanded = ExpandVP_REM(Node)) {
1024 Results.push_back(Expanded);
1025 return;
1026 }
1027 break;
1028 case ISD::VP_FNEG:
1029 if (SDValue Expanded = ExpandVP_FNEG(Node)) {
1030 Results.push_back(Expanded);
1031 return;
1032 }
1033 break;
1034 case ISD::VP_FABS:
1035 if (SDValue Expanded = ExpandVP_FABS(Node)) {
1036 Results.push_back(Expanded);
1037 return;
1038 }
1039 break;
1040 case ISD::VP_FCOPYSIGN:
1041 if (SDValue Expanded = ExpandVP_FCOPYSIGN(Node)) {
1042 Results.push_back(Expanded);
1043 return;
1044 }
1045 break;
1046 case ISD::SELECT:
1047 if (SDValue Expanded = ExpandSELECT(Node)) {
1048 Results.push_back(Expanded);
1049 return;
1050 }
1051 break;
1052 case ISD::SELECT_CC: {
1053 if (Node->getValueType(0).isScalableVector()) {
1054 EVT CondVT = TLI.getSetCCResultType(
1055 DAG.getDataLayout(), *DAG.getContext(), Node->getValueType(0));
1056 SDValue SetCC =
1057 DAG.getNode(ISD::SETCC, SDLoc(Node), CondVT, Node->getOperand(0),
1058 Node->getOperand(1), Node->getOperand(4));
1059 Results.push_back(DAG.getSelect(SDLoc(Node), Node->getValueType(0), SetCC,
1060 Node->getOperand(2),
1061 Node->getOperand(3)));
1062 return;
1063 }
1064 break;
1065 }
1066 case ISD::FP_TO_UINT:
1067 ExpandFP_TO_UINT(Node, Results);
1068 return;
1069 case ISD::UINT_TO_FP:
1070 ExpandUINT_TO_FLOAT(Node, Results);
1071 return;
1072 case ISD::FNEG:
1073 if (SDValue Expanded = ExpandFNEG(Node)) {
1074 Results.push_back(Expanded);
1075 return;
1076 }
1077 break;
1078 case ISD::FABS:
1079 if (SDValue Expanded = ExpandFABS(Node)) {
1080 Results.push_back(Expanded);
1081 return;
1082 }
1083 break;
1084 case ISD::FCOPYSIGN:
1085 if (SDValue Expanded = ExpandFCOPYSIGN(Node)) {
1086 Results.push_back(Expanded);
1087 return;
1088 }
1089 break;
1090 case ISD::FCANONICALIZE: {
1091 // If the scalar element type has a
1092 // Legal/Custom FCANONICALIZE, don't
1093 // mess with the vector, fall back.
1094 EVT VT = Node->getValueType(0);
1095 EVT EltVT = VT.getVectorElementType();
1096 if (!VT.isScalableVector() &&
1098 TargetLowering::Expand)
1099 break;
1100 // Otherwise canonicalize the whole vector.
1101 SDValue Mul = TLI.expandFCANONICALIZE(Node, DAG);
1102 Results.push_back(Mul);
1103 return;
1104 }
1105 case ISD::FSUB:
1106 ExpandFSUB(Node, Results);
1107 return;
1108 case ISD::SETCC:
1109 case ISD::VP_SETCC:
1110 ExpandSETCC(Node, Results);
1111 return;
1112 case ISD::ABS:
1114 if (SDValue Expanded = TLI.expandABS(Node, DAG)) {
1115 Results.push_back(Expanded);
1116 return;
1117 }
1118 break;
1119 case ISD::ABDS:
1120 case ISD::ABDU:
1121 if (SDValue Expanded = TLI.expandABD(Node, DAG)) {
1122 Results.push_back(Expanded);
1123 return;
1124 }
1125 break;
1126 case ISD::AVGCEILS:
1127 case ISD::AVGCEILU:
1128 case ISD::AVGFLOORS:
1129 case ISD::AVGFLOORU:
1130 if (SDValue Expanded = TLI.expandAVG(Node, DAG)) {
1131 Results.push_back(Expanded);
1132 return;
1133 }
1134 break;
1135 case ISD::BITREVERSE:
1136 if (SDValue Expanded = ExpandBITREVERSE(Node)) {
1137 Results.push_back(Expanded);
1138 return;
1139 }
1140 break;
1141 case ISD::VP_BITREVERSE:
1142 if (SDValue Expanded = TLI.expandVPBITREVERSE(Node, DAG)) {
1143 Results.push_back(Expanded);
1144 return;
1145 }
1146 break;
1147 case ISD::CTPOP:
1148 if (SDValue Expanded = TLI.expandCTPOP(Node, DAG)) {
1149 Results.push_back(Expanded);
1150 return;
1151 }
1152 break;
1153 case ISD::VP_CTPOP:
1154 if (SDValue Expanded = TLI.expandVPCTPOP(Node, DAG)) {
1155 Results.push_back(Expanded);
1156 return;
1157 }
1158 break;
1159 case ISD::CTLZ:
1161 if (SDValue Expanded = TLI.expandCTLZ(Node, DAG)) {
1162 Results.push_back(Expanded);
1163 return;
1164 }
1165 break;
1166 case ISD::VP_CTLZ:
1167 case ISD::VP_CTLZ_ZERO_POISON:
1168 if (SDValue Expanded = TLI.expandVPCTLZ(Node, DAG)) {
1169 Results.push_back(Expanded);
1170 return;
1171 }
1172 break;
1173 case ISD::CTTZ:
1175 if (SDValue Expanded = TLI.expandCTTZ(Node, DAG)) {
1176 Results.push_back(Expanded);
1177 return;
1178 }
1179 break;
1180 case ISD::VP_CTTZ:
1181 case ISD::VP_CTTZ_ZERO_POISON:
1182 if (SDValue Expanded = TLI.expandVPCTTZ(Node, DAG)) {
1183 Results.push_back(Expanded);
1184 return;
1185 }
1186 break;
1187 case ISD::FSHL:
1188 case ISD::VP_FSHL:
1189 case ISD::FSHR:
1190 case ISD::VP_FSHR:
1191 if (SDValue Expanded = TLI.expandFunnelShift(Node, DAG)) {
1192 Results.push_back(Expanded);
1193 return;
1194 }
1195 break;
1196 case ISD::CLMUL:
1197 case ISD::CLMULR:
1198 case ISD::CLMULH:
1199 if (SDValue Expanded = TLI.expandCLMUL(Node, DAG)) {
1200 Results.push_back(Expanded);
1201 return;
1202 }
1203 break;
1204 case ISD::PEXT:
1205 Results.push_back(TLI.expandPEXT(Node, DAG));
1206 return;
1207 case ISD::PDEP:
1208 Results.push_back(TLI.expandPDEP(Node, DAG));
1209 return;
1210 case ISD::ROTL:
1211 case ISD::ROTR:
1212 if (SDValue Expanded = TLI.expandROT(Node, false /*AllowVectorOps*/, DAG)) {
1213 Results.push_back(Expanded);
1214 return;
1215 }
1216 break;
1217 case ISD::FMINNUM:
1218 case ISD::FMAXNUM:
1219 if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG)) {
1220 Results.push_back(Expanded);
1221 return;
1222 }
1223 break;
1224 case ISD::FMINIMUM:
1225 case ISD::FMAXIMUM:
1226 Results.push_back(TLI.expandFMINIMUM_FMAXIMUM(Node, DAG));
1227 return;
1228 case ISD::FMINIMUMNUM:
1229 case ISD::FMAXIMUMNUM:
1230 Results.push_back(TLI.expandFMINIMUMNUM_FMAXIMUMNUM(Node, DAG));
1231 return;
1232 case ISD::SMIN:
1233 case ISD::SMAX:
1234 case ISD::UMIN:
1235 case ISD::UMAX:
1236 if (SDValue Expanded = TLI.expandIntMINMAX(Node, DAG)) {
1237 Results.push_back(Expanded);
1238 return;
1239 }
1240 break;
1241 case ISD::UADDO:
1242 case ISD::USUBO:
1243 ExpandUADDSUBO(Node, Results);
1244 return;
1245 case ISD::SADDO:
1246 case ISD::SSUBO:
1247 ExpandSADDSUBO(Node, Results);
1248 return;
1249 case ISD::UMULO:
1250 case ISD::SMULO:
1251 ExpandMULO(Node, Results);
1252 return;
1253 case ISD::USUBSAT:
1254 case ISD::SSUBSAT:
1255 case ISD::UADDSAT:
1256 case ISD::SADDSAT:
1257 if (SDValue Expanded = TLI.expandAddSubSat(Node, DAG)) {
1258 Results.push_back(Expanded);
1259 return;
1260 }
1261 break;
1262 case ISD::USHLSAT:
1263 case ISD::SSHLSAT:
1264 if (SDValue Expanded = TLI.expandShlSat(Node, DAG)) {
1265 Results.push_back(Expanded);
1266 return;
1267 }
1268 break;
1271 // Expand the fpsosisat if it is scalable to prevent it from unrolling below.
1272 if (Node->getValueType(0).isScalableVector()) {
1273 if (SDValue Expanded = TLI.expandFP_TO_INT_SAT(Node, DAG)) {
1274 Results.push_back(Expanded);
1275 return;
1276 }
1277 }
1278 break;
1279 case ISD::SMULFIX:
1280 case ISD::UMULFIX:
1281 if (SDValue Expanded = TLI.expandFixedPointMul(Node, DAG)) {
1282 Results.push_back(Expanded);
1283 return;
1284 }
1285 break;
1286 case ISD::SMULFIXSAT:
1287 case ISD::UMULFIXSAT:
1288 // FIXME: We do not expand SMULFIXSAT/UMULFIXSAT here yet, not sure exactly
1289 // why. Maybe it results in worse codegen compared to the unroll for some
1290 // targets? This should probably be investigated. And if we still prefer to
1291 // unroll an explanation could be helpful.
1292 break;
1293 case ISD::SDIVFIX:
1294 case ISD::UDIVFIX:
1295 ExpandFixedPointDiv(Node, Results);
1296 return;
1297 case ISD::SDIVFIXSAT:
1298 case ISD::UDIVFIXSAT:
1299 break;
1300#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1301 case ISD::STRICT_##DAGN:
1302#include "llvm/IR/ConstrainedOps.def"
1303 ExpandStrictFPOp(Node, Results);
1304 return;
1305 case ISD::VECREDUCE_ADD:
1306 case ISD::VECREDUCE_MUL:
1307 case ISD::VECREDUCE_AND:
1308 case ISD::VECREDUCE_OR:
1309 case ISD::VECREDUCE_XOR:
1320 Results.push_back(TLI.expandVecReduce(Node, DAG));
1321 return;
1326 Results.push_back(TLI.expandPartialReduceMLA(Node, DAG));
1327 return;
1330 Results.push_back(TLI.expandVecReduceSeq(Node, DAG));
1331 return;
1332 case ISD::SREM:
1333 case ISD::UREM:
1334 ExpandREM(Node, Results);
1335 return;
1336 case ISD::VP_MERGE:
1337 if (SDValue Expanded = ExpandVP_MERGE(Node)) {
1338 Results.push_back(Expanded);
1339 return;
1340 }
1341 break;
1342 case ISD::FREM: {
1343 RTLIB::Libcall LC = RTLIB::getREM(Node->getValueType(0));
1344 if (tryExpandVecMathCall(Node, LC, Results))
1345 return;
1346
1347 break;
1348 }
1349 case ISD::FSINCOS:
1350 case ISD::FSINCOSPI: {
1351 EVT VT = Node->getValueType(0);
1352 RTLIB::Libcall LC = Node->getOpcode() == ISD::FSINCOS
1353 ? RTLIB::getSINCOS(VT)
1354 : RTLIB::getSINCOSPI(VT);
1355 if (LC != RTLIB::UNKNOWN_LIBCALL &&
1356 TLI.expandMultipleResultFPLibCall(DAG, LC, Node, Results))
1357 return;
1358
1359 // TODO: Try to see if there's a narrower call available to use before
1360 // scalarizing.
1361 break;
1362 }
1363 case ISD::FPOW: {
1364 RTLIB::Libcall LC = RTLIB::getPOW(Node->getValueType(0));
1365 if (tryExpandVecMathCall(Node, LC, Results))
1366 return;
1367
1368 // TODO: Try to see if there's a narrower call available to use before
1369 // scalarizing.
1370 break;
1371 }
1372 case ISD::FCBRT: {
1373 RTLIB::Libcall LC = RTLIB::getCBRT(Node->getValueType(0));
1374 if (tryExpandVecMathCall(Node, LC, Results))
1375 return;
1376
1377 // TODO: Try to see if there's a narrower call available to use before
1378 // scalarizing.
1379 break;
1380 }
1381 case ISD::FMODF: {
1382 EVT VT = Node->getValueType(0);
1383 RTLIB::Libcall LC = RTLIB::getMODF(VT);
1384 if (LC != RTLIB::UNKNOWN_LIBCALL &&
1385 TLI.expandMultipleResultFPLibCall(DAG, LC, Node, Results,
1386 /*CallRetResNo=*/0))
1387 return;
1388 break;
1389 }
1391 Results.push_back(TLI.expandVECTOR_COMPRESS(Node, DAG));
1392 return;
1393 case ISD::CTTZ_ELTS:
1395 Results.push_back(TLI.expandCttzElts(Node, DAG));
1396 return;
1398 Results.push_back(TLI.expandVectorFindLastActive(Node, DAG));
1399 return;
1400 case ISD::SCMP:
1401 case ISD::UCMP:
1402 Results.push_back(TLI.expandCMP(Node, DAG));
1403 return;
1406 Results.push_back(ExpandLOOP_DEPENDENCE_MASK(Node));
1407 return;
1408
1409 case ISD::FADD:
1410 case ISD::FMUL:
1411 case ISD::FMA:
1412 case ISD::FDIV:
1413 case ISD::FCEIL:
1414 case ISD::FFLOOR:
1415 case ISD::FNEARBYINT:
1416 case ISD::FRINT:
1417 case ISD::FROUND:
1418 case ISD::FROUNDEVEN:
1419 case ISD::FTRUNC:
1420 case ISD::FSQRT:
1421 if (SDValue Expanded = TLI.expandVectorNaryOpBySplitting(Node, DAG)) {
1422 Results.push_back(Expanded);
1423 return;
1424 }
1425 break;
1427 if (SDValue Expanded = TLI.expandCONVERT_TO_ARBITRARY_FP(Node, DAG))
1428 Results.push_back(Expanded);
1429 else
1430 Results.push_back(DAG.getPOISON(Node->getValueType(0)));
1431 return;
1433 if (SDValue Expanded = TLI.expandCONVERT_FROM_ARBITRARY_FP(Node, DAG))
1434 Results.push_back(Expanded);
1435 else
1436 Results.push_back(DAG.getPOISON(Node->getValueType(0)));
1437 return;
1438 case ISD::MASKED_UDIV:
1439 case ISD::MASKED_SDIV:
1440 case ISD::MASKED_UREM:
1441 case ISD::MASKED_SREM:
1442 Results.push_back(ExpandMaskedBinOp(Node));
1443 return;
1444 }
1445
1446 SDValue Unrolled = DAG.UnrollVectorOp(Node);
1447 if (Node->getNumValues() == 1) {
1448 Results.push_back(Unrolled);
1449 } else {
1450 assert(Node->getNumValues() == Unrolled->getNumValues() &&
1451 "VectorLegalizer Expand returned wrong number of results!");
1452 for (unsigned I = 0, E = Unrolled->getNumValues(); I != E; ++I)
1453 Results.push_back(Unrolled.getValue(I));
1454 }
1455}
1456
1457SDValue VectorLegalizer::ExpandSELECT(SDNode *Node) {
1458 // Lower a select instruction where the condition is a scalar and the
1459 // operands are vectors. Lower this select to VSELECT and implement it
1460 // using XOR AND OR. The selector bit is broadcasted.
1461 EVT VT = Node->getValueType(0);
1462 SDLoc DL(Node);
1463
1464 SDValue Mask = Node->getOperand(0);
1465 SDValue Op1 = Node->getOperand(1);
1466 SDValue Op2 = Node->getOperand(2);
1467
1468 assert(VT.isVector() && !Mask.getValueType().isVector()
1469 && Op1.getValueType() == Op2.getValueType() && "Invalid type");
1470
1471 // If we can't even use the basic vector operations of
1472 // AND,OR,XOR, we will have to scalarize the op.
1473 // Notice that the operation may be 'promoted' which means that it is
1474 // 'bitcasted' to another type which is handled.
1475 // Also, we need to be able to construct a splat vector using either
1476 // BUILD_VECTOR or SPLAT_VECTOR.
1477 // FIXME: Should we also permit fixed-length SPLAT_VECTOR as a fallback to
1478 // BUILD_VECTOR?
1479 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1480 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1481 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
1484 VT) == TargetLowering::Expand)
1485 return SDValue();
1486
1487 // Generate a mask operand.
1488 EVT MaskTy = VT.changeVectorElementTypeToInteger();
1489
1490 // What is the size of each element in the vector mask.
1491 EVT BitTy = MaskTy.getScalarType();
1492
1493 Mask = DAG.getSelect(DL, BitTy, Mask, DAG.getAllOnesConstant(DL, BitTy),
1494 DAG.getConstant(0, DL, BitTy));
1495
1496 // Broadcast the mask so that the entire vector is all one or all zero.
1497 Mask = DAG.getSplat(MaskTy, DL, Mask);
1498
1499 // Bitcast the operands to be the same type as the mask.
1500 // This is needed when we select between FP types because
1501 // the mask is a vector of integers.
1502 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1);
1503 Op2 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op2);
1504
1505 SDValue NotMask = DAG.getNOT(DL, Mask, MaskTy);
1506
1507 Op1 = DAG.getNode(ISD::AND, DL, MaskTy, Op1, Mask);
1508 Op2 = DAG.getNode(ISD::AND, DL, MaskTy, Op2, NotMask);
1509 SDValue Val = DAG.getNode(ISD::OR, DL, MaskTy, Op1, Op2);
1510 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1511}
1512
1513SDValue VectorLegalizer::ExpandSEXTINREG(SDNode *Node) {
1514 EVT VT = Node->getValueType(0);
1515
1516 // Make sure that the SRA and SHL instructions are available.
1517 if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Expand ||
1518 TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Expand)
1519 return SDValue();
1520
1521 SDLoc DL(Node);
1522 EVT OrigTy = cast<VTSDNode>(Node->getOperand(1))->getVT();
1523
1524 unsigned BW = VT.getScalarSizeInBits();
1525 unsigned OrigBW = OrigTy.getScalarSizeInBits();
1526 SDValue ShiftSz = DAG.getConstant(BW - OrigBW, DL, VT);
1527
1528 SDValue Op = DAG.getNode(ISD::SHL, DL, VT, Node->getOperand(0), ShiftSz);
1529 return DAG.getNode(ISD::SRA, DL, VT, Op, ShiftSz);
1530}
1531
1532// Generically expand a vector anyext in register to a shuffle of the relevant
1533// lanes into the appropriate locations, with other lanes left undef.
1534SDValue VectorLegalizer::ExpandANY_EXTEND_VECTOR_INREG(SDNode *Node) {
1535 SDLoc DL(Node);
1536 EVT VT = Node->getValueType(0);
1537 int NumElements = VT.getVectorNumElements();
1538 SDValue Src = Node->getOperand(0);
1539 EVT SrcVT = Src.getValueType();
1540 int NumSrcElements = SrcVT.getVectorNumElements();
1541
1542 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1543 // into a larger vector type.
1544 if (SrcVT.bitsLE(VT)) {
1545 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1546 "ANY_EXTEND_VECTOR_INREG vector size mismatch");
1547 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1548 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1549 NumSrcElements);
1550 Src = DAG.getInsertSubvector(DL, DAG.getUNDEF(SrcVT), Src, 0);
1551 }
1552
1553 // Build a base mask of undef shuffles.
1554 SmallVector<int, 16> ShuffleMask;
1555 ShuffleMask.resize(NumSrcElements, -1);
1556
1557 // Place the extended lanes into the correct locations.
1558 int ExtLaneScale = NumSrcElements / NumElements;
1559 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1560 for (int i = 0; i < NumElements; ++i)
1561 ShuffleMask[i * ExtLaneScale + EndianOffset] = i;
1562
1563 return DAG.getNode(
1564 ISD::BITCAST, DL, VT,
1565 DAG.getVectorShuffle(SrcVT, DL, Src, DAG.getPOISON(SrcVT), ShuffleMask));
1566}
1567
1568SDValue VectorLegalizer::ExpandSIGN_EXTEND_VECTOR_INREG(SDNode *Node) {
1569 SDLoc DL(Node);
1570 EVT VT = Node->getValueType(0);
1571 SDValue Src = Node->getOperand(0);
1572 EVT SrcVT = Src.getValueType();
1573
1574 // First build an any-extend node which can be legalized above when we
1575 // recurse through it.
1577
1578 // Now we need sign extend. This will be exanded to shifts if it isn't
1579 // supported.
1580 EVT ExtVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getVectorElementType(),
1582 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Op,
1583 DAG.getValueType(ExtVT));
1584}
1585
1586// Generically expand a vector zext in register to a shuffle of the relevant
1587// lanes into the appropriate locations, a blend of zero into the high bits,
1588// and a bitcast to the wider element type.
1589SDValue VectorLegalizer::ExpandZERO_EXTEND_VECTOR_INREG(SDNode *Node) {
1590 SDLoc DL(Node);
1591 EVT VT = Node->getValueType(0);
1592 int NumElements = VT.getVectorNumElements();
1593 SDValue Src = Node->getOperand(0);
1594 EVT SrcVT = Src.getValueType();
1595 int NumSrcElements = SrcVT.getVectorNumElements();
1596
1597 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1598 // into a larger vector type.
1599 if (SrcVT.bitsLE(VT)) {
1600 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1601 "ZERO_EXTEND_VECTOR_INREG vector size mismatch");
1602 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1603 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1604 NumSrcElements);
1605 Src = DAG.getInsertSubvector(DL, DAG.getUNDEF(SrcVT), Src, 0);
1606 }
1607
1608 // Build up a zero vector to blend into this one.
1609 SDValue Zero = DAG.getConstant(0, DL, SrcVT);
1610
1611 // Shuffle the incoming lanes into the correct position, and pull all other
1612 // lanes from the zero vector.
1613 auto ShuffleMask = llvm::to_vector<16>(llvm::seq<int>(0, NumSrcElements));
1614
1615 int ExtLaneScale = NumSrcElements / NumElements;
1616 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1617 for (int i = 0; i < NumElements; ++i)
1618 ShuffleMask[i * ExtLaneScale + EndianOffset] = NumSrcElements + i;
1619
1620 return DAG.getNode(ISD::BITCAST, DL, VT,
1621 DAG.getVectorShuffle(SrcVT, DL, Zero, Src, ShuffleMask));
1622}
1623
1624static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) {
1625 int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;
1626 for (int I = 0, E = VT.getVectorNumElements(); I != E; ++I)
1627 for (int J = ScalarSizeInBytes - 1; J >= 0; --J)
1628 ShuffleMask.push_back((I * ScalarSizeInBytes) + J);
1629}
1630
1631SDValue VectorLegalizer::ExpandBSWAP(SDNode *Node) {
1632 EVT VT = Node->getValueType(0);
1633
1634 // Scalable vectors can't use shuffle expansion.
1635 if (VT.isScalableVector())
1636 return TLI.expandBSWAP(Node, DAG);
1637
1638 // Generate a byte wise shuffle mask for the BSWAP.
1639 SmallVector<int, 16> ShuffleMask;
1640 createBSWAPShuffleMask(VT, ShuffleMask);
1641 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, ShuffleMask.size());
1642
1643 // Only emit a shuffle if the mask is legal.
1644 if (TLI.isShuffleMaskLegal(ShuffleMask, ByteVT)) {
1645 SDLoc DL(Node);
1646 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1647 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getPOISON(ByteVT),
1648 ShuffleMask);
1649 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
1650 }
1651
1652 // If we have the appropriate vector bit operations, it is better to use them
1653 // than unrolling and expanding each component.
1654 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1658 return TLI.expandBSWAP(Node, DAG);
1659
1660 // Otherwise let the caller unroll.
1661 return SDValue();
1662}
1663
1664SDValue VectorLegalizer::ExpandBITREVERSE(SDNode *Node) {
1665 EVT VT = Node->getValueType(0);
1666
1667 // We can't unroll or use shuffles for scalable vectors.
1668 if (VT.isScalableVector())
1669 return TLI.expandBITREVERSE(Node, DAG);
1670
1671 // If we have the scalar operation, it's probably cheaper to unroll it.
1673 return SDValue();
1674
1675 // If the vector element width is a whole number of bytes, test if its legal
1676 // to BSWAP shuffle the bytes and then perform the BITREVERSE on the byte
1677 // vector. This greatly reduces the number of bit shifts necessary.
1678 unsigned ScalarSizeInBits = VT.getScalarSizeInBits();
1679 if (ScalarSizeInBits > 8 && (ScalarSizeInBits % 8) == 0) {
1680 SmallVector<int, 16> BSWAPMask;
1681 createBSWAPShuffleMask(VT, BSWAPMask);
1682
1683 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, BSWAPMask.size());
1684 if (TLI.isShuffleMaskLegal(BSWAPMask, ByteVT) &&
1686 (TLI.isOperationLegalOrCustom(ISD::SHL, ByteVT) &&
1687 TLI.isOperationLegalOrCustom(ISD::SRL, ByteVT) &&
1690 SDLoc DL(Node);
1691 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1692 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getPOISON(ByteVT),
1693 BSWAPMask);
1694 Op = DAG.getNode(ISD::BITREVERSE, DL, ByteVT, Op);
1695 Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
1696 return Op;
1697 }
1698 }
1699
1700 // If we have the appropriate vector bit operations, it is better to use them
1701 // than unrolling and expanding each component.
1702 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1706 return TLI.expandBITREVERSE(Node, DAG);
1707
1708 // Otherwise unroll.
1709 return SDValue();
1710}
1711
1712SDValue VectorLegalizer::ExpandVSELECT(SDNode *Node) {
1713 // Implement VSELECT in terms of XOR, AND, OR
1714 // on platforms which do not support blend natively.
1715 SDLoc DL(Node);
1716
1717 SDValue Mask = Node->getOperand(0);
1718 SDValue Op1 = Node->getOperand(1);
1719 SDValue Op2 = Node->getOperand(2);
1720
1721 EVT VT = Mask.getValueType();
1722
1723 // If we can't even use the basic vector operations of
1724 // AND,OR,XOR, we will have to scalarize the op.
1725 // Notice that the operation may be 'promoted' which means that it is
1726 // 'bitcasted' to another type which is handled.
1727 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1728 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1729 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand)
1730 return SDValue();
1731
1732 // This operation also isn't safe with AND, OR, XOR when the boolean type is
1733 // 0/1 and the select operands aren't also booleans, as we need an all-ones
1734 // vector constant to mask with.
1735 // FIXME: Sign extend 1 to all ones if that's legal on the target.
1736 auto BoolContents = TLI.getBooleanContents(Op1.getValueType());
1737 if (BoolContents != TargetLowering::ZeroOrNegativeOneBooleanContent &&
1738 !(BoolContents == TargetLowering::ZeroOrOneBooleanContent &&
1739 Op1.getValueType().getVectorElementType() == MVT::i1))
1740 return SDValue();
1741
1742 // If the mask and the type are different sizes, unroll the vector op. This
1743 // can occur when getSetCCResultType returns something that is different in
1744 // size from the operand types. For example, v4i8 = select v4i32, v4i8, v4i8.
1745 if (VT.getSizeInBits() != Op1.getValueSizeInBits())
1746 return SDValue();
1747
1748 // Bitcast the operands to be the same type as the mask.
1749 // This is needed when we select between FP types because
1750 // the mask is a vector of integers.
1751 Op1 = DAG.getNode(ISD::BITCAST, DL, VT, Op1);
1752 Op2 = DAG.getNode(ISD::BITCAST, DL, VT, Op2);
1753
1754 SDValue NotMask = DAG.getNOT(DL, Mask, VT);
1755
1756 Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask);
1757 Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask);
1758 SDValue Val = DAG.getNode(ISD::OR, DL, VT, Op1, Op2);
1759 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1760}
1761
1762SDValue VectorLegalizer::ExpandVP_SELECT(SDNode *Node) {
1763 // Implement VP_SELECT in terms of VP_XOR, VP_AND and VP_OR on platforms which
1764 // do not support it natively.
1765 SDLoc DL(Node);
1766
1767 SDValue Mask = Node->getOperand(0);
1768 SDValue Op1 = Node->getOperand(1);
1769 SDValue Op2 = Node->getOperand(2);
1770 SDValue EVL = Node->getOperand(3);
1771
1772 EVT VT = Mask.getValueType();
1773
1774 // If we can't even use the basic vector operations of
1775 // VP_AND,VP_OR,VP_XOR, we will have to scalarize the op.
1776 if (TLI.getOperationAction(ISD::VP_AND, VT) == TargetLowering::Expand ||
1777 TLI.getOperationAction(ISD::VP_XOR, VT) == TargetLowering::Expand ||
1778 TLI.getOperationAction(ISD::VP_OR, VT) == TargetLowering::Expand)
1779 return SDValue();
1780
1781 // This operation also isn't safe when the operands aren't also booleans.
1782 if (Op1.getValueType().getVectorElementType() != MVT::i1)
1783 return SDValue();
1784
1785 SDValue Ones = DAG.getAllOnesConstant(DL, VT);
1786 SDValue NotMask = DAG.getNode(ISD::VP_XOR, DL, VT, Mask, Ones, Ones, EVL);
1787
1788 Op1 = DAG.getNode(ISD::VP_AND, DL, VT, Op1, Mask, Ones, EVL);
1789 Op2 = DAG.getNode(ISD::VP_AND, DL, VT, Op2, NotMask, Ones, EVL);
1790 return DAG.getNode(ISD::VP_OR, DL, VT, Op1, Op2, Ones, EVL);
1791}
1792
1793SDValue VectorLegalizer::ExpandVP_MERGE(SDNode *Node) {
1794 // Implement VP_MERGE in terms of VSELECT. Construct a mask where vector
1795 // indices less than the EVL/pivot are true. Combine that with the original
1796 // mask for a full-length mask. Use a full-length VSELECT to select between
1797 // the true and false values.
1798 SDLoc DL(Node);
1799
1800 SDValue Mask = Node->getOperand(0);
1801 SDValue Op1 = Node->getOperand(1);
1802 SDValue Op2 = Node->getOperand(2);
1803 SDValue EVL = Node->getOperand(3);
1804
1805 EVT MaskVT = Mask.getValueType();
1806 bool IsFixedLen = MaskVT.isFixedLengthVector();
1807
1808 EVT EVLVecVT = EVT::getVectorVT(*DAG.getContext(), EVL.getValueType(),
1809 MaskVT.getVectorElementCount());
1810
1811 // If we can't construct the EVL mask efficiently, it's better to unroll.
1812 if ((IsFixedLen &&
1814 (!IsFixedLen &&
1815 (!TLI.isOperationLegalOrCustom(ISD::STEP_VECTOR, EVLVecVT) ||
1817 return SDValue();
1818
1819 // If using a SETCC would result in a different type than the mask type,
1820 // unroll.
1821 if (TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
1822 EVLVecVT) != MaskVT)
1823 return SDValue();
1824
1825 SDValue StepVec = DAG.getStepVector(DL, EVLVecVT);
1826 SDValue SplatEVL = DAG.getSplat(EVLVecVT, DL, EVL);
1827 SDValue EVLMask =
1828 DAG.getSetCC(DL, MaskVT, StepVec, SplatEVL, ISD::CondCode::SETULT);
1829
1830 SDValue FullMask = DAG.getNode(ISD::AND, DL, MaskVT, Mask, EVLMask);
1831 return DAG.getSelect(DL, Node->getValueType(0), FullMask, Op1, Op2);
1832}
1833
1834SDValue VectorLegalizer::ExpandVP_REM(SDNode *Node) {
1835 // Implement VP_SREM/UREM in terms of VP_SDIV/VP_UDIV, VP_MUL, VP_SUB.
1836 EVT VT = Node->getValueType(0);
1837
1838 unsigned DivOpc = Node->getOpcode() == ISD::VP_SREM ? ISD::VP_SDIV : ISD::VP_UDIV;
1839
1840 if (!TLI.isOperationLegalOrCustom(DivOpc, VT) ||
1841 !TLI.isOperationLegalOrCustom(ISD::VP_MUL, VT) ||
1842 !TLI.isOperationLegalOrCustom(ISD::VP_SUB, VT))
1843 return SDValue();
1844
1845 SDLoc DL(Node);
1846
1847 SDValue Dividend = Node->getOperand(0);
1848 SDValue Divisor = Node->getOperand(1);
1849 SDValue Mask = Node->getOperand(2);
1850 SDValue EVL = Node->getOperand(3);
1851
1852 // X % Y -> X-X/Y*Y
1853 SDValue Div = DAG.getNode(DivOpc, DL, VT, Dividend, Divisor, Mask, EVL);
1854 SDValue Mul = DAG.getNode(ISD::VP_MUL, DL, VT, Divisor, Div, Mask, EVL);
1855 return DAG.getNode(ISD::VP_SUB, DL, VT, Dividend, Mul, Mask, EVL);
1856}
1857
1858SDValue VectorLegalizer::ExpandVP_FNEG(SDNode *Node) {
1859 EVT VT = Node->getValueType(0);
1860 EVT IntVT = VT.changeVectorElementTypeToInteger();
1861
1862 if (!TLI.isOperationLegalOrCustom(ISD::VP_XOR, IntVT))
1863 return SDValue();
1864
1865 SDValue Mask = Node->getOperand(1);
1866 SDValue EVL = Node->getOperand(2);
1867
1868 SDLoc DL(Node);
1869 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1870 SDValue SignMask = DAG.getConstant(
1871 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
1872 SDValue Xor = DAG.getNode(ISD::VP_XOR, DL, IntVT, Cast, SignMask, Mask, EVL);
1873 return DAG.getNode(ISD::BITCAST, DL, VT, Xor);
1874}
1875
1876SDValue VectorLegalizer::ExpandVP_FABS(SDNode *Node) {
1877 EVT VT = Node->getValueType(0);
1878 EVT IntVT = VT.changeVectorElementTypeToInteger();
1879
1880 if (!TLI.isOperationLegalOrCustom(ISD::VP_AND, IntVT))
1881 return SDValue();
1882
1883 SDValue Mask = Node->getOperand(1);
1884 SDValue EVL = Node->getOperand(2);
1885
1886 SDLoc DL(Node);
1887 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1888 SDValue ClearSignMask = DAG.getConstant(
1890 SDValue ClearSign =
1891 DAG.getNode(ISD::VP_AND, DL, IntVT, Cast, ClearSignMask, Mask, EVL);
1892 return DAG.getNode(ISD::BITCAST, DL, VT, ClearSign);
1893}
1894
1895SDValue VectorLegalizer::ExpandVP_FCOPYSIGN(SDNode *Node) {
1896 EVT VT = Node->getValueType(0);
1897
1898 if (VT != Node->getOperand(1).getValueType())
1899 return SDValue();
1900
1901 EVT IntVT = VT.changeVectorElementTypeToInteger();
1902 if (!TLI.isOperationLegalOrCustom(ISD::VP_AND, IntVT) ||
1903 !TLI.isOperationLegalOrCustom(ISD::VP_XOR, IntVT))
1904 return SDValue();
1905
1906 SDValue Mask = Node->getOperand(2);
1907 SDValue EVL = Node->getOperand(3);
1908
1909 SDLoc DL(Node);
1910 SDValue Mag = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1911 SDValue Sign = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(1));
1912
1913 SDValue SignMask = DAG.getConstant(
1914 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
1915 SDValue SignBit =
1916 DAG.getNode(ISD::VP_AND, DL, IntVT, Sign, SignMask, Mask, EVL);
1917
1918 SDValue ClearSignMask = DAG.getConstant(
1920 SDValue ClearedSign =
1921 DAG.getNode(ISD::VP_AND, DL, IntVT, Mag, ClearSignMask, Mask, EVL);
1922
1923 SDValue CopiedSign = DAG.getNode(ISD::VP_OR, DL, IntVT, ClearedSign, SignBit,
1924 Mask, EVL, SDNodeFlags::Disjoint);
1925
1926 return DAG.getNode(ISD::BITCAST, DL, VT, CopiedSign);
1927}
1928
1929SDValue VectorLegalizer::ExpandLOOP_DEPENDENCE_MASK(SDNode *N) {
1930 return TLI.expandLoopDependenceMask(N, DAG);
1931}
1932
1933SDValue VectorLegalizer::ExpandMaskedBinOp(SDNode *N) {
1934 // Masked bin ops don't have undefined behaviour when dividing by zero
1935 // on disabled lanes and produce poison instead. Replace the divisor on the
1936 // disabled lanes with 1 to avoid division by zero or overflow.
1937 SDLoc dl(N);
1938 EVT VT = N->getValueType(0);
1939 SDValue SafeDivisor = DAG.getSelect(
1940 dl, VT, N->getOperand(2), N->getOperand(1), DAG.getConstant(1, dl, VT));
1941 return DAG.getNode(ISD::getUnmaskedBinOpOpcode(N->getOpcode()), dl, VT,
1942 N->getOperand(0), SafeDivisor);
1943}
1944
1945void VectorLegalizer::ExpandFP_TO_UINT(SDNode *Node,
1946 SmallVectorImpl<SDValue> &Results) {
1947 // Attempt to expand using TargetLowering.
1948 SDValue Result, Chain;
1949 if (TLI.expandFP_TO_UINT(Node, Result, Chain, DAG)) {
1950 Results.push_back(Result);
1951 if (Node->isStrictFPOpcode())
1952 Results.push_back(Chain);
1953 return;
1954 }
1955
1956 // Otherwise go ahead and unroll.
1957 if (Node->isStrictFPOpcode()) {
1958 UnrollStrictFPOp(Node, Results);
1959 return;
1960 }
1961
1962 Results.push_back(DAG.UnrollVectorOp(Node));
1963}
1964
1965void VectorLegalizer::ExpandUINT_TO_FLOAT(SDNode *Node,
1966 SmallVectorImpl<SDValue> &Results) {
1967 bool IsStrict = Node->isStrictFPOpcode();
1968 unsigned OpNo = IsStrict ? 1 : 0;
1969 SDValue Src = Node->getOperand(OpNo);
1970 EVT SrcVT = Src.getValueType();
1971 EVT DstVT = Node->getValueType(0);
1972 SDLoc DL(Node);
1973
1974 // Attempt to expand using TargetLowering.
1976 SDValue Chain;
1977 if (TLI.expandUINT_TO_FP(Node, Result, Chain, DAG)) {
1978 Results.push_back(Result);
1979 if (IsStrict)
1980 Results.push_back(Chain);
1981 return;
1982 }
1983
1984 // Make sure that the SINT_TO_FP and SRL instructions are available.
1985 if (((!IsStrict && TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) ==
1986 TargetLowering::Expand) ||
1987 (IsStrict && TLI.getOperationAction(ISD::STRICT_SINT_TO_FP, SrcVT) ==
1988 TargetLowering::Expand)) ||
1989 TLI.getOperationAction(ISD::SRL, SrcVT) == TargetLowering::Expand) {
1990 if (IsStrict) {
1991 UnrollStrictFPOp(Node, Results);
1992 return;
1993 }
1994
1995 Results.push_back(DAG.UnrollVectorOp(Node));
1996 return;
1997 }
1998
1999 unsigned BW = SrcVT.getScalarSizeInBits();
2000 assert((BW == 64 || BW == 32) &&
2001 "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide");
2002
2003 // If STRICT_/FMUL is not supported by the target (in case of f16) replace the
2004 // UINT_TO_FP with a larger float and round to the smaller type
2005 if ((!IsStrict && !TLI.isOperationLegalOrCustom(ISD::FMUL, DstVT)) ||
2006 (IsStrict && !TLI.isOperationLegalOrCustom(ISD::STRICT_FMUL, DstVT))) {
2007 EVT FPVT = BW == 32 ? MVT::f32 : MVT::f64;
2008 SDValue UIToFP;
2010 SDValue TargetZero = DAG.getIntPtrConstant(0, DL, /*isTarget=*/true);
2011 EVT FloatVecVT = SrcVT.changeVectorElementType(*DAG.getContext(), FPVT);
2012 if (IsStrict) {
2013 UIToFP = DAG.getNode(ISD::STRICT_UINT_TO_FP, DL, {FloatVecVT, MVT::Other},
2014 {Node->getOperand(0), Src});
2015 Result = DAG.getNode(ISD::STRICT_FP_ROUND, DL, {DstVT, MVT::Other},
2016 {Node->getOperand(0), UIToFP, TargetZero});
2017 Results.push_back(Result);
2018 Results.push_back(Result.getValue(1));
2019 } else {
2020 UIToFP = DAG.getNode(ISD::UINT_TO_FP, DL, FloatVecVT, Src);
2021 Result = DAG.getNode(ISD::FP_ROUND, DL, DstVT, UIToFP, TargetZero);
2022 Results.push_back(Result);
2023 }
2024
2025 return;
2026 }
2027
2028 SDValue HalfWord = DAG.getConstant(BW / 2, DL, SrcVT);
2029
2030 // Constants to clear the upper part of the word.
2031 // Notice that we can also use SHL+SHR, but using a constant is slightly
2032 // faster on x86.
2033 uint64_t HWMask = (BW == 64) ? 0x00000000FFFFFFFF : 0x0000FFFF;
2034 SDValue HalfWordMask = DAG.getConstant(HWMask, DL, SrcVT);
2035
2036 // Two to the power of half-word-size.
2037 SDValue TWOHW = DAG.getConstantFP(1ULL << (BW / 2), DL, DstVT);
2038
2039 // Clear upper part of LO, lower HI
2040 SDValue HI = DAG.getNode(ISD::SRL, DL, SrcVT, Src, HalfWord);
2041 SDValue LO = DAG.getNode(ISD::AND, DL, SrcVT, Src, HalfWordMask);
2042
2043 if (IsStrict) {
2044 // Convert hi and lo to floats
2045 // Convert the hi part back to the upper values
2046 // TODO: Can any fast-math-flags be set on these nodes?
2047 SDValue fHI = DAG.getNode(ISD::STRICT_SINT_TO_FP, DL, {DstVT, MVT::Other},
2048 {Node->getOperand(0), HI});
2049 fHI = DAG.getNode(ISD::STRICT_FMUL, DL, {DstVT, MVT::Other},
2050 {fHI.getValue(1), fHI, TWOHW});
2051 SDValue fLO = DAG.getNode(ISD::STRICT_SINT_TO_FP, DL, {DstVT, MVT::Other},
2052 {Node->getOperand(0), LO});
2053
2054 SDValue TF = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, fHI.getValue(1),
2055 fLO.getValue(1));
2056
2057 // Add the two halves
2058 SDValue Result =
2059 DAG.getNode(ISD::STRICT_FADD, DL, {DstVT, MVT::Other}, {TF, fHI, fLO});
2060
2061 Results.push_back(Result);
2062 Results.push_back(Result.getValue(1));
2063 return;
2064 }
2065
2066 // Convert hi and lo to floats
2067 // Convert the hi part back to the upper values
2068 // TODO: Can any fast-math-flags be set on these nodes?
2069 SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, DstVT, HI);
2070 fHI = DAG.getNode(ISD::FMUL, DL, DstVT, fHI, TWOHW);
2071 SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, DstVT, LO);
2072
2073 // Add the two halves
2074 Results.push_back(DAG.getNode(ISD::FADD, DL, DstVT, fHI, fLO));
2075}
2076
2077SDValue VectorLegalizer::ExpandFNEG(SDNode *Node) {
2078 EVT VT = Node->getValueType(0);
2079 EVT IntVT = VT.changeVectorElementTypeToInteger();
2080
2081 if (!TLI.isOperationLegalOrCustom(ISD::XOR, IntVT))
2082 return SDValue();
2083
2084 // Heuristic check to determine whether vector should be expanded to integer
2085 // operations or unrolled to scalar operations.
2086 // 1. Scalable vector is never unrolled.
2087 // 2. Fixed vector is unrolled if one of followings is true:
2088 // a. Vector only has 1 element and target knows how to handle scalar
2089 // FNEG (either legal or custom expand or promote).
2090 // b. Vector has more than 1 element and target supports scalar
2091 // FNEG natively and vector length <= 2(1 XOR + 1 CONST).
2092 // FIXME: Scalar construction instruction count varies in every architecture,
2093 // here we assume 1 instruction for now.
2094 if (VT.isFixedLengthVector()) {
2095 EVT EltVT = VT.getVectorElementType();
2096 unsigned NumElts = VT.getVectorNumElements();
2097 if ((NumElts == 1 &&
2099 (NumElts < 3 && TLI.isOperationLegal(ISD::FNEG, EltVT) &&
2100 TLI.isExtractVecEltCheap(VT, 0) &&
2101 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
2102 return SDValue();
2103 }
2104
2105 SDLoc DL(Node);
2106 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
2107 SDValue SignMask = DAG.getConstant(
2108 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
2109 SDValue Xor = DAG.getNode(ISD::XOR, DL, IntVT, Cast, SignMask);
2110 return DAG.getNode(ISD::BITCAST, DL, VT, Xor);
2111}
2112
2113SDValue VectorLegalizer::ExpandFABS(SDNode *Node) {
2114 EVT VT = Node->getValueType(0);
2115 EVT IntVT = VT.changeVectorElementTypeToInteger();
2116
2117 if (!TLI.isOperationLegalOrCustom(ISD::AND, IntVT))
2118 return SDValue();
2119
2120 // Heuristic check to determine whether vector should be expanded to integer
2121 // operations or unrolled to scalar operations.
2122 // 1. Scalable vector is never unrolled.
2123 // 2. Fixed vector is unrolled if one of followings is true:
2124 // a. Vector only has 1 element and target knows how to handle scalar
2125 // FABS(either legal or custom expand or promote).
2126 // b. Vector has more than 1 element and target supports scalar
2127 // FABS natively and vector length <= 2(1 AND + 1 CONST).
2128 // FIXME: Scalar construction instruction count varies in every architecture,
2129 // here we assume 1 instruction for now.
2130 if (VT.isFixedLengthVector()) {
2131 EVT EltVT = VT.getVectorElementType();
2132 unsigned NumElts = VT.getVectorNumElements();
2133 if ((NumElts == 1 &&
2135 (NumElts < 3 && TLI.isOperationLegal(ISD::FABS, EltVT) &&
2136 TLI.isExtractVecEltCheap(VT, 0) &&
2137 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
2138 return SDValue();
2139 }
2140
2141 SDLoc DL(Node);
2142 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
2143 SDValue ClearSignMask = DAG.getConstant(
2145 SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, Cast, ClearSignMask);
2146 return DAG.getNode(ISD::BITCAST, DL, VT, ClearedSign);
2147}
2148
2149SDValue VectorLegalizer::ExpandFCOPYSIGN(SDNode *Node) {
2150 EVT VT = Node->getValueType(0);
2151 EVT IntVT = VT.changeVectorElementTypeToInteger();
2152
2153 if (VT != Node->getOperand(1).getValueType() ||
2154 !TLI.isOperationLegalOrCustom(ISD::AND, IntVT) ||
2155 !TLI.isOperationLegalOrCustom(ISD::OR, IntVT))
2156 return SDValue();
2157
2158 // Heuristic check to determine whether vector should be expanded to integer
2159 // operations or unrolled to scalar operations.
2160 // 1. Scalable vector is never unrolled.
2161 // 2. Fixed vector is unrolled if one of followings is true:
2162 // a. Vector only has 1 element and target knows how to handle scalar
2163 // FCOPYSIGN(either legal or custom expand or promote).
2164 // b. Vector has more than 1 element and target supports scalar
2165 // FCOPYSIGN natively and vector length <= 5(2 AND + 1 OR + 2 CONST).
2166 // FIXME: Scalar construction instruction count varies in every architecture,
2167 // here we assume 1 instruction for now.
2168 if (VT.isFixedLengthVector()) {
2169 EVT EltVT = VT.getVectorElementType();
2170 unsigned NumElts = VT.getVectorNumElements();
2171 if ((NumElts == 1 &&
2173 (NumElts < 6 && TLI.isOperationLegal(ISD::FCOPYSIGN, EltVT) &&
2174 TLI.isExtractVecEltCheap(VT, 0) &&
2175 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
2176 return SDValue();
2177 }
2178
2179 SDLoc DL(Node);
2180 SDValue Mag = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
2181 SDValue Sign = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(1));
2182
2183 SDValue SignMask = DAG.getConstant(
2184 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
2185 SDValue SignBit = DAG.getNode(ISD::AND, DL, IntVT, Sign, SignMask);
2186
2187 SDValue ClearSignMask = DAG.getConstant(
2189 SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, Mag, ClearSignMask);
2190
2191 SDValue CopiedSign = DAG.getNode(ISD::OR, DL, IntVT, ClearedSign, SignBit,
2193
2194 return DAG.getNode(ISD::BITCAST, DL, VT, CopiedSign);
2195}
2196
2197void VectorLegalizer::ExpandFSUB(SDNode *Node,
2198 SmallVectorImpl<SDValue> &Results) {
2199 // For floating-point values, (a-b) is the same as a+(-b). If FNEG is legal,
2200 // we can defer this to operation legalization where it will be lowered as
2201 // a+(-b).
2202 EVT VT = Node->getValueType(0);
2203 if (TLI.isOperationLegalOrCustom(ISD::FNEG, VT) &&
2205 return; // Defer to LegalizeDAG
2206
2207 if (SDValue Expanded = TLI.expandVectorNaryOpBySplitting(Node, DAG)) {
2208 Results.push_back(Expanded);
2209 return;
2210 }
2211
2212 SDValue Tmp = DAG.UnrollVectorOp(Node);
2213 Results.push_back(Tmp);
2214}
2215
2216void VectorLegalizer::ExpandSETCC(SDNode *Node,
2217 SmallVectorImpl<SDValue> &Results) {
2218 bool NeedInvert = false;
2219 bool IsVP = Node->getOpcode() == ISD::VP_SETCC;
2220 bool IsStrict = Node->getOpcode() == ISD::STRICT_FSETCC ||
2221 Node->getOpcode() == ISD::STRICT_FSETCCS;
2222 bool IsSignaling = Node->getOpcode() == ISD::STRICT_FSETCCS;
2223 unsigned Offset = IsStrict ? 1 : 0;
2224
2225 SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
2226 SDValue LHS = Node->getOperand(0 + Offset);
2227 SDValue RHS = Node->getOperand(1 + Offset);
2228 SDValue CC = Node->getOperand(2 + Offset);
2229
2230 MVT OpVT = LHS.getSimpleValueType();
2231 ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
2232
2233 if (TLI.getCondCodeAction(CCCode, OpVT) != TargetLowering::Expand) {
2234 if (IsStrict) {
2235 UnrollStrictFPOp(Node, Results);
2236 return;
2237 }
2238 Results.push_back(UnrollVSETCC(Node));
2239 return;
2240 }
2241
2242 SDValue Mask, EVL;
2243 if (IsVP) {
2244 Mask = Node->getOperand(3 + Offset);
2245 EVL = Node->getOperand(4 + Offset);
2246 }
2247
2248 SDLoc dl(Node);
2249 bool Legalized =
2250 TLI.LegalizeSetCCCondCode(DAG, Node->getValueType(0), LHS, RHS, CC, Mask,
2251 EVL, NeedInvert, dl, Chain, IsSignaling);
2252
2253 if (Legalized) {
2254 // If we expanded the SETCC by swapping LHS and RHS, or by inverting the
2255 // condition code, create a new SETCC node.
2256 if (CC.getNode()) {
2257 if (IsStrict) {
2258 LHS = DAG.getNode(Node->getOpcode(), dl, Node->getVTList(),
2259 {Chain, LHS, RHS, CC}, Node->getFlags());
2260 Chain = LHS.getValue(1);
2261 } else if (IsVP) {
2262 LHS = DAG.getNode(ISD::VP_SETCC, dl, Node->getValueType(0),
2263 {LHS, RHS, CC, Mask, EVL}, Node->getFlags());
2264 } else {
2265 LHS = DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), LHS, RHS, CC,
2266 Node->getFlags());
2267 }
2268 }
2269
2270 // If we expanded the SETCC by inverting the condition code, then wrap
2271 // the existing SETCC in a NOT to restore the intended condition.
2272 if (NeedInvert) {
2273 if (!IsVP)
2274 LHS = DAG.getLogicalNOT(dl, LHS, LHS->getValueType(0));
2275 else
2276 LHS = DAG.getVPLogicalNOT(dl, LHS, Mask, EVL, LHS->getValueType(0));
2277 }
2278 } else {
2279 assert(!IsStrict && "Don't know how to expand for strict nodes.");
2280
2281 // Otherwise, SETCC for the given comparison type must be completely
2282 // illegal; expand it into a SELECT_CC.
2283 EVT VT = Node->getValueType(0);
2284 LHS = DAG.getNode(ISD::SELECT_CC, dl, VT, LHS, RHS,
2285 DAG.getBoolConstant(true, dl, VT, LHS.getValueType()),
2286 DAG.getBoolConstant(false, dl, VT, LHS.getValueType()),
2287 CC, Node->getFlags());
2288 }
2289
2290 Results.push_back(LHS);
2291 if (IsStrict)
2292 Results.push_back(Chain);
2293}
2294
2295void VectorLegalizer::ExpandUADDSUBO(SDNode *Node,
2296 SmallVectorImpl<SDValue> &Results) {
2297 SDValue Result, Overflow;
2298 TLI.expandUADDSUBO(Node, Result, Overflow, DAG);
2299 Results.push_back(Result);
2300 Results.push_back(Overflow);
2301}
2302
2303void VectorLegalizer::ExpandSADDSUBO(SDNode *Node,
2304 SmallVectorImpl<SDValue> &Results) {
2305 SDValue Result, Overflow;
2306 TLI.expandSADDSUBO(Node, Result, Overflow, DAG);
2307 Results.push_back(Result);
2308 Results.push_back(Overflow);
2309}
2310
2311void VectorLegalizer::ExpandMULO(SDNode *Node,
2312 SmallVectorImpl<SDValue> &Results) {
2313 SDValue Result, Overflow;
2314 if (!TLI.expandMULO(Node, Result, Overflow, DAG))
2315 std::tie(Result, Overflow) = DAG.UnrollVectorOverflowOp(Node);
2316
2317 Results.push_back(Result);
2318 Results.push_back(Overflow);
2319}
2320
2321void VectorLegalizer::ExpandFixedPointDiv(SDNode *Node,
2322 SmallVectorImpl<SDValue> &Results) {
2323 SDNode *N = Node;
2324 if (SDValue Expanded = TLI.expandFixedPointDiv(N->getOpcode(), SDLoc(N),
2325 N->getOperand(0), N->getOperand(1), N->getConstantOperandVal(2), DAG))
2326 Results.push_back(Expanded);
2327}
2328
2329void VectorLegalizer::ExpandStrictFPOp(SDNode *Node,
2330 SmallVectorImpl<SDValue> &Results) {
2331 if (Node->getOpcode() == ISD::STRICT_UINT_TO_FP) {
2332 ExpandUINT_TO_FLOAT(Node, Results);
2333 return;
2334 }
2335 if (Node->getOpcode() == ISD::STRICT_FP_TO_UINT) {
2336 ExpandFP_TO_UINT(Node, Results);
2337 return;
2338 }
2339
2340 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2341 Node->getOpcode() == ISD::STRICT_FSETCCS) {
2342 ExpandSETCC(Node, Results);
2343 return;
2344 }
2345
2346 UnrollStrictFPOp(Node, Results);
2347}
2348
2349void VectorLegalizer::ExpandREM(SDNode *Node,
2350 SmallVectorImpl<SDValue> &Results) {
2351 assert((Node->getOpcode() == ISD::SREM || Node->getOpcode() == ISD::UREM) &&
2352 "Expected REM node");
2353
2355 if (!TLI.expandREM(Node, Result, DAG))
2356 Result = DAG.UnrollVectorOp(Node);
2357 Results.push_back(Result);
2358}
2359
2360// Try to expand libm nodes into vector math routine calls. Callers provide the
2361// LibFunc equivalent of the passed in Node, which is used to lookup mappings
2362// within TargetLibraryInfo. The only mappings considered are those where the
2363// result and all operands are the same vector type. While predicated nodes are
2364// not supported, we will emit calls to masked routines by passing in an all
2365// true mask.
2366bool VectorLegalizer::tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall LC,
2367 SmallVectorImpl<SDValue> &Results) {
2368 // Chain must be propagated but currently strict fp operations are down
2369 // converted to their none strict counterpart.
2370 assert(!Node->isStrictFPOpcode() && "Unexpected strict fp operation!");
2371
2372 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2373 if (LCImpl == RTLIB::Unsupported)
2374 return false;
2375
2376 EVT VT = Node->getValueType(0);
2377 const RTLIB::RuntimeLibcallsInfo &RTLCI = TLI.getRuntimeLibcallsInfo();
2378 LLVMContext &Ctx = *DAG.getContext();
2379
2380 auto [FuncTy, FuncAttrs] = RTLCI.getFunctionTy(
2381 Ctx, DAG.getSubtarget().getTargetTriple(), DAG.getDataLayout(), LCImpl);
2382
2383 SDLoc DL(Node);
2384 TargetLowering::ArgListTy Args;
2385
2386 bool HasMaskArg = RTLCI.hasVectorMaskArgument(LCImpl);
2387
2388 // Sanity check just in case function has unexpected parameters.
2389 assert(FuncTy->getNumParams() == Node->getNumOperands() + HasMaskArg &&
2390 EVT::getEVT(FuncTy->getReturnType(), true) == VT &&
2391 "mismatch in value type and call signature type");
2392
2393 for (unsigned I = 0, E = FuncTy->getNumParams(); I != E; ++I) {
2394 Type *ParamTy = FuncTy->getParamType(I);
2395
2396 if (HasMaskArg && I == E - 1) {
2397 assert(cast<VectorType>(ParamTy)->getElementType()->isIntegerTy(1) &&
2398 "unexpected vector mask type");
2399 EVT MaskVT = TLI.getSetCCResultType(DAG.getDataLayout(), Ctx, VT);
2400 Args.emplace_back(DAG.getBoolConstant(true, DL, MaskVT, VT),
2401 MaskVT.getTypeForEVT(Ctx));
2402
2403 } else {
2404 SDValue Op = Node->getOperand(I);
2405 assert(Op.getValueType() == EVT::getEVT(ParamTy, true) &&
2406 "mismatch in value type and call argument type");
2407 Args.emplace_back(Op, ParamTy);
2408 }
2409 }
2410
2411 // Emit a call to the vector function.
2412 SDValue Callee =
2413 DAG.getExternalSymbol(LCImpl, TLI.getPointerTy(DAG.getDataLayout()));
2414 CallingConv::ID CC = RTLCI.getLibcallImplCallingConv(LCImpl);
2415
2416 TargetLowering::CallLoweringInfo CLI(DAG);
2417 CLI.setDebugLoc(DL)
2418 .setChain(DAG.getEntryNode())
2419 .setLibCallee(CC, FuncTy->getReturnType(), Callee, std::move(Args));
2420
2421 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
2422 Results.push_back(CallResult.first);
2423 return true;
2424}
2425
2426void VectorLegalizer::UnrollStrictFPOp(SDNode *Node,
2427 SmallVectorImpl<SDValue> &Results) {
2428 EVT VT = Node->getValueType(0);
2429 EVT EltVT = VT.getVectorElementType();
2430 unsigned NumElems = VT.getVectorNumElements();
2431 unsigned NumOpers = Node->getNumOperands();
2432 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
2433
2434 EVT TmpEltVT = EltVT;
2435 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2436 Node->getOpcode() == ISD::STRICT_FSETCCS)
2437 TmpEltVT = TLI.getSetCCResultType(DAG.getDataLayout(),
2438 *DAG.getContext(), TmpEltVT);
2439
2440 EVT ValueVTs[] = {TmpEltVT, MVT::Other};
2441 SDValue Chain = Node->getOperand(0);
2442 SDLoc dl(Node);
2443
2444 SmallVector<SDValue, 32> OpValues;
2445 SmallVector<SDValue, 32> OpChains;
2446 for (unsigned i = 0; i < NumElems; ++i) {
2448 SDValue Idx = DAG.getVectorIdxConstant(i, dl);
2449
2450 // The Chain is the first operand.
2451 Opers.push_back(Chain);
2452
2453 // Now process the remaining operands.
2454 for (unsigned j = 1; j < NumOpers; ++j) {
2455 SDValue Oper = Node->getOperand(j);
2456 EVT OperVT = Oper.getValueType();
2457
2458 if (OperVT.isVector())
2459 Oper = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2460 OperVT.getVectorElementType(), Oper, Idx);
2461
2462 Opers.push_back(Oper);
2463 }
2464
2465 SDValue ScalarOp = DAG.getNode(Node->getOpcode(), dl, ValueVTs, Opers);
2466 SDValue ScalarResult = ScalarOp.getValue(0);
2467 SDValue ScalarChain = ScalarOp.getValue(1);
2468
2469 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2470 Node->getOpcode() == ISD::STRICT_FSETCCS)
2471 ScalarResult = DAG.getSelect(dl, EltVT, ScalarResult,
2472 DAG.getAllOnesConstant(dl, EltVT),
2473 DAG.getConstant(0, dl, EltVT));
2474
2475 OpValues.push_back(ScalarResult);
2476 OpChains.push_back(ScalarChain);
2477 }
2478
2479 SDValue Result = DAG.getBuildVector(VT, dl, OpValues);
2480 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OpChains);
2481
2482 Results.push_back(Result);
2483 Results.push_back(NewChain);
2484}
2485
2486SDValue VectorLegalizer::UnrollVSETCC(SDNode *Node) {
2487 EVT VT = Node->getValueType(0);
2488 unsigned NumElems = VT.getVectorNumElements();
2489 EVT EltVT = VT.getVectorElementType();
2490 SDValue LHS = Node->getOperand(0);
2491 SDValue RHS = Node->getOperand(1);
2492 SDValue CC = Node->getOperand(2);
2493 EVT TmpEltVT = LHS.getValueType().getVectorElementType();
2494 SDLoc dl(Node);
2495 SmallVector<SDValue, 8> Ops(NumElems);
2496 for (unsigned i = 0; i < NumElems; ++i) {
2497 SDValue LHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
2498 DAG.getVectorIdxConstant(i, dl));
2499 SDValue RHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
2500 DAG.getVectorIdxConstant(i, dl));
2501 // FIXME: We should use i1 setcc + boolext here, but it causes regressions.
2502 Ops[i] = DAG.getNode(ISD::SETCC, dl,
2504 *DAG.getContext(), TmpEltVT),
2505 LHSElem, RHSElem, CC);
2506 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i],
2507 DAG.getBoolConstant(true, dl, EltVT, VT),
2508 DAG.getConstant(0, dl, EltVT));
2509 }
2510 return DAG.getBuildVector(VT, dl, Ops);
2511}
2512
2514 return VectorLegalizer(*this).Run();
2515}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl< int > &ShuffleMask)
#define I(x, y, z)
Definition MD5.cpp:57
#define T
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file describes how to lower LLVM code to machine code.
Value * RHS
Value * LHS
BinaryOperator * Mul
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
Definition APInt.h:230
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:210
bool isBigEndian() const
Definition DataLayout.h:218
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:286
size_t size() const
Definition Function.h:858
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Return the lowering's selection of implementation call for Call.
const Triple & getTargetTriple() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
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.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
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...
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
const TargetSubtargetInfo & getSubtarget() const
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI bool LegalizeVectors()
This transforms the SelectionDAG into a SelectionDAG that only uses vector math operations supported ...
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getInsertSubvector(const SDLoc &DL, SDValue Vec, SDValue SubVec, unsigned Idx)
Insert SubVec at the Idx element of Vec.
LLVM_ABI SDValue getStepVector(const SDLoc &DL, EVT ResVT, const APInt &StepVal)
Returns a vector of type ResVT whose elements contain the linear sequence <0, Step,...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
LLVM_ABI std::pair< SDValue, SDValue > UnrollVectorOverflowOp(SDNode *N, unsigned ResNE=0)
Like UnrollVectorOp(), but for the [US](ADD|SUB|MUL)O family of opcodes.
allnodes_const_iterator allnodes_begin() const
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.
allnodes_const_iterator allnodes_end() const
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
LLVM_ABI SDValue getVPLogicalNOT(const SDLoc &DL, SDValue Val, SDValue Mask, SDValue EVL, EVT VT)
Create a vector-predicated logical NOT operation as (VP_XOR Val, BooleanOne, Mask,...
const LibcallLoweringInfo & getLibcalls() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI unsigned AssignTopologicalOrder()
Topological-sort the AllNodes list and a assign a unique node id for each node in the DAG based on th...
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
LLVM_ABI 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.
SDValue getSplat(EVT VT, const SDLoc &DL, SDValue Op)
Returns a node representing a splat of one value into all lanes of the provided vector type.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
LLVM_ABI SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a logical NOT operation as (XOR Val, BooleanOne).
ilist< SDNode >::iterator allnodes_iterator
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void resize(size_type N)
void push_back(const T &Elt)
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
SDValue promoteTargetBoolean(SelectionDAG &DAG, SDValue Bool, EVT ValVT) const
Promote the given target boolean to a target boolean of the given type.
LegalizeAction getCondCodeAction(ISD::CondCode CC, MVT VT) const
Return how the condition code should be treated: either it is legal, needs to be expanded to some oth...
LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace) const
Return how this store with truncation should be treated: either it is legal, needs to be promoted to ...
virtual bool isExtractVecEltCheap(EVT VT, unsigned Index) const
Return true if extraction of a scalar element from the given vector type at the given index is cheap.
LegalizeAction getFixedPointOperationAction(unsigned Op, EVT VT, unsigned Scale) const
Some fixed point operations may be natively supported by the target but only for specific scales.
bool isStrictFPEnabled() const
Return true if the target support strict float operation.
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
BooleanContent getBooleanContents(bool isVec, bool isFloat) const
For targets without i1 registers, this gives the nature of the high-bits of boolean values held in ty...
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
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...
LegalizeAction getPartialReduceMLAAction(unsigned Opc, EVT AccVT, EVT InputVT) const
Return how a PARTIAL_REDUCE_U/SMLA node with Acc type AccVT and Input type InputVT should be treated.
LegalizeAction getLoadAction(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return how this load with extension should be treated: either it is legal, needs to be promoted to a ...
LegalizeAction getStrictFPOperationAction(unsigned Op, EVT VT) const
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
MVT getTypeToPromoteTo(unsigned Op, MVT VT) const
If the action for this operation is to promote, this method returns the ValueType to promote to.
bool isOperationLegalOrCustomOrPromote(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...
const RTLIB::RuntimeLibcallsInfo & getRuntimeLibcallsInfo() const
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
SDValue expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US][ADD|SUB]SAT.
bool expandMultipleResultFPLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, SDNode *Node, SmallVectorImpl< SDValue > &Results, std::optional< unsigned > CallRetResNo={}) const
Expands a node with multiple results to an FP or vector libcall.
SDValue expandVPCTLZ(SDNode *N, SelectionDAG &DAG) const
Expand VP_CTLZ/VP_CTLZ_ZERO_POISON nodes.
bool expandMULO(SDNode *Node, SDValue &Result, SDValue &Overflow, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]MULO.
SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const
SDValue expandVPBSWAP(SDNode *N, SelectionDAG &DAG) const
Expand VP_BSWAP nodes.
SDValue expandVecReduceSeq(SDNode *Node, SelectionDAG &DAG) const
Expand a VECREDUCE_SEQ_* into an explicit ordered calculation.
SDValue expandFCANONICALIZE(SDNode *Node, SelectionDAG &DAG) const
Expand FCANONICALIZE to FMUL with 1.
SDValue expandCTLZ(SDNode *N, SelectionDAG &DAG) const
Expand CTLZ/CTLZ_ZERO_POISON nodes.
SDValue expandBITREVERSE(SDNode *N, SelectionDAG &DAG) const
Expand BITREVERSE nodes.
SDValue expandCTTZ(SDNode *N, SelectionDAG &DAG) const
Expand CTTZ/CTTZ_ZERO_POISON nodes.
SDValue expandABD(SDNode *N, SelectionDAG &DAG) const
Expand ABDS/ABDU nodes.
SDValue expandCLMUL(SDNode *N, SelectionDAG &DAG) const
Expand carryless multiply.
SDValue expandShlSat(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]SHLSAT.
SDValue expandFP_TO_INT_SAT(SDNode *N, SelectionDAG &DAG) const
Expand FP_TO_[US]INT_SAT into FP_TO_[US]INT and selects or min/max.
SDValue expandCttzElts(SDNode *Node, SelectionDAG &DAG) const
Expand a CTTZ_ELTS or CTTZ_ELTS_ZERO_POISON by calculating (VL - i) for each active lane (i),...
void expandSADDSUBO(SDNode *Node, SDValue &Result, SDValue &Overflow, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::S(ADD|SUB)O.
SDValue expandVPBITREVERSE(SDNode *N, SelectionDAG &DAG) const
Expand VP_BITREVERSE nodes.
SDValue expandABS(SDNode *N, SelectionDAG &DAG, bool IsNegative=false) const
Expand ABS nodes.
SDValue expandVecReduce(SDNode *Node, SelectionDAG &DAG) const
Expand a VECREDUCE_* into an explicit calculation.
bool expandFP_TO_UINT(SDNode *N, SDValue &Result, SDValue &Chain, SelectionDAG &DAG) const
Expand float to UINT conversion.
bool expandREM(SDNode *Node, SDValue &Result, SelectionDAG &DAG) const
Expand an SREM or UREM using SDIV/UDIV or SDIVREM/UDIVREM, if legal.
SDValue expandFMINIMUMNUM_FMAXIMUMNUM(SDNode *N, SelectionDAG &DAG) const
Expand fminimumnum/fmaximumnum into multiple comparison with selects.
SDValue expandLoopDependenceMask(SDNode *N, SelectionDAG &DAG) const
Expand LOOP_DEPENDENCE_MASK nodes.
SDValue expandCTPOP(SDNode *N, SelectionDAG &DAG) const
Expand CTPOP nodes.
SDValue expandVectorNaryOpBySplitting(SDNode *Node, SelectionDAG &DAG) const
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
SDValue expandBSWAP(SDNode *N, SelectionDAG &DAG) const
Expand BSWAP nodes.
SDValue expandFMINIMUM_FMAXIMUM(SDNode *N, SelectionDAG &DAG) const
Expand fminimum/fmaximum into multiple comparison with selects.
std::pair< SDValue, SDValue > scalarizeVectorLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Turn load of vector type into a load of the individual elements.
SDValue expandCONVERT_TO_ARBITRARY_FP(SDNode *Node, SelectionDAG &DAG) const
Expand CONVERT_TO_ARBITRARY_FP using bit manipulation.
SDValue expandFunnelShift(SDNode *N, SelectionDAG &DAG) const
Expand funnel shift.
bool LegalizeSetCCCondCode(SelectionDAG &DAG, EVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, SDValue Mask, SDValue EVL, bool &NeedInvert, const SDLoc &dl, SDValue &Chain, bool IsSignaling=false) const
Legalize a SETCC or VP_SETCC with given LHS and RHS and condition code CC on the current target.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const
This callback is invoked for operations that are unsupported by the target, which are registered to u...
SDValue expandVPCTPOP(SDNode *N, SelectionDAG &DAG) const
Expand VP_CTPOP nodes.
SDValue expandFixedPointDiv(unsigned Opcode, const SDLoc &dl, SDValue LHS, SDValue RHS, unsigned Scale, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]DIVFIX[SAT].
SDValue expandPEXT(SDNode *N, SelectionDAG &DAG) const
Expand parallel bit extract (compress).
SDValue expandVPCTTZ(SDNode *N, SelectionDAG &DAG) const
Expand VP_CTTZ/VP_CTTZ_ZERO_POISON nodes.
SDValue expandVECTOR_COMPRESS(SDNode *Node, SelectionDAG &DAG) const
Expand a vector VECTOR_COMPRESS into a sequence of extract element, store temporarily,...
SDValue expandCONVERT_FROM_ARBITRARY_FP(SDNode *Node, SelectionDAG &DAG) const
Expand CONVERT_FROM_ARBITRARY_FP using bit manipulation.
SDValue expandROT(SDNode *N, bool AllowVectorOps, SelectionDAG &DAG) const
Expand rotations.
SDValue expandFMINNUM_FMAXNUM(SDNode *N, SelectionDAG &DAG) const
Expand fminnum/fmaxnum into fminnum_ieee/fmaxnum_ieee with quieted inputs.
SDValue expandCMP(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]CMP.
SDValue expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[U|S]MULFIX[SAT].
SDValue expandIntMINMAX(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US][MIN|MAX].
SDValue expandVectorFindLastActive(SDNode *N, SelectionDAG &DAG) const
Expand VECTOR_FIND_LAST_ACTIVE nodes.
SDValue expandPartialReduceMLA(SDNode *Node, SelectionDAG &DAG) const
Expands PARTIAL_REDUCE_S/UMLA nodes to a series of simpler operations, consisting of zext/sext,...
void expandUADDSUBO(SDNode *Node, SDValue &Result, SDValue &Overflow, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::U(ADD|SUB)O.
SDValue expandPDEP(SDNode *N, SelectionDAG &DAG) const
Expand parallel bit deposit (expand).
bool expandUINT_TO_FP(SDNode *N, SDValue &Result, SDValue &Chain, SelectionDAG &DAG) const
Expand UINT(i64) to double(f64) conversion.
SDValue expandAVG(SDNode *N, SelectionDAG &DAG) const
Expand vector/scalar AVGCEILS/AVGCEILU/AVGFLOORS/AVGFLOORU nodes.
Changed
#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.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:827
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition ISDOpcodes.h:261
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition ISDOpcodes.h:511
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:787
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
Definition ISDOpcodes.h:394
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
Definition ISDOpcodes.h:400
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:861
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:518
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:888
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:747
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
Definition ISDOpcodes.h:918
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
Definition ISDOpcodes.h:515
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:778
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
Definition ISDOpcodes.h:407
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:438
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:796
@ PARTIAL_REDUCE_UMLA
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:852
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition ISDOpcodes.h:715
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:485
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ PARTIAL_REDUCE_FMLA
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:352
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
Definition ISDOpcodes.h:691
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
Definition ISDOpcodes.h:541
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:374
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:804
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition ISDOpcodes.h:672
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:348
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:704
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:769
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:576
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:858
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:819
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
Definition ISDOpcodes.h:386
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:356
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
Definition ISDOpcodes.h:907
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:896
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:727
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
Definition ISDOpcodes.h:413
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:986
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:813
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:484
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_TO_UINT
Definition ISDOpcodes.h:478
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
Definition ISDOpcodes.h:783
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:500
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:477
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:934
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:505
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:739
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:735
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition ISDOpcodes.h:710
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:427
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:795
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:967
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
Definition ISDOpcodes.h:699
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
Definition ISDOpcodes.h:929
@ 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:953
@ VECREDUCE_FMINIMUM
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:864
@ VECREDUCE_SEQ_FMUL
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:534
@ PARTIAL_REDUCE_SUMLA
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:365
@ CTTZ_ELTS_ZERO_POISON
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
Definition ISDOpcodes.h:722
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
Definition ISDOpcodes.h:751
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:556
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
LLVM_ABI std::optional< unsigned > getVPMaskIdx(unsigned Opcode)
The operand position of the vector mask.
LLVM_ABI std::optional< unsigned > getVPExplicitVectorLengthIdx(unsigned Opcode)
The operand position of the explicit vector length parameter.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
LLVM_ABI Libcall getREM(EVT VT)
LLVM_ABI Libcall getSINCOSPI(EVT RetVT)
getSINCOSPI - Return the SINCOSPI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getMODF(EVT VT)
getMODF - Return the MODF_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getCBRT(EVT RetVT)
getCBRT - Return the CBRT_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getPOW(EVT RetVT)
getPOW - Return the POW_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOS(EVT RetVT)
getSINCOS - Return the SINCOS_* value for the given types, or UNKNOWN_LIBCALL if there is none.
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
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:1745
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
@ Xor
Bitwise or logical XOR of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305
#define N
Extended Value Type.
Definition ValueTypes.h:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:90
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:70
ElementCount getVectorElementCount() const
Definition ValueTypes.h:373
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
Definition ValueTypes.h:98
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isFixedLengthVector() const
Definition ValueTypes.h:199
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
Definition ValueTypes.h:187
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:351
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:359
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition ValueTypes.h:331
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
LLVM_ABI std::pair< FunctionType *, AttributeList > getFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const
static LLVM_ABI bool hasVectorMaskArgument(RTLIB::LibcallImpl Impl)
Returns true if the function has a vector mask argument, which is assumed to be the last argument.