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