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