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"
40#include "llvm/IR/DataLayout.h"
43#include "llvm/Support/Debug.h"
45#include <cassert>
46#include <cstdint>
47#include <iterator>
48#include <utility>
49
50using namespace llvm;
51
52#define DEBUG_TYPE "legalizevectorops"
53
54namespace {
55
56class VectorLegalizer {
57 SelectionDAG& DAG;
58 const TargetLowering &TLI;
59 bool Changed = false; // Keep track of whether anything changed
60
61 /// For nodes that are of legal width, and that have more than one use, this
62 /// map indicates what regularized operand to use. This allows us to avoid
63 /// legalizing the same thing more than once.
65
66 /// Adds a node to the translation cache.
67 void AddLegalizedOperand(SDValue From, SDValue To) {
68 LegalizedNodes.insert(std::make_pair(From, To));
69 // If someone requests legalization of the new node, return itself.
70 if (From != To)
71 LegalizedNodes.insert(std::make_pair(To, To));
72 }
73
74 /// Legalizes the given node.
75 SDValue LegalizeOp(SDValue Op);
76
77 /// Assuming the node is legal, "legalize" the results.
78 SDValue TranslateLegalizeResults(SDValue Op, SDNode *Result);
79
80 /// Make sure Results are legal and update the translation cache.
81 SDValue RecursivelyLegalizeResults(SDValue Op,
83
84 /// Wrapper to interface LowerOperation with a vector of Results.
85 /// Returns false if the target wants to use default expansion. Otherwise
86 /// returns true. If return is true and the Results are empty, then the
87 /// target wants to keep the input node as is.
88 bool LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results);
89
90 /// Implements unrolling a VSETCC.
91 SDValue UnrollVSETCC(SDNode *Node);
92
93 /// Implement expand-based legalization of vector operations.
94 ///
95 /// This is just a high-level routine to dispatch to specific code paths for
96 /// operations to legalize them.
98
99 /// Implements expansion for FP_TO_UINT; falls back to UnrollVectorOp if
100 /// FP_TO_SINT isn't legal.
101 void ExpandFP_TO_UINT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
102
103 /// Implements expansion for UINT_TO_FLOAT; falls back to UnrollVectorOp if
104 /// SINT_TO_FLOAT and SHR on vectors isn't legal.
105 void ExpandUINT_TO_FLOAT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
106
107 /// Implement expansion for SIGN_EXTEND_INREG using SRL and SRA.
108 SDValue ExpandSEXTINREG(SDNode *Node);
109
110 /// Implement expansion for ANY_EXTEND_VECTOR_INREG.
111 ///
112 /// Shuffles the low lanes of the operand into place and bitcasts to the proper
113 /// type. The contents of the bits in the extended part of each element are
114 /// undef.
115 SDValue ExpandANY_EXTEND_VECTOR_INREG(SDNode *Node);
116
117 /// Implement expansion for SIGN_EXTEND_VECTOR_INREG.
118 ///
119 /// Shuffles the low lanes of the operand into place, bitcasts to the proper
120 /// type, then shifts left and arithmetic shifts right to introduce a sign
121 /// extension.
122 SDValue ExpandSIGN_EXTEND_VECTOR_INREG(SDNode *Node);
123
124 /// Implement expansion for ZERO_EXTEND_VECTOR_INREG.
125 ///
126 /// Shuffles the low lanes of the operand into place and blends zeros into
127 /// the remaining lanes, finally bitcasting to the proper type.
128 SDValue ExpandZERO_EXTEND_VECTOR_INREG(SDNode *Node);
129
130 /// Expand bswap of vectors into a shuffle if legal.
131 SDValue ExpandBSWAP(SDNode *Node);
132
133 /// Implement vselect in terms of XOR, AND, OR when blend is not
134 /// supported by the target.
135 SDValue ExpandVSELECT(SDNode *Node);
136 SDValue ExpandVP_MERGE(SDNode *Node);
137 SDValue ExpandVP_REM(SDNode *Node);
138 SDValue ExpandLOOP_DEPENDENCE_MASK(SDNode *N);
139 SDValue ExpandMASK_BEFOREFIRST(SDNode *N);
140 SDValue ExpandMaskedBinOp(SDNode *N);
141 SDValue ExpandSELECT(SDNode *Node);
142 std::pair<SDValue, SDValue> ExpandLoad(SDNode *N);
143 SDValue ExpandStore(SDNode *N);
144 SDValue ExpandFNEG(SDNode *Node);
145 SDValue ExpandFABS(SDNode *Node);
146 SDValue ExpandFCOPYSIGN(SDNode *Node);
147 void ExpandFSUB(SDNode *Node, SmallVectorImpl<SDValue> &Results);
148 void ExpandSETCC(SDNode *Node, SmallVectorImpl<SDValue> &Results);
149 SDValue ExpandBITREVERSE(SDNode *Node);
150 void ExpandUADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
151 void ExpandSADDSUBO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
152 void ExpandMULO(SDNode *Node, SmallVectorImpl<SDValue> &Results);
153 void ExpandFixedPointDiv(SDNode *Node, SmallVectorImpl<SDValue> &Results);
154 void ExpandStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);
155 void ExpandREM(SDNode *Node, SmallVectorImpl<SDValue> &Results);
156
157 bool tryExpandVecMathCall(SDNode *Node,
158 function_ref<RTLIB::Libcall(EVT)> GetLibcall,
160
161 void UnrollStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);
162
163 /// Implements vector promotion.
164 ///
165 /// This is essentially just bitcasting the operands to a different type and
166 /// bitcasting the result back to the original type.
168
169 /// Implements [SU]INT_TO_FP vector promotion.
170 ///
171 /// This is a [zs]ext of the input operand to a larger integer type.
172 void PromoteINT_TO_FP(SDNode *Node, SmallVectorImpl<SDValue> &Results);
173
174 /// Implements FP_TO_[SU]INT vector promotion of the result type.
175 ///
176 /// It is promoted to a larger integer type. The result is then
177 /// truncated back to the original type.
178 void PromoteFP_TO_INT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
179
180 /// Implements vector setcc operation promotion.
181 ///
182 /// All vector operands are promoted to a vector type with larger element
183 /// type.
184 void PromoteSETCC(SDNode *Node, SmallVectorImpl<SDValue> &Results);
185
186 void PromoteSTRICT(SDNode *Node, SmallVectorImpl<SDValue> &Results);
187
188 /// Calculate the reduction using a type of higher precision and round the
189 /// result to match the original type. Setting NonArithmetic signifies the
190 /// rounding of the result does not affect its value.
191 void PromoteFloatVECREDUCE(SDNode *Node, SmallVectorImpl<SDValue> &Results,
192 bool NonArithmetic);
193
194 void PromoteVECTOR_COMPRESS(SDNode *Node, SmallVectorImpl<SDValue> &Results);
195
196public:
197 VectorLegalizer(SelectionDAG& dag) :
198 DAG(dag), TLI(dag.getTargetLoweringInfo()) {}
199
200 /// Begin legalizer the vector operations in the DAG.
201 bool Run();
202};
203
204} // end anonymous namespace
205
206bool VectorLegalizer::Run() {
207 // Before we start legalizing vector nodes, check if there are any vectors.
208 bool HasVectors = false;
210 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I) {
211 // Check if the values of the nodes contain vectors. We don't need to check
212 // the operands because we are going to check their values at some point.
213 HasVectors = llvm::any_of(I->values(), [](EVT T) { return T.isVector(); });
214
215 // If we found a vector node we can start the legalization.
216 if (HasVectors)
217 break;
218 }
219
220 // If this basic block has no vectors then no need to legalize vectors.
221 if (!HasVectors)
222 return false;
223
224 // The legalize process is inherently a bottom-up recursive process (users
225 // legalize their uses before themselves). Given infinite stack space, we
226 // could just start legalizing on the root and traverse the whole graph. In
227 // practice however, this causes us to run out of stack space on large basic
228 // blocks. To avoid this problem, compute an ordering of the nodes where each
229 // node is only legalized after all of its operands are legalized.
232 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I)
233 LegalizeOp(SDValue(&*I, 0));
234
235 // Finally, it's possible the root changed. Get the new root.
236 SDValue OldRoot = DAG.getRoot();
237 assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?");
238 DAG.setRoot(LegalizedNodes[OldRoot]);
239
240 LegalizedNodes.clear();
241
242 // Remove dead nodes now.
243 DAG.RemoveDeadNodes();
244
245 return Changed;
246}
247
248SDValue VectorLegalizer::TranslateLegalizeResults(SDValue Op, SDNode *Result) {
249 assert(Op->getNumValues() == Result->getNumValues() &&
250 "Unexpected number of results");
251 // Generic legalization: just pass the operand through.
252 for (unsigned i = 0, e = Op->getNumValues(); i != e; ++i)
253 AddLegalizedOperand(Op.getValue(i), SDValue(Result, i));
254 return SDValue(Result, Op.getResNo());
255}
256
257SDValue
258VectorLegalizer::RecursivelyLegalizeResults(SDValue Op,
260 assert(Results.size() == Op->getNumValues() &&
261 "Unexpected number of results");
262 // Make sure that the generated code is itself legal.
263 for (unsigned i = 0, e = Results.size(); i != e; ++i) {
264 Results[i] = LegalizeOp(Results[i]);
265 AddLegalizedOperand(Op.getValue(i), Results[i]);
266 }
267
268 return Results[Op.getResNo()];
269}
270
271SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
272 // Note that LegalizeOp may be reentered even from single-use nodes, which
273 // means that we always must cache transformed nodes.
274 auto I = LegalizedNodes.find(Op);
275 if (I != LegalizedNodes.end()) return I->second;
276
277 // Legalize the operands
279 for (const SDValue &Oper : Op->op_values())
280 Ops.push_back(LegalizeOp(Oper));
281
282 SDNode *Node = DAG.UpdateNodeOperands(Op.getNode(), Ops);
283
284 bool HasVectorValueOrOp =
285 llvm::any_of(Node->values(), [](EVT T) { return T.isVector(); }) ||
286 llvm::any_of(Node->op_values(),
287 [](SDValue O) { return O.getValueType().isVector(); });
288 if (!HasVectorValueOrOp)
289 return TranslateLegalizeResults(Op, Node);
290
291 TargetLowering::LegalizeAction Action = TargetLowering::Legal;
292 EVT ValVT;
293 switch (Op.getOpcode()) {
294 default:
295 return TranslateLegalizeResults(Op, Node);
296 case ISD::LOAD: {
297 LoadSDNode *LD = cast<LoadSDNode>(Node);
298 ISD::LoadExtType ExtType = LD->getExtensionType();
299 EVT LoadedVT = LD->getMemoryVT();
300 if (LoadedVT.isVector() && ExtType != ISD::NON_EXTLOAD)
301 Action = TLI.getLoadAction(LD->getValueType(0), LoadedVT, LD->getAlign(),
302 LD->getAddressSpace(), ExtType, false);
303 break;
304 }
305 case ISD::STORE: {
306 StoreSDNode *ST = cast<StoreSDNode>(Node);
307 EVT StVT = ST->getMemoryVT();
308 MVT ValVT = ST->getValue().getSimpleValueType();
309 if (StVT.isVector() && ST->isTruncatingStore())
310 Action = TLI.getTruncStoreAction(ValVT, StVT, ST->getAlign(),
311 ST->getAddressSpace());
312 break;
313 }
315 Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
316 // This operation lies about being legal: when it claims to be legal,
317 // it should actually be expanded.
318 if (Action == TargetLowering::Legal)
319 Action = TargetLowering::Expand;
320 break;
321#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
322 case ISD::STRICT_##DAGN:
323#include "llvm/IR/ConstrainedOps.def"
324 ValVT = Node->getValueType(0);
325 if (Op.getOpcode() == ISD::STRICT_SINT_TO_FP ||
326 Op.getOpcode() == ISD::STRICT_UINT_TO_FP)
327 ValVT = Node->getOperand(1).getValueType();
328 if (Op.getOpcode() == ISD::STRICT_FSETCC ||
329 Op.getOpcode() == ISD::STRICT_FSETCCS) {
330 MVT OpVT = Node->getOperand(1).getSimpleValueType();
331 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(3))->get();
332 Action = TLI.getCondCodeAction(CCCode, OpVT);
333 if (Action == TargetLowering::Legal)
334 Action = TLI.getOperationAction(Node->getOpcode(), OpVT);
335 } else {
336 Action = TLI.getOperationAction(Node->getOpcode(), ValVT);
337 }
338 // If we're asked to expand a strict vector floating-point operation,
339 // by default we're going to simply unroll it. That is usually the
340 // best approach, except in the case where the resulting strict (scalar)
341 // operations would themselves use the fallback mutation to non-strict.
342 // In that specific case, just do the fallback on the vector op.
343 if (Action == TargetLowering::Expand && !TLI.isStrictFPEnabled() &&
344 TLI.getStrictFPOperationAction(Node->getOpcode(), ValVT) ==
345 TargetLowering::Legal) {
346 EVT EltVT = ValVT.getVectorElementType();
347 if (TLI.getOperationAction(Node->getOpcode(), EltVT)
348 == TargetLowering::Expand &&
349 TLI.getStrictFPOperationAction(Node->getOpcode(), EltVT)
350 == TargetLowering::Legal)
351 Action = TargetLowering::Legal;
352 }
353 break;
354 case ISD::ADD:
355 case ISD::SUB:
356 case ISD::MUL:
357 case ISD::MULHS:
358 case ISD::MULHU:
359 case ISD::SDIV:
360 case ISD::UDIV:
361 case ISD::SREM:
362 case ISD::UREM:
363 case ISD::SDIVREM:
364 case ISD::UDIVREM:
365 case ISD::FADD:
366 case ISD::FSUB:
367 case ISD::FMUL:
368 case ISD::FDIV:
369 case ISD::FREM:
370 case ISD::AND:
371 case ISD::OR:
372 case ISD::XOR:
373 case ISD::SHL:
374 case ISD::SRA:
375 case ISD::SRL:
376 case ISD::FSHL:
377 case ISD::FSHR:
378 case ISD::ROTL:
379 case ISD::ROTR:
380 case ISD::ABS:
382 case ISD::ABDS:
383 case ISD::ABDU:
384 case ISD::AVGCEILS:
385 case ISD::AVGCEILU:
386 case ISD::AVGFLOORS:
387 case ISD::AVGFLOORU:
390 case ISD::BSWAP:
391 case ISD::BITREVERSE:
392 case ISD::CTLZ:
393 case ISD::CTTZ:
396 case ISD::CTPOP:
397 case ISD::CLMUL:
398 case ISD::CLMULH:
399 case ISD::CLMULR:
400 case ISD::SELECT:
401 case ISD::VSELECT:
402 case ISD::SELECT_CC:
403 case ISD::ZERO_EXTEND:
404 case ISD::ANY_EXTEND:
405 case ISD::TRUNCATE:
406 case ISD::SIGN_EXTEND:
407 case ISD::FP_TO_SINT:
408 case ISD::FP_TO_UINT:
409 case ISD::FNEG:
410 case ISD::FABS:
411 case ISD::FMINNUM:
412 case ISD::FMAXNUM:
415 case ISD::FMINIMUM:
416 case ISD::FMAXIMUM:
417 case ISD::FMINIMUMNUM:
418 case ISD::FMAXIMUMNUM:
419 case ISD::FCOPYSIGN:
420 case ISD::FSQRT:
421 case ISD::FSIN:
422 case ISD::FCOS:
423 case ISD::FTAN:
424 case ISD::FASIN:
425 case ISD::FACOS:
426 case ISD::FATAN:
427 case ISD::FATAN2:
428 case ISD::FSINH:
429 case ISD::FCOSH:
430 case ISD::FTANH:
431 case ISD::FLDEXP:
432 case ISD::FPOWI:
433 case ISD::FPOW:
434 case ISD::FCBRT:
435 case ISD::FLOG:
436 case ISD::FLOG2:
437 case ISD::FLOG10:
438 case ISD::FEXP:
439 case ISD::FEXP2:
440 case ISD::FEXP10:
441 case ISD::FCEIL:
442 case ISD::FTRUNC:
443 case ISD::FRINT:
444 case ISD::FNEARBYINT:
445 case ISD::FROUND:
446 case ISD::FROUNDEVEN:
447 case ISD::FFLOOR:
448 case ISD::FP_ROUND:
449 case ISD::FP_EXTEND:
451 case ISD::FMA:
456 case ISD::SMIN:
457 case ISD::SMAX:
458 case ISD::UMIN:
459 case ISD::UMAX:
460 case ISD::SMUL_LOHI:
461 case ISD::UMUL_LOHI:
462 case ISD::SADDO:
463 case ISD::UADDO:
464 case ISD::SSUBO:
465 case ISD::USUBO:
466 case ISD::SMULO:
467 case ISD::UMULO:
471 case ISD::FFREXP:
472 case ISD::FMODF:
473 case ISD::FSINCOS:
474 case ISD::FSINCOSPI:
475 case ISD::SADDSAT:
476 case ISD::UADDSAT:
477 case ISD::SSUBSAT:
478 case ISD::USUBSAT:
479 case ISD::SSHLSAT:
480 case ISD::USHLSAT:
483 case ISD::MGATHER:
485 case ISD::SCMP:
486 case ISD::UCMP:
491 case ISD::MASKED_UDIV:
492 case ISD::MASKED_SDIV:
493 case ISD::MASKED_UREM:
494 case ISD::MASKED_SREM:
496 Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
497 break;
500 EVT VT = Node->getValueType(0);
501 unsigned Factor = Node->getNumOperands();
502 Action = TLI.getVectorInterleaveAction(Node->getOpcode(), Factor, VT);
503 // Early Custom Lowering causes RISC-V regressions.
504 if (Action == TargetLowering::Custom &&
505 (VT.isScalableVector() || Factor != 2)) {
506 Action = TargetLowering::Legal;
507 }
508 break;
509 }
510 case ISD::SMULFIX:
511 case ISD::SMULFIXSAT:
512 case ISD::UMULFIX:
513 case ISD::UMULFIXSAT:
514 case ISD::SDIVFIX:
515 case ISD::SDIVFIXSAT:
516 case ISD::UDIVFIX:
517 case ISD::UDIVFIXSAT: {
518 unsigned Scale = Node->getConstantOperandVal(2);
519 Action = TLI.getFixedPointOperationAction(Node->getOpcode(),
520 Node->getValueType(0), Scale);
521 break;
522 }
523 case ISD::LROUND:
524 case ISD::LLROUND:
525 case ISD::LRINT:
526 case ISD::LLRINT:
527 case ISD::SINT_TO_FP:
528 case ISD::UINT_TO_FP:
546 case ISD::CTTZ_ELTS:
549 Action = TLI.getOperationAction(Node->getOpcode(),
550 Node->getOperand(0).getValueType());
551 break;
554 Action = TLI.getOperationAction(Node->getOpcode(),
555 Node->getOperand(1).getValueType());
556 break;
557 case ISD::SETCC: {
558 MVT OpVT = Node->getOperand(0).getSimpleValueType();
559 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get();
560 Action = TLI.getCondCodeAction(CCCode, OpVT);
561 if (Action == TargetLowering::Legal)
562 Action = TLI.getOperationAction(Node->getOpcode(), OpVT);
563 break;
564 }
569 Action =
570 TLI.getPartialReduceMLAAction(Op.getOpcode(), Node->getValueType(0),
571 Node->getOperand(1).getValueType());
572 break;
573
574#define BEGIN_REGISTER_VP_SDNODE(VPID, LEGALPOS, ...) \
575 case ISD::VPID: { \
576 EVT LegalizeVT = LEGALPOS < 0 ? Node->getValueType(-(1 + LEGALPOS)) \
577 : Node->getOperand(LEGALPOS).getValueType(); \
578 /* Defer non-vector results to LegalizeDAG. */ \
579 if (!Node->getValueType(0).isVector() && \
580 Node->getValueType(0) != MVT::Other) { \
581 Action = TargetLowering::Legal; \
582 break; \
583 } \
584 Action = TLI.getOperationAction(Node->getOpcode(), LegalizeVT); \
585 } break;
586#include "llvm/IR/VPIntrinsics.def"
587 }
588
589 LLVM_DEBUG(dbgs() << "\nLegalizing vector op: "; Node->dump(&DAG));
590
591 SmallVector<SDValue, 8> ResultVals;
592 switch (Action) {
593 default: llvm_unreachable("This action is not supported yet!");
594 case TargetLowering::Promote:
595 assert((Op.getOpcode() != ISD::LOAD && Op.getOpcode() != ISD::STORE) &&
596 "This action is not supported yet!");
597 LLVM_DEBUG(dbgs() << "Promoting\n");
598 Promote(Node, ResultVals);
599 assert(!ResultVals.empty() && "No results for promotion?");
600 break;
601 case TargetLowering::Legal:
602 LLVM_DEBUG(dbgs() << "Legal node: nothing to do\n");
603 break;
604 case TargetLowering::Custom:
605 LLVM_DEBUG(dbgs() << "Trying custom legalization\n");
606 if (LowerOperationWrapper(Node, ResultVals))
607 break;
608 LLVM_DEBUG(dbgs() << "Could not custom legalize node\n");
609 [[fallthrough]];
610 case TargetLowering::Expand:
611 LLVM_DEBUG(dbgs() << "Expanding\n");
612 Expand(Node, ResultVals);
613 break;
614 }
615
616 if (ResultVals.empty())
617 return TranslateLegalizeResults(Op, Node);
618
619 Changed = true;
620 return RecursivelyLegalizeResults(Op, ResultVals);
621}
622
623// FIXME: This is very similar to TargetLowering::LowerOperationWrapper. Can we
624// merge them somehow?
625bool VectorLegalizer::LowerOperationWrapper(SDNode *Node,
626 SmallVectorImpl<SDValue> &Results) {
627 SDValue Res = TLI.LowerOperation(SDValue(Node, 0), DAG);
628
629 if (!Res.getNode())
630 return false;
631
632 if (Res == SDValue(Node, 0))
633 return true;
634
635 // If the original node has one result, take the return value from
636 // LowerOperation as is. It might not be result number 0.
637 if (Node->getNumValues() == 1) {
638 Results.push_back(Res);
639 return true;
640 }
641
642 // If the original node has multiple results, then the return node should
643 // have the same number of results.
644 assert((Node->getNumValues() == Res->getNumValues()) &&
645 "Lowering returned the wrong number of results!");
646
647 // Places new result values base on N result number.
648 for (unsigned I = 0, E = Node->getNumValues(); I != E; ++I)
649 Results.push_back(Res.getValue(I));
650
651 return true;
652}
653
654void VectorLegalizer::PromoteSETCC(SDNode *Node,
655 SmallVectorImpl<SDValue> &Results) {
656 MVT VecVT = Node->getOperand(0).getSimpleValueType();
657 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
658
659 unsigned ExtOp = VecVT.isFloatingPoint() ? ISD::FP_EXTEND : ISD::ANY_EXTEND;
660
661 SDLoc DL(Node);
662 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
663
664 Operands[0] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(0));
665 Operands[1] = DAG.getNode(ExtOp, DL, NewVecVT, Node->getOperand(1));
666 Operands[2] = Node->getOperand(2);
667
668 EVT ResVT =
669 TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), NewVecVT);
670 SDValue Res =
671 DAG.getNode(Node->getOpcode(), DL, ResVT, Operands, Node->getFlags());
672 if (ResVT != Node->getValueType(0))
673 Res = DAG.getBoolExtOrTrunc(Res, DL, Node->getValueType(0), NewVecVT);
674 Results.push_back(Res);
675}
676
677void VectorLegalizer::PromoteSTRICT(SDNode *Node,
678 SmallVectorImpl<SDValue> &Results) {
679 MVT VecVT = Node->getOperand(1).getSimpleValueType();
680 MVT NewVecVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VecVT);
681
682 assert(VecVT.isFloatingPoint());
683
684 SDLoc DL(Node);
685 SmallVector<SDValue, 5> Operands(Node->getNumOperands());
687
688 for (unsigned j = 1; j != Node->getNumOperands(); ++j)
689 if (Node->getOperand(j).getValueType().isVector() &&
690 !(ISD::isVPOpcode(Node->getOpcode()) &&
691 ISD::getVPMaskIdx(Node->getOpcode()) == j)) // Skip mask operand.
692 {
693 // promote the vector operand.
694 SDValue Ext =
695 DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {NewVecVT, MVT::Other},
696 {Node->getOperand(0), Node->getOperand(j)});
697 Operands[j] = Ext.getValue(0);
698 Chains.push_back(Ext.getValue(1));
699 } else
700 Operands[j] = Node->getOperand(j); // Skip no vector operand.
701
702 SDVTList VTs = DAG.getVTList(NewVecVT, Node->getValueType(1));
703
704 Operands[0] = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
705
706 SDValue Res =
707 DAG.getNode(Node->getOpcode(), DL, VTs, Operands, Node->getFlags());
708
709 SDValue Round =
710 DAG.getNode(ISD::STRICT_FP_ROUND, DL, {VecVT, MVT::Other},
711 {Res.getValue(1), Res.getValue(0),
712 DAG.getIntPtrConstant(0, DL, /*isTarget=*/true)});
713
714 Results.push_back(Round.getValue(0));
715 Results.push_back(Round.getValue(1));
716}
717
718void VectorLegalizer::PromoteFloatVECREDUCE(SDNode *Node,
719 SmallVectorImpl<SDValue> &Results,
720 bool NonArithmetic) {
721 MVT OpVT = Node->getOperand(0).getSimpleValueType();
722 assert(OpVT.isFloatingPoint() && "Expected floating point reduction!");
723 MVT NewOpVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OpVT);
724
725 SDLoc DL(Node);
726 SDValue NewOp = DAG.getNode(ISD::FP_EXTEND, DL, NewOpVT, Node->getOperand(0));
727 SDValue Rdx =
728 DAG.getNode(Node->getOpcode(), DL, NewOpVT.getVectorElementType(), NewOp,
729 Node->getFlags());
730 SDValue Res =
731 DAG.getNode(ISD::FP_ROUND, DL, Node->getValueType(0), Rdx,
732 DAG.getIntPtrConstant(NonArithmetic, DL, /*isTarget=*/true));
733 Results.push_back(Res);
734}
735
736void VectorLegalizer::PromoteVECTOR_COMPRESS(
737 SDNode *Node, SmallVectorImpl<SDValue> &Results) {
738 SDLoc DL(Node);
739 EVT VT = Node->getValueType(0);
740 MVT PromotedVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT.getSimpleVT());
741 assert((VT.isInteger() || VT.getSizeInBits() == PromotedVT.getSizeInBits()) &&
742 "Only integer promotion or bitcasts between types is supported");
743
744 SDValue Vec = Node->getOperand(0);
745 SDValue Mask = Node->getOperand(1);
746 SDValue Passthru = Node->getOperand(2);
747 if (VT.isInteger()) {
748 Vec = DAG.getNode(ISD::ANY_EXTEND, DL, PromotedVT, Vec);
749 Mask = TLI.promoteTargetBoolean(DAG, Mask, PromotedVT);
750 Passthru = DAG.getNode(ISD::ANY_EXTEND, DL, PromotedVT, Passthru);
751 } else {
752 Vec = DAG.getBitcast(PromotedVT, Vec);
753 Passthru = DAG.getBitcast(PromotedVT, Passthru);
754 }
755
756 SDValue Result =
757 DAG.getNode(ISD::VECTOR_COMPRESS, DL, PromotedVT, Vec, Mask, Passthru);
758 Result = VT.isInteger() ? DAG.getNode(ISD::TRUNCATE, DL, VT, Result)
759 : DAG.getBitcast(VT, Result);
760 Results.push_back(Result);
761}
762
763void VectorLegalizer::Promote(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
764 // For a few operations there is a specific concept for promotion based on
765 // the operand's type.
766 switch (Node->getOpcode()) {
767 case ISD::SINT_TO_FP:
768 case ISD::UINT_TO_FP:
771 // "Promote" the operation by extending the operand.
772 PromoteINT_TO_FP(Node, Results);
773 return;
774 case ISD::FP_TO_UINT:
775 case ISD::FP_TO_SINT:
778 // Promote the operation by extending the operand.
779 PromoteFP_TO_INT(Node, Results);
780 return;
781 case ISD::SETCC:
782 // Promote the operation by extending the operand.
783 PromoteSETCC(Node, Results);
784 return;
785 case ISD::STRICT_FADD:
786 case ISD::STRICT_FSUB:
787 case ISD::STRICT_FMUL:
788 case ISD::STRICT_FDIV:
790 case ISD::STRICT_FMA:
791 PromoteSTRICT(Node, Results);
792 return;
795 PromoteFloatVECREDUCE(Node, Results, /*NonArithmetic=*/false);
796 return;
803 PromoteFloatVECREDUCE(Node, Results, /*NonArithmetic=*/true);
804 return;
806 PromoteVECTOR_COMPRESS(Node, Results);
807 return;
808
809 case ISD::FP_ROUND:
810 case ISD::FP_EXTEND:
811 // These operations are used to do promotion so they can't be promoted
812 // themselves.
813 llvm_unreachable("Don't know how to promote this operation!");
814 }
815
816 // There are currently two cases of vector promotion:
817 // 1) Bitcasting a vector of integers to a different type to a vector of the
818 // same overall length. For example, x86 promotes ISD::AND v2i32 to v1i64.
819 // 2) Extending a vector of floats to a vector of the same number of larger
820 // floats. For example, AArch64 promotes ISD::FADD on v4f16 to v4f32.
821 assert(Node->getNumValues() == 1 &&
822 "Can't promote a vector with multiple results!");
823 MVT VT = Node->getSimpleValueType(0);
824 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
825 SDLoc dl(Node);
826 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
827
828 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
829 // Do not promote the mask operand of a VP OP.
830 bool SkipPromote = ISD::isVPOpcode(Node->getOpcode()) &&
831 ISD::getVPMaskIdx(Node->getOpcode()) == j;
832 if (Node->getOperand(j).getValueType().isVector() && !SkipPromote)
833 if (Node->getOperand(j)
834 .getValueType()
835 .getVectorElementType()
836 .isFloatingPoint() &&
838 Operands[j] = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(j));
839 else
840 Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(j));
841 else
842 Operands[j] = Node->getOperand(j);
843 }
844
845 SDValue Res =
846 DAG.getNode(Node->getOpcode(), dl, NVT, Operands, Node->getFlags());
847
848 if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
851 Res = DAG.getNode(ISD::FP_ROUND, dl, VT, Res,
852 DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
853 else
854 Res = DAG.getNode(ISD::BITCAST, dl, VT, Res);
855
856 Results.push_back(Res);
857}
858
859void VectorLegalizer::PromoteINT_TO_FP(SDNode *Node,
860 SmallVectorImpl<SDValue> &Results) {
861 // INT_TO_FP operations may require the input operand be promoted even
862 // when the type is otherwise legal.
863 bool IsStrict = Node->isStrictFPOpcode();
864 MVT VT = Node->getOperand(IsStrict ? 1 : 0).getSimpleValueType();
865 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
867 "Vectors have different number of elements!");
868
869 SDLoc dl(Node);
870 SmallVector<SDValue, 4> Operands(Node->getNumOperands());
871
872 unsigned Opc = (Node->getOpcode() == ISD::UINT_TO_FP ||
873 Node->getOpcode() == ISD::STRICT_UINT_TO_FP)
876 for (unsigned j = 0; j != Node->getNumOperands(); ++j) {
877 if (Node->getOperand(j).getValueType().isVector())
878 Operands[j] = DAG.getNode(Opc, dl, NVT, Node->getOperand(j));
879 else
880 Operands[j] = Node->getOperand(j);
881 }
882
883 if (IsStrict) {
884 SDValue Res = DAG.getNode(Node->getOpcode(), dl,
885 {Node->getValueType(0), MVT::Other}, Operands);
886 Results.push_back(Res);
887 Results.push_back(Res.getValue(1));
888 return;
889 }
890
891 SDValue Res =
892 DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Operands);
893 Results.push_back(Res);
894}
895
896// For FP_TO_INT we promote the result type to a vector type with wider
897// elements and then truncate the result. This is different from the default
898// PromoteVector which uses bitcast to promote thus assumning that the
899// promoted vector type has the same overall size.
900void VectorLegalizer::PromoteFP_TO_INT(SDNode *Node,
901 SmallVectorImpl<SDValue> &Results) {
902 MVT VT = Node->getSimpleValueType(0);
903 MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
904 bool IsStrict = Node->isStrictFPOpcode();
906 "Vectors have different number of elements!");
907
908 unsigned NewOpc = Node->getOpcode();
909 // Change FP_TO_UINT to FP_TO_SINT if possible.
910 // TODO: Should we only do this if FP_TO_UINT itself isn't legal?
911 if (NewOpc == ISD::FP_TO_UINT &&
913 NewOpc = ISD::FP_TO_SINT;
914
915 if (NewOpc == ISD::STRICT_FP_TO_UINT &&
917 NewOpc = ISD::STRICT_FP_TO_SINT;
918
919 SDLoc dl(Node);
920 SDValue Promoted, Chain;
921 if (IsStrict) {
922 Promoted = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
923 {Node->getOperand(0), Node->getOperand(1)});
924 Chain = Promoted.getValue(1);
925 } else
926 Promoted = DAG.getNode(NewOpc, dl, NVT, Node->getOperand(0));
927
928 // Assert that the converted value fits in the original type. If it doesn't
929 // (eg: because the value being converted is too big), then the result of the
930 // original operation was undefined anyway, so the assert is still correct.
931 if (Node->getOpcode() == ISD::FP_TO_UINT ||
932 Node->getOpcode() == ISD::STRICT_FP_TO_UINT)
933 NewOpc = ISD::AssertZext;
934 else
935 NewOpc = ISD::AssertSext;
936
937 Promoted = DAG.getNode(NewOpc, dl, NVT, Promoted,
938 DAG.getValueType(VT.getScalarType()));
939 Promoted = DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted);
940 Results.push_back(Promoted);
941 if (IsStrict)
942 Results.push_back(Chain);
943}
944
945std::pair<SDValue, SDValue> VectorLegalizer::ExpandLoad(SDNode *N) {
946 LoadSDNode *LD = cast<LoadSDNode>(N);
947 return TLI.scalarizeVectorLoad(LD, DAG);
948}
949
950SDValue VectorLegalizer::ExpandStore(SDNode *N) {
951 StoreSDNode *ST = cast<StoreSDNode>(N);
952 SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
953 return TF;
954}
955
956void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
957 switch (Node->getOpcode()) {
958 case ISD::LOAD: {
959 std::pair<SDValue, SDValue> Tmp = ExpandLoad(Node);
960 Results.push_back(Tmp.first);
961 Results.push_back(Tmp.second);
962 return;
963 }
964 case ISD::STORE:
965 Results.push_back(ExpandStore(Node));
966 return;
968 for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
969 Results.push_back(Node->getOperand(i));
970 return;
972 TLI.expandVectorInterleave(Node, Results, DAG);
973 return;
975 TLI.expandVectorDeinterleave(Node, Results, DAG);
976 return;
978 if (SDValue Expanded = ExpandSEXTINREG(Node)) {
979 Results.push_back(Expanded);
980 return;
981 }
982 break;
984 Results.push_back(ExpandANY_EXTEND_VECTOR_INREG(Node));
985 return;
987 Results.push_back(ExpandSIGN_EXTEND_VECTOR_INREG(Node));
988 return;
990 Results.push_back(ExpandZERO_EXTEND_VECTOR_INREG(Node));
991 return;
992 case ISD::BSWAP:
993 if (SDValue Expanded = ExpandBSWAP(Node)) {
994 Results.push_back(Expanded);
995 return;
996 }
997 break;
998 case ISD::VSELECT:
999 if (SDValue Expanded = ExpandVSELECT(Node)) {
1000 Results.push_back(Expanded);
1001 return;
1002 }
1003 break;
1004 case ISD::VP_SREM:
1005 case ISD::VP_UREM:
1006 if (SDValue Expanded = ExpandVP_REM(Node)) {
1007 Results.push_back(Expanded);
1008 return;
1009 }
1010 break;
1011 case ISD::SELECT:
1012 if (SDValue Expanded = ExpandSELECT(Node)) {
1013 Results.push_back(Expanded);
1014 return;
1015 }
1016 break;
1017 case ISD::SELECT_CC: {
1018 if (Node->getValueType(0).isScalableVector()) {
1019 EVT CondVT = TLI.getSetCCResultType(
1020 DAG.getDataLayout(), *DAG.getContext(), Node->getValueType(0));
1021 SDValue SetCC =
1022 DAG.getNode(ISD::SETCC, SDLoc(Node), CondVT, Node->getOperand(0),
1023 Node->getOperand(1), Node->getOperand(4));
1024 Results.push_back(DAG.getSelect(SDLoc(Node), Node->getValueType(0), SetCC,
1025 Node->getOperand(2),
1026 Node->getOperand(3)));
1027 return;
1028 }
1029 break;
1030 }
1031 case ISD::FP_TO_UINT:
1032 ExpandFP_TO_UINT(Node, Results);
1033 return;
1034 case ISD::UINT_TO_FP:
1035 ExpandUINT_TO_FLOAT(Node, Results);
1036 return;
1037 case ISD::FNEG:
1038 if (SDValue Expanded = ExpandFNEG(Node)) {
1039 Results.push_back(Expanded);
1040 return;
1041 }
1042 break;
1043 case ISD::FABS:
1044 if (SDValue Expanded = ExpandFABS(Node)) {
1045 Results.push_back(Expanded);
1046 return;
1047 }
1048 break;
1049 case ISD::FCOPYSIGN:
1050 if (SDValue Expanded = ExpandFCOPYSIGN(Node)) {
1051 Results.push_back(Expanded);
1052 return;
1053 }
1054 break;
1055 case ISD::FCANONICALIZE: {
1056 // If the scalar element type has a
1057 // Legal/Custom FCANONICALIZE, don't
1058 // mess with the vector, fall back.
1059 EVT VT = Node->getValueType(0);
1060 EVT EltVT = VT.getVectorElementType();
1061 if (!VT.isScalableVector() &&
1063 TargetLowering::Expand)
1064 break;
1065 // Otherwise canonicalize the whole vector.
1066 SDValue Mul = TLI.expandFCANONICALIZE(Node, DAG);
1067 Results.push_back(Mul);
1068 return;
1069 }
1070 case ISD::FSUB:
1071 ExpandFSUB(Node, Results);
1072 return;
1073 case ISD::SETCC:
1074 ExpandSETCC(Node, Results);
1075 return;
1076 case ISD::ABS:
1078 if (SDValue Expanded = TLI.expandABS(Node, DAG)) {
1079 Results.push_back(Expanded);
1080 return;
1081 }
1082 break;
1083 case ISD::ABDS:
1084 case ISD::ABDU:
1085 if (SDValue Expanded = TLI.expandABD(Node, DAG)) {
1086 Results.push_back(Expanded);
1087 return;
1088 }
1089 break;
1090 case ISD::AVGCEILS:
1091 case ISD::AVGCEILU:
1092 case ISD::AVGFLOORS:
1093 case ISD::AVGFLOORU:
1094 if (SDValue Expanded = TLI.expandAVG(Node, DAG)) {
1095 Results.push_back(Expanded);
1096 return;
1097 }
1098 break;
1099 case ISD::BITREVERSE:
1100 if (SDValue Expanded = ExpandBITREVERSE(Node)) {
1101 Results.push_back(Expanded);
1102 return;
1103 }
1104 break;
1105 case ISD::CTPOP:
1106 if (SDValue Expanded = TLI.expandCTPOP(Node, DAG)) {
1107 Results.push_back(Expanded);
1108 return;
1109 }
1110 break;
1111 case ISD::CTLZ:
1113 if (SDValue Expanded = TLI.expandCTLZ(Node, DAG)) {
1114 Results.push_back(Expanded);
1115 return;
1116 }
1117 break;
1118 case ISD::CTTZ:
1120 if (SDValue Expanded = TLI.expandCTTZ(Node, DAG)) {
1121 Results.push_back(Expanded);
1122 return;
1123 }
1124 break;
1125 case ISD::FSHL:
1126 case ISD::FSHR:
1127 if (SDValue Expanded = TLI.expandFunnelShift(Node, DAG)) {
1128 Results.push_back(Expanded);
1129 return;
1130 }
1131 break;
1132 case ISD::CLMUL:
1133 case ISD::CLMULR:
1134 case ISD::CLMULH:
1135 if (SDValue Expanded = TLI.expandCLMUL(Node, DAG)) {
1136 Results.push_back(Expanded);
1137 return;
1138 }
1139 break;
1140 case ISD::PEXT:
1141 Results.push_back(TLI.expandPEXT(Node, DAG));
1142 return;
1143 case ISD::PDEP:
1144 Results.push_back(TLI.expandPDEP(Node, DAG));
1145 return;
1146 case ISD::ROTL:
1147 case ISD::ROTR:
1148 if (SDValue Expanded = TLI.expandROT(Node, false /*AllowVectorOps*/, DAG)) {
1149 Results.push_back(Expanded);
1150 return;
1151 }
1152 break;
1153 case ISD::FMINNUM:
1154 case ISD::FMAXNUM:
1155 if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG)) {
1156 Results.push_back(Expanded);
1157 return;
1158 }
1159 break;
1160 case ISD::FMINIMUM:
1161 case ISD::FMAXIMUM:
1162 Results.push_back(TLI.expandFMINIMUM_FMAXIMUM(Node, DAG));
1163 return;
1164 case ISD::FMINIMUMNUM:
1165 case ISD::FMAXIMUMNUM:
1166 Results.push_back(TLI.expandFMINIMUMNUM_FMAXIMUMNUM(Node, DAG));
1167 return;
1168 case ISD::SMIN:
1169 case ISD::SMAX:
1170 case ISD::UMIN:
1171 case ISD::UMAX:
1172 if (SDValue Expanded = TLI.expandIntMINMAX(Node, DAG)) {
1173 Results.push_back(Expanded);
1174 return;
1175 }
1176 break;
1177 case ISD::UADDO:
1178 case ISD::USUBO:
1179 ExpandUADDSUBO(Node, Results);
1180 return;
1181 case ISD::SADDO:
1182 case ISD::SSUBO:
1183 ExpandSADDSUBO(Node, Results);
1184 return;
1185 case ISD::UMULO:
1186 case ISD::SMULO:
1187 ExpandMULO(Node, Results);
1188 return;
1189 case ISD::MULHS:
1190 case ISD::MULHU:
1191 if (SDValue Expanded = TLI.expandMULH(Node, DAG)) {
1192 Results.push_back(Expanded);
1193 return;
1194 }
1195 break;
1196 case ISD::USUBSAT:
1197 case ISD::SSUBSAT:
1198 case ISD::UADDSAT:
1199 case ISD::SADDSAT:
1200 if (SDValue Expanded = TLI.expandAddSubSat(Node, DAG)) {
1201 Results.push_back(Expanded);
1202 return;
1203 }
1204 break;
1205 case ISD::USHLSAT:
1206 case ISD::SSHLSAT:
1207 if (SDValue Expanded = TLI.expandShlSat(Node, DAG)) {
1208 Results.push_back(Expanded);
1209 return;
1210 }
1211 break;
1214 // Expand the fpsosisat if it is scalable to prevent it from unrolling below.
1215 if (Node->getValueType(0).isScalableVector()) {
1216 if (SDValue Expanded = TLI.expandFP_TO_INT_SAT(Node, DAG)) {
1217 Results.push_back(Expanded);
1218 return;
1219 }
1220 }
1221 break;
1222 case ISD::SMULFIX:
1223 case ISD::UMULFIX:
1224 case ISD::SMULFIXSAT:
1225 case ISD::UMULFIXSAT:
1226 if (SDValue Expanded = TLI.expandFixedPointMul(Node, DAG)) {
1227 Results.push_back(Expanded);
1228 return;
1229 }
1230 break;
1231 case ISD::SDIVFIX:
1232 case ISD::UDIVFIX:
1233 ExpandFixedPointDiv(Node, Results);
1234 return;
1235 case ISD::SDIVFIXSAT:
1236 case ISD::UDIVFIXSAT:
1237 break;
1238#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1239 case ISD::STRICT_##DAGN:
1240#include "llvm/IR/ConstrainedOps.def"
1241 ExpandStrictFPOp(Node, Results);
1242 return;
1243 case ISD::VECREDUCE_ADD:
1244 case ISD::VECREDUCE_MUL:
1245 case ISD::VECREDUCE_AND:
1246 case ISD::VECREDUCE_OR:
1247 case ISD::VECREDUCE_XOR:
1260 Results.push_back(TLI.expandVecReduce(Node, DAG));
1261 return;
1266 Results.push_back(TLI.expandPartialReduceMLA(Node, DAG));
1267 return;
1270 Results.push_back(TLI.expandVecReduceSeq(Node, DAG));
1271 return;
1272 case ISD::VECTOR_MATCH:
1273 Results.push_back(TLI.expandVectorMatch(Node, DAG));
1274 return;
1275 case ISD::SREM:
1276 case ISD::UREM:
1277 ExpandREM(Node, Results);
1278 return;
1279 case ISD::VP_MERGE:
1280 if (SDValue Expanded = ExpandVP_MERGE(Node)) {
1281 Results.push_back(Expanded);
1282 return;
1283 }
1284 break;
1285 case ISD::FREM:
1286 if (tryExpandVecMathCall(Node, RTLIB::getREM, Results))
1287 return;
1288 break;
1289 case ISD::FSINCOS:
1290 case ISD::FSINCOSPI: {
1291 EVT VT = Node->getValueType(0);
1292 RTLIB::Libcall LC = Node->getOpcode() == ISD::FSINCOS
1293 ? RTLIB::getSINCOS(VT)
1294 : RTLIB::getSINCOSPI(VT);
1295 if (LC != RTLIB::UNKNOWN_LIBCALL &&
1296 TLI.expandMultipleResultFPLibCall(DAG, LC, Node, Results))
1297 return;
1298
1299 // TODO: Try to see if there's a narrower call available to use before
1300 // scalarizing.
1301 break;
1302 }
1303 case ISD::FPOW:
1304 if (tryExpandVecMathCall(Node, RTLIB::getPOW, Results))
1305 return;
1306
1307 // TODO: Try to see if there's a narrower call available to use before
1308 // scalarizing.
1309 break;
1310 case ISD::FCBRT:
1311 if (tryExpandVecMathCall(Node, RTLIB::getCBRT, Results))
1312 return;
1313
1314 // TODO: Try to see if there's a narrower call available to use before
1315 // scalarizing.
1316 break;
1317 case ISD::FMODF: {
1318 EVT VT = Node->getValueType(0);
1319 RTLIB::Libcall LC = RTLIB::getMODF(VT);
1320 if (LC != RTLIB::UNKNOWN_LIBCALL &&
1321 TLI.expandMultipleResultFPLibCall(DAG, LC, Node, Results,
1322 /*CallRetResNo=*/0))
1323 return;
1324 break;
1325 }
1327 Results.push_back(TLI.expandVECTOR_COMPRESS(Node, DAG));
1328 return;
1329 case ISD::CTTZ_ELTS:
1331 Results.push_back(TLI.expandCttzElts(Node, DAG));
1332 return;
1334 Results.push_back(TLI.expandVectorFindLastActive(Node, DAG));
1335 return;
1336 case ISD::SCMP:
1337 case ISD::UCMP:
1338 Results.push_back(TLI.expandCMP(Node, DAG));
1339 return;
1341 if (SDValue R = TLI.expandGetActiveLaneMask(Node, DAG))
1342 Results.push_back(R);
1343 return;
1346 Results.push_back(ExpandLOOP_DEPENDENCE_MASK(Node));
1347 return;
1349 Results.push_back(ExpandMASK_BEFOREFIRST(Node));
1350 return;
1351
1352 case ISD::FADD:
1353 case ISD::FMUL:
1354 case ISD::FMA:
1355 case ISD::FDIV:
1356 case ISD::FCEIL:
1357 case ISD::FFLOOR:
1358 case ISD::FNEARBYINT:
1359 case ISD::FRINT:
1360 case ISD::FROUND:
1361 case ISD::FROUNDEVEN:
1362 case ISD::FTRUNC:
1363 case ISD::FSQRT:
1364 if (SDValue Expanded = TLI.expandVectorNaryOpBySplitting(Node, DAG)) {
1365 Results.push_back(Expanded);
1366 return;
1367 }
1368 break;
1370 if (SDValue Expanded = TLI.expandCONVERT_TO_ARBITRARY_FP(Node, DAG))
1371 Results.push_back(Expanded);
1372 else
1373 Results.push_back(DAG.getPOISON(Node->getValueType(0)));
1374 return;
1376 if (SDValue Expanded = TLI.expandCONVERT_FROM_ARBITRARY_FP(Node, DAG))
1377 Results.push_back(Expanded);
1378 else
1379 Results.push_back(DAG.getPOISON(Node->getValueType(0)));
1380 return;
1381 case ISD::MASKED_UDIV:
1382 case ISD::MASKED_SDIV:
1383 case ISD::MASKED_UREM:
1384 case ISD::MASKED_SREM:
1385 Results.push_back(ExpandMaskedBinOp(Node));
1386 return;
1387 }
1388
1389 SDValue Unrolled = DAG.UnrollVectorOp(Node);
1390 if (Node->getNumValues() == 1) {
1391 Results.push_back(Unrolled);
1392 } else {
1393 assert(Node->getNumValues() == Unrolled->getNumValues() &&
1394 "VectorLegalizer Expand returned wrong number of results!");
1395 for (unsigned I = 0, E = Unrolled->getNumValues(); I != E; ++I)
1396 Results.push_back(Unrolled.getValue(I));
1397 }
1398}
1399
1400SDValue VectorLegalizer::ExpandSELECT(SDNode *Node) {
1401 // Lower a select instruction where the condition is a scalar and the
1402 // operands are vectors. Lower this select to VSELECT and implement it
1403 // using XOR AND OR. The selector bit is broadcasted.
1404 EVT VT = Node->getValueType(0);
1405 SDLoc DL(Node);
1406
1407 SDValue Mask = Node->getOperand(0);
1408 SDValue Op1 = Node->getOperand(1);
1409 SDValue Op2 = Node->getOperand(2);
1410
1411 assert(VT.isVector() && !Mask.getValueType().isVector()
1412 && Op1.getValueType() == Op2.getValueType() && "Invalid type");
1413
1414 // If we can't even use the basic vector operations of
1415 // AND,OR,XOR, we will have to scalarize the op.
1416 // Notice that the operation may be 'promoted' which means that it is
1417 // 'bitcasted' to another type which is handled.
1418 // Also, we need to be able to construct a splat vector using either
1419 // BUILD_VECTOR or SPLAT_VECTOR.
1420 // FIXME: Should we also permit fixed-length SPLAT_VECTOR as a fallback to
1421 // BUILD_VECTOR?
1422 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1423 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1424 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
1427 VT) == TargetLowering::Expand)
1428 return SDValue();
1429
1430 // Generate a mask operand.
1431 EVT MaskTy = VT.changeVectorElementTypeToInteger();
1432
1433 // What is the size of each element in the vector mask.
1434 EVT BitTy = MaskTy.getScalarType();
1435
1436 Mask = DAG.getSelect(DL, BitTy, Mask, DAG.getAllOnesConstant(DL, BitTy),
1437 DAG.getConstant(0, DL, BitTy));
1438
1439 // Broadcast the mask so that the entire vector is all one or all zero.
1440 Mask = DAG.getSplat(MaskTy, DL, Mask);
1441
1442 // Bitcast the operands to be the same type as the mask.
1443 // This is needed when we select between FP types because
1444 // the mask is a vector of integers.
1445 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1);
1446 Op2 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op2);
1447
1448 SDValue NotMask = DAG.getNOT(DL, Mask, MaskTy);
1449
1450 Op1 = DAG.getNode(ISD::AND, DL, MaskTy, Op1, Mask);
1451 Op2 = DAG.getNode(ISD::AND, DL, MaskTy, Op2, NotMask);
1452 SDValue Val = DAG.getNode(ISD::OR, DL, MaskTy, Op1, Op2);
1453 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1454}
1455
1456SDValue VectorLegalizer::ExpandSEXTINREG(SDNode *Node) {
1457 EVT VT = Node->getValueType(0);
1458
1459 // Make sure that the SRA and SHL instructions are available.
1460 if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Expand ||
1461 TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Expand)
1462 return SDValue();
1463
1464 SDLoc DL(Node);
1465 EVT OrigTy = cast<VTSDNode>(Node->getOperand(1))->getVT();
1466
1467 unsigned BW = VT.getScalarSizeInBits();
1468 unsigned OrigBW = OrigTy.getScalarSizeInBits();
1469 SDValue ShiftSz = DAG.getConstant(BW - OrigBW, DL, VT);
1470
1471 SDValue Op = DAG.getNode(ISD::SHL, DL, VT, Node->getOperand(0), ShiftSz);
1472 return DAG.getNode(ISD::SRA, DL, VT, Op, ShiftSz);
1473}
1474
1475// Generically expand a vector anyext in register to a shuffle of the relevant
1476// lanes into the appropriate locations, with other lanes left undef.
1477SDValue VectorLegalizer::ExpandANY_EXTEND_VECTOR_INREG(SDNode *Node) {
1478 SDLoc DL(Node);
1479 EVT VT = Node->getValueType(0);
1480 int NumElements = VT.getVectorNumElements();
1481 SDValue Src = Node->getOperand(0);
1482 EVT SrcVT = Src.getValueType();
1483 int NumSrcElements = SrcVT.getVectorNumElements();
1484
1485 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1486 // into a larger vector type.
1487 if (SrcVT.bitsLE(VT)) {
1488 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1489 "ANY_EXTEND_VECTOR_INREG vector size mismatch");
1490 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1491 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1492 NumSrcElements);
1493 Src = DAG.getInsertSubvector(DL, DAG.getUNDEF(SrcVT), Src, 0);
1494 }
1495
1496 // Build a base mask of undef shuffles.
1497 SmallVector<int, 16> ShuffleMask;
1498 ShuffleMask.resize(NumSrcElements, -1);
1499
1500 // Place the extended lanes into the correct locations.
1501 int ExtLaneScale = NumSrcElements / NumElements;
1502 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1503 for (int i = 0; i < NumElements; ++i)
1504 ShuffleMask[i * ExtLaneScale + EndianOffset] = i;
1505
1506 return DAG.getNode(
1507 ISD::BITCAST, DL, VT,
1508 DAG.getVectorShuffle(SrcVT, DL, Src, DAG.getPOISON(SrcVT), ShuffleMask));
1509}
1510
1511SDValue VectorLegalizer::ExpandSIGN_EXTEND_VECTOR_INREG(SDNode *Node) {
1512 SDLoc DL(Node);
1513 EVT VT = Node->getValueType(0);
1514 SDValue Src = Node->getOperand(0);
1515 EVT SrcVT = Src.getValueType();
1516
1517 // First build an any-extend node which can be legalized above when we
1518 // recurse through it.
1519 SDValue Op = DAG.getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, VT, Src);
1520
1521 // Now we need sign extend. This will be exanded to shifts if it isn't
1522 // supported.
1523 EVT ExtVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getVectorElementType(),
1525 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Op,
1526 DAG.getValueType(ExtVT));
1527}
1528
1529// Generically expand a vector zext in register to a shuffle of the relevant
1530// lanes into the appropriate locations, a blend of zero into the high bits,
1531// and a bitcast to the wider element type.
1532SDValue VectorLegalizer::ExpandZERO_EXTEND_VECTOR_INREG(SDNode *Node) {
1533 SDLoc DL(Node);
1534 EVT VT = Node->getValueType(0);
1535 int NumElements = VT.getVectorNumElements();
1536 SDValue Src = Node->getOperand(0);
1537 EVT SrcVT = Src.getValueType();
1538 int NumSrcElements = SrcVT.getVectorNumElements();
1539
1540 // *_EXTEND_VECTOR_INREG SrcVT can be smaller than VT - so insert the vector
1541 // into a larger vector type.
1542 if (SrcVT.bitsLE(VT)) {
1543 assert((VT.getSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
1544 "ZERO_EXTEND_VECTOR_INREG vector size mismatch");
1545 NumSrcElements = VT.getSizeInBits() / SrcVT.getScalarSizeInBits();
1546 SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getScalarType(),
1547 NumSrcElements);
1548 Src = DAG.getInsertSubvector(DL, DAG.getUNDEF(SrcVT), Src, 0);
1549 }
1550
1551 // Build up a zero vector to blend into this one.
1552 SDValue Zero = DAG.getConstant(0, DL, SrcVT);
1553
1554 // Shuffle the incoming lanes into the correct position, and pull all other
1555 // lanes from the zero vector.
1556 auto ShuffleMask = llvm::to_vector<16>(llvm::seq<int>(0, NumSrcElements));
1557
1558 int ExtLaneScale = NumSrcElements / NumElements;
1559 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1560 for (int i = 0; i < NumElements; ++i)
1561 ShuffleMask[i * ExtLaneScale + EndianOffset] = NumSrcElements + i;
1562
1563 return DAG.getNode(ISD::BITCAST, DL, VT,
1564 DAG.getVectorShuffle(SrcVT, DL, Zero, Src, ShuffleMask));
1565}
1566
1567static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) {
1568 int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;
1569 for (int I = 0, E = VT.getVectorNumElements(); I != E; ++I)
1570 for (int J = ScalarSizeInBytes - 1; J >= 0; --J)
1571 ShuffleMask.push_back((I * ScalarSizeInBytes) + J);
1572}
1573
1574SDValue VectorLegalizer::ExpandBSWAP(SDNode *Node) {
1575 EVT VT = Node->getValueType(0);
1576
1577 // Scalable vectors can't use shuffle expansion.
1578 if (VT.isScalableVector())
1579 return TLI.expandBSWAP(Node, DAG);
1580
1581 // Generate a byte wise shuffle mask for the BSWAP.
1582 SmallVector<int, 16> ShuffleMask;
1583 createBSWAPShuffleMask(VT, ShuffleMask);
1584 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, ShuffleMask.size());
1585
1586 // Only emit a shuffle if the mask is legal.
1587 if (TLI.isShuffleMaskLegal(ShuffleMask, ByteVT)) {
1588 SDLoc DL(Node);
1589 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1590 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getPOISON(ByteVT),
1591 ShuffleMask);
1592 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
1593 }
1594
1595 // If we have the appropriate vector bit operations, it is better to use them
1596 // than unrolling and expanding each component.
1597 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1601 return TLI.expandBSWAP(Node, DAG);
1602
1603 // Otherwise let the caller unroll.
1604 return SDValue();
1605}
1606
1607SDValue VectorLegalizer::ExpandBITREVERSE(SDNode *Node) {
1608 EVT VT = Node->getValueType(0);
1609
1610 // We can't unroll or use shuffles for scalable vectors.
1611 if (VT.isScalableVector())
1612 return TLI.expandBITREVERSE(Node, DAG);
1613
1614 // If we have the scalar operation, it's probably cheaper to unroll it.
1616 return SDValue();
1617
1618 // If the vector element width is a whole number of bytes, test if its legal
1619 // to BSWAP shuffle the bytes and then perform the BITREVERSE on the byte
1620 // vector. This greatly reduces the number of bit shifts necessary.
1621 unsigned ScalarSizeInBits = VT.getScalarSizeInBits();
1622 if (ScalarSizeInBits > 8 && (ScalarSizeInBits % 8) == 0) {
1623 SmallVector<int, 16> BSWAPMask;
1624 createBSWAPShuffleMask(VT, BSWAPMask);
1625
1626 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, BSWAPMask.size());
1627 if (TLI.isShuffleMaskLegal(BSWAPMask, ByteVT) &&
1629 (TLI.isOperationLegalOrCustom(ISD::SHL, ByteVT) &&
1630 TLI.isOperationLegalOrCustom(ISD::SRL, ByteVT) &&
1633 SDLoc DL(Node);
1634 SDValue Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Node->getOperand(0));
1635 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getPOISON(ByteVT),
1636 BSWAPMask);
1637 Op = DAG.getNode(ISD::BITREVERSE, DL, ByteVT, Op);
1638 Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
1639 return Op;
1640 }
1641 }
1642
1643 // If we have the appropriate vector bit operations, it is better to use them
1644 // than unrolling and expanding each component.
1645 if (TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
1649 return TLI.expandBITREVERSE(Node, DAG);
1650
1651 // Otherwise unroll.
1652 return SDValue();
1653}
1654
1655SDValue VectorLegalizer::ExpandVSELECT(SDNode *Node) {
1656 // Implement VSELECT in terms of XOR, AND, OR
1657 // on platforms which do not support blend natively.
1658 SDLoc DL(Node);
1659
1660 SDValue Mask = Node->getOperand(0);
1661 SDValue Op1 = Node->getOperand(1);
1662 SDValue Op2 = Node->getOperand(2);
1663
1664 EVT VT = Mask.getValueType();
1665
1666 // If we can't even use the basic vector operations of
1667 // AND,OR,XOR, we will have to scalarize the op.
1668 // Notice that the operation may be 'promoted' which means that it is
1669 // 'bitcasted' to another type which is handled.
1670 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
1671 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
1672 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand)
1673 return SDValue();
1674
1675 // This operation also isn't safe with AND, OR, XOR when the boolean type is
1676 // 0/1 and the select operands aren't also booleans, as we need an all-ones
1677 // vector constant to mask with.
1678 // FIXME: Sign extend 1 to all ones if that's legal on the target.
1679 auto BoolContents = TLI.getBooleanContents(Op1.getValueType());
1680 if (BoolContents != TargetLowering::ZeroOrNegativeOneBooleanContent &&
1681 !(BoolContents == TargetLowering::ZeroOrOneBooleanContent &&
1682 Op1.getValueType().getVectorElementType() == MVT::i1))
1683 return SDValue();
1684
1685 // If the mask and the type are different sizes, unroll the vector op. This
1686 // can occur when getSetCCResultType returns something that is different in
1687 // size from the operand types. For example, v4i8 = select v4i32, v4i8, v4i8.
1688 if (VT.getSizeInBits() != Op1.getValueSizeInBits())
1689 return SDValue();
1690
1691 // Bitcast the operands to be the same type as the mask.
1692 // This is needed when we select between FP types because
1693 // the mask is a vector of integers.
1694 Op1 = DAG.getNode(ISD::BITCAST, DL, VT, Op1);
1695 Op2 = DAG.getNode(ISD::BITCAST, DL, VT, Op2);
1696
1697 SDValue NotMask = DAG.getNOT(DL, Mask, VT);
1698
1699 Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask);
1700 Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask);
1701 SDValue Val = DAG.getNode(ISD::OR, DL, VT, Op1, Op2);
1702 return DAG.getNode(ISD::BITCAST, DL, Node->getValueType(0), Val);
1703}
1704
1705SDValue VectorLegalizer::ExpandVP_MERGE(SDNode *Node) {
1706 // Implement VP_MERGE in terms of VSELECT. Construct a mask where vector
1707 // indices less than the EVL/pivot are true. Combine that with the original
1708 // mask for a full-length mask. Use a full-length VSELECT to select between
1709 // the true and false values.
1710 SDLoc DL(Node);
1711
1712 SDValue Mask = Node->getOperand(0);
1713 SDValue Op1 = Node->getOperand(1);
1714 SDValue Op2 = Node->getOperand(2);
1715 SDValue EVL = Node->getOperand(3);
1716
1717 EVT MaskVT = Mask.getValueType();
1718 bool IsFixedLen = MaskVT.isFixedLengthVector();
1719
1720 EVT EVLVecVT = EVT::getVectorVT(*DAG.getContext(), EVL.getValueType(),
1721 MaskVT.getVectorElementCount());
1722
1723 // If we can't construct the EVL mask efficiently, it's better to unroll.
1724 if ((IsFixedLen &&
1726 (!IsFixedLen &&
1727 (!TLI.isOperationLegalOrCustom(ISD::STEP_VECTOR, EVLVecVT) ||
1729 return SDValue();
1730
1731 // If using a SETCC would result in a different type than the mask type,
1732 // unroll.
1733 if (TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
1734 EVLVecVT) != MaskVT)
1735 return SDValue();
1736
1737 SDValue StepVec = DAG.getStepVector(DL, EVLVecVT);
1738 SDValue SplatEVL = DAG.getSplat(EVLVecVT, DL, EVL);
1739 SDValue EVLMask =
1740 DAG.getSetCC(DL, MaskVT, StepVec, SplatEVL, ISD::CondCode::SETULT);
1741
1742 SDValue FullMask = DAG.getNode(ISD::AND, DL, MaskVT, Mask, EVLMask);
1743 return DAG.getSelect(DL, Node->getValueType(0), FullMask, Op1, Op2);
1744}
1745
1746SDValue VectorLegalizer::ExpandVP_REM(SDNode *Node) {
1747 // Implement VP_SREM/UREM in terms of VP_SDIV/VP_UDIV, MUL, SUB.
1748 EVT VT = Node->getValueType(0);
1749
1750 unsigned DivOpc = Node->getOpcode() == ISD::VP_SREM ? ISD::VP_SDIV : ISD::VP_UDIV;
1751
1752 if (!TLI.isOperationLegalOrCustom(DivOpc, VT) ||
1755 return SDValue();
1756
1757 SDLoc DL(Node);
1758
1759 SDValue Dividend = Node->getOperand(0);
1760 SDValue Divisor = Node->getOperand(1);
1761 SDValue Mask = Node->getOperand(2);
1762 SDValue EVL = Node->getOperand(3);
1763
1764 // X % Y -> X-X/Y*Y
1765 SDValue Div = DAG.getNode(DivOpc, DL, VT, Dividend, Divisor, Mask, EVL);
1766 SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, Divisor, Div);
1767 return DAG.getNode(ISD::SUB, DL, VT, Dividend, Mul);
1768}
1769
1770SDValue VectorLegalizer::ExpandLOOP_DEPENDENCE_MASK(SDNode *N) {
1771 return TLI.expandLoopDependenceMask(N, DAG);
1772}
1773
1774SDValue VectorLegalizer::ExpandMASK_BEFOREFIRST(SDNode *N) {
1775 // Expand to (get_active_lane_mask 0, (cttz_elts x))
1776 SDLoc DL(N);
1777 EVT VT = N->getValueType(0);
1778 EVT VecIdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());
1779 SDValue CttzElts =
1780 DAG.getNode(ISD::CTTZ_ELTS, DL, VecIdxVT, N->getOperand(0));
1781 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, VT,
1782 DAG.getConstant(0, DL, VecIdxVT), CttzElts);
1783}
1784
1785SDValue VectorLegalizer::ExpandMaskedBinOp(SDNode *N) {
1786 // Masked bin ops don't have undefined behaviour when dividing by zero
1787 // on disabled lanes and produce poison instead. Replace the divisor on the
1788 // disabled lanes with 1 to avoid division by zero or overflow.
1789 SDLoc dl(N);
1790 EVT VT = N->getValueType(0);
1791 SDValue SafeDivisor = DAG.getSelect(
1792 dl, VT, N->getOperand(2), N->getOperand(1), DAG.getConstant(1, dl, VT));
1793 return DAG.getNode(ISD::getUnmaskedBinOpOpcode(N->getOpcode()), dl, VT,
1794 N->getOperand(0), SafeDivisor);
1795}
1796
1797void VectorLegalizer::ExpandFP_TO_UINT(SDNode *Node,
1798 SmallVectorImpl<SDValue> &Results) {
1799 // Attempt to expand using TargetLowering.
1800 SDValue Result, Chain;
1801 if (TLI.expandFP_TO_UINT(Node, Result, Chain, DAG)) {
1802 Results.push_back(Result);
1803 if (Node->isStrictFPOpcode())
1804 Results.push_back(Chain);
1805 return;
1806 }
1807
1808 // Otherwise go ahead and unroll.
1809 if (Node->isStrictFPOpcode()) {
1810 UnrollStrictFPOp(Node, Results);
1811 return;
1812 }
1813
1814 Results.push_back(DAG.UnrollVectorOp(Node));
1815}
1816
1817void VectorLegalizer::ExpandUINT_TO_FLOAT(SDNode *Node,
1818 SmallVectorImpl<SDValue> &Results) {
1819 bool IsStrict = Node->isStrictFPOpcode();
1820 unsigned OpNo = IsStrict ? 1 : 0;
1821 SDValue Src = Node->getOperand(OpNo);
1822 EVT SrcVT = Src.getValueType();
1823 EVT DstVT = Node->getValueType(0);
1824 SDLoc DL(Node);
1825
1826 // Attempt to expand using TargetLowering.
1827 SDValue Result;
1828 SDValue Chain;
1829 if (TLI.expandUINT_TO_FP(Node, Result, Chain, DAG)) {
1830 Results.push_back(Result);
1831 if (IsStrict)
1832 Results.push_back(Chain);
1833 return;
1834 }
1835
1836 // Make sure that the SINT_TO_FP and SRL instructions are available.
1837 if (((!IsStrict && TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) ==
1838 TargetLowering::Expand) ||
1839 (IsStrict && TLI.getOperationAction(ISD::STRICT_SINT_TO_FP, SrcVT) ==
1840 TargetLowering::Expand)) ||
1841 TLI.getOperationAction(ISD::SRL, SrcVT) == TargetLowering::Expand) {
1842 if (IsStrict) {
1843 UnrollStrictFPOp(Node, Results);
1844 return;
1845 }
1846
1847 Results.push_back(DAG.UnrollVectorOp(Node));
1848 return;
1849 }
1850
1851 unsigned BW = SrcVT.getScalarSizeInBits();
1852 assert((BW == 64 || BW == 32) &&
1853 "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide");
1854
1855 // If STRICT_/FMUL is not supported by the target (in case of f16) replace the
1856 // UINT_TO_FP with a larger float and round to the smaller type
1857 if ((!IsStrict && !TLI.isOperationLegalOrCustom(ISD::FMUL, DstVT)) ||
1858 (IsStrict && !TLI.isOperationLegalOrCustom(ISD::STRICT_FMUL, DstVT))) {
1859 EVT FPVT = BW == 32 ? MVT::f32 : MVT::f64;
1860 SDValue UIToFP;
1861 SDValue Result;
1862 SDValue TargetZero = DAG.getIntPtrConstant(0, DL, /*isTarget=*/true);
1863 EVT FloatVecVT = SrcVT.changeVectorElementType(*DAG.getContext(), FPVT);
1864 if (IsStrict) {
1865 UIToFP = DAG.getNode(ISD::STRICT_UINT_TO_FP, DL, {FloatVecVT, MVT::Other},
1866 {Node->getOperand(0), Src});
1867 Result = DAG.getNode(ISD::STRICT_FP_ROUND, DL, {DstVT, MVT::Other},
1868 {Node->getOperand(0), UIToFP, TargetZero});
1869 Results.push_back(Result);
1870 Results.push_back(Result.getValue(1));
1871 } else {
1872 UIToFP = DAG.getNode(ISD::UINT_TO_FP, DL, FloatVecVT, Src);
1873 Result = DAG.getNode(ISD::FP_ROUND, DL, DstVT, UIToFP, TargetZero);
1874 Results.push_back(Result);
1875 }
1876
1877 return;
1878 }
1879
1880 SDValue HalfWord = DAG.getConstant(BW / 2, DL, SrcVT);
1881
1882 // Constants to clear the upper part of the word.
1883 // Notice that we can also use SHL+SHR, but using a constant is slightly
1884 // faster on x86.
1885 uint64_t HWMask = (BW == 64) ? 0x00000000FFFFFFFF : 0x0000FFFF;
1886 SDValue HalfWordMask = DAG.getConstant(HWMask, DL, SrcVT);
1887
1888 // Two to the power of half-word-size.
1889 SDValue TWOHW = DAG.getConstantFP(1ULL << (BW / 2), DL, DstVT);
1890
1891 // Clear upper part of LO, lower HI
1892 SDValue HI = DAG.getNode(ISD::SRL, DL, SrcVT, Src, HalfWord);
1893 SDValue LO = DAG.getNode(ISD::AND, DL, SrcVT, Src, HalfWordMask);
1894
1895 if (IsStrict) {
1896 // Convert hi and lo to floats
1897 // Convert the hi part back to the upper values
1898 // TODO: Can any fast-math-flags be set on these nodes?
1899 SDValue fHI = DAG.getNode(ISD::STRICT_SINT_TO_FP, DL, {DstVT, MVT::Other},
1900 {Node->getOperand(0), HI});
1901 fHI = DAG.getNode(ISD::STRICT_FMUL, DL, {DstVT, MVT::Other},
1902 {fHI.getValue(1), fHI, TWOHW});
1903 SDValue fLO = DAG.getNode(ISD::STRICT_SINT_TO_FP, DL, {DstVT, MVT::Other},
1904 {Node->getOperand(0), LO});
1905
1906 SDValue TF = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, fHI.getValue(1),
1907 fLO.getValue(1));
1908
1909 // Add the two halves
1910 SDValue Result =
1911 DAG.getNode(ISD::STRICT_FADD, DL, {DstVT, MVT::Other}, {TF, fHI, fLO});
1912
1913 Results.push_back(Result);
1914 Results.push_back(Result.getValue(1));
1915 return;
1916 }
1917
1918 // Convert hi and lo to floats
1919 // Convert the hi part back to the upper values
1920 // TODO: Can any fast-math-flags be set on these nodes?
1921 SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, DstVT, HI);
1922 fHI = DAG.getNode(ISD::FMUL, DL, DstVT, fHI, TWOHW);
1923 SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, DstVT, LO);
1924
1925 // Add the two halves
1926 Results.push_back(DAG.getNode(ISD::FADD, DL, DstVT, fHI, fLO));
1927}
1928
1929SDValue VectorLegalizer::ExpandFNEG(SDNode *Node) {
1930 EVT VT = Node->getValueType(0);
1931 EVT IntVT = VT.changeVectorElementTypeToInteger();
1932
1933 if (!TLI.isOperationLegalOrCustom(ISD::XOR, IntVT))
1934 return SDValue();
1935
1936 // Heuristic check to determine whether vector should be expanded to integer
1937 // operations or unrolled to scalar operations.
1938 // 1. Scalable vector is never unrolled.
1939 // 2. Fixed vector is unrolled if one of followings is true:
1940 // a. Vector only has 1 element and target knows how to handle scalar
1941 // FNEG (either legal or custom expand or promote).
1942 // b. Vector has more than 1 element and target supports scalar
1943 // FNEG natively and vector length <= 2(1 XOR + 1 CONST).
1944 // FIXME: Scalar construction instruction count varies in every architecture,
1945 // here we assume 1 instruction for now.
1946 if (VT.isFixedLengthVector()) {
1947 EVT EltVT = VT.getVectorElementType();
1948 unsigned NumElts = VT.getVectorNumElements();
1949 if ((NumElts == 1 &&
1951 (NumElts < 3 && TLI.isOperationLegal(ISD::FNEG, EltVT) &&
1952 TLI.isExtractVecEltCheap(VT, 0) &&
1953 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
1954 return SDValue();
1955 }
1956
1957 SDLoc DL(Node);
1958 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1959 SDValue SignMask = DAG.getConstant(
1960 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
1961 SDValue Xor = DAG.getNode(ISD::XOR, DL, IntVT, Cast, SignMask);
1962 return DAG.getNode(ISD::BITCAST, DL, VT, Xor);
1963}
1964
1965SDValue VectorLegalizer::ExpandFABS(SDNode *Node) {
1966 EVT VT = Node->getValueType(0);
1967 EVT IntVT = VT.changeVectorElementTypeToInteger();
1968
1969 if (!TLI.isOperationLegalOrCustom(ISD::AND, IntVT))
1970 return SDValue();
1971
1972 // Heuristic check to determine whether vector should be expanded to integer
1973 // operations or unrolled to scalar operations.
1974 // 1. Scalable vector is never unrolled.
1975 // 2. Fixed vector is unrolled if one of followings is true:
1976 // a. Vector only has 1 element and target knows how to handle scalar
1977 // FABS(either legal or custom expand or promote).
1978 // b. Vector has more than 1 element and target supports scalar
1979 // FABS natively and vector length <= 2(1 AND + 1 CONST).
1980 // FIXME: Scalar construction instruction count varies in every architecture,
1981 // here we assume 1 instruction for now.
1982 if (VT.isFixedLengthVector()) {
1983 EVT EltVT = VT.getVectorElementType();
1984 unsigned NumElts = VT.getVectorNumElements();
1985 if ((NumElts == 1 &&
1987 (NumElts < 3 && TLI.isOperationLegal(ISD::FABS, EltVT) &&
1988 TLI.isExtractVecEltCheap(VT, 0) &&
1989 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
1990 return SDValue();
1991 }
1992
1993 SDLoc DL(Node);
1994 SDValue Cast = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
1995 SDValue ClearSignMask = DAG.getConstant(
1997 SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, Cast, ClearSignMask);
1998 return DAG.getNode(ISD::BITCAST, DL, VT, ClearedSign);
1999}
2000
2001SDValue VectorLegalizer::ExpandFCOPYSIGN(SDNode *Node) {
2002 EVT VT = Node->getValueType(0);
2003 EVT IntVT = VT.changeVectorElementTypeToInteger();
2004
2005 if (VT != Node->getOperand(1).getValueType() ||
2006 !TLI.isOperationLegalOrCustom(ISD::AND, IntVT) ||
2007 !TLI.isOperationLegalOrCustom(ISD::OR, IntVT))
2008 return SDValue();
2009
2010 // Heuristic check to determine whether vector should be expanded to integer
2011 // operations or unrolled to scalar operations.
2012 // 1. Scalable vector is never unrolled.
2013 // 2. Fixed vector is unrolled if one of followings is true:
2014 // a. Vector only has 1 element and target knows how to handle scalar
2015 // FCOPYSIGN(either legal or custom expand or promote).
2016 // b. Vector has more than 1 element and target supports scalar
2017 // FCOPYSIGN natively and vector length <= 5(2 AND + 1 OR + 2 CONST).
2018 // FIXME: Scalar construction instruction count varies in every architecture,
2019 // here we assume 1 instruction for now.
2020 if (VT.isFixedLengthVector()) {
2021 EVT EltVT = VT.getVectorElementType();
2022 unsigned NumElts = VT.getVectorNumElements();
2023 if ((NumElts == 1 &&
2025 (NumElts < 6 && TLI.isOperationLegal(ISD::FCOPYSIGN, EltVT) &&
2026 TLI.isExtractVecEltCheap(VT, 0) &&
2027 (NumElts == 1 || TLI.isExtractVecEltCheap(VT, 1))))
2028 return SDValue();
2029 }
2030
2031 SDLoc DL(Node);
2032 SDValue Mag = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(0));
2033 SDValue Sign = DAG.getNode(ISD::BITCAST, DL, IntVT, Node->getOperand(1));
2034
2035 SDValue SignMask = DAG.getConstant(
2036 APInt::getSignMask(IntVT.getScalarSizeInBits()), DL, IntVT);
2037 SDValue SignBit = DAG.getNode(ISD::AND, DL, IntVT, Sign, SignMask);
2038
2039 SDValue ClearSignMask = DAG.getConstant(
2041 SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, Mag, ClearSignMask);
2042
2043 SDValue CopiedSign = DAG.getNode(ISD::OR, DL, IntVT, ClearedSign, SignBit,
2045
2046 return DAG.getNode(ISD::BITCAST, DL, VT, CopiedSign);
2047}
2048
2049void VectorLegalizer::ExpandFSUB(SDNode *Node,
2050 SmallVectorImpl<SDValue> &Results) {
2051 // For floating-point values, (a-b) is the same as a+(-b). If FNEG is legal,
2052 // we can defer this to operation legalization where it will be lowered as
2053 // a+(-b).
2054 EVT VT = Node->getValueType(0);
2055 if (TLI.isOperationLegalOrCustom(ISD::FNEG, VT) &&
2057 return; // Defer to LegalizeDAG
2058
2059 if (SDValue Expanded = TLI.expandVectorNaryOpBySplitting(Node, DAG)) {
2060 Results.push_back(Expanded);
2061 return;
2062 }
2063
2064 SDValue Tmp = DAG.UnrollVectorOp(Node);
2065 Results.push_back(Tmp);
2066}
2067
2068void VectorLegalizer::ExpandSETCC(SDNode *Node,
2069 SmallVectorImpl<SDValue> &Results) {
2070 bool NeedInvert = false;
2071 bool IsStrict = Node->getOpcode() == ISD::STRICT_FSETCC ||
2072 Node->getOpcode() == ISD::STRICT_FSETCCS;
2073 bool IsSignaling = Node->getOpcode() == ISD::STRICT_FSETCCS;
2074 unsigned Offset = IsStrict ? 1 : 0;
2075
2076 SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
2077 SDValue LHS = Node->getOperand(0 + Offset);
2078 SDValue RHS = Node->getOperand(1 + Offset);
2079 SDValue CC = Node->getOperand(2 + Offset);
2080
2081 MVT OpVT = LHS.getSimpleValueType();
2082 ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
2083
2084 if (TLI.getCondCodeAction(CCCode, OpVT) != TargetLowering::Expand) {
2085 if (IsStrict) {
2086 UnrollStrictFPOp(Node, Results);
2087 return;
2088 }
2089 Results.push_back(UnrollVSETCC(Node));
2090 return;
2091 }
2092
2093 SDLoc dl(Node);
2094 bool Legalized =
2095 TLI.LegalizeSetCCCondCode(DAG, Node->getValueType(0), LHS, RHS, CC,
2096 NeedInvert, dl, Chain, IsSignaling);
2097
2098 if (Legalized) {
2099 // If we expanded the SETCC by swapping LHS and RHS, or by inverting the
2100 // condition code, create a new SETCC node.
2101 if (CC.getNode()) {
2102 if (IsStrict) {
2103 LHS = DAG.getNode(Node->getOpcode(), dl, Node->getVTList(),
2104 {Chain, LHS, RHS, CC}, Node->getFlags());
2105 Chain = LHS.getValue(1);
2106 } else {
2107 LHS = DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), LHS, RHS, CC,
2108 Node->getFlags());
2109 }
2110 }
2111
2112 // If we expanded the SETCC by inverting the condition code, then wrap
2113 // the existing SETCC in a NOT to restore the intended condition.
2114 if (NeedInvert)
2115 LHS = DAG.getLogicalNOT(dl, LHS, LHS->getValueType(0));
2116 } else {
2117 assert(!IsStrict && "Don't know how to expand for strict nodes.");
2118
2119 // Otherwise, SETCC for the given comparison type must be completely
2120 // illegal; expand it into a SELECT_CC.
2121 EVT VT = Node->getValueType(0);
2122 LHS = DAG.getNode(ISD::SELECT_CC, dl, VT, LHS, RHS,
2123 DAG.getBoolConstant(true, dl, VT, LHS.getValueType()),
2124 DAG.getBoolConstant(false, dl, VT, LHS.getValueType()),
2125 CC, Node->getFlags());
2126 }
2127
2128 Results.push_back(LHS);
2129 if (IsStrict)
2130 Results.push_back(Chain);
2131}
2132
2133void VectorLegalizer::ExpandUADDSUBO(SDNode *Node,
2134 SmallVectorImpl<SDValue> &Results) {
2135 SDValue Result, Overflow;
2136 TLI.expandUADDSUBO(Node, Result, Overflow, DAG);
2137 Results.push_back(Result);
2138 Results.push_back(Overflow);
2139}
2140
2141void VectorLegalizer::ExpandSADDSUBO(SDNode *Node,
2142 SmallVectorImpl<SDValue> &Results) {
2143 SDValue Result, Overflow;
2144 TLI.expandSADDSUBO(Node, Result, Overflow, DAG);
2145 Results.push_back(Result);
2146 Results.push_back(Overflow);
2147}
2148
2149void VectorLegalizer::ExpandMULO(SDNode *Node,
2150 SmallVectorImpl<SDValue> &Results) {
2151 SDValue Result, Overflow;
2152 if (!TLI.expandMULO(Node, Result, Overflow, DAG))
2153 std::tie(Result, Overflow) = DAG.UnrollVectorOverflowOp(Node);
2154
2155 Results.push_back(Result);
2156 Results.push_back(Overflow);
2157}
2158
2159void VectorLegalizer::ExpandFixedPointDiv(SDNode *Node,
2160 SmallVectorImpl<SDValue> &Results) {
2161 SDNode *N = Node;
2162 if (SDValue Expanded = TLI.expandFixedPointDiv(N->getOpcode(), SDLoc(N),
2163 N->getOperand(0), N->getOperand(1), N->getConstantOperandVal(2), DAG))
2164 Results.push_back(Expanded);
2165}
2166
2167void VectorLegalizer::ExpandStrictFPOp(SDNode *Node,
2168 SmallVectorImpl<SDValue> &Results) {
2169 if (Node->getOpcode() == ISD::STRICT_UINT_TO_FP) {
2170 ExpandUINT_TO_FLOAT(Node, Results);
2171 return;
2172 }
2173 if (Node->getOpcode() == ISD::STRICT_FP_TO_UINT) {
2174 ExpandFP_TO_UINT(Node, Results);
2175 return;
2176 }
2177
2178 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2179 Node->getOpcode() == ISD::STRICT_FSETCCS) {
2180 ExpandSETCC(Node, Results);
2181 return;
2182 }
2183
2184 UnrollStrictFPOp(Node, Results);
2185}
2186
2187void VectorLegalizer::ExpandREM(SDNode *Node,
2188 SmallVectorImpl<SDValue> &Results) {
2189 assert((Node->getOpcode() == ISD::SREM || Node->getOpcode() == ISD::UREM) &&
2190 "Expected REM node");
2191
2192 SDValue Result;
2193 if (!TLI.expandREM(Node, Result, DAG))
2194 Result = DAG.UnrollVectorOp(Node);
2195 Results.push_back(Result);
2196}
2197
2198// Try to expand libm nodes into vector math routine calls. Callers provide the
2199// RTLIB::get<OP>(EVT) selector of the node's libcall family, which is used to
2200// look up mappings within RuntimeLibcallsInfo. The only mappings considered are
2201// those where the result and all operands are the same vector type. While
2202// predicated nodes are not supported, we will emit calls to masked routines by
2203// passing in a mask that is true for the lanes computed by the node.
2204bool VectorLegalizer::tryExpandVecMathCall(
2205 SDNode *Node, function_ref<RTLIB::Libcall(EVT)> GetLibcall,
2206 SmallVectorImpl<SDValue> &Results) {
2207 // Chain must be propagated but currently strict fp operations are down
2208 // converted to their none strict counterpart.
2209 assert(!Node->isStrictFPOpcode() && "Unexpected strict fp operation!");
2210
2211 EVT VT = Node->getValueType(0);
2212 LLVMContext &Ctx = *DAG.getContext();
2213 const LibcallLoweringInfo &Libcalls = DAG.getLibcalls();
2214
2215 // Try to widen the vector type when no libcall is available at that width.
2216 EVT CallVT = VT;
2217 RTLIB::LibcallImpl LCImpl =
2218 Libcalls.getVectorLibcallImplOrMasked(GetLibcall(CallVT));
2219 if (LCImpl == RTLIB::Unsupported && VT.getVectorElementCount().isScalar())
2220 return false;
2221 while (LCImpl == RTLIB::Unsupported) {
2222 CallVT = CallVT.getDoubleNumVectorElementsVT(Ctx);
2223 if (!CallVT.isSimple())
2224 return false;
2225 if (TLI.isTypeLegal(CallVT))
2226 LCImpl = Libcalls.getVectorLibcallImplOrMasked(GetLibcall(CallVT));
2227 }
2228
2229 const RTLIB::RuntimeLibcallsInfo &RTLCI = TLI.getRuntimeLibcallsInfo();
2230
2231 auto [FuncTy, FuncAttrs] = RTLCI.getFunctionTy(
2232 Ctx, DAG.getSubtarget().getTargetTriple(), DAG.getDataLayout(), LCImpl);
2233
2234 SDLoc DL(Node);
2235 TargetLowering::ArgListTy Args;
2236
2237 bool HasMaskArg = RTLCI.hasVectorMaskArgument(LCImpl);
2238
2239 // Sanity check just in case function has unexpected parameters.
2240 assert(FuncTy->getNumParams() == Node->getNumOperands() + HasMaskArg &&
2241 EVT::getEVT(FuncTy->getReturnType(), true) == CallVT &&
2242 "mismatch in value type and call signature type");
2243
2244 for (unsigned I = 0, E = FuncTy->getNumParams(); I != E; ++I) {
2245 Type *ParamTy = FuncTy->getParamType(I);
2246
2247 if (HasMaskArg && I == E - 1) {
2248 assert(cast<VectorType>(ParamTy)->getElementType()->isIntegerTy(1) &&
2249 cast<VectorType>(ParamTy)->getElementCount() ==
2250 CallVT.getVectorElementCount() &&
2251 "unexpected vector mask type");
2252 EVT MaskVT = EVT::getEVT(ParamTy, /*HandleUnknown=*/true);
2253 EVT SubMaskVT =
2255 SDValue Mask = DAG.getBoolConstant(true, DL, SubMaskVT, VT);
2256 // Only the lanes holding the node's elements need to be active.
2257 if (CallVT != VT)
2259 DL, DAG.getBoolConstant(false, DL, MaskVT, CallVT), Mask, 0);
2260 Args.emplace_back(Mask, ParamTy);
2261 } else {
2262 SDValue Op = Node->getOperand(I);
2263 assert(Op.getValueType() == VT && "mismatch in vector types");
2264 if (CallVT != VT) {
2265 unsigned NumConcat =
2267 SmallVector<SDValue, 4> Ops(NumConcat, Op);
2268 Op = DAG.getNode(ISD::CONCAT_VECTORS, DL, CallVT, Ops);
2269 }
2270 assert(Op.getValueType() == EVT::getEVT(ParamTy, true) &&
2271 "mismatch in value type and call argument type");
2272 Args.emplace_back(Op, ParamTy);
2273 }
2274 }
2275
2276 // Emit a call to the vector function.
2277 SDValue Callee =
2278 DAG.getExternalSymbol(LCImpl, TLI.getPointerTy(DAG.getDataLayout()));
2279 CallingConv::ID CC = RTLCI.getLibcallImplCallingConv(LCImpl);
2280
2281 TargetLowering::CallLoweringInfo CLI(DAG);
2282 CLI.setDebugLoc(DL)
2283 .setChain(DAG.getEntryNode())
2284 .setLibCallee(CC, FuncTy->getReturnType(), Callee, std::move(Args));
2285
2286 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
2287 SDValue Result = CallResult.first;
2288 if (CallVT != VT)
2289 Result = DAG.getExtractSubvector(DL, VT, Result, 0);
2290 Results.push_back(Result);
2291 return true;
2292}
2293
2294void VectorLegalizer::UnrollStrictFPOp(SDNode *Node,
2295 SmallVectorImpl<SDValue> &Results) {
2296 EVT VT = Node->getValueType(0);
2297
2298 // Cannot unroll a scalable vector. Delay error reporting until the final
2299 // operation legalisation phase to maximise the chances of removing the node.
2300 if (VT.isScalableVector())
2301 return;
2302
2303 EVT EltVT = VT.getVectorElementType();
2304 unsigned NumElems = VT.getVectorNumElements();
2305 unsigned NumOpers = Node->getNumOperands();
2306 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
2307
2308 EVT TmpEltVT = EltVT;
2309 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2310 Node->getOpcode() == ISD::STRICT_FSETCCS)
2311 TmpEltVT = TLI.getSetCCResultType(DAG.getDataLayout(),
2312 *DAG.getContext(), TmpEltVT);
2313
2314 EVT ValueVTs[] = {TmpEltVT, MVT::Other};
2315 SDValue Chain = Node->getOperand(0);
2316 SDLoc dl(Node);
2317
2318 SmallVector<SDValue, 32> OpValues;
2319 SmallVector<SDValue, 32> OpChains;
2320 for (unsigned i = 0; i < NumElems; ++i) {
2322 SDValue Idx = DAG.getVectorIdxConstant(i, dl);
2323
2324 // The Chain is the first operand.
2325 Opers.push_back(Chain);
2326
2327 // Now process the remaining operands.
2328 for (unsigned j = 1; j < NumOpers; ++j) {
2329 SDValue Oper = Node->getOperand(j);
2330 EVT OperVT = Oper.getValueType();
2331
2332 if (OperVT.isVector())
2333 Oper = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2334 OperVT.getVectorElementType(), Oper, Idx);
2335
2336 Opers.push_back(Oper);
2337 }
2338
2339 SDValue ScalarOp = DAG.getNode(Node->getOpcode(), dl, ValueVTs, Opers);
2340 SDValue ScalarResult = ScalarOp.getValue(0);
2341 SDValue ScalarChain = ScalarOp.getValue(1);
2342
2343 if (Node->getOpcode() == ISD::STRICT_FSETCC ||
2344 Node->getOpcode() == ISD::STRICT_FSETCCS)
2345 ScalarResult = DAG.getSelect(dl, EltVT, ScalarResult,
2346 DAG.getAllOnesConstant(dl, EltVT),
2347 DAG.getConstant(0, dl, EltVT));
2348
2349 OpValues.push_back(ScalarResult);
2350 OpChains.push_back(ScalarChain);
2351 }
2352
2353 SDValue Result = DAG.getBuildVector(VT, dl, OpValues);
2354 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OpChains);
2355
2356 Results.push_back(Result);
2357 Results.push_back(NewChain);
2358}
2359
2360SDValue VectorLegalizer::UnrollVSETCC(SDNode *Node) {
2361 EVT VT = Node->getValueType(0);
2362 unsigned NumElems = VT.getVectorNumElements();
2363 EVT EltVT = VT.getVectorElementType();
2364 SDValue LHS = Node->getOperand(0);
2365 SDValue RHS = Node->getOperand(1);
2366 SDValue CC = Node->getOperand(2);
2367 EVT TmpEltVT = LHS.getValueType().getVectorElementType();
2368 SDLoc dl(Node);
2369 SmallVector<SDValue, 8> Ops(NumElems);
2370 for (unsigned i = 0; i < NumElems; ++i) {
2371 SDValue LHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
2372 DAG.getVectorIdxConstant(i, dl));
2373 SDValue RHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
2374 DAG.getVectorIdxConstant(i, dl));
2375 // FIXME: We should use i1 setcc + boolext here, but it causes regressions.
2376 Ops[i] = DAG.getNode(ISD::SETCC, dl,
2378 *DAG.getContext(), TmpEltVT),
2379 LHSElem, RHSElem, CC);
2380 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i],
2381 DAG.getBoolConstant(true, dl, EltVT, VT),
2382 DAG.getConstant(0, dl, EltVT));
2383 }
2384 return DAG.getBuildVector(VT, dl, Ops);
2385}
2386
2388 return VectorLegalizer(*this).Run();
2389}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl< int > &ShuffleMask)
#define I(x, y, z)
Definition MD5.cpp:57
#define T
SI Fold Operands
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file describes how to lower LLVM code to machine code.
Value * RHS
Value * LHS
BinaryOperator * Mul
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
Definition APInt.h:225
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:205
bool isBigEndian() const
Definition DataLayout.h:218
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:828
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:316
size_t size() const
Definition Function.h:843
RTLIB::LibcallImpl getVectorLibcallImplOrMasked(RTLIB::Libcall Call) const
Return the implementation for Call, or for its masked variant if Call has no implementation.
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 getExtractSubvector(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Return the VT typed sub-vector of Vec at Idx.
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)
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.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
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...
LegalizeAction getVectorInterleaveAction(unsigned Opc, unsigned Factor, EVT VT) const
Return how a VECTOR_INTERLEAVE or VECTOR_DEINTERLEAVE node with the given interleave factor and VT sh...
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
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.
void expandVectorDeinterleave(SDNode *Node, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
Expand a VECTOR_DEINTERLEAVE without introducing wider vector types.
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.
bool expandMULO(SDNode *Node, SDValue &Result, SDValue &Overflow, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]MULO.
bool LegalizeSetCCCondCode(SelectionDAG &DAG, EVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, bool &NeedInvert, const SDLoc &dl, SDValue &Chain, bool IsSignaling=false) const
Legalize a SETCC with given LHS and RHS and condition code CC on the current target.
SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const
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 expandGetActiveLaneMask(SDNode *N, SelectionDAG &DAG) const
Expand GET_ACTIVE_LANE_MASK 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 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.
SDValue expandMULH(SDNode *Node, SelectionDAG &DAG) const
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.
void expandVectorInterleave(SDNode *Node, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
Expand a VECTOR_INTERLEAVE without introducing wider vector types.
SDValue expandLoopDependenceMask(SDNode *N, SelectionDAG &DAG) const
Expand LOOP_DEPENDENCE_MASK nodes.
SDValue expandCTPOP(SDNode *N, SelectionDAG &DAG) const
Expand CTPOP nodes.
SDValue expandVectorNaryOpBySplitting(SDNode *Node, SelectionDAG &DAG) const
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
SDValue expandBSWAP(SDNode *N, SelectionDAG &DAG) const
Expand BSWAP nodes.
SDValue expandFMINIMUM_FMAXIMUM(SDNode *N, SelectionDAG &DAG) const
Expand fminimum/fmaximum into multiple comparison with selects.
std::pair< SDValue, SDValue > scalarizeVectorLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Turn load of vector type into a load of the individual elements.
SDValue expandVectorMatch(SDNode *N, SelectionDAG &DAG) const
Expand VECTOR_MATCH nodes.
SDValue expandCONVERT_TO_ARBITRARY_FP(SDNode *Node, SelectionDAG &DAG) const
Expand CONVERT_TO_ARBITRARY_FP using bit manipulation.
SDValue expandFunnelShift(SDNode *N, SelectionDAG &DAG) const
Expand funnel shift.
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 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 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.
An efficient, type-erasing, non-owning reference to a callable.
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:845
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition ISDOpcodes.h:263
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition ISDOpcodes.h:516
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ MASK_BEFOREFIRST
Has one mask vector operand.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ VECREDUCE_FMINIMUMNUM
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ AVGSUBFLOORS
AVGSUBFLOORS/AVGSUBFLOORU - Averaging subtract - Subtract two integers using an integer of type i[N+1...
Definition ISDOpcodes.h:733
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
Definition ISDOpcodes.h:397
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ 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:403
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:879
@ 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:523
@ 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:906
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition ISDOpcodes.h:589
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ 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:765
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
Definition ISDOpcodes.h:936
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
Definition ISDOpcodes.h:520
@ 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:796
@ 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:410
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:441
@ 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:814
@ PARTIAL_REDUCE_UMLA
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition ISDOpcodes.h:725
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:490
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ PARTIAL_REDUCE_FMLA
@ VECREDUCE_FMAXIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM nodes do not propagate NaNs and order signed zeroes using the llvm....
@ 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:355
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
Definition ISDOpcodes.h:640
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
Definition ISDOpcodes.h:701
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
Definition ISDOpcodes.h:546
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:377
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition ISDOpcodes.h:682
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:351
@ 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:714
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ 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:581
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ 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:389
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:359
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
Definition ISDOpcodes.h:925
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:745
@ 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:416
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:831
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:489
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_TO_UINT
Definition ISDOpcodes.h:483
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
Definition ISDOpcodes.h:801
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:505
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:482
@ 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:952
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:510
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:753
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition ISDOpcodes.h:720
@ VECTOR_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:430
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:813
@ 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:985
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
Definition ISDOpcodes.h:709
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
Definition ISDOpcodes.h:947
@ 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:971
@ VECREDUCE_FMINIMUM
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ 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:64
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:539
@ PARTIAL_REDUCE_SUMLA
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:368
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
Definition ISDOpcodes.h:629
@ 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:740
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
Definition ISDOpcodes.h:769
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:561
@ 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.
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.
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
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:1762
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
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
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
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
Definition ValueTypes.h:494
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
Definition ValueTypes.h:382
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
EVT changeVectorElementCount(LLVMContext &Context, ElementCount EC) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element coun...
Definition ValueTypes.h:109
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
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.
static bool hasVectorMaskArgument(RTLIB::LibcallImpl Impl)
Returns true if the function has a vector mask argument, which is assumed to be the last argument.
LLVM_ABI std::pair< FunctionType *, AttributeList > getFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const