LLVM 24.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:
493 Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
494 break;
495 case ISD::SMULFIX:
496 case ISD::SMULFIXSAT:
497 case ISD::UMULFIX:
498 case ISD::UMULFIXSAT:
499 case ISD::SDIVFIX:
500 case ISD::SDIVFIXSAT:
501 case ISD::UDIVFIX:
502 case ISD::UDIVFIXSAT: {
503 unsigned Scale = Node->getConstantOperandVal(2);
504 Action = TLI.getFixedPointOperationAction(Node->getOpcode(),
505 Node->getValueType(0), Scale);
506 break;
507 }
508 case ISD::LROUND:
509 case ISD::LLROUND:
510 case ISD::LRINT:
511 case ISD::LLRINT:
512 case ISD::SINT_TO_FP:
513 case ISD::UINT_TO_FP:
529 case ISD::CTTZ_ELTS:
532 Action = TLI.getOperationAction(Node->getOpcode(),
533 Node->getOperand(0).getValueType());
534 break;
537 Action = TLI.getOperationAction(Node->getOpcode(),
538 Node->getOperand(1).getValueType());
539 break;
540 case ISD::SETCC: {
541 MVT OpVT = Node->getOperand(0).getSimpleValueType();
542 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get();
543 Action = TLI.getCondCodeAction(CCCode, OpVT);
544 if (Action == TargetLowering::Legal)
545 Action = TLI.getOperationAction(Node->getOpcode(), OpVT);
546 break;
547 }
552 Action =
553 TLI.getPartialReduceMLAAction(Op.getOpcode(), Node->getValueType(0),
554 Node->getOperand(1).getValueType());
555 break;
556
557#define BEGIN_REGISTER_VP_SDNODE(VPID, LEGALPOS, ...) \
558 case ISD::VPID: { \
559 EVT LegalizeVT = LEGALPOS < 0 ? Node->getValueType(-(1 + LEGALPOS)) \
560 : Node->getOperand(LEGALPOS).getValueType(); \
561 if (ISD::VPID == ISD::VP_SETCC) { \
562 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get(); \
563 Action = TLI.getCondCodeAction(CCCode, LegalizeVT.getSimpleVT()); \
564 if (Action != TargetLowering::Legal) \
565 break; \
566 } \
567 /* Defer non-vector results to LegalizeDAG. */ \
568 if (!Node->getValueType(0).isVector() && \
569 Node->getValueType(0) != MVT::Other) { \
570 Action = TargetLowering::Legal; \
571 break; \
572 } \
573 Action = TLI.getOperationAction(Node->getOpcode(), LegalizeVT); \
574 } break;
575#include "llvm/IR/VPIntrinsics.def"
576 }
577
578 LLVM_DEBUG(dbgs() << "\nLegalizing vector op: "; Node->dump(&DAG));
579
580 SmallVector<SDValue, 8> ResultVals;
581 switch (Action) {
582 default: llvm_unreachable("This action is not supported yet!");
583 case TargetLowering::Promote:
584 assert((Op.getOpcode() != ISD::LOAD && Op.getOpcode() != ISD::STORE) &&
585 "This action is not supported yet!");
586 LLVM_DEBUG(dbgs() << "Promoting\n");
587 Promote(Node, ResultVals);
588 assert(!ResultVals.empty() && "No results for promotion?");
589 break;
590 case TargetLowering::Legal:
591 LLVM_DEBUG(dbgs() << "Legal node: nothing to do\n");
592 break;
593 case TargetLowering::Custom:
594 LLVM_DEBUG(dbgs() << "Trying custom legalization\n");
595 if (LowerOperationWrapper(Node, ResultVals))
596 break;
597 LLVM_DEBUG(dbgs() << "Could not custom legalize node\n");
598 [[fallthrough]];
599 case TargetLowering::Expand:
600 LLVM_DEBUG(dbgs() << "Expanding\n");
601 Expand(Node, ResultVals);
602 break;
603 }
604
605 if (ResultVals.empty())
606 return TranslateLegalizeResults(Op, Node);
607
608 Changed = true;
609 return RecursivelyLegalizeResults(Op, ResultVals);
610}
611
612// FIXME: This is very similar to TargetLowering::LowerOperationWrapper. Can we
613// merge them somehow?
614bool VectorLegalizer::LowerOperationWrapper(SDNode *Node,
615 SmallVectorImpl<SDValue> &Results) {
616 SDValue Res = TLI.LowerOperation(SDValue(Node, 0), DAG);
617
618 if (!Res.getNode())
619 return false;
620
621 if (Res == SDValue(Node, 0))
622 return true;
623
624 // If the original node has one result, take the return value from
625 // LowerOperation as is. It might not be result number 0.
626 if (Node->getNumValues() == 1) {
627 Results.push_back(Res);
628 return true;
629 }
630
631 // If the original node has multiple results, then the return node should
632 // have the same number of results.
633 assert((Node->getNumValues() == Res->getNumValues()) &&
634 "Lowering returned the wrong number of results!");
635
636 // Places new result values base on N result number.
637 for (unsigned I = 0, E = Node->getNumValues(); I != E; ++I)
638 Results.push_back(Res.getValue(I));
639
640 return true;
641}
642
643void VectorLegalizer::PromoteSETCC(SDNode *Node,
644 SmallVectorImpl<SDValue> &Results) {
645 MVT VecVT = Node->getOperand(0).getSimpleValueType();
646 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
647
648 unsigned ExtOp = VecVT.isFloatingPoint() ? ISD::FP_EXTEND : ISD::ANY_EXTEND;
649
650 SDLoc DL(Node);
651 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
652
653 Operands[0] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(0));
654 Operands[1] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(1));
655 Operands[2] = Node->getOperand(2);
656
657 if (Node->getOpcode() == ISD::VP_SETCC) {
658 Operands[3] = Node->getOperand(3); // mask
659 Operands[4] = Node->getOperand(4); // evl
660 }
661
662 EVT ResVT =
663 TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), NewVecVT);
664 SDValue Res =
665 DAG.getNode(Node->getOpcode(), DL, ResVT, Operands, Node->getFlags());
666 if (ResVT != Node->getValueType(0))
667 Res = DAG.getBoolExtOrTrunc(Res, DL, Node->getValueType(0), NewVecVT);
668 Results.push_back(Res);
669}
670
671void VectorLegalizer::PromoteSTRICT(SDNode *Node,
672 SmallVectorImpl<SDValue> &Results) {
673 MVT VecVT = Node->getOperand(1).getSimpleValueType();
674 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
675
676 assert(VecVT.isFloatingPoint());
677
678 SDLoc DL(Node);
679 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
681
682 for (unsigned j = 1; j != Node->getNumOperands(); ++j)
683 if (Node->getOperand(j).getValueType().isVector() &&
684 !(ISD::isVPOpcode(Node->getOpcode()) &&
685 ISD::getVPMaskIdx(Node->getOpcode()) == j)) // Skip mask operand.
686 {
687 // promote the vector operand.
688 SDValue Ext =
689 DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {NewVecVT, MVT::Other},
690 {Node->getOperand(0), Node->getOperand(j)});
691 Operands[j] = Ext.getValue(0);
692 Chains.push_back(Ext.getValue(1));
693 } else
694 Operands[j] = Node->getOperand(j); // Skip no vector operand.
695
696 SDVTList VTs = DAG.getVTList(NewVecVT, Node->getValueType(1));
697
698 Operands[0] = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
699
700 SDValue Res =
701 DAG.getNode(Node->getOpcode(), DL, VTs, Operands, Node->getFlags());
702
703 SDValue Round =
704 DAG.getNode(ISD::STRICT_FP_ROUND, DL, {VecVT, MVT::Other},
705 {Res.getValue(1), Res.getValue(0),
706 DAG.getIntPtrConstant(0, DL, /*isTarget=*/true)});
707
708 Results.push_back(Round.getValue(0));
709 Results.push_back(Round.getValue(1));
710}
711
712void VectorLegalizer::PromoteFloatVECREDUCE(SDNode *Node,
713 SmallVectorImpl<SDValue> &Results,
714 bool NonArithmetic) {
715 MVT OpVT = Node->getOperand(0).getSimpleValueType();
716 assert(OpVT.isFloatingPoint() && "Expected floating point reduction!");
717 MVT NewOpVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OpVT);
718
719 SDLoc DL(Node);
720 SDValue NewOp = DAG.getNode(ISD::FP_EXTEND, DL, NewOpVT, Node->getOperand(0));
721 SDValue Rdx =
722 DAG.getNode(Node->getOpcode(), DL, NewOpVT.getVectorElementType(), NewOp,
723 Node->getFlags());
724 SDValue Res =
725 DAG.getNode(ISD::FP_ROUND, DL, Node->getValueType(0), Rdx,
726 DAG.getIntPtrConstant(NonArithmetic, DL, /*isTarget=*/true));
727 Results.push_back(Res);
728}
729
730void VectorLegalizer::PromoteVECTOR_COMPRESS(
731 SDNode *Node, SmallVectorImpl<SDValue> &Results) {
732 SDLoc DL(Node);
733 EVT VT = Node->getValueType(0);
734 MVT PromotedVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT.getSimpleVT());
735 assert((VT.isInteger() || VT.getSizeInBits() == PromotedVT.getSizeInBits()) &&
736 "Only integer promotion or bitcasts between types is supported");
737
738 SDValue Vec = Node->getOperand(0);
739 SDValue Mask = Node->getOperand(1);
740 SDValue Passthru = Node->getOperand(2);
741 if (VT.isInteger()) {
742 Vec = DAG.getNode(ISD::ANY_EXTEND, DL, PromotedVT, Vec);
743 Mask = TLI.promoteTargetBoolean(DAG, Mask, PromotedVT);
744 Passthru = DAG.getNode(ISD::ANY_EXTEND, DL, PromotedVT, Passthru);
745 } else {
746 Vec = DAG.getBitcast(PromotedVT, Vec);
747 Passthru = DAG.getBitcast(PromotedVT, Passthru);
748 }
749
751 DAG.getNode(ISD::VECTOR_COMPRESS, DL, PromotedVT, Vec, Mask, Passthru);
752 Result = VT.isInteger() ? DAG.getNode(ISD::TRUNCATE, DL, VT, Result)
753 : DAG.getBitcast(VT, Result);
754 Results.push_back(Result);
755}
756
757void VectorLegalizer::Promote(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
758 // For a few operations there is a specific concept for promotion based on
759 // the operand's type.
760 switch (Node->getOpcode()) {
761 case ISD::SINT_TO_FP:
762 case ISD::UINT_TO_FP:
765 // "Promote" the operation by extending the operand.
766 PromoteINT_TO_FP(Node, Results);
767 return;
768 case ISD::FP_TO_UINT:
769 case ISD::FP_TO_SINT:
772 // Promote the operation by extending the operand.
773 PromoteFP_TO_INT(Node, Results);
774 return;
775 case ISD::VP_SETCC:
776 case ISD::SETCC:
777 // Promote the operation by extending the operand.
778 PromoteSETCC(Node, Results);
779 return;
780 case ISD::STRICT_FADD:
781 case ISD::STRICT_FSUB:
782 case ISD::STRICT_FMUL:
783 case ISD::STRICT_FDIV:
785 case ISD::STRICT_FMA:
786 PromoteSTRICT(Node, Results);
787 return;
790 PromoteFloatVECREDUCE(Node, Results, /*NonArithmetic=*/false);
791 return;
796 PromoteFloatVECREDUCE(Node, Results, /*NonArithmetic=*/true);
797 return;
799 PromoteVECTOR_COMPRESS(Node, Results);
800 return;
801
802 case ISD::FP_ROUND:
803 case ISD::FP_EXTEND:
804 // These operations are used to do promotion so they can't be promoted
805 // themselves.
806 llvm_unreachable("Don't know how to promote this operation!");
807 case ISD::VP_FABS:
808 case ISD::VP_FCOPYSIGN:
809 case ISD::VP_FNEG:
810 // Promoting fabs, fneg, and fcopysign changes their semantics.
811 llvm_unreachable("These operations should not be promoted");
812 }
813
814 // There are currently two cases of vector promotion:
815 // 1) Bitcasting a vector of integers to a different type to a vector of the
816 // same overall length. For example, x86 promotes ISD::AND v2i32 to v1i64.
817 // 2) Extending a vector of floats to a vector of the same number of larger
818 // floats. For example, AArch64 promotes ISD::FADD on v4f16 to v4f32.
819 assert(Node->getNumValues() == 1 &&
820 "Can't promote a vector with multiple results!");
821 MVT VT = Node->getSimpleValueType(0);
822 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
823 SDLoc dl(Node);
824 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
825
826 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
827 // Do not promote the mask operand of a VP OP.
828 bool SkipPromote = ISD::isVPOpcode(Node->getOpcode()) &&
829 ISD::getVPMaskIdx(Node->getOpcode()) == j;
830 if (Node->getOperand(j).getValueType().isVector() && !SkipPromote)
831 if (Node->getOperand(j)
832 .getValueType()
833 .getVectorElementType()
834 .isFloatingPoint() &&
836 if (ISD::isVPOpcode(Node->getOpcode())) {
837 unsigned EVLIdx =
839 unsigned MaskIdx = *ISD::getVPMaskIdx(Node->getOpcode());
840 Operands[j] =
841 DAG.getNode(ISD::VP_FP_EXTEND, dl, NVT, Node->getOperand(j),
842 Node->getOperand(MaskIdx), Node->getOperand(EVLIdx));
843 } else {
844 Operands[j] =
845 DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(j));
846 }
847 else
848 Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(j));
849 else
850 Operands[j] = Node->getOperand(j);
851 }
852
853 SDValue Res =
854 DAG.getNode(Node->getOpcode(), dl, NVT, Operands, Node->getFlags());
855
856 if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
859 if (ISD::isVPOpcode(Node->getOpcode())) {
860 unsigned EVLIdx = *ISD::getVPExplicitVectorLengthIdx(Node->getOpcode());
861 unsigned MaskIdx = *ISD::getVPMaskIdx(Node->getOpcode());
862 Res = DAG.getNode(ISD::VP_FP_ROUND, dl, VT, Res,
863 Node->getOperand(MaskIdx), Node->getOperand(EVLIdx));
864 } else {
865 Res = DAG.getNode(ISD::FP_ROUND, dl, VT, Res,
866 DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
867 }
868 else
869 Res = DAG.getNode(ISD::BITCAST, dl, VT, Res);
870
871 Results.push_back(Res);
872}
873
874void VectorLegalizer::PromoteINT_TO_FP(SDNode *Node,
875 SmallVectorImpl<SDValue> &Results) {
876 // INT_TO_FP operations may require the input operand be promoted even
877 // when the type is otherwise legal.
878 bool IsStrict = Node->isStrictFPOpcode();
879 MVT VT = Node->getOperand(IsStrict ? 1 : 0).getSimpleValueType();
880 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
882 "Vectors have different number of elements!");
883
884 SDLoc dl(Node);
885 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
886
887 unsigned Opc = (Node->getOpcode() == ISD::UINT_TO_FP ||
888 Node->getOpcode() == ISD::STRICT_UINT_TO_FP)
891 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
892 if (Node->getOperand(j).getValueType().isVector())
893 Operands[j] = DAG.getNode(Opc, dl, NVT, Node->getOperand(j));
894 else
895 Operands[j] = Node->getOperand(j);
896 }
897
898 if (IsStrict) {
899 SDValue Res = DAG.getNode(Node->getOpcode(), dl,
900 {Node->getValueType(0), MVT::Other}, Operands);
901 Results.push_back(Res);
902 Results.push_back(Res.getValue(1));
903 return;
904 }
905
906 SDValue Res =
907 DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Operands);
908 Results.push_back(Res);
909}
910
911// For FP_TO_INT we promote the result type to a vector type with wider
912// elements and then truncate the result. This is different from the default
913// PromoteVector which uses bitcast to promote thus assumning that the
914// promoted vector type has the same overall size.
915void VectorLegalizer::PromoteFP_TO_INT(SDNode *Node,
916 SmallVectorImpl<SDValue> &Results) {
917 MVT VT = Node->getSimpleValueType(0);
918 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
919 bool IsStrict = Node->isStrictFPOpcode();
921 "Vectors have different number of elements!");
922
923 unsigned NewOpc = Node->getOpcode();
924 // Change FP_TO_UINT to FP_TO_SINT if possible.
925 // TODO: Should we only do this if FP_TO_UINT itself isn't legal?
926 if (NewOpc == ISD::FP_TO_UINT &&
928 NewOpc = ISD::FP_TO_SINT;
929
930 if (NewOpc == ISD::STRICT_FP_TO_UINT &&
932 NewOpc = ISD::STRICT_FP_TO_SINT;
933
934 SDLoc dl(Node);
935 SDValue Promoted, Chain;
936 if (IsStrict) {
937 Promoted = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
938 {Node->getOperand(0), Node->getOperand(1)});
939 Chain = Promoted.getValue(1);
940 } else
941 Promoted = DAG.getNode(NewOpc, dl, NVT, Node->getOperand(0));
942
943 // Assert that the converted value fits in the original type. If it doesn't
944 // (eg: because the value being converted is too big), then the result of the
945 // original operation was undefined anyway, so the assert is still correct.
946 if (Node->getOpcode() == ISD::FP_TO_UINT ||
947 Node->getOpcode() == ISD::STRICT_FP_TO_UINT)
948 NewOpc = ISD::AssertZext;
949 else
950 NewOpc = ISD::AssertSext;
951
952 Promoted = DAG.getNode(NewOpc, dl, NVT, Promoted,
953 DAG.getValueType(VT.getScalarType()));
954 Promoted = DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted);
955 Results.push_back(Promoted);
956 if (IsStrict)
957 Results.push_back(Chain);
958}
959
960std::pair<SDValue, SDValue> VectorLegalizer::ExpandLoad(SDNode *N) {
961 LoadSDNode *LD = cast<LoadSDNode>(N);
962 return TLI.scalarizeVectorLoad(LD, DAG);
963}
964
965SDValue VectorLegalizer::ExpandStore(SDNode *N) {
966 StoreSDNode *ST = cast<StoreSDNode>(N);
967 SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
968 return TF;
969}
970
971void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
972 switch (Node->getOpcode()) {
973 case ISD::LOAD: {
974 std::pair<SDValue, SDValue> Tmp = ExpandLoad(Node);
975 Results.push_back(Tmp.first);
976 Results.push_back(Tmp.second);
977 return;
978 }
979 case ISD::STORE:
980 Results.push_back(ExpandStore(Node));
981 return;
983 for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
984 Results.push_back(Node->getOperand(i));
985 return;
987 if (SDValue Expanded = ExpandSEXTINREG(Node)) {
988 Results.push_back(Expanded);
989 return;
990 }
991 break;
993 Results.push_back(ExpandANY_EXTEND_VECTOR_INREG(Node));
994 return;
996 Results.push_back(ExpandSIGN_EXTEND_VECTOR_INREG(Node));
997 return;
999 Results.push_back(ExpandZERO_EXTEND_VECTOR_INREG(Node));
1000 return;
1001 case ISD::BSWAP:
1002 if (SDValue Expanded = ExpandBSWAP(Node)) {
1003 Results.push_back(Expanded);
1004 return;
1005 }
1006 break;
1007 case ISD::VP_BSWAP:
1008 Results.push_back(TLI.expandVPBSWAP(Node, DAG));
1009 return;
1010 case ISD::VSELECT:
1011 if (SDValue Expanded = ExpandVSELECT(Node)) {
1012 Results.push_back(Expanded);
1013 return;
1014 }
1015 break;
1016 case ISD::VP_SELECT:
1017 if (SDValue Expanded = ExpandVP_SELECT(Node)) {
1018 Results.push_back(Expanded);
1019 return;
1020 }
1021 break;
1022 case ISD::VP_SREM:
1023 case ISD::VP_UREM:
1024 if (SDValue Expanded = ExpandVP_REM(Node)) {
1025 Results.push_back(Expanded);
1026 return;
1027 }
1028 break;
1029 case ISD::VP_FNEG:
1030 if (SDValue Expanded = ExpandVP_FNEG(Node)) {
1031 Results.push_back(Expanded);
1032 return;
1033 }
1034 break;
1035 case ISD::VP_FABS:
1036 if (SDValue Expanded = ExpandVP_FABS(Node)) {
1037 Results.push_back(Expanded);
1038 return;
1039 }
1040 break;
1041 case ISD::VP_FCOPYSIGN:
1042 if (SDValue Expanded = ExpandVP_FCOPYSIGN(Node)) {
1043 Results.push_back(Expanded);
1044 return;
1045 }
1046 break;
1047 case ISD::SELECT:
1048 if (SDValue Expanded = ExpandSELECT(Node)) {
1049 Results.push_back(Expanded);
1050 return;
1051 }
1052 break;
1053 case ISD::SELECT_CC: {
1054 if (Node->getValueType(0).isScalableVector()) {
1055 EVT CondVT = TLI.getSetCCResultType(
1056 DAG.getDataLayout(), *DAG.getContext(), Node->getValueType(0));
1057 SDValue SetCC =
1058 DAG.getNode(ISD::SETCC, SDLoc(Node), CondVT, Node->getOperand(0),
1059 Node->getOperand(1), Node->getOperand(4));
1060 Results.push_back(DAG.getSelect(SDLoc(Node), Node->getValueType(0), SetCC,
1061 Node->getOperand(2),
1062 Node->getOperand(3)));
1063 return;
1064 }
1065 break;
1066 }
1067 case ISD::FP_TO_UINT:
1068 ExpandFP_TO_UINT(Node, Results);
1069 return;
1070 case ISD::UINT_TO_FP:
1071 ExpandUINT_TO_FLOAT(Node, Results);
1072 return;
1073 case ISD::FNEG:
1074 if (SDValue Expanded = ExpandFNEG(Node)) {
1075 Results.push_back(Expanded);
1076 return;
1077 }
1078 break;
1079 case ISD::FABS:
1080 if (SDValue Expanded = ExpandFABS(Node)) {
1081 Results.push_back(Expanded);
1082 return;
1083 }
1084 break;
1085 case ISD::FCOPYSIGN:
1086 if (SDValue Expanded = ExpandFCOPYSIGN(Node)) {
1087 Results.push_back(Expanded);
1088 return;
1089 }
1090 break;
1091 case ISD::FCANONICALIZE: {
1092 // If the scalar element type has a
1093 // Legal/Custom FCANONICALIZE, don't
1094 // mess with the vector, fall back.
1095 EVT VT = Node->getValueType(0);
1096 EVT EltVT = VT.getVectorElementType();
1097 if (!VT.isScalableVector() &&
1099 TargetLowering::Expand)
1100 break;
1101 // Otherwise canonicalize the whole vector.
1102 SDValue Mul = TLI.expandFCANONICALIZE(Node, DAG);
1103 Results.push_back(Mul);
1104 return;
1105 }
1106 case ISD::FSUB:
1107 ExpandFSUB(Node, Results);
1108 return;
1109 case ISD::SETCC:
1110 case ISD::VP_SETCC:
1111 ExpandSETCC(Node, Results);
1112 return;
1113 case ISD::ABS:
1115 if (SDValue Expanded = TLI.expandABS(Node, DAG)) {
1116 Results.push_back(Expanded);
1117 return;
1118 }
1119 break;
1120 case ISD::ABDS:
1121 case ISD::ABDU:
1122 if (SDValue Expanded = TLI.expandABD(Node, DAG)) {
1123 Results.push_back(Expanded);
1124 return;
1125 }
1126 break;
1127 case ISD::AVGCEILS:
1128 case ISD::AVGCEILU:
1129 case ISD::AVGFLOORS:
1130 case ISD::AVGFLOORU:
1131 if (SDValue Expanded = TLI.expandAVG(Node, DAG)) {
1132 Results.push_back(Expanded);
1133 return;
1134 }
1135 break;
1136 case ISD::BITREVERSE:
1137 if (SDValue Expanded = ExpandBITREVERSE(Node)) {
1138 Results.push_back(Expanded);
1139 return;
1140 }
1141 break;
1142 case ISD::VP_BITREVERSE:
1143 if (SDValue Expanded = TLI.expandVPBITREVERSE(Node, DAG)) {
1144 Results.push_back(Expanded);
1145 return;
1146 }
1147 break;
1148 case ISD::CTPOP:
1149 if (SDValue Expanded = TLI.expandCTPOP(Node, DAG)) {
1150 Results.push_back(Expanded);
1151 return;
1152 }
1153 break;
1154 case ISD::VP_CTPOP:
1155 if (SDValue Expanded = TLI.expandVPCTPOP(Node, DAG)) {
1156 Results.push_back(Expanded);
1157 return;
1158 }
1159 break;
1160 case ISD::CTLZ:
1162 if (SDValue Expanded = TLI.expandCTLZ(Node, DAG)) {
1163 Results.push_back(Expanded);
1164 return;
1165 }
1166 break;
1167 case ISD::VP_CTLZ:
1168 case ISD::VP_CTLZ_ZERO_POISON:
1169 if (SDValue Expanded = TLI.expandVPCTLZ(Node, DAG)) {
1170 Results.push_back(Expanded);
1171 return;
1172 }
1173 break;
1174 case ISD::CTTZ:
1176 if (SDValue Expanded = TLI.expandCTTZ(Node, DAG)) {
1177 Results.push_back(Expanded);
1178 return;
1179 }
1180 break;
1181 case ISD::VP_CTTZ:
1182 case ISD::VP_CTTZ_ZERO_POISON:
1183 if (SDValue Expanded = TLI.expandVPCTTZ(Node, DAG)) {
1184 Results.push_back(Expanded);
1185 return;
1186 }
1187 break;
1188 case ISD::FSHL:
1189 case ISD::VP_FSHL:
1190 case ISD::FSHR:
1191 case ISD::VP_FSHR:
1192 if (SDValue Expanded = TLI.expandFunnelShift(Node, DAG)) {
1193 Results.push_back(Expanded);
1194 return;
1195 }
1196 break;
1197 case ISD::CLMUL:
1198 case ISD::CLMULR:
1199 case ISD::CLMULH:
1200 if (SDValue Expanded = TLI.expandCLMUL(Node, DAG)) {
1201 Results.push_back(Expanded);
1202 return;
1203 }
1204 break;
1205 case ISD::PEXT:
1206 Results.push_back(TLI.expandPEXT(Node, DAG));
1207 return;
1208 case ISD::PDEP:
1209 Results.push_back(TLI.expandPDEP(Node, DAG));
1210 return;
1211 case ISD::ROTL:
1212 case ISD::ROTR:
1213 if (SDValue Expanded = TLI.expandROT(Node, false /*AllowVectorOps*/, DAG)) {
1214 Results.push_back(Expanded);
1215 return;
1216 }
1217 break;
1218 case ISD::FMINNUM:
1219 case ISD::FMAXNUM:
1220 if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG)) {
1221 Results.push_back(Expanded);
1222 return;
1223 }
1224 break;
1225 case ISD::FMINIMUM:
1226 case ISD::FMAXIMUM:
1227 Results.push_back(TLI.expandFMINIMUM_FMAXIMUM(Node, DAG));
1228 return;
1229 case ISD::FMINIMUMNUM:
1230 case ISD::FMAXIMUMNUM:
1231 Results.push_back(TLI.expandFMINIMUMNUM_FMAXIMUMNUM(Node, DAG));
1232 return;
1233 case ISD::SMIN:
1234 case ISD::SMAX:
1235 case ISD::UMIN:
1236 case ISD::UMAX:
1237 if (SDValue Expanded = TLI.expandIntMINMAX(Node, DAG)) {
1238 Results.push_back(Expanded);
1239 return;
1240 }
1241 break;
1242 case ISD::UADDO:
1243 case ISD::USUBO:
1244 ExpandUADDSUBO(Node, Results);
1245 return;
1246 case ISD::SADDO:
1247 case ISD::SSUBO:
1248 ExpandSADDSUBO(Node, Results);
1249 return;
1250 case ISD::UMULO:
1251 case ISD::SMULO:
1252 ExpandMULO(Node, Results);
1253 return;
1254 case ISD::USUBSAT:
1255 case ISD::SSUBSAT:
1256 case ISD::UADDSAT:
1257 case ISD::SADDSAT:
1258 if (SDValue Expanded = TLI.expandAddSubSat(Node, DAG)) {
1259 Results.push_back(Expanded);
1260 return;
1261 }
1262 break;
1263 case ISD::USHLSAT:
1264 case ISD::SSHLSAT:
1265 if (SDValue Expanded = TLI.expandShlSat(Node, DAG)) {
1266 Results.push_back(Expanded);
1267 return;
1268 }
1269 break;
1272 // Expand the fpsosisat if it is scalable to prevent it from unrolling below.
1273 if (Node->getValueType(0).isScalableVector()) {
1274 if (SDValue Expanded = TLI.expandFP_TO_INT_SAT(Node, DAG)) {
1275 Results.push_back(Expanded);
1276 return;
1277 }
1278 }
1279 break;
1280 case ISD::SMULFIX:
1281 case ISD::UMULFIX:
1282 case ISD::SMULFIXSAT:
1283 case ISD::UMULFIXSAT:
1284 if (SDValue Expanded = TLI.expandFixedPointMul(Node, DAG)) {
1285 Results.push_back(Expanded);
1286 return;
1287 }
1288 break;
1289 case ISD::SDIVFIX:
1290 case ISD::UDIVFIX:
1291 ExpandFixedPointDiv(Node, Results);
1292 return;
1293 case ISD::SDIVFIXSAT:
1294 case ISD::UDIVFIXSAT:
1295 break;
1296#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1297 case ISD::STRICT_##DAGN:
1298#include "llvm/IR/ConstrainedOps.def"
1299 ExpandStrictFPOp(Node, Results);
1300 return;
1301 case ISD::VECREDUCE_ADD:
1302 case ISD::VECREDUCE_MUL:
1303 case ISD::VECREDUCE_AND:
1304 case ISD::VECREDUCE_OR:
1305 case ISD::VECREDUCE_XOR:
1316 Results.push_back(TLI.expandVecReduce(Node, DAG));
1317 return;
1322 Results.push_back(TLI.expandPartialReduceMLA(Node, DAG));
1323 return;
1326 Results.push_back(TLI.expandVecReduceSeq(Node, DAG));
1327 return;
1328 case ISD::VECTOR_MATCH:
1329 Results.push_back(TLI.expandVectorMatch(Node, DAG));
1330 return;
1331 case ISD::SREM:
1332 case ISD::UREM:
1333 ExpandREM(Node, Results);
1334 return;
1335 case ISD::VP_MERGE:
1336 if (SDValue Expanded = ExpandVP_MERGE(Node)) {
1337 Results.push_back(Expanded);
1338 return;
1339 }
1340 break;
1341 case ISD::FREM: {
1342 RTLIB::Libcall LC = RTLIB::getREM(Node->getValueType(0));
1343 if (tryExpandVecMathCall(Node, LC, Results))
1344 return;
1345
1346 break;
1347 }
1348 case ISD::FSINCOS:
1349 case ISD::FSINCOSPI: {
1350 EVT VT = Node->getValueType(0);
1351 RTLIB::Libcall LC = Node->getOpcode() == ISD::FSINCOS
1352 ? RTLIB::getSINCOS(VT)
1353 : RTLIB::getSINCOSPI(VT);
1354 if (LC != RTLIB::UNKNOWN_LIBCALL &&
1355 TLI.expandMultipleResultFPLibCall(DAG, LC, Node, Results))
1356 return;
1357
1358 // TODO: Try to see if there's a narrower call available to use before
1359 // scalarizing.
1360 break;
1361 }
1362 case ISD::FPOW: {
1363 RTLIB::Libcall LC = RTLIB::getPOW(Node->getValueType(0));
1364 if (tryExpandVecMathCall(Node, LC, Results))
1365 return;
1366
1367 // TODO: Try to see if there's a narrower call available to use before
1368 // scalarizing.
1369 break;
1370 }
1371 case ISD::FCBRT: {
1372 RTLIB::Libcall LC = RTLIB::getCBRT(Node->getValueType(0));
1373 if (tryExpandVecMathCall(Node, LC, Results))
1374 return;
1375
1376 // TODO: Try to see if there's a narrower call available to use before
1377 // scalarizing.
1378 break;
1379 }
1380 case ISD::FMODF: {
1381 EVT VT = Node->getValueType(0);
1382 RTLIB::Libcall LC = RTLIB::getMODF(VT);
1383 if (LC != RTLIB::UNKNOWN_LIBCALL &&
1384 TLI.expandMultipleResultFPLibCall(DAG, LC, Node, Results,
1385 /*CallRetResNo=*/0))
1386 return;
1387 break;
1388 }
1390 Results.push_back(TLI.expandVECTOR_COMPRESS(Node, DAG));
1391 return;
1392 case ISD::CTTZ_ELTS:
1394 Results.push_back(TLI.expandCttzElts(Node, DAG));
1395 return;
1397 Results.push_back(TLI.expandVectorFindLastActive(Node, DAG));
1398 return;
1399 case ISD::SCMP:
1400 case ISD::UCMP:
1401 Results.push_back(TLI.expandCMP(Node, DAG));
1402 return;
1405 Results.push_back(ExpandLOOP_DEPENDENCE_MASK(Node));
1406 return;
1407
1408 case ISD::FADD:
1409 case ISD::FMUL:
1410 case ISD::FMA:
1411 case ISD::FDIV:
1412 case ISD::FCEIL:
1413 case ISD::FFLOOR:
1414 case ISD::FNEARBYINT:
1415 case ISD::FRINT:
1416 case ISD::FROUND:
1417 case ISD::FROUNDEVEN:
1418 case ISD::FTRUNC:
1419 case ISD::FSQRT:
1420 if (SDValue Expanded = TLI.expandVectorNaryOpBySplitting(Node, DAG)) {
1421 Results.push_back(Expanded);
1422 return;
1423 }
1424 break;
1426 if (SDValue Expanded = TLI.expandCONVERT_TO_ARBITRARY_FP(Node, DAG))
1427 Results.push_back(Expanded);
1428 else
1429 Results.push_back(DAG.getPOISON(Node->getValueType(0)));
1430 return;
1432 if (SDValue Expanded = TLI.expandCONVERT_FROM_ARBITRARY_FP(Node, DAG))
1433 Results.push_back(Expanded);
1434 else
1435 Results.push_back(DAG.getPOISON(Node->getValueType(0)));
1436 return;
1437 case ISD::MASKED_UDIV:
1438 case ISD::MASKED_SDIV:
1439 case ISD::MASKED_UREM:
1440 case ISD::MASKED_SREM:
1441 Results.push_back(ExpandMaskedBinOp(Node));
1442 return;
1443 }
1444
1445 SDValue Unrolled = DAG.UnrollVectorOp(Node);
1446 if (Node->getNumValues() == 1) {
1447 Results.push_back(Unrolled);
1448 } else {
1449 assert(Node->getNumValues() == Unrolled->getNumValues() &&
1450 "VectorLegalizer Expand returned wrong number of results!");
1451 for (unsigned I = 0, E = Unrolled->getNumValues(); I != E; ++I)
1452 Results.push_back(Unrolled.getValue(I));
1453 }
1454}
1455
1456SDValue VectorLegalizer::ExpandSELECT(SDNode *Node) {
1457 // Lower a select instruction where the condition is a scalar and the
1458 // operands are vectors. Lower this select to VSELECT and implement it
1459 // using XOR AND OR. The selector bit is broadcasted.
1460 EVT VT = Node->getValueType(0);
1461 SDLoc DL(Node);
1462
1463 SDValue Mask = Node->getOperand(0);
1464 SDValue Op1 = Node->getOperand(1);
1465 SDValue Op2 = Node->getOperand(2);
1466
1467 assert(VT.isVector() && !Mask.getValueType().isVector()
1468 && Op1.getValueType() == Op2.getValueType() && "Invalid type");
1469
1470 // If we can't even use the basic vector operations of
1471 // AND,OR,XOR, we will have to scalarize the op.
1472 // Notice that the operation may be 'promoted' which means that it is
1473 // 'bitcasted' to another type which is handled.
1474 // Also, we need to be able to construct a splat vector using either
1475 // BUILD_VECTOR or SPLAT_VECTOR.
1476 // FIXME: Should we also permit fixed-length SPLAT_VECTOR as a fallback to
1477 // BUILD_VECTOR?
1478 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1479 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1480 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
1483 VT) == TargetLowering::Expand)
1484 return SDValue();
1485
1486 // Generate a mask operand.
1487 EVT MaskTy = VT.changeVectorElementTypeToInteger();
1488
1489 // What is the size of each element in the vector mask.
1490 EVT BitTy = MaskTy.getScalarType();
1491
1492 Mask = DAG.getSelect(DL, BitTy, Mask, DAG.getAllOnesConstant(DL, BitTy),
1493 DAG.getConstant(0, DL, BitTy));
1494
1495 // Broadcast the mask so that the entire vector is all one or all zero.
1496 Mask = DAG.getSplat(MaskTy, DL, Mask);
1497
1498 // Bitcast the operands to be the same type as the mask.
1499 // This is needed when we select between FP types because
1500 // the mask is a vector of integers.
1501 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1);
1502 Op2 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op2);
1503
1504 SDValue NotMask = DAG.getNOT(DL, Mask, MaskTy);
1505
1506 Op1 = DAG.getNode(ISD::AND, DL, MaskTy, Op1, Mask);
1507 Op2 = DAG.getNode(ISD::AND, DL, MaskTy, Op2, NotMask);
1508 SDValue Val = DAG.getNode(ISD::OR, DL, MaskTy, Op1, Op2);
1509 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1510}
1511
1512SDValue VectorLegalizer::ExpandSEXTINREG(SDNode *Node) {
1513 EVT VT = Node->getValueType(0);
1514
1515 // Make sure that the SRA and SHL instructions are available.
1516 if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Expand ||
1517 TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Expand)
1518 return SDValue();
1519
1520 SDLoc DL(Node);
1521 EVT OrigTy = cast<VTSDNode>(Node->getOperand(1))->getVT();
1522
1523 unsigned BW = VT.getScalarSizeInBits();
1524 unsigned OrigBW = OrigTy.getScalarSizeInBits();
1525 SDValue ShiftSz = DAG.getConstant(BW - OrigBW, DL, VT);
1526
1527 SDValue Op = DAG.getNode(ISD::SHL, DL, VT, Node->getOperand(0), ShiftSz);
1528 return DAG.getNode(ISD::SRA, DL, VT, Op, ShiftSz);
1529}
1530
1531// Generically expand a vector anyext in register to a shuffle of the relevant
1532// lanes into the appropriate locations, with other lanes left undef.
1533SDValue VectorLegalizer::ExpandANY_EXTEND_VECTOR_INREG(SDNode *Node) {
1534 SDLoc DL(Node);
1535 EVT VT = Node->getValueType(0);
1536 int NumElements = VT.getVectorNumElements();
1537 SDValue Src = Node->getOperand(0);
1538 EVT SrcVT = Src.getValueType();
1539 int NumSrcElements = SrcVT.getVectorNumElements();
1540
1541 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1542 // into a larger vector type.
1543 if (SrcVT.bitsLE(VT)) {
1544 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1545 "ANY_EXTEND_VECTOR_INREG vector size mismatch");
1546 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1547 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1548 NumSrcElements);
1549 Src = DAG.getInsertSubvector(DL, DAG.getUNDEF(SrcVT), Src, 0);
1550 }
1551
1552 // Build a base mask of undef shuffles.
1553 SmallVector<int, 16> ShuffleMask;
1554 ShuffleMask.resize(NumSrcElements, -1);
1555
1556 // Place the extended lanes into the correct locations.
1557 int ExtLaneScale = NumSrcElements / NumElements;
1558 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1559 for (int i = 0; i < NumElements; ++i)
1560 ShuffleMask[i * ExtLaneScale + EndianOffset] = i;
1561
1562 return DAG.getNode(
1563 ISD::BITCAST, DL, VT,
1564 DAG.getVectorShuffle(SrcVT, DL, Src, DAG.getPOISON(SrcVT), ShuffleMask));
1565}
1566
1567SDValue VectorLegalizer::ExpandSIGN_EXTEND_VECTOR_INREG(SDNode *Node) {
1568 SDLoc DL(Node);
1569 EVT VT = Node->getValueType(0);
1570 SDValue Src = Node->getOperand(0);
1571 EVT SrcVT = Src.getValueType();
1572
1573 // First build an any-extend node which can be legalized above when we
1574 // recurse through it.
1576
1577 // Now we need sign extend. This will be exanded to shifts if it isn't
1578 // supported.
1579 EVT ExtVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getVectorElementType(),
1581 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Op,
1582 DAG.getValueType(ExtVT));
1583}
1584
1585// Generically expand a vector zext in register to a shuffle of the relevant
1586// lanes into the appropriate locations, a blend of zero into the high bits,
1587// and a bitcast to the wider element type.
1588SDValue VectorLegalizer::ExpandZERO_EXTEND_VECTOR_INREG(SDNode *Node) {
1589 SDLoc DL(Node);
1590 EVT VT = Node->getValueType(0);
1591 int NumElements = VT.getVectorNumElements();
1592 SDValue Src = Node->getOperand(0);
1593 EVT SrcVT = Src.getValueType();
1594 int NumSrcElements = SrcVT.getVectorNumElements();
1595
1596 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1597 // into a larger vector type.
1598 if (SrcVT.bitsLE(VT)) {
1599 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1600 "ZERO_EXTEND_VECTOR_INREG vector size mismatch");
1601 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1602 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1603 NumSrcElements);
1604 Src = DAG.getInsertSubvector(DL, DAG.getUNDEF(SrcVT), Src, 0);
1605 }
1606
1607 // Build up a zero vector to blend into this one.
1608 SDValue Zero = DAG.getConstant(0, DL, SrcVT);
1609
1610 // Shuffle the incoming lanes into the correct position, and pull all other
1611 // lanes from the zero vector.
1612 auto ShuffleMask = llvm::to_vector<16>(llvm::seq<int>(0, NumSrcElements));
1613
1614 int ExtLaneScale = NumSrcElements / NumElements;
1615 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1616 for (int i = 0; i < NumElements; ++i)
1617 ShuffleMask[i * ExtLaneScale + EndianOffset] = NumSrcElements + i;
1618
1619 return DAG.getNode(ISD::BITCAST, DL, VT,
1620 DAG.getVectorShuffle(SrcVT, DL, Zero, Src, ShuffleMask));
1621}
1622
1623static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) {
1624 int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;
1625 for (int I = 0, E = VT.getVectorNumElements(); I != E; ++I)
1626 for (int J = ScalarSizeInBytes - 1; J >= 0; --J)
1627 ShuffleMask.push_back((I * ScalarSizeInBytes) + J);
1628}
1629
1630SDValue VectorLegalizer::ExpandBSWAP(SDNode *Node) {
1631 EVT VT = Node->getValueType(0);
1632
1633 // Scalable vectors can't use shuffle expansion.
1634 if (VT.isScalableVector())
1635 return TLI.expandBSWAP(Node, DAG);
1636
1637 // Generate a byte wise shuffle mask for the BSWAP.
1638 SmallVector<int, 16> ShuffleMask;
1639 createBSWAPShuffleMask(VT, ShuffleMask);
1640 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, ShuffleMask.size());
1641
1642 // Only emit a shuffle if the mask is legal.
1643 if (TLI.isShuffleMaskLegal(ShuffleMask, ByteVT)) {
1644 SDLoc DL(Node);
1645 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1646 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getPOISON(ByteVT),
1647 ShuffleMask);
1648 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
1649 }
1650
1651 // If we have the appropriate vector bit operations, it is better to use them
1652 // than unrolling and expanding each component.
1653 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1657 return TLI.expandBSWAP(Node, DAG);
1658
1659 // Otherwise let the caller unroll.
1660 return SDValue();
1661}
1662
1663SDValue VectorLegalizer::ExpandBITREVERSE(SDNode *Node) {
1664 EVT VT = Node->getValueType(0);
1665
1666 // We can't unroll or use shuffles for scalable vectors.
1667 if (VT.isScalableVector())
1668 return TLI.expandBITREVERSE(Node, DAG);
1669
1670 // If we have the scalar operation, it's probably cheaper to unroll it.
1672 return SDValue();
1673
1674 // If the vector element width is a whole number of bytes, test if its legal
1675 // to BSWAP shuffle the bytes and then perform the BITREVERSE on the byte
1676 // vector. This greatly reduces the number of bit shifts necessary.
1677 unsigned ScalarSizeInBits = VT.getScalarSizeInBits();
1678 if (ScalarSizeInBits > 8 && (ScalarSizeInBits % 8) == 0) {
1679 SmallVector<int, 16> BSWAPMask;
1680 createBSWAPShuffleMask(VT, BSWAPMask);
1681
1682 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, BSWAPMask.size());
1683 if (TLI.isShuffleMaskLegal(BSWAPMask, ByteVT) &&
1685 (TLI.isOperationLegalOrCustom(ISD::SHL, ByteVT) &&
1686 TLI.isOperationLegalOrCustom(ISD::SRL, ByteVT) &&
1689 SDLoc DL(Node);
1690 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1691 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getPOISON(ByteVT),
1692 BSWAPMask);
1693 Op = DAG.getNode(ISD::BITREVERSE, DL, ByteVT, Op);
1694 Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
1695 return Op;
1696 }
1697 }
1698
1699 // If we have the appropriate vector bit operations, it is better to use them
1700 // than unrolling and expanding each component.
1701 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1705 return TLI.expandBITREVERSE(Node, DAG);
1706
1707 // Otherwise unroll.
1708 return SDValue();
1709}
1710
1711SDValue VectorLegalizer::ExpandVSELECT(SDNode *Node) {
1712 // Implement VSELECT in terms of XOR, AND, OR
1713 // on platforms which do not support blend natively.
1714 SDLoc DL(Node);
1715
1716 SDValue Mask = Node->getOperand(0);
1717 SDValue Op1 = Node->getOperand(1);
1718 SDValue Op2 = Node->getOperand(2);
1719
1720 EVT VT = Mask.getValueType();
1721
1722 // If we can't even use the basic vector operations of
1723 // AND,OR,XOR, we will have to scalarize the op.
1724 // Notice that the operation may be 'promoted' which means that it is
1725 // 'bitcasted' to another type which is handled.
1726 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1727 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1728 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand)
1729 return SDValue();
1730
1731 // This operation also isn't safe with AND, OR, XOR when the boolean type is
1732 // 0/1 and the select operands aren't also booleans, as we need an all-ones
1733 // vector constant to mask with.
1734 // FIXME: Sign extend 1 to all ones if that's legal on the target.
1735 auto BoolContents = TLI.getBooleanContents(Op1.getValueType());
1736 if (BoolContents != TargetLowering::ZeroOrNegativeOneBooleanContent &&
1737 !(BoolContents == TargetLowering::ZeroOrOneBooleanContent &&
1738 Op1.getValueType().getVectorElementType() == MVT::i1))
1739 return SDValue();
1740
1741 // If the mask and the type are different sizes, unroll the vector op. This
1742 // can occur when getSetCCResultType returns something that is different in
1743 // size from the operand types. For example, v4i8 = select v4i32, v4i8, v4i8.
1744 if (VT.getSizeInBits() != Op1.getValueSizeInBits())
1745 return SDValue();
1746
1747 // Bitcast the operands to be the same type as the mask.
1748 // This is needed when we select between FP types because
1749 // the mask is a vector of integers.
1750 Op1 = DAG.getNode(ISD::BITCAST, DL, VT, Op1);
1751 Op2 = DAG.getNode(ISD::BITCAST, DL, VT, Op2);
1752
1753 SDValue NotMask = DAG.getNOT(DL, Mask, VT);
1754
1755 Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask);
1756 Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask);
1757 SDValue Val = DAG.getNode(ISD::OR, DL, VT, Op1, Op2);
1758 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1759}
1760
1761SDValue VectorLegalizer::ExpandVP_SELECT(SDNode *Node) {
1762 // Implement VP_SELECT in terms of VP_XOR, VP_AND and VP_OR on platforms which
1763 // do not support it natively.
1764 SDLoc DL(Node);
1765
1766 SDValue Mask = Node->getOperand(0);
1767 SDValue Op1 = Node->getOperand(1);
1768 SDValue Op2 = Node->getOperand(2);
1769 SDValue EVL = Node->getOperand(3);
1770
1771 EVT VT = Mask.getValueType();
1772
1773 // If we can't even use the basic vector operations of
1774 // VP_AND,VP_OR,VP_XOR, we will have to scalarize the op.
1775 if (TLI.getOperationAction(ISD::VP_AND, VT) == TargetLowering::Expand ||
1776 TLI.getOperationAction(ISD::VP_XOR, VT) == TargetLowering::Expand ||
1777 TLI.getOperationAction(ISD::VP_OR, VT) == TargetLowering::Expand)
1778 return SDValue();
1779
1780 // This operation also isn't safe when the operands aren't also booleans.
1781 if (Op1.getValueType().getVectorElementType() != MVT::i1)
1782 return SDValue();
1783
1784 SDValue Ones = DAG.getAllOnesConstant(DL, VT);
1785 SDValue NotMask = DAG.getNode(ISD::VP_XOR, DL, VT, Mask, Ones, Ones, EVL);
1786
1787 Op1 = DAG.getNode(ISD::VP_AND, DL, VT, Op1, Mask, Ones, EVL);
1788 Op2 = DAG.getNode(ISD::VP_AND, DL, VT, Op2, NotMask, Ones, EVL);
1789 return DAG.getNode(ISD::VP_OR, DL, VT, Op1, Op2, Ones, EVL);
1790}
1791
1792SDValue VectorLegalizer::ExpandVP_MERGE(SDNode *Node) {
1793 // Implement VP_MERGE in terms of VSELECT. Construct a mask where vector
1794 // indices less than the EVL/pivot are true. Combine that with the original
1795 // mask for a full-length mask. Use a full-length VSELECT to select between
1796 // the true and false values.
1797 SDLoc DL(Node);
1798
1799 SDValue Mask = Node->getOperand(0);
1800 SDValue Op1 = Node->getOperand(1);
1801 SDValue Op2 = Node->getOperand(2);
1802 SDValue EVL = Node->getOperand(3);
1803
1804 EVT MaskVT = Mask.getValueType();
1805 bool IsFixedLen = MaskVT.isFixedLengthVector();
1806
1807 EVT EVLVecVT = EVT::getVectorVT(*DAG.getContext(), EVL.getValueType(),
1808 MaskVT.getVectorElementCount());
1809
1810 // If we can't construct the EVL mask efficiently, it's better to unroll.
1811 if ((IsFixedLen &&
1813 (!IsFixedLen &&
1814 (!TLI.isOperationLegalOrCustom(ISD::STEP_VECTOR, EVLVecVT) ||
1816 return SDValue();
1817
1818 // If using a SETCC would result in a different type than the mask type,
1819 // unroll.
1820 if (TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
1821 EVLVecVT) != MaskVT)
1822 return SDValue();
1823
1824 SDValue StepVec = DAG.getStepVector(DL, EVLVecVT);
1825 SDValue SplatEVL = DAG.getSplat(EVLVecVT, DL, EVL);
1826 SDValue EVLMask =
1827 DAG.getSetCC(DL, MaskVT, StepVec, SplatEVL, ISD::CondCode::SETULT);
1828
1829 SDValue FullMask = DAG.getNode(ISD::AND, DL, MaskVT, Mask, EVLMask);
1830 return DAG.getSelect(DL, Node->getValueType(0), FullMask, Op1, Op2);
1831}
1832
1833SDValue VectorLegalizer::ExpandVP_REM(SDNode *Node) {
1834 // Implement VP_SREM/UREM in terms of VP_SDIV/VP_UDIV, VP_MUL, VP_SUB.
1835 EVT VT = Node->getValueType(0);
1836
1837 unsigned DivOpc = Node->getOpcode() == ISD::VP_SREM ? ISD::VP_SDIV : ISD::VP_UDIV;
1838
1839 if (!TLI.isOperationLegalOrCustom(DivOpc, VT) ||
1840 !TLI.isOperationLegalOrCustom(ISD::VP_MUL, VT) ||
1841 !TLI.isOperationLegalOrCustom(ISD::VP_SUB, VT))
1842 return SDValue();
1843
1844 SDLoc DL(Node);
1845
1846 SDValue Dividend = Node->getOperand(0);
1847 SDValue Divisor = Node->getOperand(1);
1848 SDValue Mask = Node->getOperand(2);
1849 SDValue EVL = Node->getOperand(3);
1850
1851 // X % Y -> X-X/Y*Y
1852 SDValue Div = DAG.getNode(DivOpc, DL, VT, Dividend, Divisor, Mask, EVL);
1853 SDValue Mul = DAG.getNode(ISD::VP_MUL, DL, VT, Divisor, Div, Mask, EVL);
1854 return DAG.getNode(ISD::VP_SUB, DL, VT, Dividend, Mul, Mask, EVL);
1855}
1856
1857SDValue VectorLegalizer::ExpandVP_FNEG(SDNode *Node) {
1858 EVT VT = Node->getValueType(0);
1859 EVT IntVT = VT.changeVectorElementTypeToInteger();
1860
1861 if (!TLI.isOperationLegalOrCustom(ISD::VP_XOR, IntVT))
1862 return SDValue();
1863
1864 SDValue Mask = Node->getOperand(1);
1865 SDValue EVL = Node->getOperand(2);
1866
1867 SDLoc DL(Node);
1868 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1869 SDValue SignMask = DAG.getConstant(
1870 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
1871 SDValue Xor = DAG.getNode(ISD::VP_XOR, DL, IntVT, Cast, SignMask, Mask, EVL);
1872 return DAG.getNode(ISD::BITCAST, DL, VT, Xor);
1873}
1874
1875SDValue VectorLegalizer::ExpandVP_FABS(SDNode *Node) {
1876 EVT VT = Node->getValueType(0);
1877 EVT IntVT = VT.changeVectorElementTypeToInteger();
1878
1879 if (!TLI.isOperationLegalOrCustom(ISD::VP_AND, IntVT))
1880 return SDValue();
1881
1882 SDValue Mask = Node->getOperand(1);
1883 SDValue EVL = Node->getOperand(2);
1884
1885 SDLoc DL(Node);
1886 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1887 SDValue ClearSignMask = DAG.getConstant(
1889 SDValue ClearSign =
1890 DAG.getNode(ISD::VP_AND, DL, IntVT, Cast, ClearSignMask, Mask, EVL);
1891 return DAG.getNode(ISD::BITCAST, DL, VT, ClearSign);
1892}
1893
1894SDValue VectorLegalizer::ExpandVP_FCOPYSIGN(SDNode *Node) {
1895 EVT VT = Node->getValueType(0);
1896
1897 if (VT != Node->getOperand(1).getValueType())
1898 return SDValue();
1899
1900 EVT IntVT = VT.changeVectorElementTypeToInteger();
1901 if (!TLI.isOperationLegalOrCustom(ISD::VP_AND, IntVT) ||
1902 !TLI.isOperationLegalOrCustom(ISD::VP_XOR, IntVT))
1903 return SDValue();
1904
1905 SDValue Mask = Node->getOperand(2);
1906 SDValue EVL = Node->getOperand(3);
1907
1908 SDLoc DL(Node);
1909 SDValue Mag = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1910 SDValue Sign = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(1));
1911
1912 SDValue SignMask = DAG.getConstant(
1913 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
1914 SDValue SignBit =
1915 DAG.getNode(ISD::VP_AND, DL, IntVT, Sign, SignMask, Mask, EVL);
1916
1917 SDValue ClearSignMask = DAG.getConstant(
1919 SDValue ClearedSign =
1920 DAG.getNode(ISD::VP_AND, DL, IntVT, Mag, ClearSignMask, Mask, EVL);
1921
1922 SDValue CopiedSign = DAG.getNode(ISD::VP_OR, DL, IntVT, ClearedSign, SignBit,
1923 Mask, EVL, SDNodeFlags::Disjoint);
1924
1925 return DAG.getNode(ISD::BITCAST, DL, VT, CopiedSign);
1926}
1927
1928SDValue VectorLegalizer::ExpandLOOP_DEPENDENCE_MASK(SDNode *N) {
1929 return TLI.expandLoopDependenceMask(N, DAG);
1930}
1931
1932SDValue VectorLegalizer::ExpandMaskedBinOp(SDNode *N) {
1933 // Masked bin ops don't have undefined behaviour when dividing by zero
1934 // on disabled lanes and produce poison instead. Replace the divisor on the
1935 // disabled lanes with 1 to avoid division by zero or overflow.
1936 SDLoc dl(N);
1937 EVT VT = N->getValueType(0);
1938 SDValue SafeDivisor = DAG.getSelect(
1939 dl, VT, N->getOperand(2), N->getOperand(1), DAG.getConstant(1, dl, VT));
1940 return DAG.getNode(ISD::getUnmaskedBinOpOpcode(N->getOpcode()), dl, VT,
1941 N->getOperand(0), SafeDivisor);
1942}
1943
1944void VectorLegalizer::ExpandFP_TO_UINT(SDNode *Node,
1945 SmallVectorImpl<SDValue> &Results) {
1946 // Attempt to expand using TargetLowering.
1947 SDValue Result, Chain;
1948 if (TLI.expandFP_TO_UINT(Node, Result, Chain, DAG)) {
1949 Results.push_back(Result);
1950 if (Node->isStrictFPOpcode())
1951 Results.push_back(Chain);
1952 return;
1953 }
1954
1955 // Otherwise go ahead and unroll.
1956 if (Node->isStrictFPOpcode()) {
1957 UnrollStrictFPOp(Node, Results);
1958 return;
1959 }
1960
1961 Results.push_back(DAG.UnrollVectorOp(Node));
1962}
1963
1964void VectorLegalizer::ExpandUINT_TO_FLOAT(SDNode *Node,
1965 SmallVectorImpl<SDValue> &Results) {
1966 bool IsStrict = Node->isStrictFPOpcode();
1967 unsigned OpNo = IsStrict ? 1 : 0;
1968 SDValue Src = Node->getOperand(OpNo);
1969 EVT SrcVT = Src.getValueType();
1970 EVT DstVT = Node->getValueType(0);
1971 SDLoc DL(Node);
1972
1973 // Attempt to expand using TargetLowering.
1975 SDValue Chain;
1976 if (TLI.expandUINT_TO_FP(Node, Result, Chain, DAG)) {
1977 Results.push_back(Result);
1978 if (IsStrict)
1979 Results.push_back(Chain);
1980 return;
1981 }
1982
1983 // Make sure that the SINT_TO_FP and SRL instructions are available.
1984 if (((!IsStrict && TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) ==
1985 TargetLowering::Expand) ||
1986 (IsStrict && TLI.getOperationAction(ISD::STRICT_SINT_TO_FP, SrcVT) ==
1987 TargetLowering::Expand)) ||
1988 TLI.getOperationAction(ISD::SRL, SrcVT) == TargetLowering::Expand) {
1989 if (IsStrict) {
1990 UnrollStrictFPOp(Node, Results);
1991 return;
1992 }
1993
1994 Results.push_back(DAG.UnrollVectorOp(Node));
1995 return;
1996 }
1997
1998 unsigned BW = SrcVT.getScalarSizeInBits();
1999 assert((BW == 64 || BW == 32) &&
2000 "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide");
2001
2002 // If STRICT_/FMUL is not supported by the target (in case of f16) replace the
2003 // UINT_TO_FP with a larger float and round to the smaller type
2004 if ((!IsStrict && !TLI.isOperationLegalOrCustom(ISD::FMUL, DstVT)) ||
2005 (IsStrict && !TLI.isOperationLegalOrCustom(ISD::STRICT_FMUL, DstVT))) {
2006 EVT FPVT = BW == 32 ? MVT::f32 : MVT::f64;
2007 SDValue UIToFP;
2009 SDValue TargetZero = DAG.getIntPtrConstant(0, DL, /*isTarget=*/true);
2010 EVT FloatVecVT = SrcVT.changeVectorElementType(*DAG.getContext(), FPVT);
2011 if (IsStrict) {
2012 UIToFP = DAG.getNode(ISD::STRICT_UINT_TO_FP, DL, {FloatVecVT, MVT::Other},
2013 {Node->getOperand(0), Src});
2014 Result = DAG.getNode(ISD::STRICT_FP_ROUND, DL, {DstVT, MVT::Other},
2015 {Node->getOperand(0), UIToFP, TargetZero});
2016 Results.push_back(Result);
2017 Results.push_back(Result.getValue(1));
2018 } else {
2019 UIToFP = DAG.getNode(ISD::UINT_TO_FP, DL, FloatVecVT, Src);
2020 Result = DAG.getNode(ISD::FP_ROUND, DL, DstVT, UIToFP, TargetZero);
2021 Results.push_back(Result);
2022 }
2023
2024 return;
2025 }
2026
2027 SDValue HalfWord = DAG.getConstant(BW / 2, DL, SrcVT);
2028
2029 // Constants to clear the upper part of the word.
2030 // Notice that we can also use SHL+SHR, but using a constant is slightly
2031 // faster on x86.
2032 uint64_t HWMask = (BW == 64) ? 0x00000000FFFFFFFF : 0x0000FFFF;
2033 SDValue HalfWordMask = DAG.getConstant(HWMask, DL, SrcVT);
2034
2035 // Two to the power of half-word-size.
2036 SDValue TWOHW = DAG.getConstantFP(1ULL << (BW / 2), DL, DstVT);
2037
2038 // Clear upper part of LO, lower HI
2039 SDValue HI = DAG.getNode(ISD::SRL, DL, SrcVT, Src, HalfWord);
2040 SDValue LO = DAG.getNode(ISD::AND, DL, SrcVT, Src, HalfWordMask);
2041
2042 if (IsStrict) {
2043 // Convert hi and lo to floats
2044 // Convert the hi part back to the upper values
2045 // TODO: Can any fast-math-flags be set on these nodes?
2046 SDValue fHI = DAG.getNode(ISD::STRICT_SINT_TO_FP, DL, {DstVT, MVT::Other},
2047 {Node->getOperand(0), HI});
2048 fHI = DAG.getNode(ISD::STRICT_FMUL, DL, {DstVT, MVT::Other},
2049 {fHI.getValue(1), fHI, TWOHW});
2050 SDValue fLO = DAG.getNode(ISD::STRICT_SINT_TO_FP, DL, {DstVT, MVT::Other},
2051 {Node->getOperand(0), LO});
2052
2053 SDValue TF = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, fHI.getValue(1),
2054 fLO.getValue(1));
2055
2056 // Add the two halves
2057 SDValue Result =
2058 DAG.getNode(ISD::STRICT_FADD, DL, {DstVT, MVT::Other}, {TF, fHI, fLO});
2059
2060 Results.push_back(Result);
2061 Results.push_back(Result.getValue(1));
2062 return;
2063 }
2064
2065 // Convert hi and lo to floats
2066 // Convert the hi part back to the upper values
2067 // TODO: Can any fast-math-flags be set on these nodes?
2068 SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, DstVT, HI);
2069 fHI = DAG.getNode(ISD::FMUL, DL, DstVT, fHI, TWOHW);
2070 SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, DstVT, LO);
2071
2072 // Add the two halves
2073 Results.push_back(DAG.getNode(ISD::FADD, DL, DstVT, fHI, fLO));
2074}
2075
2076SDValue VectorLegalizer::ExpandFNEG(SDNode *Node) {
2077 EVT VT = Node->getValueType(0);
2078 EVT IntVT = VT.changeVectorElementTypeToInteger();
2079
2080 if (!TLI.isOperationLegalOrCustom(ISD::XOR, IntVT))
2081 return SDValue();
2082
2083 // Heuristic check to determine whether vector should be expanded to integer
2084 // operations or unrolled to scalar operations.
2085 // 1. Scalable vector is never unrolled.
2086 // 2. Fixed vector is unrolled if one of followings is true:
2087 // a. Vector only has 1 element and target knows how to handle scalar
2088 // FNEG (either legal or custom expand or promote).
2089 // b. Vector has more than 1 element and target supports scalar
2090 // FNEG natively and vector length <= 2(1 XOR + 1 CONST).
2091 // FIXME: Scalar construction instruction count varies in every architecture,
2092 // here we assume 1 instruction for now.
2093 if (VT.isFixedLengthVector()) {
2094 EVT EltVT = VT.getVectorElementType();
2095 unsigned NumElts = VT.getVectorNumElements();
2096 if ((NumElts == 1 &&
2098 (NumElts < 3 && TLI.isOperationLegal(ISD::FNEG, EltVT) &&
2099 TLI.isExtractVecEltCheap(VT, 0) &&
2100 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
2101 return SDValue();
2102 }
2103
2104 SDLoc DL(Node);
2105 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
2106 SDValue SignMask = DAG.getConstant(
2107 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
2108 SDValue Xor = DAG.getNode(ISD::XOR, DL, IntVT, Cast, SignMask);
2109 return DAG.getNode(ISD::BITCAST, DL, VT, Xor);
2110}
2111
2112SDValue VectorLegalizer::ExpandFABS(SDNode *Node) {
2113 EVT VT = Node->getValueType(0);
2114 EVT IntVT = VT.changeVectorElementTypeToInteger();
2115
2116 if (!TLI.isOperationLegalOrCustom(ISD::AND, IntVT))
2117 return SDValue();
2118
2119 // Heuristic check to determine whether vector should be expanded to integer
2120 // operations or unrolled to scalar operations.
2121 // 1. Scalable vector is never unrolled.
2122 // 2. Fixed vector is unrolled if one of followings is true:
2123 // a. Vector only has 1 element and target knows how to handle scalar
2124 // FABS(either legal or custom expand or promote).
2125 // b. Vector has more than 1 element and target supports scalar
2126 // FABS natively and vector length <= 2(1 AND + 1 CONST).
2127 // FIXME: Scalar construction instruction count varies in every architecture,
2128 // here we assume 1 instruction for now.
2129 if (VT.isFixedLengthVector()) {
2130 EVT EltVT = VT.getVectorElementType();
2131 unsigned NumElts = VT.getVectorNumElements();
2132 if ((NumElts == 1 &&
2134 (NumElts < 3 && TLI.isOperationLegal(ISD::FABS, EltVT) &&
2135 TLI.isExtractVecEltCheap(VT, 0) &&
2136 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
2137 return SDValue();
2138 }
2139
2140 SDLoc DL(Node);
2141 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
2142 SDValue ClearSignMask = DAG.getConstant(
2144 SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, Cast, ClearSignMask);
2145 return DAG.getNode(ISD::BITCAST, DL, VT, ClearedSign);
2146}
2147
2148SDValue VectorLegalizer::ExpandFCOPYSIGN(SDNode *Node) {
2149 EVT VT = Node->getValueType(0);
2150 EVT IntVT = VT.changeVectorElementTypeToInteger();
2151
2152 if (VT != Node->getOperand(1).getValueType() ||
2153 !TLI.isOperationLegalOrCustom(ISD::AND, IntVT) ||
2154 !TLI.isOperationLegalOrCustom(ISD::OR, IntVT))
2155 return SDValue();
2156
2157 // Heuristic check to determine whether vector should be expanded to integer
2158 // operations or unrolled to scalar operations.
2159 // 1. Scalable vector is never unrolled.
2160 // 2. Fixed vector is unrolled if one of followings is true:
2161 // a. Vector only has 1 element and target knows how to handle scalar
2162 // FCOPYSIGN(either legal or custom expand or promote).
2163 // b. Vector has more than 1 element and target supports scalar
2164 // FCOPYSIGN natively and vector length <= 5(2 AND + 1 OR + 2 CONST).
2165 // FIXME: Scalar construction instruction count varies in every architecture,
2166 // here we assume 1 instruction for now.
2167 if (VT.isFixedLengthVector()) {
2168 EVT EltVT = VT.getVectorElementType();
2169 unsigned NumElts = VT.getVectorNumElements();
2170 if ((NumElts == 1 &&
2172 (NumElts < 6 && TLI.isOperationLegal(ISD::FCOPYSIGN, EltVT) &&
2173 TLI.isExtractVecEltCheap(VT, 0) &&
2174 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
2175 return SDValue();
2176 }
2177
2178 SDLoc DL(Node);
2179 SDValue Mag = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
2180 SDValue Sign = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(1));
2181
2182 SDValue SignMask = DAG.getConstant(
2183 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
2184 SDValue SignBit = DAG.getNode(ISD::AND, DL, IntVT, Sign, SignMask);
2185
2186 SDValue ClearSignMask = DAG.getConstant(
2188 SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, Mag, ClearSignMask);
2189
2190 SDValue CopiedSign = DAG.getNode(ISD::OR, DL, IntVT, ClearedSign, SignBit,
2192
2193 return DAG.getNode(ISD::BITCAST, DL, VT, CopiedSign);
2194}
2195
2196void VectorLegalizer::ExpandFSUB(SDNode *Node,
2197 SmallVectorImpl<SDValue> &Results) {
2198 // For floating-point values, (a-b) is the same as a+(-b). If FNEG is legal,
2199 // we can defer this to operation legalization where it will be lowered as
2200 // a+(-b).
2201 EVT VT = Node->getValueType(0);
2202 if (TLI.isOperationLegalOrCustom(ISD::FNEG, VT) &&
2204 return; // Defer to LegalizeDAG
2205
2206 if (SDValue Expanded = TLI.expandVectorNaryOpBySplitting(Node, DAG)) {
2207 Results.push_back(Expanded);
2208 return;
2209 }
2210
2211 SDValue Tmp = DAG.UnrollVectorOp(Node);
2212 Results.push_back(Tmp);
2213}
2214
2215void VectorLegalizer::ExpandSETCC(SDNode *Node,
2216 SmallVectorImpl<SDValue> &Results) {
2217 bool NeedInvert = false;
2218 bool IsVP = Node->getOpcode() == ISD::VP_SETCC;
2219 bool IsStrict = Node->getOpcode() == ISD::STRICT_FSETCC ||
2220 Node->getOpcode() == ISD::STRICT_FSETCCS;
2221 bool IsSignaling = Node->getOpcode() == ISD::STRICT_FSETCCS;
2222 unsigned Offset = IsStrict ? 1 : 0;
2223
2224 SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
2225 SDValue LHS = Node->getOperand(0 + Offset);
2226 SDValue RHS = Node->getOperand(1 + Offset);
2227 SDValue CC = Node->getOperand(2 + Offset);
2228
2229 MVT OpVT = LHS.getSimpleValueType();
2230 ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
2231
2232 if (TLI.getCondCodeAction(CCCode, OpVT) != TargetLowering::Expand) {
2233 if (IsStrict) {
2234 UnrollStrictFPOp(Node, Results);
2235 return;
2236 }
2237 Results.push_back(UnrollVSETCC(Node));
2238 return;
2239 }
2240
2241 SDValue Mask, EVL;
2242 if (IsVP) {
2243 Mask = Node->getOperand(3 + Offset);
2244 EVL = Node->getOperand(4 + Offset);
2245 }
2246
2247 SDLoc dl(Node);
2248 bool Legalized =
2249 TLI.LegalizeSetCCCondCode(DAG, Node->getValueType(0), LHS, RHS, CC, Mask,
2250 EVL, NeedInvert, dl, Chain, IsSignaling);
2251
2252 if (Legalized) {
2253 // If we expanded the SETCC by swapping LHS and RHS, or by inverting the
2254 // condition code, create a new SETCC node.
2255 if (CC.getNode()) {
2256 if (IsStrict) {
2257 LHS = DAG.getNode(Node->getOpcode(), dl, Node->getVTList(),
2258 {Chain, LHS, RHS, CC}, Node->getFlags());
2259 Chain = LHS.getValue(1);
2260 } else if (IsVP) {
2261 LHS = DAG.getNode(ISD::VP_SETCC, dl, Node->getValueType(0),
2262 {LHS, RHS, CC, Mask, EVL}, Node->getFlags());
2263 } else {
2264 LHS = DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), LHS, RHS, CC,
2265 Node->getFlags());
2266 }
2267 }
2268
2269 // If we expanded the SETCC by inverting the condition code, then wrap
2270 // the existing SETCC in a NOT to restore the intended condition.
2271 if (NeedInvert) {
2272 if (!IsVP)
2273 LHS = DAG.getLogicalNOT(dl, LHS, LHS->getValueType(0));
2274 else
2275 LHS = DAG.getVPLogicalNOT(dl, LHS, Mask, EVL, LHS->getValueType(0));
2276 }
2277 } else {
2278 assert(!IsStrict && "Don't know how to expand for strict nodes.");
2279
2280 // Otherwise, SETCC for the given comparison type must be completely
2281 // illegal; expand it into a SELECT_CC.
2282 EVT VT = Node->getValueType(0);
2283 LHS = DAG.getNode(ISD::SELECT_CC, dl, VT, LHS, RHS,
2284 DAG.getBoolConstant(true, dl, VT, LHS.getValueType()),
2285 DAG.getBoolConstant(false, dl, VT, LHS.getValueType()),
2286 CC, Node->getFlags());
2287 }
2288
2289 Results.push_back(LHS);
2290 if (IsStrict)
2291 Results.push_back(Chain);
2292}
2293
2294void VectorLegalizer::ExpandUADDSUBO(SDNode *Node,
2295 SmallVectorImpl<SDValue> &Results) {
2296 SDValue Result, Overflow;
2297 TLI.expandUADDSUBO(Node, Result, Overflow, DAG);
2298 Results.push_back(Result);
2299 Results.push_back(Overflow);
2300}
2301
2302void VectorLegalizer::ExpandSADDSUBO(SDNode *Node,
2303 SmallVectorImpl<SDValue> &Results) {
2304 SDValue Result, Overflow;
2305 TLI.expandSADDSUBO(Node, Result, Overflow, DAG);
2306 Results.push_back(Result);
2307 Results.push_back(Overflow);
2308}
2309
2310void VectorLegalizer::ExpandMULO(SDNode *Node,
2311 SmallVectorImpl<SDValue> &Results) {
2312 SDValue Result, Overflow;
2313 if (!TLI.expandMULO(Node, Result, Overflow, DAG))
2314 std::tie(Result, Overflow) = DAG.UnrollVectorOverflowOp(Node);
2315
2316 Results.push_back(Result);
2317 Results.push_back(Overflow);
2318}
2319
2320void VectorLegalizer::ExpandFixedPointDiv(SDNode *Node,
2321 SmallVectorImpl<SDValue> &Results) {
2322 SDNode *N = Node;
2323 if (SDValue Expanded = TLI.expandFixedPointDiv(N->getOpcode(), SDLoc(N),
2324 N->getOperand(0), N->getOperand(1), N->getConstantOperandVal(2), DAG))
2325 Results.push_back(Expanded);
2326}
2327
2328void VectorLegalizer::ExpandStrictFPOp(SDNode *Node,
2329 SmallVectorImpl<SDValue> &Results) {
2330 if (Node->getOpcode() == ISD::STRICT_UINT_TO_FP) {
2331 ExpandUINT_TO_FLOAT(Node, Results);
2332 return;
2333 }
2334 if (Node->getOpcode() == ISD::STRICT_FP_TO_UINT) {
2335 ExpandFP_TO_UINT(Node, Results);
2336 return;
2337 }
2338
2339 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2340 Node->getOpcode() == ISD::STRICT_FSETCCS) {
2341 ExpandSETCC(Node, Results);
2342 return;
2343 }
2344
2345 UnrollStrictFPOp(Node, Results);
2346}
2347
2348void VectorLegalizer::ExpandREM(SDNode *Node,
2349 SmallVectorImpl<SDValue> &Results) {
2350 assert((Node->getOpcode() == ISD::SREM || Node->getOpcode() == ISD::UREM) &&
2351 "Expected REM node");
2352
2354 if (!TLI.expandREM(Node, Result, DAG))
2355 Result = DAG.UnrollVectorOp(Node);
2356 Results.push_back(Result);
2357}
2358
2359// Try to expand libm nodes into vector math routine calls. Callers provide the
2360// LibFunc equivalent of the passed in Node, which is used to lookup mappings
2361// within TargetLibraryInfo. The only mappings considered are those where the
2362// result and all operands are the same vector type. While predicated nodes are
2363// not supported, we will emit calls to masked routines by passing in an all
2364// true mask.
2365bool VectorLegalizer::tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall LC,
2366 SmallVectorImpl<SDValue> &Results) {
2367 // Chain must be propagated but currently strict fp operations are down
2368 // converted to their none strict counterpart.
2369 assert(!Node->isStrictFPOpcode() && "Unexpected strict fp operation!");
2370
2371 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2372 if (LCImpl == RTLIB::Unsupported)
2373 return false;
2374
2375 EVT VT = Node->getValueType(0);
2376 const RTLIB::RuntimeLibcallsInfo &RTLCI = TLI.getRuntimeLibcallsInfo();
2377 LLVMContext &Ctx = *DAG.getContext();
2378
2379 auto [FuncTy, FuncAttrs] = RTLCI.getFunctionTy(
2380 Ctx, DAG.getSubtarget().getTargetTriple(), DAG.getDataLayout(), LCImpl);
2381
2382 SDLoc DL(Node);
2383 TargetLowering::ArgListTy Args;
2384
2385 bool HasMaskArg = RTLCI.hasVectorMaskArgument(LCImpl);
2386
2387 // Sanity check just in case function has unexpected parameters.
2388 assert(FuncTy->getNumParams() == Node->getNumOperands() + HasMaskArg &&
2389 EVT::getEVT(FuncTy->getReturnType(), true) == VT &&
2390 "mismatch in value type and call signature type");
2391
2392 for (unsigned I = 0, E = FuncTy->getNumParams(); I != E; ++I) {
2393 Type *ParamTy = FuncTy->getParamType(I);
2394
2395 if (HasMaskArg && I == E - 1) {
2396 assert(cast<VectorType>(ParamTy)->getElementType()->isIntegerTy(1) &&
2397 "unexpected vector mask type");
2398 EVT MaskVT = TLI.getSetCCResultType(DAG.getDataLayout(), Ctx, VT);
2399 Args.emplace_back(DAG.getBoolConstant(true, DL, MaskVT, VT),
2400 MaskVT.getTypeForEVT(Ctx));
2401
2402 } else {
2403 SDValue Op = Node->getOperand(I);
2404 assert(Op.getValueType() == EVT::getEVT(ParamTy, true) &&
2405 "mismatch in value type and call argument type");
2406 Args.emplace_back(Op, ParamTy);
2407 }
2408 }
2409
2410 // Emit a call to the vector function.
2411 SDValue Callee =
2412 DAG.getExternalSymbol(LCImpl, TLI.getPointerTy(DAG.getDataLayout()));
2413 CallingConv::ID CC = RTLCI.getLibcallImplCallingConv(LCImpl);
2414
2415 TargetLowering::CallLoweringInfo CLI(DAG);
2416 CLI.setDebugLoc(DL)
2417 .setChain(DAG.getEntryNode())
2418 .setLibCallee(CC, FuncTy->getReturnType(), Callee, std::move(Args));
2419
2420 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
2421 Results.push_back(CallResult.first);
2422 return true;
2423}
2424
2425void VectorLegalizer::UnrollStrictFPOp(SDNode *Node,
2426 SmallVectorImpl<SDValue> &Results) {
2427 EVT VT = Node->getValueType(0);
2428 EVT EltVT = VT.getVectorElementType();
2429 unsigned NumElems = VT.getVectorNumElements();
2430 unsigned NumOpers = Node->getNumOperands();
2431 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
2432
2433 EVT TmpEltVT = EltVT;
2434 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2435 Node->getOpcode() == ISD::STRICT_FSETCCS)
2436 TmpEltVT = TLI.getSetCCResultType(DAG.getDataLayout(),
2437 *DAG.getContext(), TmpEltVT);
2438
2439 EVT ValueVTs[] = {TmpEltVT, MVT::Other};
2440 SDValue Chain = Node->getOperand(0);
2441 SDLoc dl(Node);
2442
2443 SmallVector<SDValue, 32> OpValues;
2444 SmallVector<SDValue, 32> OpChains;
2445 for (unsigned i = 0; i < NumElems; ++i) {
2447 SDValue Idx = DAG.getVectorIdxConstant(i, dl);
2448
2449 // The Chain is the first operand.
2450 Opers.push_back(Chain);
2451
2452 // Now process the remaining operands.
2453 for (unsigned j = 1; j < NumOpers; ++j) {
2454 SDValue Oper = Node->getOperand(j);
2455 EVT OperVT = Oper.getValueType();
2456
2457 if (OperVT.isVector())
2458 Oper = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2459 OperVT.getVectorElementType(), Oper, Idx);
2460
2461 Opers.push_back(Oper);
2462 }
2463
2464 SDValue ScalarOp = DAG.getNode(Node->getOpcode(), dl, ValueVTs, Opers);
2465 SDValue ScalarResult = ScalarOp.getValue(0);
2466 SDValue ScalarChain = ScalarOp.getValue(1);
2467
2468 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2469 Node->getOpcode() == ISD::STRICT_FSETCCS)
2470 ScalarResult = DAG.getSelect(dl, EltVT, ScalarResult,
2471 DAG.getAllOnesConstant(dl, EltVT),
2472 DAG.getConstant(0, dl, EltVT));
2473
2474 OpValues.push_back(ScalarResult);
2475 OpChains.push_back(ScalarChain);
2476 }
2477
2478 SDValue Result = DAG.getBuildVector(VT, dl, OpValues);
2479 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OpChains);
2480
2481 Results.push_back(Result);
2482 Results.push_back(NewChain);
2483}
2484
2485SDValue VectorLegalizer::UnrollVSETCC(SDNode *Node) {
2486 EVT VT = Node->getValueType(0);
2487 unsigned NumElems = VT.getVectorNumElements();
2488 EVT EltVT = VT.getVectorElementType();
2489 SDValue LHS = Node->getOperand(0);
2490 SDValue RHS = Node->getOperand(1);
2491 SDValue CC = Node->getOperand(2);
2492 EVT TmpEltVT = LHS.getValueType().getVectorElementType();
2493 SDLoc dl(Node);
2494 SmallVector<SDValue, 8> Ops(NumElems);
2495 for (unsigned i = 0; i < NumElems; ++i) {
2496 SDValue LHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
2497 DAG.getVectorIdxConstant(i, dl));
2498 SDValue RHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
2499 DAG.getVectorIdxConstant(i, dl));
2500 // FIXME: We should use i1 setcc + boolext here, but it causes regressions.
2501 Ops[i] = DAG.getNode(ISD::SETCC, dl,
2503 *DAG.getContext(), TmpEltVT),
2504 LHSElem, RHSElem, CC);
2505 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i],
2506 DAG.getBoolConstant(true, dl, EltVT, VT),
2507 DAG.getConstant(0, dl, EltVT));
2508 }
2509 return DAG.getBuildVector(VT, dl, Ops);
2510}
2511
2513 return VectorLegalizer(*this).Run();
2514}
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
SI Fold Operands
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:284
size_t size() const
Definition Function.h:835
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 expandVectorMatch(SDNode *N, SelectionDAG &DAG) const
Expand VECTOR_MATCH nodes.
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:829
@ 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:513
@ 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:789
@ 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:863
@ 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:520
@ 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:890
@ 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:749
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
Definition ISDOpcodes.h:920
@ 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:517
@ 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:780
@ 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:798
@ PARTIAL_REDUCE_UMLA
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition ISDOpcodes.h:717
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:487
@ 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:693
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
Definition ISDOpcodes.h:543
@ 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:806
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition ISDOpcodes.h:674
@ 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:706
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ 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:578
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:821
@ 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:909
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:898
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ 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:988
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:815
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:486
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_TO_UINT
Definition ISDOpcodes.h:480
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
Definition ISDOpcodes.h:785
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:502
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:479
@ 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:936
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:507
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:737
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition ISDOpcodes.h:712
@ VECTOR_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ 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:797
@ 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:969
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
Definition ISDOpcodes.h:701
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
Definition ISDOpcodes.h:931
@ 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:955
@ VECREDUCE_FMINIMUM
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ 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:536
@ 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:724
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
Definition ISDOpcodes.h:753
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:558
@ 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:578
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:1746
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
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
#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.