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