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