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