LLVM 20.0.0git
LegalizeIntegerTypes.cpp
Go to the documentation of this file.
1//===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===//
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 integer type expansion and promotion for LegalizeTypes.
10// Promotion is the act of changing a computation in an illegal type into a
11// computation in a larger type. For example, implementing i8 arithmetic in an
12// i32 register (often needed on powerpc).
13// Expansion is the act of changing a computation in an illegal type into a
14// computation in two identical registers of a smaller type. For example,
15// implementing i64 arithmetic in two i32 registers (often needed on 32-bit
16// targets).
17//
18//===----------------------------------------------------------------------===//
19
20#include "LegalizeTypes.h"
28#include <algorithm>
29using namespace llvm;
30
31#define DEBUG_TYPE "legalize-types"
32
33//===----------------------------------------------------------------------===//
34// Integer Result Promotion
35//===----------------------------------------------------------------------===//
36
37/// PromoteIntegerResult - This method is called when a result of a node is
38/// found to be in need of promotion to a larger type. At this point, the node
39/// may also have invalid operands or may have other results that need
40/// expansion, we just know that (at least) one result needs promotion.
41void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
42 LLVM_DEBUG(dbgs() << "Promote integer result: "; N->dump(&DAG));
43 SDValue Res = SDValue();
44
45 // See if the target wants to custom expand this node.
46 if (CustomLowerNode(N, N->getValueType(ResNo), true)) {
47 LLVM_DEBUG(dbgs() << "Node has been custom expanded, done\n");
48 return;
49 }
50
51 switch (N->getOpcode()) {
52 default:
53#ifndef NDEBUG
54 dbgs() << "PromoteIntegerResult #" << ResNo << ": ";
55 N->dump(&DAG); dbgs() << "\n";
56#endif
57 report_fatal_error("Do not know how to promote this operator!");
58 case ISD::MERGE_VALUES:Res = PromoteIntRes_MERGE_VALUES(N, ResNo); break;
59 case ISD::AssertSext: Res = PromoteIntRes_AssertSext(N); break;
60 case ISD::AssertZext: Res = PromoteIntRes_AssertZext(N); break;
61 case ISD::BITCAST: Res = PromoteIntRes_BITCAST(N); break;
62 case ISD::VP_BITREVERSE:
63 case ISD::BITREVERSE: Res = PromoteIntRes_BITREVERSE(N); break;
64 case ISD::VP_BSWAP:
65 case ISD::BSWAP: Res = PromoteIntRes_BSWAP(N); break;
66 case ISD::BUILD_PAIR: Res = PromoteIntRes_BUILD_PAIR(N); break;
67 case ISD::Constant: Res = PromoteIntRes_Constant(N); break;
68 case ISD::VP_CTLZ_ZERO_UNDEF:
69 case ISD::VP_CTLZ:
71 case ISD::CTLZ: Res = PromoteIntRes_CTLZ(N); break;
72 case ISD::PARITY:
73 case ISD::VP_CTPOP:
74 case ISD::CTPOP: Res = PromoteIntRes_CTPOP_PARITY(N); break;
75 case ISD::VP_CTTZ_ZERO_UNDEF:
76 case ISD::VP_CTTZ:
78 case ISD::CTTZ: Res = PromoteIntRes_CTTZ(N); break;
79 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
80 case ISD::VP_CTTZ_ELTS:
81 Res = PromoteIntRes_VP_CttzElements(N);
82 break;
84 Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break;
85 case ISD::LOAD: Res = PromoteIntRes_LOAD(cast<LoadSDNode>(N)); break;
86 case ISD::MLOAD: Res = PromoteIntRes_MLOAD(cast<MaskedLoadSDNode>(N));
87 break;
88 case ISD::MGATHER: Res = PromoteIntRes_MGATHER(cast<MaskedGatherSDNode>(N));
89 break;
91 Res = PromoteIntRes_VECTOR_COMPRESS(N);
92 break;
93 case ISD::SELECT:
94 case ISD::VSELECT:
95 case ISD::VP_SELECT:
96 case ISD::VP_MERGE:
97 Res = PromoteIntRes_Select(N);
98 break;
99 case ISD::SELECT_CC: Res = PromoteIntRes_SELECT_CC(N); break;
102 case ISD::SETCC: Res = PromoteIntRes_SETCC(N); break;
103 case ISD::SMIN:
104 case ISD::SMAX: Res = PromoteIntRes_SExtIntBinOp(N); break;
105 case ISD::UMIN:
106 case ISD::UMAX: Res = PromoteIntRes_UMINUMAX(N); break;
107
108 case ISD::SHL:
109 case ISD::VP_SHL: Res = PromoteIntRes_SHL(N); break;
111 Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break;
112 case ISD::SRA:
113 case ISD::VP_SRA: Res = PromoteIntRes_SRA(N); break;
114 case ISD::SRL:
115 case ISD::VP_SRL: Res = PromoteIntRes_SRL(N); break;
116 case ISD::VP_TRUNCATE:
117 case ISD::TRUNCATE: Res = PromoteIntRes_TRUNCATE(N); break;
118 case ISD::UNDEF: Res = PromoteIntRes_UNDEF(N); break;
119 case ISD::VAARG: Res = PromoteIntRes_VAARG(N); break;
120 case ISD::VSCALE: Res = PromoteIntRes_VSCALE(N); break;
121
123 Res = PromoteIntRes_EXTRACT_SUBVECTOR(N); break;
125 Res = PromoteIntRes_INSERT_SUBVECTOR(N); break;
127 Res = PromoteIntRes_VECTOR_REVERSE(N); break;
129 Res = PromoteIntRes_VECTOR_SHUFFLE(N); break;
131 Res = PromoteIntRes_VECTOR_SPLICE(N); break;
134 Res = PromoteIntRes_VECTOR_INTERLEAVE_DEINTERLEAVE(N);
135 return;
137 Res = PromoteIntRes_INSERT_VECTOR_ELT(N); break;
139 Res = PromoteIntRes_BUILD_VECTOR(N);
140 break;
143 case ISD::EXPERIMENTAL_VP_SPLAT:
144 Res = PromoteIntRes_ScalarOp(N);
145 break;
146 case ISD::STEP_VECTOR: Res = PromoteIntRes_STEP_VECTOR(N); break;
148 Res = PromoteIntRes_CONCAT_VECTORS(N); break;
149
153 Res = PromoteIntRes_EXTEND_VECTOR_INREG(N); break;
154
155 case ISD::SIGN_EXTEND:
156 case ISD::VP_SIGN_EXTEND:
157 case ISD::ZERO_EXTEND:
158 case ISD::VP_ZERO_EXTEND:
159 case ISD::ANY_EXTEND: Res = PromoteIntRes_INT_EXTEND(N); break;
160
161 case ISD::VP_FP_TO_SINT:
162 case ISD::VP_FP_TO_UINT:
165 case ISD::FP_TO_SINT:
166 case ISD::FP_TO_UINT: Res = PromoteIntRes_FP_TO_XINT(N); break;
167
170 Res = PromoteIntRes_FP_TO_XINT_SAT(N); break;
171
172 case ISD::FP_TO_BF16:
173 case ISD::FP_TO_FP16:
174 Res = PromoteIntRes_FP_TO_FP16_BF16(N);
175 break;
178 Res = PromoteIntRes_STRICT_FP_TO_FP16_BF16(N);
179 break;
180 case ISD::GET_ROUNDING: Res = PromoteIntRes_GET_ROUNDING(N); break;
181
182 case ISD::AND:
183 case ISD::OR:
184 case ISD::XOR:
185 case ISD::ADD:
186 case ISD::SUB:
187 case ISD::MUL:
188 case ISD::VP_AND:
189 case ISD::VP_OR:
190 case ISD::VP_XOR:
191 case ISD::VP_ADD:
192 case ISD::VP_SUB:
193 case ISD::VP_MUL: Res = PromoteIntRes_SimpleIntBinOp(N); break;
194
195 case ISD::AVGCEILS:
196 case ISD::AVGFLOORS:
197 case ISD::VP_SMIN:
198 case ISD::VP_SMAX:
199 case ISD::SDIV:
200 case ISD::SREM:
201 case ISD::VP_SDIV:
202 case ISD::VP_SREM: Res = PromoteIntRes_SExtIntBinOp(N); break;
203
204 case ISD::AVGCEILU:
205 case ISD::AVGFLOORU:
206 case ISD::VP_UMIN:
207 case ISD::VP_UMAX:
208 case ISD::UDIV:
209 case ISD::UREM:
210 case ISD::VP_UDIV:
211 case ISD::VP_UREM: Res = PromoteIntRes_ZExtIntBinOp(N); break;
212
213 case ISD::SADDO:
214 case ISD::SSUBO: Res = PromoteIntRes_SADDSUBO(N, ResNo); break;
215 case ISD::UADDO:
216 case ISD::USUBO: Res = PromoteIntRes_UADDSUBO(N, ResNo); break;
217 case ISD::SMULO:
218 case ISD::UMULO: Res = PromoteIntRes_XMULO(N, ResNo); break;
219
220 case ISD::ADDE:
221 case ISD::SUBE:
222 case ISD::UADDO_CARRY:
223 case ISD::USUBO_CARRY: Res = PromoteIntRes_UADDSUBO_CARRY(N, ResNo); break;
224
225 case ISD::SADDO_CARRY:
226 case ISD::SSUBO_CARRY: Res = PromoteIntRes_SADDSUBO_CARRY(N, ResNo); break;
227
228 case ISD::SADDSAT:
229 case ISD::UADDSAT:
230 case ISD::SSUBSAT:
231 case ISD::USUBSAT:
232 case ISD::SSHLSAT:
233 case ISD::USHLSAT:
234 Res = PromoteIntRes_ADDSUBSHLSAT<EmptyMatchContext>(N);
235 break;
236 case ISD::VP_SADDSAT:
237 case ISD::VP_UADDSAT:
238 case ISD::VP_SSUBSAT:
239 case ISD::VP_USUBSAT:
240 Res = PromoteIntRes_ADDSUBSHLSAT<VPMatchContext>(N);
241 break;
242
243 case ISD::SCMP:
244 case ISD::UCMP:
245 Res = PromoteIntRes_CMP(N);
246 break;
247
248 case ISD::SMULFIX:
249 case ISD::SMULFIXSAT:
250 case ISD::UMULFIX:
251 case ISD::UMULFIXSAT: Res = PromoteIntRes_MULFIX(N); break;
252
253 case ISD::SDIVFIX:
254 case ISD::SDIVFIXSAT:
255 case ISD::UDIVFIX:
256 case ISD::UDIVFIXSAT: Res = PromoteIntRes_DIVFIX(N); break;
257
258 case ISD::ABS: Res = PromoteIntRes_ABS(N); break;
259
260 case ISD::ATOMIC_LOAD:
261 Res = PromoteIntRes_Atomic0(cast<AtomicSDNode>(N)); break;
262
274 case ISD::ATOMIC_SWAP:
275 Res = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break;
276
279 Res = PromoteIntRes_AtomicCmpSwap(cast<AtomicSDNode>(N), ResNo);
280 break;
281
291 Res = PromoteIntRes_VECREDUCE(N);
292 break;
293
294 case ISD::VP_REDUCE_ADD:
295 case ISD::VP_REDUCE_MUL:
296 case ISD::VP_REDUCE_AND:
297 case ISD::VP_REDUCE_OR:
298 case ISD::VP_REDUCE_XOR:
299 case ISD::VP_REDUCE_SMAX:
300 case ISD::VP_REDUCE_SMIN:
301 case ISD::VP_REDUCE_UMAX:
302 case ISD::VP_REDUCE_UMIN:
303 Res = PromoteIntRes_VP_REDUCE(N);
304 break;
305
306 case ISD::FREEZE:
307 Res = PromoteIntRes_FREEZE(N);
308 break;
309
310 case ISD::ROTL:
311 case ISD::ROTR:
312 Res = PromoteIntRes_Rotate(N);
313 break;
314
315 case ISD::FSHL:
316 case ISD::FSHR:
317 Res = PromoteIntRes_FunnelShift(N);
318 break;
319
320 case ISD::VP_FSHL:
321 case ISD::VP_FSHR:
322 Res = PromoteIntRes_VPFunnelShift(N);
323 break;
324
325 case ISD::IS_FPCLASS:
326 Res = PromoteIntRes_IS_FPCLASS(N);
327 break;
328 case ISD::FFREXP:
329 Res = PromoteIntRes_FFREXP(N);
330 break;
331
332 case ISD::LRINT:
333 case ISD::LLRINT:
334 Res = PromoteIntRes_XRINT(N);
335 break;
336
337 case ISD::PATCHPOINT:
338 Res = PromoteIntRes_PATCHPOINT(N);
339 break;
340 }
341
342 // If the result is null then the sub-method took care of registering it.
343 if (Res.getNode())
344 SetPromotedInteger(SDValue(N, ResNo), Res);
345}
346
347SDValue DAGTypeLegalizer::PromoteIntRes_MERGE_VALUES(SDNode *N,
348 unsigned ResNo) {
349 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
350 return GetPromotedInteger(Op);
351}
352
353SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
354 // Sign-extend the new bits, and continue the assertion.
355 SDValue Op = SExtPromotedInteger(N->getOperand(0));
356 return DAG.getNode(ISD::AssertSext, SDLoc(N),
357 Op.getValueType(), Op, N->getOperand(1));
358}
359
360SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
361 // Zero the new bits, and continue the assertion.
362 SDValue Op = ZExtPromotedInteger(N->getOperand(0));
363 return DAG.getNode(ISD::AssertZext, SDLoc(N),
364 Op.getValueType(), Op, N->getOperand(1));
365}
366
367SDValue DAGTypeLegalizer::PromoteIntRes_Atomic0(AtomicSDNode *N) {
368 EVT ResVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
369 SDValue Res = DAG.getAtomic(N->getOpcode(), SDLoc(N),
370 N->getMemoryVT(), ResVT,
371 N->getChain(), N->getBasePtr(),
372 N->getMemOperand());
373 if (N->getOpcode() == ISD::ATOMIC_LOAD) {
374 ISD::LoadExtType ETy = cast<AtomicSDNode>(N)->getExtensionType();
375 if (ETy == ISD::NON_EXTLOAD) {
376 switch (TLI.getExtendForAtomicOps()) {
377 case ISD::SIGN_EXTEND:
378 ETy = ISD::SEXTLOAD;
379 break;
380 case ISD::ZERO_EXTEND:
381 ETy = ISD::ZEXTLOAD;
382 break;
383 case ISD::ANY_EXTEND:
384 ETy = ISD::EXTLOAD;
385 break;
386 default:
387 llvm_unreachable("Invalid atomic op extension");
388 }
389 }
390 cast<AtomicSDNode>(Res)->setExtensionType(ETy);
391 }
392
393 // Legalize the chain result - switch anything that used the old chain to
394 // use the new one.
395 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
396 return Res;
397}
398
399SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
400 SDValue Op2 = GetPromotedInteger(N->getOperand(2));
401 SDValue Res = DAG.getAtomic(N->getOpcode(), SDLoc(N),
402 N->getMemoryVT(),
403 N->getChain(), N->getBasePtr(),
404 Op2, N->getMemOperand());
405 // Legalize the chain result - switch anything that used the old chain to
406 // use the new one.
407 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
408 return Res;
409}
410
411SDValue DAGTypeLegalizer::PromoteIntRes_AtomicCmpSwap(AtomicSDNode *N,
412 unsigned ResNo) {
413 if (ResNo == 1) {
415 EVT SVT = getSetCCResultType(N->getOperand(2).getValueType());
416 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1));
417
418 // Only use the result of getSetCCResultType if it is legal,
419 // otherwise just use the promoted result type (NVT).
420 if (!TLI.isTypeLegal(SVT))
421 SVT = NVT;
422
423 SDVTList VTs = DAG.getVTList(N->getValueType(0), SVT, MVT::Other);
424 SDValue Res = DAG.getAtomicCmpSwap(
425 ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, SDLoc(N), N->getMemoryVT(), VTs,
426 N->getChain(), N->getBasePtr(), N->getOperand(2), N->getOperand(3),
427 N->getMemOperand());
428 ReplaceValueWith(SDValue(N, 0), Res.getValue(0));
429 ReplaceValueWith(SDValue(N, 2), Res.getValue(2));
430 return DAG.getSExtOrTrunc(Res.getValue(1), SDLoc(N), NVT);
431 }
432
433 // Op2 is used for the comparison and thus must be extended according to the
434 // target's atomic operations. Op3 is merely stored and so can be left alone.
435 SDValue Op2 = N->getOperand(2);
436 SDValue Op3 = GetPromotedInteger(N->getOperand(3));
437 switch (TLI.getExtendForAtomicCmpSwapArg()) {
438 case ISD::SIGN_EXTEND:
439 Op2 = SExtPromotedInteger(Op2);
440 break;
441 case ISD::ZERO_EXTEND:
442 Op2 = ZExtPromotedInteger(Op2);
443 break;
444 case ISD::ANY_EXTEND:
445 Op2 = GetPromotedInteger(Op2);
446 break;
447 default:
448 llvm_unreachable("Invalid atomic op extension");
449 }
450
451 SDVTList VTs =
452 DAG.getVTList(Op2.getValueType(), N->getValueType(1), MVT::Other);
453 SDValue Res = DAG.getAtomicCmpSwap(
454 N->getOpcode(), SDLoc(N), N->getMemoryVT(), VTs, N->getChain(),
455 N->getBasePtr(), Op2, Op3, N->getMemOperand());
456 // Update the use to N with the newly created Res.
457 for (unsigned i = 1, NumResults = N->getNumValues(); i < NumResults; ++i)
458 ReplaceValueWith(SDValue(N, i), Res.getValue(i));
459 return Res;
460}
461
462SDValue DAGTypeLegalizer::PromoteIntRes_BITCAST(SDNode *N) {
463 SDValue InOp = N->getOperand(0);
464 EVT InVT = InOp.getValueType();
465 EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
466 EVT OutVT = N->getValueType(0);
467 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
468 SDLoc dl(N);
469
470 switch (getTypeAction(InVT)) {
472 break;
474 if (NOutVT.bitsEq(NInVT) && !NOutVT.isVector() && !NInVT.isVector())
475 // The input promotes to the same size. Convert the promoted value.
476 return DAG.getNode(ISD::BITCAST, dl, NOutVT, GetPromotedInteger(InOp));
477 break;
479 // Promote the integer operand by hand.
480 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp));
482 // Promote the integer operand by hand.
483 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftPromotedHalf(InOp));
485 // Convert the promoted float by hand.
486 if (!NOutVT.isVector())
487 return DAG.getNode(ISD::FP_TO_FP16, dl, NOutVT, GetPromotedFloat(InOp));
488 break;
489 }
492 break;
494 // Convert the element to an integer and promote it by hand.
495 if (!NOutVT.isVector())
496 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
497 BitConvertToInteger(GetScalarizedVector(InOp)));
498 break;
500 report_fatal_error("Scalarization of scalable vectors is not supported.");
502 if (!NOutVT.isVector()) {
503 // For example, i32 = BITCAST v2i16 on alpha. Convert the split
504 // pieces of the input into integers and reassemble in the final type.
505 SDValue Lo, Hi;
506 GetSplitVector(N->getOperand(0), Lo, Hi);
507 Lo = BitConvertToInteger(Lo);
508 Hi = BitConvertToInteger(Hi);
509
510 if (DAG.getDataLayout().isBigEndian())
511 std::swap(Lo, Hi);
512
513 InOp = DAG.getNode(ISD::ANY_EXTEND, dl,
515 NOutVT.getSizeInBits()),
516 JoinIntegers(Lo, Hi));
517 return DAG.getNode(ISD::BITCAST, dl, NOutVT, InOp);
518 }
519 break;
520 }
522 // The input is widened to the same size. Convert to the widened value.
523 // Make sure that the outgoing value is not a vector, because this would
524 // make us bitcast between two vectors which are legalized in different ways.
525 if (NOutVT.bitsEq(NInVT) && !NOutVT.isVector()) {
526 SDValue Res =
527 DAG.getNode(ISD::BITCAST, dl, NOutVT, GetWidenedVector(InOp));
528
529 // For big endian targets we need to shift the casted value or the
530 // interesting bits will end up at the wrong place.
531 if (DAG.getDataLayout().isBigEndian()) {
532 unsigned ShiftAmt = NInVT.getSizeInBits() - InVT.getSizeInBits();
533 assert(ShiftAmt < NOutVT.getSizeInBits() && "Too large shift amount!");
534 Res = DAG.getNode(ISD::SRL, dl, NOutVT, Res,
535 DAG.getShiftAmountConstant(ShiftAmt, NOutVT, dl));
536 }
537 return Res;
538 }
539 // If the output type is also a vector and widening it to the same size
540 // as the widened input type would be a legal type, we can widen the bitcast
541 // and handle the promotion after.
542 if (NOutVT.isVector()) {
543 TypeSize WidenInSize = NInVT.getSizeInBits();
544 TypeSize OutSize = OutVT.getSizeInBits();
545 if (WidenInSize.hasKnownScalarFactor(OutSize)) {
546 unsigned Scale = WidenInSize.getKnownScalarFactor(OutSize);
547 EVT WideOutVT =
549 OutVT.getVectorElementCount() * Scale);
550 if (isTypeLegal(WideOutVT)) {
551 InOp = DAG.getBitcast(WideOutVT, GetWidenedVector(InOp));
552 InOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OutVT, InOp,
553 DAG.getVectorIdxConstant(0, dl));
554 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, InOp);
555 }
556 }
557 }
558 }
559
560 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
561 CreateStackStoreLoad(InOp, OutVT));
562}
563
564SDValue DAGTypeLegalizer::PromoteIntRes_FREEZE(SDNode *N) {
565 SDValue V = GetPromotedInteger(N->getOperand(0));
566 return DAG.getNode(ISD::FREEZE, SDLoc(N),
567 V.getValueType(), V);
568}
569
570SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
571 SDValue Op = GetPromotedInteger(N->getOperand(0));
572 EVT OVT = N->getValueType(0);
573 EVT NVT = Op.getValueType();
574 SDLoc dl(N);
575
576 // If the larger BSWAP isn't supported by the target, try to expand now.
577 // If we expand later we'll end up with more operations since we lost the
578 // original type. We only do this for scalars since we have a shuffle
579 // based lowering for vectors in LegalizeVectorOps.
580 if (!OVT.isVector() &&
582 if (SDValue Res = TLI.expandBSWAP(N, DAG))
583 return DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Res);
584 }
585
586 unsigned DiffBits = NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits();
587 SDValue ShAmt = DAG.getShiftAmountConstant(DiffBits, NVT, dl);
588 if (N->getOpcode() == ISD::BSWAP)
589 return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op),
590 ShAmt);
591 SDValue Mask = N->getOperand(1);
592 SDValue EVL = N->getOperand(2);
593 return DAG.getNode(ISD::VP_SRL, dl, NVT,
594 DAG.getNode(ISD::VP_BSWAP, dl, NVT, Op, Mask, EVL), ShAmt,
595 Mask, EVL);
596}
597
598SDValue DAGTypeLegalizer::PromoteIntRes_BITREVERSE(SDNode *N) {
599 SDValue Op = GetPromotedInteger(N->getOperand(0));
600 EVT OVT = N->getValueType(0);
601 EVT NVT = Op.getValueType();
602 SDLoc dl(N);
603
604 // If the larger BITREVERSE isn't supported by the target, try to expand now.
605 // If we expand later we'll end up with more operations since we lost the
606 // original type. We only do this for scalars since we have a shuffle
607 // based lowering for vectors in LegalizeVectorOps.
608 if (!OVT.isVector() && OVT.isSimple() &&
610 if (SDValue Res = TLI.expandBITREVERSE(N, DAG))
611 return DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Res);
612 }
613
614 unsigned DiffBits = NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits();
615 SDValue ShAmt = DAG.getShiftAmountConstant(DiffBits, NVT, dl);
616 if (N->getOpcode() == ISD::BITREVERSE)
617 return DAG.getNode(ISD::SRL, dl, NVT,
618 DAG.getNode(ISD::BITREVERSE, dl, NVT, Op), ShAmt);
619 SDValue Mask = N->getOperand(1);
620 SDValue EVL = N->getOperand(2);
621 return DAG.getNode(ISD::VP_SRL, dl, NVT,
622 DAG.getNode(ISD::VP_BITREVERSE, dl, NVT, Op, Mask, EVL),
623 ShAmt, Mask, EVL);
624}
625
626SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
627 // The pair element type may be legal, or may not promote to the same type as
628 // the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases.
629 return DAG.getNode(ISD::ANY_EXTEND, SDLoc(N),
631 N->getValueType(0)), JoinIntegers(N->getOperand(0),
632 N->getOperand(1)));
633}
634
635SDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
636 EVT VT = N->getValueType(0);
637 // FIXME there is no actual debug info here
638 SDLoc dl(N);
639 // Zero extend things like i1, sign extend everything else. It shouldn't
640 // matter in theory which one we pick, but this tends to give better code?
641 unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
642 SDValue Result = DAG.getNode(Opc, dl,
643 TLI.getTypeToTransformTo(*DAG.getContext(), VT),
644 SDValue(N, 0));
645 assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
646 return Result;
647}
648
649SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
650 EVT OVT = N->getValueType(0);
651 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
652 SDLoc dl(N);
653
654 // If the larger CTLZ isn't supported by the target, try to expand now.
655 // If we expand later we'll end up with more operations since we lost the
656 // original type.
657 if (!OVT.isVector() && TLI.isTypeLegal(NVT) &&
660 if (SDValue Result = TLI.expandCTLZ(N, DAG)) {
661 Result = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Result);
662 return Result;
663 }
664 }
665
666 unsigned CtlzOpcode = N->getOpcode();
667 if (CtlzOpcode == ISD::CTLZ || CtlzOpcode == ISD::VP_CTLZ) {
668 // Subtract off the extra leading bits in the bigger type.
669 SDValue ExtractLeadingBits = DAG.getConstant(
670 NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits(), dl, NVT);
671
672 if (!N->isVPOpcode()) {
673 // Zero extend to the promoted type and do the count there.
674 SDValue Op = ZExtPromotedInteger(N->getOperand(0));
675 return DAG.getNode(ISD::SUB, dl, NVT,
676 DAG.getNode(N->getOpcode(), dl, NVT, Op),
677 ExtractLeadingBits);
678 }
679 SDValue Mask = N->getOperand(1);
680 SDValue EVL = N->getOperand(2);
681 // Zero extend to the promoted type and do the count there.
682 SDValue Op = VPZExtPromotedInteger(N->getOperand(0), Mask, EVL);
683 return DAG.getNode(ISD::VP_SUB, dl, NVT,
684 DAG.getNode(N->getOpcode(), dl, NVT, Op, Mask, EVL),
685 ExtractLeadingBits, Mask, EVL);
686 }
687 if (CtlzOpcode == ISD::CTLZ_ZERO_UNDEF ||
688 CtlzOpcode == ISD::VP_CTLZ_ZERO_UNDEF) {
689 // Any Extend the argument
690 SDValue Op = GetPromotedInteger(N->getOperand(0));
691 // Op = Op << (sizeinbits(NVT) - sizeinbits(Old VT))
692 unsigned SHLAmount = NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits();
693 auto ShiftConst =
694 DAG.getShiftAmountConstant(SHLAmount, Op.getValueType(), dl);
695 if (!N->isVPOpcode()) {
696 Op = DAG.getNode(ISD::SHL, dl, NVT, Op, ShiftConst);
697 return DAG.getNode(CtlzOpcode, dl, NVT, Op);
698 }
699
700 SDValue Mask = N->getOperand(1);
701 SDValue EVL = N->getOperand(2);
702 Op = DAG.getNode(ISD::VP_SHL, dl, NVT, Op, ShiftConst, Mask, EVL);
703 return DAG.getNode(CtlzOpcode, dl, NVT, Op, Mask, EVL);
704 }
705 llvm_unreachable("Invalid CTLZ Opcode");
706}
707
708SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP_PARITY(SDNode *N) {
709 EVT OVT = N->getValueType(0);
710 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
711
712 // If the larger CTPOP isn't supported by the target, try to expand now.
713 // If we expand later we'll end up with more operations since we lost the
714 // original type.
715 // TODO: Expand ISD::PARITY. Need to move ExpandPARITY from LegalizeDAG to
716 // TargetLowering.
717 if (N->getOpcode() == ISD::CTPOP && !OVT.isVector() && TLI.isTypeLegal(NVT) &&
719 if (SDValue Result = TLI.expandCTPOP(N, DAG)) {
720 Result = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), NVT, Result);
721 return Result;
722 }
723 }
724
725 // Zero extend to the promoted type and do the count or parity there.
726 if (!N->isVPOpcode()) {
727 SDValue Op = ZExtPromotedInteger(N->getOperand(0));
728 return DAG.getNode(N->getOpcode(), SDLoc(N), Op.getValueType(), Op);
729 }
730
731 SDValue Mask = N->getOperand(1);
732 SDValue EVL = N->getOperand(2);
733 SDValue Op = VPZExtPromotedInteger(N->getOperand(0), Mask, EVL);
734 return DAG.getNode(N->getOpcode(), SDLoc(N), Op.getValueType(), Op, Mask,
735 EVL);
736}
737
738SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
739 SDValue Op = GetPromotedInteger(N->getOperand(0));
740 EVT OVT = N->getValueType(0);
741 EVT NVT = Op.getValueType();
742 SDLoc dl(N);
743
744 // If the larger CTTZ isn't supported by the target, try to expand now.
745 // If we expand later we'll end up with more operations since we lost the
746 // original type. Don't expand if we can use CTPOP or CTLZ expansion on the
747 // larger type.
748 if (!OVT.isVector() && TLI.isTypeLegal(NVT) &&
751 !TLI.isOperationLegal(ISD::CTPOP, NVT) &&
752 !TLI.isOperationLegal(ISD::CTLZ, NVT)) {
753 if (SDValue Result = TLI.expandCTTZ(N, DAG)) {
754 Result = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Result);
755 return Result;
756 }
757 }
758
759 unsigned NewOpc = N->getOpcode();
760 if (NewOpc == ISD::CTTZ || NewOpc == ISD::VP_CTTZ) {
761 // The count is the same in the promoted type except if the original
762 // value was zero. This can be handled by setting the bit just off
763 // the top of the original type.
764 auto TopBit = APInt::getOneBitSet(NVT.getScalarSizeInBits(),
765 OVT.getScalarSizeInBits());
766 if (NewOpc == ISD::CTTZ) {
767 Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, dl, NVT));
768 NewOpc = ISD::CTTZ_ZERO_UNDEF;
769 } else {
770 Op =
771 DAG.getNode(ISD::VP_OR, dl, NVT, Op, DAG.getConstant(TopBit, dl, NVT),
772 N->getOperand(1), N->getOperand(2));
773 NewOpc = ISD::VP_CTTZ_ZERO_UNDEF;
774 }
775 }
776 if (!N->isVPOpcode())
777 return DAG.getNode(NewOpc, dl, NVT, Op);
778 return DAG.getNode(NewOpc, dl, NVT, Op, N->getOperand(1), N->getOperand(2));
779}
780
781SDValue DAGTypeLegalizer::PromoteIntRes_VP_CttzElements(SDNode *N) {
782 SDLoc DL(N);
783 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
784 return DAG.getNode(N->getOpcode(), DL, NewVT, N->ops());
785}
786
787SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
788 SDLoc dl(N);
789 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
790
791 SDValue Op0 = N->getOperand(0);
792 SDValue Op1 = N->getOperand(1);
793
794 // If the input also needs to be promoted, do that first so we can get a
795 // get a good idea for the output type.
796 if (TLI.getTypeAction(*DAG.getContext(), Op0.getValueType())
798 SDValue In = GetPromotedInteger(Op0);
799
800 // If the new type is larger than NVT, use it. We probably won't need to
801 // promote it again.
802 EVT SVT = In.getValueType().getScalarType();
803 if (SVT.bitsGE(NVT)) {
804 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SVT, In, Op1);
805 return DAG.getAnyExtOrTrunc(Ext, dl, NVT);
806 }
807 }
808
809 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, Op0, Op1);
810}
811
812SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
813 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
814 unsigned NewOpc = N->getOpcode();
815 SDLoc dl(N);
816
817 // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is
818 // not Legal, check to see if we can use FP_TO_SINT instead. (If both UINT
819 // and SINT conversions are Custom, there is no way to tell which is
820 // preferable. We choose SINT because that's the right thing on PPC.)
821 if (N->getOpcode() == ISD::FP_TO_UINT &&
824 NewOpc = ISD::FP_TO_SINT;
825
826 if (N->getOpcode() == ISD::STRICT_FP_TO_UINT &&
829 NewOpc = ISD::STRICT_FP_TO_SINT;
830
831 if (N->getOpcode() == ISD::VP_FP_TO_UINT &&
832 !TLI.isOperationLegal(ISD::VP_FP_TO_UINT, NVT) &&
833 TLI.isOperationLegalOrCustom(ISD::VP_FP_TO_SINT, NVT))
834 NewOpc = ISD::VP_FP_TO_SINT;
835
836 SDValue Res;
837 if (N->isStrictFPOpcode()) {
838 Res = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
839 {N->getOperand(0), N->getOperand(1)});
840 // Legalize the chain result - switch anything that used the old chain to
841 // use the new one.
842 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
843 } else if (NewOpc == ISD::VP_FP_TO_SINT || NewOpc == ISD::VP_FP_TO_UINT) {
844 Res = DAG.getNode(NewOpc, dl, NVT, {N->getOperand(0), N->getOperand(1),
845 N->getOperand(2)});
846 } else {
847 Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0));
848 }
849
850 // Assert that the converted value fits in the original type. If it doesn't
851 // (eg: because the value being converted is too big), then the result of the
852 // original operation was undefined anyway, so the assert is still correct.
853 //
854 // NOTE: fp-to-uint to fp-to-sint promotion guarantees zero extend. For example:
855 // before legalization: fp-to-uint16, 65534. -> 0xfffe
856 // after legalization: fp-to-sint32, 65534. -> 0x0000fffe
857 return DAG.getNode((N->getOpcode() == ISD::FP_TO_UINT ||
858 N->getOpcode() == ISD::STRICT_FP_TO_UINT ||
859 N->getOpcode() == ISD::VP_FP_TO_UINT)
862 dl, NVT, Res,
863 DAG.getValueType(N->getValueType(0).getScalarType()));
864}
865
866SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT_SAT(SDNode *N) {
867 // Promote the result type, while keeping the original width in Op1.
868 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
869 SDLoc dl(N);
870 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0),
871 N->getOperand(1));
872}
873
874SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_FP16_BF16(SDNode *N) {
875 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
876 SDLoc dl(N);
877
878 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
879}
880
881SDValue DAGTypeLegalizer::PromoteIntRes_STRICT_FP_TO_FP16_BF16(SDNode *N) {
882 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
883 SDLoc dl(N);
884
885 SDValue Res = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
886 N->getOperand(0), N->getOperand(1));
887 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
888 return Res;
889}
890
891SDValue DAGTypeLegalizer::PromoteIntRes_XRINT(SDNode *N) {
892 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
893 SDLoc dl(N);
894 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
895}
896
897SDValue DAGTypeLegalizer::PromoteIntRes_GET_ROUNDING(SDNode *N) {
898 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
899 SDLoc dl(N);
900
901 SDValue Res =
902 DAG.getNode(N->getOpcode(), dl, {NVT, MVT::Other}, N->getOperand(0));
903
904 // Legalize the chain result - switch anything that used the old chain to
905 // use the new one.
906 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
907 return Res;
908}
909
910SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
911 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
912 SDLoc dl(N);
913
914 if (getTypeAction(N->getOperand(0).getValueType())
916 SDValue Res = GetPromotedInteger(N->getOperand(0));
917 assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!");
918
919 // If the result and operand types are the same after promotion, simplify
920 // to an in-register extension. Unless this is a VP_*_EXTEND.
921 if (NVT == Res.getValueType() && N->getNumOperands() == 1) {
922 // The high bits are not guaranteed to be anything. Insert an extend.
923 if (N->getOpcode() == ISD::SIGN_EXTEND)
924 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
925 DAG.getValueType(N->getOperand(0).getValueType()));
926 if (N->getOpcode() == ISD::ZERO_EXTEND)
927 return DAG.getZeroExtendInReg(Res, dl, N->getOperand(0).getValueType());
928 assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
929 return Res;
930 }
931 }
932
933 // Otherwise, just extend the original operand all the way to the larger type.
934 if (N->getNumOperands() != 1) {
935 assert(N->getNumOperands() == 3 && "Unexpected number of operands!");
936 assert(N->isVPOpcode() && "Expected VP opcode");
937 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0),
938 N->getOperand(1), N->getOperand(2));
939 }
940 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
941}
942
943SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
944 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
945 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
946 ISD::LoadExtType ExtType =
947 ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
948 SDLoc dl(N);
949 SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
950 N->getMemoryVT(), N->getMemOperand());
951
952 // Legalize the chain result - switch anything that used the old chain to
953 // use the new one.
954 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
955 return Res;
956}
957
958SDValue DAGTypeLegalizer::PromoteIntRes_MLOAD(MaskedLoadSDNode *N) {
959 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
960 SDValue ExtPassThru = GetPromotedInteger(N->getPassThru());
961
962 ISD::LoadExtType ExtType = N->getExtensionType();
963 if (ExtType == ISD::NON_EXTLOAD)
964 ExtType = ISD::EXTLOAD;
965
966 SDLoc dl(N);
967 SDValue Res = DAG.getMaskedLoad(NVT, dl, N->getChain(), N->getBasePtr(),
968 N->getOffset(), N->getMask(), ExtPassThru,
969 N->getMemoryVT(), N->getMemOperand(),
970 N->getAddressingMode(), ExtType,
971 N->isExpandingLoad());
972 // Legalize the chain result - switch anything that used the old chain to
973 // use the new one.
974 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
975 return Res;
976}
977
978SDValue DAGTypeLegalizer::PromoteIntRes_MGATHER(MaskedGatherSDNode *N) {
979 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
980 SDValue ExtPassThru = GetPromotedInteger(N->getPassThru());
981 assert(NVT == ExtPassThru.getValueType() &&
982 "Gather result type and the passThru argument type should be the same");
983
984 ISD::LoadExtType ExtType = N->getExtensionType();
985 if (ExtType == ISD::NON_EXTLOAD)
986 ExtType = ISD::EXTLOAD;
987
988 SDLoc dl(N);
989 SDValue Ops[] = {N->getChain(), ExtPassThru, N->getMask(), N->getBasePtr(),
990 N->getIndex(), N->getScale() };
991 SDValue Res = DAG.getMaskedGather(DAG.getVTList(NVT, MVT::Other),
992 N->getMemoryVT(), dl, Ops,
993 N->getMemOperand(), N->getIndexType(),
994 ExtType);
995 // Legalize the chain result - switch anything that used the old chain to
996 // use the new one.
997 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
998 return Res;
999}
1000
1001SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_COMPRESS(SDNode *N) {
1002 SDValue Vec = GetPromotedInteger(N->getOperand(0));
1003 SDValue Passthru = GetPromotedInteger(N->getOperand(2));
1004 return DAG.getNode(ISD::VECTOR_COMPRESS, SDLoc(N), Vec.getValueType(), Vec,
1005 N->getOperand(1), Passthru);
1006}
1007
1008/// Promote the overflow flag of an overflowing arithmetic node.
1009SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
1010 // Change the return type of the boolean result while obeying
1011 // getSetCCResultType.
1012 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1));
1013 EVT VT = N->getValueType(0);
1014 EVT SVT = getSetCCResultType(VT);
1015 SDValue Ops[3] = { N->getOperand(0), N->getOperand(1) };
1016 unsigned NumOps = N->getNumOperands();
1017 assert(NumOps <= 3 && "Too many operands");
1018 if (NumOps == 3)
1019 Ops[2] = PromoteTargetBoolean(N->getOperand(2), VT);
1020
1021 SDLoc dl(N);
1022 SDValue Res = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(VT, SVT),
1023 ArrayRef(Ops, NumOps));
1024
1025 // Modified the sum result - switch anything that used the old sum to use
1026 // the new one.
1027 ReplaceValueWith(SDValue(N, 0), Res);
1028
1029 // Convert to the expected type.
1030 return DAG.getBoolExtOrTrunc(Res.getValue(1), dl, NVT, VT);
1031}
1032
1033template <class MatchContextClass>
1034SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
1035 // If the promoted type is legal, we can convert this to:
1036 // 1. ANY_EXTEND iN to iM
1037 // 2. SHL by M-N
1038 // 3. [US][ADD|SUB|SHL]SAT
1039 // 4. L/ASHR by M-N
1040 // Else it is more efficient to convert this to a min and a max
1041 // operation in the higher precision arithmetic.
1042 SDLoc dl(N);
1043 SDValue Op1 = N->getOperand(0);
1044 SDValue Op2 = N->getOperand(1);
1045 MatchContextClass matcher(DAG, TLI, N);
1046 unsigned OldBits = Op1.getScalarValueSizeInBits();
1047
1048 unsigned Opcode = matcher.getRootBaseOpcode();
1049 bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
1050
1051 // FIXME: We need vp-aware PromotedInteger functions.
1052 SDValue Op1Promoted, Op2Promoted;
1053 if (IsShift) {
1054 Op1Promoted = GetPromotedInteger(Op1);
1055 Op2Promoted = ZExtPromotedInteger(Op2);
1056 } else if (Opcode == ISD::UADDSAT || Opcode == ISD::USUBSAT) {
1057 Op1Promoted = ZExtPromotedInteger(Op1);
1058 Op2Promoted = ZExtPromotedInteger(Op2);
1059 } else {
1060 Op1Promoted = SExtPromotedInteger(Op1);
1061 Op2Promoted = SExtPromotedInteger(Op2);
1062 }
1063 EVT PromotedType = Op1Promoted.getValueType();
1064 unsigned NewBits = PromotedType.getScalarSizeInBits();
1065
1066 if (Opcode == ISD::UADDSAT) {
1067 APInt MaxVal = APInt::getAllOnes(OldBits).zext(NewBits);
1068 SDValue SatMax = DAG.getConstant(MaxVal, dl, PromotedType);
1069 SDValue Add =
1070 matcher.getNode(ISD::ADD, dl, PromotedType, Op1Promoted, Op2Promoted);
1071 return matcher.getNode(ISD::UMIN, dl, PromotedType, Add, SatMax);
1072 }
1073
1074 // USUBSAT can always be promoted as long as we have zero-extended the args.
1075 if (Opcode == ISD::USUBSAT)
1076 return matcher.getNode(ISD::USUBSAT, dl, PromotedType, Op1Promoted,
1077 Op2Promoted);
1078
1079 // Shift cannot use a min/max expansion, we can't detect overflow if all of
1080 // the bits have been shifted out.
1081 if (IsShift || matcher.isOperationLegal(Opcode, PromotedType)) {
1082 unsigned ShiftOp;
1083 switch (Opcode) {
1084 case ISD::SADDSAT:
1085 case ISD::SSUBSAT:
1086 case ISD::SSHLSAT:
1087 ShiftOp = ISD::SRA;
1088 break;
1089 case ISD::USHLSAT:
1090 ShiftOp = ISD::SRL;
1091 break;
1092 default:
1093 llvm_unreachable("Expected opcode to be signed or unsigned saturation "
1094 "addition, subtraction or left shift");
1095 }
1096
1097 unsigned SHLAmount = NewBits - OldBits;
1098 SDValue ShiftAmount =
1099 DAG.getShiftAmountConstant(SHLAmount, PromotedType, dl);
1100 Op1Promoted =
1101 DAG.getNode(ISD::SHL, dl, PromotedType, Op1Promoted, ShiftAmount);
1102 if (!IsShift)
1103 Op2Promoted =
1104 matcher.getNode(ISD::SHL, dl, PromotedType, Op2Promoted, ShiftAmount);
1105
1106 SDValue Result =
1107 matcher.getNode(Opcode, dl, PromotedType, Op1Promoted, Op2Promoted);
1108 return matcher.getNode(ShiftOp, dl, PromotedType, Result, ShiftAmount);
1109 }
1110
1111 unsigned AddOp = Opcode == ISD::SADDSAT ? ISD::ADD : ISD::SUB;
1112 APInt MinVal = APInt::getSignedMinValue(OldBits).sext(NewBits);
1113 APInt MaxVal = APInt::getSignedMaxValue(OldBits).sext(NewBits);
1114 SDValue SatMin = DAG.getConstant(MinVal, dl, PromotedType);
1115 SDValue SatMax = DAG.getConstant(MaxVal, dl, PromotedType);
1116 SDValue Result =
1117 matcher.getNode(AddOp, dl, PromotedType, Op1Promoted, Op2Promoted);
1118 Result = matcher.getNode(ISD::SMIN, dl, PromotedType, Result, SatMax);
1119 Result = matcher.getNode(ISD::SMAX, dl, PromotedType, Result, SatMin);
1120 return Result;
1121}
1122
1123SDValue DAGTypeLegalizer::PromoteIntRes_MULFIX(SDNode *N) {
1124 // Can just promote the operands then continue with operation.
1125 SDLoc dl(N);
1126 SDValue Op1Promoted, Op2Promoted;
1127 bool Signed =
1128 N->getOpcode() == ISD::SMULFIX || N->getOpcode() == ISD::SMULFIXSAT;
1129 bool Saturating =
1130 N->getOpcode() == ISD::SMULFIXSAT || N->getOpcode() == ISD::UMULFIXSAT;
1131 if (Signed) {
1132 Op1Promoted = SExtPromotedInteger(N->getOperand(0));
1133 Op2Promoted = SExtPromotedInteger(N->getOperand(1));
1134 } else {
1135 Op1Promoted = ZExtPromotedInteger(N->getOperand(0));
1136 Op2Promoted = ZExtPromotedInteger(N->getOperand(1));
1137 }
1138 EVT OldType = N->getOperand(0).getValueType();
1139 EVT PromotedType = Op1Promoted.getValueType();
1140 unsigned DiffSize =
1141 PromotedType.getScalarSizeInBits() - OldType.getScalarSizeInBits();
1142
1143 if (Saturating) {
1144 // Promoting the operand and result values changes the saturation width,
1145 // which is extends the values that we clamp to on saturation. This could be
1146 // resolved by shifting one of the operands the same amount, which would
1147 // also shift the result we compare against, then shifting back.
1148 Op1Promoted =
1149 DAG.getNode(ISD::SHL, dl, PromotedType, Op1Promoted,
1150 DAG.getShiftAmountConstant(DiffSize, PromotedType, dl));
1151 SDValue Result = DAG.getNode(N->getOpcode(), dl, PromotedType, Op1Promoted,
1152 Op2Promoted, N->getOperand(2));
1153 unsigned ShiftOp = Signed ? ISD::SRA : ISD::SRL;
1154 return DAG.getNode(ShiftOp, dl, PromotedType, Result,
1155 DAG.getShiftAmountConstant(DiffSize, PromotedType, dl));
1156 }
1157 return DAG.getNode(N->getOpcode(), dl, PromotedType, Op1Promoted, Op2Promoted,
1158 N->getOperand(2));
1159}
1160
1162 unsigned SatW, bool Signed,
1163 const TargetLowering &TLI,
1164 SelectionDAG &DAG) {
1165 EVT VT = V.getValueType();
1166 unsigned VTW = VT.getScalarSizeInBits();
1167
1168 if (!Signed) {
1169 // Saturate to the unsigned maximum by getting the minimum of V and the
1170 // maximum.
1171 return DAG.getNode(ISD::UMIN, dl, VT, V,
1172 DAG.getConstant(APInt::getLowBitsSet(VTW, SatW),
1173 dl, VT));
1174 }
1175
1176 // Saturate to the signed maximum (the low SatW - 1 bits) by taking the
1177 // signed minimum of it and V.
1178 V = DAG.getNode(ISD::SMIN, dl, VT, V,
1179 DAG.getConstant(APInt::getLowBitsSet(VTW, SatW - 1),
1180 dl, VT));
1181 // Saturate to the signed minimum (the high SatW + 1 bits) by taking the
1182 // signed maximum of it and V.
1183 V = DAG.getNode(ISD::SMAX, dl, VT, V,
1184 DAG.getConstant(APInt::getHighBitsSet(VTW, VTW - SatW + 1),
1185 dl, VT));
1186 return V;
1187}
1188
1190 unsigned Scale, const TargetLowering &TLI,
1191 SelectionDAG &DAG, unsigned SatW = 0) {
1192 EVT VT = LHS.getValueType();
1193 unsigned VTSize = VT.getScalarSizeInBits();
1194 bool Signed = N->getOpcode() == ISD::SDIVFIX ||
1195 N->getOpcode() == ISD::SDIVFIXSAT;
1196 bool Saturating = N->getOpcode() == ISD::SDIVFIXSAT ||
1197 N->getOpcode() == ISD::UDIVFIXSAT;
1198
1199 SDLoc dl(N);
1200 // Widen the types by a factor of two. This is guaranteed to expand, since it
1201 // will always have enough high bits in the LHS to shift into.
1202 EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VTSize * 2);
1203 if (VT.isVector())
1204 WideVT = EVT::getVectorVT(*DAG.getContext(), WideVT,
1206 LHS = DAG.getExtOrTrunc(Signed, LHS, dl, WideVT);
1207 RHS = DAG.getExtOrTrunc(Signed, RHS, dl, WideVT);
1208 SDValue Res = TLI.expandFixedPointDiv(N->getOpcode(), dl, LHS, RHS, Scale,
1209 DAG);
1210 assert(Res && "Expanding DIVFIX with wide type failed?");
1211 if (Saturating) {
1212 // If the caller has told us to saturate at something less, use that width
1213 // instead of the type before doubling. However, it cannot be more than
1214 // what we just widened!
1215 assert(SatW <= VTSize &&
1216 "Tried to saturate to more than the original type?");
1217 Res = SaturateWidenedDIVFIX(Res, dl, SatW == 0 ? VTSize : SatW, Signed,
1218 TLI, DAG);
1219 }
1220 return DAG.getZExtOrTrunc(Res, dl, VT);
1221}
1222
1223SDValue DAGTypeLegalizer::PromoteIntRes_DIVFIX(SDNode *N) {
1224 SDLoc dl(N);
1225 SDValue Op1Promoted, Op2Promoted;
1226 bool Signed = N->getOpcode() == ISD::SDIVFIX ||
1227 N->getOpcode() == ISD::SDIVFIXSAT;
1228 bool Saturating = N->getOpcode() == ISD::SDIVFIXSAT ||
1229 N->getOpcode() == ISD::UDIVFIXSAT;
1230 if (Signed) {
1231 Op1Promoted = SExtPromotedInteger(N->getOperand(0));
1232 Op2Promoted = SExtPromotedInteger(N->getOperand(1));
1233 } else {
1234 Op1Promoted = ZExtPromotedInteger(N->getOperand(0));
1235 Op2Promoted = ZExtPromotedInteger(N->getOperand(1));
1236 }
1237 EVT PromotedType = Op1Promoted.getValueType();
1238 unsigned Scale = N->getConstantOperandVal(2);
1239
1240 // If the type is already legal and the operation is legal in that type, we
1241 // should not early expand.
1242 if (TLI.isTypeLegal(PromotedType)) {
1244 TLI.getFixedPointOperationAction(N->getOpcode(), PromotedType, Scale);
1245 if (Action == TargetLowering::Legal || Action == TargetLowering::Custom) {
1246 unsigned Diff = PromotedType.getScalarSizeInBits() -
1247 N->getValueType(0).getScalarSizeInBits();
1248 if (Saturating)
1249 Op1Promoted =
1250 DAG.getNode(ISD::SHL, dl, PromotedType, Op1Promoted,
1251 DAG.getShiftAmountConstant(Diff, PromotedType, dl));
1252 SDValue Res = DAG.getNode(N->getOpcode(), dl, PromotedType, Op1Promoted,
1253 Op2Promoted, N->getOperand(2));
1254 if (Saturating)
1255 Res = DAG.getNode(Signed ? ISD::SRA : ISD::SRL, dl, PromotedType, Res,
1256 DAG.getShiftAmountConstant(Diff, PromotedType, dl));
1257 return Res;
1258 }
1259 }
1260
1261 // See if we can perform the division in this type without expanding.
1262 if (SDValue Res = TLI.expandFixedPointDiv(N->getOpcode(), dl, Op1Promoted,
1263 Op2Promoted, Scale, DAG)) {
1264 if (Saturating)
1265 Res = SaturateWidenedDIVFIX(Res, dl,
1266 N->getValueType(0).getScalarSizeInBits(),
1267 Signed, TLI, DAG);
1268 return Res;
1269 }
1270 // If we cannot, expand it to twice the type width. If we are saturating, give
1271 // it the original width as a saturating width so we don't need to emit
1272 // two saturations.
1273 return earlyExpandDIVFIX(N, Op1Promoted, Op2Promoted, Scale, TLI, DAG,
1274 N->getValueType(0).getScalarSizeInBits());
1275}
1276
1277SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
1278 if (ResNo == 1)
1279 return PromoteIntRes_Overflow(N);
1280
1281 // The operation overflowed iff the result in the larger type is not the
1282 // sign extension of its truncation to the original type.
1283 SDValue LHS = SExtPromotedInteger(N->getOperand(0));
1284 SDValue RHS = SExtPromotedInteger(N->getOperand(1));
1285 EVT OVT = N->getOperand(0).getValueType();
1286 EVT NVT = LHS.getValueType();
1287 SDLoc dl(N);
1288
1289 // Do the arithmetic in the larger type.
1290 unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB;
1291 SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
1292
1293 // Calculate the overflow flag: sign extend the arithmetic result from
1294 // the original type.
1295 SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
1296 DAG.getValueType(OVT));
1297 // Overflowed if and only if this is not equal to Res.
1298 Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
1299
1300 // Use the calculated overflow everywhere.
1301 ReplaceValueWith(SDValue(N, 1), Ofl);
1302
1303 return Res;
1304}
1305
1306SDValue DAGTypeLegalizer::PromoteIntRes_CMP(SDNode *N) {
1307 EVT PromotedResultTy =
1308 TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1309 return DAG.getNode(N->getOpcode(), SDLoc(N), PromotedResultTy,
1310 N->getOperand(0), N->getOperand(1));
1311}
1312
1313SDValue DAGTypeLegalizer::PromoteIntRes_Select(SDNode *N) {
1314 SDValue Mask = N->getOperand(0);
1315
1316 SDValue LHS = GetPromotedInteger(N->getOperand(1));
1317 SDValue RHS = GetPromotedInteger(N->getOperand(2));
1318
1319 unsigned Opcode = N->getOpcode();
1320 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
1321 return DAG.getNode(Opcode, SDLoc(N), LHS.getValueType(), Mask, LHS, RHS,
1322 N->getOperand(3));
1323 return DAG.getNode(Opcode, SDLoc(N), LHS.getValueType(), Mask, LHS, RHS);
1324}
1325
1326SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
1327 SDValue LHS = GetPromotedInteger(N->getOperand(2));
1328 SDValue RHS = GetPromotedInteger(N->getOperand(3));
1329 return DAG.getNode(ISD::SELECT_CC, SDLoc(N),
1330 LHS.getValueType(), N->getOperand(0),
1331 N->getOperand(1), LHS, RHS, N->getOperand(4));
1332}
1333
1334SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
1335 unsigned OpNo = N->isStrictFPOpcode() ? 1 : 0;
1336 EVT InVT = N->getOperand(OpNo).getValueType();
1337 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1338
1339 EVT SVT = getSetCCResultType(InVT);
1340
1341 // If we got back a type that needs to be promoted, this likely means the
1342 // the input type also needs to be promoted. So get the promoted type for
1343 // the input and try the query again.
1344 if (getTypeAction(SVT) == TargetLowering::TypePromoteInteger) {
1345 if (getTypeAction(InVT) == TargetLowering::TypePromoteInteger) {
1346 InVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
1347 SVT = getSetCCResultType(InVT);
1348 } else {
1349 // Input type isn't promoted, just use the default promoted type.
1350 SVT = NVT;
1351 }
1352 }
1353
1354 SDLoc dl(N);
1355 assert(SVT.isVector() == N->getOperand(OpNo).getValueType().isVector() &&
1356 "Vector compare must return a vector result!");
1357
1358 // Get the SETCC result using the canonical SETCC type.
1359 SDValue SetCC;
1360 if (N->isStrictFPOpcode()) {
1361 SDVTList VTs = DAG.getVTList({SVT, MVT::Other});
1362 SDValue Opers[] = {N->getOperand(0), N->getOperand(1),
1363 N->getOperand(2), N->getOperand(3)};
1364 SetCC = DAG.getNode(N->getOpcode(), dl, VTs, Opers, N->getFlags());
1365 // Legalize the chain result - switch anything that used the old chain to
1366 // use the new one.
1367 ReplaceValueWith(SDValue(N, 1), SetCC.getValue(1));
1368 } else
1369 SetCC = DAG.getNode(N->getOpcode(), dl, SVT, N->getOperand(0),
1370 N->getOperand(1), N->getOperand(2), N->getFlags());
1371
1372 // Convert to the expected type.
1373 return DAG.getSExtOrTrunc(SetCC, dl, NVT);
1374}
1375
1376SDValue DAGTypeLegalizer::PromoteIntRes_IS_FPCLASS(SDNode *N) {
1377 SDLoc DL(N);
1378 SDValue Arg = N->getOperand(0);
1379 SDValue Test = N->getOperand(1);
1380 EVT NResVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1381 return DAG.getNode(ISD::IS_FPCLASS, DL, NResVT, Arg, Test);
1382}
1383
1384SDValue DAGTypeLegalizer::PromoteIntRes_FFREXP(SDNode *N) {
1385 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1));
1386 EVT VT = N->getValueType(0);
1387
1388 SDLoc dl(N);
1389 SDValue Res =
1390 DAG.getNode(N->getOpcode(), dl, DAG.getVTList(VT, NVT), N->getOperand(0));
1391
1392 ReplaceValueWith(SDValue(N, 0), Res);
1393 return Res.getValue(1);
1394}
1395
1396SDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
1397 SDValue LHS = GetPromotedInteger(N->getOperand(0));
1398 SDValue RHS = N->getOperand(1);
1399 if (N->getOpcode() != ISD::VP_SHL) {
1400 if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger)
1401 RHS = ZExtPromotedInteger(RHS);
1402
1403 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS);
1404 }
1405
1406 SDValue Mask = N->getOperand(2);
1407 SDValue EVL = N->getOperand(3);
1408 if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger)
1409 RHS = VPZExtPromotedInteger(RHS, Mask, EVL);
1410 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS,
1411 Mask, EVL);
1412}
1413
1414SDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) {
1415 SDValue Op = GetPromotedInteger(N->getOperand(0));
1417 Op.getValueType(), Op, N->getOperand(1));
1418}
1419
1420SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
1421 // The input may have strange things in the top bits of the registers, but
1422 // these operations don't care. They may have weird bits going out, but
1423 // that too is okay if they are integer operations.
1424 SDValue LHS = GetPromotedInteger(N->getOperand(0));
1425 SDValue RHS = GetPromotedInteger(N->getOperand(1));
1426 if (N->getNumOperands() == 2)
1427 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS);
1428 assert(N->getNumOperands() == 4 && "Unexpected number of operands!");
1429 assert(N->isVPOpcode() && "Expected VP opcode");
1430 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS,
1431 N->getOperand(2), N->getOperand(3));
1432}
1433
1434SDValue DAGTypeLegalizer::PromoteIntRes_SExtIntBinOp(SDNode *N) {
1435 if (N->getNumOperands() == 2) {
1436 // Sign extend the input.
1437 SDValue LHS = SExtPromotedInteger(N->getOperand(0));
1438 SDValue RHS = SExtPromotedInteger(N->getOperand(1));
1439 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS);
1440 }
1441 assert(N->getNumOperands() == 4 && "Unexpected number of operands!");
1442 assert(N->isVPOpcode() && "Expected VP opcode");
1443 SDValue Mask = N->getOperand(2);
1444 SDValue EVL = N->getOperand(3);
1445 // Sign extend the input.
1446 SDValue LHS = VPSExtPromotedInteger(N->getOperand(0), Mask, EVL);
1447 SDValue RHS = VPSExtPromotedInteger(N->getOperand(1), Mask, EVL);
1448 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS,
1449 Mask, EVL);
1450}
1451
1452SDValue DAGTypeLegalizer::PromoteIntRes_ZExtIntBinOp(SDNode *N) {
1453 if (N->getNumOperands() == 2) {
1454 // Zero extend the input.
1455 SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
1456 SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
1457 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS);
1458 }
1459 assert(N->getNumOperands() == 4 && "Unexpected number of operands!");
1460 assert(N->isVPOpcode() && "Expected VP opcode");
1461 // Zero extend the input.
1462 SDValue Mask = N->getOperand(2);
1463 SDValue EVL = N->getOperand(3);
1464 SDValue LHS = VPZExtPromotedInteger(N->getOperand(0), Mask, EVL);
1465 SDValue RHS = VPZExtPromotedInteger(N->getOperand(1), Mask, EVL);
1466 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS,
1467 Mask, EVL);
1468}
1469
1470SDValue DAGTypeLegalizer::PromoteIntRes_UMINUMAX(SDNode *N) {
1471 SDValue LHS = N->getOperand(0);
1472 SDValue RHS = N->getOperand(1);
1473
1474 // It doesn't matter if we sign extend or zero extend in the inputs. So do
1475 // whatever is best for the target and the promoted operands.
1476 SExtOrZExtPromotedOperands(LHS, RHS);
1477
1478 return DAG.getNode(N->getOpcode(), SDLoc(N),
1479 LHS.getValueType(), LHS, RHS);
1480}
1481
1482SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
1483 SDValue RHS = N->getOperand(1);
1484 if (N->getOpcode() != ISD::VP_SRA) {
1485 // The input value must be properly sign extended.
1486 SDValue LHS = SExtPromotedInteger(N->getOperand(0));
1487 if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger)
1488 RHS = ZExtPromotedInteger(RHS);
1489 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS);
1490 }
1491
1492 SDValue Mask = N->getOperand(2);
1493 SDValue EVL = N->getOperand(3);
1494 // The input value must be properly sign extended.
1495 SDValue LHS = VPSExtPromotedInteger(N->getOperand(0), Mask, EVL);
1496 if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger)
1497 RHS = VPZExtPromotedInteger(RHS, Mask, EVL);
1498 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS,
1499 Mask, EVL);
1500}
1501
1502SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
1503 SDValue RHS = N->getOperand(1);
1504 if (N->getOpcode() != ISD::VP_SRL) {
1505 // The input value must be properly zero extended.
1506 SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
1507 if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger)
1508 RHS = ZExtPromotedInteger(RHS);
1509 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS);
1510 }
1511
1512 SDValue Mask = N->getOperand(2);
1513 SDValue EVL = N->getOperand(3);
1514 // The input value must be properly zero extended.
1515 SDValue LHS = VPZExtPromotedInteger(N->getOperand(0), Mask, EVL);
1516 if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger)
1517 RHS = VPZExtPromotedInteger(RHS, Mask, EVL);
1518 return DAG.getNode(N->getOpcode(), SDLoc(N), LHS.getValueType(), LHS, RHS,
1519 Mask, EVL);
1520}
1521
1522SDValue DAGTypeLegalizer::PromoteIntRes_Rotate(SDNode *N) {
1523 // Lower the rotate to shifts and ORs which can be promoted.
1524 SDValue Res = TLI.expandROT(N, true /*AllowVectorOps*/, DAG);
1525 ReplaceValueWith(SDValue(N, 0), Res);
1526 return SDValue();
1527}
1528
1529SDValue DAGTypeLegalizer::PromoteIntRes_FunnelShift(SDNode *N) {
1530 SDValue Hi = GetPromotedInteger(N->getOperand(0));
1531 SDValue Lo = GetPromotedInteger(N->getOperand(1));
1532 SDValue Amt = N->getOperand(2);
1533 if (getTypeAction(Amt.getValueType()) == TargetLowering::TypePromoteInteger)
1534 Amt = ZExtPromotedInteger(Amt);
1535 EVT AmtVT = Amt.getValueType();
1536
1537 SDLoc DL(N);
1538 EVT OldVT = N->getOperand(0).getValueType();
1539 EVT VT = Lo.getValueType();
1540 unsigned Opcode = N->getOpcode();
1541 bool IsFSHR = Opcode == ISD::FSHR;
1542 unsigned OldBits = OldVT.getScalarSizeInBits();
1543 unsigned NewBits = VT.getScalarSizeInBits();
1544
1545 // Amount has to be interpreted modulo the old bit width.
1546 Amt = DAG.getNode(ISD::UREM, DL, AmtVT, Amt,
1547 DAG.getConstant(OldBits, DL, AmtVT));
1548
1549 // If the promoted type is twice the size (or more), then we use the
1550 // traditional funnel 'double' shift codegen. This isn't necessary if the
1551 // shift amount is constant.
1552 // fshl(x,y,z) -> (((aext(x) << bw) | zext(y)) << (z % bw)) >> bw.
1553 // fshr(x,y,z) -> (((aext(x) << bw) | zext(y)) >> (z % bw)).
1554 if (NewBits >= (2 * OldBits) && !isa<ConstantSDNode>(Amt) &&
1555 !TLI.isOperationLegalOrCustom(Opcode, VT)) {
1556 SDValue HiShift = DAG.getConstant(OldBits, DL, VT);
1557 Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, HiShift);
1558 Lo = DAG.getZeroExtendInReg(Lo, DL, OldVT);
1559 SDValue Res = DAG.getNode(ISD::OR, DL, VT, Hi, Lo);
1560 Res = DAG.getNode(IsFSHR ? ISD::SRL : ISD::SHL, DL, VT, Res, Amt);
1561 if (!IsFSHR)
1562 Res = DAG.getNode(ISD::SRL, DL, VT, Res, HiShift);
1563 return Res;
1564 }
1565
1566 // Shift Lo up to occupy the upper bits of the promoted type.
1567 SDValue ShiftOffset = DAG.getConstant(NewBits - OldBits, DL, AmtVT);
1568 Lo = DAG.getNode(ISD::SHL, DL, VT, Lo, ShiftOffset);
1569
1570 // Increase Amount to shift the result into the lower bits of the promoted
1571 // type.
1572 if (IsFSHR)
1573 Amt = DAG.getNode(ISD::ADD, DL, AmtVT, Amt, ShiftOffset);
1574
1575 return DAG.getNode(Opcode, DL, VT, Hi, Lo, Amt);
1576}
1577
1578// A vp version of PromoteIntRes_FunnelShift.
1579SDValue DAGTypeLegalizer::PromoteIntRes_VPFunnelShift(SDNode *N) {
1580 SDValue Hi = GetPromotedInteger(N->getOperand(0));
1581 SDValue Lo = GetPromotedInteger(N->getOperand(1));
1582 SDValue Amt = N->getOperand(2);
1583 SDValue Mask = N->getOperand(3);
1584 SDValue EVL = N->getOperand(4);
1585 if (getTypeAction(Amt.getValueType()) == TargetLowering::TypePromoteInteger)
1586 Amt = VPZExtPromotedInteger(Amt, Mask, EVL);
1587 EVT AmtVT = Amt.getValueType();
1588
1589 SDLoc DL(N);
1590 EVT OldVT = N->getOperand(0).getValueType();
1591 EVT VT = Lo.getValueType();
1592 unsigned Opcode = N->getOpcode();
1593 bool IsFSHR = Opcode == ISD::VP_FSHR;
1594 unsigned OldBits = OldVT.getScalarSizeInBits();
1595 unsigned NewBits = VT.getScalarSizeInBits();
1596
1597 // Amount has to be interpreted modulo the old bit width.
1598 Amt = DAG.getNode(ISD::VP_UREM, DL, AmtVT, Amt,
1599 DAG.getConstant(OldBits, DL, AmtVT), Mask, EVL);
1600
1601 // If the promoted type is twice the size (or more), then we use the
1602 // traditional funnel 'double' shift codegen. This isn't necessary if the
1603 // shift amount is constant.
1604 // fshl(x,y,z) -> (((aext(x) << bw) | zext(y)) << (z % bw)) >> bw.
1605 // fshr(x,y,z) -> (((aext(x) << bw) | zext(y)) >> (z % bw)).
1606 if (NewBits >= (2 * OldBits) && !isa<ConstantSDNode>(Amt) &&
1607 !TLI.isOperationLegalOrCustom(Opcode, VT)) {
1608 SDValue HiShift = DAG.getConstant(OldBits, DL, VT);
1609 Hi = DAG.getNode(ISD::VP_SHL, DL, VT, Hi, HiShift, Mask, EVL);
1610 Lo = DAG.getVPZeroExtendInReg(Lo, Mask, EVL, DL, OldVT);
1611 SDValue Res = DAG.getNode(ISD::VP_OR, DL, VT, Hi, Lo, Mask, EVL);
1612 Res = DAG.getNode(IsFSHR ? ISD::VP_SRL : ISD::VP_SHL, DL, VT, Res, Amt,
1613 Mask, EVL);
1614 if (!IsFSHR)
1615 Res = DAG.getNode(ISD::VP_SRL, DL, VT, Res, HiShift, Mask, EVL);
1616 return Res;
1617 }
1618
1619 // Shift Lo up to occupy the upper bits of the promoted type.
1620 SDValue ShiftOffset = DAG.getConstant(NewBits - OldBits, DL, AmtVT);
1621 Lo = DAG.getNode(ISD::VP_SHL, DL, VT, Lo, ShiftOffset, Mask, EVL);
1622
1623 // Increase Amount to shift the result into the lower bits of the promoted
1624 // type.
1625 if (IsFSHR)
1626 Amt = DAG.getNode(ISD::VP_ADD, DL, AmtVT, Amt, ShiftOffset, Mask, EVL);
1627
1628 return DAG.getNode(Opcode, DL, VT, Hi, Lo, Amt, Mask, EVL);
1629}
1630
1631SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
1632 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1633 SDValue Res;
1634 SDValue InOp = N->getOperand(0);
1635 SDLoc dl(N);
1636
1637 switch (getTypeAction(InOp.getValueType())) {
1638 default: llvm_unreachable("Unknown type action!");
1641 Res = InOp;
1642 break;
1644 Res = GetPromotedInteger(InOp);
1645 break;
1647 EVT InVT = InOp.getValueType();
1648 assert(InVT.isVector() && "Cannot split scalar types");
1649 ElementCount NumElts = InVT.getVectorElementCount();
1650 assert(NumElts == NVT.getVectorElementCount() &&
1651 "Dst and Src must have the same number of elements");
1653 "Promoted vector type must be a power of two");
1654
1655 SDValue EOp1, EOp2;
1656 GetSplitVector(InOp, EOp1, EOp2);
1657
1658 EVT HalfNVT = EVT::getVectorVT(*DAG.getContext(), NVT.getScalarType(),
1659 NumElts.divideCoefficientBy(2));
1660 if (N->getOpcode() == ISD::TRUNCATE) {
1661 EOp1 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp1);
1662 EOp2 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp2);
1663 } else {
1664 assert(N->getOpcode() == ISD::VP_TRUNCATE &&
1665 "Expected VP_TRUNCATE opcode");
1666 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
1667 std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(1));
1668 std::tie(EVLLo, EVLHi) =
1669 DAG.SplitEVL(N->getOperand(2), N->getValueType(0), dl);
1670 EOp1 = DAG.getNode(ISD::VP_TRUNCATE, dl, HalfNVT, EOp1, MaskLo, EVLLo);
1671 EOp2 = DAG.getNode(ISD::VP_TRUNCATE, dl, HalfNVT, EOp2, MaskHi, EVLHi);
1672 }
1673 return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, EOp1, EOp2);
1674 }
1675 // TODO: VP_TRUNCATE need to handle when TypeWidenVector access to some
1676 // targets.
1678 SDValue WideInOp = GetWidenedVector(InOp);
1679
1680 // Truncate widened InOp.
1681 unsigned NumElem = WideInOp.getValueType().getVectorNumElements();
1682 EVT TruncVT = EVT::getVectorVT(*DAG.getContext(),
1683 N->getValueType(0).getScalarType(), NumElem);
1684 SDValue WideTrunc = DAG.getNode(ISD::TRUNCATE, dl, TruncVT, WideInOp);
1685
1686 // Zero extend so that the elements are of same type as those of NVT
1688 NumElem);
1689 SDValue WideExt = DAG.getNode(ISD::ZERO_EXTEND, dl, ExtVT, WideTrunc);
1690
1691 // Extract the low NVT subvector.
1692 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, dl);
1693 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NVT, WideExt, ZeroIdx);
1694 }
1695 }
1696
1697 // Truncate to NVT instead of VT
1698 if (N->getOpcode() == ISD::VP_TRUNCATE)
1699 return DAG.getNode(ISD::VP_TRUNCATE, dl, NVT, Res, N->getOperand(1),
1700 N->getOperand(2));
1701 return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res);
1702}
1703
1704SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
1705 if (ResNo == 1)
1706 return PromoteIntRes_Overflow(N);
1707
1708 // The operation overflowed iff the result in the larger type is not the
1709 // zero extension of its truncation to the original type.
1710 SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
1711 SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
1712 EVT OVT = N->getOperand(0).getValueType();
1713 EVT NVT = LHS.getValueType();
1714 SDLoc dl(N);
1715
1716 // Do the arithmetic in the larger type.
1717 unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB;
1718 SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
1719
1720 // Calculate the overflow flag: zero extend the arithmetic result from
1721 // the original type.
1722 SDValue Ofl = DAG.getZeroExtendInReg(Res, dl, OVT);
1723 // Overflowed if and only if this is not equal to Res.
1724 Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
1725
1726 // Use the calculated overflow everywhere.
1727 ReplaceValueWith(SDValue(N, 1), Ofl);
1728
1729 return Res;
1730}
1731
1732// Handle promotion for the ADDE/SUBE/UADDO_CARRY/USUBO_CARRY nodes. Notice that
1733// the third operand of ADDE/SUBE nodes is carry flag, which differs from
1734// the UADDO_CARRY/USUBO_CARRY nodes in that the third operand is carry Boolean.
1735SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO_CARRY(SDNode *N,
1736 unsigned ResNo) {
1737 if (ResNo == 1)
1738 return PromoteIntRes_Overflow(N);
1739
1740 // We need to sign-extend the operands so the carry value computed by the
1741 // wide operation will be equivalent to the carry value computed by the
1742 // narrow operation.
1743 // An UADDO_CARRY can generate carry only if any of the operands has its
1744 // most significant bit set. Sign extension propagates the most significant
1745 // bit into the higher bits which means the extra bit that the narrow
1746 // addition would need (i.e. the carry) will be propagated through the higher
1747 // bits of the wide addition.
1748 // A USUBO_CARRY can generate borrow only if LHS < RHS and this property will
1749 // be preserved by sign extension.
1750 SDValue LHS = SExtPromotedInteger(N->getOperand(0));
1751 SDValue RHS = SExtPromotedInteger(N->getOperand(1));
1752
1753 EVT ValueVTs[] = {LHS.getValueType(), N->getValueType(1)};
1754
1755 // Do the arithmetic in the wide type.
1756 SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N), DAG.getVTList(ValueVTs),
1757 LHS, RHS, N->getOperand(2));
1758
1759 // Update the users of the original carry/borrow value.
1760 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
1761
1762 return SDValue(Res.getNode(), 0);
1763}
1764
1765SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO_CARRY(SDNode *N,
1766 unsigned ResNo) {
1767 assert(ResNo == 1 && "Don't know how to promote other results yet.");
1768 return PromoteIntRes_Overflow(N);
1769}
1770
1771SDValue DAGTypeLegalizer::PromoteIntRes_ABS(SDNode *N) {
1772 EVT OVT = N->getValueType(0);
1773 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
1774
1775 // If a larger ABS or SMAX isn't supported by the target, try to expand now.
1776 // If we expand later we'll end up sign extending more than just the sra input
1777 // in sra+xor+sub expansion.
1778 if (!OVT.isVector() &&
1780 !TLI.isOperationLegal(ISD::SMAX, NVT)) {
1781 if (SDValue Res = TLI.expandABS(N, DAG))
1782 return DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), NVT, Res);
1783 }
1784
1785 SDValue Op0 = SExtPromotedInteger(N->getOperand(0));
1786 return DAG.getNode(ISD::ABS, SDLoc(N), Op0.getValueType(), Op0);
1787}
1788
1789SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
1790 // Promote the overflow bit trivially.
1791 if (ResNo == 1)
1792 return PromoteIntRes_Overflow(N);
1793
1794 SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
1795 SDLoc DL(N);
1796 EVT SmallVT = LHS.getValueType();
1797
1798 // To determine if the result overflowed in a larger type, we extend the
1799 // input to the larger type, do the multiply (checking if it overflows),
1800 // then also check the high bits of the result to see if overflow happened
1801 // there.
1802 if (N->getOpcode() == ISD::SMULO) {
1803 LHS = SExtPromotedInteger(LHS);
1804 RHS = SExtPromotedInteger(RHS);
1805 } else {
1806 LHS = ZExtPromotedInteger(LHS);
1807 RHS = ZExtPromotedInteger(RHS);
1808 }
1809 SDVTList VTs = DAG.getVTList(LHS.getValueType(), N->getValueType(1));
1810 SDValue Mul = DAG.getNode(N->getOpcode(), DL, VTs, LHS, RHS);
1811
1812 // Overflow occurred if it occurred in the larger type, or if the high part
1813 // of the result does not zero/sign-extend the low part. Check this second
1814 // possibility first.
1815 SDValue Overflow;
1816 if (N->getOpcode() == ISD::UMULO) {
1817 // Unsigned overflow occurred if the high part is non-zero.
1818 unsigned Shift = SmallVT.getScalarSizeInBits();
1819 SDValue Hi =
1820 DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
1821 DAG.getShiftAmountConstant(Shift, Mul.getValueType(), DL));
1822 Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
1823 DAG.getConstant(0, DL, Hi.getValueType()),
1824 ISD::SETNE);
1825 } else {
1826 // Signed overflow occurred if the high part does not sign extend the low.
1827 SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(),
1828 Mul, DAG.getValueType(SmallVT));
1829 Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE);
1830 }
1831
1832 // The only other way for overflow to occur is if the multiplication in the
1833 // larger type itself overflowed.
1834 Overflow = DAG.getNode(ISD::OR, DL, N->getValueType(1), Overflow,
1835 SDValue(Mul.getNode(), 1));
1836
1837 // Use the calculated overflow everywhere.
1838 ReplaceValueWith(SDValue(N, 1), Overflow);
1839 return Mul;
1840}
1841
1842SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
1843 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
1844 N->getValueType(0)));
1845}
1846
1847SDValue DAGTypeLegalizer::PromoteIntRes_VSCALE(SDNode *N) {
1848 EVT VT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1849
1850 const APInt &MulImm = N->getConstantOperandAPInt(0);
1851 return DAG.getVScale(SDLoc(N), VT, MulImm.sext(VT.getSizeInBits()));
1852}
1853
1854SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
1855 SDValue Chain = N->getOperand(0); // Get the chain.
1856 SDValue Ptr = N->getOperand(1); // Get the pointer.
1857 EVT VT = N->getValueType(0);
1858 SDLoc dl(N);
1859
1860 MVT RegVT = TLI.getRegisterType(*DAG.getContext(), VT);
1861 unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), VT);
1862 // The argument is passed as NumRegs registers of type RegVT.
1863
1864 SmallVector<SDValue, 8> Parts(NumRegs);
1865 for (unsigned i = 0; i < NumRegs; ++i) {
1866 Parts[i] = DAG.getVAArg(RegVT, dl, Chain, Ptr, N->getOperand(2),
1867 N->getConstantOperandVal(3));
1868 Chain = Parts[i].getValue(1);
1869 }
1870
1871 // Handle endianness of the load.
1872 if (DAG.getDataLayout().isBigEndian())
1873 std::reverse(Parts.begin(), Parts.end());
1874
1875 // Assemble the parts in the promoted type.
1876 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1877 SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]);
1878 for (unsigned i = 1; i < NumRegs; ++i) {
1879 SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]);
1880 // Shift it to the right position and "or" it in.
1881 Part = DAG.getNode(ISD::SHL, dl, NVT, Part,
1882 DAG.getConstant(i * RegVT.getSizeInBits(), dl,
1883 TLI.getPointerTy(DAG.getDataLayout())));
1884 Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part);
1885 }
1886
1887 // Modified the chain result - switch anything that used the old chain to
1888 // use the new one.
1889 ReplaceValueWith(SDValue(N, 1), Chain);
1890
1891 return Res;
1892}
1893
1894//===----------------------------------------------------------------------===//
1895// Integer Operand Promotion
1896//===----------------------------------------------------------------------===//
1897
1898/// PromoteIntegerOperand - This method is called when the specified operand of
1899/// the specified node is found to need promotion. At this point, all of the
1900/// result types of the node are known to be legal, but other operands of the
1901/// node may need promotion or expansion as well as the specified one.
1902bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
1903 LLVM_DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG));
1904 SDValue Res = SDValue();
1905 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) {
1906 LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n");
1907 return false;
1908 }
1909
1910 switch (N->getOpcode()) {
1911 default:
1912 #ifndef NDEBUG
1913 dbgs() << "PromoteIntegerOperand Op #" << OpNo << ": ";
1914 N->dump(&DAG); dbgs() << "\n";
1915 #endif
1916 report_fatal_error("Do not know how to promote this operator's operand!");
1917
1918 case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break;
1919 case ISD::ATOMIC_STORE:
1920 Res = PromoteIntOp_ATOMIC_STORE(cast<AtomicSDNode>(N));
1921 break;
1922 case ISD::BITCAST: Res = PromoteIntOp_BITCAST(N); break;
1923 case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
1924 case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break;
1925 case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break;
1926 case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
1927 case ISD::CONCAT_VECTORS: Res = PromoteIntOp_CONCAT_VECTORS(N); break;
1928 case ISD::EXTRACT_VECTOR_ELT: Res = PromoteIntOp_EXTRACT_VECTOR_ELT(N); break;
1930 Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);
1931 break;
1932 case ISD::SPLAT_VECTOR:
1934 case ISD::EXPERIMENTAL_VP_SPLAT:
1935 Res = PromoteIntOp_ScalarOp(N);
1936 break;
1937 case ISD::VSELECT:
1938 case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break;
1939 case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
1940 case ISD::VP_SETCC:
1941 case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
1942 case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break;
1943 case ISD::VP_SIGN_EXTEND: Res = PromoteIntOp_VP_SIGN_EXTEND(N); break;
1944 case ISD::VP_SINT_TO_FP:
1945 case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break;
1946 case ISD::STRICT_SINT_TO_FP: Res = PromoteIntOp_STRICT_SINT_TO_FP(N); break;
1947 case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
1948 OpNo); break;
1949 case ISD::MSTORE: Res = PromoteIntOp_MSTORE(cast<MaskedStoreSDNode>(N),
1950 OpNo); break;
1951 case ISD::MLOAD: Res = PromoteIntOp_MLOAD(cast<MaskedLoadSDNode>(N),
1952 OpNo); break;
1953 case ISD::MGATHER: Res = PromoteIntOp_MGATHER(cast<MaskedGatherSDNode>(N),
1954 OpNo); break;
1955 case ISD::MSCATTER: Res = PromoteIntOp_MSCATTER(cast<MaskedScatterSDNode>(N),
1956 OpNo); break;
1958 Res = PromoteIntOp_VECTOR_COMPRESS(N, OpNo);
1959 break;
1960 case ISD::VP_TRUNCATE:
1961 case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
1962 case ISD::BF16_TO_FP:
1963 case ISD::FP16_TO_FP:
1964 case ISD::VP_UINT_TO_FP:
1965 case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break;
1967 case ISD::STRICT_UINT_TO_FP: Res = PromoteIntOp_STRICT_UINT_TO_FP(N); break;
1968 case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
1969 case ISD::VP_ZERO_EXTEND: Res = PromoteIntOp_VP_ZERO_EXTEND(N); break;
1970 case ISD::EXTRACT_SUBVECTOR: Res = PromoteIntOp_EXTRACT_SUBVECTOR(N); break;
1971 case ISD::INSERT_SUBVECTOR: Res = PromoteIntOp_INSERT_SUBVECTOR(N); break;
1972
1973 case ISD::SHL:
1974 case ISD::SRA:
1975 case ISD::SRL:
1976 case ISD::ROTL:
1977 case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
1978
1979 case ISD::SCMP:
1980 case ISD::UCMP: Res = PromoteIntOp_CMP(N); break;
1981
1982 case ISD::FSHL:
1983 case ISD::FSHR: Res = PromoteIntOp_FunnelShift(N); break;
1984
1985 case ISD::FRAMEADDR:
1986 case ISD::RETURNADDR: Res = PromoteIntOp_FRAMERETURNADDR(N); break;
1987
1988 case ISD::SMULFIX:
1989 case ISD::SMULFIXSAT:
1990 case ISD::UMULFIX:
1991 case ISD::UMULFIXSAT:
1992 case ISD::SDIVFIX:
1993 case ISD::SDIVFIXSAT:
1994 case ISD::UDIVFIX:
1995 case ISD::UDIVFIXSAT: Res = PromoteIntOp_FIX(N); break;
1996 case ISD::FPOWI:
1997 case ISD::STRICT_FPOWI:
1998 case ISD::FLDEXP:
1999 case ISD::STRICT_FLDEXP: Res = PromoteIntOp_ExpOp(N); break;
2000 case ISD::VECREDUCE_ADD:
2001 case ISD::VECREDUCE_MUL:
2002 case ISD::VECREDUCE_AND:
2003 case ISD::VECREDUCE_OR:
2004 case ISD::VECREDUCE_XOR:
2008 case ISD::VECREDUCE_UMIN: Res = PromoteIntOp_VECREDUCE(N); break;
2009 case ISD::VP_REDUCE_ADD:
2010 case ISD::VP_REDUCE_MUL:
2011 case ISD::VP_REDUCE_AND:
2012 case ISD::VP_REDUCE_OR:
2013 case ISD::VP_REDUCE_XOR:
2014 case ISD::VP_REDUCE_SMAX:
2015 case ISD::VP_REDUCE_SMIN:
2016 case ISD::VP_REDUCE_UMAX:
2017 case ISD::VP_REDUCE_UMIN:
2018 Res = PromoteIntOp_VP_REDUCE(N, OpNo);
2019 break;
2020
2021 case ISD::SET_ROUNDING: Res = PromoteIntOp_SET_ROUNDING(N); break;
2022 case ISD::STACKMAP:
2023 Res = PromoteIntOp_STACKMAP(N, OpNo);
2024 break;
2025 case ISD::PATCHPOINT:
2026 Res = PromoteIntOp_PATCHPOINT(N, OpNo);
2027 break;
2028 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2029 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2030 Res = PromoteIntOp_VP_STRIDED(N, OpNo);
2031 break;
2032 case ISD::EXPERIMENTAL_VP_SPLICE:
2033 Res = PromoteIntOp_VP_SPLICE(N, OpNo);
2034 break;
2035 }
2036
2037 // If the result is null, the sub-method took care of registering results etc.
2038 if (!Res.getNode()) return false;
2039
2040 // If the result is N, the sub-method updated N in place. Tell the legalizer
2041 // core about this.
2042 if (Res.getNode() == N)
2043 return true;
2044
2045 const bool IsStrictFp = N->isStrictFPOpcode();
2046 assert(Res.getValueType() == N->getValueType(0) &&
2047 N->getNumValues() == (IsStrictFp ? 2 : 1) &&
2048 "Invalid operand expansion");
2049 LLVM_DEBUG(dbgs() << "Replacing: "; N->dump(&DAG); dbgs() << " with: ";
2050 Res.dump());
2051
2052 ReplaceValueWith(SDValue(N, 0), Res);
2053 if (IsStrictFp)
2054 ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1));
2055
2056 return false;
2057}
2058
2059// These operands can be either sign extended or zero extended as long as we
2060// treat them the same. If an extension is free, choose that. Otherwise, follow
2061// target preference.
2062void DAGTypeLegalizer::SExtOrZExtPromotedOperands(SDValue &LHS, SDValue &RHS) {
2063 SDValue OpL = GetPromotedInteger(LHS);
2064 SDValue OpR = GetPromotedInteger(RHS);
2065
2066 if (TLI.isSExtCheaperThanZExt(LHS.getValueType(), OpL.getValueType())) {
2067 // The target would prefer to promote the comparison operand with sign
2068 // extension. Honor that unless the promoted values are already zero
2069 // extended.
2070 unsigned OpLEffectiveBits =
2072 unsigned OpREffectiveBits =
2074 if (OpLEffectiveBits <= LHS.getScalarValueSizeInBits() &&
2075 OpREffectiveBits <= RHS.getScalarValueSizeInBits()) {
2076 LHS = OpL;
2077 RHS = OpR;
2078 return;
2079 }
2080
2081 // The promoted values aren't zero extended, use a sext_inreg.
2082 LHS = SExtPromotedInteger(LHS);
2083 RHS = SExtPromotedInteger(RHS);
2084 return;
2085 }
2086
2087 // Prefer to promote the comparison operand with zero extension.
2088
2089 // If the width of OpL/OpR excluding the duplicated sign bits is no greater
2090 // than the width of LHS/RHS, we can avoid/ inserting a zext_inreg operation
2091 // that we might not be able to remove.
2092 unsigned OpLEffectiveBits = DAG.ComputeMaxSignificantBits(OpL);
2093 unsigned OpREffectiveBits = DAG.ComputeMaxSignificantBits(OpR);
2094 if (OpLEffectiveBits <= LHS.getScalarValueSizeInBits() &&
2095 OpREffectiveBits <= RHS.getScalarValueSizeInBits()) {
2096 LHS = OpL;
2097 RHS = OpR;
2098 return;
2099 }
2100
2101 // Otherwise, use zext_inreg.
2102 LHS = ZExtPromotedInteger(LHS);
2103 RHS = ZExtPromotedInteger(RHS);
2104}
2105
2106/// PromoteSetCCOperands - Promote the operands of a comparison. This code is
2107/// shared among BR_CC, SELECT_CC, and SETCC handlers.
2108void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &LHS, SDValue &RHS,
2109 ISD::CondCode CCCode) {
2110 // We have to insert explicit sign or zero extends. Note that we could
2111 // insert sign extends for ALL conditions. For those operations where either
2112 // zero or sign extension would be valid, we ask the target which extension
2113 // it would prefer.
2114
2115 // Signed comparisons always require sign extension.
2116 if (ISD::isSignedIntSetCC(CCCode)) {
2117 LHS = SExtPromotedInteger(LHS);
2118 RHS = SExtPromotedInteger(RHS);
2119 return;
2120 }
2121
2123 "Unknown integer comparison!");
2124
2125 SExtOrZExtPromotedOperands(LHS, RHS);
2126}
2127
2128SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
2129 SDValue Op = GetPromotedInteger(N->getOperand(0));
2130 return DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0), Op);
2131}
2132
2133SDValue DAGTypeLegalizer::PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N) {
2134 SDValue Op1 = GetPromotedInteger(N->getOperand(1));
2135 return DAG.getAtomic(N->getOpcode(), SDLoc(N), N->getMemoryVT(),
2136 N->getChain(), Op1, N->getBasePtr(), N->getMemOperand());
2137}
2138
2139SDValue DAGTypeLegalizer::PromoteIntOp_BITCAST(SDNode *N) {
2140 // This should only occur in unusual situations like bitcasting to an
2141 // x86_fp80, so just turn it into a store+load
2142 return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
2143}
2144
2145SDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
2146 assert(OpNo == 2 && "Don't know how to promote this operand!");
2147
2148 SDValue LHS = N->getOperand(2);
2149 SDValue RHS = N->getOperand(3);
2150 PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
2151
2152 // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
2153 // legal types.
2154 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2155 N->getOperand(1), LHS, RHS, N->getOperand(4)),
2156 0);
2157}
2158
2159SDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
2160 assert(OpNo == 1 && "only know how to promote condition");
2161
2162 // Promote all the way up to the canonical SetCC type.
2163 SDValue Cond = PromoteTargetBoolean(N->getOperand(1), MVT::Other);
2164
2165 // The chain (Op#0) and basic block destination (Op#2) are always legal types.
2166 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Cond,
2167 N->getOperand(2)), 0);
2168}
2169
2170SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
2171 // Since the result type is legal, the operands must promote to it.
2172 EVT OVT = N->getOperand(0).getValueType();
2173 SDValue Lo = ZExtPromotedInteger(N->getOperand(0));
2174 SDValue Hi = GetPromotedInteger(N->getOperand(1));
2175 assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
2176 SDLoc dl(N);
2177
2178 Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi,
2179 DAG.getConstant(OVT.getSizeInBits(), dl,
2180 TLI.getPointerTy(DAG.getDataLayout())));
2181 return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi);
2182}
2183
2184SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
2185 // The vector type is legal but the element type is not. This implies
2186 // that the vector is a power-of-two in length and that the element
2187 // type does not have a strange size (eg: it is not i1).
2188 EVT VecVT = N->getValueType(0);
2189 unsigned NumElts = VecVT.getVectorNumElements();
2190 assert(!((NumElts & 1) && (!TLI.isTypeLegal(VecVT))) &&
2191 "Legal vector of one illegal element?");
2192
2193 // Promote the inserted value. The type does not need to match the
2194 // vector element type. Check that any extra bits introduced will be
2195 // truncated away.
2196 assert(N->getOperand(0).getValueSizeInBits() >=
2197 N->getValueType(0).getScalarSizeInBits() &&
2198 "Type of inserted value narrower than vector element type!");
2199
2201 for (unsigned i = 0; i < NumElts; ++i)
2202 NewOps.push_back(GetPromotedInteger(N->getOperand(i)));
2203
2204 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2205}
2206
2207SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
2208 unsigned OpNo) {
2209 if (OpNo == 1) {
2210 // Promote the inserted value. This is valid because the type does not
2211 // have to match the vector element type.
2212
2213 // Check that any extra bits introduced will be truncated away.
2214 assert(N->getOperand(1).getValueSizeInBits() >=
2215 N->getValueType(0).getScalarSizeInBits() &&
2216 "Type of inserted value narrower than vector element type!");
2217 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2218 GetPromotedInteger(N->getOperand(1)),
2219 N->getOperand(2)),
2220 0);
2221 }
2222
2223 assert(OpNo == 2 && "Different operand and result vector types?");
2224
2225 // Promote the index.
2226 SDValue Idx = DAG.getZExtOrTrunc(N->getOperand(2), SDLoc(N),
2227 TLI.getVectorIdxTy(DAG.getDataLayout()));
2228 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2229 N->getOperand(1), Idx), 0);
2230}
2231
2232SDValue DAGTypeLegalizer::PromoteIntOp_ScalarOp(SDNode *N) {
2233 SDValue Op = GetPromotedInteger(N->getOperand(0));
2234 if (N->getOpcode() == ISD::EXPERIMENTAL_VP_SPLAT)
2235 return SDValue(
2236 DAG.UpdateNodeOperands(N, Op, N->getOperand(1), N->getOperand(2)), 0);
2237
2238 // Integer SPLAT_VECTOR/SCALAR_TO_VECTOR operands are implicitly truncated,
2239 // so just promote the operand in place.
2240 return SDValue(DAG.UpdateNodeOperands(N, Op), 0);
2241}
2242
2243SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
2244 assert(OpNo == 0 && "Only know how to promote the condition!");
2245 SDValue Cond = N->getOperand(0);
2246 EVT OpTy = N->getOperand(1).getValueType();
2247
2248 if (N->getOpcode() == ISD::VSELECT)
2249 if (SDValue Res = WidenVSELECTMask(N))
2250 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
2251 Res, N->getOperand(1), N->getOperand(2));
2252
2253 // Promote all the way up to the canonical SetCC type.
2254 EVT OpVT = N->getOpcode() == ISD::SELECT ? OpTy.getScalarType() : OpTy;
2255 Cond = PromoteTargetBoolean(Cond, OpVT);
2256
2257 return SDValue(DAG.UpdateNodeOperands(N, Cond, N->getOperand(1),
2258 N->getOperand(2)), 0);
2259}
2260
2261SDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) {
2262 assert(OpNo == 0 && "Don't know how to promote this operand!");
2263
2264 SDValue LHS = N->getOperand(0);
2265 SDValue RHS = N->getOperand(1);
2266 PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(4))->get());
2267
2268 // The CC (#4) and the possible return values (#2 and #3) have legal types.
2269 return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2),
2270 N->getOperand(3), N->getOperand(4)), 0);
2271}
2272
2273SDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
2274 assert(OpNo == 0 && "Don't know how to promote this operand!");
2275
2276 SDValue LHS = N->getOperand(0);
2277 SDValue RHS = N->getOperand(1);
2278 PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
2279
2280 // The CC (#2) is always legal.
2281 if (N->getOpcode() == ISD::SETCC)
2282 return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2)), 0);
2283
2284 assert(N->getOpcode() == ISD::VP_SETCC && "Expected VP_SETCC opcode");
2285
2286 return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2),
2287 N->getOperand(3), N->getOperand(4)),
2288 0);
2289}
2290
2291SDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) {
2292 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2293 ZExtPromotedInteger(N->getOperand(1))), 0);
2294}
2295
2296SDValue DAGTypeLegalizer::PromoteIntOp_CMP(SDNode *N) {
2297 SDValue LHS = N->getOpcode() == ISD::UCMP
2298 ? ZExtPromotedInteger(N->getOperand(0))
2299 : SExtPromotedInteger(N->getOperand(0));
2300 SDValue RHS = N->getOpcode() == ISD::UCMP
2301 ? ZExtPromotedInteger(N->getOperand(1))
2302 : SExtPromotedInteger(N->getOperand(1));
2303
2304 return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS), 0);
2305}
2306
2307SDValue DAGTypeLegalizer::PromoteIntOp_FunnelShift(SDNode *N) {
2308 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), N->getOperand(1),
2309 ZExtPromotedInteger(N->getOperand(2))), 0);
2310}
2311
2312SDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
2313 SDValue Op = GetPromotedInteger(N->getOperand(0));
2314 SDLoc dl(N);
2315 Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
2316 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(),
2317 Op, DAG.getValueType(N->getOperand(0).getValueType()));
2318}
2319
2320SDValue DAGTypeLegalizer::PromoteIntOp_VP_SIGN_EXTEND(SDNode *N) {
2321 SDLoc dl(N);
2322 EVT VT = N->getValueType(0);
2323 SDValue Op = GetPromotedInteger(N->getOperand(0));
2324 // FIXME: There is no VP_ANY_EXTEND yet.
2325 Op = DAG.getNode(ISD::VP_ZERO_EXTEND, dl, VT, Op, N->getOperand(1),
2326 N->getOperand(2));
2327 unsigned Diff =
2328 VT.getScalarSizeInBits() - N->getOperand(0).getScalarValueSizeInBits();
2329 SDValue ShAmt = DAG.getShiftAmountConstant(Diff, VT, dl);
2330 // FIXME: There is no VP_SIGN_EXTEND_INREG so use a pair of shifts.
2331 SDValue Shl = DAG.getNode(ISD::VP_SHL, dl, VT, Op, ShAmt, N->getOperand(1),
2332 N->getOperand(2));
2333 return DAG.getNode(ISD::VP_SRA, dl, VT, Shl, ShAmt, N->getOperand(1),
2334 N->getOperand(2));
2335}
2336
2337SDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) {
2338 if (N->getOpcode() == ISD::VP_SINT_TO_FP)
2339 return SDValue(DAG.UpdateNodeOperands(N,
2340 SExtPromotedInteger(N->getOperand(0)),
2341 N->getOperand(1), N->getOperand(2)),
2342 0);
2343 return SDValue(DAG.UpdateNodeOperands(N,
2344 SExtPromotedInteger(N->getOperand(0))), 0);
2345}
2346
2347SDValue DAGTypeLegalizer::PromoteIntOp_STRICT_SINT_TO_FP(SDNode *N) {
2348 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2349 SExtPromotedInteger(N->getOperand(1))), 0);
2350}
2351
2352SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
2353 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
2354 SDValue Ch = N->getChain(), Ptr = N->getBasePtr();
2355 SDLoc dl(N);
2356
2357 SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value.
2358
2359 // Truncate the value and store the result.
2360 return DAG.getTruncStore(Ch, dl, Val, Ptr,
2361 N->getMemoryVT(), N->getMemOperand());
2362}
2363
2364SDValue DAGTypeLegalizer::PromoteIntOp_MSTORE(MaskedStoreSDNode *N,
2365 unsigned OpNo) {
2366 SDValue DataOp = N->getValue();
2367 SDValue Mask = N->getMask();
2368
2369 if (OpNo == 4) {
2370 // The Mask. Update in place.
2371 EVT DataVT = DataOp.getValueType();
2372 Mask = PromoteTargetBoolean(Mask, DataVT);
2373 SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
2374 NewOps[4] = Mask;
2375 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2376 }
2377
2378 assert(OpNo == 1 && "Unexpected operand for promotion");
2379 DataOp = GetPromotedInteger(DataOp);
2380
2381 return DAG.getMaskedStore(N->getChain(), SDLoc(N), DataOp, N->getBasePtr(),
2382 N->getOffset(), Mask, N->getMemoryVT(),
2383 N->getMemOperand(), N->getAddressingMode(),
2384 /*IsTruncating*/ true, N->isCompressingStore());
2385}
2386
2387SDValue DAGTypeLegalizer::PromoteIntOp_MLOAD(MaskedLoadSDNode *N,
2388 unsigned OpNo) {
2389 assert(OpNo == 3 && "Only know how to promote the mask!");
2390 EVT DataVT = N->getValueType(0);
2391 SDValue Mask = PromoteTargetBoolean(N->getOperand(OpNo), DataVT);
2392 SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
2393 NewOps[OpNo] = Mask;
2394 SDNode *Res = DAG.UpdateNodeOperands(N, NewOps);
2395 if (Res == N)
2396 return SDValue(Res, 0);
2397
2398 // Update triggered CSE, do our own replacement since caller can't.
2399 ReplaceValueWith(SDValue(N, 0), SDValue(Res, 0));
2400 ReplaceValueWith(SDValue(N, 1), SDValue(Res, 1));
2401 return SDValue();
2402}
2403
2404SDValue DAGTypeLegalizer::PromoteIntOp_MGATHER(MaskedGatherSDNode *N,
2405 unsigned OpNo) {
2406 SmallVector<SDValue, 5> NewOps(N->op_begin(), N->op_end());
2407
2408 if (OpNo == 2) {
2409 // The Mask
2410 EVT DataVT = N->getValueType(0);
2411 NewOps[OpNo] = PromoteTargetBoolean(N->getOperand(OpNo), DataVT);
2412 } else if (OpNo == 4) {
2413 // The Index
2414 if (N->isIndexSigned())
2415 // Need to sign extend the index since the bits will likely be used.
2416 NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo));
2417 else
2418 NewOps[OpNo] = ZExtPromotedInteger(N->getOperand(OpNo));
2419 } else
2420 NewOps[OpNo] = GetPromotedInteger(N->getOperand(OpNo));
2421
2422 SDNode *Res = DAG.UpdateNodeOperands(N, NewOps);
2423 if (Res == N)
2424 return SDValue(Res, 0);
2425
2426 // Update triggered CSE, do our own replacement since caller can't.
2427 ReplaceValueWith(SDValue(N, 0), SDValue(Res, 0));
2428 ReplaceValueWith(SDValue(N, 1), SDValue(Res, 1));
2429 return SDValue();
2430}
2431
2432SDValue DAGTypeLegalizer::PromoteIntOp_MSCATTER(MaskedScatterSDNode *N,
2433 unsigned OpNo) {
2434 bool TruncateStore = N->isTruncatingStore();
2435 SmallVector<SDValue, 5> NewOps(N->op_begin(), N->op_end());
2436
2437 if (OpNo == 2) {
2438 // The Mask
2439 EVT DataVT = N->getValue().getValueType();
2440 NewOps[OpNo] = PromoteTargetBoolean(N->getOperand(OpNo), DataVT);
2441 } else if (OpNo == 4) {
2442 // The Index
2443 if (N->isIndexSigned())
2444 // Need to sign extend the index since the bits will likely be used.
2445 NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo));
2446 else
2447 NewOps[OpNo] = ZExtPromotedInteger(N->getOperand(OpNo));
2448 } else {
2449 NewOps[OpNo] = GetPromotedInteger(N->getOperand(OpNo));
2450 TruncateStore = true;
2451 }
2452
2453 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), N->getMemoryVT(),
2454 SDLoc(N), NewOps, N->getMemOperand(),
2455 N->getIndexType(), TruncateStore);
2456}
2457
2458SDValue DAGTypeLegalizer::PromoteIntOp_VECTOR_COMPRESS(SDNode *N,
2459 unsigned OpNo) {
2460 assert(OpNo == 1 && "Can only promote VECTOR_COMPRESS mask.");
2461 SDValue Vec = N->getOperand(0);
2462 EVT VT = Vec.getValueType();
2463 SDValue Passthru = N->getOperand(2);
2464 SDValue Mask = PromoteTargetBoolean(N->getOperand(1), VT);
2465 return DAG.getNode(ISD::VECTOR_COMPRESS, SDLoc(N), VT, Vec, Mask, Passthru);
2466}
2467
2468SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
2469 SDValue Op = GetPromotedInteger(N->getOperand(0));
2470 if (N->getOpcode() == ISD::VP_TRUNCATE)
2471 return DAG.getNode(ISD::VP_TRUNCATE, SDLoc(N), N->getValueType(0), Op,
2472 N->getOperand(1), N->getOperand(2));
2473 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0), Op);
2474}
2475
2476SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
2477 if (N->getOpcode() == ISD::VP_UINT_TO_FP)
2478 return SDValue(DAG.UpdateNodeOperands(N,
2479 ZExtPromotedInteger(N->getOperand(0)),
2480 N->getOperand(1), N->getOperand(2)),
2481 0);
2482 return SDValue(DAG.UpdateNodeOperands(N,
2483 ZExtPromotedInteger(N->getOperand(0))), 0);
2484}
2485
2486SDValue DAGTypeLegalizer::PromoteIntOp_STRICT_UINT_TO_FP(SDNode *N) {
2487 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2488 ZExtPromotedInteger(N->getOperand(1))), 0);
2489}
2490
2491SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
2492 SDLoc dl(N);
2493 SDValue Op = GetPromotedInteger(N->getOperand(0));
2494 Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
2495 return DAG.getZeroExtendInReg(Op, dl, N->getOperand(0).getValueType());
2496}
2497
2498SDValue DAGTypeLegalizer::PromoteIntOp_VP_ZERO_EXTEND(SDNode *N) {
2499 SDLoc dl(N);
2500 EVT VT = N->getValueType(0);
2501 SDValue Op = GetPromotedInteger(N->getOperand(0));
2502 // FIXME: There is no VP_ANY_EXTEND yet.
2503 Op = DAG.getNode(ISD::VP_ZERO_EXTEND, dl, VT, Op, N->getOperand(1),
2504 N->getOperand(2));
2505 return DAG.getVPZeroExtendInReg(Op, N->getOperand(1), N->getOperand(2), dl,
2506 N->getOperand(0).getValueType());
2507}
2508
2509SDValue DAGTypeLegalizer::PromoteIntOp_FIX(SDNode *N) {
2510 SDValue Op2 = ZExtPromotedInteger(N->getOperand(2));
2511 return SDValue(
2512 DAG.UpdateNodeOperands(N, N->getOperand(0), N->getOperand(1), Op2), 0);
2513}
2514
2515SDValue DAGTypeLegalizer::PromoteIntOp_FRAMERETURNADDR(SDNode *N) {
2516 // Promote the RETURNADDR/FRAMEADDR argument to a supported integer width.
2517 SDValue Op = ZExtPromotedInteger(N->getOperand(0));
2518 return SDValue(DAG.UpdateNodeOperands(N, Op), 0);
2519}
2520
2521SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) {
2522 bool IsStrict = N->isStrictFPOpcode();
2523 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
2524
2525 bool IsPowI =
2526 N->getOpcode() == ISD::FPOWI || N->getOpcode() == ISD::STRICT_FPOWI;
2527
2528 // The integer operand is the last operand in FPOWI (or FLDEXP) (so the result
2529 // and floating point operand is already type legalized).
2530 RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0))
2531 : RTLIB::getLDEXP(N->getValueType(0));
2532
2533 if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC)) {
2534 SDValue Op = SExtPromotedInteger(N->getOperand(1));
2535 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op), 0);
2536 }
2537
2538 // We can't just promote the exponent type in FPOWI, since we want to lower
2539 // the node to a libcall and we if we promote to a type larger than
2540 // sizeof(int) the libcall might not be according to the targets ABI. Instead
2541 // we rewrite to a libcall here directly, letting makeLibCall handle promotion
2542 // if the target accepts it according to shouldSignExtendTypeInLibCall.
2543
2544 unsigned OpOffset = IsStrict ? 1 : 0;
2545 // The exponent should fit in a sizeof(int) type for the libcall to be valid.
2546 assert(DAG.getLibInfo().getIntSize() ==
2547 N->getOperand(1 + OpOffset).getValueType().getSizeInBits() &&
2548 "POWI exponent should match with sizeof(int) when doing the libcall.");
2550 CallOptions.setSExt(true);
2551 SDValue Ops[2] = {N->getOperand(0 + OpOffset), N->getOperand(1 + OpOffset)};
2552 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
2553 DAG, LC, N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain);
2554 ReplaceValueWith(SDValue(N, 0), Tmp.first);
2555 if (IsStrict)
2556 ReplaceValueWith(SDValue(N, 1), Tmp.second);
2557 return SDValue();
2558}
2559
2561 switch (N->getOpcode()) {
2562 default:
2563 llvm_unreachable("Expected integer vector reduction");
2564 case ISD::VECREDUCE_ADD:
2565 case ISD::VECREDUCE_MUL:
2566 case ISD::VECREDUCE_AND:
2567 case ISD::VECREDUCE_OR:
2568 case ISD::VECREDUCE_XOR:
2569 case ISD::VP_REDUCE_ADD:
2570 case ISD::VP_REDUCE_MUL:
2571 case ISD::VP_REDUCE_AND:
2572 case ISD::VP_REDUCE_OR:
2573 case ISD::VP_REDUCE_XOR:
2574 return ISD::ANY_EXTEND;
2577 case ISD::VP_REDUCE_SMAX:
2578 case ISD::VP_REDUCE_SMIN:
2579 return ISD::SIGN_EXTEND;
2582 case ISD::VP_REDUCE_UMAX:
2583 case ISD::VP_REDUCE_UMIN:
2584 return ISD::ZERO_EXTEND;
2585 }
2586}
2587
2588SDValue DAGTypeLegalizer::PromoteIntOpVectorReduction(SDNode *N, SDValue V) {
2589 switch (getExtendForIntVecReduction(N)) {
2590 default:
2591 llvm_unreachable("Impossible extension kind for integer reduction");
2592 case ISD::ANY_EXTEND:
2593 return GetPromotedInteger(V);
2594 case ISD::SIGN_EXTEND:
2595 return SExtPromotedInteger(V);
2596 case ISD::ZERO_EXTEND:
2597 return ZExtPromotedInteger(V);
2598 }
2599}
2600
2601SDValue DAGTypeLegalizer::PromoteIntOp_VECREDUCE(SDNode *N) {
2602 SDLoc dl(N);
2603 SDValue Op = PromoteIntOpVectorReduction(N, N->getOperand(0));
2604
2605 EVT OrigEltVT = N->getOperand(0).getValueType().getVectorElementType();
2606 EVT InVT = Op.getValueType();
2607 EVT EltVT = InVT.getVectorElementType();
2608 EVT ResVT = N->getValueType(0);
2609 unsigned Opcode = N->getOpcode();
2610
2611 // An i1 vecreduce_xor is equivalent to vecreduce_add, use that instead if
2612 // vecreduce_xor is not legal
2613 if (Opcode == ISD::VECREDUCE_XOR && OrigEltVT == MVT::i1 &&
2616 Opcode = ISD::VECREDUCE_ADD;
2617
2618 // An i1 vecreduce_or is equivalent to vecreduce_umax, use that instead if
2619 // vecreduce_or is not legal
2620 else if (Opcode == ISD::VECREDUCE_OR && OrigEltVT == MVT::i1 &&
2623 Opcode = ISD::VECREDUCE_UMAX;
2624 // Can't use promoteTargetBoolean here because we still need
2625 // to either sign_ext or zero_ext in the undefined case.
2626 switch (TLI.getBooleanContents(InVT)) {
2629 Op = ZExtPromotedInteger(N->getOperand(0));
2630 break;
2632 Op = SExtPromotedInteger(N->getOperand(0));
2633 break;
2634 }
2635 }
2636
2637 // An i1 vecreduce_and is equivalent to vecreduce_umin, use that instead if
2638 // vecreduce_and is not legal
2639 else if (Opcode == ISD::VECREDUCE_AND && OrigEltVT == MVT::i1 &&
2642 Opcode = ISD::VECREDUCE_UMIN;
2643 // Can't use promoteTargetBoolean here because we still need
2644 // to either sign_ext or zero_ext in the undefined case.
2645 switch (TLI.getBooleanContents(InVT)) {
2648 Op = ZExtPromotedInteger(N->getOperand(0));
2649 break;
2651 Op = SExtPromotedInteger(N->getOperand(0));
2652 break;
2653 }
2654 }
2655
2656 if (ResVT.bitsGE(EltVT))
2657 return DAG.getNode(Opcode, SDLoc(N), ResVT, Op);
2658
2659 // Result size must be >= element size. If this is not the case after
2660 // promotion, also promote the result type and then truncate.
2661 SDValue Reduce = DAG.getNode(Opcode, dl, EltVT, Op);
2662 return DAG.getNode(ISD::TRUNCATE, dl, ResVT, Reduce);
2663}
2664
2665SDValue DAGTypeLegalizer::PromoteIntOp_VP_REDUCE(SDNode *N, unsigned OpNo) {
2666 SDLoc DL(N);
2667 SDValue Op = N->getOperand(OpNo);
2668 SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
2669
2670 if (OpNo == 2) { // Mask
2671 // Update in place.
2672 NewOps[2] = PromoteTargetBoolean(Op, N->getOperand(1).getValueType());
2673 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2674 }
2675
2676 assert(OpNo == 1 && "Unexpected operand for promotion");
2677
2678 Op = PromoteIntOpVectorReduction(N, Op);
2679
2680 NewOps[OpNo] = Op;
2681
2682 EVT VT = N->getValueType(0);
2683 EVT EltVT = Op.getValueType().getScalarType();
2684
2685 if (VT.bitsGE(EltVT))
2686 return DAG.getNode(N->getOpcode(), SDLoc(N), VT, NewOps);
2687
2688 // Result size must be >= element/start-value size. If this is not the case
2689 // after promotion, also promote both the start value and result type and
2690 // then truncate.
2691 NewOps[0] =
2692 DAG.getNode(getExtendForIntVecReduction(N), DL, EltVT, N->getOperand(0));
2693 SDValue Reduce = DAG.getNode(N->getOpcode(), DL, EltVT, NewOps);
2694 return DAG.getNode(ISD::TRUNCATE, DL, VT, Reduce);
2695}
2696
2697SDValue DAGTypeLegalizer::PromoteIntOp_SET_ROUNDING(SDNode *N) {
2698 SDValue Op = ZExtPromotedInteger(N->getOperand(1));
2699 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op), 0);
2700}
2701
2702SDValue DAGTypeLegalizer::PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
2703 assert(OpNo > 1); // Because the first two arguments are guaranteed legal.
2704 SmallVector<SDValue> NewOps(N->ops().begin(), N->ops().end());
2705 SDValue Operand = N->getOperand(OpNo);
2706 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Operand.getValueType());
2707 NewOps[OpNo] = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), NVT, Operand);
2708 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2709}
2710
2711SDValue DAGTypeLegalizer::PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
2712 assert(OpNo >= 7);
2713 SmallVector<SDValue> NewOps(N->ops().begin(), N->ops().end());
2714 SDValue Operand = N->getOperand(OpNo);
2715 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Operand.getValueType());
2716 NewOps[OpNo] = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), NVT, Operand);
2717 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2718}
2719
2720SDValue DAGTypeLegalizer::PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) {
2721 assert((N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD && OpNo == 3) ||
2722 (N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE && OpNo == 4));
2723
2724 SmallVector<SDValue, 8> NewOps(N->op_begin(), N->op_end());
2725 NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo));
2726
2727 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2728}
2729
2730SDValue DAGTypeLegalizer::PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo) {
2731 SmallVector<SDValue, 6> NewOps(N->op_begin(), N->op_end());
2732
2733 if (OpNo == 2) { // Offset operand
2734 NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo));
2735 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2736 }
2737
2738 assert((OpNo == 4 || OpNo == 5) && "Unexpected operand for promotion");
2739
2740 NewOps[OpNo] = ZExtPromotedInteger(N->getOperand(OpNo));
2741 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2742}
2743
2744//===----------------------------------------------------------------------===//
2745// Integer Result Expansion
2746//===----------------------------------------------------------------------===//
2747
2748/// ExpandIntegerResult - This method is called when the specified result of the
2749/// specified node is found to need expansion. At this point, the node may also
2750/// have invalid operands or may have other results that need promotion, we just
2751/// know that (at least) one result needs expansion.
2752void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
2753 LLVM_DEBUG(dbgs() << "Expand integer result: "; N->dump(&DAG));
2754 SDValue Lo, Hi;
2755 Lo = Hi = SDValue();
2756
2757 // See if the target wants to custom expand this node.
2758 if (CustomLowerNode(N, N->getValueType(ResNo), true))
2759 return;
2760
2761 switch (N->getOpcode()) {
2762 default:
2763#ifndef NDEBUG
2764 dbgs() << "ExpandIntegerResult #" << ResNo << ": ";
2765 N->dump(&DAG); dbgs() << "\n";
2766#endif
2767 report_fatal_error("Do not know how to expand the result of this "
2768 "operator!");
2769
2770 case ISD::ARITH_FENCE: SplitRes_ARITH_FENCE(N, Lo, Hi); break;
2771 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
2772 case ISD::SELECT: SplitRes_Select(N, Lo, Hi); break;
2773 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
2774 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
2775 case ISD::FREEZE: SplitRes_FREEZE(N, Lo, Hi); break;
2776
2777 case ISD::BITCAST: ExpandRes_BITCAST(N, Lo, Hi); break;
2778 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
2779 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
2780 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
2781 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break;
2782
2783 case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
2784 case ISD::AssertSext: ExpandIntRes_AssertSext(N, Lo, Hi); break;
2785 case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break;
2786 case ISD::BITREVERSE: ExpandIntRes_BITREVERSE(N, Lo, Hi); break;
2787 case ISD::BSWAP: ExpandIntRes_BSWAP(N, Lo, Hi); break;
2788 case ISD::PARITY: ExpandIntRes_PARITY(N, Lo, Hi); break;
2789 case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break;
2790 case ISD::ABS: ExpandIntRes_ABS(N, Lo, Hi); break;
2792 case ISD::CTLZ: ExpandIntRes_CTLZ(N, Lo, Hi); break;
2793 case ISD::CTPOP: ExpandIntRes_CTPOP(N, Lo, Hi); break;
2795 case ISD::CTTZ: ExpandIntRes_CTTZ(N, Lo, Hi); break;
2796 case ISD::GET_ROUNDING:ExpandIntRes_GET_ROUNDING(N, Lo, Hi); break;
2798 case ISD::FP_TO_SINT:
2800 case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_XINT(N, Lo, Hi); break;
2802 case ISD::FP_TO_UINT_SAT: ExpandIntRes_FP_TO_XINT_SAT(N, Lo, Hi); break;
2803 case ISD::STRICT_LROUND:
2804 case ISD::STRICT_LRINT:
2805 case ISD::LROUND:
2806 case ISD::LRINT:
2808 case ISD::STRICT_LLRINT:
2809 case ISD::LLROUND:
2810 case ISD::LLRINT: ExpandIntRes_XROUND_XRINT(N, Lo, Hi); break;
2811 case ISD::LOAD: ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
2812 case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break;
2814 case ISD::READSTEADYCOUNTER: ExpandIntRes_READCOUNTER(N, Lo, Hi); break;
2815 case ISD::SDIV: ExpandIntRes_SDIV(N, Lo, Hi); break;
2816 case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
2817 case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
2818 case ISD::SREM: ExpandIntRes_SREM(N, Lo, Hi); break;
2819 case ISD::TRUNCATE: ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
2820 case ISD::UDIV: ExpandIntRes_UDIV(N, Lo, Hi); break;
2821 case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break;
2822 case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
2823 case ISD::ATOMIC_LOAD: ExpandIntRes_ATOMIC_LOAD(N, Lo, Hi); break;
2824
2836 case ISD::ATOMIC_SWAP:
2837 case ISD::ATOMIC_CMP_SWAP: {
2838 std::pair<SDValue, SDValue> Tmp = ExpandAtomic(N);
2839 SplitInteger(Tmp.first, Lo, Hi);
2840 ReplaceValueWith(SDValue(N, 1), Tmp.second);
2841 break;
2842 }
2844 AtomicSDNode *AN = cast<AtomicSDNode>(N);
2845 SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::Other);
2846 SDValue Tmp = DAG.getAtomicCmpSwap(
2848 N->getOperand(0), N->getOperand(1), N->getOperand(2), N->getOperand(3),
2849 AN->getMemOperand());
2850
2851 // Expanding to the strong ATOMIC_CMP_SWAP node means we can determine
2852 // success simply by comparing the loaded value against the ingoing
2853 // comparison.
2854 SDValue Success = DAG.getSetCC(SDLoc(N), N->getValueType(1), Tmp,
2855 N->getOperand(2), ISD::SETEQ);
2856
2857 SplitInteger(Tmp, Lo, Hi);
2858 ReplaceValueWith(SDValue(N, 1), Success);
2859 ReplaceValueWith(SDValue(N, 2), Tmp.getValue(1));
2860 break;
2861 }
2862
2863 case ISD::AND:
2864 case ISD::OR:
2865 case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
2866
2867 case ISD::UMAX:
2868 case ISD::SMAX:
2869 case ISD::UMIN:
2870 case ISD::SMIN: ExpandIntRes_MINMAX(N, Lo, Hi); break;
2871
2872 case ISD::SCMP:
2873 case ISD::UCMP: ExpandIntRes_CMP(N, Lo, Hi); break;
2874
2875 case ISD::ADD:
2876 case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
2877
2878 case ISD::ADDC:
2879 case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
2880
2881 case ISD::ADDE:
2882 case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
2883
2884 case ISD::UADDO_CARRY:
2885 case ISD::USUBO_CARRY: ExpandIntRes_UADDSUBO_CARRY(N, Lo, Hi); break;
2886
2887 case ISD::SADDO_CARRY:
2888 case ISD::SSUBO_CARRY: ExpandIntRes_SADDSUBO_CARRY(N, Lo, Hi); break;
2889
2890 case ISD::SHL:
2891 case ISD::SRA:
2892 case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
2893
2894 case ISD::SADDO:
2895 case ISD::SSUBO: ExpandIntRes_SADDSUBO(N, Lo, Hi); break;
2896 case ISD::UADDO:
2897 case ISD::USUBO: ExpandIntRes_UADDSUBO(N, Lo, Hi); break;
2898 case ISD::UMULO:
2899 case ISD::SMULO: ExpandIntRes_XMULO(N, Lo, Hi); break;
2900
2901 case ISD::SADDSAT:
2902 case ISD::UADDSAT:
2903 case ISD::SSUBSAT:
2904 case ISD::USUBSAT: ExpandIntRes_ADDSUBSAT(N, Lo, Hi); break;
2905
2906 case ISD::SSHLSAT:
2907 case ISD::USHLSAT: ExpandIntRes_SHLSAT(N, Lo, Hi); break;
2908
2909 case ISD::AVGCEILS:
2910 case ISD::AVGCEILU:
2911 case ISD::AVGFLOORS:
2912 case ISD::AVGFLOORU: ExpandIntRes_AVG(N, Lo, Hi); break;
2913
2914 case ISD::SMULFIX:
2915 case ISD::SMULFIXSAT:
2916 case ISD::UMULFIX:
2917 case ISD::UMULFIXSAT: ExpandIntRes_MULFIX(N, Lo, Hi); break;
2918
2919 case ISD::SDIVFIX:
2920 case ISD::SDIVFIXSAT:
2921 case ISD::UDIVFIX:
2922 case ISD::UDIVFIXSAT: ExpandIntRes_DIVFIX(N, Lo, Hi); break;
2923
2924 case ISD::VECREDUCE_ADD:
2925 case ISD::VECREDUCE_MUL:
2926 case ISD::VECREDUCE_AND:
2927 case ISD::VECREDUCE_OR:
2928 case ISD::VECREDUCE_XOR:
2932 case ISD::VECREDUCE_UMIN: ExpandIntRes_VECREDUCE(N, Lo, Hi); break;
2933
2934 case ISD::ROTL:
2935 case ISD::ROTR:
2936 ExpandIntRes_Rotate(N, Lo, Hi);
2937 break;
2938
2939 case ISD::FSHL:
2940 case ISD::FSHR:
2941 ExpandIntRes_FunnelShift(N, Lo, Hi);
2942 break;
2943
2944 case ISD::VSCALE:
2945 ExpandIntRes_VSCALE(N, Lo, Hi);
2946 break;
2947 }
2948
2949 // If Lo/Hi is null, the sub-method took care of registering results etc.
2950 if (Lo.getNode())
2951 SetExpandedInteger(SDValue(N, ResNo), Lo, Hi);
2952}
2953
2954/// Lower an atomic node to the appropriate builtin call.
2955std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
2956 unsigned Opc = Node->getOpcode();
2957 MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
2958 AtomicOrdering order = cast<AtomicSDNode>(Node)->getMergedOrdering();
2959 // Lower to outline atomic libcall if outline atomics enabled,
2960 // or to sync libcall otherwise
2961 RTLIB::Libcall LC = RTLIB::getOUTLINE_ATOMIC(Opc, order, VT);
2962 EVT RetVT = Node->getValueType(0);
2965 if (TLI.getLibcallName(LC)) {
2966 Ops.append(Node->op_begin() + 2, Node->op_end());
2967 Ops.push_back(Node->getOperand(1));
2968 } else {
2969 LC = RTLIB::getSYNC(Opc, VT);
2970 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
2971 "Unexpected atomic op or value type!");
2972 Ops.append(Node->op_begin() + 1, Node->op_end());
2973 }
2974 return TLI.makeLibCall(DAG, LC, RetVT, Ops, CallOptions, SDLoc(Node),
2975 Node->getOperand(0));
2976}
2977
2978/// N is a shift by a value that needs to be expanded,
2979/// and the shift amount is a constant 'Amt'. Expand the operation.
2980void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, const APInt &Amt,
2981 SDValue &Lo, SDValue &Hi) {
2982 SDLoc DL(N);
2983 // Expand the incoming operand to be shifted, so that we have its parts
2984 SDValue InL, InH;
2985 GetExpandedInteger(N->getOperand(0), InL, InH);
2986
2987 // Though Amt shouldn't usually be 0, it's possible. E.g. when legalization
2988 // splitted a vector shift, like this: <op1, op2> SHL <0, 2>.
2989 if (!Amt) {
2990 Lo = InL;
2991 Hi = InH;
2992 return;
2993 }
2994
2995 EVT NVT = InL.getValueType();
2996 unsigned VTBits = N->getValueType(0).getSizeInBits();
2997 unsigned NVTBits = NVT.getSizeInBits();
2998
2999 if (N->getOpcode() == ISD::SHL) {
3000 if (Amt.uge(VTBits)) {
3001 Lo = Hi = DAG.getConstant(0, DL, NVT);
3002 } else if (Amt.ugt(NVTBits)) {
3003 Lo = DAG.getConstant(0, DL, NVT);
3004 Hi = DAG.getNode(ISD::SHL, DL, NVT, InL,
3005 DAG.getShiftAmountConstant(Amt - NVTBits, NVT, DL));
3006 } else if (Amt == NVTBits) {
3007 Lo = DAG.getConstant(0, DL, NVT);
3008 Hi = InL;
3009 } else {
3010 Lo = DAG.getNode(ISD::SHL, DL, NVT, InL,
3011 DAG.getShiftAmountConstant(Amt, NVT, DL));
3012 Hi = DAG.getNode(
3013 ISD::OR, DL, NVT,
3014 DAG.getNode(ISD::SHL, DL, NVT, InH,
3015 DAG.getShiftAmountConstant(Amt, NVT, DL)),
3016 DAG.getNode(ISD::SRL, DL, NVT, InL,
3017 DAG.getShiftAmountConstant(-Amt + NVTBits, NVT, DL)));
3018 }
3019 return;
3020 }
3021
3022 if (N->getOpcode() == ISD::SRL) {
3023 if (Amt.uge(VTBits)) {
3024 Lo = Hi = DAG.getConstant(0, DL, NVT);
3025 } else if (Amt.ugt(NVTBits)) {
3026 Lo = DAG.getNode(ISD::SRL, DL, NVT, InH,
3027 DAG.getShiftAmountConstant(Amt - NVTBits, NVT, DL));
3028 Hi = DAG.getConstant(0, DL, NVT);
3029 } else if (Amt == NVTBits) {
3030 Lo = InH;
3031 Hi = DAG.getConstant(0, DL, NVT);
3032 } else {
3033 Lo = DAG.getNode(
3034 ISD::OR, DL, NVT,
3035 DAG.getNode(ISD::SRL, DL, NVT, InL,
3036 DAG.getShiftAmountConstant(Amt, NVT, DL)),
3037 DAG.getNode(ISD::SHL, DL, NVT, InH,
3038 DAG.getShiftAmountConstant(-Amt + NVTBits, NVT, DL)));
3039 Hi = DAG.getNode(ISD::SRL, DL, NVT, InH,
3040 DAG.getShiftAmountConstant(Amt, NVT, DL));
3041 }
3042 return;
3043 }
3044
3045 assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
3046 if (Amt.uge(VTBits)) {
3047 Hi = Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
3048 DAG.getShiftAmountConstant(NVTBits - 1, NVT, DL));
3049 } else if (Amt.ugt(NVTBits)) {
3050 Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
3051 DAG.getShiftAmountConstant(Amt - NVTBits, NVT, DL));
3052 Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
3053 DAG.getShiftAmountConstant(NVTBits - 1, NVT, DL));
3054 } else if (Amt == NVTBits) {
3055 Lo = InH;
3056 Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
3057 DAG.getShiftAmountConstant(NVTBits - 1, NVT, DL));
3058 } else {
3059 Lo = DAG.getNode(
3060 ISD::OR, DL, NVT,
3061 DAG.getNode(ISD::SRL, DL, NVT, InL,
3062 DAG.getShiftAmountConstant(Amt, NVT, DL)),
3063 DAG.getNode(ISD::SHL, DL, NVT, InH,
3064 DAG.getShiftAmountConstant(-Amt + NVTBits, NVT, DL)));
3065 Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
3066 DAG.getShiftAmountConstant(Amt, NVT, DL));
3067 }
3068}
3069
3070/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
3071/// this shift based on knowledge of the high bit of the shift amount. If we
3072/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
3073/// shift amount.
3074bool DAGTypeLegalizer::
3075ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
3076 unsigned Opc = N->getOpcode();
3077 SDValue In = N->getOperand(0);
3078 SDValue Amt = N->getOperand(1);
3079 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3080 EVT ShTy = Amt.getValueType();
3081 unsigned ShBits = ShTy.getScalarSizeInBits();
3082 unsigned NVTBits = NVT.getScalarSizeInBits();
3083 assert(isPowerOf2_32(NVTBits) &&
3084 "Expanded integer type size not a power of two!");
3085 SDLoc dl(N);
3086
3087 APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
3088 KnownBits Known = DAG.computeKnownBits(Amt);
3089
3090 // If we don't know anything about the high bits, exit.
3091 if (((Known.Zero | Known.One) & HighBitMask) == 0)
3092 return false;
3093
3094 // Get the incoming operand to be shifted.
3095 SDValue InL, InH;
3096 GetExpandedInteger(In, InL, InH);
3097
3098 // If we know that any of the high bits of the shift amount are one, then we
3099 // can do this as a couple of simple shifts.
3100 if (Known.One.intersects(HighBitMask)) {
3101 // Mask out the high bit, which we know is set.
3102 Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
3103 DAG.getConstant(~HighBitMask, dl, ShTy));
3104
3105 switch (Opc) {
3106 default: llvm_unreachable("Unknown shift");
3107 case ISD::SHL:
3108 Lo = DAG.getConstant(0, dl, NVT); // Low part is zero.
3109 Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
3110 return true;
3111 case ISD::SRL:
3112 Hi = DAG.getConstant(0, dl, NVT); // Hi part is zero.
3113 Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
3114 return true;
3115 case ISD::SRA:
3116 Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part.
3117 DAG.getConstant(NVTBits - 1, dl, ShTy));
3118 Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
3119 return true;
3120 }
3121 }
3122
3123 // If we know that all of the high bits of the shift amount are zero, then we
3124 // can do this as a couple of simple shifts.
3125 if (HighBitMask.isSubsetOf(Known.Zero)) {
3126 // Calculate 31-x. 31 is used instead of 32 to avoid creating an undefined
3127 // shift if x is zero. We can use XOR here because x is known to be smaller
3128 // than 32.
3129 SDValue Amt2 = DAG.getNode(ISD::XOR, dl, ShTy, Amt,
3130 DAG.getConstant(NVTBits - 1, dl, ShTy));
3131
3132 unsigned Op1, Op2;
3133 switch (Opc) {
3134 default: llvm_unreachable("Unknown shift");
3135 case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break;
3136 case ISD::SRL:
3137 case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break;
3138 }
3139
3140 // When shifting right the arithmetic for Lo and Hi is swapped.
3141 if (Opc != ISD::SHL)
3142 std::swap(InL, InH);
3143
3144 // Use a little trick to get the bits that move from Lo to Hi. First
3145 // shift by one bit.
3146 SDValue Sh1 = DAG.getNode(Op2, dl, NVT, InL, DAG.getConstant(1, dl, ShTy));
3147 // Then compute the remaining shift with amount-1.
3148 SDValue Sh2 = DAG.getNode(Op2, dl, NVT, Sh1, Amt2);
3149
3150 Lo = DAG.getNode(Opc, dl, NVT, InL, Amt);
3151 Hi = DAG.getNode(ISD::OR, dl, NVT, DAG.getNode(Op1, dl, NVT, InH, Amt),Sh2);
3152
3153 if (Opc != ISD::SHL)
3154 std::swap(Hi, Lo);
3155 return true;
3156 }
3157
3158 return false;
3159}
3160
3161/// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift
3162/// of any size.
3163bool DAGTypeLegalizer::
3164ExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
3165 SDValue Amt = N->getOperand(1);
3166 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3167 EVT ShTy = Amt.getValueType();
3168 unsigned NVTBits = NVT.getSizeInBits();
3169 assert(isPowerOf2_32(NVTBits) &&
3170 "Expanded integer type size not a power of two!");
3171 SDLoc dl(N);
3172
3173 // Get the incoming operand to be shifted.
3174 SDValue InL, InH;
3175 GetExpandedInteger(N->getOperand(0), InL, InH);
3176
3177 SDValue NVBitsNode = DAG.getConstant(NVTBits, dl, ShTy);
3178 SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode);
3179 SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
3180 SDValue isShort = DAG.getSetCC(dl, getSetCCResultType(ShTy),
3181 Amt, NVBitsNode, ISD::SETULT);
3182 SDValue isZero = DAG.getSetCC(dl, getSetCCResultType(ShTy),
3183 Amt, DAG.getConstant(0, dl, ShTy),
3184 ISD::SETEQ);
3185
3186 SDValue LoS, HiS, LoL, HiL;
3187 switch (N->getOpcode()) {
3188 default: llvm_unreachable("Unknown shift");
3189 case ISD::SHL:
3190 // Short: ShAmt < NVTBits
3191 LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
3192 HiS = DAG.getNode(ISD::OR, dl, NVT,
3193 DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
3194 DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack));
3195
3196 // Long: ShAmt >= NVTBits
3197 LoL = DAG.getConstant(0, dl, NVT); // Lo part is zero.
3198 HiL = DAG.getNode(ISD::SHL, dl, NVT, InL, AmtExcess); // Hi from Lo part.
3199
3200 Lo = DAG.getSelect(dl, NVT, isShort, LoS, LoL);
3201 Hi = DAG.getSelect(dl, NVT, isZero, InH,
3202 DAG.getSelect(dl, NVT, isShort, HiS, HiL));
3203 return true;
3204 case ISD::SRL:
3205 // Short: ShAmt < NVTBits
3206 HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
3207 LoS = DAG.getNode(ISD::OR, dl, NVT,
3208 DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
3209 // FIXME: If Amt is zero, the following shift generates an undefined result
3210 // on some architectures.
3211 DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
3212
3213 // Long: ShAmt >= NVTBits
3214 HiL = DAG.getConstant(0, dl, NVT); // Hi part is zero.
3215 LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part.
3216
3217 Lo = DAG.getSelect(dl, NVT, isZero, InL,
3218 DAG.getSelect(dl, NVT, isShort, LoS, LoL));
3219 Hi = DAG.getSelect(dl, NVT, isShort, HiS, HiL);
3220 return true;
3221 case ISD::SRA:
3222 // Short: ShAmt < NVTBits
3223 HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
3224 LoS = DAG.getNode(ISD::OR, dl, NVT,
3225 DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
3226 DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
3227
3228 // Long: ShAmt >= NVTBits
3229 HiL = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign of Hi part.
3230 DAG.getConstant(NVTBits - 1, dl, ShTy));
3231 LoL = DAG.getNode(ISD::SRA, dl, NVT, InH, AmtExcess); // Lo from Hi part.
3232
3233 Lo = DAG.getSelect(dl, NVT, isZero, InL,
3234 DAG.getSelect(dl, NVT, isShort, LoS, LoL));
3235 Hi = DAG.getSelect(dl, NVT, isShort, HiS, HiL);
3236 return true;
3237 }
3238}
3239
3240static std::pair<ISD::CondCode, ISD::NodeType> getExpandedMinMaxOps(int Op) {
3241
3242 switch (Op) {
3243 default: llvm_unreachable("invalid min/max opcode");
3244 case ISD::SMAX:
3245 return std::make_pair(ISD::SETGT, ISD::UMAX);
3246 case ISD::UMAX:
3247 return std::make_pair(ISD::SETUGT, ISD::UMAX);
3248 case ISD::SMIN:
3249 return std::make_pair(ISD::SETLT, ISD::UMIN);
3250 case ISD::UMIN:
3251 return std::make_pair(ISD::SETULT, ISD::UMIN);
3252 }
3253}
3254
3255void DAGTypeLegalizer::ExpandIntRes_MINMAX(SDNode *N,
3256 SDValue &Lo, SDValue &Hi) {
3257 SDLoc DL(N);
3258
3259 SDValue LHS = N->getOperand(0);
3260 SDValue RHS = N->getOperand(1);
3261
3262 // If the upper halves are all sign bits, then we can perform the MINMAX on
3263 // the lower half and sign-extend the result to the upper half.
3264 unsigned NumBits = N->getValueType(0).getScalarSizeInBits();
3265 unsigned NumHalfBits = NumBits / 2;
3266 if (DAG.ComputeNumSignBits(LHS) > NumHalfBits &&
3267 DAG.ComputeNumSignBits(RHS) > NumHalfBits) {
3268 SDValue LHSL, LHSH, RHSL, RHSH;
3269 GetExpandedInteger(LHS, LHSL, LHSH);
3270 GetExpandedInteger(RHS, RHSL, RHSH);
3271 EVT NVT = LHSL.getValueType();
3272
3273 Lo = DAG.getNode(N->getOpcode(), DL, NVT, LHSL, RHSL);
3274 Hi = DAG.getNode(ISD::SRA, DL, NVT, Lo,
3275 DAG.getShiftAmountConstant(NumHalfBits - 1, NVT, DL));
3276 return;
3277 }
3278
3279 // The Lo of smin(X, -1) is LHSL if X is negative. Otherwise it's -1.
3280 // The Lo of smax(X, 0) is 0 if X is negative. Otherwise it's LHSL.
3281 if ((N->getOpcode() == ISD::SMAX && isNullConstant(RHS)) ||
3282 (N->getOpcode() == ISD::SMIN && isAllOnesConstant(RHS))) {
3283 SDValue LHSL, LHSH, RHSL, RHSH;
3284 GetExpandedInteger(LHS, LHSL, LHSH);
3285 GetExpandedInteger(RHS, RHSL, RHSH);
3286 EVT NVT = LHSL.getValueType();
3287 EVT CCT = getSetCCResultType(NVT);
3288
3289 SDValue HiNeg =
3290 DAG.getSetCC(DL, CCT, LHSH, DAG.getConstant(0, DL, NVT), ISD::SETLT);
3291 if (N->getOpcode() == ISD::SMIN) {
3292 Lo = DAG.getSelect(DL, NVT, HiNeg, LHSL, DAG.getConstant(-1, DL, NVT));
3293 } else {
3294 Lo = DAG.getSelect(DL, NVT, HiNeg, DAG.getConstant(0, DL, NVT), LHSL);
3295 }
3296 Hi = DAG.getNode(N->getOpcode(), DL, NVT, {LHSH, RHSH});
3297 return;
3298 }
3299
3300 const APInt *RHSVal = nullptr;
3301 if (auto *RHSConst = dyn_cast<ConstantSDNode>(RHS))
3302 RHSVal = &RHSConst->getAPIntValue();
3303
3304 // The high half of MIN/MAX is always just the the MIN/MAX of the
3305 // high halves of the operands. Expand this way if it appears profitable.
3306 if (RHSVal && (N->getOpcode() == ISD::UMIN || N->getOpcode() == ISD::UMAX) &&
3307 (RHSVal->countLeadingOnes() >= NumHalfBits ||
3308 RHSVal->countLeadingZeros() >= NumHalfBits)) {
3309 SDValue LHSL, LHSH, RHSL, RHSH;
3310 GetExpandedInteger(LHS, LHSL, LHSH);
3311 GetExpandedInteger(RHS, RHSL, RHSH);
3312 EVT NVT = LHSL.getValueType();
3313 EVT CCT = getSetCCResultType(NVT);
3314
3315 ISD::NodeType LoOpc;
3316 ISD::CondCode CondC;
3317 std::tie(CondC, LoOpc) = getExpandedMinMaxOps(N->getOpcode());
3318
3319 Hi = DAG.getNode(N->getOpcode(), DL, NVT, {LHSH, RHSH});
3320 // We need to know whether to select Lo part that corresponds to 'winning'
3321 // Hi part or if Hi parts are equal.
3322 SDValue IsHiLeft = DAG.getSetCC(DL, CCT, LHSH, RHSH, CondC);
3323 SDValue IsHiEq = DAG.getSetCC(DL, CCT, LHSH, RHSH, ISD::SETEQ);
3324
3325 // Lo part corresponding to the 'winning' Hi part
3326 SDValue LoCmp = DAG.getSelect(DL, NVT, IsHiLeft, LHSL, RHSL);
3327
3328 // Recursed Lo part if Hi parts are equal, this uses unsigned version
3329 SDValue LoMinMax = DAG.getNode(LoOpc, DL, NVT, {LHSL, RHSL});
3330
3331 Lo = DAG.getSelect(DL, NVT, IsHiEq, LoMinMax, LoCmp);
3332 return;
3333 }
3334
3335 // Expand to "a < b ? a : b" etc. Prefer ge/le if that simplifies
3336 // the compare.
3337 ISD::CondCode Pred;
3338 switch (N->getOpcode()) {
3339 default: llvm_unreachable("How did we get here?");
3340 case ISD::SMAX:
3341 if (RHSVal && RHSVal->countTrailingZeros() >= NumHalfBits)
3342 Pred = ISD::SETGE;
3343 else
3344 Pred = ISD::SETGT;
3345 break;
3346 case ISD::SMIN:
3347 if (RHSVal && RHSVal->countTrailingOnes() >= NumHalfBits)
3348 Pred = ISD::SETLE;
3349 else
3350 Pred = ISD::SETLT;
3351 break;
3352 case ISD::UMAX:
3353 if (RHSVal && RHSVal->countTrailingZeros() >= NumHalfBits)
3354 Pred = ISD::SETUGE;
3355 else
3356 Pred = ISD::SETUGT;
3357 break;
3358 case ISD::UMIN:
3359 if (RHSVal && RHSVal->countTrailingOnes() >= NumHalfBits)
3360 Pred = ISD::SETULE;
3361 else
3362 Pred = ISD::SETULT;
3363 break;
3364 }
3365 EVT VT = N->getValueType(0);
3366 EVT CCT = getSetCCResultType(VT);
3367 SDValue Cond = DAG.getSetCC(DL, CCT, LHS, RHS, Pred);
3368 SDValue Result = DAG.getSelect(DL, VT, Cond, LHS, RHS);
3369 SplitInteger(Result, Lo, Hi);
3370}
3371
3372void DAGTypeLegalizer::ExpandIntRes_CMP(SDNode *N, SDValue &Lo, SDValue &Hi) {
3373 SDValue ExpandedCMP = TLI.expandCMP(N, DAG);
3374 SplitInteger(ExpandedCMP, Lo, Hi);
3375}
3376
3377void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
3378 SDValue &Lo, SDValue &Hi) {
3379 SDLoc dl(N);
3380 // Expand the subcomponents.
3381 SDValue LHSL, LHSH, RHSL, RHSH;
3382 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3383 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3384
3385 EVT NVT = LHSL.getValueType();
3386 SDValue LoOps[2] = { LHSL, RHSL };
3387 SDValue HiOps[3] = { LHSH, RHSH };
3388
3389 bool HasOpCarry = TLI.isOperationLegalOrCustom(
3390 N->getOpcode() == ISD::ADD ? ISD::UADDO_CARRY : ISD::USUBO_CARRY,
3391 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
3392 if (HasOpCarry) {
3393 SDVTList VTList = DAG.getVTList(NVT, getSetCCResultType(NVT));
3394 if (N->getOpcode() == ISD::ADD) {
3395 Lo = DAG.getNode(ISD::UADDO, dl, VTList, LoOps);
3396 HiOps[2] = Lo.getValue(1);
3397 Hi = DAG.computeKnownBits(HiOps[2]).isZero()
3398 ? DAG.getNode(ISD::UADDO, dl, VTList, ArrayRef(HiOps, 2))
3399 : DAG.getNode(ISD::UADDO_CARRY, dl, VTList, HiOps);
3400 } else {
3401 Lo = DAG.getNode(ISD::USUBO, dl, VTList, LoOps);
3402 HiOps[2] = Lo.getValue(1);
3403 Hi = DAG.computeKnownBits(HiOps[2]).isZero()
3404 ? DAG.getNode(ISD::USUBO, dl, VTList, ArrayRef(HiOps, 2))
3405 : DAG.getNode(ISD::USUBO_CARRY, dl, VTList, HiOps);
3406 }
3407 return;
3408 }
3409
3410 // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support
3411 // them. TODO: Teach operation legalization how to expand unsupported
3412 // ADDC/ADDE/SUBC/SUBE. The problem is that these operations generate
3413 // a carry of type MVT::Glue, but there doesn't seem to be any way to
3414 // generate a value of this type in the expanded code sequence.
3415 bool hasCarry =
3416 TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
3418 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
3419
3420 if (hasCarry) {
3421 SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
3422 if (N->getOpcode() == ISD::ADD) {
3423 Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps);
3424 HiOps[2] = Lo.getValue(1);
3425 Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps);
3426 } else {
3427 Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps);
3428 HiOps[2] = Lo.getValue(1);
3429 Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps);
3430 }
3431 return;
3432 }
3433
3434 bool hasOVF =
3435 TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
3437 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
3439
3440 if (hasOVF) {
3441 EVT OvfVT = getSetCCResultType(NVT);
3442 SDVTList VTList = DAG.getVTList(NVT, OvfVT);
3443 int RevOpc;
3444 if (N->getOpcode() == ISD::ADD) {
3445 RevOpc = ISD::SUB;
3446 Lo = DAG.getNode(ISD::UADDO, dl, VTList, LoOps);
3447 Hi = DAG.getNode(ISD::ADD, dl, NVT, ArrayRef(HiOps, 2));
3448 } else {
3449 RevOpc = ISD::ADD;
3450 Lo = DAG.getNode(ISD::USUBO, dl, VTList, LoOps);
3451 Hi = DAG.getNode(ISD::SUB, dl, NVT, ArrayRef(HiOps, 2));
3452 }
3453 SDValue OVF = Lo.getValue(1);
3454
3455 switch (BoolType) {
3457 OVF = DAG.getNode(ISD::AND, dl, OvfVT, DAG.getConstant(1, dl, OvfVT), OVF);
3458 [[fallthrough]];
3460 OVF = DAG.getZExtOrTrunc(OVF, dl, NVT);
3461 Hi = DAG.getNode(N->getOpcode(), dl, NVT, Hi, OVF);
3462 break;
3464 OVF = DAG.getSExtOrTrunc(OVF, dl, NVT);
3465 Hi = DAG.getNode(RevOpc, dl, NVT, Hi, OVF);
3466 }
3467 return;
3468 }
3469
3470 if (N->getOpcode() == ISD::ADD) {
3471 Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps);
3472 Hi = DAG.getNode(ISD::ADD, dl, NVT, ArrayRef(HiOps, 2));
3473 SDValue Cmp;
3474 // Special case: X+1 has a carry out if X+1==0. This may reduce the live
3475 // range of X. We assume comparing with 0 is cheap.
3476 if (isOneConstant(LoOps[1]))
3477 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo,
3478 DAG.getConstant(0, dl, NVT), ISD::SETEQ);
3479 else if (isAllOnesConstant(LoOps[1])) {
3480 if (isAllOnesConstant(HiOps[1]))
3481 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), LoOps[0],
3482 DAG.getConstant(0, dl, NVT), ISD::SETEQ);
3483 else
3484 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), LoOps[0],
3485 DAG.getConstant(0, dl, NVT), ISD::SETNE);
3486 } else
3487 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo, LoOps[0],
3488 ISD::SETULT);
3489
3490 SDValue Carry;
3492 Carry = DAG.getZExtOrTrunc(Cmp, dl, NVT);
3493 else
3494 Carry = DAG.getSelect(dl, NVT, Cmp, DAG.getConstant(1, dl, NVT),
3495 DAG.getConstant(0, dl, NVT));
3496
3497 if (isAllOnesConstant(LoOps[1]) && isAllOnesConstant(HiOps[1]))
3498 Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps[0], Carry);
3499 else
3500 Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry);
3501 } else {
3502 Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps);
3503 Hi = DAG.getNode(ISD::SUB, dl, NVT, ArrayRef(HiOps, 2));
3504 SDValue Cmp =
3505 DAG.getSetCC(dl, getSetCCResultType(LoOps[0].getValueType()),
3506 LoOps[0], LoOps[1], ISD::SETULT);
3507
3508 SDValue Borrow;
3510 Borrow = DAG.getZExtOrTrunc(Cmp, dl, NVT);
3511 else
3512 Borrow = DAG.getSelect(dl, NVT, Cmp, DAG.getConstant(1, dl, NVT),
3513 DAG.getConstant(0, dl, NVT));
3514
3515 Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
3516 }
3517}
3518
3519void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
3520 SDValue &Lo, SDValue &Hi) {
3521 // Expand the subcomponents.
3522 SDValue LHSL, LHSH, RHSL, RHSH;
3523 SDLoc dl(N);
3524 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3525 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3526 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
3527 SDValue LoOps[2] = { LHSL, RHSL };
3528 SDValue HiOps[3] = { LHSH, RHSH };
3529
3530 if (N->getOpcode() == ISD::ADDC) {
3531 Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps);
3532 HiOps[2] = Lo.getValue(1);
3533 Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps);
3534 } else {
3535 Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps);
3536 HiOps[2] = Lo.getValue(1);
3537 Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps);
3538 }
3539
3540 // Legalized the flag result - switch anything that used the old flag to
3541 // use the new one.
3542 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
3543}
3544
3545void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
3546 SDValue &Lo, SDValue &Hi) {
3547 // Expand the subcomponents.
3548 SDValue LHSL, LHSH, RHSL, RHSH;
3549 SDLoc dl(N);
3550 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3551 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3552 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
3553 SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
3554 SDValue HiOps[3] = { LHSH, RHSH };
3555
3556 Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps);
3557 HiOps[2] = Lo.getValue(1);
3558 Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps);
3559
3560 // Legalized the flag result - switch anything that used the old flag to
3561 // use the new one.
3562 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
3563}
3564
3565void DAGTypeLegalizer::ExpandIntRes_UADDSUBO(SDNode *N,
3566 SDValue &Lo, SDValue &Hi) {
3567 SDValue LHS = N->getOperand(0);
3568 SDValue RHS = N->getOperand(1);
3569 SDLoc dl(N);
3570
3571 SDValue Ovf;
3572
3573 unsigned CarryOp, NoCarryOp;
3575 switch(N->getOpcode()) {
3576 case ISD::UADDO:
3577 CarryOp = ISD::UADDO_CARRY;
3578 NoCarryOp = ISD::ADD;
3579 Cond = ISD::SETULT;
3580 break;
3581 case ISD::USUBO:
3582 CarryOp = ISD::USUBO_CARRY;
3583 NoCarryOp = ISD::SUB;
3584 Cond = ISD::SETUGT;
3585 break;
3586 default:
3587 llvm_unreachable("Node has unexpected Opcode");
3588 }
3589
3590 bool HasCarryOp = TLI.isOperationLegalOrCustom(
3591 CarryOp, TLI.getTypeToExpandTo(*DAG.getContext(), LHS.getValueType()));
3592
3593 if (HasCarryOp) {
3594 // Expand the subcomponents.
3595 SDValue LHSL, LHSH, RHSL, RHSH;
3596 GetExpandedInteger(LHS, LHSL, LHSH);
3597 GetExpandedInteger(RHS, RHSL, RHSH);
3598 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
3599 SDValue LoOps[2] = { LHSL, RHSL };
3600 SDValue HiOps[3] = { LHSH, RHSH };
3601
3602 Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps);
3603 HiOps[2] = Lo.getValue(1);
3604 Hi = DAG.getNode(CarryOp, dl, VTList, HiOps);
3605
3606 Ovf = Hi.getValue(1);
3607 } else {
3608 // Expand the result by simply replacing it with the equivalent
3609 // non-overflow-checking operation.
3610 SDValue Sum = DAG.getNode(NoCarryOp, dl, LHS.getValueType(), LHS, RHS);
3611 SplitInteger(Sum, Lo, Hi);
3612
3613 if (N->getOpcode() == ISD::UADDO && isOneConstant(RHS)) {
3614 // Special case: uaddo X, 1 overflowed if X+1 == 0. We can detect this
3615 // with (Lo | Hi) == 0.
3616 SDValue Or = DAG.getNode(ISD::OR, dl, Lo.getValueType(), Lo, Hi);
3617 Ovf = DAG.getSetCC(dl, N->getValueType(1), Or,
3618 DAG.getConstant(0, dl, Lo.getValueType()), ISD::SETEQ);
3619 } else if (N->getOpcode() == ISD::UADDO && isAllOnesConstant(RHS)) {
3620 // Special case: uaddo X, -1 overflows if X == 0.
3621 Ovf =
3622 DAG.getSetCC(dl, N->getValueType(1), LHS,
3623 DAG.getConstant(0, dl, LHS.getValueType()), ISD::SETNE);
3624 } else {
3625 // Calculate the overflow: addition overflows iff a + b < a, and
3626 // subtraction overflows iff a - b > a.
3627 Ovf = DAG.getSetCC(dl, N->getValueType(1), Sum, LHS, Cond);
3628 }
3629 }
3630
3631 // Legalized the flag result - switch anything that used the old flag to
3632 // use the new one.
3633 ReplaceValueWith(SDValue(N, 1), Ovf);
3634}
3635
3636void DAGTypeLegalizer::ExpandIntRes_UADDSUBO_CARRY(SDNode *N, SDValue &Lo,
3637 SDValue &Hi) {
3638 // Expand the subcomponents.
3639 SDValue LHSL, LHSH, RHSL, RHSH;
3640 SDLoc dl(N);
3641 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3642 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3643 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
3644 SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
3645 SDValue HiOps[3] = { LHSH, RHSH, SDValue() };
3646
3647 Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps);
3648 HiOps[2] = Lo.getValue(1);
3649 Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps);
3650
3651 // Legalized the flag result - switch anything that used the old flag to
3652 // use the new one.
3653 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
3654}
3655
3656void DAGTypeLegalizer::ExpandIntRes_SADDSUBO_CARRY(SDNode *N,
3657 SDValue &Lo, SDValue &Hi) {
3658 // Expand the subcomponents.
3659 SDValue LHSL, LHSH, RHSL, RHSH;
3660 SDLoc dl(N);
3661 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3662 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3663 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
3664
3665 // We need to use an unsigned carry op for the lo part.
3666 unsigned CarryOp =
3668 Lo = DAG.getNode(CarryOp, dl, VTList, { LHSL, RHSL, N->getOperand(2) });
3669 Hi = DAG.getNode(N->getOpcode(), dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
3670
3671 // Legalized the flag result - switch anything that used the old flag to
3672 // use the new one.
3673 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
3674}
3675
3676void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
3677 SDValue &Lo, SDValue &Hi) {
3678 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3679 SDLoc dl(N);
3680 SDValue Op = N->getOperand(0);
3681 if (Op.getValueType().bitsLE(NVT)) {
3682 // The low part is any extension of the input (which degenerates to a copy).
3683 Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op);
3684 Hi = DAG.getUNDEF(NVT); // The high part is undefined.
3685 } else {
3686 // For example, extension of an i48 to an i64. The operand type necessarily
3687 // promotes to the result type, so will end up being expanded too.
3688 assert(getTypeAction(Op.getValueType()) ==
3690 "Only know how to promote this result!");
3691 SDValue Res = GetPromotedInteger(Op);
3692 assert(Res.getValueType() == N->getValueType(0) &&
3693 "Operand over promoted?");
3694 // Split the promoted operand. This will simplify when it is expanded.
3695 SplitInteger(Res, Lo, Hi);
3696 }
3697}
3698
3699void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
3700 SDValue &Lo, SDValue &Hi) {
3701 SDLoc dl(N);
3702 GetExpandedInteger(N->getOperand(0), Lo, Hi);
3703 EVT NVT = Lo.getValueType();
3704 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
3705 unsigned NVTBits = NVT.getSizeInBits();
3706 unsigned EVTBits = EVT.getSizeInBits();
3707
3708 if (NVTBits < EVTBits) {
3709 Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi,
3711 EVTBits - NVTBits)));
3712 } else {
3713 Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
3714 // The high part replicates the sign bit of Lo, make it explicit.
3715 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
3716 DAG.getConstant(NVTBits - 1, dl,
3717 TLI.getPointerTy(DAG.getDataLayout())));
3718 }
3719}
3720
3721void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
3722 SDValue &Lo, SDValue &Hi) {
3723 SDLoc dl(N);
3724 GetExpandedInteger(N->getOperand(0), Lo, Hi);
3725 EVT NVT = Lo.getValueType();
3726 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
3727 unsigned NVTBits = NVT.getSizeInBits();
3728 unsigned EVTBits = EVT.getSizeInBits();
3729
3730 if (NVTBits < EVTBits) {
3731 Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi,
3733 EVTBits - NVTBits)));
3734 } else {
3735 Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT));
3736 // The high part must be zero, make it explicit.
3737 Hi = DAG.getConstant(0, dl, NVT);
3738 }
3739}
3740
3741void DAGTypeLegalizer::ExpandIntRes_BITREVERSE(SDNode *N,
3742 SDValue &Lo, SDValue &Hi) {
3743 SDLoc dl(N);
3744 GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands.
3745 Lo = DAG.getNode(ISD::BITREVERSE, dl, Lo.getValueType(), Lo);
3746 Hi = DAG.getNode(ISD::BITREVERSE, dl, Hi.getValueType(), Hi);
3747}
3748
3749void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
3750 SDValue &Lo, SDValue &Hi) {
3751 SDLoc dl(N);
3752 GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands.
3753 Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo);
3754 Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
3755}
3756
3757void DAGTypeLegalizer::ExpandIntRes_PARITY(SDNode *N, SDValue &Lo,
3758 SDValue &Hi) {
3759 SDLoc dl(N);
3760 // parity(HiLo) -> parity(Lo^Hi)
3761 GetExpandedInteger(N->getOperand(0), Lo, Hi);
3762 EVT NVT = Lo.getValueType();
3763 Lo =
3764 DAG.getNode(ISD::PARITY, dl, NVT, DAG.getNode(ISD::XOR, dl, NVT, Lo, Hi));
3765 Hi = DAG.getConstant(0, dl, NVT);
3766}
3767
3768void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
3769 SDValue &Lo, SDValue &Hi) {
3770 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3771 unsigned NBitWidth = NVT.getSizeInBits();
3772 auto Constant = cast<ConstantSDNode>(N);
3773 const APInt &Cst = Constant->getAPIntValue();
3774 bool IsTarget = Constant->isTargetOpcode();
3775 bool IsOpaque = Constant->isOpaque();
3776 SDLoc dl(N);
3777 Lo = DAG.getConstant(Cst.trunc(NBitWidth), dl, NVT, IsTarget, IsOpaque);
3778 Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), dl, NVT, IsTarget,
3779 IsOpaque);
3780}
3781
3782void DAGTypeLegalizer::ExpandIntRes_ABS(SDNode *N, SDValue &Lo, SDValue &Hi) {
3783 SDLoc dl(N);
3784
3785 SDValue N0 = N->getOperand(0);
3786 GetExpandedInteger(N0, Lo, Hi);
3787 EVT NVT = Lo.getValueType();
3788
3789 // If the upper half is all sign bits, then we can perform the ABS on the
3790 // lower half and zero-extend.
3791 if (DAG.ComputeNumSignBits(N0) > NVT.getScalarSizeInBits()) {
3792 Lo = DAG.getNode(ISD::ABS, dl, NVT, Lo);
3793 Hi = DAG.getConstant(0, dl, NVT);
3794 return;
3795 }
3796
3797 // If we have USUBO_CARRY, use the expanded form of the sra+xor+sub sequence
3798 // we use in LegalizeDAG. The SUB part of the expansion is based on
3799 // ExpandIntRes_ADDSUB which also uses USUBO_CARRY/USUBO after checking that
3800 // USUBO_CARRY is LegalOrCustom. Each of the pieces here can be further
3801 // expanded if needed. Shift expansion has a special case for filling with
3802 // sign bits so that we will only end up with one SRA.
3803 bool HasSubCarry = TLI.isOperationLegalOrCustom(
3805 if (HasSubCarry) {
3806 SDValue Sign = DAG.getNode(
3807 ISD::SRA, dl, NVT, Hi,
3808 DAG.getShiftAmountConstant(NVT.getSizeInBits() - 1, NVT, dl));
3809 SDVTList VTList = DAG.getVTList(NVT, getSetCCResultType(NVT));
3810 Lo = DAG.getNode(ISD::XOR, dl, NVT, Lo, Sign);
3811 Hi = DAG.getNode(ISD::XOR, dl, NVT, Hi, Sign);
3812 Lo = DAG.getNode(ISD::USUBO, dl, VTList, Lo, Sign);
3813 Hi = DAG.getNode(ISD::USUBO_CARRY, dl, VTList, Hi, Sign, Lo.getValue(1));
3814 return;
3815 }
3816
3817 // abs(HiLo) -> (Hi < 0 ? -HiLo : HiLo)
3818 EVT VT = N->getValueType(0);
3819 SDValue Neg = DAG.getNode(ISD::SUB, dl, VT,
3820 DAG.getConstant(0, dl, VT), N0);
3821 SDValue NegLo, NegHi;
3822 SplitInteger(Neg, NegLo, NegHi);
3823
3824 SDValue HiIsNeg = DAG.getSetCC(dl, getSetCCResultType(NVT), Hi,
3825 DAG.getConstant(0, dl, NVT), ISD::SETLT);
3826 Lo = DAG.getSelect(dl, NVT, HiIsNeg, NegLo, Lo);
3827 Hi = DAG.getSelect(dl, NVT, HiIsNeg, NegHi, Hi);
3828}
3829
3830void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
3831 SDValue &Lo, SDValue &Hi) {
3832 SDLoc dl(N);
3833 // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
3834 GetExpandedInteger(N->getOperand(0), Lo, Hi);
3835 EVT NVT = Lo.getValueType();
3836
3837 SDValue HiNotZero = DAG.getSetCC(dl, getSetCCResultType(NVT), Hi,
3838 DAG.getConstant(0, dl, NVT), ISD::SETNE);
3839
3840 SDValue LoLZ = DAG.getNode(N->getOpcode(), dl, NVT, Lo);
3841 SDValue HiLZ = DAG.getNode(ISD::CTLZ_ZERO_UNDEF, dl, NVT, Hi);
3842
3843 Lo = DAG.getSelect(dl, NVT, HiNotZero, HiLZ,
3844 DAG.getNode(ISD::ADD, dl, NVT, LoLZ,
3845 DAG.getConstant(NVT.getSizeInBits(), dl,
3846 NVT)));
3847 Hi = DAG.getConstant(0, dl, NVT);
3848}
3849
3850void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
3851 SDValue &Lo, SDValue &Hi) {
3852 SDLoc dl(N);
3853 // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
3854 GetExpandedInteger(N->getOperand(0), Lo, Hi);
3855 EVT NVT = Lo.getValueType();
3856 Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, dl, NVT, Lo),
3857 DAG.getNode(ISD::CTPOP, dl, NVT, Hi));
3858 Hi = DAG.getConstant(0, dl, NVT);
3859}
3860
3861void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
3862 SDValue &Lo, SDValue &Hi) {
3863 SDLoc dl(N);
3864 // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
3865 GetExpandedInteger(N->getOperand(0), Lo, Hi);
3866 EVT NVT = Lo.getValueType();
3867
3868 SDValue LoNotZero = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo,
3869 DAG.getConstant(0, dl, NVT), ISD::SETNE);
3870
3871 SDValue LoLZ = DAG.getNode(ISD::CTTZ_ZERO_UNDEF, dl, NVT, Lo);
3872 SDValue HiLZ = DAG.getNode(N->getOpcode(), dl, NVT, Hi);
3873
3874 Lo = DAG.getSelect(dl, NVT, LoNotZero, LoLZ,
3875 DAG.getNode(ISD::ADD, dl, NVT, HiLZ,
3876 DAG.getConstant(NVT.getSizeInBits(), dl,
3877 NVT)));
3878 Hi = DAG.getConstant(0, dl, NVT);
3879}
3880
3881void DAGTypeLegalizer::ExpandIntRes_GET_ROUNDING(SDNode *N, SDValue &Lo,
3882 SDValue &Hi) {
3883 SDLoc dl(N);
3884 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3885 unsigned NBitWidth = NVT.getSizeInBits();
3886
3887 Lo = DAG.getNode(ISD::GET_ROUNDING, dl, {NVT, MVT::Other}, N->getOperand(0));
3888 SDValue Chain = Lo.getValue(1);
3889 // The high part is the sign of Lo, as -1 is a valid value for GET_ROUNDING
3890 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
3891 DAG.getShiftAmountConstant(NBitWidth - 1, NVT, dl));
3892
3893 // Legalize the chain result - switch anything that used the old chain to
3894 // use the new one.
3895 ReplaceValueWith(SDValue(N, 1), Chain);
3896}
3897
3898// Helper for producing an FP_EXTEND/STRICT_FP_EXTEND of Op.
3899static SDValue fpExtendHelper(SDValue Op, SDValue &Chain, bool IsStrict, EVT VT,
3900 SDLoc DL, SelectionDAG &DAG) {
3901 if (IsStrict) {
3902 Op = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {VT, MVT::Other}, {Chain, Op});
3903 Chain = Op.getValue(1);
3904 return Op;
3905 }
3906 return DAG.getNode(ISD::FP_EXTEND, DL, VT, Op);
3907}
3908
3909void DAGTypeLegalizer::ExpandIntRes_FP_TO_XINT(SDNode *N, SDValue &Lo,
3910 SDValue &Hi) {
3911 SDLoc dl(N);
3912 EVT VT = N->getValueType(0);
3913
3914 bool IsSigned = N->getOpcode() == ISD::FP_TO_SINT ||
3915 N->getOpcode() == ISD::STRICT_FP_TO_SINT;
3916 bool IsStrict = N->isStrictFPOpcode();
3917 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
3918 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
3919 if (getTypeAction(Op.getValueType()) == TargetLowering::TypePromoteFloat)
3920 Op = GetPromotedFloat(Op);
3921
3922 if (getTypeAction(Op.getValueType()) == TargetLowering::TypeSoftPromoteHalf) {
3923 EVT OFPVT = Op.getValueType();
3924 EVT NFPVT = TLI.getTypeToTransformTo(*DAG.getContext(), OFPVT);
3925 Op = GetSoftPromotedHalf(Op);
3926 Op = DAG.getNode(OFPVT == MVT::f16 ? ISD::FP16_TO_FP : ISD::BF16_TO_FP, dl,
3927 NFPVT, Op);
3928 Op = DAG.getNode(IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT, dl, VT, Op);
3929 SplitInteger(Op, Lo, Hi);
3930 return;
3931 }
3932
3933 if (Op.getValueType() == MVT::bf16) {
3934 // Extend to f32 as there is no bf16 libcall.
3935 Op = fpExtendHelper(Op, Chain, IsStrict, MVT::f32, dl, DAG);
3936 }
3937
3938 RTLIB::Libcall LC = IsSigned ? RTLIB::getFPTOSINT(Op.getValueType(), VT)
3939 : RTLIB::getFPTOUINT(Op.getValueType(), VT);
3940 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-xint conversion!");
3942 CallOptions.setSExt(true);
3943 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, VT, Op,
3944 CallOptions, dl, Chain);
3945 SplitInteger(Tmp.first, Lo, Hi);
3946
3947 if (IsStrict)
3948 ReplaceValueWith(SDValue(N, 1), Tmp.second);
3949}
3950
3951void DAGTypeLegalizer::ExpandIntRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo,
3952 SDValue &Hi) {
3953 SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
3954 SplitInteger(Res, Lo, Hi);
3955}
3956
3957void DAGTypeLegalizer::ExpandIntRes_XROUND_XRINT(SDNode *N, SDValue &Lo,
3958 SDValue &Hi) {
3959 SDLoc dl(N);
3960 bool IsStrict = N->isStrictFPOpcode();
3961 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
3962 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
3963
3964 assert(getTypeAction(Op.getValueType()) != TargetLowering::TypePromoteFloat &&
3965 "Input type needs to be promoted!");
3966
3967 EVT VT = Op.getValueType();
3968
3969 if (VT == MVT::f16) {
3970 // Extend to f32.
3971 VT = MVT::f32;
3972 Op = fpExtendHelper(Op, Chain, IsStrict, VT, dl, DAG);
3973 }
3974
3975 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
3976 if (N->getOpcode() == ISD::LROUND ||
3977 N->getOpcode() == ISD::STRICT_LROUND) {
3978 if (VT == MVT::f32)
3979 LC = RTLIB::LROUND_F32;
3980 else if (VT == MVT::f64)
3981 LC = RTLIB::LROUND_F64;
3982 else if (VT == MVT::f80)
3983 LC = RTLIB::LROUND_F80;
3984 else if (VT == MVT::f128)
3985 LC = RTLIB::LROUND_F128;
3986 else if (VT == MVT::ppcf128)
3987 LC = RTLIB::LROUND_PPCF128;
3988 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected lround input type!");
3989 } else if (N->getOpcode() == ISD::LRINT ||
3990 N->getOpcode() == ISD::STRICT_LRINT) {
3991 if (VT == MVT::f32)
3992 LC = RTLIB::LRINT_F32;
3993 else if (VT == MVT::f64)
3994 LC = RTLIB::LRINT_F64;
3995 else if (VT == MVT::f80)
3996 LC = RTLIB::LRINT_F80;
3997 else if (VT == MVT::f128)
3998 LC = RTLIB::LRINT_F128;
3999 else if (VT == MVT::ppcf128)
4000 LC = RTLIB::LRINT_PPCF128;
4001 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected lrint input type!");
4002 } else if (N->getOpcode() == ISD::LLROUND ||
4003 N->getOpcode() == ISD::STRICT_LLROUND) {
4004 if (VT == MVT::f32)
4005 LC = RTLIB::LLROUND_F32;
4006 else if (VT == MVT::f64)
4007 LC = RTLIB::LLROUND_F64;
4008 else if (VT == MVT::f80)
4009 LC = RTLIB::LLROUND_F80;
4010 else if (VT == MVT::f128)
4011 LC = RTLIB::LLROUND_F128;
4012 else if (VT == MVT::ppcf128)
4013 LC = RTLIB::LLROUND_PPCF128;
4014 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected llround input type!");
4015 } else if (N->getOpcode() == ISD::LLRINT ||
4016 N->getOpcode() == ISD::STRICT_LLRINT) {
4017 if (VT == MVT::f32)
4018 LC = RTLIB::LLRINT_F32;
4019 else if (VT == MVT::f64)
4020 LC = RTLIB::LLRINT_F64;
4021 else if (VT == MVT::f80)
4022 LC = RTLIB::LLRINT_F80;
4023 else if (VT == MVT::f128)
4024 LC = RTLIB::LLRINT_F128;
4025 else if (VT == MVT::ppcf128)
4026 LC = RTLIB::LLRINT_PPCF128;
4027 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected llrint input type!");
4028 } else
4029 llvm_unreachable("Unexpected opcode!");
4030
4031 EVT RetVT = N->getValueType(0);
4032
4034 CallOptions.setSExt(true);
4035 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RetVT,
4036 Op, CallOptions, dl,
4037 Chain);
4038 SplitInteger(Tmp.first, Lo, Hi);
4039
4040 if (N->isStrictFPOpcode())
4041 ReplaceValueWith(SDValue(N, 1), Tmp.second);
4042}
4043
4044void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
4045 SDValue &Lo, SDValue &Hi) {
4046 assert(!N->isAtomic() && "Should have been a ATOMIC_LOAD?");
4047
4048 if (ISD::isNormalLoad(N)) {
4049 ExpandRes_NormalLoad(N, Lo, Hi);
4050 return;
4051 }
4052
4053 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
4054
4055 EVT VT = N->getValueType(0);
4056 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4057 SDValue Ch = N->getChain();
4058 SDValue Ptr = N->getBasePtr();
4059 ISD::LoadExtType ExtType = N->getExtensionType();
4060 MachineMemOperand::Flags MMOFlags = N->getMemOperand()->getFlags();
4061 AAMDNodes AAInfo = N->getAAInfo();
4062 SDLoc dl(N);
4063
4064 assert(NVT.isByteSized() && "Expanded type not byte sized!");
4065
4066 if (N->getMemoryVT().bitsLE(NVT)) {
4067 EVT MemVT = N->getMemoryVT();
4068
4069 Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(), MemVT,
4070 N->getOriginalAlign(), MMOFlags, AAInfo);
4071
4072 // Remember the chain.
4073 Ch = Lo.getValue(1);
4074
4075 if (ExtType == ISD::SEXTLOAD) {
4076 // The high part is obtained by SRA'ing all but one of the bits of the
4077 // lo part.
4078 unsigned LoSize = Lo.getValueSizeInBits();
4079 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
4080 DAG.getConstant(LoSize - 1, dl,
4081 TLI.getPointerTy(DAG.getDataLayout())));
4082 } else if (ExtType == ISD::ZEXTLOAD) {
4083 // The high part is just a zero.
4084 Hi = DAG.getConstant(0, dl, NVT);
4085 } else {
4086 assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
4087 // The high part is undefined.
4088 Hi = DAG.getUNDEF(NVT);
4089 }
4090 } else if (DAG.getDataLayout().isLittleEndian()) {
4091 // Little-endian - low bits are at low addresses.
4092 Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getPointerInfo(),
4093 N->getOriginalAlign(), MMOFlags, AAInfo);
4094
4095 unsigned ExcessBits =
4096 N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
4097 EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
4098
4099 // Increment the pointer to the other half.
4100 unsigned IncrementSize = NVT.getSizeInBits()/8;
4101 Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::getFixed(IncrementSize), dl);
4102 Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr,
4103 N->getPointerInfo().getWithOffset(IncrementSize), NEVT,
4104 N->getOriginalAlign(), MMOFlags, AAInfo);
4105
4106 // Build a factor node to remember that this load is independent of the
4107 // other one.
4108 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
4109 Hi.getValue(1));
4110 } else {
4111 // Big-endian - high bits are at low addresses. Favor aligned loads at
4112 // the cost of some bit-fiddling.
4113 EVT MemVT = N->getMemoryVT();
4114 unsigned EBytes = MemVT.getStoreSize();
4115 unsigned IncrementSize = NVT.getSizeInBits()/8;
4116 unsigned ExcessBits = (EBytes - IncrementSize)*8;
4117
4118 // Load both the high bits and maybe some of the low bits.
4119 Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
4121 MemVT.getSizeInBits() - ExcessBits),
4122 N->getOriginalAlign(), MMOFlags, AAInfo);
4123
4124 // Increment the pointer to the other half.
4125 Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::getFixed(IncrementSize), dl);
4126 // Load the rest of the low bits.
4127 Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr,
4128 N->getPointerInfo().getWithOffset(IncrementSize),
4129 EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
4130 N->getOriginalAlign(), MMOFlags, AAInfo);
4131
4132 // Build a factor node to remember that this load is independent of the
4133 // other one.
4134 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
4135 Hi.getValue(1));
4136
4137 if (ExcessBits < NVT.getSizeInBits()) {
4138 // Transfer low bits from the bottom of Hi to the top of Lo.
4139 Lo = DAG.getNode(
4140 ISD::OR, dl, NVT, Lo,
4141 DAG.getNode(ISD::SHL, dl, NVT, Hi,
4142 DAG.getConstant(ExcessBits, dl,
4143 TLI.getPointerTy(DAG.getDataLayout()))));
4144 // Move high bits to the right position in Hi.
4145 Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, NVT,
4146 Hi,
4147 DAG.getConstant(NVT.getSizeInBits() - ExcessBits, dl,
4148 TLI.getPointerTy(DAG.getDataLayout())));
4149 }
4150 }
4151
4152 // Legalize the chain result - switch anything that used the old chain to
4153 // use the new one.
4154 ReplaceValueWith(SDValue(N, 1), Ch);
4155}
4156
4157void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
4158 SDValue &Lo, SDValue &Hi) {
4159 SDLoc dl(N);
4160 SDValue LL, LH, RL, RH;
4161 GetExpandedInteger(N->getOperand(0), LL, LH);
4162 GetExpandedInteger(N->getOperand(1), RL, RH);
4163 Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL);
4164 Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH);
4165}
4166
4167void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
4168 SDValue &Lo, SDValue &Hi) {
4169 EVT VT = N->getValueType(0);
4170 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4171 SDLoc dl(N);
4172
4173 SDValue LL, LH, RL, RH;
4174 GetExpandedInteger(N->getOperand(0), LL, LH);
4175 GetExpandedInteger(N->getOperand(1), RL, RH);
4176
4177 if (TLI.expandMUL(N, Lo, Hi, NVT, DAG,
4179 LL, LH, RL, RH))
4180 return;
4181
4182 // If nothing else, we can make a libcall.
4183 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4184 if (VT == MVT::i16)
4185 LC = RTLIB::MUL_I16;
4186 else if (VT == MVT::i32)
4187 LC = RTLIB::MUL_I32;
4188 else if (VT == MVT::i64)
4189 LC = RTLIB::MUL_I64;
4190 else if (VT == MVT::i128)
4191 LC = RTLIB::MUL_I128;
4192
4193 if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC)) {
4194 // Perform a wide multiplication where the wide type is the original VT and
4195 // the 4 parts are the split arguments.
4196 TLI.forceExpandWideMUL(DAG, dl, /*Signed=*/true, VT, LL, LH, RL, RH, Lo,
4197 Hi);
4198 return;
4199 }
4200
4201 // Note that we don't need to do a wide MUL here since we don't care about the
4202 // upper half of the result if it exceeds VT.
4203 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4205 CallOptions.setSExt(true);
4206 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first,
4207 Lo, Hi);
4208}
4209
4210void DAGTypeLegalizer::ExpandIntRes_READCOUNTER(SDNode *N, SDValue &Lo,
4211 SDValue &Hi) {
4212 SDLoc DL(N);
4213 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4214 SDVTList VTs = DAG.getVTList(NVT, NVT, MVT::Other);
4215 SDValue R = DAG.getNode(N->getOpcode(), DL, VTs, N->getOperand(0));
4216 Lo = R.getValue(0);
4217 Hi = R.getValue(1);
4218 ReplaceValueWith(SDValue(N, 1), R.getValue(2));
4219}
4220
4221void DAGTypeLegalizer::ExpandIntRes_AVG(SDNode *N, SDValue &Lo, SDValue &Hi) {
4222 SDValue Result = TLI.expandAVG(N, DAG);
4223 SplitInteger(Result, Lo, Hi);
4224}
4225
4226void DAGTypeLegalizer::ExpandIntRes_ADDSUBSAT(SDNode *N, SDValue &Lo,
4227 SDValue &Hi) {
4228 SDValue Result = TLI.expandAddSubSat(N, DAG);
4229 SplitInteger(Result, Lo, Hi);
4230}
4231
4232void DAGTypeLegalizer::ExpandIntRes_SHLSAT(SDNode *N, SDValue &Lo,
4233 SDValue &Hi) {
4234 SDValue Result = TLI.expandShlSat(N, DAG);
4235 SplitInteger(Result, Lo, Hi);
4236}
4237
4238/// This performs an expansion of the integer result for a fixed point
4239/// multiplication. The default expansion performs rounding down towards
4240/// negative infinity, though targets that do care about rounding should specify
4241/// a target hook for rounding and provide their own expansion or lowering of
4242/// fixed point multiplication to be consistent with rounding.
4243void DAGTypeLegalizer::ExpandIntRes_MULFIX(SDNode *N, SDValue &Lo,
4244 SDValue &Hi) {
4245 SDLoc dl(N);
4246 EVT VT = N->getValueType(0);
4247 unsigned VTSize = VT.getScalarSizeInBits();
4248 SDValue LHS = N->getOperand(0);
4249 SDValue RHS = N->getOperand(1);
4250 uint64_t Scale = N->getConstantOperandVal(2);
4251 bool Saturating = (N->getOpcode() == ISD::SMULFIXSAT ||
4252 N->getOpcode() == ISD::UMULFIXSAT);
4253 bool Signed = (N->getOpcode() == ISD::SMULFIX ||
4254 N->getOpcode() == ISD::SMULFIXSAT);
4255
4256 // Handle special case when scale is equal to zero.
4257 if (!Scale) {
4259 if (!Saturating) {
4260 Result = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS);
4261 } else {
4262 EVT BoolVT = getSetCCResultType(VT);
4263 unsigned MulOp = Signed ? ISD::SMULO : ISD::UMULO;
4264 Result = DAG.getNode(MulOp, dl, DAG.getVTList(VT, BoolVT), LHS, RHS);
4265 SDValue Product = Result.getValue(0);
4266 SDValue Overflow = Result.getValue(1);
4267 if (Signed) {
4268 APInt MinVal = APInt::getSignedMinValue(VTSize);
4269 APInt MaxVal = APInt::getSignedMaxValue(VTSize);
4270 SDValue SatMin = DAG.getConstant(MinVal, dl, VT);
4271 SDValue SatMax = DAG.getConstant(MaxVal, dl, VT);
4272 SDValue Zero = DAG.getConstant(0, dl, VT);
4273 // Xor the inputs, if resulting sign bit is 0 the product will be
4274 // positive, else negative.
4275 SDValue Xor = DAG.getNode(ISD::XOR, dl, VT, LHS, RHS);
4276 SDValue ProdNeg = DAG.getSetCC(dl, BoolVT, Xor, Zero, ISD::SETLT);
4277 Result = DAG.getSelect(dl, VT, ProdNeg, SatMin, SatMax);
4278 Result = DAG.getSelect(dl, VT, Overflow, Result, Product);
4279 } else {
4280 // For unsigned multiplication, we only need to check the max since we
4281 // can't really overflow towards zero.
4282 APInt MaxVal = APInt::getMaxValue(VTSize);
4283 SDValue SatMax = DAG.getConstant(MaxVal, dl, VT);
4284 Result = DAG.getSelect(dl, VT, Overflow, SatMax, Product);
4285 }
4286 }
4287 SplitInteger(Result, Lo, Hi);
4288 return;
4289 }
4290
4291 // For SMULFIX[SAT] we only expect to find Scale<VTSize, but this assert will
4292 // cover for unhandled cases below, while still being valid for UMULFIX[SAT].
4293 assert(Scale <= VTSize && "Scale can't be larger than the value type size.");
4294
4295 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4296 SDValue LL, LH, RL, RH;
4297 GetExpandedInteger(LHS, LL, LH);
4298 GetExpandedInteger(RHS, RL, RH);
4300
4301 unsigned LoHiOp = Signed ? ISD::SMUL_LOHI : ISD::UMUL_LOHI;
4302 if (!TLI.expandMUL_LOHI(LoHiOp, VT, dl, LHS, RHS, Result, NVT, DAG,
4304 LL, LH, RL, RH)) {
4305 Result.clear();
4306 Result.resize(4);
4307
4308 SDValue LoTmp, HiTmp;
4309 TLI.forceExpandWideMUL(DAG, dl, Signed, LHS, RHS, LoTmp, HiTmp);
4310 SplitInteger(LoTmp, Result[0], Result[1]);
4311 SplitInteger(HiTmp, Result[2], Result[3]);
4312 }
4313 assert(Result.size() == 4 && "Unexpected number of partlets in the result");
4314
4315 unsigned NVTSize = NVT.getScalarSizeInBits();
4316 assert((VTSize == NVTSize * 2) && "Expected the new value type to be half "
4317 "the size of the current value type");
4318
4319 // After getting the multiplication result in 4 parts, we need to perform a
4320 // shift right by the amount of the scale to get the result in that scale.
4321 //
4322 // Let's say we multiply 2 64 bit numbers. The resulting value can be held in
4323 // 128 bits that are cut into 4 32-bit parts:
4324 //
4325 // HH HL LH LL
4326 // |---32---|---32---|---32---|---32---|
4327 // 128 96 64 32 0
4328 //
4329 // |------VTSize-----|
4330 //
4331 // |NVTSize-|
4332 //
4333 // The resulting Lo and Hi would normally be in LL and LH after the shift. But
4334 // to avoid unneccessary shifting of all 4 parts, we can adjust the shift
4335 // amount and get Lo and Hi using two funnel shifts. Or for the special case
4336 // when Scale is a multiple of NVTSize we can just pick the result without
4337 // shifting.
4338 uint64_t Part0 = Scale / NVTSize; // Part holding lowest bit needed.
4339 if (Scale % NVTSize) {
4340 SDValue ShiftAmount = DAG.getShiftAmountConstant(Scale % NVTSize, NVT, dl);
4341 Lo = DAG.getNode(ISD::FSHR, dl, NVT, Result[Part0 + 1], Result[Part0],
4342 ShiftAmount);
4343 Hi = DAG.getNode(ISD::FSHR, dl, NVT, Result[Part0 + 2], Result[Part0 + 1],
4344 ShiftAmount);
4345 } else {
4346 Lo = Result[Part0];
4347 Hi = Result[Part0 + 1];
4348 }
4349
4350 // Unless saturation is requested we are done. The result is in <Hi,Lo>.
4351 if (!Saturating)
4352 return;
4353
4354 // Can not overflow when there is no integer part.
4355 if (Scale == VTSize)
4356 return;
4357
4358 // To handle saturation we must check for overflow in the multiplication.
4359 //
4360 // Unsigned overflow happened if the upper (VTSize - Scale) bits (of Result)
4361 // aren't all zeroes.
4362 //
4363 // Signed overflow happened if the upper (VTSize - Scale + 1) bits (of Result)
4364 // aren't all ones or all zeroes.
4365 //
4366 // We cannot overflow past HH when multiplying 2 ints of size VTSize, so the
4367 // highest bit of HH determines saturation direction in the event of signed
4368 // saturation.
4369
4370 SDValue ResultHL = Result[2];
4371 SDValue ResultHH = Result[3];
4372
4373 SDValue SatMax, SatMin;
4374 SDValue NVTZero = DAG.getConstant(0, dl, NVT);
4375 SDValue NVTNeg1 = DAG.getConstant(-1, dl, NVT);
4376 EVT BoolNVT = getSetCCResultType(NVT);
4377
4378 if (!Signed) {
4379 if (Scale < NVTSize) {
4380 // Overflow happened if ((HH | (HL >> Scale)) != 0).
4381 SDValue HLAdjusted =
4382 DAG.getNode(ISD::SRL, dl, NVT, ResultHL,
4383 DAG.getShiftAmountConstant(Scale, NVT, dl));
4384 SDValue Tmp = DAG.getNode(ISD::OR, dl, NVT, HLAdjusted, ResultHH);
4385 SatMax = DAG.getSetCC(dl, BoolNVT, Tmp, NVTZero, ISD::SETNE);
4386 } else if (Scale == NVTSize) {
4387 // Overflow happened if (HH != 0).
4388 SatMax = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETNE);
4389 } else if (Scale < VTSize) {
4390 // Overflow happened if ((HH >> (Scale - NVTSize)) != 0).
4391 SDValue HLAdjusted =
4392 DAG.getNode(ISD::SRL, dl, NVT, ResultHL,
4393 DAG.getShiftAmountConstant(Scale - NVTSize, NVT, dl));
4394 SatMax = DAG.getSetCC(dl, BoolNVT, HLAdjusted, NVTZero, ISD::SETNE);
4395 } else
4396 llvm_unreachable("Scale must be less or equal to VTSize for UMULFIXSAT"
4397 "(and saturation can't happen with Scale==VTSize).");
4398
4399 Hi = DAG.getSelect(dl, NVT, SatMax, NVTNeg1, Hi);
4400 Lo = DAG.getSelect(dl, NVT, SatMax, NVTNeg1, Lo);
4401 return;
4402 }
4403
4404 if (Scale < NVTSize) {
4405 // The number of overflow bits we can check are VTSize - Scale + 1 (we
4406 // include the sign bit). If these top bits are > 0, then we overflowed past
4407 // the max value. If these top bits are < -1, then we overflowed past the
4408 // min value. Otherwise, we did not overflow.
4409 unsigned OverflowBits = VTSize - Scale + 1;
4410 assert(OverflowBits <= VTSize && OverflowBits > NVTSize &&
4411 "Extent of overflow bits must start within HL");
4412 SDValue HLHiMask = DAG.getConstant(
4413 APInt::getHighBitsSet(NVTSize, OverflowBits - NVTSize), dl, NVT);
4414 SDValue HLLoMask = DAG.getConstant(
4415 APInt::getLowBitsSet(NVTSize, VTSize - OverflowBits), dl, NVT);
4416 // We overflow max if HH > 0 or (HH == 0 && HL > HLLoMask).
4417 SDValue HHGT0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETGT);
4418 SDValue HHEQ0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETEQ);
4419 SDValue HLUGT = DAG.getSetCC(dl, BoolNVT, ResultHL, HLLoMask, ISD::SETUGT);
4420 SatMax = DAG.getNode(ISD::OR, dl, BoolNVT, HHGT0,
4421 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ0, HLUGT));
4422 // We overflow min if HH < -1 or (HH == -1 && HL < HLHiMask).
4423 SDValue HHLT = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETLT);
4424 SDValue HHEQ = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETEQ);
4425 SDValue HLULT = DAG.getSetCC(dl, BoolNVT, ResultHL, HLHiMask, ISD::SETULT);
4426 SatMin = DAG.getNode(ISD::OR, dl, BoolNVT, HHLT,
4427 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ, HLULT));
4428 } else if (Scale == NVTSize) {
4429 // We overflow max if HH > 0 or (HH == 0 && HL sign bit is 1).
4430 SDValue HHGT0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETGT);
4431 SDValue HHEQ0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETEQ);
4432 SDValue HLNeg = DAG.getSetCC(dl, BoolNVT, ResultHL, NVTZero, ISD::SETLT);
4433 SatMax = DAG.getNode(ISD::OR, dl, BoolNVT, HHGT0,
4434 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ0, HLNeg));
4435 // We overflow min if HH < -1 or (HH == -1 && HL sign bit is 0).
4436 SDValue HHLT = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETLT);
4437 SDValue HHEQ = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETEQ);
4438 SDValue HLPos = DAG.getSetCC(dl, BoolNVT, ResultHL, NVTZero, ISD::SETGE);
4439 SatMin = DAG.getNode(ISD::OR, dl, BoolNVT, HHLT,
4440 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ, HLPos));
4441 } else if (Scale < VTSize) {
4442 // This is similar to the case when we saturate if Scale < NVTSize, but we
4443 // only need to check HH.
4444 unsigned OverflowBits = VTSize - Scale + 1;
4445 SDValue HHHiMask = DAG.getConstant(
4446 APInt::getHighBitsSet(NVTSize, OverflowBits), dl, NVT);
4447 SDValue HHLoMask = DAG.getConstant(
4448 APInt::getLowBitsSet(NVTSize, NVTSize - OverflowBits), dl, NVT);
4449 SatMax = DAG.getSetCC(dl, BoolNVT, ResultHH, HHLoMask, ISD::SETGT);
4450 SatMin = DAG.getSetCC(dl, BoolNVT, ResultHH, HHHiMask, ISD::SETLT);
4451 } else
4452 llvm_unreachable("Illegal scale for signed fixed point mul.");
4453
4454 // Saturate to signed maximum.
4455 APInt MaxHi = APInt::getSignedMaxValue(NVTSize);
4456 APInt MaxLo = APInt::getAllOnes(NVTSize);
4457 Hi = DAG.getSelect(dl, NVT, SatMax, DAG.getConstant(MaxHi, dl, NVT), Hi);
4458 Lo = DAG.getSelect(dl, NVT, SatMax, DAG.getConstant(MaxLo, dl, NVT), Lo);
4459 // Saturate to signed minimum.
4460 APInt MinHi = APInt::getSignedMinValue(NVTSize);
4461 Hi = DAG.getSelect(dl, NVT, SatMin, DAG.getConstant(MinHi, dl, NVT), Hi);
4462 Lo = DAG.getSelect(dl, NVT, SatMin, NVTZero, Lo);
4463}
4464
4465void DAGTypeLegalizer::ExpandIntRes_DIVFIX(SDNode *N, SDValue &Lo,
4466 SDValue &Hi) {
4467 SDLoc dl(N);
4468 // Try expanding in the existing type first.
4469 SDValue Res = TLI.expandFixedPointDiv(N->getOpcode(), dl, N->getOperand(0),
4470 N->getOperand(1),
4471 N->getConstantOperandVal(2), DAG);
4472
4473 if (!Res)
4474 Res = earlyExpandDIVFIX(N, N->getOperand(0), N->getOperand(1),
4475 N->getConstantOperandVal(2), TLI, DAG);
4476 SplitInteger(Res, Lo, Hi);
4477}
4478
4479void DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node,
4480 SDValue &Lo, SDValue &Hi) {
4481 assert((Node->getOpcode() == ISD::SADDO || Node->getOpcode() == ISD::SSUBO) &&
4482 "Node has unexpected Opcode");
4483 SDValue LHS = Node->getOperand(0);
4484 SDValue RHS = Node->getOperand(1);
4485 SDLoc dl(Node);
4486
4487 SDValue Ovf;
4488
4489 bool IsAdd = Node->getOpcode() == ISD::SADDO;
4490 unsigned CarryOp = IsAdd ? ISD::SADDO_CARRY : ISD::SSUBO_CARRY;
4491
4492 bool HasCarryOp = TLI.isOperationLegalOrCustom(
4493 CarryOp, TLI.getTypeToExpandTo(*DAG.getContext(), LHS.getValueType()));
4494
4495 if (HasCarryOp) {
4496 // Expand the subcomponents.
4497 SDValue LHSL, LHSH, RHSL, RHSH;
4498 GetExpandedInteger(LHS, LHSL, LHSH);
4499 GetExpandedInteger(RHS, RHSL, RHSH);
4500 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), Node->getValueType(1));
4501
4502 Lo = DAG.getNode(IsAdd ? ISD::UADDO : ISD::USUBO, dl, VTList, {LHSL, RHSL});
4503 Hi = DAG.getNode(CarryOp, dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
4504
4505 Ovf = Hi.getValue(1);
4506 } else {
4507 // Expand the result by simply replacing it with the equivalent
4508 // non-overflow-checking operation.
4509 SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
4510 ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
4511 LHS, RHS);
4512 SplitInteger(Sum, Lo, Hi);
4513
4514 // Compute the overflow.
4515 //
4516 // LHSSign -> LHS < 0
4517 // RHSSign -> RHS < 0
4518 // SumSign -> Sum < 0
4519 //
4520 // Add:
4521 // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
4522 // Sub:
4523 // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
4524 //
4525 // To get better codegen we can rewrite this by doing bitwise math on
4526 // the integers and extract the final sign bit at the end. So the
4527 // above becomes:
4528 //
4529 // Add:
4530 // Overflow -> (~(LHS ^ RHS) & (LHS ^ Sum)) < 0
4531 // Sub:
4532 // Overflow -> ((LHS ^ RHS) & (LHS ^ Sum)) < 0
4533 //
4534 // NOTE: This is different than the expansion we do in expandSADDSUBO
4535 // because it is more costly to determine the RHS is > 0 for SSUBO with the
4536 // integers split.
4537 EVT VT = LHS.getValueType();
4538 SDValue SignsMatch = DAG.getNode(ISD::XOR, dl, VT, LHS, RHS);
4539 if (IsAdd)
4540 SignsMatch = DAG.getNOT(dl, SignsMatch, VT);
4541
4542 SDValue SumSignNE = DAG.getNode(ISD::XOR, dl, VT, LHS, Sum);
4543 Ovf = DAG.getNode(ISD::AND, dl, VT, SignsMatch, SumSignNE);
4544 EVT OType = Node->getValueType(1);
4545 Ovf = DAG.getSetCC(dl, OType, Ovf, DAG.getConstant(0, dl, VT), ISD::SETLT);
4546 }
4547
4548 // Use the calculated overflow everywhere.
4549 ReplaceValueWith(SDValue(Node, 1), Ovf);
4550}
4551
4552void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
4553 SDValue &Lo, SDValue &Hi) {
4554 EVT VT = N->getValueType(0);
4555 SDLoc dl(N);
4556 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4557
4559 SDValue Res = DAG.getNode(ISD::SDIVREM, dl, DAG.getVTList(VT, VT), Ops);
4560 SplitInteger(Res.getValue(0), Lo, Hi);
4561 return;
4562 }
4563
4564 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4565 if (VT == MVT::i16)
4566 LC = RTLIB::SDIV_I16;
4567 else if (VT == MVT::i32)
4568 LC = RTLIB::SDIV_I32;
4569 else if (VT == MVT::i64)
4570 LC = RTLIB::SDIV_I64;
4571 else if (VT == MVT::i128)
4572 LC = RTLIB::SDIV_I128;
4573 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
4574
4576 CallOptions.setSExt(true);
4577 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
4578}
4579
4580void DAGTypeLegalizer::ExpandIntRes_ShiftThroughStack(SDNode *N, SDValue &Lo,
4581 SDValue &Hi) {
4582 SDLoc dl(N);
4583 SDValue Shiftee = N->getOperand(0);
4584 EVT VT = Shiftee.getValueType();
4585 SDValue ShAmt = N->getOperand(1);
4586 EVT ShAmtVT = ShAmt.getValueType();
4587
4588 // This legalization is optimal when the shift is by a multiple of byte width,
4589 // %x * 8 <-> %x << 3 so 3 low bits should be be known zero.
4590 bool ShiftByByteMultiple =
4591 DAG.computeKnownBits(ShAmt).countMinTrailingZeros() >= 3;
4592
4593 // If we can't do it as one step, we'll have two uses of shift amount,
4594 // and thus must freeze it.
4595 if (!ShiftByByteMultiple)
4596 ShAmt = DAG.getFreeze(ShAmt);
4597
4598 unsigned VTBitWidth = VT.getScalarSizeInBits();
4599 assert(VTBitWidth % 8 == 0 && "Shifting a not byte multiple value?");
4600 unsigned VTByteWidth = VTBitWidth / 8;
4601 assert(isPowerOf2_32(VTByteWidth) &&
4602 "Shiftee type size is not a power of two!");
4603 unsigned StackSlotByteWidth = 2 * VTByteWidth;
4604 unsigned StackSlotBitWidth = 8 * StackSlotByteWidth;
4605 EVT StackSlotVT = EVT::getIntegerVT(*DAG.getContext(), StackSlotBitWidth);
4606
4607 // Get a temporary stack slot 2x the width of our VT.
4608 // FIXME: reuse stack slots?
4609 // FIXME: should we be more picky about alignment?
4610 Align StackSlotAlignment(1);
4612 TypeSize::getFixed(StackSlotByteWidth), StackSlotAlignment);
4613 EVT PtrTy = StackPtr.getValueType();
4614 SDValue Ch = DAG.getEntryNode();
4615
4617 DAG.getMachineFunction(),
4618 cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex());
4619
4620 // Extend the value, that is being shifted, to the entire stack slot's width.
4621 SDValue Init;
4622 if (N->getOpcode() != ISD::SHL) {
4623 unsigned WideningOpc =
4624 N->getOpcode() == ISD::SRA ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
4625 Init = DAG.getNode(WideningOpc, dl, StackSlotVT, Shiftee);
4626 } else {
4627 // For left-shifts, pad the Shiftee's LSB with zeros to twice it's width.
4628 SDValue AllZeros = DAG.getConstant(0, dl, VT);
4629 Init = DAG.getNode(ISD::BUILD_PAIR, dl, StackSlotVT, AllZeros, Shiftee);
4630 }
4631 // And spill it into the stack slot.
4632 Ch = DAG.getStore(Ch, dl, Init, StackPtr, StackPtrInfo, StackSlotAlignment);
4633
4634 // Now, compute the full-byte offset into stack slot from where we can load.
4635 // We have shift amount, which is in bits, but in multiples of byte.
4636 // So just divide by CHAR_BIT.
4638 if (ShiftByByteMultiple)
4639 Flags.setExact(true);
4640 SDValue ByteOffset = DAG.getNode(ISD::SRL, dl, ShAmtVT, ShAmt,
4641 DAG.getConstant(3, dl, ShAmtVT), Flags);
4642 // And clamp it, because OOB load is an immediate UB,
4643 // while shift overflow would have *just* been poison.
4644 ByteOffset = DAG.getNode(ISD::AND, dl, ShAmtVT, ByteOffset,
4645 DAG.getConstant(VTByteWidth - 1, dl, ShAmtVT));
4646 // We have exactly two strategies on indexing into stack slot here:
4647 // 1. upwards starting from the beginning of the slot
4648 // 2. downwards starting from the middle of the slot
4649 // On little-endian machine, we pick 1. for right shifts and 2. for left-shift
4650 // and vice versa on big-endian machine.
4651 bool WillIndexUpwards = N->getOpcode() != ISD::SHL;
4652 if (DAG.getDataLayout().isBigEndian())
4653 WillIndexUpwards = !WillIndexUpwards;
4654
4655 SDValue AdjStackPtr;
4656 if (WillIndexUpwards) {
4657 AdjStackPtr = StackPtr;
4658 } else {
4659 AdjStackPtr = DAG.getMemBasePlusOffset(
4660 StackPtr, DAG.getConstant(VTByteWidth, dl, PtrTy), dl);
4661 ByteOffset = DAG.getNegative(ByteOffset, dl, ShAmtVT);
4662 }
4663
4664 // Get the pointer somewhere into the stack slot from which we need to load.
4665 ByteOffset = DAG.getSExtOrTrunc(ByteOffset, dl, PtrTy);
4666 AdjStackPtr = DAG.getMemBasePlusOffset(AdjStackPtr, ByteOffset, dl);
4667
4668 // And load it! While the load is not legal, legalizing it is obvious.
4669 SDValue Res = DAG.getLoad(
4670 VT, dl, Ch, AdjStackPtr,
4672 // We've performed the shift by a CHAR_BIT * [_ShAmt / CHAR_BIT_]
4673
4674 // If we may still have a less-than-CHAR_BIT to shift by, do so now.
4675 if (!ShiftByByteMultiple) {
4676 SDValue ShAmtRem = DAG.getNode(ISD::AND, dl, ShAmtVT, ShAmt,
4677 DAG.getConstant(7, dl, ShAmtVT));
4678 Res = DAG.getNode(N->getOpcode(), dl, VT, Res, ShAmtRem);
4679 }
4680
4681 // Finally, split the computed value.
4682 SplitInteger(Res, Lo, Hi);
4683}
4684
4685void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
4686 SDValue &Lo, SDValue &Hi) {
4687 EVT VT = N->getValueType(0);
4688 unsigned Opc = N->getOpcode();
4689 SDLoc dl(N);
4690
4691 // If we can emit an efficient shift operation, do so now. Check to see if
4692 // the RHS is a constant.
4693 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
4694 return ExpandShiftByConstant(N, CN->getAPIntValue(), Lo, Hi);
4695
4696 // If we can determine that the high bit of the shift is zero or one, even if
4697 // the low bits are variable, emit this shift in an optimized form.
4698 if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
4699 return;
4700
4701 // If this target supports shift_PARTS, use it. First, map to the _PARTS opc.
4702 unsigned PartsOpc;
4703 if (Opc == ISD::SHL) {
4704 PartsOpc = ISD::SHL_PARTS;
4705 } else if (Opc == ISD::SRL) {
4706 PartsOpc = ISD::SRL_PARTS;
4707 } else {
4708 assert(Opc == ISD::SRA && "Unknown shift!");
4709 PartsOpc = ISD::SRA_PARTS;
4710 }
4711
4712 // Next check to see if the target supports this SHL_PARTS operation or if it
4713 // will custom expand it. Don't lower this to SHL_PARTS when we optimise for
4714 // size, but create a libcall instead.
4715 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4717 const bool LegalOrCustom =
4718 (Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
4719 Action == TargetLowering::Custom;
4720
4721 unsigned ExpansionFactor = 1;
4722 // That VT->NVT expansion is one step. But will we re-expand NVT?
4723 for (EVT TmpVT = NVT;;) {
4724 EVT NewTMPVT = TLI.getTypeToTransformTo(*DAG.getContext(), TmpVT);
4725 if (NewTMPVT == TmpVT)
4726 break;
4727 TmpVT = NewTMPVT;
4728 ++ExpansionFactor;
4729 }
4730
4732 TLI.preferredShiftLegalizationStrategy(DAG, N, ExpansionFactor);
4733
4735 return ExpandIntRes_ShiftThroughStack(N, Lo, Hi);
4736
4737 if (LegalOrCustom &&
4739 // Expand the subcomponents.
4740 SDValue LHSL, LHSH;
4741 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
4742 EVT VT = LHSL.getValueType();
4743
4744 // If the shift amount operand is coming from a vector legalization it may
4745 // have an illegal type. Fix that first by casting the operand, otherwise
4746 // the new SHL_PARTS operation would need further legalization.
4747 SDValue ShiftOp = N->getOperand(1);
4748 EVT ShiftTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
4749 if (ShiftOp.getValueType() != ShiftTy)
4750 ShiftOp = DAG.getZExtOrTrunc(ShiftOp, dl, ShiftTy);
4751
4752 SDValue Ops[] = { LHSL, LHSH, ShiftOp };
4753 Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops);
4754 Hi = Lo.getValue(1);
4755 return;
4756 }
4757
4758 // Otherwise, emit a libcall.
4759 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4760 bool isSigned;
4761 if (Opc == ISD::SHL) {
4762 isSigned = false; /*sign irrelevant*/
4763 if (VT == MVT::i16)
4764 LC = RTLIB::SHL_I16;
4765 else if (VT == MVT::i32)
4766 LC = RTLIB::SHL_I32;
4767 else if (VT == MVT::i64)
4768 LC = RTLIB::SHL_I64;
4769 else if (VT == MVT::i128)
4770 LC = RTLIB::SHL_I128;
4771 } else if (Opc == ISD::SRL) {
4772 isSigned = false;
4773 if (VT == MVT::i16)
4774 LC = RTLIB::SRL_I16;
4775 else if (VT == MVT::i32)
4776 LC = RTLIB::SRL_I32;
4777 else if (VT == MVT::i64)
4778 LC = RTLIB::SRL_I64;
4779 else if (VT == MVT::i128)
4780 LC = RTLIB::SRL_I128;
4781 } else {
4782 assert(Opc == ISD::SRA && "Unknown shift!");
4783 isSigned = true;
4784 if (VT == MVT::i16)
4785 LC = RTLIB::SRA_I16;
4786 else if (VT == MVT::i32)
4787 LC = RTLIB::SRA_I32;
4788 else if (VT == MVT::i64)
4789 LC = RTLIB::SRA_I64;
4790 else if (VT == MVT::i128)
4791 LC = RTLIB::SRA_I128;
4792 }
4793
4794 if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
4795 EVT ShAmtTy =
4797 SDValue ShAmt = DAG.getZExtOrTrunc(N->getOperand(1), dl, ShAmtTy);
4798 SDValue Ops[2] = {N->getOperand(0), ShAmt};
4800 CallOptions.setSExt(isSigned);
4801 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
4802 return;
4803 }
4804
4805 if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi))
4806 llvm_unreachable("Unsupported shift!");
4807}
4808
4809void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
4810 SDValue &Lo, SDValue &Hi) {
4811 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4812 SDLoc dl(N);
4813 SDValue Op = N->getOperand(0);
4814 if (Op.getValueType().bitsLE(NVT)) {
4815 // The low part is sign extension of the input (degenerates to a copy).
4816 Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
4817 // The high part is obtained by SRA'ing all but one of the bits of low part.
4818 unsigned LoSize = NVT.getSizeInBits();
4819 Hi = DAG.getNode(
4820 ISD::SRA, dl, NVT, Lo,
4821 DAG.getConstant(LoSize - 1, dl, TLI.getPointerTy(DAG.getDataLayout())));
4822 } else {
4823 // For example, extension of an i48 to an i64. The operand type necessarily
4824 // promotes to the result type, so will end up being expanded too.
4825 assert(getTypeAction(Op.getValueType()) ==
4827 "Only know how to promote this result!");
4828 SDValue Res = GetPromotedInteger(Op);
4829 assert(Res.getValueType() == N->getValueType(0) &&
4830 "Operand over promoted?");
4831 // Split the promoted operand. This will simplify when it is expanded.
4832 SplitInteger(Res, Lo, Hi);
4833 unsigned ExcessBits = Op.getValueSizeInBits() - NVT.getSizeInBits();
4834 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
4836 ExcessBits)));
4837 }
4838}
4839
4840void DAGTypeLegalizer::
4841ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
4842 SDLoc dl(N);
4843 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4844 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
4845
4846 if (EVT.bitsLE(Lo.getValueType())) {
4847 // sext_inreg the low part if needed.
4848 Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
4849 N->getOperand(1));
4850
4851 // The high part gets the sign extension from the lo-part. This handles
4852 // things like sextinreg V:i64 from i8.
4853 Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
4854 DAG.getConstant(Hi.getValueSizeInBits() - 1, dl,
4855 TLI.getPointerTy(DAG.getDataLayout())));
4856 } else {
4857 // For example, extension of an i48 to an i64. Leave the low part alone,
4858 // sext_inreg the high part.
4859 unsigned ExcessBits = EVT.getSizeInBits() - Lo.getValueSizeInBits();
4860 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
4862 ExcessBits)));
4863 }
4864}
4865
4866void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
4867 SDValue &Lo, SDValue &Hi) {
4868 EVT VT = N->getValueType(0);
4869 SDLoc dl(N);
4870 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4871
4873 SDValue Res = DAG.getNode(ISD::SDIVREM, dl, DAG.getVTList(VT, VT), Ops);
4874 SplitInteger(Res.getValue(1), Lo, Hi);
4875 return;
4876 }
4877
4878 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4879 if (VT == MVT::i16)
4880 LC = RTLIB::SREM_I16;
4881 else if (VT == MVT::i32)
4882 LC = RTLIB::SREM_I32;
4883 else if (VT == MVT::i64)
4884 LC = RTLIB::SREM_I64;
4885 else if (VT == MVT::i128)
4886 LC = RTLIB::SREM_I128;
4887 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
4888
4890 CallOptions.setSExt(true);
4891 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
4892}
4893
4894void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
4895 SDValue &Lo, SDValue &Hi) {
4896 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4897 SDLoc dl(N);
4898 Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
4899 Hi = DAG.getNode(ISD::SRL, dl, N->getOperand(0).getValueType(),
4900 N->getOperand(0),
4901 DAG.getConstant(NVT.getSizeInBits(), dl,
4902 TLI.getPointerTy(DAG.getDataLayout())));
4903 Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
4904}
4905
4906void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
4907 SDValue &Lo, SDValue &Hi) {
4908 EVT VT = N->getValueType(0);
4909 SDLoc dl(N);
4910
4911 if (N->getOpcode() == ISD::UMULO) {
4912 // This section expands the operation into the following sequence of
4913 // instructions. `iNh` here refers to a type which has half the bit width of
4914 // the type the original operation operated on.
4915 //
4916 // %0 = %LHS.HI != 0 && %RHS.HI != 0
4917 // %1 = { iNh, i1 } @umul.with.overflow.iNh(iNh %LHS.HI, iNh %RHS.LO)
4918 // %2 = { iNh, i1 } @umul.with.overflow.iNh(iNh %RHS.HI, iNh %LHS.LO)
4919 // %3 = mul nuw iN (%LHS.LOW as iN), (%RHS.LOW as iN)
4920 // %4 = add iNh %1.0, %2.0 as iN
4921 // %5 = { iNh, i1 } @uadd.with.overflow.iNh(iNh %4, iNh %3.HIGH)
4922 //
4923 // %lo = %3.LO
4924 // %hi = %5.0
4925 // %ovf = %0 || %1.1 || %2.1 || %5.1
4926 SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
4927 SDValue LHSHigh, LHSLow, RHSHigh, RHSLow;
4928 GetExpandedInteger(LHS, LHSLow, LHSHigh);
4929 GetExpandedInteger(RHS, RHSLow, RHSHigh);
4930 EVT HalfVT = LHSLow.getValueType();
4931 EVT BitVT = N->getValueType(1);
4932 SDVTList VTHalfWithO = DAG.getVTList(HalfVT, BitVT);
4933
4934 SDValue HalfZero = DAG.getConstant(0, dl, HalfVT);
4935 SDValue Overflow = DAG.getNode(ISD::AND, dl, BitVT,
4936 DAG.getSetCC(dl, BitVT, LHSHigh, HalfZero, ISD::SETNE),
4937 DAG.getSetCC(dl, BitVT, RHSHigh, HalfZero, ISD::SETNE));
4938
4939 SDValue One = DAG.getNode(ISD::UMULO, dl, VTHalfWithO, LHSHigh, RHSLow);
4940 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, One.getValue(1));
4941
4942 SDValue Two = DAG.getNode(ISD::UMULO, dl, VTHalfWithO, RHSHigh, LHSLow);
4943 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, Two.getValue(1));
4944
4945 SDValue HighSum = DAG.getNode(ISD::ADD, dl, HalfVT, One, Two);
4946
4947 // Cannot use `UMUL_LOHI` directly, because some 32-bit targets (ARM) do not
4948 // know how to expand `i64,i64 = umul_lohi a, b` and abort (why isn’t this
4949 // operation recursively legalized?).
4950 //
4951 // Many backends understand this pattern and will convert into LOHI
4952 // themselves, if applicable.
4953 SDValue Three = DAG.getNode(ISD::MUL, dl, VT,
4954 DAG.getNode(ISD::ZERO_EXTEND, dl, VT, LHSLow),
4955 DAG.getNode(ISD::ZERO_EXTEND, dl, VT, RHSLow));
4956 SplitInteger(Three, Lo, Hi);
4957
4958 Hi = DAG.getNode(ISD::UADDO, dl, VTHalfWithO, Hi, HighSum);
4959 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, Hi.getValue(1));
4960 ReplaceValueWith(SDValue(N, 1), Overflow);
4961 return;
4962 }
4963
4964 Type *RetTy = VT.getTypeForEVT(*DAG.getContext());
4965 EVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
4966 Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext());
4967
4968 // Replace this with a libcall that will check overflow.
4969 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4970 if (VT == MVT::i32)
4971 LC = RTLIB::MULO_I32;
4972 else if (VT == MVT::i64)
4973 LC = RTLIB::MULO_I64;
4974 else if (VT == MVT::i128)
4975 LC = RTLIB::MULO_I128;
4976
4977 // If we don't have the libcall or if the function we are compiling is the
4978 // implementation of the expected libcall (avoid inf-loop), expand inline.
4979 if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC) ||
4980 TLI.getLibcallName(LC) == DAG.getMachineFunction().getName()) {
4981 // FIXME: This is not an optimal expansion, but better than crashing.
4982 EVT WideVT =
4984 SDValue LHS = DAG.getNode(ISD::SIGN_EXTEND, dl, WideVT, N->getOperand(0));
4985 SDValue RHS = DAG.getNode(ISD::SIGN_EXTEND, dl, WideVT, N->getOperand(1));
4986 SDValue Mul = DAG.getNode(ISD::MUL, dl, WideVT, LHS, RHS);
4987 SDValue MulLo, MulHi;
4988 SplitInteger(Mul, MulLo, MulHi);
4989 SDValue SRA =
4990 DAG.getNode(ISD::SRA, dl, VT, MulLo,
4991 DAG.getConstant(VT.getScalarSizeInBits() - 1, dl, VT));
4992 SDValue Overflow =
4993 DAG.getSetCC(dl, N->getValueType(1), MulHi, SRA, ISD::SETNE);
4994 SplitInteger(MulLo, Lo, Hi);
4995 ReplaceValueWith(SDValue(N, 1), Overflow);
4996 return;
4997 }
4998
4999 SDValue Temp = DAG.CreateStackTemporary(PtrVT);
5000 // Temporary for the overflow value, default it to zero.
5001 SDValue Chain =
5002 DAG.getStore(DAG.getEntryNode(), dl, DAG.getConstant(0, dl, PtrVT), Temp,
5004
5007 for (const SDValue &Op : N->op_values()) {
5008 EVT ArgVT = Op.getValueType();
5009 Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
5010 Entry.Node = Op;
5011 Entry.Ty = ArgTy;
5012 Entry.IsSExt = true;
5013 Entry.IsZExt = false;
5014 Args.push_back(Entry);
5015 }
5016
5017 // Also pass the address of the overflow check.
5018 Entry.Node = Temp;
5020 Entry.IsSExt = true;
5021 Entry.IsZExt = false;
5022 Args.push_back(Entry);
5023
5024 SDValue Func = DAG.getExternalSymbol(TLI.getLibcallName(LC), PtrVT);
5025
5027 CLI.setDebugLoc(dl)
5028 .setChain(Chain)
5029 .setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Func, std::move(Args))
5030 .setSExtResult();
5031
5032 std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
5033
5034 SplitInteger(CallInfo.first, Lo, Hi);
5035 SDValue Temp2 =
5036 DAG.getLoad(PtrVT, dl, CallInfo.second, Temp, MachinePointerInfo());
5037 SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Temp2,
5038 DAG.getConstant(0, dl, PtrVT),
5039 ISD::SETNE);
5040 // Use the overflow from the libcall everywhere.
5041 ReplaceValueWith(SDValue(N, 1), Ofl);
5042}
5043
5044void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
5045 SDValue &Lo, SDValue &Hi) {
5046 EVT VT = N->getValueType(0);
5047 SDLoc dl(N);
5048 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
5049
5051 SDValue Res = DAG.getNode(ISD::UDIVREM, dl, DAG.getVTList(VT, VT), Ops);
5052 SplitInteger(Res.getValue(0), Lo, Hi);
5053 return;
5054 }
5055
5056 // Try to expand UDIV by constant.
5057 if (isa<ConstantSDNode>(N->getOperand(1))) {
5058 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5059 // Only if the new type is legal.
5060 if (isTypeLegal(NVT)) {
5061 SDValue InL, InH;
5062 GetExpandedInteger(N->getOperand(0), InL, InH);
5064 if (TLI.expandDIVREMByConstant(N, Result, NVT, DAG, InL, InH)) {
5065 Lo = Result[0];
5066 Hi = Result[1];
5067 return;
5068 }
5069 }
5070 }
5071
5072 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5073 if (VT == MVT::i16)
5074 LC = RTLIB::UDIV_I16;
5075 else if (VT == MVT::i32)
5076 LC = RTLIB::UDIV_I32;
5077 else if (VT == MVT::i64)
5078 LC = RTLIB::UDIV_I64;
5079 else if (VT == MVT::i128)
5080 LC = RTLIB::UDIV_I128;
5081 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
5082
5084 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5085}
5086
5087void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
5088 SDValue &Lo, SDValue &Hi) {
5089 EVT VT = N->getValueType(0);
5090 SDLoc dl(N);
5091 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
5092
5094 SDValue Res = DAG.getNode(ISD::UDIVREM, dl, DAG.getVTList(VT, VT), Ops);
5095 SplitInteger(Res.getValue(1), Lo, Hi);
5096 return;
5097 }
5098
5099 // Try to expand UREM by constant.
5100 if (isa<ConstantSDNode>(N->getOperand(1))) {
5101 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5102 // Only if the new type is legal.
5103 if (isTypeLegal(NVT)) {
5104 SDValue InL, InH;
5105 GetExpandedInteger(N->getOperand(0), InL, InH);
5107 if (TLI.expandDIVREMByConstant(N, Result, NVT, DAG, InL, InH)) {
5108 Lo = Result[0];
5109 Hi = Result[1];
5110 return;
5111 }
5112 }
5113 }
5114
5115 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5116 if (VT == MVT::i16)
5117 LC = RTLIB::UREM_I16;
5118 else if (VT == MVT::i32)
5119 LC = RTLIB::UREM_I32;
5120 else if (VT == MVT::i64)
5121 LC = RTLIB::UREM_I64;
5122 else if (VT == MVT::i128)
5123 LC = RTLIB::UREM_I128;
5124 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
5125
5127 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5128}
5129
5130void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
5131 SDValue &Lo, SDValue &Hi) {
5132 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5133 SDLoc dl(N);
5134 SDValue Op = N->getOperand(0);
5135 if (Op.getValueType().bitsLE(NVT)) {
5136 // The low part is zero extension of the input (degenerates to a copy).
5137 Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
5138 Hi = DAG.getConstant(0, dl, NVT); // The high part is just a zero.
5139 } else {
5140 // For example, extension of an i48 to an i64. The operand type necessarily
5141 // promotes to the result type, so will end up being expanded too.
5142 assert(getTypeAction(Op.getValueType()) ==
5144 "Only know how to promote this result!");
5145 SDValue Res = GetPromotedInteger(Op);
5146 assert(Res.getValueType() == N->getValueType(0) &&
5147 "Operand over promoted?");
5148 // Split the promoted operand. This will simplify when it is expanded.
5149 SplitInteger(Res, Lo, Hi);
5150 unsigned ExcessBits = Op.getValueSizeInBits() - NVT.getSizeInBits();
5151 Hi = DAG.getZeroExtendInReg(Hi, dl,
5153 ExcessBits));
5154 }
5155}
5156
5157void DAGTypeLegalizer::ExpandIntRes_ATOMIC_LOAD(SDNode *N,
5158 SDValue &Lo, SDValue &Hi) {
5159 SDLoc dl(N);
5160 EVT VT = cast<AtomicSDNode>(N)->getMemoryVT();
5161 SDVTList VTs = DAG.getVTList(VT, MVT::i1, MVT::Other);
5162 SDValue Zero = DAG.getConstant(0, dl, VT);
5163 SDValue Swap = DAG.getAtomicCmpSwap(
5165 cast<AtomicSDNode>(N)->getMemoryVT(), VTs, N->getOperand(0),
5166 N->getOperand(1), Zero, Zero, cast<AtomicSDNode>(N)->getMemOperand());
5167
5168 ReplaceValueWith(SDValue(N, 0), Swap.getValue(0));
5169 ReplaceValueWith(SDValue(N, 1), Swap.getValue(2));
5170}
5171
5172void DAGTypeLegalizer::ExpandIntRes_VECREDUCE(SDNode *N,
5173 SDValue &Lo, SDValue &Hi) {
5174 // TODO For VECREDUCE_(AND|OR|XOR) we could split the vector and calculate
5175 // both halves independently.
5176 SDValue Res = TLI.expandVecReduce(N, DAG);
5177 SplitInteger(Res, Lo, Hi);
5178}
5179
5180void DAGTypeLegalizer::ExpandIntRes_Rotate(SDNode *N,
5181 SDValue &Lo, SDValue &Hi) {
5182 // Delegate to funnel-shift expansion.
5183 SDLoc DL(N);
5184 unsigned Opcode = N->getOpcode() == ISD::ROTL ? ISD::FSHL : ISD::FSHR;
5185 SDValue Res = DAG.getNode(Opcode, DL, N->getValueType(0), N->getOperand(0),
5186 N->getOperand(0), N->getOperand(1));
5187 SplitInteger(Res, Lo, Hi);
5188}
5189
5190void DAGTypeLegalizer::ExpandIntRes_FunnelShift(SDNode *N, SDValue &Lo,
5191 SDValue &Hi) {
5192 // Values numbered from least significant to most significant.
5193 SDValue In1, In2, In3, In4;
5194 GetExpandedInteger(N->getOperand(0), In3, In4);
5195 GetExpandedInteger(N->getOperand(1), In1, In2);
5196 EVT HalfVT = In1.getValueType();
5197
5198 SDLoc DL(N);
5199 unsigned Opc = N->getOpcode();
5200 SDValue ShAmt = N->getOperand(2);
5201 EVT ShAmtVT = ShAmt.getValueType();
5202 EVT ShAmtCCVT = getSetCCResultType(ShAmtVT);
5203
5204 // If the shift amount is at least half the bitwidth, swap the inputs.
5205 unsigned HalfVTBits = HalfVT.getScalarSizeInBits();
5206 SDValue AndNode = DAG.getNode(ISD::AND, DL, ShAmtVT, ShAmt,
5207 DAG.getConstant(HalfVTBits, DL, ShAmtVT));
5208 SDValue Cond =
5209 DAG.getSetCC(DL, ShAmtCCVT, AndNode, DAG.getConstant(0, DL, ShAmtVT),
5210 Opc == ISD::FSHL ? ISD::SETNE : ISD::SETEQ);
5211
5212 // Expand to a pair of funnel shifts.
5213 EVT NewShAmtVT = TLI.getShiftAmountTy(HalfVT, DAG.getDataLayout());
5214 SDValue NewShAmt = DAG.getAnyExtOrTrunc(ShAmt, DL, NewShAmtVT);
5215
5216 SDValue Select1 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In1, In2);
5217 SDValue Select2 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In2, In3);
5218 SDValue Select3 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In3, In4);
5219 Lo = DAG.getNode(Opc, DL, HalfVT, Select2, Select1, NewShAmt);
5220 Hi = DAG.getNode(Opc, DL, HalfVT, Select3, Select2, NewShAmt);
5221}
5222
5223void DAGTypeLegalizer::ExpandIntRes_VSCALE(SDNode *N, SDValue &Lo,
5224 SDValue &Hi) {
5225 EVT VT = N->getValueType(0);
5226 EVT HalfVT =
5227 EVT::getIntegerVT(*DAG.getContext(), N->getValueSizeInBits(0) / 2);
5228 SDLoc dl(N);
5229
5230 // We assume VSCALE(1) fits into a legal integer.
5231 APInt One(HalfVT.getSizeInBits(), 1);
5232 SDValue VScaleBase = DAG.getVScale(dl, HalfVT, One);
5233 VScaleBase = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, VScaleBase);
5234 SDValue Res = DAG.getNode(ISD::MUL, dl, VT, VScaleBase, N->getOperand(0));
5235 SplitInteger(Res, Lo, Hi);
5236}
5237
5238//===----------------------------------------------------------------------===//
5239// Integer Operand Expansion
5240//===----------------------------------------------------------------------===//
5241
5242/// ExpandIntegerOperand - This method is called when the specified operand of
5243/// the specified node is found to need expansion. At this point, all of the
5244/// result types of the node are known to be legal, but other operands of the
5245/// node may need promotion or expansion as well as the specified one.
5246bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
5247 LLVM_DEBUG(dbgs() << "Expand integer operand: "; N->dump(&DAG));
5248 SDValue Res = SDValue();
5249
5250 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
5251 return false;
5252
5253 switch (N->getOpcode()) {
5254 default:
5255 #ifndef NDEBUG
5256 dbgs() << "ExpandIntegerOperand Op #" << OpNo << ": ";
5257 N->dump(&DAG); dbgs() << "\n";
5258 #endif
5259 report_fatal_error("Do not know how to expand this operator's operand!");
5260
5261 case ISD::BITCAST: Res = ExpandOp_BITCAST(N); break;
5262 case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
5263 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
5264 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
5265 case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
5266 case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
5267 case ISD::EXPERIMENTAL_VP_SPLAT:
5268 case ISD::SPLAT_VECTOR: Res = ExpandIntOp_SPLAT_VECTOR(N); break;
5269 case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
5270 case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
5271 case ISD::SETCCCARRY: Res = ExpandIntOp_SETCCCARRY(N); break;
5273 case ISD::SINT_TO_FP:
5275 case ISD::UINT_TO_FP: Res = ExpandIntOp_XINT_TO_FP(N); break;
5276 case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
5277 case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
5278
5279 case ISD::SHL:
5280 case ISD::SRA:
5281 case ISD::SRL:
5282 case ISD::ROTL:
5283 case ISD::ROTR: Res = ExpandIntOp_Shift(N); break;
5284 case ISD::RETURNADDR:
5285 case ISD::FRAMEADDR: Res = ExpandIntOp_RETURNADDR(N); break;
5286
5287 case ISD::SCMP:
5288 case ISD::UCMP: Res = ExpandIntOp_CMP(N); break;
5289
5290 case ISD::ATOMIC_STORE: Res = ExpandIntOp_ATOMIC_STORE(N); break;
5291 case ISD::STACKMAP:
5292 Res = ExpandIntOp_STACKMAP(N, OpNo);
5293 break;
5294 case ISD::PATCHPOINT:
5295 Res = ExpandIntOp_PATCHPOINT(N, OpNo);
5296 break;
5297 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5298 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
5299 Res = ExpandIntOp_VP_STRIDED(N, OpNo);
5300 break;
5301 }
5302
5303 // If the result is null, the sub-method took care of registering results etc.
5304 if (!Res.getNode()) return false;
5305
5306 // If the result is N, the sub-method updated N in place. Tell the legalizer
5307 // core about this.
5308 if (Res.getNode() == N)
5309 return true;
5310
5311 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
5312 "Invalid operand expansion");
5313
5314 ReplaceValueWith(SDValue(N, 0), Res);
5315 return false;
5316}
5317
5318/// IntegerExpandSetCCOperands - Expand the operands of a comparison. This code
5319/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
5320void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
5321 SDValue &NewRHS,
5322 ISD::CondCode &CCCode,
5323 const SDLoc &dl) {
5324 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5325 GetExpandedInteger(NewLHS, LHSLo, LHSHi);
5326 GetExpandedInteger(NewRHS, RHSLo, RHSHi);
5327
5328 if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
5329 if (RHSLo == RHSHi && isAllOnesConstant(RHSLo)) {
5330 // Equality comparison to -1.
5331 NewLHS = DAG.getNode(ISD::AND, dl, LHSLo.getValueType(), LHSLo, LHSHi);
5332 NewRHS = RHSLo;
5333 return;
5334 }
5335
5336 NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
5337 NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
5338 NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
5339 NewRHS = DAG.getConstant(0, dl, NewLHS.getValueType());
5340 return;
5341 }
5342
5343 // If this is a comparison of the sign bit, just look at the top part.
5344 // X > -1, x < 0
5345 if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
5346 if ((CCCode == ISD::SETLT && CST->isZero()) || // X < 0
5347 (CCCode == ISD::SETGT && CST->isAllOnes())) { // X > -1
5348 NewLHS = LHSHi;
5349 NewRHS = RHSHi;
5350 return;
5351 }
5352
5353 // FIXME: This generated code sucks.
5354 ISD::CondCode LowCC;
5355 switch (CCCode) {
5356 default: llvm_unreachable("Unknown integer setcc!");
5357 case ISD::SETLT:
5358 case ISD::SETULT: LowCC = ISD::SETULT; break;
5359 case ISD::SETGT:
5360 case ISD::SETUGT: LowCC = ISD::SETUGT; break;
5361 case ISD::SETLE:
5362 case ISD::SETULE: LowCC = ISD::SETULE; break;
5363 case ISD::SETGE:
5364 case ISD::SETUGE: LowCC = ISD::SETUGE; break;
5365 }
5366
5367 // LoCmp = lo(op1) < lo(op2) // Always unsigned comparison
5368 // HiCmp = hi(op1) < hi(op2) // Signedness depends on operands
5369 // dest = hi(op1) == hi(op2) ? LoCmp : HiCmp;
5370
5371 // NOTE: on targets without efficient SELECT of bools, we can always use
5372 // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
5373 TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, AfterLegalizeTypes, true,
5374 nullptr);
5375 SDValue LoCmp, HiCmp;
5376 if (TLI.isTypeLegal(LHSLo.getValueType()) &&
5377 TLI.isTypeLegal(RHSLo.getValueType()))
5378 LoCmp = TLI.SimplifySetCC(getSetCCResultType(LHSLo.getValueType()), LHSLo,
5379 RHSLo, LowCC, false, DagCombineInfo, dl);
5380 if (!LoCmp.getNode())
5381 LoCmp = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
5382 RHSLo, LowCC);
5383 if (TLI.isTypeLegal(LHSHi.getValueType()) &&
5384 TLI.isTypeLegal(RHSHi.getValueType()))
5385 HiCmp = TLI.SimplifySetCC(getSetCCResultType(LHSHi.getValueType()), LHSHi,
5386 RHSHi, CCCode, false, DagCombineInfo, dl);
5387 if (!HiCmp.getNode())
5388 HiCmp =
5389 DAG.getNode(ISD::SETCC, dl, getSetCCResultType(LHSHi.getValueType()),
5390 LHSHi, RHSHi, DAG.getCondCode(CCCode));
5391
5392 ConstantSDNode *LoCmpC = dyn_cast<ConstantSDNode>(LoCmp.getNode());
5393 ConstantSDNode *HiCmpC = dyn_cast<ConstantSDNode>(HiCmp.getNode());
5394
5395 bool EqAllowed = ISD::isTrueWhenEqual(CCCode);
5396
5397 // FIXME: Is the HiCmpC->isOne() here correct for
5398 // ZeroOrNegativeOneBooleanContent.
5399 if ((EqAllowed && (HiCmpC && HiCmpC->isZero())) ||
5400 (!EqAllowed &&
5401 ((HiCmpC && HiCmpC->isOne()) || (LoCmpC && LoCmpC->isZero())))) {
5402 // For LE / GE, if high part is known false, ignore the low part.
5403 // For LT / GT: if low part is known false, return the high part.
5404 // if high part is known true, ignore the low part.
5405 NewLHS = HiCmp;
5406 NewRHS = SDValue();
5407 return;
5408 }
5409
5410 if (LHSHi == RHSHi) {
5411 // Comparing the low bits is enough.
5412 NewLHS = LoCmp;
5413 NewRHS = SDValue();
5414 return;
5415 }
5416
5417 // Lower with SETCCCARRY if the target supports it.
5418 EVT HiVT = LHSHi.getValueType();
5419 EVT ExpandVT = TLI.getTypeToExpandTo(*DAG.getContext(), HiVT);
5420 bool HasSETCCCARRY = TLI.isOperationLegalOrCustom(ISD::SETCCCARRY, ExpandVT);
5421
5422 // FIXME: Make all targets support this, then remove the other lowering.
5423 if (HasSETCCCARRY) {
5424 // SETCCCARRY can detect < and >= directly. For > and <=, flip
5425 // operands and condition code.
5426 bool FlipOperands = false;
5427 switch (CCCode) {
5428 case ISD::SETGT: CCCode = ISD::SETLT; FlipOperands = true; break;
5429 case ISD::SETUGT: CCCode = ISD::SETULT; FlipOperands = true; break;
5430 case ISD::SETLE: CCCode = ISD::SETGE; FlipOperands = true; break;
5431 case ISD::SETULE: CCCode = ISD::SETUGE; FlipOperands = true; break;
5432 default: break;
5433 }
5434 if (FlipOperands) {
5435 std::swap(LHSLo, RHSLo);
5436 std::swap(LHSHi, RHSHi);
5437 }
5438 // Perform a wide subtraction, feeding the carry from the low part into
5439 // SETCCCARRY. The SETCCCARRY operation is essentially looking at the high
5440 // part of the result of LHS - RHS. It is negative iff LHS < RHS. It is
5441 // zero or positive iff LHS >= RHS.
5442 EVT LoVT = LHSLo.getValueType();
5443 SDVTList VTList = DAG.getVTList(LoVT, getSetCCResultType(LoVT));
5444 SDValue LowCmp = DAG.getNode(ISD::USUBO, dl, VTList, LHSLo, RHSLo);
5445 SDValue Res = DAG.getNode(ISD::SETCCCARRY, dl, getSetCCResultType(HiVT),
5446 LHSHi, RHSHi, LowCmp.getValue(1),
5447 DAG.getCondCode(CCCode));
5448 NewLHS = Res;
5449 NewRHS = SDValue();
5450 return;
5451 }
5452
5453 NewLHS = TLI.SimplifySetCC(getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ,
5454 false, DagCombineInfo, dl);
5455 if (!NewLHS.getNode())
5456 NewLHS =
5457 DAG.getSetCC(dl, getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ);
5458 NewLHS = DAG.getSelect(dl, LoCmp.getValueType(), NewLHS, LoCmp, HiCmp);
5459 NewRHS = SDValue();
5460}
5461
5462SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
5463 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
5464 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
5465 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5466
5467 // If ExpandSetCCOperands returned a scalar, we need to compare the result
5468 // against zero to select between true and false values.
5469 if (!NewRHS.getNode()) {
5470 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
5471 CCCode = ISD::SETNE;
5472 }
5473
5474 // Update N to have the operands specified.
5475 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
5476 DAG.getCondCode(CCCode), NewLHS, NewRHS,
5477 N->getOperand(4)), 0);
5478}
5479
5480SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
5481 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
5482 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
5483 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5484
5485 // If ExpandSetCCOperands returned a scalar, we need to compare the result
5486 // against zero to select between true and false values.
5487 if (!NewRHS.getNode()) {
5488 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
5489 CCCode = ISD::SETNE;
5490 }
5491
5492 // Update N to have the operands specified.
5493 return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
5494 N->getOperand(2), N->getOperand(3),
5495 DAG.getCondCode(CCCode)), 0);
5496}
5497
5498SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
5499 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
5500 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
5501 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5502
5503 // If ExpandSetCCOperands returned a scalar, use it.
5504 if (!NewRHS.getNode()) {
5505 assert(NewLHS.getValueType() == N->getValueType(0) &&
5506 "Unexpected setcc expansion!");
5507 return NewLHS;
5508 }
5509
5510 // Otherwise, update N to have the operands specified.
5511 return SDValue(
5512 DAG.UpdateNodeOperands(N, NewLHS, NewRHS, DAG.getCondCode(CCCode)), 0);
5513}
5514
5515SDValue DAGTypeLegalizer::ExpandIntOp_SETCCCARRY(SDNode *N) {
5516 SDValue LHS = N->getOperand(0);
5517 SDValue RHS = N->getOperand(1);
5518 SDValue Carry = N->getOperand(2);
5519 SDValue Cond = N->getOperand(3);
5520 SDLoc dl = SDLoc(N);
5521
5522 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5523 GetExpandedInteger(LHS, LHSLo, LHSHi);
5524 GetExpandedInteger(RHS, RHSLo, RHSHi);
5525
5526 // Expand to a USUBO_CARRY for the low part and a SETCCCARRY for the high.
5527 SDVTList VTList = DAG.getVTList(LHSLo.getValueType(), Carry.getValueType());
5528 SDValue LowCmp =
5529 DAG.getNode(ISD::USUBO_CARRY, dl, VTList, LHSLo, RHSLo, Carry);
5530 return DAG.getNode(ISD::SETCCCARRY, dl, N->getValueType(0), LHSHi, RHSHi,
5531 LowCmp.getValue(1), Cond);
5532}
5533
5534SDValue DAGTypeLegalizer::ExpandIntOp_SPLAT_VECTOR(SDNode *N) {
5535 // Split the operand and replace with SPLAT_VECTOR_PARTS.
5536 SDValue Lo, Hi;
5537 GetExpandedInteger(N->getOperand(0), Lo, Hi);
5538 return DAG.getNode(ISD::SPLAT_VECTOR_PARTS, SDLoc(N), N->getValueType(0), Lo,
5539 Hi);
5540}
5541
5542SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
5543 // The value being shifted is legal, but the shift amount is too big.
5544 // It follows that either the result of the shift is undefined, or the
5545 // upper half of the shift amount is zero. Just use the lower half.
5546 SDValue Lo, Hi;
5547 GetExpandedInteger(N->getOperand(1), Lo, Hi);
5548 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0);
5549}
5550
5551SDValue DAGTypeLegalizer::ExpandIntOp_CMP(SDNode *N) {
5552 return TLI.expandCMP(N, DAG);
5553}
5554
5555SDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) {
5556 // The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant. This
5557 // surely makes pretty nice problems on 8/16 bit targets. Just truncate this
5558 // constant to valid type.
5559 SDValue Lo, Hi;
5560 GetExpandedInteger(N->getOperand(0), Lo, Hi);
5561 return SDValue(DAG.UpdateNodeOperands(N, Lo), 0);
5562}
5563
5564SDValue DAGTypeLegalizer::ExpandIntOp_XINT_TO_FP(SDNode *N) {
5565 bool IsStrict = N->isStrictFPOpcode();
5566 bool IsSigned = N->getOpcode() == ISD::SINT_TO_FP ||
5567 N->getOpcode() == ISD::STRICT_SINT_TO_FP;
5568 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
5569 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
5570 EVT DstVT = N->getValueType(0);
5571 RTLIB::Libcall LC = IsSigned ? RTLIB::getSINTTOFP(Op.getValueType(), DstVT)
5572 : RTLIB::getUINTTOFP(Op.getValueType(), DstVT);
5573 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
5574 "Don't know how to expand this XINT_TO_FP!");
5576 CallOptions.setSExt(true);
5577 std::pair<SDValue, SDValue> Tmp =
5578 TLI.makeLibCall(DAG, LC, DstVT, Op, CallOptions, SDLoc(N), Chain);
5579
5580 if (!IsStrict)
5581 return Tmp.first;
5582
5583 ReplaceValueWith(SDValue(N, 1), Tmp.second);
5584 ReplaceValueWith(SDValue(N, 0), Tmp.first);
5585 return SDValue();
5586}
5587
5588SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
5589 assert(!N->isAtomic() && "Should have been a ATOMIC_STORE?");
5590
5591 if (ISD::isNormalStore(N))
5592 return ExpandOp_NormalStore(N, OpNo);
5593
5594 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
5595 assert(OpNo == 1 && "Can only expand the stored value so far");
5596
5597 EVT VT = N->getOperand(1).getValueType();
5598 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5599 SDValue Ch = N->getChain();
5600 SDValue Ptr = N->getBasePtr();
5601 MachineMemOperand::Flags MMOFlags = N->getMemOperand()->getFlags();
5602 AAMDNodes AAInfo = N->getAAInfo();
5603 SDLoc dl(N);
5604 SDValue Lo, Hi;
5605
5606 assert(NVT.isByteSized() && "Expanded type not byte sized!");
5607
5608 if (N->getMemoryVT().bitsLE(NVT)) {
5609 GetExpandedInteger(N->getValue(), Lo, Hi);
5610 return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
5611 N->getMemoryVT(), N->getOriginalAlign(), MMOFlags,
5612 AAInfo);
5613 }
5614
5615 if (DAG.getDataLayout().isLittleEndian()) {
5616 // Little-endian - low bits are at low addresses.
5617 GetExpandedInteger(N->getValue(), Lo, Hi);
5618
5619 Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
5620 N->getOriginalAlign(), MMOFlags, AAInfo);
5621
5622 unsigned ExcessBits =
5623 N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
5624 EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
5625
5626 // Increment the pointer to the other half.
5627 unsigned IncrementSize = NVT.getSizeInBits()/8;
5628 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
5629 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
5630 N->getPointerInfo().getWithOffset(IncrementSize),
5631 NEVT, N->getOriginalAlign(), MMOFlags, AAInfo);
5632 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
5633 }
5634
5635 // Big-endian - high bits are at low addresses. Favor aligned stores at
5636 // the cost of some bit-fiddling.
5637 GetExpandedInteger(N->getValue(), Lo, Hi);
5638
5639 EVT ExtVT = N->getMemoryVT();
5640 unsigned EBytes = ExtVT.getStoreSize();
5641 unsigned IncrementSize = NVT.getSizeInBits()/8;
5642 unsigned ExcessBits = (EBytes - IncrementSize)*8;
5643 EVT HiVT = EVT::getIntegerVT(*DAG.getContext(),
5644 ExtVT.getSizeInBits() - ExcessBits);
5645
5646 if (ExcessBits < NVT.getSizeInBits()) {
5647 // Transfer high bits from the top of Lo to the bottom of Hi.
5648 Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
5649 DAG.getConstant(NVT.getSizeInBits() - ExcessBits, dl,
5650 TLI.getPointerTy(DAG.getDataLayout())));
5651 Hi = DAG.getNode(
5652 ISD::OR, dl, NVT, Hi,
5653 DAG.getNode(ISD::SRL, dl, NVT, Lo,
5654 DAG.getConstant(ExcessBits, dl,
5655 TLI.getPointerTy(DAG.getDataLayout()))));
5656 }
5657
5658 // Store both the high bits and maybe some of the low bits.
5659 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getPointerInfo(), HiVT,
5660 N->getOriginalAlign(), MMOFlags, AAInfo);
5661
5662 // Increment the pointer to the other half.
5663 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
5664 // Store the lowest ExcessBits bits in the second half.
5665 Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr,
5666 N->getPointerInfo().getWithOffset(IncrementSize),
5667 EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
5668 N->getOriginalAlign(), MMOFlags, AAInfo);
5669 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
5670}
5671
5672SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
5673 SDValue InL, InH;
5674 GetExpandedInteger(N->getOperand(0), InL, InH);
5675 // Just truncate the low part of the source.
5676 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0), InL);
5677}
5678
5679SDValue DAGTypeLegalizer::ExpandIntOp_ATOMIC_STORE(SDNode *N) {
5680 SDLoc dl(N);
5681 SDValue Swap =
5682 DAG.getAtomic(ISD::ATOMIC_SWAP, dl, cast<AtomicSDNode>(N)->getMemoryVT(),
5683 N->getOperand(0), N->getOperand(2), N->getOperand(1),
5684 cast<AtomicSDNode>(N)->getMemOperand());
5685 return Swap.getValue(1);
5686}
5687
5688SDValue DAGTypeLegalizer::ExpandIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) {
5689 assert((N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD && OpNo == 3) ||
5690 (N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE && OpNo == 4));
5691
5692 SDValue Hi; // The upper half is dropped out.
5693 SmallVector<SDValue, 8> NewOps(N->op_begin(), N->op_end());
5694 GetExpandedInteger(NewOps[OpNo], NewOps[OpNo], Hi);
5695
5696 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
5697}
5698
5699SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SPLICE(SDNode *N) {
5700 SDLoc dl(N);
5701
5702 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5703 SDValue V1 = GetPromotedInteger(N->getOperand(1));
5704 EVT OutVT = V0.getValueType();
5705
5706 return DAG.getNode(ISD::VECTOR_SPLICE, dl, OutVT, V0, V1, N->getOperand(2));
5707}
5708
5709SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_INTERLEAVE_DEINTERLEAVE(SDNode *N) {
5710 SDLoc dl(N);
5711
5712 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5713 SDValue V1 = GetPromotedInteger(N->getOperand(1));
5714 EVT ResVT = V0.getValueType();
5715 SDValue Res = DAG.getNode(N->getOpcode(), dl,
5716 DAG.getVTList(ResVT, ResVT), V0, V1);
5717 SetPromotedInteger(SDValue(N, 0), Res.getValue(0));
5718 SetPromotedInteger(SDValue(N, 1), Res.getValue(1));
5719 return SDValue();
5720}
5721
5722SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
5723
5724 EVT OutVT = N->getValueType(0);
5725 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5726 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5727 EVT NOutVTElem = NOutVT.getVectorElementType();
5728
5729 SDLoc dl(N);
5730 SDValue BaseIdx = N->getOperand(1);
5731
5732 // TODO: We may be able to use this for types other than scalable
5733 // vectors and fix those tests that expect BUILD_VECTOR to be used
5734 if (OutVT.isScalableVector()) {
5735 SDValue InOp0 = N->getOperand(0);
5736 EVT InVT = InOp0.getValueType();
5737
5738 // Try and extract from a smaller type so that it eventually falls
5739 // into the promotion code below.
5740 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector ||
5741 getTypeAction(InVT) == TargetLowering::TypeLegal) {
5742 EVT NInVT = InVT.getHalfNumVectorElementsVT(*DAG.getContext());
5743 unsigned NElts = NInVT.getVectorMinNumElements();
5744 uint64_t IdxVal = BaseIdx->getAsZExtVal();
5745
5746 SDValue Step1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NInVT, InOp0,
5747 DAG.getConstant(alignDown(IdxVal, NElts), dl,
5748 BaseIdx.getValueType()));
5749 SDValue Step2 = DAG.getNode(
5750 ISD::EXTRACT_SUBVECTOR, dl, OutVT, Step1,
5751 DAG.getConstant(IdxVal % NElts, dl, BaseIdx.getValueType()));
5752 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Step2);
5753 }
5754
5755 // Try and extract from a widened type.
5756 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
5757 SDValue Ops[] = {GetWidenedVector(InOp0), BaseIdx};
5758 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), OutVT, Ops);
5759 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Ext);
5760 }
5761
5762 // Promote operands and see if this is handled by target lowering,
5763 // Otherwise, use the BUILD_VECTOR approach below
5764 if (getTypeAction(InVT) == TargetLowering::TypePromoteInteger) {
5765 // Collect the (promoted) operands
5766 SDValue Ops[] = { GetPromotedInteger(InOp0), BaseIdx };
5767
5768 EVT PromEltVT = Ops[0].getValueType().getVectorElementType();
5769 assert(PromEltVT.bitsLE(NOutVTElem) &&
5770 "Promoted operand has an element type greater than result");
5771
5772 EVT ExtVT = NOutVT.changeVectorElementType(PromEltVT);
5773 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), ExtVT, Ops);
5774 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Ext);
5775 }
5776 }
5777
5778 if (OutVT.isScalableVector())
5779 report_fatal_error("Unable to promote scalable types using BUILD_VECTOR");
5780
5781 SDValue InOp0 = N->getOperand(0);
5782 if (getTypeAction(InOp0.getValueType()) == TargetLowering::TypePromoteInteger)
5783 InOp0 = GetPromotedInteger(InOp0);
5784
5785 EVT InVT = InOp0.getValueType();
5786 EVT InSVT = InVT.getVectorElementType();
5787
5788 unsigned OutNumElems = OutVT.getVectorNumElements();
5790 Ops.reserve(OutNumElems);
5791 for (unsigned i = 0; i != OutNumElems; ++i) {
5792 // Extract the element from the original vector.
5793 SDValue Index = DAG.getNode(ISD::ADD, dl, BaseIdx.getValueType(), BaseIdx,
5794 DAG.getConstant(i, dl, BaseIdx.getValueType()));
5795 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InSVT,
5796 N->getOperand(0), Index);
5797 SDValue Op = DAG.getAnyExtOrTrunc(Ext, dl, NOutVTElem);
5798 // Insert the converted element to the new vector.
5799 Ops.push_back(Op);
5800 }
5801
5802 return DAG.getBuildVector(NOutVT, dl, Ops);
5803}
5804
5805SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_SUBVECTOR(SDNode *N) {
5806 EVT OutVT = N->getValueType(0);
5807 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5808 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5809
5810 SDLoc dl(N);
5811 SDValue Vec = N->getOperand(0);
5812 SDValue SubVec = N->getOperand(1);
5813 SDValue Idx = N->getOperand(2);
5814
5815 EVT SubVecVT = SubVec.getValueType();
5816 EVT NSubVT =
5818 SubVecVT.getVectorElementCount());
5819
5820 Vec = GetPromotedInteger(Vec);
5821 SubVec = DAG.getNode(ISD::ANY_EXTEND, dl, NSubVT, SubVec);
5822
5823 return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, NOutVT, Vec, SubVec, Idx);
5824}
5825
5826SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_REVERSE(SDNode *N) {
5827 SDLoc dl(N);
5828
5829 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5830 EVT OutVT = V0.getValueType();
5831
5832 return DAG.getNode(ISD::VECTOR_REVERSE, dl, OutVT, V0);
5833}
5834
5835SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) {
5836 ShuffleVectorSDNode *SV = cast<ShuffleVectorSDNode>(N);
5837 EVT VT = N->getValueType(0);
5838 SDLoc dl(N);
5839
5840 ArrayRef<int> NewMask = SV->getMask().slice(0, VT.getVectorNumElements());
5841
5842 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5843 SDValue V1 = GetPromotedInteger(N->getOperand(1));
5844 EVT OutVT = V0.getValueType();
5845
5846 return DAG.getVectorShuffle(OutVT, dl, V0, V1, NewMask);
5847}
5848
5849SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) {
5850 EVT OutVT = N->getValueType(0);
5851 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5852 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5853 unsigned NumElems = N->getNumOperands();
5854 EVT NOutVTElem = NOutVT.getVectorElementType();
5855 TargetLoweringBase::BooleanContent NOutBoolType = TLI.getBooleanContents(NOutVT);
5856 unsigned NOutExtOpc = TargetLowering::getExtendForContent(NOutBoolType);
5857 SDLoc dl(N);
5858
5860 Ops.reserve(NumElems);
5861 for (unsigned i = 0; i != NumElems; ++i) {
5862 SDValue Op = N->getOperand(i);
5863 EVT OpVT = Op.getValueType();
5864 // BUILD_VECTOR integer operand types are allowed to be larger than the
5865 // result's element type. This may still be true after the promotion. For
5866 // example, we might be promoting (<v?i1> = BV <i32>, <i32>, ...) to
5867 // (v?i16 = BV <i32>, <i32>, ...), and we can't any_extend <i32> to <i16>.
5868 if (OpVT.bitsLT(NOutVTElem)) {
5869 unsigned ExtOpc = ISD::ANY_EXTEND;
5870 // Attempt to extend constant bool vectors to match target's BooleanContent.
5871 // While not necessary, this improves chances of the constant correctly
5872 // folding with compare results (e.g. for NOT patterns).
5873 if (OpVT == MVT::i1 && Op.getOpcode() == ISD::Constant)
5874 ExtOpc = NOutExtOpc;
5875 Op = DAG.getNode(ExtOpc, dl, NOutVTElem, Op);
5876 }
5877 Ops.push_back(Op);
5878 }
5879
5880 return DAG.getBuildVector(NOutVT, dl, Ops);
5881}
5882
5883SDValue DAGTypeLegalizer::PromoteIntRes_ScalarOp(SDNode *N) {
5884
5885 SDLoc dl(N);
5886
5887 assert(!N->getOperand(0).getValueType().isVector() &&
5888 "Input must be a scalar");
5889
5890 EVT OutVT = N->getValueType(0);
5891 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5892 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5893 EVT NOutElemVT = NOutVT.getVectorElementType();
5894
5895 SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutElemVT, N->getOperand(0));
5896 if (N->isVPOpcode())
5897 return DAG.getNode(N->getOpcode(), dl, NOutVT, Op, N->getOperand(1),
5898 N->getOperand(2));
5899
5900 return DAG.getNode(N->getOpcode(), dl, NOutVT, Op);
5901}
5902
5903SDValue DAGTypeLegalizer::PromoteIntRes_STEP_VECTOR(SDNode *N) {
5904 SDLoc dl(N);
5905 EVT OutVT = N->getValueType(0);
5906 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5907 assert(NOutVT.isScalableVector() &&
5908 "Type must be promoted to a scalable vector type");
5909 const APInt &StepVal = N->getConstantOperandAPInt(0);
5910 return DAG.getStepVector(dl, NOutVT,
5911 StepVal.sext(NOutVT.getScalarSizeInBits()));
5912}
5913
5914SDValue DAGTypeLegalizer::PromoteIntRes_CONCAT_VECTORS(SDNode *N) {
5915 SDLoc dl(N);
5916
5917 EVT OutVT = N->getValueType(0);
5918 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5919 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5920
5921 unsigned NumOperands = N->getNumOperands();
5922 unsigned NumOutElem = NOutVT.getVectorMinNumElements();
5923 EVT OutElemTy = NOutVT.getVectorElementType();
5924 if (OutVT.isScalableVector()) {
5925 // Find the largest promoted element type for each of the operands.
5926 SDUse *MaxSizedValue = std::max_element(
5927 N->op_begin(), N->op_end(), [](const SDValue &A, const SDValue &B) {
5928 EVT AVT = A.getValueType().getVectorElementType();
5929 EVT BVT = B.getValueType().getVectorElementType();
5930 return AVT.getScalarSizeInBits() < BVT.getScalarSizeInBits();
5931 });
5932 EVT MaxElementVT = MaxSizedValue->getValueType().getVectorElementType();
5933
5934 // Then promote all vectors to the largest element type.
5936 for (unsigned I = 0; I < NumOperands; ++I) {
5937 SDValue Op = N->getOperand(I);
5938 EVT OpVT = Op.getValueType();
5939 if (getTypeAction(OpVT) == TargetLowering::TypePromoteInteger)
5940 Op = GetPromotedInteger(Op);
5941 else
5942 assert(getTypeAction(OpVT) == TargetLowering::TypeLegal &&
5943 "Unhandled legalization type");
5944
5946 MaxElementVT.getScalarSizeInBits())
5947 Op = DAG.getAnyExtOrTrunc(Op, dl,
5948 OpVT.changeVectorElementType(MaxElementVT));
5949 Ops.push_back(Op);
5950 }
5951
5952 // Do the CONCAT on the promoted type and finally truncate to (the promoted)
5953 // NOutVT.
5954 return DAG.getAnyExtOrTrunc(
5956 OutVT.changeVectorElementType(MaxElementVT), Ops),
5957 dl, NOutVT);
5958 }
5959
5960 unsigned NumElem = N->getOperand(0).getValueType().getVectorNumElements();
5961 assert(NumElem * NumOperands == NumOutElem &&
5962 "Unexpected number of elements");
5963
5964 // Take the elements from the first vector.
5965 SmallVector<SDValue, 8> Ops(NumOutElem);
5966 for (unsigned i = 0; i < NumOperands; ++i) {
5967 SDValue Op = N->getOperand(i);
5968 if (getTypeAction(Op.getValueType()) == TargetLowering::TypePromoteInteger)
5969 Op = GetPromotedInteger(Op);
5970 EVT SclrTy = Op.getValueType().getVectorElementType();
5971 assert(NumElem == Op.getValueType().getVectorNumElements() &&
5972 "Unexpected number of elements");
5973
5974 for (unsigned j = 0; j < NumElem; ++j) {
5975 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy, Op,
5976 DAG.getVectorIdxConstant(j, dl));
5977 Ops[i * NumElem + j] = DAG.getAnyExtOrTrunc(Ext, dl, OutElemTy);
5978 }
5979 }
5980
5981 return DAG.getBuildVector(NOutVT, dl, Ops);
5982}
5983
5984SDValue DAGTypeLegalizer::PromoteIntRes_EXTEND_VECTOR_INREG(SDNode *N) {
5985 EVT VT = N->getValueType(0);
5986 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5987 assert(NVT.isVector() && "This type must be promoted to a vector type");
5988
5989 SDLoc dl(N);
5990
5991 // For operands whose TypeAction is to promote, extend the promoted node
5992 // appropriately (ZERO_EXTEND or SIGN_EXTEND) from the original pre-promotion
5993 // type, and then construct a new *_EXTEND_VECTOR_INREG node to the promote-to
5994 // type..
5995 if (getTypeAction(N->getOperand(0).getValueType())
5997 SDValue Promoted;
5998
5999 switch(N->getOpcode()) {
6001 Promoted = SExtPromotedInteger(N->getOperand(0));
6002 break;
6004 Promoted = ZExtPromotedInteger(N->getOperand(0));
6005 break;
6007 Promoted = GetPromotedInteger(N->getOperand(0));
6008 break;
6009 default:
6010 llvm_unreachable("Node has unexpected Opcode");
6011 }
6012 return DAG.getNode(N->getOpcode(), dl, NVT, Promoted);
6013 }
6014
6015 // Directly extend to the appropriate transform-to type.
6016 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
6017}
6018
6019SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) {
6020 EVT OutVT = N->getValueType(0);
6021 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6022 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6023
6024 EVT NOutVTElem = NOutVT.getVectorElementType();
6025
6026 SDLoc dl(N);
6027 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6028
6029 SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl,
6030 NOutVTElem, N->getOperand(1));
6031 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NOutVT,
6032 V0, ConvElem, N->getOperand(2));
6033}
6034
6035SDValue DAGTypeLegalizer::PromoteIntRes_VECREDUCE(SDNode *N) {
6036 // The VECREDUCE result size may be larger than the element size, so
6037 // we can simply change the result type.
6038 SDLoc dl(N);
6039 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6040 return DAG.getNode(N->getOpcode(), dl, NVT, N->ops());
6041}
6042
6043SDValue DAGTypeLegalizer::PromoteIntRes_VP_REDUCE(SDNode *N) {
6044 // The VP_REDUCE result size may be larger than the element size, so we can
6045 // simply change the result type. However the start value and result must be
6046 // the same.
6047 SDLoc DL(N);
6048 SDValue Start = PromoteIntOpVectorReduction(N, N->getOperand(0));
6049 return DAG.getNode(N->getOpcode(), DL, Start.getValueType(), Start,
6050 N->getOperand(1), N->getOperand(2), N->getOperand(3));
6051}
6052
6053SDValue DAGTypeLegalizer::PromoteIntRes_PATCHPOINT(SDNode *N) {
6054 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6055 SDLoc dl(N);
6056
6057 assert(N->getNumValues() == 3 && "Expected 3 values for PATCHPOINT");
6058 SDVTList VTList = DAG.getVTList({NVT, MVT::Other, MVT::Glue});
6059
6060 SmallVector<SDValue> Ops(N->ops());
6061 SDValue Res = DAG.getNode(ISD::PATCHPOINT, dl, VTList, Ops);
6062
6063 // Replace chain and glue uses with the new patchpoint.
6064 SDValue From[] = {SDValue(N, 1), SDValue(N, 2)};
6065 SDValue To[] = {Res.getValue(1), Res.getValue(2)};
6066 DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
6067
6068 return Res.getValue(0);
6069}
6070
6071SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
6072 SDLoc dl(N);
6073 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6074 SDValue V1 = DAG.getZExtOrTrunc(N->getOperand(1), dl,
6075 TLI.getVectorIdxTy(DAG.getDataLayout()));
6077 V0->getValueType(0).getScalarType(), V0, V1);
6078
6079 // EXTRACT_VECTOR_ELT can return types which are wider than the incoming
6080 // element types. If this is the case then we need to expand the outgoing
6081 // value and not truncate it.
6082 return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
6083}
6084
6085SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_SUBVECTOR(SDNode *N) {
6086 SDLoc dl(N);
6087 // The result type is equal to the first input operand's type, so the
6088 // type that needs promoting must be the second source vector.
6089 SDValue V0 = N->getOperand(0);
6090 SDValue V1 = GetPromotedInteger(N->getOperand(1));
6091 SDValue Idx = N->getOperand(2);
6092 EVT PromVT = EVT::getVectorVT(*DAG.getContext(),
6095 V0 = DAG.getAnyExtOrTrunc(V0, dl, PromVT);
6096 SDValue Ext = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, PromVT, V0, V1, Idx);
6097 return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
6098}
6099
6100SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_SUBVECTOR(SDNode *N) {
6101 SDLoc dl(N);
6102 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6103 MVT InVT = V0.getValueType().getSimpleVT();
6105 N->getValueType(0).getVectorNumElements());
6106 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OutVT, V0, N->getOperand(1));
6107 return DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), Ext);
6108}
6109
6110SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
6111 SDLoc dl(N);
6112
6113 EVT ResVT = N->getValueType(0);
6114 unsigned NumElems = N->getNumOperands();
6115
6116 if (ResVT.isScalableVector()) {
6117 SDValue ResVec = DAG.getUNDEF(ResVT);
6118
6119 for (unsigned OpIdx = 0; OpIdx < NumElems; ++OpIdx) {
6120 SDValue Op = N->getOperand(OpIdx);
6121 unsigned OpNumElts = Op.getValueType().getVectorMinNumElements();
6122 ResVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, ResVec, Op,
6123 DAG.getIntPtrConstant(OpIdx * OpNumElts, dl));
6124 }
6125
6126 return ResVec;
6127 }
6128
6129 EVT RetSclrTy = N->getValueType(0).getVectorElementType();
6130
6132 NewOps.reserve(NumElems);
6133
6134 // For each incoming vector
6135 for (unsigned VecIdx = 0; VecIdx != NumElems; ++VecIdx) {
6136 SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx));
6137 EVT SclrTy = Incoming->getValueType(0).getVectorElementType();
6138 unsigned NumElem = Incoming->getValueType(0).getVectorNumElements();
6139
6140 for (unsigned i=0; i<NumElem; ++i) {
6141 // Extract element from incoming vector
6142 SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy, Incoming,
6143 DAG.getVectorIdxConstant(i, dl));
6144 SDValue Tr = DAG.getNode(ISD::TRUNCATE, dl, RetSclrTy, Ex);
6145 NewOps.push_back(Tr);
6146 }
6147 }
6148
6149 return DAG.getBuildVector(N->getValueType(0), dl, NewOps);
6150}
6151
6152SDValue DAGTypeLegalizer::ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
6153 assert(OpNo > 1);
6154 SDValue Op = N->getOperand(OpNo);
6155
6156 // FIXME: Non-constant operands are not yet handled:
6157 // - https://github.com/llvm/llvm-project/issues/26431
6158 // - https://github.com/llvm/llvm-project/issues/55957
6159 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
6160 if (!CN)
6161 return SDValue();
6162
6163 // Copy operands before the one being expanded.
6164 SmallVector<SDValue> NewOps;
6165 for (unsigned I = 0; I < OpNo; I++)
6166 NewOps.push_back(N->getOperand(I));
6167
6168 EVT Ty = Op.getValueType();
6169 SDLoc DL = SDLoc(N);
6170 if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
6171 NewOps.push_back(
6172 DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
6173 NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
6174 } else {
6175 // FIXME: https://github.com/llvm/llvm-project/issues/55609
6176 return SDValue();
6177 }
6178
6179 // Copy remaining operands.
6180 for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
6181 NewOps.push_back(N->getOperand(I));
6182
6183 SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
6184
6185 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
6186 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
6187
6188 return SDValue(); // Signal that we have replaced the node already.
6189}
6190
6191SDValue DAGTypeLegalizer::ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
6192 assert(OpNo >= 7);
6193 SDValue Op = N->getOperand(OpNo);
6194
6195 // FIXME: Non-constant operands are not yet handled:
6196 // - https://github.com/llvm/llvm-project/issues/26431
6197 // - https://github.com/llvm/llvm-project/issues/55957
6198 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
6199 if (!CN)
6200 return SDValue();
6201
6202 // Copy operands before the one being expanded.
6203 SmallVector<SDValue> NewOps;
6204 for (unsigned I = 0; I < OpNo; I++)
6205 NewOps.push_back(N->getOperand(I));
6206
6207 EVT Ty = Op.getValueType();
6208 SDLoc DL = SDLoc(N);
6209 if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
6210 NewOps.push_back(
6211 DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
6212 NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
6213 } else {
6214 // FIXME: https://github.com/llvm/llvm-project/issues/55609
6215 return SDValue();
6216 }
6217
6218 // Copy remaining operands.
6219 for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
6220 NewOps.push_back(N->getOperand(I));
6221
6222 SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
6223
6224 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
6225 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
6226
6227 return SDValue(); // Signal that we have replaced the node already.
6228}
#define Success
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define LLVM_DEBUG(X)
Definition: Debug.h:101
static bool isSigned(unsigned int Opcode)
static SDValue SaturateWidenedDIVFIX(SDValue V, SDLoc &dl, unsigned SatW, bool Signed, const TargetLowering &TLI, SelectionDAG &DAG)
static SDValue fpExtendHelper(SDValue Op, SDValue &Chain, bool IsStrict, EVT VT, SDLoc DL, SelectionDAG &DAG)
static SDValue earlyExpandDIVFIX(SDNode *N, SDValue LHS, SDValue RHS, unsigned Scale, const TargetLowering &TLI, SelectionDAG &DAG, unsigned SatW=0)
static unsigned getExtendForIntVecReduction(SDNode *N)
static std::pair< ISD::CondCode, ISD::NodeType > getExpandedMinMaxOps(int Op)
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition: Lint.cpp:512
#define I(x, y, z)
Definition: MD5.cpp:58
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition: APInt.h:214
APInt zext(unsigned width) const
Zero extend to a new width.
Definition: APInt.cpp:981
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition: APInt.h:1472
APInt trunc(unsigned width) const
Truncate to new width.
Definition: APInt.cpp:906
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Definition: APInt.h:186
unsigned countLeadingOnes() const
Definition: APInt.h:1583
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition: APInt.h:1162
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition: APInt.h:189
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
Definition: APInt.h:1229
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition: APInt.h:199
unsigned countTrailingZeros() const
Definition: APInt.h:1606
unsigned countLeadingZeros() const
Definition: APInt.h:1565
APInt sext(unsigned width) const
Sign extend to a new width.
Definition: APInt.cpp:954
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
Definition: APInt.h:1237
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition: APInt.h:286
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition: APInt.h:276
unsigned countTrailingOnes() const
Definition: APInt.h:1621
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition: APInt.h:219
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.h:831
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition: APInt.h:1201
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition: ArrayRef.h:195
This is an SDNode representing atomic operations.
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:146
const ConstantInt * getConstantIntValue() const
uint64_t getZExtValue() const
This is an important base class in LLVM.
Definition: Constant.h:42
@ NewNode
This is a new node, not before seen, that was created in the process of legalizing some other node.
Definition: LegalizeTypes.h:43
This class represents an Operation in the Expression.
bool isLittleEndian() const
Layout endianness...
Definition: DataLayout.h:238
bool isBigEndian() const
Definition: DataLayout.h:239
This class is used to represent ISD::LOAD nodes.
Machine Value Type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Flags
Flags values. These may be or'd together.
This class is used to represent an MGATHER node.
This class is used to represent an MLOAD node.
This class is used to represent an MSCATTER node.
This class is used to represent an MSTORE node.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
EVT getMemoryVT() const
Return the type of the in-memory value.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:662
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Represents a use of a SDNode.
EVT getValueType() const
Convenience function for get().getValueType().
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
void dump() const
EVT getValueType() const
Return the ValueType of the referenced return value.
uint64_t getScalarValueSizeInBits() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:227
SDValue getVPZeroExtendInReg(SDValue Op, SDValue Mask, SDValue EVL, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
Definition: SelectionDAG.h:969
unsigned ComputeMaxSignificantBits(SDValue Op, unsigned Depth=0) const
Get the upper bound on bit size for this Value Op as a signed integer.
SDValue getMaskedGather(SDVTList VTs, EVT MemVT, const SDLoc &dl, ArrayRef< SDValue > Ops, MachineMemOperand *MMO, ISD::MemIndexType IndexType, ISD::LoadExtType ExtTy)
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
SDValue getVScale(const SDLoc &DL, EVT VT, APInt MulImm, bool ConstantFold=true)
Return a node that represents the runtime scaling 'MulImm * RuntimeVL'.
SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDVTList VTs, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, MachineMemOperand *MMO)
Gets a node for an atomic cmpxchg op.
void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To, unsigned Num)
Like ReplaceAllUsesOfValueWith, but for multiple values at once.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
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 getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
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.
Definition: SelectionDAG.h:843
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...
SDValue getNegative(SDValue Val, const SDLoc &DL, EVT VT)
Create negative operation as (SUB 0, Val).
SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:488
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue SV, unsigned Align)
VAArg produces a result and token chain, and takes a pointer and a source value as input.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
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 ...
SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Base, SDValue Offset, SDValue Mask, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexedMode AM, bool IsTruncating=false, bool IsCompressing=false)
SDValue getExternalSymbol(const char *Sym, EVT VT)
std::pair< SDValue, SDValue > SplitEVL(SDValue N, EVT VecVT, const SDLoc &DL)
Split the explicit vector length parameter of a VP operation.
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:691
const TargetLibraryInfo & getLibInfo() const
Definition: SelectionDAG.h:495
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:483
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
Definition: SelectionDAG.h:501
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
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.
Definition: SelectionDAG.h:571
SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Base, SDValue Offset, SDValue Mask, SDValue Src0, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexedMode AM, ISD::LoadExtType, bool IsExpanding=false)
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
SDValue getMaskedScatter(SDVTList VTs, EVT MemVT, const SDLoc &dl, ArrayRef< SDValue > Ops, MachineMemOperand *MMO, ISD::MemIndexType IndexType, bool IsTruncating=false)
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
ArrayRef< int > getMask() const
void reserve(size_type N)
Definition: SmallVector.h:676
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:696
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
This class is used to represent ISD::STORE nodes.
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const
Get the CallingConv that should be used for the specified libcall.
ShiftLegalizationStrategy
Return the preferred strategy to legalize tihs SHIFT instruction, with ExpansionFactor being the recu...
EVT getTypeToExpandTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const
Return the number of registers that this ValueType will eventually require.
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.
virtual ISD::NodeType getExtendForAtomicOps() const
Returns how the platform's atomic operations are extended (ZERO_EXTEND, SIGN_EXTEND,...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
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.
virtual ISD::NodeType getExtendForAtomicCmpSwapArg() const
Returns how the platform's atomic compare and swap expects its comparison value to be extended (ZERO_...
BooleanContent
Enum that describes how the target represents true/false values.
virtual ShiftLegalizationStrategy preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const
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...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
std::vector< ArgListEntry > ArgListTy
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
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...
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...
static ISD::NodeType getExtendForContent(BooleanContent Content)
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 expandMUL(SDNode *N, SDValue &Lo, SDValue &Hi, EVT HiLoVT, SelectionDAG &DAG, MulExpansionKind Kind, SDValue LL=SDValue(), SDValue LH=SDValue(), SDValue RL=SDValue(), SDValue RH=SDValue()) const
Expand a MUL into two nodes.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue expandCTLZ(SDNode *N, SelectionDAG &DAG) const
Expand CTLZ/CTLZ_ZERO_UNDEF nodes.
SDValue expandBITREVERSE(SDNode *N, SelectionDAG &DAG) const
Expand BITREVERSE nodes.
SDValue expandCTTZ(SDNode *N, SelectionDAG &DAG) const
Expand CTTZ/CTTZ_ZERO_UNDEF nodes.
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 expandABS(SDNode *N, SelectionDAG &DAG, bool IsNegative=false) const
Expand ABS nodes.
SDValue expandVecReduce(SDNode *Node, SelectionDAG &DAG) const
Expand a VECREDUCE_* into an explicit calculation.
SDValue expandCTPOP(SDNode *N, SelectionDAG &DAG) const
Expand CTPOP nodes.
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.
bool expandDIVREMByConstant(SDNode *N, SmallVectorImpl< SDValue > &Result, EVT HiLoVT, SelectionDAG &DAG, SDValue LL=SDValue(), SDValue LH=SDValue()) const
Attempt to expand an n-bit div/rem/divrem by constant using a n/2-bit urem by constant and other arit...
void forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl, bool Signed, EVT WideVT, const SDValue LL, const SDValue LH, const SDValue RL, const SDValue RH, SDValue &Lo, SDValue &Hi) const
forceExpandWideMUL - Unconditionally expand a MUL into either a libcall or brute force via a wide mul...
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, bool foldBooleans, DAGCombinerInfo &DCI, const SDLoc &dl) const
Try to simplify a setcc built with the specified operands and cc.
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 expandROT(SDNode *N, bool AllowVectorOps, SelectionDAG &DAG) const
Expand rotations.
SDValue expandCMP(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]CMP.
bool expandMUL_LOHI(unsigned Opcode, EVT VT, const SDLoc &dl, SDValue LHS, SDValue RHS, SmallVectorImpl< SDValue > &Result, EVT HiLoVT, SelectionDAG &DAG, MulExpansionKind Kind, SDValue LL=SDValue(), SDValue LH=SDValue(), SDValue RL=SDValue(), SDValue RH=SDValue()) const
Expand a MUL or [US]MUL_LOHI of n-bit values into two or four nodes, respectively,...
SDValue expandAVG(SDNode *N, SelectionDAG &DAG) const
Expand vector/scalar AVGCEILS/AVGCEILU/AVGFLOORS/AVGFLOORU nodes.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:345
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:129
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
Definition: TypeSize.h:271
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
Definition: TypeSize.h:279
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:168
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
Definition: TypeSize.h:254
#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.
Definition: BitmaskEnum.h:121
@ Entry
Definition: COFF.h:811
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition: ISDOpcodes.h:40
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:779
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition: ISDOpcodes.h:243
@ CTLZ_ZERO_UNDEF
Definition: ISDOpcodes.h:752
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition: ISDOpcodes.h:490
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
Definition: ISDOpcodes.h:1330
@ VECREDUCE_SMIN
Definition: ISDOpcodes.h:1415
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:257
@ ATOMIC_LOAD_NAND
Definition: ISDOpcodes.h:1312
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition: ISDOpcodes.h:573
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:743
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
Definition: ISDOpcodes.h:374
@ ATOMIC_LOAD_MAX
Definition: ISDOpcodes.h:1314
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
Definition: ISDOpcodes.h:1284
@ ATOMIC_LOAD_UMIN
Definition: ISDOpcodes.h:1315
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:276
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1074
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
Definition: ISDOpcodes.h:380
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:813
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
Definition: ISDOpcodes.h:1297
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:820
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition: ISDOpcodes.h:557
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:716
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
Definition: ISDOpcodes.h:850
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:262
@ VECREDUCE_SMAX
Definition: ISDOpcodes.h:1414
@ STRICT_FSETCCS
Definition: ISDOpcodes.h:491
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:943
@ ATOMIC_LOAD_OR
Definition: ISDOpcodes.h:1310
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:933
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition: ISDOpcodes.h:236
@ ATOMIC_LOAD_XOR
Definition: ISDOpcodes.h:1311
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
Definition: ISDOpcodes.h:976
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
Definition: ISDOpcodes.h:387
@ SET_ROUNDING
Set rounding mode.
Definition: ISDOpcodes.h:915
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:804
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition: ISDOpcodes.h:684
@ STRICT_UINT_TO_FP
Definition: ISDOpcodes.h:464
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition: ISDOpcodes.h:634
@ READSTEADYCOUNTER
READSTEADYCOUNTER - This corresponds to the readfixedcounter intrinsic.
Definition: ISDOpcodes.h:1231
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
Definition: ISDOpcodes.h:751
@ SETCCCARRY
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
Definition: ISDOpcodes.h:787
@ STRICT_LROUND
Definition: ISDOpcodes.h:445
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1120
@ SSUBO
Same for subtraction.
Definition: ISDOpcodes.h:334
@ ATOMIC_LOAD_MIN
Definition: ISDOpcodes.h:1313
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2) - Returns two vectors with all input and output vectors having the same...
Definition: ISDOpcodes.h:600
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
Definition: ISDOpcodes.h:660
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
Definition: ISDOpcodes.h:521
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition: ISDOpcodes.h:356
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:756
@ STRICT_FPOWI
Definition: ISDOpcodes.h:420
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
Definition: ISDOpcodes.h:1280
@ UNDEF
UNDEF - An undefined node.
Definition: ISDOpcodes.h:218
@ VECREDUCE_UMAX
Definition: ISDOpcodes.h:1416
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
Definition: ISDOpcodes.h:229
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition: ISDOpcodes.h:641
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition: ISDOpcodes.h:330
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
Definition: ISDOpcodes.h:1268
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
Definition: ISDOpcodes.h:1409
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
Definition: ISDOpcodes.h:910
@ STRICT_FP_TO_FP16
Definition: ISDOpcodes.h:946
@ STRICT_FP16_TO_FP
Definition: ISDOpcodes.h:945
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:734
@ ATOMIC_LOAD_CLR
Definition: ISDOpcodes.h:1309
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition: ISDOpcodes.h:614
@ ATOMIC_LOAD_AND
Definition: ISDOpcodes.h:1308
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition: ISDOpcodes.h:587
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:549
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:810
@ FP_TO_UINT_SAT
Definition: ISDOpcodes.h:886
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:771
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
Definition: ISDOpcodes.h:1372
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
Definition: ISDOpcodes.h:1291
@ ATOMIC_LOAD_UMAX
Definition: ISDOpcodes.h:1316
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
Definition: ISDOpcodes.h:366
@ SMULO
Same for multiplication.
Definition: ISDOpcodes.h:338
@ STRICT_LRINT
Definition: ISDOpcodes.h:447
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
Definition: ISDOpcodes.h:839
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:828
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition: ISDOpcodes.h:696
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
Definition: ISDOpcodes.h:605
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
Definition: ISDOpcodes.h:393
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition: ISDOpcodes.h:918
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition: ISDOpcodes.h:765
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:310
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition: ISDOpcodes.h:463
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
Definition: ISDOpcodes.h:1342
@ VECREDUCE_UMIN
Definition: ISDOpcodes.h:1417
@ BF16_TO_FP
BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions and truncation for bfloat16.
Definition: ISDOpcodes.h:952
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:100
@ ATOMIC_LOAD_ADD
Definition: ISDOpcodes.h:1306
@ STRICT_FP_TO_UINT
Definition: ISDOpcodes.h:457
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:456
@ ATOMIC_LOAD_SUB
Definition: ISDOpcodes.h:1307
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:866
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
Definition: ISDOpcodes.h:1225
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition: ISDOpcodes.h:484
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:708
@ STRICT_FP_TO_BF16
Definition: ISDOpcodes.h:955
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition: ISDOpcodes.h:704
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition: ISDOpcodes.h:679
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:286
@ SPLAT_VECTOR_PARTS
SPLAT_VECTOR_PARTS(SCALAR1, SCALAR2, ...) - Returns a vector with the scalar values joined together a...
Definition: ISDOpcodes.h:650
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
Definition: ISDOpcodes.h:223
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition: ISDOpcodes.h:538
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ STRICT_LLRINT
Definition: ISDOpcodes.h:448
@ VECTOR_SPLICE
VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as VEC1/VEC2 from CONCAT_VECTOR...
Definition: ISDOpcodes.h:626
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
Definition: ISDOpcodes.h:1305
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
Definition: ISDOpcodes.h:981
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
Definition: ISDOpcodes.h:668
@ STRICT_FLDEXP
Definition: ISDOpcodes.h:421
@ STRICT_LLROUND
Definition: ISDOpcodes.h:446
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
Definition: ISDOpcodes.h:861
@ 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:885
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:816
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1189
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1113
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:793
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition: ISDOpcodes.h:347
@ AssertZext
Definition: ISDOpcodes.h:62
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2) - Returns two vectors with all input and output vectors having the sa...
Definition: ISDOpcodes.h:594
@ SADDO_CARRY
Carry-using overflow-aware nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:320
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:529
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isTrueWhenEqual(CondCode Cond)
Return true if the specified condition returns true if the two operands to the condition are equal.
Definition: ISDOpcodes.h:1636
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
Definition: ISDOpcodes.h:1611
bool isUNINDEXEDStore(const SDNode *N)
Returns true if the specified node is an unindexed store.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1578
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1558
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
Definition: ISDOpcodes.h:1617
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
bool isIntEqualitySetCC(CondCode Code)
Return true if this is a setcc instruction that performs an equality comparison when used with intege...
Definition: ISDOpcodes.h:1623
Libcall getPOWI(EVT RetVT)
getPOWI - Return the POWI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getSYNC(unsigned Opc, MVT VT)
Return the SYNC_FETCH_AND_* value for the given opcode and type, or UNKNOWN_LIBCALL if there is none.
Libcall getLDEXP(EVT RetVT)
getLDEXP - Return the LDEXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, MVT VT)
Return the outline atomics value for the given opcode, atomic ordering and type, or UNKNOWN_LIBCALL i...
ManagedStatic< cl::opt< FnT >, OptCreatorT > Action
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition: MathExtras.h:547
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:340
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:291
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ AfterLegalizeTypes
Definition: DAGCombine.h:17
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ Add
Sum of integers.
DWARFExpression::Operation Op
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
#define N
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition: Metadata.h:760
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Extended Value Type.
Definition: ValueTypes.h:34
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition: ValueTypes.h:380
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:136
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:73
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
Definition: ValueTypes.h:290
ElementCount getVectorElementCount() const
Definition: ValueTypes.h:340
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:358
bool isByteSized() const
Return true if the bit size is a multiple of 8.
Definition: ValueTypes.h:233
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
Definition: ValueTypes.h:349
uint64_t getScalarSizeInBits() const
Definition: ValueTypes.h:370
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:306
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition: ValueTypes.h:64
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:167
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition: ValueTypes.h:313
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
Definition: ValueTypes.h:282
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
Definition: ValueTypes.h:246
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:203
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
Definition: ValueTypes.h:173
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:318
EVT changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
Definition: ValueTypes.h:101
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:326
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition: ValueTypes.h:298
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
Definition: ValueTypes.h:438
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
bool isZero() const
Returns true if value is all zero.
Definition: KnownBits.h:76
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
Definition: KnownBits.h:231
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
Definition: KnownBits.h:285
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
These are IR-level optimization flags that may be propagated to SDNodes.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.
This structure is used to pass arguments to makeLibCall function.
MakeLibCallOptions & setSExt(bool Value=true)