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.forceExpandMultiply(DAG, dl, /*Signed=*/false, Lo, Hi, LL, RL, LH, RH);
4300 return;
4301 }
4302
4303 // Note that we don't need to do a wide MUL here since we don't care about the
4304 // upper half of the result if it exceeds VT.
4305 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4307 CallOptions.setIsSigned(true);
4308 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first,
4309 Lo, Hi);
4310}
4311
4312void DAGTypeLegalizer::ExpandIntRes_READCOUNTER(SDNode *N, SDValue &Lo,
4313 SDValue &Hi) {
4314 SDLoc DL(N);
4315 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4316 SDVTList VTs = DAG.getVTList(NVT, NVT, MVT::Other);
4317 SDValue R = DAG.getNode(N->getOpcode(), DL, VTs, N->getOperand(0));
4318 Lo = R.getValue(0);
4319 Hi = R.getValue(1);
4320 ReplaceValueWith(SDValue(N, 1), R.getValue(2));
4321}
4322
4323void DAGTypeLegalizer::ExpandIntRes_AVG(SDNode *N, SDValue &Lo, SDValue &Hi) {
4324 SDValue Result = TLI.expandAVG(N, DAG);
4325 SplitInteger(Result, Lo, Hi);
4326}
4327
4328void DAGTypeLegalizer::ExpandIntRes_ADDSUBSAT(SDNode *N, SDValue &Lo,
4329 SDValue &Hi) {
4330 SDValue Result = TLI.expandAddSubSat(N, DAG);
4331 SplitInteger(Result, Lo, Hi);
4332}
4333
4334void DAGTypeLegalizer::ExpandIntRes_SHLSAT(SDNode *N, SDValue &Lo,
4335 SDValue &Hi) {
4336 SDValue Result = TLI.expandShlSat(N, DAG);
4337 SplitInteger(Result, Lo, Hi);
4338}
4339
4340/// This performs an expansion of the integer result for a fixed point
4341/// multiplication. The default expansion performs rounding down towards
4342/// negative infinity, though targets that do care about rounding should specify
4343/// a target hook for rounding and provide their own expansion or lowering of
4344/// fixed point multiplication to be consistent with rounding.
4345void DAGTypeLegalizer::ExpandIntRes_MULFIX(SDNode *N, SDValue &Lo,
4346 SDValue &Hi) {
4347 SDLoc dl(N);
4348 EVT VT = N->getValueType(0);
4349 unsigned VTSize = VT.getScalarSizeInBits();
4350 SDValue LHS = N->getOperand(0);
4351 SDValue RHS = N->getOperand(1);
4352 uint64_t Scale = N->getConstantOperandVal(2);
4353 bool Saturating = (N->getOpcode() == ISD::SMULFIXSAT ||
4354 N->getOpcode() == ISD::UMULFIXSAT);
4355 bool Signed = (N->getOpcode() == ISD::SMULFIX ||
4356 N->getOpcode() == ISD::SMULFIXSAT);
4357
4358 // Handle special case when scale is equal to zero.
4359 if (!Scale) {
4361 if (!Saturating) {
4362 Result = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS);
4363 } else {
4364 EVT BoolVT = getSetCCResultType(VT);
4365 unsigned MulOp = Signed ? ISD::SMULO : ISD::UMULO;
4366 Result = DAG.getNode(MulOp, dl, DAG.getVTList(VT, BoolVT), LHS, RHS);
4367 SDValue Product = Result.getValue(0);
4368 SDValue Overflow = Result.getValue(1);
4369 if (Signed) {
4370 APInt MinVal = APInt::getSignedMinValue(VTSize);
4371 APInt MaxVal = APInt::getSignedMaxValue(VTSize);
4372 SDValue SatMin = DAG.getConstant(MinVal, dl, VT);
4373 SDValue SatMax = DAG.getConstant(MaxVal, dl, VT);
4374 SDValue Zero = DAG.getConstant(0, dl, VT);
4375 // Xor the inputs, if resulting sign bit is 0 the product will be
4376 // positive, else negative.
4377 SDValue Xor = DAG.getNode(ISD::XOR, dl, VT, LHS, RHS);
4378 SDValue ProdNeg = DAG.getSetCC(dl, BoolVT, Xor, Zero, ISD::SETLT);
4379 Result = DAG.getSelect(dl, VT, ProdNeg, SatMin, SatMax);
4380 Result = DAG.getSelect(dl, VT, Overflow, Result, Product);
4381 } else {
4382 // For unsigned multiplication, we only need to check the max since we
4383 // can't really overflow towards zero.
4384 APInt MaxVal = APInt::getMaxValue(VTSize);
4385 SDValue SatMax = DAG.getConstant(MaxVal, dl, VT);
4386 Result = DAG.getSelect(dl, VT, Overflow, SatMax, Product);
4387 }
4388 }
4389 SplitInteger(Result, Lo, Hi);
4390 return;
4391 }
4392
4393 // For SMULFIX[SAT] we only expect to find Scale<VTSize, but this assert will
4394 // cover for unhandled cases below, while still being valid for UMULFIX[SAT].
4395 assert(Scale <= VTSize && "Scale can't be larger than the value type size.");
4396
4397 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4398 SDValue LL, LH, RL, RH;
4399 GetExpandedInteger(LHS, LL, LH);
4400 GetExpandedInteger(RHS, RL, RH);
4402
4403 unsigned LoHiOp = Signed ? ISD::SMUL_LOHI : ISD::UMUL_LOHI;
4404 if (!TLI.expandMUL_LOHI(LoHiOp, VT, dl, LHS, RHS, Result, NVT, DAG,
4406 LL, LH, RL, RH)) {
4407 Result.clear();
4408 Result.resize(4);
4409
4410 SDValue LoTmp, HiTmp;
4411 TLI.forceExpandWideMUL(DAG, dl, Signed, LHS, RHS, LoTmp, HiTmp);
4412 SplitInteger(LoTmp, Result[0], Result[1]);
4413 SplitInteger(HiTmp, Result[2], Result[3]);
4414 }
4415 assert(Result.size() == 4 && "Unexpected number of partlets in the result");
4416
4417 unsigned NVTSize = NVT.getScalarSizeInBits();
4418 assert((VTSize == NVTSize * 2) && "Expected the new value type to be half "
4419 "the size of the current value type");
4420
4421 // After getting the multiplication result in 4 parts, we need to perform a
4422 // shift right by the amount of the scale to get the result in that scale.
4423 //
4424 // Let's say we multiply 2 64 bit numbers. The resulting value can be held in
4425 // 128 bits that are cut into 4 32-bit parts:
4426 //
4427 // HH HL LH LL
4428 // |---32---|---32---|---32---|---32---|
4429 // 128 96 64 32 0
4430 //
4431 // |------VTSize-----|
4432 //
4433 // |NVTSize-|
4434 //
4435 // The resulting Lo and Hi would normally be in LL and LH after the shift. But
4436 // to avoid unneccessary shifting of all 4 parts, we can adjust the shift
4437 // amount and get Lo and Hi using two funnel shifts. Or for the special case
4438 // when Scale is a multiple of NVTSize we can just pick the result without
4439 // shifting.
4440 uint64_t Part0 = Scale / NVTSize; // Part holding lowest bit needed.
4441 if (Scale % NVTSize) {
4442 SDValue ShiftAmount = DAG.getShiftAmountConstant(Scale % NVTSize, NVT, dl);
4443 Lo = DAG.getNode(ISD::FSHR, dl, NVT, Result[Part0 + 1], Result[Part0],
4444 ShiftAmount);
4445 Hi = DAG.getNode(ISD::FSHR, dl, NVT, Result[Part0 + 2], Result[Part0 + 1],
4446 ShiftAmount);
4447 } else {
4448 Lo = Result[Part0];
4449 Hi = Result[Part0 + 1];
4450 }
4451
4452 // Unless saturation is requested we are done. The result is in <Hi,Lo>.
4453 if (!Saturating)
4454 return;
4455
4456 // Can not overflow when there is no integer part.
4457 if (Scale == VTSize)
4458 return;
4459
4460 // To handle saturation we must check for overflow in the multiplication.
4461 //
4462 // Unsigned overflow happened if the upper (VTSize - Scale) bits (of Result)
4463 // aren't all zeroes.
4464 //
4465 // Signed overflow happened if the upper (VTSize - Scale + 1) bits (of Result)
4466 // aren't all ones or all zeroes.
4467 //
4468 // We cannot overflow past HH when multiplying 2 ints of size VTSize, so the
4469 // highest bit of HH determines saturation direction in the event of signed
4470 // saturation.
4471
4472 SDValue ResultHL = Result[2];
4473 SDValue ResultHH = Result[3];
4474
4475 SDValue SatMax, SatMin;
4476 SDValue NVTZero = DAG.getConstant(0, dl, NVT);
4477 SDValue NVTNeg1 = DAG.getAllOnesConstant(dl, NVT);
4478 EVT BoolNVT = getSetCCResultType(NVT);
4479
4480 if (!Signed) {
4481 if (Scale < NVTSize) {
4482 // Overflow happened if ((HH | (HL >> Scale)) != 0).
4483 SDValue HLAdjusted =
4484 DAG.getNode(ISD::SRL, dl, NVT, ResultHL,
4485 DAG.getShiftAmountConstant(Scale, NVT, dl));
4486 SDValue Tmp = DAG.getNode(ISD::OR, dl, NVT, HLAdjusted, ResultHH);
4487 SatMax = DAG.getSetCC(dl, BoolNVT, Tmp, NVTZero, ISD::SETNE);
4488 } else if (Scale == NVTSize) {
4489 // Overflow happened if (HH != 0).
4490 SatMax = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETNE);
4491 } else if (Scale < VTSize) {
4492 // Overflow happened if ((HH >> (Scale - NVTSize)) != 0).
4493 SDValue HLAdjusted =
4494 DAG.getNode(ISD::SRL, dl, NVT, ResultHL,
4495 DAG.getShiftAmountConstant(Scale - NVTSize, NVT, dl));
4496 SatMax = DAG.getSetCC(dl, BoolNVT, HLAdjusted, NVTZero, ISD::SETNE);
4497 } else
4498 llvm_unreachable("Scale must be less or equal to VTSize for UMULFIXSAT"
4499 "(and saturation can't happen with Scale==VTSize).");
4500
4501 Hi = DAG.getSelect(dl, NVT, SatMax, NVTNeg1, Hi);
4502 Lo = DAG.getSelect(dl, NVT, SatMax, NVTNeg1, Lo);
4503 return;
4504 }
4505
4506 if (Scale < NVTSize) {
4507 // The number of overflow bits we can check are VTSize - Scale + 1 (we
4508 // include the sign bit). If these top bits are > 0, then we overflowed past
4509 // the max value. If these top bits are < -1, then we overflowed past the
4510 // min value. Otherwise, we did not overflow.
4511 unsigned OverflowBits = VTSize - Scale + 1;
4512 assert(OverflowBits <= VTSize && OverflowBits > NVTSize &&
4513 "Extent of overflow bits must start within HL");
4514 SDValue HLHiMask = DAG.getConstant(
4515 APInt::getHighBitsSet(NVTSize, OverflowBits - NVTSize), dl, NVT);
4516 SDValue HLLoMask = DAG.getConstant(
4517 APInt::getLowBitsSet(NVTSize, VTSize - OverflowBits), dl, NVT);
4518 // We overflow max if HH > 0 or (HH == 0 && HL > HLLoMask).
4519 SDValue HHGT0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETGT);
4520 SDValue HHEQ0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETEQ);
4521 SDValue HLUGT = DAG.getSetCC(dl, BoolNVT, ResultHL, HLLoMask, ISD::SETUGT);
4522 SatMax = DAG.getNode(ISD::OR, dl, BoolNVT, HHGT0,
4523 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ0, HLUGT));
4524 // We overflow min if HH < -1 or (HH == -1 && HL < HLHiMask).
4525 SDValue HHLT = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETLT);
4526 SDValue HHEQ = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETEQ);
4527 SDValue HLULT = DAG.getSetCC(dl, BoolNVT, ResultHL, HLHiMask, ISD::SETULT);
4528 SatMin = DAG.getNode(ISD::OR, dl, BoolNVT, HHLT,
4529 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ, HLULT));
4530 } else if (Scale == NVTSize) {
4531 // We overflow max if HH > 0 or (HH == 0 && HL sign bit is 1).
4532 SDValue HHGT0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETGT);
4533 SDValue HHEQ0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETEQ);
4534 SDValue HLNeg = DAG.getSetCC(dl, BoolNVT, ResultHL, NVTZero, ISD::SETLT);
4535 SatMax = DAG.getNode(ISD::OR, dl, BoolNVT, HHGT0,
4536 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ0, HLNeg));
4537 // We overflow min if HH < -1 or (HH == -1 && HL sign bit is 0).
4538 SDValue HHLT = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETLT);
4539 SDValue HHEQ = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETEQ);
4540 SDValue HLPos = DAG.getSetCC(dl, BoolNVT, ResultHL, NVTZero, ISD::SETGE);
4541 SatMin = DAG.getNode(ISD::OR, dl, BoolNVT, HHLT,
4542 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ, HLPos));
4543 } else if (Scale < VTSize) {
4544 // This is similar to the case when we saturate if Scale < NVTSize, but we
4545 // only need to check HH.
4546 unsigned OverflowBits = VTSize - Scale + 1;
4547 SDValue HHHiMask = DAG.getConstant(
4548 APInt::getHighBitsSet(NVTSize, OverflowBits), dl, NVT);
4549 SDValue HHLoMask = DAG.getConstant(
4550 APInt::getLowBitsSet(NVTSize, NVTSize - OverflowBits), dl, NVT);
4551 SatMax = DAG.getSetCC(dl, BoolNVT, ResultHH, HHLoMask, ISD::SETGT);
4552 SatMin = DAG.getSetCC(dl, BoolNVT, ResultHH, HHHiMask, ISD::SETLT);
4553 } else
4554 llvm_unreachable("Illegal scale for signed fixed point mul.");
4555
4556 // Saturate to signed maximum.
4557 APInt MaxHi = APInt::getSignedMaxValue(NVTSize);
4558 APInt MaxLo = APInt::getAllOnes(NVTSize);
4559 Hi = DAG.getSelect(dl, NVT, SatMax, DAG.getConstant(MaxHi, dl, NVT), Hi);
4560 Lo = DAG.getSelect(dl, NVT, SatMax, DAG.getConstant(MaxLo, dl, NVT), Lo);
4561 // Saturate to signed minimum.
4562 APInt MinHi = APInt::getSignedMinValue(NVTSize);
4563 Hi = DAG.getSelect(dl, NVT, SatMin, DAG.getConstant(MinHi, dl, NVT), Hi);
4564 Lo = DAG.getSelect(dl, NVT, SatMin, NVTZero, Lo);
4565}
4566
4567void DAGTypeLegalizer::ExpandIntRes_DIVFIX(SDNode *N, SDValue &Lo,
4568 SDValue &Hi) {
4569 SDLoc dl(N);
4570 // Try expanding in the existing type first.
4571 SDValue Res = TLI.expandFixedPointDiv(N->getOpcode(), dl, N->getOperand(0),
4572 N->getOperand(1),
4573 N->getConstantOperandVal(2), DAG);
4574
4575 if (!Res)
4576 Res = earlyExpandDIVFIX(N, N->getOperand(0), N->getOperand(1),
4577 N->getConstantOperandVal(2), TLI, DAG);
4578 SplitInteger(Res, Lo, Hi);
4579}
4580
4581void DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node,
4582 SDValue &Lo, SDValue &Hi) {
4583 assert((Node->getOpcode() == ISD::SADDO || Node->getOpcode() == ISD::SSUBO) &&
4584 "Node has unexpected Opcode");
4585 SDValue LHS = Node->getOperand(0);
4586 SDValue RHS = Node->getOperand(1);
4587 SDLoc dl(Node);
4588
4589 SDValue Ovf;
4590
4591 bool IsAdd = Node->getOpcode() == ISD::SADDO;
4592 unsigned CarryOp = IsAdd ? ISD::SADDO_CARRY : ISD::SSUBO_CARRY;
4593
4594 bool HasCarryOp = TLI.isOperationLegalOrCustom(
4595 CarryOp, TLI.getTypeToExpandTo(*DAG.getContext(), LHS.getValueType()));
4596
4597 if (HasCarryOp) {
4598 // Expand the subcomponents.
4599 SDValue LHSL, LHSH, RHSL, RHSH;
4600 GetExpandedInteger(LHS, LHSL, LHSH);
4601 GetExpandedInteger(RHS, RHSL, RHSH);
4602 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), Node->getValueType(1));
4603
4604 Lo = DAG.getNode(IsAdd ? ISD::UADDO : ISD::USUBO, dl, VTList, {LHSL, RHSL});
4605 Hi = DAG.getNode(CarryOp, dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
4606
4607 Ovf = Hi.getValue(1);
4608 } else {
4609 // Expand the result by simply replacing it with the equivalent
4610 // non-overflow-checking operation.
4611 SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
4612 ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
4613 LHS, RHS);
4614 SplitInteger(Sum, Lo, Hi);
4615
4616 // Compute the overflow.
4617 //
4618 // LHSSign -> LHS < 0
4619 // RHSSign -> RHS < 0
4620 // SumSign -> Sum < 0
4621 //
4622 // Add:
4623 // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
4624 // Sub:
4625 // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
4626 //
4627 // To get better codegen we can rewrite this by doing bitwise math on
4628 // the integers and extract the final sign bit at the end. So the
4629 // above becomes:
4630 //
4631 // Add:
4632 // Overflow -> (~(LHS ^ RHS) & (LHS ^ Sum)) < 0
4633 // Sub:
4634 // Overflow -> ((LHS ^ RHS) & (LHS ^ Sum)) < 0
4635 //
4636 // NOTE: This is different than the expansion we do in expandSADDSUBO
4637 // because it is more costly to determine the RHS is > 0 for SSUBO with the
4638 // integers split.
4639 EVT VT = LHS.getValueType();
4640 SDValue SignsMatch = DAG.getNode(ISD::XOR, dl, VT, LHS, RHS);
4641 if (IsAdd)
4642 SignsMatch = DAG.getNOT(dl, SignsMatch, VT);
4643
4644 SDValue SumSignNE = DAG.getNode(ISD::XOR, dl, VT, LHS, Sum);
4645 Ovf = DAG.getNode(ISD::AND, dl, VT, SignsMatch, SumSignNE);
4646 EVT OType = Node->getValueType(1);
4647 Ovf = DAG.getSetCC(dl, OType, Ovf, DAG.getConstant(0, dl, VT), ISD::SETLT);
4648 }
4649
4650 // Use the calculated overflow everywhere.
4651 ReplaceValueWith(SDValue(Node, 1), Ovf);
4652}
4653
4654void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
4655 SDValue &Lo, SDValue &Hi) {
4656 EVT VT = N->getValueType(0);
4657 SDLoc dl(N);
4658 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4659
4661 SDValue Res = DAG.getNode(ISD::SDIVREM, dl, DAG.getVTList(VT, VT), Ops);
4662 SplitInteger(Res.getValue(0), Lo, Hi);
4663 return;
4664 }
4665
4666 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4667 if (VT == MVT::i16)
4668 LC = RTLIB::SDIV_I16;
4669 else if (VT == MVT::i32)
4670 LC = RTLIB::SDIV_I32;
4671 else if (VT == MVT::i64)
4672 LC = RTLIB::SDIV_I64;
4673 else if (VT == MVT::i128)
4674 LC = RTLIB::SDIV_I128;
4675 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
4676
4678 CallOptions.setIsSigned(true);
4679 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
4680}
4681
4682void DAGTypeLegalizer::ExpandIntRes_ShiftThroughStack(SDNode *N, SDValue &Lo,
4683 SDValue &Hi) {
4684 SDLoc dl(N);
4685 SDValue Shiftee = N->getOperand(0);
4686 EVT VT = Shiftee.getValueType();
4687 SDValue ShAmt = N->getOperand(1);
4688 EVT ShAmtVT = ShAmt.getValueType();
4689
4690 EVT LoadVT = VT;
4691 do {
4692 LoadVT = TLI.getTypeToTransformTo(*DAG.getContext(), LoadVT);
4693 } while (!TLI.isTypeLegal(LoadVT));
4694
4695 const unsigned ShiftUnitInBits = LoadVT.getStoreSizeInBits();
4696 assert(ShiftUnitInBits <= VT.getScalarSizeInBits());
4697 assert(isPowerOf2_32(ShiftUnitInBits) &&
4698 "Shifting unit is not a a power of two!");
4699
4700 const bool IsOneStepShift =
4702 Log2_32(ShiftUnitInBits);
4703
4704 // If we can't do it as one step, we'll have two uses of shift amount,
4705 // and thus must freeze it.
4706 if (!IsOneStepShift)
4707 ShAmt = DAG.getFreeze(ShAmt);
4708
4709 unsigned VTBitWidth = VT.getScalarSizeInBits();
4710 assert(VTBitWidth % 8 == 0 && "Shifting a not byte multiple value?");
4711 unsigned VTByteWidth = VTBitWidth / 8;
4712 assert(isPowerOf2_32(VTByteWidth) &&
4713 "Shiftee type size is not a power of two!");
4714 unsigned StackSlotByteWidth = 2 * VTByteWidth;
4715 unsigned StackSlotBitWidth = 8 * StackSlotByteWidth;
4716 EVT StackSlotVT = EVT::getIntegerVT(*DAG.getContext(), StackSlotBitWidth);
4717
4718 // Get a temporary stack slot 2x the width of our VT.
4719 // FIXME: reuse stack slots?
4720 Align StackAlign = DAG.getReducedAlign(StackSlotVT, /*UseABI=*/false);
4722 DAG.CreateStackTemporary(StackSlotVT.getStoreSize(), StackAlign);
4723 EVT PtrTy = StackPtr.getValueType();
4724 SDValue Ch = DAG.getEntryNode();
4725
4727 DAG.getMachineFunction(),
4728 cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex());
4729
4730 // Extend the value, that is being shifted, to the entire stack slot's width.
4731 SDValue Init;
4732 if (N->getOpcode() != ISD::SHL) {
4733 unsigned WideningOpc =
4734 N->getOpcode() == ISD::SRA ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
4735 Init = DAG.getNode(WideningOpc, dl, StackSlotVT, Shiftee);
4736 } else {
4737 // For left-shifts, pad the Shiftee's LSB with zeros to twice it's width.
4738 SDValue AllZeros = DAG.getConstant(0, dl, VT);
4739 Init = DAG.getNode(ISD::BUILD_PAIR, dl, StackSlotVT, AllZeros, Shiftee);
4740 }
4741 // And spill it into the stack slot.
4742 Ch = DAG.getStore(Ch, dl, Init, StackPtr, StackPtrInfo, StackAlign);
4743
4744 // Now, compute the full-byte offset into stack slot from where we can load.
4745 // We have shift amount, which is in bits. Offset should point to an aligned
4746 // address.
4748 Flags.setExact(IsOneStepShift);
4749 SDValue SrlTmp = DAG.getNode(
4750 ISD::SRL, dl, ShAmtVT, ShAmt,
4751 DAG.getConstant(Log2_32(ShiftUnitInBits), dl, ShAmtVT), Flags);
4752 SDValue BitOffset =
4753 DAG.getNode(ISD::SHL, dl, ShAmtVT, SrlTmp,
4754 DAG.getConstant(Log2_32(ShiftUnitInBits), dl, ShAmtVT));
4755
4756 SDValue ByteOffset =
4757 DAG.getNode(ISD::SRL, dl, ShAmtVT, BitOffset,
4758 DAG.getConstant(3, dl, ShAmtVT), SDNodeFlags::Exact);
4759 // And clamp it, because OOB load is an immediate UB,
4760 // while shift overflow would have *just* been poison.
4761 ByteOffset = DAG.getNode(ISD::AND, dl, ShAmtVT, ByteOffset,
4762 DAG.getConstant(VTByteWidth - 1, dl, ShAmtVT));
4763 // We have exactly two strategies on indexing into stack slot here:
4764 // 1. upwards starting from the beginning of the slot
4765 // 2. downwards starting from the middle of the slot
4766 // On little-endian machine, we pick 1. for right shifts and 2. for left-shift
4767 // and vice versa on big-endian machine.
4768 bool WillIndexUpwards = N->getOpcode() != ISD::SHL;
4769 if (DAG.getDataLayout().isBigEndian())
4770 WillIndexUpwards = !WillIndexUpwards;
4771
4772 SDValue AdjStackPtr;
4773 if (WillIndexUpwards) {
4774 AdjStackPtr = StackPtr;
4775 } else {
4776 AdjStackPtr = DAG.getMemBasePlusOffset(
4777 StackPtr, DAG.getConstant(VTByteWidth, dl, PtrTy), dl);
4778 ByteOffset = DAG.getNegative(ByteOffset, dl, ShAmtVT);
4779 }
4780
4781 // Get the pointer somewhere into the stack slot from which we need to load.
4782 ByteOffset = DAG.getSExtOrTrunc(ByteOffset, dl, PtrTy);
4783 AdjStackPtr = DAG.getMemBasePlusOffset(AdjStackPtr, ByteOffset, dl);
4784
4785 // And load it! While the load is not legal, legalizing it is obvious.
4786 SDValue Res =
4787 DAG.getLoad(VT, dl, Ch, AdjStackPtr,
4789 commonAlignment(StackAlign, LoadVT.getStoreSize()));
4790
4791 // If we may still have a remaining bits to shift by, do so now.
4792 if (!IsOneStepShift) {
4793 SDValue ShAmtRem =
4794 DAG.getNode(ISD::AND, dl, ShAmtVT, ShAmt,
4795 DAG.getConstant(ShiftUnitInBits - 1, dl, ShAmtVT));
4796 Res = DAG.getNode(N->getOpcode(), dl, VT, Res, ShAmtRem);
4797 }
4798
4799 // Finally, split the computed value.
4800 SplitInteger(Res, Lo, Hi);
4801}
4802
4803void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
4804 SDValue &Lo, SDValue &Hi) {
4805 EVT VT = N->getValueType(0);
4806 unsigned Opc = N->getOpcode();
4807 SDLoc dl(N);
4808
4809 // If we can emit an efficient shift operation, do so now. Check to see if
4810 // the RHS is a constant.
4811 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
4812 return ExpandShiftByConstant(N, CN->getAPIntValue(), Lo, Hi);
4813
4814 // If we can determine that the high bit of the shift is zero or one, even if
4815 // the low bits are variable, emit this shift in an optimized form.
4816 if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
4817 return;
4818
4819 // If this target supports shift_PARTS, use it. First, map to the _PARTS opc.
4820 unsigned PartsOpc;
4821 if (Opc == ISD::SHL) {
4822 PartsOpc = ISD::SHL_PARTS;
4823 } else if (Opc == ISD::SRL) {
4824 PartsOpc = ISD::SRL_PARTS;
4825 } else {
4826 assert(Opc == ISD::SRA && "Unknown shift!");
4827 PartsOpc = ISD::SRA_PARTS;
4828 }
4829
4830 // Next check to see if the target supports this SHL_PARTS operation or if it
4831 // will custom expand it. Don't lower this to SHL_PARTS when we optimise for
4832 // size, but create a libcall instead.
4833 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4834 TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
4835 const bool LegalOrCustom =
4836 (Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
4837 Action == TargetLowering::Custom;
4838
4839 unsigned ExpansionFactor = 1;
4840 // That VT->NVT expansion is one step. But will we re-expand NVT?
4841 for (EVT TmpVT = NVT;;) {
4842 EVT NewTMPVT = TLI.getTypeToTransformTo(*DAG.getContext(), TmpVT);
4843 if (NewTMPVT == TmpVT)
4844 break;
4845 TmpVT = NewTMPVT;
4846 ++ExpansionFactor;
4847 }
4848
4850 TLI.preferredShiftLegalizationStrategy(DAG, N, ExpansionFactor);
4851
4853 return ExpandIntRes_ShiftThroughStack(N, Lo, Hi);
4854
4855 if (LegalOrCustom &&
4857 // Expand the subcomponents.
4858 SDValue LHSL, LHSH;
4859 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
4860 EVT VT = LHSL.getValueType();
4861
4862 // If the shift amount operand is coming from a vector legalization it may
4863 // have an illegal type. Fix that first by casting the operand, otherwise
4864 // the new SHL_PARTS operation would need further legalization.
4865 SDValue ShiftOp = N->getOperand(1);
4866 EVT ShiftTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
4867 if (ShiftOp.getValueType() != ShiftTy)
4868 ShiftOp = DAG.getZExtOrTrunc(ShiftOp, dl, ShiftTy);
4869
4870 SDValue Ops[] = { LHSL, LHSH, ShiftOp };
4871 Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops);
4872 Hi = Lo.getValue(1);
4873 return;
4874 }
4875
4876 // Otherwise, emit a libcall.
4877 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4878 bool isSigned;
4879 if (Opc == ISD::SHL) {
4880 isSigned = false; /*sign irrelevant*/
4881 if (VT == MVT::i16)
4882 LC = RTLIB::SHL_I16;
4883 else if (VT == MVT::i32)
4884 LC = RTLIB::SHL_I32;
4885 else if (VT == MVT::i64)
4886 LC = RTLIB::SHL_I64;
4887 else if (VT == MVT::i128)
4888 LC = RTLIB::SHL_I128;
4889 } else if (Opc == ISD::SRL) {
4890 isSigned = false;
4891 if (VT == MVT::i16)
4892 LC = RTLIB::SRL_I16;
4893 else if (VT == MVT::i32)
4894 LC = RTLIB::SRL_I32;
4895 else if (VT == MVT::i64)
4896 LC = RTLIB::SRL_I64;
4897 else if (VT == MVT::i128)
4898 LC = RTLIB::SRL_I128;
4899 } else {
4900 assert(Opc == ISD::SRA && "Unknown shift!");
4901 isSigned = true;
4902 if (VT == MVT::i16)
4903 LC = RTLIB::SRA_I16;
4904 else if (VT == MVT::i32)
4905 LC = RTLIB::SRA_I32;
4906 else if (VT == MVT::i64)
4907 LC = RTLIB::SRA_I64;
4908 else if (VT == MVT::i128)
4909 LC = RTLIB::SRA_I128;
4910 }
4911
4912 if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
4913 EVT ShAmtTy =
4915 SDValue ShAmt = DAG.getZExtOrTrunc(N->getOperand(1), dl, ShAmtTy);
4916 SDValue Ops[2] = {N->getOperand(0), ShAmt};
4918 CallOptions.setIsSigned(isSigned);
4919 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
4920 return;
4921 }
4922
4923 if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi))
4924 llvm_unreachable("Unsupported shift!");
4925}
4926
4927void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
4928 SDValue &Lo, SDValue &Hi) {
4929 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4930 SDLoc dl(N);
4931 SDValue Op = N->getOperand(0);
4932 if (Op.getValueType().bitsLE(NVT)) {
4933 // The low part is sign extension of the input (degenerates to a copy).
4934 Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
4935 // The high part is obtained by SRA'ing all but one of the bits of low part.
4936 unsigned LoSize = NVT.getSizeInBits();
4937 Hi = DAG.getNode(
4938 ISD::SRA, dl, NVT, Lo,
4939 DAG.getConstant(LoSize - 1, dl, TLI.getPointerTy(DAG.getDataLayout())));
4940 } else {
4941 // For example, extension of an i48 to an i64. The operand type necessarily
4942 // promotes to the result type, so will end up being expanded too.
4943 assert(getTypeAction(Op.getValueType()) ==
4945 "Only know how to promote this result!");
4946 SDValue Res = GetPromotedInteger(Op);
4947 assert(Res.getValueType() == N->getValueType(0) &&
4948 "Operand over promoted?");
4949 // Split the promoted operand. This will simplify when it is expanded.
4950 SplitInteger(Res, Lo, Hi);
4951 unsigned ExcessBits = Op.getValueSizeInBits() - NVT.getSizeInBits();
4952 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
4954 ExcessBits)));
4955 }
4956}
4957
4958void DAGTypeLegalizer::
4959ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
4960 SDLoc dl(N);
4961 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4962 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
4963
4964 if (EVT.bitsLE(Lo.getValueType())) {
4965 // sext_inreg the low part if needed.
4966 Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
4967 N->getOperand(1));
4968
4969 // The high part gets the sign extension from the lo-part. This handles
4970 // things like sextinreg V:i64 from i8.
4971 Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
4972 DAG.getConstant(Hi.getValueSizeInBits() - 1, dl,
4973 TLI.getPointerTy(DAG.getDataLayout())));
4974 } else {
4975 // For example, extension of an i48 to an i64. Leave the low part alone,
4976 // sext_inreg the high part.
4977 unsigned ExcessBits = EVT.getSizeInBits() - Lo.getValueSizeInBits();
4978 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
4980 ExcessBits)));
4981 }
4982}
4983
4984void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
4985 SDValue &Lo, SDValue &Hi) {
4986 EVT VT = N->getValueType(0);
4987 SDLoc dl(N);
4988 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4989
4991 SDValue Res = DAG.getNode(ISD::SDIVREM, dl, DAG.getVTList(VT, VT), Ops);
4992 SplitInteger(Res.getValue(1), Lo, Hi);
4993 return;
4994 }
4995
4996 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4997 if (VT == MVT::i16)
4998 LC = RTLIB::SREM_I16;
4999 else if (VT == MVT::i32)
5000 LC = RTLIB::SREM_I32;
5001 else if (VT == MVT::i64)
5002 LC = RTLIB::SREM_I64;
5003 else if (VT == MVT::i128)
5004 LC = RTLIB::SREM_I128;
5005 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
5006
5008 CallOptions.setIsSigned(true);
5009 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5010}
5011
5012void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
5013 SDValue &Lo, SDValue &Hi) {
5014 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5015 SDLoc dl(N);
5016 Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
5017 Hi = DAG.getNode(ISD::SRL, dl, N->getOperand(0).getValueType(),
5018 N->getOperand(0),
5019 DAG.getConstant(NVT.getSizeInBits(), dl,
5020 TLI.getPointerTy(DAG.getDataLayout())));
5021 Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
5022}
5023
5024void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
5025 SDValue &Lo, SDValue &Hi) {
5026 EVT VT = N->getValueType(0);
5027 SDLoc dl(N);
5028
5029 if (N->getOpcode() == ISD::UMULO) {
5030 // This section expands the operation into the following sequence of
5031 // instructions. `iNh` here refers to a type which has half the bit width of
5032 // the type the original operation operated on.
5033 //
5034 // %0 = %LHS.HI != 0 && %RHS.HI != 0
5035 // %1 = { iNh, i1 } @umul.with.overflow.iNh(iNh %LHS.HI, iNh %RHS.LO)
5036 // %2 = { iNh, i1 } @umul.with.overflow.iNh(iNh %RHS.HI, iNh %LHS.LO)
5037 // %3 = mul nuw iN (%LHS.LOW as iN), (%RHS.LOW as iN)
5038 // %4 = add iNh %1.0, %2.0 as iN
5039 // %5 = { iNh, i1 } @uadd.with.overflow.iNh(iNh %4, iNh %3.HIGH)
5040 //
5041 // %lo = %3.LO
5042 // %hi = %5.0
5043 // %ovf = %0 || %1.1 || %2.1 || %5.1
5044 SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
5045 SDValue LHSHigh, LHSLow, RHSHigh, RHSLow;
5046 GetExpandedInteger(LHS, LHSLow, LHSHigh);
5047 GetExpandedInteger(RHS, RHSLow, RHSHigh);
5048 EVT HalfVT = LHSLow.getValueType();
5049 EVT BitVT = N->getValueType(1);
5050 SDVTList VTHalfWithO = DAG.getVTList(HalfVT, BitVT);
5051
5052 SDValue HalfZero = DAG.getConstant(0, dl, HalfVT);
5053 SDValue Overflow = DAG.getNode(ISD::AND, dl, BitVT,
5054 DAG.getSetCC(dl, BitVT, LHSHigh, HalfZero, ISD::SETNE),
5055 DAG.getSetCC(dl, BitVT, RHSHigh, HalfZero, ISD::SETNE));
5056
5057 SDValue One = DAG.getNode(ISD::UMULO, dl, VTHalfWithO, LHSHigh, RHSLow);
5058 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, One.getValue(1));
5059
5060 SDValue Two = DAG.getNode(ISD::UMULO, dl, VTHalfWithO, RHSHigh, LHSLow);
5061 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, Two.getValue(1));
5062
5063 SDValue HighSum = DAG.getNode(ISD::ADD, dl, HalfVT, One, Two);
5064
5065 // Cannot use `UMUL_LOHI` directly, because some 32-bit targets (ARM) do not
5066 // know how to expand `i64,i64 = umul_lohi a, b` and abort (why isn’t this
5067 // operation recursively legalized?).
5068 //
5069 // Many backends understand this pattern and will convert into LOHI
5070 // themselves, if applicable.
5071 SDValue Three = DAG.getNode(ISD::MUL, dl, VT,
5072 DAG.getNode(ISD::ZERO_EXTEND, dl, VT, LHSLow),
5073 DAG.getNode(ISD::ZERO_EXTEND, dl, VT, RHSLow));
5074 SplitInteger(Three, Lo, Hi);
5075
5076 Hi = DAG.getNode(ISD::UADDO, dl, VTHalfWithO, Hi, HighSum);
5077 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, Hi.getValue(1));
5078 ReplaceValueWith(SDValue(N, 1), Overflow);
5079 return;
5080 }
5081
5082 Type *RetTy = VT.getTypeForEVT(*DAG.getContext());
5083 EVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
5084 Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext());
5085
5086 // Replace this with a libcall that will check overflow.
5087 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5088 if (VT == MVT::i32)
5089 LC = RTLIB::MULO_I32;
5090 else if (VT == MVT::i64)
5091 LC = RTLIB::MULO_I64;
5092 else if (VT == MVT::i128)
5093 LC = RTLIB::MULO_I128;
5094
5095 // If we don't have the libcall or if the function we are compiling is the
5096 // implementation of the expected libcall (avoid inf-loop), expand inline.
5097 if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC) ||
5098 TLI.getLibcallName(LC) == DAG.getMachineFunction().getName()) {
5099 // FIXME: This is not an optimal expansion, but better than crashing.
5100 SDValue MulLo, MulHi;
5101 TLI.forceExpandWideMUL(DAG, dl, /*Signed=*/true, N->getOperand(0),
5102 N->getOperand(1), MulLo, MulHi);
5103 SDValue SRA =
5104 DAG.getNode(ISD::SRA, dl, VT, MulLo,
5105 DAG.getConstant(VT.getScalarSizeInBits() - 1, dl, VT));
5106 SDValue Overflow =
5107 DAG.getSetCC(dl, N->getValueType(1), MulHi, SRA, ISD::SETNE);
5108 SplitInteger(MulLo, Lo, Hi);
5109 ReplaceValueWith(SDValue(N, 1), Overflow);
5110 return;
5111 }
5112
5113 SDValue Temp = DAG.CreateStackTemporary(PtrVT);
5114 // Temporary for the overflow value, default it to zero.
5115 SDValue Chain =
5116 DAG.getStore(DAG.getEntryNode(), dl, DAG.getConstant(0, dl, PtrVT), Temp,
5118
5121 for (const SDValue &Op : N->op_values()) {
5122 EVT ArgVT = Op.getValueType();
5123 Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
5124 Entry.Node = Op;
5125 Entry.Ty = ArgTy;
5126 Entry.IsSExt = true;
5127 Entry.IsZExt = false;
5128 Args.push_back(Entry);
5129 }
5130
5131 // Also pass the address of the overflow check.
5132 Entry.Node = Temp;
5134 Entry.IsSExt = true;
5135 Entry.IsZExt = false;
5136 Args.push_back(Entry);
5137
5138 SDValue Func = DAG.getExternalSymbol(TLI.getLibcallName(LC), PtrVT);
5139
5141 CLI.setDebugLoc(dl)
5142 .setChain(Chain)
5143 .setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Func, std::move(Args))
5144 .setSExtResult();
5145
5146 std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
5147
5148 SplitInteger(CallInfo.first, Lo, Hi);
5149 SDValue Temp2 =
5150 DAG.getLoad(PtrVT, dl, CallInfo.second, Temp, MachinePointerInfo());
5151 SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Temp2,
5152 DAG.getConstant(0, dl, PtrVT),
5153 ISD::SETNE);
5154 // Use the overflow from the libcall everywhere.
5155 ReplaceValueWith(SDValue(N, 1), Ofl);
5156}
5157
5158void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
5159 SDValue &Lo, SDValue &Hi) {
5160 EVT VT = N->getValueType(0);
5161 SDLoc dl(N);
5162 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
5163
5165 SDValue Res = DAG.getNode(ISD::UDIVREM, dl, DAG.getVTList(VT, VT), Ops);
5166 SplitInteger(Res.getValue(0), Lo, Hi);
5167 return;
5168 }
5169
5170 // Try to expand UDIV by constant.
5171 if (isa<ConstantSDNode>(N->getOperand(1))) {
5172 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5173 // Only if the new type is legal.
5174 if (isTypeLegal(NVT)) {
5175 SDValue InL, InH;
5176 GetExpandedInteger(N->getOperand(0), InL, InH);
5178 if (TLI.expandDIVREMByConstant(N, Result, NVT, DAG, InL, InH)) {
5179 Lo = Result[0];
5180 Hi = Result[1];
5181 return;
5182 }
5183 }
5184 }
5185
5186 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5187 if (VT == MVT::i16)
5188 LC = RTLIB::UDIV_I16;
5189 else if (VT == MVT::i32)
5190 LC = RTLIB::UDIV_I32;
5191 else if (VT == MVT::i64)
5192 LC = RTLIB::UDIV_I64;
5193 else if (VT == MVT::i128)
5194 LC = RTLIB::UDIV_I128;
5195 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
5196
5198 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5199}
5200
5201void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
5202 SDValue &Lo, SDValue &Hi) {
5203 EVT VT = N->getValueType(0);
5204 SDLoc dl(N);
5205 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
5206
5208 SDValue Res = DAG.getNode(ISD::UDIVREM, dl, DAG.getVTList(VT, VT), Ops);
5209 SplitInteger(Res.getValue(1), Lo, Hi);
5210 return;
5211 }
5212
5213 // Try to expand UREM by constant.
5214 if (isa<ConstantSDNode>(N->getOperand(1))) {
5215 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5216 // Only if the new type is legal.
5217 if (isTypeLegal(NVT)) {
5218 SDValue InL, InH;
5219 GetExpandedInteger(N->getOperand(0), InL, InH);
5221 if (TLI.expandDIVREMByConstant(N, Result, NVT, DAG, InL, InH)) {
5222 Lo = Result[0];
5223 Hi = Result[1];
5224 return;
5225 }
5226 }
5227 }
5228
5229 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5230 if (VT == MVT::i16)
5231 LC = RTLIB::UREM_I16;
5232 else if (VT == MVT::i32)
5233 LC = RTLIB::UREM_I32;
5234 else if (VT == MVT::i64)
5235 LC = RTLIB::UREM_I64;
5236 else if (VT == MVT::i128)
5237 LC = RTLIB::UREM_I128;
5238 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
5239
5241 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5242}
5243
5244void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
5245 SDValue &Lo, SDValue &Hi) {
5246 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5247 SDLoc dl(N);
5248 SDValue Op = N->getOperand(0);
5249 if (Op.getValueType().bitsLE(NVT)) {
5250 // The low part is zero extension of the input (degenerates to a copy).
5251 Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
5252 Hi = DAG.getConstant(0, dl, NVT); // The high part is just a zero.
5253 } else {
5254 // For example, extension of an i48 to an i64. The operand type necessarily
5255 // promotes to the result type, so will end up being expanded too.
5256 assert(getTypeAction(Op.getValueType()) ==
5258 "Only know how to promote this result!");
5259 SDValue Res = GetPromotedInteger(Op);
5260 assert(Res.getValueType() == N->getValueType(0) &&
5261 "Operand over promoted?");
5262 // Split the promoted operand. This will simplify when it is expanded.
5263 SplitInteger(Res, Lo, Hi);
5264 unsigned ExcessBits = Op.getValueSizeInBits() - NVT.getSizeInBits();
5265 Hi = DAG.getZeroExtendInReg(Hi, dl,
5267 ExcessBits));
5268 }
5269}
5270
5271void DAGTypeLegalizer::ExpandIntRes_ATOMIC_LOAD(SDNode *N,
5272 SDValue &Lo, SDValue &Hi) {
5273 SDLoc dl(N);
5274 EVT VT = cast<AtomicSDNode>(N)->getMemoryVT();
5275 SDVTList VTs = DAG.getVTList(VT, MVT::i1, MVT::Other);
5276 SDValue Zero = DAG.getConstant(0, dl, VT);
5277 SDValue Swap = DAG.getAtomicCmpSwap(
5279 cast<AtomicSDNode>(N)->getMemoryVT(), VTs, N->getOperand(0),
5280 N->getOperand(1), Zero, Zero, cast<AtomicSDNode>(N)->getMemOperand());
5281
5282 ReplaceValueWith(SDValue(N, 0), Swap.getValue(0));
5283 ReplaceValueWith(SDValue(N, 1), Swap.getValue(2));
5284}
5285
5286void DAGTypeLegalizer::ExpandIntRes_VECREDUCE(SDNode *N,
5287 SDValue &Lo, SDValue &Hi) {
5288 // TODO For VECREDUCE_(AND|OR|XOR) we could split the vector and calculate
5289 // both halves independently.
5290 SDValue Res = TLI.expandVecReduce(N, DAG);
5291 SplitInteger(Res, Lo, Hi);
5292}
5293
5294void DAGTypeLegalizer::ExpandIntRes_Rotate(SDNode *N,
5295 SDValue &Lo, SDValue &Hi) {
5296 // Delegate to funnel-shift expansion.
5297 SDLoc DL(N);
5298 unsigned Opcode = N->getOpcode() == ISD::ROTL ? ISD::FSHL : ISD::FSHR;
5299 SDValue Res = DAG.getNode(Opcode, DL, N->getValueType(0), N->getOperand(0),
5300 N->getOperand(0), N->getOperand(1));
5301 SplitInteger(Res, Lo, Hi);
5302}
5303
5304void DAGTypeLegalizer::ExpandIntRes_FunnelShift(SDNode *N, SDValue &Lo,
5305 SDValue &Hi) {
5306 // Values numbered from least significant to most significant.
5307 SDValue In1, In2, In3, In4;
5308 GetExpandedInteger(N->getOperand(0), In3, In4);
5309 GetExpandedInteger(N->getOperand(1), In1, In2);
5310 EVT HalfVT = In1.getValueType();
5311
5312 SDLoc DL(N);
5313 unsigned Opc = N->getOpcode();
5314 SDValue ShAmt = N->getOperand(2);
5315 EVT ShAmtVT = ShAmt.getValueType();
5316 EVT ShAmtCCVT = getSetCCResultType(ShAmtVT);
5317
5318 // If the shift amount is at least half the bitwidth, swap the inputs.
5319 unsigned HalfVTBits = HalfVT.getScalarSizeInBits();
5320 SDValue AndNode = DAG.getNode(ISD::AND, DL, ShAmtVT, ShAmt,
5321 DAG.getConstant(HalfVTBits, DL, ShAmtVT));
5322 SDValue Cond =
5323 DAG.getSetCC(DL, ShAmtCCVT, AndNode, DAG.getConstant(0, DL, ShAmtVT),
5324 Opc == ISD::FSHL ? ISD::SETNE : ISD::SETEQ);
5325
5326 // Expand to a pair of funnel shifts.
5327 EVT NewShAmtVT = TLI.getShiftAmountTy(HalfVT, DAG.getDataLayout());
5328 SDValue NewShAmt = DAG.getAnyExtOrTrunc(ShAmt, DL, NewShAmtVT);
5329
5330 SDValue Select1 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In1, In2);
5331 SDValue Select2 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In2, In3);
5332 SDValue Select3 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In3, In4);
5333 Lo = DAG.getNode(Opc, DL, HalfVT, Select2, Select1, NewShAmt);
5334 Hi = DAG.getNode(Opc, DL, HalfVT, Select3, Select2, NewShAmt);
5335}
5336
5337void DAGTypeLegalizer::ExpandIntRes_VSCALE(SDNode *N, SDValue &Lo,
5338 SDValue &Hi) {
5339 EVT VT = N->getValueType(0);
5340 EVT HalfVT =
5341 EVT::getIntegerVT(*DAG.getContext(), N->getValueSizeInBits(0) / 2);
5342 SDLoc dl(N);
5343
5344 // We assume VSCALE(1) fits into a legal integer.
5345 APInt One(HalfVT.getSizeInBits(), 1);
5346 SDValue VScaleBase = DAG.getVScale(dl, HalfVT, One);
5347 VScaleBase = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, VScaleBase);
5348 SDValue Res = DAG.getNode(ISD::MUL, dl, VT, VScaleBase, N->getOperand(0));
5349 SplitInteger(Res, Lo, Hi);
5350}
5351
5352//===----------------------------------------------------------------------===//
5353// Integer Operand Expansion
5354//===----------------------------------------------------------------------===//
5355
5356/// ExpandIntegerOperand - This method is called when the specified operand of
5357/// the specified node is found to need expansion. At this point, all of the
5358/// result types of the node are known to be legal, but other operands of the
5359/// node may need promotion or expansion as well as the specified one.
5360bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
5361 LLVM_DEBUG(dbgs() << "Expand integer operand: "; N->dump(&DAG));
5362 SDValue Res = SDValue();
5363
5364 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
5365 return false;
5366
5367 switch (N->getOpcode()) {
5368 default:
5369 #ifndef NDEBUG
5370 dbgs() << "ExpandIntegerOperand Op #" << OpNo << ": ";
5371 N->dump(&DAG); dbgs() << "\n";
5372 #endif
5373 report_fatal_error("Do not know how to expand this operator's operand!");
5374
5375 case ISD::BITCAST: Res = ExpandOp_BITCAST(N); break;
5376 case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
5377 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
5378 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
5379 case ISD::FAKE_USE:
5380 Res = ExpandOp_FAKE_USE(N);
5381 break;
5382 case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
5383 case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
5384 case ISD::EXPERIMENTAL_VP_SPLAT:
5385 case ISD::SPLAT_VECTOR: Res = ExpandIntOp_SPLAT_VECTOR(N); break;
5386 case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
5387 case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
5388 case ISD::SETCCCARRY: Res = ExpandIntOp_SETCCCARRY(N); break;
5390 case ISD::SINT_TO_FP:
5392 case ISD::UINT_TO_FP: Res = ExpandIntOp_XINT_TO_FP(N); break;
5393 case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
5394 case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
5395
5396 case ISD::SHL:
5397 case ISD::SRA:
5398 case ISD::SRL:
5399 case ISD::ROTL:
5400 case ISD::ROTR: Res = ExpandIntOp_Shift(N); break;
5401 case ISD::RETURNADDR:
5402 case ISD::FRAMEADDR: Res = ExpandIntOp_RETURNADDR(N); break;
5403
5404 case ISD::SCMP:
5405 case ISD::UCMP: Res = ExpandIntOp_CMP(N); break;
5406
5407 case ISD::ATOMIC_STORE: Res = ExpandIntOp_ATOMIC_STORE(N); break;
5408 case ISD::STACKMAP:
5409 Res = ExpandIntOp_STACKMAP(N, OpNo);
5410 break;
5411 case ISD::PATCHPOINT:
5412 Res = ExpandIntOp_PATCHPOINT(N, OpNo);
5413 break;
5414 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5415 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
5416 Res = ExpandIntOp_VP_STRIDED(N, OpNo);
5417 break;
5418 }
5419
5420 // If the result is null, the sub-method took care of registering results etc.
5421 if (!Res.getNode()) return false;
5422
5423 // If the result is N, the sub-method updated N in place. Tell the legalizer
5424 // core about this.
5425 if (Res.getNode() == N)
5426 return true;
5427
5428 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
5429 "Invalid operand expansion");
5430
5431 ReplaceValueWith(SDValue(N, 0), Res);
5432 return false;
5433}
5434
5435/// IntegerExpandSetCCOperands - Expand the operands of a comparison. This code
5436/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
5437void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
5438 SDValue &NewRHS,
5439 ISD::CondCode &CCCode,
5440 const SDLoc &dl) {
5441 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5442 GetExpandedInteger(NewLHS, LHSLo, LHSHi);
5443 GetExpandedInteger(NewRHS, RHSLo, RHSHi);
5444
5445 if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
5446 if (RHSLo == RHSHi && isAllOnesConstant(RHSLo)) {
5447 // Equality comparison to -1.
5448 NewLHS = DAG.getNode(ISD::AND, dl, LHSLo.getValueType(), LHSLo, LHSHi);
5449 NewRHS = RHSLo;
5450 return;
5451 }
5452
5453 NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
5454 NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
5455 NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
5456 NewRHS = DAG.getConstant(0, dl, NewLHS.getValueType());
5457 return;
5458 }
5459
5460 // If this is a comparison of the sign bit, just look at the top part.
5461 // X > -1, x < 0
5462 if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
5463 if ((CCCode == ISD::SETLT && CST->isZero()) || // X < 0
5464 (CCCode == ISD::SETGT && CST->isAllOnes())) { // X > -1
5465 NewLHS = LHSHi;
5466 NewRHS = RHSHi;
5467 return;
5468 }
5469
5470 // FIXME: This generated code sucks.
5471 ISD::CondCode LowCC;
5472 switch (CCCode) {
5473 default: llvm_unreachable("Unknown integer setcc!");
5474 case ISD::SETLT:
5475 case ISD::SETULT: LowCC = ISD::SETULT; break;
5476 case ISD::SETGT:
5477 case ISD::SETUGT: LowCC = ISD::SETUGT; break;
5478 case ISD::SETLE:
5479 case ISD::SETULE: LowCC = ISD::SETULE; break;
5480 case ISD::SETGE:
5481 case ISD::SETUGE: LowCC = ISD::SETUGE; break;
5482 }
5483
5484 // LoCmp = lo(op1) < lo(op2) // Always unsigned comparison
5485 // HiCmp = hi(op1) < hi(op2) // Signedness depends on operands
5486 // dest = hi(op1) == hi(op2) ? LoCmp : HiCmp;
5487
5488 // NOTE: on targets without efficient SELECT of bools, we can always use
5489 // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
5490 TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, AfterLegalizeTypes, true,
5491 nullptr);
5492 SDValue LoCmp, HiCmp;
5493 if (TLI.isTypeLegal(LHSLo.getValueType()) &&
5494 TLI.isTypeLegal(RHSLo.getValueType()))
5495 LoCmp = TLI.SimplifySetCC(getSetCCResultType(LHSLo.getValueType()), LHSLo,
5496 RHSLo, LowCC, false, DagCombineInfo, dl);
5497 if (!LoCmp.getNode())
5498 LoCmp = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
5499 RHSLo, LowCC);
5500 if (TLI.isTypeLegal(LHSHi.getValueType()) &&
5501 TLI.isTypeLegal(RHSHi.getValueType()))
5502 HiCmp = TLI.SimplifySetCC(getSetCCResultType(LHSHi.getValueType()), LHSHi,
5503 RHSHi, CCCode, false, DagCombineInfo, dl);
5504 if (!HiCmp.getNode())
5505 HiCmp =
5506 DAG.getNode(ISD::SETCC, dl, getSetCCResultType(LHSHi.getValueType()),
5507 LHSHi, RHSHi, DAG.getCondCode(CCCode));
5508
5509 ConstantSDNode *LoCmpC = dyn_cast<ConstantSDNode>(LoCmp.getNode());
5510 ConstantSDNode *HiCmpC = dyn_cast<ConstantSDNode>(HiCmp.getNode());
5511
5512 bool EqAllowed = ISD::isTrueWhenEqual(CCCode);
5513
5514 // FIXME: Is the HiCmpC->isOne() here correct for
5515 // ZeroOrNegativeOneBooleanContent.
5516 if ((EqAllowed && (HiCmpC && HiCmpC->isZero())) ||
5517 (!EqAllowed &&
5518 ((HiCmpC && HiCmpC->isOne()) || (LoCmpC && LoCmpC->isZero())))) {
5519 // For LE / GE, if high part is known false, ignore the low part.
5520 // For LT / GT: if low part is known false, return the high part.
5521 // if high part is known true, ignore the low part.
5522 NewLHS = HiCmp;
5523 NewRHS = SDValue();
5524 return;
5525 }
5526
5527 if (LHSHi == RHSHi) {
5528 // Comparing the low bits is enough.
5529 NewLHS = LoCmp;
5530 NewRHS = SDValue();
5531 return;
5532 }
5533
5534 // Lower with SETCCCARRY if the target supports it.
5535 EVT HiVT = LHSHi.getValueType();
5536 EVT ExpandVT = TLI.getTypeToExpandTo(*DAG.getContext(), HiVT);
5537 bool HasSETCCCARRY = TLI.isOperationLegalOrCustom(ISD::SETCCCARRY, ExpandVT);
5538
5539 // FIXME: Make all targets support this, then remove the other lowering.
5540 if (HasSETCCCARRY) {
5541 // SETCCCARRY can detect < and >= directly. For > and <=, flip
5542 // operands and condition code.
5543 bool FlipOperands = false;
5544 switch (CCCode) {
5545 case ISD::SETGT: CCCode = ISD::SETLT; FlipOperands = true; break;
5546 case ISD::SETUGT: CCCode = ISD::SETULT; FlipOperands = true; break;
5547 case ISD::SETLE: CCCode = ISD::SETGE; FlipOperands = true; break;
5548 case ISD::SETULE: CCCode = ISD::SETUGE; FlipOperands = true; break;
5549 default: break;
5550 }
5551 if (FlipOperands) {
5552 std::swap(LHSLo, RHSLo);
5553 std::swap(LHSHi, RHSHi);
5554 }
5555 // Perform a wide subtraction, feeding the carry from the low part into
5556 // SETCCCARRY. The SETCCCARRY operation is essentially looking at the high
5557 // part of the result of LHS - RHS. It is negative iff LHS < RHS. It is
5558 // zero or positive iff LHS >= RHS.
5559 EVT LoVT = LHSLo.getValueType();
5560 SDVTList VTList = DAG.getVTList(LoVT, getSetCCResultType(LoVT));
5561 SDValue LowCmp = DAG.getNode(ISD::USUBO, dl, VTList, LHSLo, RHSLo);
5562 SDValue Res = DAG.getNode(ISD::SETCCCARRY, dl, getSetCCResultType(HiVT),
5563 LHSHi, RHSHi, LowCmp.getValue(1),
5564 DAG.getCondCode(CCCode));
5565 NewLHS = Res;
5566 NewRHS = SDValue();
5567 return;
5568 }
5569
5570 NewLHS = TLI.SimplifySetCC(getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ,
5571 false, DagCombineInfo, dl);
5572 if (!NewLHS.getNode())
5573 NewLHS =
5574 DAG.getSetCC(dl, getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ);
5575 NewLHS = DAG.getSelect(dl, LoCmp.getValueType(), NewLHS, LoCmp, HiCmp);
5576 NewRHS = SDValue();
5577}
5578
5579SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
5580 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
5581 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
5582 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5583
5584 // If ExpandSetCCOperands returned a scalar, we need to compare the result
5585 // against zero to select between true and false values.
5586 if (!NewRHS.getNode()) {
5587 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
5588 CCCode = ISD::SETNE;
5589 }
5590
5591 // Update N to have the operands specified.
5592 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
5593 DAG.getCondCode(CCCode), NewLHS, NewRHS,
5594 N->getOperand(4)), 0);
5595}
5596
5597SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
5598 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
5599 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
5600 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5601
5602 // If ExpandSetCCOperands returned a scalar, we need to compare the result
5603 // against zero to select between true and false values.
5604 if (!NewRHS.getNode()) {
5605 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
5606 CCCode = ISD::SETNE;
5607 }
5608
5609 // Update N to have the operands specified.
5610 return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
5611 N->getOperand(2), N->getOperand(3),
5612 DAG.getCondCode(CCCode)), 0);
5613}
5614
5615SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
5616 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
5617 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
5618 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5619
5620 // If ExpandSetCCOperands returned a scalar, use it.
5621 if (!NewRHS.getNode()) {
5622 assert(NewLHS.getValueType() == N->getValueType(0) &&
5623 "Unexpected setcc expansion!");
5624 return NewLHS;
5625 }
5626
5627 // Otherwise, update N to have the operands specified.
5628 return SDValue(
5629 DAG.UpdateNodeOperands(N, NewLHS, NewRHS, DAG.getCondCode(CCCode)), 0);
5630}
5631
5632SDValue DAGTypeLegalizer::ExpandIntOp_SETCCCARRY(SDNode *N) {
5633 SDValue LHS = N->getOperand(0);
5634 SDValue RHS = N->getOperand(1);
5635 SDValue Carry = N->getOperand(2);
5636 SDValue Cond = N->getOperand(3);
5637 SDLoc dl = SDLoc(N);
5638
5639 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5640 GetExpandedInteger(LHS, LHSLo, LHSHi);
5641 GetExpandedInteger(RHS, RHSLo, RHSHi);
5642
5643 // Expand to a USUBO_CARRY for the low part and a SETCCCARRY for the high.
5644 SDVTList VTList = DAG.getVTList(LHSLo.getValueType(), Carry.getValueType());
5645 SDValue LowCmp =
5646 DAG.getNode(ISD::USUBO_CARRY, dl, VTList, LHSLo, RHSLo, Carry);
5647 return DAG.getNode(ISD::SETCCCARRY, dl, N->getValueType(0), LHSHi, RHSHi,
5648 LowCmp.getValue(1), Cond);
5649}
5650
5651SDValue DAGTypeLegalizer::ExpandIntOp_SPLAT_VECTOR(SDNode *N) {
5652 // Split the operand and replace with SPLAT_VECTOR_PARTS.
5653 SDValue Lo, Hi;
5654 GetExpandedInteger(N->getOperand(0), Lo, Hi);
5655 return DAG.getNode(ISD::SPLAT_VECTOR_PARTS, SDLoc(N), N->getValueType(0), Lo,
5656 Hi);
5657}
5658
5659SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
5660 // The value being shifted is legal, but the shift amount is too big.
5661 // It follows that either the result of the shift is undefined, or the
5662 // upper half of the shift amount is zero. Just use the lower half.
5663 SDValue Lo, Hi;
5664 GetExpandedInteger(N->getOperand(1), Lo, Hi);
5665 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0);
5666}
5667
5668SDValue DAGTypeLegalizer::ExpandIntOp_CMP(SDNode *N) {
5669 return TLI.expandCMP(N, DAG);
5670}
5671
5672SDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) {
5673 // The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant. This
5674 // surely makes pretty nice problems on 8/16 bit targets. Just truncate this
5675 // constant to valid type.
5676 SDValue Lo, Hi;
5677 GetExpandedInteger(N->getOperand(0), Lo, Hi);
5678 return SDValue(DAG.UpdateNodeOperands(N, Lo), 0);
5679}
5680
5681SDValue DAGTypeLegalizer::ExpandIntOp_XINT_TO_FP(SDNode *N) {
5682 bool IsStrict = N->isStrictFPOpcode();
5683 bool IsSigned = N->getOpcode() == ISD::SINT_TO_FP ||
5684 N->getOpcode() == ISD::STRICT_SINT_TO_FP;
5685 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
5686 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
5687 EVT DstVT = N->getValueType(0);
5688 RTLIB::Libcall LC = IsSigned ? RTLIB::getSINTTOFP(Op.getValueType(), DstVT)
5689 : RTLIB::getUINTTOFP(Op.getValueType(), DstVT);
5690 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
5691 "Don't know how to expand this XINT_TO_FP!");
5693 CallOptions.setIsSigned(true);
5694 std::pair<SDValue, SDValue> Tmp =
5695 TLI.makeLibCall(DAG, LC, DstVT, Op, CallOptions, SDLoc(N), Chain);
5696
5697 if (!IsStrict)
5698 return Tmp.first;
5699
5700 ReplaceValueWith(SDValue(N, 1), Tmp.second);
5701 ReplaceValueWith(SDValue(N, 0), Tmp.first);
5702 return SDValue();
5703}
5704
5705SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
5706 assert(!N->isAtomic() && "Should have been a ATOMIC_STORE?");
5707
5708 if (ISD::isNormalStore(N))
5709 return ExpandOp_NormalStore(N, OpNo);
5710
5711 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
5712 assert(OpNo == 1 && "Can only expand the stored value so far");
5713
5714 EVT VT = N->getOperand(1).getValueType();
5715 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5716 SDValue Ch = N->getChain();
5717 SDValue Ptr = N->getBasePtr();
5718 MachineMemOperand::Flags MMOFlags = N->getMemOperand()->getFlags();
5719 AAMDNodes AAInfo = N->getAAInfo();
5720 SDLoc dl(N);
5721 SDValue Lo, Hi;
5722
5723 assert(NVT.isByteSized() && "Expanded type not byte sized!");
5724
5725 if (N->getMemoryVT().bitsLE(NVT)) {
5726 GetExpandedInteger(N->getValue(), Lo, Hi);
5727 return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
5728 N->getMemoryVT(), N->getOriginalAlign(), MMOFlags,
5729 AAInfo);
5730 }
5731
5732 if (DAG.getDataLayout().isLittleEndian()) {
5733 // Little-endian - low bits are at low addresses.
5734 GetExpandedInteger(N->getValue(), Lo, Hi);
5735
5736 Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
5737 N->getOriginalAlign(), MMOFlags, AAInfo);
5738
5739 unsigned ExcessBits =
5740 N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
5741 EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
5742
5743 // Increment the pointer to the other half.
5744 unsigned IncrementSize = NVT.getSizeInBits()/8;
5745 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
5746 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
5747 N->getPointerInfo().getWithOffset(IncrementSize),
5748 NEVT, N->getOriginalAlign(), MMOFlags, AAInfo);
5749 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
5750 }
5751
5752 // Big-endian - high bits are at low addresses. Favor aligned stores at
5753 // the cost of some bit-fiddling.
5754 GetExpandedInteger(N->getValue(), Lo, Hi);
5755
5756 EVT ExtVT = N->getMemoryVT();
5757 unsigned EBytes = ExtVT.getStoreSize();
5758 unsigned IncrementSize = NVT.getSizeInBits()/8;
5759 unsigned ExcessBits = (EBytes - IncrementSize)*8;
5760 EVT HiVT = EVT::getIntegerVT(*DAG.getContext(),
5761 ExtVT.getSizeInBits() - ExcessBits);
5762
5763 if (ExcessBits < NVT.getSizeInBits()) {
5764 // Transfer high bits from the top of Lo to the bottom of Hi.
5765 Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
5766 DAG.getConstant(NVT.getSizeInBits() - ExcessBits, dl,
5767 TLI.getPointerTy(DAG.getDataLayout())));
5768 Hi = DAG.getNode(
5769 ISD::OR, dl, NVT, Hi,
5770 DAG.getNode(ISD::SRL, dl, NVT, Lo,
5771 DAG.getConstant(ExcessBits, dl,
5772 TLI.getPointerTy(DAG.getDataLayout()))));
5773 }
5774
5775 // Store both the high bits and maybe some of the low bits.
5776 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getPointerInfo(), HiVT,
5777 N->getOriginalAlign(), MMOFlags, AAInfo);
5778
5779 // Increment the pointer to the other half.
5780 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
5781 // Store the lowest ExcessBits bits in the second half.
5782 Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr,
5783 N->getPointerInfo().getWithOffset(IncrementSize),
5784 EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
5785 N->getOriginalAlign(), MMOFlags, AAInfo);
5786 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
5787}
5788
5789SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
5790 SDValue InL, InH;
5791 GetExpandedInteger(N->getOperand(0), InL, InH);
5792 // Just truncate the low part of the source.
5793 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0), InL);
5794}
5795
5796SDValue DAGTypeLegalizer::ExpandIntOp_ATOMIC_STORE(SDNode *N) {
5797 SDLoc dl(N);
5798 SDValue Swap =
5799 DAG.getAtomic(ISD::ATOMIC_SWAP, dl, cast<AtomicSDNode>(N)->getMemoryVT(),
5800 N->getOperand(0), N->getOperand(2), N->getOperand(1),
5801 cast<AtomicSDNode>(N)->getMemOperand());
5802 return Swap.getValue(1);
5803}
5804
5805SDValue DAGTypeLegalizer::ExpandIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) {
5806 assert((N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD && OpNo == 3) ||
5807 (N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE && OpNo == 4));
5808
5809 SDValue Hi; // The upper half is dropped out.
5810 SmallVector<SDValue, 8> NewOps(N->ops());
5811 GetExpandedInteger(NewOps[OpNo], NewOps[OpNo], Hi);
5812
5813 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
5814}
5815
5816SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SPLICE(SDNode *N) {
5817 SDLoc dl(N);
5818
5819 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5820 SDValue V1 = GetPromotedInteger(N->getOperand(1));
5821 EVT OutVT = V0.getValueType();
5822
5823 return DAG.getNode(ISD::VECTOR_SPLICE, dl, OutVT, V0, V1, N->getOperand(2));
5824}
5825
5826SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_INTERLEAVE_DEINTERLEAVE(SDNode *N) {
5827 SDLoc dl(N);
5828
5829 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5830 SDValue V1 = GetPromotedInteger(N->getOperand(1));
5831 EVT ResVT = V0.getValueType();
5832 SDValue Res = DAG.getNode(N->getOpcode(), dl,
5833 DAG.getVTList(ResVT, ResVT), V0, V1);
5834 SetPromotedInteger(SDValue(N, 0), Res.getValue(0));
5835 SetPromotedInteger(SDValue(N, 1), Res.getValue(1));
5836 return SDValue();
5837}
5838
5839SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
5840
5841 EVT OutVT = N->getValueType(0);
5842 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5843 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5844 EVT NOutVTElem = NOutVT.getVectorElementType();
5845
5846 SDLoc dl(N);
5847 SDValue BaseIdx = N->getOperand(1);
5848
5849 // TODO: We may be able to use this for types other than scalable
5850 // vectors and fix those tests that expect BUILD_VECTOR to be used
5851 if (OutVT.isScalableVector()) {
5852 SDValue InOp0 = N->getOperand(0);
5853 EVT InVT = InOp0.getValueType();
5854
5855 // Try and extract from a smaller type so that it eventually falls
5856 // into the promotion code below.
5857 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector ||
5858 getTypeAction(InVT) == TargetLowering::TypeLegal) {
5859 EVT NInVT = InVT.getHalfNumVectorElementsVT(*DAG.getContext());
5860 unsigned NElts = NInVT.getVectorMinNumElements();
5861 uint64_t IdxVal = BaseIdx->getAsZExtVal();
5862
5863 SDValue Step1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NInVT, InOp0,
5864 DAG.getConstant(alignDown(IdxVal, NElts), dl,
5865 BaseIdx.getValueType()));
5866 SDValue Step2 = DAG.getNode(
5867 ISD::EXTRACT_SUBVECTOR, dl, OutVT, Step1,
5868 DAG.getConstant(IdxVal % NElts, dl, BaseIdx.getValueType()));
5869 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Step2);
5870 }
5871
5872 // Try and extract from a widened type.
5873 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
5874 SDValue Ops[] = {GetWidenedVector(InOp0), BaseIdx};
5875 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), OutVT, Ops);
5876 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Ext);
5877 }
5878
5879 // Promote operands and see if this is handled by target lowering,
5880 // Otherwise, use the BUILD_VECTOR approach below
5881 if (getTypeAction(InVT) == TargetLowering::TypePromoteInteger) {
5882 // Collect the (promoted) operands
5883 SDValue Ops[] = { GetPromotedInteger(InOp0), BaseIdx };
5884
5885 EVT PromEltVT = Ops[0].getValueType().getVectorElementType();
5886 assert(PromEltVT.bitsLE(NOutVTElem) &&
5887 "Promoted operand has an element type greater than result");
5888
5889 EVT ExtVT = NOutVT.changeVectorElementType(PromEltVT);
5890 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), ExtVT, Ops);
5891 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Ext);
5892 }
5893 }
5894
5895 if (OutVT.isScalableVector())
5896 report_fatal_error("Unable to promote scalable types using BUILD_VECTOR");
5897
5898 SDValue InOp0 = N->getOperand(0);
5899 if (getTypeAction(InOp0.getValueType()) == TargetLowering::TypePromoteInteger)
5900 InOp0 = GetPromotedInteger(InOp0);
5901
5902 EVT InVT = InOp0.getValueType();
5903 EVT InSVT = InVT.getVectorElementType();
5904
5905 unsigned OutNumElems = OutVT.getVectorNumElements();
5907 Ops.reserve(OutNumElems);
5908 for (unsigned i = 0; i != OutNumElems; ++i) {
5909 // Extract the element from the original vector.
5910 SDValue Index = DAG.getNode(ISD::ADD, dl, BaseIdx.getValueType(), BaseIdx,
5911 DAG.getConstant(i, dl, BaseIdx.getValueType()));
5912 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InSVT,
5913 N->getOperand(0), Index);
5914 SDValue Op = DAG.getAnyExtOrTrunc(Ext, dl, NOutVTElem);
5915 // Insert the converted element to the new vector.
5916 Ops.push_back(Op);
5917 }
5918
5919 return DAG.getBuildVector(NOutVT, dl, Ops);
5920}
5921
5922SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_SUBVECTOR(SDNode *N) {
5923 EVT OutVT = N->getValueType(0);
5924 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5925 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5926
5927 SDLoc dl(N);
5928 SDValue Vec = N->getOperand(0);
5929 SDValue SubVec = N->getOperand(1);
5930 SDValue Idx = N->getOperand(2);
5931
5932 EVT SubVecVT = SubVec.getValueType();
5933 EVT NSubVT =
5935 SubVecVT.getVectorElementCount());
5936
5937 Vec = GetPromotedInteger(Vec);
5938 SubVec = DAG.getNode(ISD::ANY_EXTEND, dl, NSubVT, SubVec);
5939
5940 return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, NOutVT, Vec, SubVec, Idx);
5941}
5942
5943SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_REVERSE(SDNode *N) {
5944 SDLoc dl(N);
5945
5946 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5947 EVT OutVT = V0.getValueType();
5948
5949 return DAG.getNode(ISD::VECTOR_REVERSE, dl, OutVT, V0);
5950}
5951
5952SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) {
5953 ShuffleVectorSDNode *SV = cast<ShuffleVectorSDNode>(N);
5954 EVT VT = N->getValueType(0);
5955 SDLoc dl(N);
5956
5957 ArrayRef<int> NewMask = SV->getMask().slice(0, VT.getVectorNumElements());
5958
5959 SDValue V0 = GetPromotedInteger(N->getOperand(0));
5960 SDValue V1 = GetPromotedInteger(N->getOperand(1));
5961 EVT OutVT = V0.getValueType();
5962
5963 return DAG.getVectorShuffle(OutVT, dl, V0, V1, NewMask);
5964}
5965
5966SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) {
5967 EVT OutVT = N->getValueType(0);
5968 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
5969 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
5970 unsigned NumElems = N->getNumOperands();
5971 EVT NOutVTElem = NOutVT.getVectorElementType();
5972 TargetLoweringBase::BooleanContent NOutBoolType = TLI.getBooleanContents(NOutVT);
5973 unsigned NOutExtOpc = TargetLowering::getExtendForContent(NOutBoolType);
5974 SDLoc dl(N);
5975
5977 Ops.reserve(NumElems);
5978 for (unsigned i = 0; i != NumElems; ++i) {
5979 SDValue Op = N->getOperand(i);
5980 EVT OpVT = Op.getValueType();
5981 // BUILD_VECTOR integer operand types are allowed to be larger than the
5982 // result's element type. This may still be true after the promotion. For
5983 // example, we might be promoting (<v?i1> = BV <i32>, <i32>, ...) to
5984 // (v?i16 = BV <i32>, <i32>, ...), and we can't any_extend <i32> to <i16>.
5985 if (OpVT.bitsLT(NOutVTElem)) {
5986 unsigned ExtOpc = ISD::ANY_EXTEND;
5987 // Attempt to extend constant bool vectors to match target's BooleanContent.
5988 // While not necessary, this improves chances of the constant correctly
5989 // folding with compare results (e.g. for NOT patterns).
5990 if (OpVT == MVT::i1 && Op.getOpcode() == ISD::Constant)
5991 ExtOpc = NOutExtOpc;
5992 Op = DAG.getNode(ExtOpc, dl, NOutVTElem, Op);
5993 }
5994 Ops.push_back(Op);
5995 }
5996
5997 return DAG.getBuildVector(NOutVT, dl, Ops);
5998}
5999
6000SDValue DAGTypeLegalizer::PromoteIntRes_ScalarOp(SDNode *N) {
6001
6002 SDLoc dl(N);
6003
6004 assert(!N->getOperand(0).getValueType().isVector() &&
6005 "Input must be a scalar");
6006
6007 EVT OutVT = N->getValueType(0);
6008 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6009 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6010 EVT NOutElemVT = NOutVT.getVectorElementType();
6011
6012 SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutElemVT, N->getOperand(0));
6013 if (N->isVPOpcode())
6014 return DAG.getNode(N->getOpcode(), dl, NOutVT, Op, N->getOperand(1),
6015 N->getOperand(2));
6016
6017 return DAG.getNode(N->getOpcode(), dl, NOutVT, Op);
6018}
6019
6020SDValue DAGTypeLegalizer::PromoteIntRes_STEP_VECTOR(SDNode *N) {
6021 SDLoc dl(N);
6022 EVT OutVT = N->getValueType(0);
6023 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6024 assert(NOutVT.isScalableVector() &&
6025 "Type must be promoted to a scalable vector type");
6026 const APInt &StepVal = N->getConstantOperandAPInt(0);
6027 return DAG.getStepVector(dl, NOutVT,
6028 StepVal.sext(NOutVT.getScalarSizeInBits()));
6029}
6030
6031SDValue DAGTypeLegalizer::PromoteIntRes_CONCAT_VECTORS(SDNode *N) {
6032 SDLoc dl(N);
6033
6034 EVT OutVT = N->getValueType(0);
6035 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6036 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6037
6038 unsigned NumOperands = N->getNumOperands();
6039 unsigned NumOutElem = NOutVT.getVectorMinNumElements();
6040 EVT OutElemTy = NOutVT.getVectorElementType();
6041 if (OutVT.isScalableVector()) {
6042 // Find the largest promoted element type for each of the operands.
6043 SDUse *MaxSizedValue = std::max_element(
6044 N->op_begin(), N->op_end(), [](const SDValue &A, const SDValue &B) {
6045 EVT AVT = A.getValueType().getVectorElementType();
6046 EVT BVT = B.getValueType().getVectorElementType();
6047 return AVT.getScalarSizeInBits() < BVT.getScalarSizeInBits();
6048 });
6049 EVT MaxElementVT = MaxSizedValue->getValueType().getVectorElementType();
6050
6051 // Then promote all vectors to the largest element type.
6053 for (unsigned I = 0; I < NumOperands; ++I) {
6054 SDValue Op = N->getOperand(I);
6055 EVT OpVT = Op.getValueType();
6056 if (getTypeAction(OpVT) == TargetLowering::TypePromoteInteger)
6057 Op = GetPromotedInteger(Op);
6058 else
6059 assert(getTypeAction(OpVT) == TargetLowering::TypeLegal &&
6060 "Unhandled legalization type");
6061
6063 MaxElementVT.getScalarSizeInBits())
6064 Op = DAG.getAnyExtOrTrunc(Op, dl,
6065 OpVT.changeVectorElementType(MaxElementVT));
6066 Ops.push_back(Op);
6067 }
6068
6069 // Do the CONCAT on the promoted type and finally truncate to (the promoted)
6070 // NOutVT.
6071 return DAG.getAnyExtOrTrunc(
6073 OutVT.changeVectorElementType(MaxElementVT), Ops),
6074 dl, NOutVT);
6075 }
6076
6077 unsigned NumElem = N->getOperand(0).getValueType().getVectorNumElements();
6078 assert(NumElem * NumOperands == NumOutElem &&
6079 "Unexpected number of elements");
6080
6081 // Take the elements from the first vector.
6082 SmallVector<SDValue, 8> Ops(NumOutElem);
6083 for (unsigned i = 0; i < NumOperands; ++i) {
6084 SDValue Op = N->getOperand(i);
6085 if (getTypeAction(Op.getValueType()) == TargetLowering::TypePromoteInteger)
6086 Op = GetPromotedInteger(Op);
6087 EVT SclrTy = Op.getValueType().getVectorElementType();
6088 assert(NumElem == Op.getValueType().getVectorNumElements() &&
6089 "Unexpected number of elements");
6090
6091 for (unsigned j = 0; j < NumElem; ++j) {
6092 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy, Op,
6093 DAG.getVectorIdxConstant(j, dl));
6094 Ops[i * NumElem + j] = DAG.getAnyExtOrTrunc(Ext, dl, OutElemTy);
6095 }
6096 }
6097
6098 return DAG.getBuildVector(NOutVT, dl, Ops);
6099}
6100
6101SDValue DAGTypeLegalizer::PromoteIntRes_EXTEND_VECTOR_INREG(SDNode *N) {
6102 EVT VT = N->getValueType(0);
6103 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6104 assert(NVT.isVector() && "This type must be promoted to a vector type");
6105
6106 SDLoc dl(N);
6107
6108 // For operands whose TypeAction is to promote, extend the promoted node
6109 // appropriately (ZERO_EXTEND or SIGN_EXTEND) from the original pre-promotion
6110 // type, and then construct a new *_EXTEND_VECTOR_INREG node to the promote-to
6111 // type..
6112 if (getTypeAction(N->getOperand(0).getValueType())
6114 SDValue Promoted;
6115
6116 switch(N->getOpcode()) {
6118 Promoted = SExtPromotedInteger(N->getOperand(0));
6119 break;
6121 Promoted = ZExtPromotedInteger(N->getOperand(0));
6122 break;
6124 Promoted = GetPromotedInteger(N->getOperand(0));
6125 break;
6126 default:
6127 llvm_unreachable("Node has unexpected Opcode");
6128 }
6129 return DAG.getNode(N->getOpcode(), dl, NVT, Promoted);
6130 }
6131
6132 // Directly extend to the appropriate transform-to type.
6133 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
6134}
6135
6136SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_FIND_LAST_ACTIVE(SDNode *N) {
6137 EVT VT = N->getValueType(0);
6138 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6139 return DAG.getNode(ISD::VECTOR_FIND_LAST_ACTIVE, SDLoc(N), NVT, N->ops());
6140}
6141
6142SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) {
6143 EVT OutVT = N->getValueType(0);
6144 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6145 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6146
6147 EVT NOutVTElem = NOutVT.getVectorElementType();
6148
6149 SDLoc dl(N);
6150 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6151
6152 SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl,
6153 NOutVTElem, N->getOperand(1));
6154 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NOutVT,
6155 V0, ConvElem, N->getOperand(2));
6156}
6157
6158SDValue DAGTypeLegalizer::PromoteIntRes_VECREDUCE(SDNode *N) {
6159 // The VECREDUCE result size may be larger than the element size, so
6160 // we can simply change the result type.
6161 SDLoc dl(N);
6162 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6163 return DAG.getNode(N->getOpcode(), dl, NVT, N->ops());
6164}
6165
6166SDValue DAGTypeLegalizer::PromoteIntRes_VP_REDUCE(SDNode *N) {
6167 // The VP_REDUCE result size may be larger than the element size, so we can
6168 // simply change the result type. However the start value and result must be
6169 // the same.
6170 SDLoc DL(N);
6171 SDValue Start = PromoteIntOpVectorReduction(N, N->getOperand(0));
6172 return DAG.getNode(N->getOpcode(), DL, Start.getValueType(), Start,
6173 N->getOperand(1), N->getOperand(2), N->getOperand(3));
6174}
6175
6176SDValue DAGTypeLegalizer::PromoteIntRes_PATCHPOINT(SDNode *N) {
6177 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6178 SDLoc dl(N);
6179
6180 assert(N->getNumValues() == 3 && "Expected 3 values for PATCHPOINT");
6181 SDVTList VTList = DAG.getVTList({NVT, MVT::Other, MVT::Glue});
6182
6183 SmallVector<SDValue> Ops(N->ops());
6184 SDValue Res = DAG.getNode(ISD::PATCHPOINT, dl, VTList, Ops);
6185
6186 // Replace chain and glue uses with the new patchpoint.
6187 SDValue From[] = {SDValue(N, 1), SDValue(N, 2)};
6188 SDValue To[] = {Res.getValue(1), Res.getValue(2)};
6189 DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
6190
6191 return Res.getValue(0);
6192}
6193
6194SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
6195 SDLoc dl(N);
6196 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6197 SDValue V1 = DAG.getZExtOrTrunc(N->getOperand(1), dl,
6198 TLI.getVectorIdxTy(DAG.getDataLayout()));
6200 V0->getValueType(0).getScalarType(), V0, V1);
6201
6202 // EXTRACT_VECTOR_ELT can return types which are wider than the incoming
6203 // element types. If this is the case then we need to expand the outgoing
6204 // value and not truncate it.
6205 return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
6206}
6207
6208SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_SUBVECTOR(SDNode *N) {
6209 SDLoc dl(N);
6210 // The result type is equal to the first input operand's type, so the
6211 // type that needs promoting must be the second source vector.
6212 SDValue V0 = N->getOperand(0);
6213 SDValue V1 = GetPromotedInteger(N->getOperand(1));
6214 SDValue Idx = N->getOperand(2);
6215 EVT PromVT = EVT::getVectorVT(*DAG.getContext(),
6218 V0 = DAG.getAnyExtOrTrunc(V0, dl, PromVT);
6219 SDValue Ext = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, PromVT, V0, V1, Idx);
6220 return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
6221}
6222
6223// FIXME: We wouldn't need this if clang could promote short integers
6224// that are arguments to FAKE_USE.
6225SDValue DAGTypeLegalizer::PromoteIntOp_FAKE_USE(SDNode *N) {
6226 SDLoc dl(N);
6227 SDValue V0 = N->getOperand(0);
6228 SDValue V1 = N->getOperand(1);
6229 EVT InVT1 = V1.getValueType();
6230 SDValue VPromoted =
6231 DAG.getNode(ISD::ANY_EXTEND, dl,
6232 TLI.getTypeToTransformTo(*DAG.getContext(), InVT1), V1);
6233 return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), V0, VPromoted);
6234}
6235
6236SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_SUBVECTOR(SDNode *N) {
6237 SDLoc dl(N);
6238 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6239 MVT InVT = V0.getValueType().getSimpleVT();
6241 N->getValueType(0).getVectorNumElements());
6242 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OutVT, V0, N->getOperand(1));
6243 return DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), Ext);
6244}
6245
6246SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
6247 SDLoc dl(N);
6248
6249 EVT ResVT = N->getValueType(0);
6250 unsigned NumElems = N->getNumOperands();
6251
6252 if (ResVT.isScalableVector()) {
6253 SDValue ResVec = DAG.getUNDEF(ResVT);
6254
6255 for (unsigned OpIdx = 0; OpIdx < NumElems; ++OpIdx) {
6256 SDValue Op = N->getOperand(OpIdx);
6257 unsigned OpNumElts = Op.getValueType().getVectorMinNumElements();
6258 ResVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, ResVec, Op,
6259 DAG.getIntPtrConstant(OpIdx * OpNumElts, dl));
6260 }
6261
6262 return ResVec;
6263 }
6264
6265 EVT RetSclrTy = N->getValueType(0).getVectorElementType();
6266
6268 NewOps.reserve(NumElems);
6269
6270 // For each incoming vector
6271 for (unsigned VecIdx = 0; VecIdx != NumElems; ++VecIdx) {
6272 SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx));
6273 EVT SclrTy = Incoming->getValueType(0).getVectorElementType();
6274 unsigned NumElem = Incoming->getValueType(0).getVectorNumElements();
6275
6276 for (unsigned i=0; i<NumElem; ++i) {
6277 // Extract element from incoming vector
6278 SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy, Incoming,
6279 DAG.getVectorIdxConstant(i, dl));
6280 SDValue Tr = DAG.getNode(ISD::TRUNCATE, dl, RetSclrTy, Ex);
6281 NewOps.push_back(Tr);
6282 }
6283 }
6284
6285 return DAG.getBuildVector(N->getValueType(0), dl, NewOps);
6286}
6287
6288SDValue DAGTypeLegalizer::ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
6289 assert(OpNo > 1);
6290 SDValue Op = N->getOperand(OpNo);
6291
6292 // FIXME: Non-constant operands are not yet handled:
6293 // - https://github.com/llvm/llvm-project/issues/26431
6294 // - https://github.com/llvm/llvm-project/issues/55957
6295 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
6296 if (!CN)
6297 return SDValue();
6298
6299 // Copy operands before the one being expanded.
6300 SmallVector<SDValue> NewOps;
6301 for (unsigned I = 0; I < OpNo; I++)
6302 NewOps.push_back(N->getOperand(I));
6303
6304 EVT Ty = Op.getValueType();
6305 SDLoc DL = SDLoc(N);
6306 if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
6307 NewOps.push_back(
6308 DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
6309 NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
6310 } else {
6311 // FIXME: https://github.com/llvm/llvm-project/issues/55609
6312 return SDValue();
6313 }
6314
6315 // Copy remaining operands.
6316 for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
6317 NewOps.push_back(N->getOperand(I));
6318
6319 SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
6320
6321 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
6322 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
6323
6324 return SDValue(); // Signal that we have replaced the node already.
6325}
6326
6327SDValue DAGTypeLegalizer::ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
6328 assert(OpNo >= 7);
6329 SDValue Op = N->getOperand(OpNo);
6330
6331 // FIXME: Non-constant operands are not yet handled:
6332 // - https://github.com/llvm/llvm-project/issues/26431
6333 // - https://github.com/llvm/llvm-project/issues/55957
6334 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
6335 if (!CN)
6336 return SDValue();
6337
6338 // Copy operands before the one being expanded.
6339 SmallVector<SDValue> NewOps;
6340 for (unsigned I = 0; I < OpNo; I++)
6341 NewOps.push_back(N->getOperand(I));
6342
6343 EVT Ty = Op.getValueType();
6344 SDLoc DL = SDLoc(N);
6345 if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
6346 NewOps.push_back(
6347 DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
6348 NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
6349 } else {
6350 // FIXME: https://github.com/llvm/llvm-project/issues/55609
6351 return SDValue();
6352 }
6353
6354 // Copy remaining operands.
6355 for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
6356 NewOps.push_back(N->getOperand(I));
6357
6358 SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
6359
6360 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
6361 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
6362
6363 return SDValue(); // Signal that we have replaced the node already.
6364}
#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:983
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:857
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:701
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.
void forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl, bool Signed, const SDValue LHS, const SDValue RHS, SDValue &Lo, SDValue &Hi) const
Calculate full product of LHS and RHS either via a libcall or through brute force expansion of the mu...
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.
void forceExpandMultiply(SelectionDAG &DAG, const SDLoc &dl, bool Signed, SDValue &Lo, SDValue &Hi, SDValue LHS, SDValue RHS, SDValue HiLHS=SDValue(), SDValue HiRHS=SDValue()) const
Calculate the product twice the width of LHS and RHS.
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...
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:556
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:341
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:292
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)