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