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