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
3011 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3012}
3013
3014SDValue DAGTypeLegalizer::PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo) {
3015 SmallVector<SDValue, 6> NewOps(N->ops());
3016
3017 if (OpNo == 2) { // Offset operand
3018 NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo));
3019 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3020 }
3021
3022 assert((OpNo == 4 || OpNo == 5) && "Unexpected operand for promotion");
3023
3024 NewOps[OpNo] = ZExtPromotedInteger(N->getOperand(OpNo));
3025 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3026}
3027
3028SDValue DAGTypeLegalizer::PromoteIntOp_VECTOR_HISTOGRAM(SDNode *N,
3029 unsigned OpNo) {
3030 assert(OpNo == 1 && "Unexpected operand for promotion");
3031 SmallVector<SDValue, 7> NewOps(N->ops());
3032 NewOps[1] = GetPromotedInteger(N->getOperand(1));
3033 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3034}
3035
3036SDValue DAGTypeLegalizer::PromoteIntOp_UnaryBooleanVectorOp(SDNode *N,
3037 unsigned OpNo) {
3038 assert(OpNo == 0 && "Unexpected operand for promotion");
3039 SDValue Op = N->getOperand(0);
3040
3041 SDValue NewOp;
3042 if (TLI.getBooleanContents(Op.getValueType()) ==
3044 NewOp = SExtPromotedInteger(Op);
3045 else
3046 NewOp = ZExtPromotedInteger(Op);
3047
3048 return SDValue(DAG.UpdateNodeOperands(N, NewOp), 0);
3049}
3050
3051SDValue DAGTypeLegalizer::PromoteIntOp_GET_ACTIVE_LANE_MASK(SDNode *N) {
3052 SmallVector<SDValue, 1> NewOps(N->ops());
3053 NewOps[0] = ZExtPromotedInteger(N->getOperand(0));
3054 NewOps[1] = ZExtPromotedInteger(N->getOperand(1));
3055 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3056}
3057
3058SDValue DAGTypeLegalizer::PromoteIntOp_MaskedBinOp(SDNode *N, unsigned OpNo) {
3059 assert(OpNo == 2);
3060 SmallVector<SDValue, 3> NewOps(N->ops());
3061 NewOps[2] = PromoteTargetBoolean(NewOps[2], N->getValueType(0));
3062 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3063}
3064
3065SDValue DAGTypeLegalizer::PromoteIntOp_PARTIAL_REDUCE_MLA(SDNode *N) {
3066 SmallVector<SDValue, 1> NewOps(N->ops());
3067 switch (N->getOpcode()) {
3069 NewOps[1] = SExtPromotedInteger(N->getOperand(1));
3070 NewOps[2] = SExtPromotedInteger(N->getOperand(2));
3071 break;
3073 NewOps[1] = ZExtPromotedInteger(N->getOperand(1));
3074 NewOps[2] = ZExtPromotedInteger(N->getOperand(2));
3075 break;
3077 NewOps[1] = SExtPromotedInteger(N->getOperand(1));
3078 NewOps[2] = ZExtPromotedInteger(N->getOperand(2));
3079 break;
3080 default:
3081 llvm_unreachable("unexpected opcode");
3082 }
3083 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3084}
3085
3086SDValue DAGTypeLegalizer::PromoteIntOp_LOOP_DEPENDENCE_MASK(SDNode *N) {
3087 SDValue NewOps[4];
3088 NewOps[0] = ZExtPromotedInteger(N->getOperand(0));
3089 NewOps[1] = ZExtPromotedInteger(N->getOperand(1));
3090 NewOps[2] = ZExtPromotedInteger(N->getOperand(2));
3091 NewOps[3] = N->getOperand(3);
3092 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
3093}
3094
3095//===----------------------------------------------------------------------===//
3096// Integer Result Expansion
3097//===----------------------------------------------------------------------===//
3098
3099/// ExpandIntegerResult - This method is called when the specified result of the
3100/// specified node is found to need expansion. At this point, the node may also
3101/// have invalid operands or may have other results that need promotion, we just
3102/// know that (at least) one result needs expansion.
3103void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
3104 LLVM_DEBUG(dbgs() << "Expand integer result: "; N->dump(&DAG));
3105 SDValue Lo, Hi;
3106 Lo = Hi = SDValue();
3107
3108 // See if the target wants to custom expand this node.
3109 if (CustomLowerNode(N, N->getValueType(ResNo), true))
3110 return;
3111
3112 switch (N->getOpcode()) {
3113 default:
3114#ifndef NDEBUG
3115 dbgs() << "ExpandIntegerResult #" << ResNo << ": ";
3116 N->dump(&DAG); dbgs() << "\n";
3117#endif
3118 report_fatal_error("Do not know how to expand the result of this "
3119 "operator!");
3120
3121 case ISD::ARITH_FENCE: SplitRes_ARITH_FENCE(N, Lo, Hi); break;
3122 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
3123 case ISD::SELECT: SplitRes_Select(N, Lo, Hi); break;
3124 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
3125 case ISD::POISON:
3126 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
3127 case ISD::FREEZE: SplitRes_FREEZE(N, Lo, Hi); break;
3128 case ISD::SETCC: ExpandIntRes_SETCC(N, Lo, Hi); break;
3129
3130 case ISD::BITCAST: ExpandRes_BITCAST(N, Lo, Hi); break;
3131 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
3132 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
3133 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
3134 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break;
3135
3136 case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
3137 case ISD::AssertSext: ExpandIntRes_AssertSext(N, Lo, Hi); break;
3138 case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break;
3139 case ISD::BITREVERSE: ExpandIntRes_BITREVERSE(N, Lo, Hi); break;
3140 case ISD::BSWAP: ExpandIntRes_BSWAP(N, Lo, Hi); break;
3141 case ISD::PARITY: ExpandIntRes_PARITY(N, Lo, Hi); break;
3142 case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break;
3143 case ISD::ABS:
3145 ExpandIntRes_ABS(N, Lo, Hi);
3146 break;
3147 case ISD::ABDS:
3148 case ISD::ABDU: ExpandIntRes_ABD(N, Lo, Hi); break;
3150 case ISD::CTLZ: ExpandIntRes_CTLZ(N, Lo, Hi); break;
3151 case ISD::CTLS: ExpandIntRes_CTLS(N, Lo, Hi); break;
3152 case ISD::CTPOP: ExpandIntRes_CTPOP(N, Lo, Hi); break;
3154 case ISD::CTTZ: ExpandIntRes_CTTZ(N, Lo, Hi); break;
3155 case ISD::GET_ROUNDING:ExpandIntRes_GET_ROUNDING(N, Lo, Hi); break;
3157 case ISD::FP_TO_SINT:
3159 case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_XINT(N, Lo, Hi); break;
3161 case ISD::FP_TO_UINT_SAT: ExpandIntRes_FP_TO_XINT_SAT(N, Lo, Hi); break;
3162 case ISD::STRICT_LROUND:
3163 case ISD::STRICT_LRINT:
3164 case ISD::LROUND:
3165 case ISD::LRINT:
3167 case ISD::STRICT_LLRINT:
3168 case ISD::LLROUND:
3169 case ISD::LLRINT: ExpandIntRes_XROUND_XRINT(N, Lo, Hi); break;
3170 case ISD::LOAD: ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
3171 case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break;
3173 case ISD::READSTEADYCOUNTER: ExpandIntRes_READCOUNTER(N, Lo, Hi); break;
3174 case ISD::SDIV: ExpandIntRes_SDIV(N, Lo, Hi); break;
3175 case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
3176 case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
3177 case ISD::SREM: ExpandIntRes_SREM(N, Lo, Hi); break;
3178 case ISD::TRUNCATE: ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
3179 case ISD::UDIV: ExpandIntRes_UDIV(N, Lo, Hi); break;
3180 case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break;
3181 case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
3182 case ISD::ATOMIC_LOAD: ExpandIntRes_ATOMIC_LOAD(N, Lo, Hi); break;
3183
3195 case ISD::ATOMIC_SWAP:
3196 case ISD::ATOMIC_CMP_SWAP: {
3197 std::pair<SDValue, SDValue> Tmp = ExpandAtomic(N);
3198 SplitInteger(Tmp.first, Lo, Hi);
3199 ReplaceValueWith(SDValue(N, 1), Tmp.second);
3200 break;
3201 }
3203 AtomicSDNode *AN = cast<AtomicSDNode>(N);
3204 SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::Other);
3205 SDValue Tmp = DAG.getAtomicCmpSwap(
3206 ISD::ATOMIC_CMP_SWAP, SDLoc(N), AN->getMemoryVT(), VTs,
3207 N->getOperand(0), N->getOperand(1), N->getOperand(2), N->getOperand(3),
3208 AN->getMemOperand());
3209
3210 // Expanding to the strong ATOMIC_CMP_SWAP node means we can determine
3211 // success simply by comparing the loaded value against the ingoing
3212 // comparison.
3213 SDValue Success = DAG.getSetCC(SDLoc(N), N->getValueType(1), Tmp,
3214 N->getOperand(2), ISD::SETEQ);
3215
3216 SplitInteger(Tmp, Lo, Hi);
3217 ReplaceValueWith(SDValue(N, 1), Success);
3218 ReplaceValueWith(SDValue(N, 2), Tmp.getValue(1));
3219 break;
3220 }
3221
3222 case ISD::AND:
3223 case ISD::OR:
3224 case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
3225
3226 case ISD::UMAX:
3227 case ISD::SMAX:
3228 case ISD::UMIN:
3229 case ISD::SMIN: ExpandIntRes_MINMAX(N, Lo, Hi); break;
3230
3231 case ISD::SCMP:
3232 case ISD::UCMP: ExpandIntRes_CMP(N, Lo, Hi); break;
3233
3234 case ISD::ADD:
3235 case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
3236
3237 case ISD::ADDC:
3238 case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
3239
3240 case ISD::ADDE:
3241 case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
3242
3243 case ISD::UADDO_CARRY:
3244 case ISD::USUBO_CARRY: ExpandIntRes_UADDSUBO_CARRY(N, Lo, Hi); break;
3245
3246 case ISD::SADDO_CARRY:
3247 case ISD::SSUBO_CARRY: ExpandIntRes_SADDSUBO_CARRY(N, Lo, Hi); break;
3248
3249 case ISD::SHL:
3250 case ISD::SRA:
3251 case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
3252
3253 case ISD::SADDO:
3254 case ISD::SSUBO: ExpandIntRes_SADDSUBO(N, Lo, Hi); break;
3255 case ISD::UADDO:
3256 case ISD::USUBO: ExpandIntRes_UADDSUBO(N, Lo, Hi); break;
3257 case ISD::UMULO:
3258 case ISD::SMULO: ExpandIntRes_XMULO(N, Lo, Hi); break;
3259
3260 case ISD::SADDSAT:
3261 case ISD::UADDSAT:
3262 case ISD::SSUBSAT:
3263 case ISD::USUBSAT: ExpandIntRes_ADDSUBSAT(N, Lo, Hi); break;
3264
3265 case ISD::SSHLSAT:
3266 case ISD::USHLSAT: ExpandIntRes_SHLSAT(N, Lo, Hi); break;
3267
3268 case ISD::AVGCEILS:
3269 case ISD::AVGCEILU:
3270 case ISD::AVGFLOORS:
3271 case ISD::AVGFLOORU: ExpandIntRes_AVG(N, Lo, Hi); break;
3272
3273 case ISD::SMULFIX:
3274 case ISD::SMULFIXSAT:
3275 case ISD::UMULFIX:
3276 case ISD::UMULFIXSAT: ExpandIntRes_MULFIX(N, Lo, Hi); break;
3277
3278 case ISD::SDIVFIX:
3279 case ISD::SDIVFIXSAT:
3280 case ISD::UDIVFIX:
3281 case ISD::UDIVFIXSAT: ExpandIntRes_DIVFIX(N, Lo, Hi); break;
3282
3283 case ISD::VECREDUCE_ADD:
3284 case ISD::VECREDUCE_MUL:
3285 case ISD::VECREDUCE_AND:
3286 case ISD::VECREDUCE_OR:
3287 case ISD::VECREDUCE_XOR:
3291 case ISD::VECREDUCE_UMIN: ExpandIntRes_VECREDUCE(N, Lo, Hi); break;
3292
3293 case ISD::ROTL:
3294 case ISD::ROTR:
3295 ExpandIntRes_Rotate(N, Lo, Hi);
3296 break;
3297
3298 case ISD::FSHL:
3299 case ISD::FSHR:
3300 ExpandIntRes_FunnelShift(N, Lo, Hi);
3301 break;
3302
3303 case ISD::CLMUL:
3304 case ISD::CLMULR:
3305 case ISD::CLMULH:
3306 ExpandIntRes_CLMUL(N, Lo, Hi);
3307 break;
3308
3309 case ISD::VSCALE:
3310 ExpandIntRes_VSCALE(N, Lo, Hi);
3311 break;
3312
3313 case ISD::READ_REGISTER:
3314 ExpandIntRes_READ_REGISTER(N, Lo, Hi);
3315 break;
3316
3317 case ISD::CTTZ_ELTS:
3319 ExpandIntRes_CTTZ_ELTS(N, Lo, Hi);
3320 break;
3321 }
3322
3323 // If Lo/Hi is null, the sub-method took care of registering results etc.
3324 if (Lo.getNode())
3325 SetExpandedInteger(SDValue(N, ResNo), Lo, Hi);
3326}
3327
3328/// Lower an atomic node to the appropriate builtin call.
3329std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
3330 unsigned Opc = Node->getOpcode();
3331 MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
3332 AtomicOrdering order = cast<AtomicSDNode>(Node)->getMergedOrdering();
3333 // Lower to outline atomic libcall if outline atomics enabled,
3334 // or to sync libcall otherwise
3335 RTLIB::Libcall LC = RTLIB::getOUTLINE_ATOMIC(Opc, order, VT);
3336 EVT RetVT = Node->getValueType(0);
3337 TargetLowering::MakeLibCallOptions CallOptions;
3339
3340 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
3341 if (LCImpl != RTLIB::Unsupported) {
3342 Ops.append(Node->op_begin() + 2, Node->op_end());
3343 Ops.push_back(Node->getOperand(1));
3344 } else {
3345 LC = RTLIB::getSYNC(Opc, VT);
3346 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
3347 "Unexpected atomic op or value type!");
3348 Ops.append(Node->op_begin() + 1, Node->op_end());
3349 LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
3350 }
3351 return TLI.makeLibCall(DAG, LCImpl, RetVT, Ops, CallOptions, SDLoc(Node),
3352 Node->getOperand(0));
3353}
3354
3355/// N is a shift by a value that needs to be expanded,
3356/// and the shift amount is a constant 'Amt'. Expand the operation.
3357void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, const APInt &Amt,
3358 SDValue &Lo, SDValue &Hi) {
3359 SDLoc DL(N);
3360 // Expand the incoming operand to be shifted, so that we have its parts
3361 SDValue InL, InH;
3362 GetExpandedInteger(N->getOperand(0), InL, InH);
3363
3364 // Though Amt shouldn't usually be 0, it's possible. E.g. when legalization
3365 // splitted a vector shift, like this: <op1, op2> SHL <0, 2>.
3366 if (!Amt) {
3367 Lo = InL;
3368 Hi = InH;
3369 return;
3370 }
3371
3372 EVT NVT = InL.getValueType();
3373 unsigned VTBits = N->getValueType(0).getSizeInBits();
3374 unsigned NVTBits = NVT.getSizeInBits();
3375
3376 if (N->getOpcode() == ISD::SHL) {
3377 if (Amt.uge(VTBits)) {
3378 Lo = Hi = DAG.getConstant(0, DL, NVT);
3379 } else if (Amt.ugt(NVTBits)) {
3380 Lo = DAG.getConstant(0, DL, NVT);
3381 Hi = DAG.getNode(ISD::SHL, DL, NVT, InL,
3382 DAG.getShiftAmountConstant(Amt - NVTBits, NVT, DL));
3383 } else if (Amt == NVTBits) {
3384 Lo = DAG.getConstant(0, DL, NVT);
3385 Hi = InL;
3386 } else {
3387 Lo = DAG.getNode(ISD::SHL, DL, NVT, InL,
3388 DAG.getShiftAmountConstant(Amt, NVT, DL));
3389 // Use FSHL if legal so we don't need to combine it later.
3390 if (TLI.isOperationLegal(ISD::FSHL, NVT)) {
3391 Hi = DAG.getNode(ISD::FSHL, DL, NVT, InH, InL,
3392 DAG.getShiftAmountConstant(Amt, NVT, DL));
3393 } else {
3394 Hi = DAG.getNode(
3395 ISD::OR, DL, NVT,
3396 DAG.getNode(ISD::SHL, DL, NVT, InH,
3397 DAG.getShiftAmountConstant(Amt, NVT, DL)),
3398 DAG.getNode(ISD::SRL, DL, NVT, InL,
3399 DAG.getShiftAmountConstant(-Amt + NVTBits, NVT, DL)));
3400 }
3401 }
3402 return;
3403 }
3404
3405 if (N->getOpcode() == ISD::SRL) {
3406 if (Amt.uge(VTBits)) {
3407 Lo = Hi = DAG.getConstant(0, DL, NVT);
3408 } else if (Amt.ugt(NVTBits)) {
3409 Lo = DAG.getNode(ISD::SRL, DL, NVT, InH,
3410 DAG.getShiftAmountConstant(Amt - NVTBits, NVT, DL));
3411 Hi = DAG.getConstant(0, DL, NVT);
3412 } else if (Amt == NVTBits) {
3413 Lo = InH;
3414 Hi = DAG.getConstant(0, DL, NVT);
3415 } else {
3416 // Use FSHR if legal so we don't need to combine it later.
3417 if (TLI.isOperationLegal(ISD::FSHR, NVT)) {
3418 Lo = DAG.getNode(ISD::FSHR, DL, NVT, InH, InL,
3419 DAG.getShiftAmountConstant(Amt, NVT, DL));
3420 } else {
3421 Lo = DAG.getNode(
3422 ISD::OR, DL, NVT,
3423 DAG.getNode(ISD::SRL, DL, NVT, InL,
3424 DAG.getShiftAmountConstant(Amt, NVT, DL)),
3425 DAG.getNode(ISD::SHL, DL, NVT, InH,
3426 DAG.getShiftAmountConstant(-Amt + NVTBits, NVT, DL)));
3427 }
3428 Hi = DAG.getNode(ISD::SRL, DL, NVT, InH,
3429 DAG.getShiftAmountConstant(Amt, NVT, DL));
3430 }
3431 return;
3432 }
3433
3434 assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
3435 if (Amt.uge(VTBits)) {
3436 Hi = Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
3437 DAG.getShiftAmountConstant(NVTBits - 1, NVT, DL));
3438 } else if (Amt.ugt(NVTBits)) {
3439 Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
3440 DAG.getShiftAmountConstant(Amt - NVTBits, NVT, DL));
3441 Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
3442 DAG.getShiftAmountConstant(NVTBits - 1, NVT, DL));
3443 } else if (Amt == NVTBits) {
3444 Lo = InH;
3445 Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
3446 DAG.getShiftAmountConstant(NVTBits - 1, NVT, DL));
3447 } else {
3448 // Use FSHR if legal so we don't need to combine it later.
3449 if (TLI.isOperationLegal(ISD::FSHR, NVT)) {
3450 Lo = DAG.getNode(ISD::FSHR, DL, NVT, InH, InL,
3451 DAG.getShiftAmountConstant(Amt, NVT, DL));
3452 } else {
3453 Lo = DAG.getNode(
3454 ISD::OR, DL, NVT,
3455 DAG.getNode(ISD::SRL, DL, NVT, InL,
3456 DAG.getShiftAmountConstant(Amt, NVT, DL)),
3457 DAG.getNode(ISD::SHL, DL, NVT, InH,
3458 DAG.getShiftAmountConstant(-Amt + NVTBits, NVT, DL)));
3459 }
3460 Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
3461 DAG.getShiftAmountConstant(Amt, NVT, DL));
3462 }
3463}
3464
3465/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
3466/// this shift based on knowledge of the high bit of the shift amount. If we
3467/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
3468/// shift amount.
3469bool DAGTypeLegalizer::
3470ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
3471 unsigned Opc = N->getOpcode();
3472 SDValue In = N->getOperand(0);
3473 SDValue Amt = N->getOperand(1);
3474 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3475 EVT ShTy = Amt.getValueType();
3476 unsigned ShBits = ShTy.getScalarSizeInBits();
3477 unsigned NVTBits = NVT.getScalarSizeInBits();
3478 assert(isPowerOf2_32(NVTBits) &&
3479 "Expanded integer type size not a power of two!");
3480 SDLoc dl(N);
3481
3482 APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
3483 KnownBits Known = DAG.computeKnownBits(Amt);
3484
3485 // If we don't know anything about the high bits, exit.
3486 if (((Known.Zero | Known.One) & HighBitMask) == 0)
3487 return false;
3488
3489 // Get the incoming operand to be shifted.
3490 SDValue InL, InH;
3491 GetExpandedInteger(In, InL, InH);
3492
3493 // If we know that any of the high bits of the shift amount are one, then we
3494 // can do this as a couple of simple shifts.
3495 if (Known.One.intersects(HighBitMask)) {
3496 // Mask out the high bit, which we know is set.
3497 Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
3498 DAG.getConstant(~HighBitMask, dl, ShTy));
3499
3500 switch (Opc) {
3501 default: llvm_unreachable("Unknown shift");
3502 case ISD::SHL:
3503 Lo = DAG.getConstant(0, dl, NVT); // Low part is zero.
3504 Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
3505 return true;
3506 case ISD::SRL:
3507 Hi = DAG.getConstant(0, dl, NVT); // Hi part is zero.
3508 Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
3509 return true;
3510 case ISD::SRA:
3511 Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part.
3512 DAG.getConstant(NVTBits - 1, dl, ShTy));
3513 Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
3514 return true;
3515 }
3516 }
3517
3518 // If we know that all of the high bits of the shift amount are zero, then we
3519 // can do this as a couple of simple shifts.
3520 if (HighBitMask.isSubsetOf(Known.Zero)) {
3521 // Calculate 31-x. 31 is used instead of 32 to avoid creating an undefined
3522 // shift if x is zero. We can use XOR here because x is known to be smaller
3523 // than 32.
3524 SDValue Amt2 = DAG.getNode(ISD::XOR, dl, ShTy, Amt,
3525 DAG.getConstant(NVTBits - 1, dl, ShTy));
3526
3527 unsigned Op1, Op2;
3528 switch (Opc) {
3529 default: llvm_unreachable("Unknown shift");
3530 case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break;
3531 case ISD::SRL:
3532 case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break;
3533 }
3534
3535 // When shifting right the arithmetic for Lo and Hi is swapped.
3536 if (Opc != ISD::SHL)
3537 std::swap(InL, InH);
3538
3539 // Use a little trick to get the bits that move from Lo to Hi. First
3540 // shift by one bit.
3541 SDValue Sh1 = DAG.getNode(Op2, dl, NVT, InL, DAG.getConstant(1, dl, ShTy));
3542 // Then compute the remaining shift with amount-1.
3543 SDValue Sh2 = DAG.getNode(Op2, dl, NVT, Sh1, Amt2);
3544
3545 Lo = DAG.getNode(Opc, dl, NVT, InL, Amt);
3546 Hi = DAG.getNode(ISD::OR, dl, NVT, DAG.getNode(Op1, dl, NVT, InH, Amt),Sh2);
3547
3548 if (Opc != ISD::SHL)
3549 std::swap(Hi, Lo);
3550 return true;
3551 }
3552
3553 return false;
3554}
3555
3556/// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift
3557/// of any size.
3558bool DAGTypeLegalizer::
3559ExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
3560 SDValue Amt = N->getOperand(1);
3561 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3562 EVT ShTy = Amt.getValueType();
3563 unsigned NVTBits = NVT.getSizeInBits();
3564 assert(isPowerOf2_32(NVTBits) &&
3565 "Expanded integer type size not a power of two!");
3566 SDLoc dl(N);
3567
3568 // Get the incoming operand to be shifted.
3569 SDValue InL, InH;
3570 GetExpandedInteger(N->getOperand(0), InL, InH);
3571
3572 SDValue NVBitsNode = DAG.getConstant(NVTBits, dl, ShTy);
3573 SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode);
3574 SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
3575 SDValue isShort = DAG.getSetCC(dl, getSetCCResultType(ShTy),
3576 Amt, NVBitsNode, ISD::SETULT);
3577 SDValue isZero = DAG.getSetCC(dl, getSetCCResultType(ShTy),
3578 Amt, DAG.getConstant(0, dl, ShTy),
3579 ISD::SETEQ);
3580
3581 SDValue LoS, HiS, LoL, HiL;
3582 switch (N->getOpcode()) {
3583 default: llvm_unreachable("Unknown shift");
3584 case ISD::SHL:
3585 // Short: ShAmt < NVTBits
3586 LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
3587 HiS = DAG.getNode(ISD::OR, dl, NVT,
3588 DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
3589 DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack));
3590
3591 // Long: ShAmt >= NVTBits
3592 LoL = DAG.getConstant(0, dl, NVT); // Lo part is zero.
3593 HiL = DAG.getNode(ISD::SHL, dl, NVT, InL, AmtExcess); // Hi from Lo part.
3594
3595 Lo = DAG.getSelect(dl, NVT, isShort, LoS, LoL);
3596 Hi = DAG.getSelect(dl, NVT, isZero, InH,
3597 DAG.getSelect(dl, NVT, isShort, HiS, HiL));
3598 return true;
3599 case ISD::SRL:
3600 // Short: ShAmt < NVTBits
3601 HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
3602 LoS = DAG.getNode(ISD::OR, dl, NVT,
3603 DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
3604 // FIXME: If Amt is zero, the following shift generates an undefined result
3605 // on some architectures.
3606 DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
3607
3608 // Long: ShAmt >= NVTBits
3609 HiL = DAG.getConstant(0, dl, NVT); // Hi part is zero.
3610 LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part.
3611
3612 Lo = DAG.getSelect(dl, NVT, isZero, InL,
3613 DAG.getSelect(dl, NVT, isShort, LoS, LoL));
3614 Hi = DAG.getSelect(dl, NVT, isShort, HiS, HiL);
3615 return true;
3616 case ISD::SRA:
3617 // Short: ShAmt < NVTBits
3618 HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
3619 LoS = DAG.getNode(ISD::OR, dl, NVT,
3620 DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
3621 DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
3622
3623 // Long: ShAmt >= NVTBits
3624 HiL = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign of Hi part.
3625 DAG.getConstant(NVTBits - 1, dl, ShTy));
3626 LoL = DAG.getNode(ISD::SRA, dl, NVT, InH, AmtExcess); // Lo from Hi part.
3627
3628 Lo = DAG.getSelect(dl, NVT, isZero, InL,
3629 DAG.getSelect(dl, NVT, isShort, LoS, LoL));
3630 Hi = DAG.getSelect(dl, NVT, isShort, HiS, HiL);
3631 return true;
3632 }
3633}
3634
3635static std::pair<ISD::CondCode, ISD::NodeType> getExpandedMinMaxOps(int Op) {
3636
3637 switch (Op) {
3638 default: llvm_unreachable("invalid min/max opcode");
3639 case ISD::SMAX:
3640 return std::make_pair(ISD::SETGT, ISD::UMAX);
3641 case ISD::UMAX:
3642 return std::make_pair(ISD::SETUGT, ISD::UMAX);
3643 case ISD::SMIN:
3644 return std::make_pair(ISD::SETLT, ISD::UMIN);
3645 case ISD::UMIN:
3646 return std::make_pair(ISD::SETULT, ISD::UMIN);
3647 }
3648}
3649
3650void DAGTypeLegalizer::ExpandIntRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) {
3651 SDLoc DL(N);
3652
3653 SDValue LHS = N->getOperand(0);
3654 SDValue RHS = N->getOperand(1);
3655 EVT NewVT = getSetCCResultType(LHS.getValueType());
3656
3657 // Taking the same approach as ScalarizeVecRes_SETCC
3658 SDValue Res = DAG.getNode(ISD::SETCC, DL, NewVT, LHS, RHS, N->getOperand(2));
3659
3660 Res = DAG.getBoolExtOrTrunc(Res, DL, N->getValueType(0), NewVT);
3661 SplitInteger(Res, Lo, Hi);
3662}
3663
3664void DAGTypeLegalizer::ExpandIntRes_MINMAX(SDNode *N,
3665 SDValue &Lo, SDValue &Hi) {
3666 SDLoc DL(N);
3667
3668 SDValue LHS = N->getOperand(0);
3669 SDValue RHS = N->getOperand(1);
3670
3671 // If the upper halves are all sign bits, then we can perform the MINMAX on
3672 // the lower half and sign-extend the result to the upper half.
3673 unsigned NumBits = N->getValueType(0).getScalarSizeInBits();
3674 unsigned NumHalfBits = NumBits / 2;
3675 if (DAG.ComputeNumSignBits(LHS) > NumHalfBits &&
3676 DAG.ComputeNumSignBits(RHS) > NumHalfBits) {
3677 SDValue LHSL, LHSH, RHSL, RHSH;
3678 GetExpandedInteger(LHS, LHSL, LHSH);
3679 GetExpandedInteger(RHS, RHSL, RHSH);
3680 EVT NVT = LHSL.getValueType();
3681
3682 Lo = DAG.getNode(N->getOpcode(), DL, NVT, LHSL, RHSL);
3683 Hi = DAG.getNode(ISD::SRA, DL, NVT, Lo,
3684 DAG.getShiftAmountConstant(NumHalfBits - 1, NVT, DL));
3685 return;
3686 }
3687
3688 // The Lo of smin(X, -1) is LHSL if X is negative. Otherwise it's -1.
3689 // The Lo of smax(X, 0) is 0 if X is negative. Otherwise it's LHSL.
3690 if ((N->getOpcode() == ISD::SMAX && isNullConstant(RHS)) ||
3691 (N->getOpcode() == ISD::SMIN && isAllOnesConstant(RHS))) {
3692 SDValue LHSL, LHSH, RHSL, RHSH;
3693 GetExpandedInteger(LHS, LHSL, LHSH);
3694 GetExpandedInteger(RHS, RHSL, RHSH);
3695 EVT NVT = LHSL.getValueType();
3696 EVT CCT = getSetCCResultType(NVT);
3697
3698 SDValue HiNeg =
3699 DAG.getSetCC(DL, CCT, LHSH, DAG.getConstant(0, DL, NVT), ISD::SETLT);
3700 if (N->getOpcode() == ISD::SMIN) {
3701 Lo = DAG.getSelect(DL, NVT, HiNeg, LHSL, DAG.getAllOnesConstant(DL, NVT));
3702 } else {
3703 Lo = DAG.getSelect(DL, NVT, HiNeg, DAG.getConstant(0, DL, NVT), LHSL);
3704 }
3705 Hi = DAG.getNode(N->getOpcode(), DL, NVT, {LHSH, RHSH});
3706 return;
3707 }
3708
3709 const APInt *RHSVal = nullptr;
3710 if (auto *RHSConst = dyn_cast<ConstantSDNode>(RHS))
3711 RHSVal = &RHSConst->getAPIntValue();
3712
3713 // The high half of MIN/MAX is always just the the MIN/MAX of the
3714 // high halves of the operands. Expand this way if it appears profitable.
3715 if (RHSVal && (N->getOpcode() == ISD::UMIN || N->getOpcode() == ISD::UMAX) &&
3716 (RHSVal->countLeadingOnes() >= NumHalfBits ||
3717 RHSVal->countLeadingZeros() >= NumHalfBits)) {
3718 SDValue LHSL, LHSH, RHSL, RHSH;
3719 GetExpandedInteger(LHS, LHSL, LHSH);
3720 GetExpandedInteger(RHS, RHSL, RHSH);
3721 EVT NVT = LHSL.getValueType();
3722 EVT CCT = getSetCCResultType(NVT);
3723
3724 ISD::NodeType LoOpc;
3725 ISD::CondCode CondC;
3726 std::tie(CondC, LoOpc) = getExpandedMinMaxOps(N->getOpcode());
3727
3728 Hi = DAG.getNode(N->getOpcode(), DL, NVT, {LHSH, RHSH});
3729 // We need to know whether to select Lo part that corresponds to 'winning'
3730 // Hi part or if Hi parts are equal.
3731 SDValue IsHiLeft = DAG.getSetCC(DL, CCT, LHSH, RHSH, CondC);
3732 SDValue IsHiEq = DAG.getSetCC(DL, CCT, LHSH, RHSH, ISD::SETEQ);
3733
3734 // Lo part corresponding to the 'winning' Hi part
3735 SDValue LoCmp = DAG.getSelect(DL, NVT, IsHiLeft, LHSL, RHSL);
3736
3737 // Recursed Lo part if Hi parts are equal, this uses unsigned version
3738 SDValue LoMinMax = DAG.getNode(LoOpc, DL, NVT, {LHSL, RHSL});
3739
3740 Lo = DAG.getSelect(DL, NVT, IsHiEq, LoMinMax, LoCmp);
3741 return;
3742 }
3743
3744 // Expand to "a < b ? a : b" etc. Prefer ge/le if that simplifies
3745 // the compare.
3746 ISD::CondCode Pred;
3747 switch (N->getOpcode()) {
3748 default: llvm_unreachable("How did we get here?");
3749 case ISD::SMAX:
3750 if (RHSVal && RHSVal->countTrailingZeros() >= NumHalfBits)
3751 Pred = ISD::SETGE;
3752 else
3753 Pred = ISD::SETGT;
3754 break;
3755 case ISD::SMIN:
3756 if (RHSVal && RHSVal->countTrailingOnes() >= NumHalfBits)
3757 Pred = ISD::SETLE;
3758 else
3759 Pred = ISD::SETLT;
3760 break;
3761 case ISD::UMAX:
3762 if (RHSVal && RHSVal->countTrailingZeros() >= NumHalfBits)
3763 Pred = ISD::SETUGE;
3764 else
3765 Pred = ISD::SETUGT;
3766 break;
3767 case ISD::UMIN:
3768 if (RHSVal && RHSVal->countTrailingOnes() >= NumHalfBits)
3769 Pred = ISD::SETULE;
3770 else
3771 Pred = ISD::SETULT;
3772 break;
3773 }
3774 EVT VT = N->getValueType(0);
3775 EVT CCT = getSetCCResultType(VT);
3776 SDValue Cond = DAG.getSetCC(DL, CCT, LHS, RHS, Pred);
3777 SDValue Result = DAG.getSelect(DL, VT, Cond, LHS, RHS);
3778 SplitInteger(Result, Lo, Hi);
3779}
3780
3781void DAGTypeLegalizer::ExpandIntRes_CMP(SDNode *N, SDValue &Lo, SDValue &Hi) {
3782 SDValue ExpandedCMP = TLI.expandCMP(N, DAG);
3783 SplitInteger(ExpandedCMP, Lo, Hi);
3784}
3785
3786void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
3787 SDValue &Lo, SDValue &Hi) {
3788 SDLoc dl(N);
3789 // Expand the subcomponents.
3790 SDValue LHSL, LHSH, RHSL, RHSH;
3791 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3792 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3793
3794 EVT NVT = LHSL.getValueType();
3795 SDValue LoOps[2] = { LHSL, RHSL };
3796 SDValue HiOps[3] = { LHSH, RHSH };
3797
3798 bool HasOpCarry = TLI.isOperationLegalOrCustom(
3799 N->getOpcode() == ISD::ADD ? ISD::UADDO_CARRY : ISD::USUBO_CARRY,
3800 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
3801 if (HasOpCarry) {
3802 SDVTList VTList = DAG.getVTList(NVT, getSetCCResultType(NVT));
3803 if (N->getOpcode() == ISD::ADD) {
3804 Lo = DAG.getNode(ISD::UADDO, dl, VTList, LoOps);
3805 HiOps[2] = Lo.getValue(1);
3806 Hi = DAG.computeKnownBits(HiOps[2]).isZero()
3807 ? DAG.getNode(ISD::ADD, dl, NVT, ArrayRef(HiOps, 2))
3808 : DAG.getNode(ISD::UADDO_CARRY, dl, VTList, HiOps);
3809 } else {
3810 Lo = DAG.getNode(ISD::USUBO, dl, VTList, LoOps);
3811 HiOps[2] = Lo.getValue(1);
3812 Hi = DAG.computeKnownBits(HiOps[2]).isZero()
3813 ? DAG.getNode(ISD::SUB, dl, NVT, ArrayRef(HiOps, 2))
3814 : DAG.getNode(ISD::USUBO_CARRY, dl, VTList, HiOps);
3815 }
3816 return;
3817 }
3818
3819 // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support
3820 // them. TODO: Teach operation legalization how to expand unsupported
3821 // ADDC/ADDE/SUBC/SUBE. The problem is that these operations generate
3822 // a carry of type MVT::Glue, but there doesn't seem to be any way to
3823 // generate a value of this type in the expanded code sequence.
3824 bool hasCarry =
3825 TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
3827 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
3828
3829 if (hasCarry) {
3830 SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
3831 if (N->getOpcode() == ISD::ADD) {
3832 Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps);
3833 HiOps[2] = Lo.getValue(1);
3834 Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps);
3835 } else {
3836 Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps);
3837 HiOps[2] = Lo.getValue(1);
3838 Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps);
3839 }
3840 return;
3841 }
3842
3843 bool hasOVF =
3844 TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
3846 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
3847 TargetLoweringBase::BooleanContent BoolType = TLI.getBooleanContents(NVT);
3848
3849 if (hasOVF) {
3850 EVT OvfVT = getSetCCResultType(NVT);
3851 SDVTList VTList = DAG.getVTList(NVT, OvfVT);
3852 int RevOpc;
3853 if (N->getOpcode() == ISD::ADD) {
3854 RevOpc = ISD::SUB;
3855 Lo = DAG.getNode(ISD::UADDO, dl, VTList, LoOps);
3856 Hi = DAG.getNode(ISD::ADD, dl, NVT, ArrayRef(HiOps, 2));
3857 } else {
3858 RevOpc = ISD::ADD;
3859 Lo = DAG.getNode(ISD::USUBO, dl, VTList, LoOps);
3860 Hi = DAG.getNode(ISD::SUB, dl, NVT, ArrayRef(HiOps, 2));
3861 }
3862 SDValue OVF = Lo.getValue(1);
3863
3864 switch (BoolType) {
3866 OVF = DAG.getNode(ISD::AND, dl, OvfVT, DAG.getConstant(1, dl, OvfVT), OVF);
3867 [[fallthrough]];
3869 OVF = DAG.getZExtOrTrunc(OVF, dl, NVT);
3870 Hi = DAG.getNode(N->getOpcode(), dl, NVT, Hi, OVF);
3871 break;
3873 OVF = DAG.getSExtOrTrunc(OVF, dl, NVT);
3874 Hi = DAG.getNode(RevOpc, dl, NVT, Hi, OVF);
3875 }
3876 return;
3877 }
3878
3879 if (N->getOpcode() == ISD::ADD) {
3880 Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps);
3881 SDValue Cmp;
3882 // Special case: X+1 has a carry out if X+1==0. This may reduce the live
3883 // range of X. We assume comparing with 0 is cheap.
3884 if (isOneConstant(LoOps[1]))
3885 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo,
3886 DAG.getConstant(0, dl, NVT), ISD::SETEQ);
3887 else if (isAllOnesConstant(LoOps[1])) {
3888 if (isAllOnesConstant(HiOps[1]))
3889 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), LoOps[0],
3890 DAG.getConstant(0, dl, NVT), ISD::SETEQ);
3891 else
3892 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), LoOps[0],
3893 DAG.getConstant(0, dl, NVT), ISD::SETNE);
3894 } else
3895 Cmp = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo, LoOps[0],
3896 ISD::SETULT);
3897
3898 SDValue Carry;
3900 Carry = DAG.getZExtOrTrunc(Cmp, dl, NVT);
3901 else
3902 Carry = DAG.getSelect(dl, NVT, Cmp, DAG.getConstant(1, dl, NVT),
3903 DAG.getConstant(0, dl, NVT));
3904
3905 if (isAllOnesConstant(LoOps[1]) && isAllOnesConstant(HiOps[1])) {
3906 Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps[0], Carry);
3907 } else {
3908 Hi = DAG.getNode(ISD::ADD, dl, NVT, ArrayRef(HiOps, 2));
3909 Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry);
3910 }
3911 } else {
3912 Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps);
3913 Hi = DAG.getNode(ISD::SUB, dl, NVT, ArrayRef(HiOps, 2));
3914 SDValue Cmp =
3915 DAG.getSetCC(dl, getSetCCResultType(LoOps[0].getValueType()),
3916 LoOps[0], LoOps[1], ISD::SETULT);
3917
3918 SDValue Borrow;
3920 Borrow = DAG.getZExtOrTrunc(Cmp, dl, NVT);
3921 else
3922 Borrow = DAG.getSelect(dl, NVT, Cmp, DAG.getConstant(1, dl, NVT),
3923 DAG.getConstant(0, dl, NVT));
3924
3925 Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
3926 }
3927}
3928
3929void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
3930 SDValue &Lo, SDValue &Hi) {
3931 // Expand the subcomponents.
3932 SDValue LHSL, LHSH, RHSL, RHSH;
3933 SDLoc dl(N);
3934 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3935 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3936 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
3937 SDValue LoOps[2] = { LHSL, RHSL };
3938 SDValue HiOps[3] = { LHSH, RHSH };
3939
3940 if (N->getOpcode() == ISD::ADDC) {
3941 Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps);
3942 HiOps[2] = Lo.getValue(1);
3943 Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps);
3944 } else {
3945 Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps);
3946 HiOps[2] = Lo.getValue(1);
3947 Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps);
3948 }
3949
3950 // Legalized the flag result - switch anything that used the old flag to
3951 // use the new one.
3952 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
3953}
3954
3955void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
3956 SDValue &Lo, SDValue &Hi) {
3957 // Expand the subcomponents.
3958 SDValue LHSL, LHSH, RHSL, RHSH;
3959 SDLoc dl(N);
3960 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
3961 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
3962 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
3963 SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
3964 SDValue HiOps[3] = { LHSH, RHSH };
3965
3966 Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps);
3967 HiOps[2] = Lo.getValue(1);
3968 Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps);
3969
3970 // Legalized the flag result - switch anything that used the old flag to
3971 // use the new one.
3972 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
3973}
3974
3975void DAGTypeLegalizer::ExpandIntRes_UADDSUBO(SDNode *N,
3976 SDValue &Lo, SDValue &Hi) {
3977 SDValue LHS = N->getOperand(0);
3978 SDValue RHS = N->getOperand(1);
3979 SDLoc dl(N);
3980
3981 SDValue Ovf;
3982
3983 unsigned CarryOp, NoCarryOp;
3985 switch(N->getOpcode()) {
3986 case ISD::UADDO:
3987 CarryOp = ISD::UADDO_CARRY;
3988 NoCarryOp = ISD::ADD;
3989 Cond = ISD::SETULT;
3990 break;
3991 case ISD::USUBO:
3992 CarryOp = ISD::USUBO_CARRY;
3993 NoCarryOp = ISD::SUB;
3994 Cond = ISD::SETUGT;
3995 break;
3996 default:
3997 llvm_unreachable("Node has unexpected Opcode");
3998 }
3999
4000 bool HasCarryOp = TLI.isOperationLegalOrCustom(
4001 CarryOp, TLI.getTypeToExpandTo(*DAG.getContext(), LHS.getValueType()));
4002
4003 if (HasCarryOp) {
4004 // Expand the subcomponents.
4005 SDValue LHSL, LHSH, RHSL, RHSH;
4006 GetExpandedInteger(LHS, LHSL, LHSH);
4007 GetExpandedInteger(RHS, RHSL, RHSH);
4008 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
4009 SDValue LoOps[2] = { LHSL, RHSL };
4010 SDValue HiOps[3] = { LHSH, RHSH };
4011
4012 Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps);
4013 HiOps[2] = Lo.getValue(1);
4014 Hi = DAG.getNode(CarryOp, dl, VTList, HiOps);
4015
4016 Ovf = Hi.getValue(1);
4017 } else {
4018 // Expand the result by simply replacing it with the equivalent
4019 // non-overflow-checking operation.
4020 SDValue Sum = DAG.getNode(NoCarryOp, dl, LHS.getValueType(), LHS, RHS);
4021 SplitInteger(Sum, Lo, Hi);
4022
4023 if (N->getOpcode() == ISD::UADDO && isOneConstant(RHS)) {
4024 // Special case: uaddo X, 1 overflowed if X+1 == 0. We can detect this
4025 // with (Lo | Hi) == 0.
4026 SDValue Or = DAG.getNode(ISD::OR, dl, Lo.getValueType(), Lo, Hi);
4027 Ovf = DAG.getSetCC(dl, N->getValueType(1), Or,
4028 DAG.getConstant(0, dl, Lo.getValueType()), ISD::SETEQ);
4029 } else if (N->getOpcode() == ISD::UADDO && isAllOnesConstant(RHS)) {
4030 // Special case: uaddo X, -1 overflows if X == 0.
4031 Ovf =
4032 DAG.getSetCC(dl, N->getValueType(1), LHS,
4033 DAG.getConstant(0, dl, LHS.getValueType()), ISD::SETNE);
4034 } else {
4035 // Calculate the overflow: addition overflows iff a + b < a, and
4036 // subtraction overflows iff a - b > a.
4037 Ovf = DAG.getSetCC(dl, N->getValueType(1), Sum, LHS, Cond);
4038 }
4039 }
4040
4041 // Legalized the flag result - switch anything that used the old flag to
4042 // use the new one.
4043 ReplaceValueWith(SDValue(N, 1), Ovf);
4044}
4045
4046void DAGTypeLegalizer::ExpandIntRes_UADDSUBO_CARRY(SDNode *N, SDValue &Lo,
4047 SDValue &Hi) {
4048 // Expand the subcomponents.
4049 SDValue LHSL, LHSH, RHSL, RHSH;
4050 SDLoc dl(N);
4051 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
4052 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
4053 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
4054 SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
4055 SDValue HiOps[3] = { LHSH, RHSH, SDValue() };
4056
4057 Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps);
4058 HiOps[2] = Lo.getValue(1);
4059 Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps);
4060
4061 // Legalized the flag result - switch anything that used the old flag to
4062 // use the new one.
4063 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
4064}
4065
4066void DAGTypeLegalizer::ExpandIntRes_SADDSUBO_CARRY(SDNode *N,
4067 SDValue &Lo, SDValue &Hi) {
4068 // Expand the subcomponents.
4069 SDValue LHSL, LHSH, RHSL, RHSH;
4070 SDLoc dl(N);
4071 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
4072 GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
4073 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
4074
4075 // We need to use an unsigned carry op for the lo part.
4076 unsigned CarryOp =
4078 Lo = DAG.getNode(CarryOp, dl, VTList, { LHSL, RHSL, N->getOperand(2) });
4079 Hi = DAG.getNode(N->getOpcode(), dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
4080
4081 // Legalized the flag result - switch anything that used the old flag to
4082 // use the new one.
4083 ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
4084}
4085
4086void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
4087 SDValue &Lo, SDValue &Hi) {
4088 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4089 SDLoc dl(N);
4090 SDValue Op = N->getOperand(0);
4091 if (Op.getValueType().bitsLE(NVT)) {
4092 // The low part is any extension of the input (which degenerates to a copy).
4093 Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op);
4094 Hi = DAG.getUNDEF(NVT); // The high part is undefined.
4095 } else {
4096 // For example, extension of an i48 to an i64. The operand type necessarily
4097 // promotes to the result type, so will end up being expanded too.
4098 assert(getTypeAction(Op.getValueType()) ==
4100 "Only know how to promote this result!");
4101 SDValue Res = GetPromotedInteger(Op);
4102 assert(Res.getValueType() == N->getValueType(0) &&
4103 "Operand over promoted?");
4104 // Split the promoted operand. This will simplify when it is expanded.
4105 SplitInteger(Res, Lo, Hi);
4106 }
4107}
4108
4109void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
4110 SDValue &Lo, SDValue &Hi) {
4111 SDLoc dl(N);
4112 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4113 EVT NVT = Lo.getValueType();
4114 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
4115 unsigned NVTBits = NVT.getSizeInBits();
4116 unsigned EVTBits = EVT.getSizeInBits();
4117
4118 if (NVTBits < EVTBits) {
4119 Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi,
4120 DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
4121 EVTBits - NVTBits)));
4122 } else {
4123 Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
4124 // The high part replicates the sign bit of Lo, make it explicit.
4125 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
4126 DAG.getShiftAmountConstant(NVTBits - 1, NVT, dl));
4127 }
4128}
4129
4130void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
4131 SDValue &Lo, SDValue &Hi) {
4132 SDLoc dl(N);
4133 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4134 EVT NVT = Lo.getValueType();
4135 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
4136 unsigned NVTBits = NVT.getSizeInBits();
4137 unsigned EVTBits = EVT.getSizeInBits();
4138
4139 if (NVTBits < EVTBits) {
4140 Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi,
4141 DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
4142 EVTBits - NVTBits)));
4143 } else {
4144 Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT));
4145 // The high part must be zero, make it explicit.
4146 Hi = DAG.getConstant(0, dl, NVT);
4147 }
4148}
4149
4150void DAGTypeLegalizer::ExpandIntRes_BITREVERSE(SDNode *N,
4151 SDValue &Lo, SDValue &Hi) {
4152 SDLoc dl(N);
4153 GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands.
4154 Lo = DAG.getNode(ISD::BITREVERSE, dl, Lo.getValueType(), Lo);
4155 Hi = DAG.getNode(ISD::BITREVERSE, dl, Hi.getValueType(), Hi);
4156}
4157
4158void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
4159 SDValue &Lo, SDValue &Hi) {
4160 SDLoc dl(N);
4161 GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands.
4162 Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo);
4163 Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
4164}
4165
4166void DAGTypeLegalizer::ExpandIntRes_PARITY(SDNode *N, SDValue &Lo,
4167 SDValue &Hi) {
4168 SDLoc dl(N);
4169 // parity(HiLo) -> parity(Lo^Hi)
4170 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4171 EVT NVT = Lo.getValueType();
4172 Lo =
4173 DAG.getNode(ISD::PARITY, dl, NVT, DAG.getNode(ISD::XOR, dl, NVT, Lo, Hi));
4174 Hi = DAG.getConstant(0, dl, NVT);
4175}
4176
4177void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
4178 SDValue &Lo, SDValue &Hi) {
4179 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4180 unsigned NBitWidth = NVT.getSizeInBits();
4182 const APInt &Cst = Constant->getAPIntValue();
4183 bool IsTarget = Constant->isTargetOpcode();
4184 bool IsOpaque = Constant->isOpaque();
4185 SDLoc dl(N);
4186 Lo = DAG.getConstant(Cst.trunc(NBitWidth), dl, NVT, IsTarget, IsOpaque);
4187 Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), dl, NVT, IsTarget,
4188 IsOpaque);
4189}
4190
4191void DAGTypeLegalizer::ExpandIntRes_ABS(SDNode *N, SDValue &Lo, SDValue &Hi) {
4192 SDLoc dl(N);
4193
4194 SDValue N0 = N->getOperand(0);
4195 GetExpandedInteger(N0, Lo, Hi);
4196 EVT NVT = Lo.getValueType();
4197
4198 // If the upper half is all sign bits, then we can perform the ABS on the
4199 // lower half and zero-extend. We could use ISD::ABS_MIN_POISON here if
4200 // DAG.ComputeNumSignBits(N0) is larger than NVT.getScalarSizeInBits() + 1.
4201 unsigned NumSignBits = DAG.ComputeNumSignBits(N0);
4202 if (NumSignBits > NVT.getScalarSizeInBits()) {
4203 unsigned AbsOpc = NumSignBits > NVT.getScalarSizeInBits() + 1
4205 : ISD::ABS;
4206 Lo = DAG.getNode(AbsOpc, dl, NVT, Lo);
4207 Hi = DAG.getConstant(0, dl, NVT);
4208 return;
4209 }
4210
4211 // If we have USUBO_CARRY, use the expanded form of the sra+xor+sub sequence
4212 // we use in LegalizeDAG. The SUB part of the expansion is based on
4213 // ExpandIntRes_ADDSUB which also uses USUBO_CARRY/USUBO after checking that
4214 // USUBO_CARRY is LegalOrCustom. Each of the pieces here can be further
4215 // expanded if needed. Shift expansion has a special case for filling with
4216 // sign bits so that we will only end up with one SRA.
4217 bool HasSubCarry = TLI.isOperationLegalOrCustom(
4218 ISD::USUBO_CARRY, TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
4219 if (HasSubCarry) {
4220 SDValue Sign = DAG.getNode(
4221 ISD::SRA, dl, NVT, Hi,
4222 DAG.getShiftAmountConstant(NVT.getSizeInBits() - 1, NVT, dl));
4223 SDVTList VTList = DAG.getVTList(NVT, getSetCCResultType(NVT));
4224 Lo = DAG.getNode(ISD::XOR, dl, NVT, Lo, Sign);
4225 Hi = DAG.getNode(ISD::XOR, dl, NVT, Hi, Sign);
4226 Lo = DAG.getNode(ISD::USUBO, dl, VTList, Lo, Sign);
4227 Hi = DAG.getNode(ISD::USUBO_CARRY, dl, VTList, Hi, Sign, Lo.getValue(1));
4228 return;
4229 }
4230
4231 // abs(HiLo) -> (Hi < 0 ? -HiLo : HiLo)
4232 EVT VT = N->getValueType(0);
4233 SDValue Neg = DAG.getNode(ISD::SUB, dl, VT,
4234 DAG.getConstant(0, dl, VT), N0);
4235 SDValue NegLo, NegHi;
4236 SplitInteger(Neg, NegLo, NegHi);
4237
4238 SDValue HiIsNeg = DAG.getSetCC(dl, getSetCCResultType(NVT), Hi,
4239 DAG.getConstant(0, dl, NVT), ISD::SETLT);
4240 Lo = DAG.getSelect(dl, NVT, HiIsNeg, NegLo, Lo);
4241 Hi = DAG.getSelect(dl, NVT, HiIsNeg, NegHi, Hi);
4242}
4243
4244void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
4245 SDValue &Lo, SDValue &Hi) {
4246 SDLoc dl(N);
4247 // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
4248 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4249 EVT NVT = Lo.getValueType();
4250
4251 SDValue HiNotZero = DAG.getSetCC(dl, getSetCCResultType(NVT), Hi,
4252 DAG.getConstant(0, dl, NVT), ISD::SETNE);
4253
4254 SDValue LoLZ = DAG.getNode(N->getOpcode(), dl, NVT, Lo);
4255 SDValue HiLZ = DAG.getNode(ISD::CTLZ_ZERO_POISON, dl, NVT, Hi);
4256
4257 Lo = DAG.getSelect(dl, NVT, HiNotZero, HiLZ,
4258 DAG.getNode(ISD::ADD, dl, NVT, LoLZ,
4259 DAG.getConstant(NVT.getSizeInBits(), dl,
4260 NVT)));
4261 Hi = DAG.getConstant(0, dl, NVT);
4262}
4263
4264void DAGTypeLegalizer::ExpandIntRes_CTLS(SDNode *N, SDValue &Lo, SDValue &Hi) {
4265 SDLoc dl(N);
4266 // ctls(HiLo) -> if (IsAllSignBits = (ctls(Hi) == BW-1)) then
4267 // BW-1 + clz(IsNegative = (Hi < 0) ? ~Lo : Lo)
4268 // else ctls(Hi)
4269 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4270 EVT NVT = Lo.getValueType();
4271 unsigned NVTBits = NVT.getScalarSizeInBits();
4272
4273 SDValue Constant0 = DAG.getConstant(0, dl, NVT);
4274 SDValue ConstantBWM1 = DAG.getConstant(NVTBits - 1, dl, NVT);
4275
4276 SDValue HiCTLS = DAG.getNode(ISD::CTLS, dl, NVT, Hi);
4277 SDValue IsAllSignBits = DAG.getSetCC(dl, getSetCCResultType(NVT), HiCTLS,
4278 ConstantBWM1, ISD::SETEQ);
4279 SDValue IsNegative =
4280 DAG.getSetCC(dl, getSetCCResultType(NVT), Hi, Constant0, ISD::SETLT);
4281 SDValue AdjustedLo =
4282 DAG.getSelect(dl, NVT, IsNegative, DAG.getNOT(dl, Lo, NVT), Lo);
4283 SDValue LoCLZ = DAG.getNode(ISD::CTLZ, dl, NVT, AdjustedLo);
4284 Lo = DAG.getSelect(dl, NVT, IsAllSignBits,
4285 DAG.getNode(ISD::ADD, dl, NVT, LoCLZ, ConstantBWM1),
4286 HiCTLS);
4287 Hi = DAG.getConstant(0, dl, NVT);
4288}
4289
4290void DAGTypeLegalizer::ExpandIntRes_ABD(SDNode *N, SDValue &Lo, SDValue &Hi) {
4291 SDValue Result = TLI.expandABD(N, DAG);
4292 SplitInteger(Result, Lo, Hi);
4293}
4294
4295void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N, SDValue &Lo, SDValue &Hi) {
4296 SDValue Op = N->getOperand(0);
4297 EVT VT = N->getValueType(0);
4298 SDLoc DL(N);
4299
4300 if (TLI.getOperationAction(ISD::CTPOP, VT) == TargetLoweringBase::LibCall) {
4301 RTLIB::Libcall LC = RTLIB::getCTPOP(VT);
4302 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
4303 "LibCall explicitly requested, but not available");
4304
4305 if (RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC)) {
4306 TargetLowering::MakeLibCallOptions CallOptions;
4307 EVT IntVT =
4308 EVT::getIntegerVT(*DAG.getContext(), DAG.getLibInfo().getIntSize());
4309 SDValue Res =
4310 TLI.makeLibCall(DAG, LCImpl, IntVT, Op, CallOptions, DL).first;
4311 SplitInteger(DAG.getSExtOrTrunc(Res, DL, VT), Lo, Hi);
4312 return;
4313 }
4314
4315 // If the function is not available, fall back on the expansion.
4316 }
4317
4318 // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
4319 GetExpandedInteger(Op, Lo, Hi);
4320 EVT NVT = Lo.getValueType();
4321 Lo = DAG.getNode(ISD::ADD, DL, NVT, DAG.getNode(ISD::CTPOP, DL, NVT, Lo),
4322 DAG.getNode(ISD::CTPOP, DL, NVT, Hi));
4323 Hi = DAG.getConstant(0, DL, NVT);
4324}
4325
4326void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
4327 SDValue &Lo, SDValue &Hi) {
4328 SDLoc dl(N);
4329 // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
4330 GetExpandedInteger(N->getOperand(0), Lo, Hi);
4331 EVT NVT = Lo.getValueType();
4332
4333 SDValue LoNotZero = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo,
4334 DAG.getConstant(0, dl, NVT), ISD::SETNE);
4335
4336 SDValue LoLZ = DAG.getNode(ISD::CTTZ_ZERO_POISON, dl, NVT, Lo);
4337 SDValue HiLZ = DAG.getNode(N->getOpcode(), dl, NVT, Hi);
4338
4339 Lo = DAG.getSelect(dl, NVT, LoNotZero, LoLZ,
4340 DAG.getNode(ISD::ADD, dl, NVT, HiLZ,
4341 DAG.getConstant(NVT.getSizeInBits(), dl,
4342 NVT)));
4343 Hi = DAG.getConstant(0, dl, NVT);
4344}
4345
4346void DAGTypeLegalizer::ExpandIntRes_GET_ROUNDING(SDNode *N, SDValue &Lo,
4347 SDValue &Hi) {
4348 SDLoc dl(N);
4349 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4350 unsigned NBitWidth = NVT.getSizeInBits();
4351
4352 Lo = DAG.getNode(ISD::GET_ROUNDING, dl, {NVT, MVT::Other}, N->getOperand(0));
4353 SDValue Chain = Lo.getValue(1);
4354 // The high part is the sign of Lo, as -1 is a valid value for GET_ROUNDING
4355 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
4356 DAG.getShiftAmountConstant(NBitWidth - 1, NVT, dl));
4357
4358 // Legalize the chain result - switch anything that used the old chain to
4359 // use the new one.
4360 ReplaceValueWith(SDValue(N, 1), Chain);
4361}
4362
4363// Helper for producing an FP_EXTEND/STRICT_FP_EXTEND of Op.
4364static SDValue fpExtendHelper(SDValue Op, SDValue &Chain, bool IsStrict, EVT VT,
4365 SDLoc DL, SelectionDAG &DAG) {
4366 if (IsStrict) {
4367 Op = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {VT, MVT::Other}, {Chain, Op});
4368 Chain = Op.getValue(1);
4369 return Op;
4370 }
4371 return DAG.getNode(ISD::FP_EXTEND, DL, VT, Op);
4372}
4373
4374void DAGTypeLegalizer::ExpandIntRes_FP_TO_XINT(SDNode *N, SDValue &Lo,
4375 SDValue &Hi) {
4376 SDLoc dl(N);
4377 EVT VT = N->getValueType(0);
4378
4379 bool IsSigned = N->getOpcode() == ISD::FP_TO_SINT ||
4380 N->getOpcode() == ISD::STRICT_FP_TO_SINT;
4381 bool IsStrict = N->isStrictFPOpcode();
4382 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
4383 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
4384
4385 // If the input is bf16 or needs to be soft promoted, extend to f32.
4386 if (getTypeAction(Op.getValueType()) == TargetLowering::TypeSoftPromoteHalf ||
4387 Op.getValueType() == MVT::bf16) {
4388 Op = fpExtendHelper(Op, Chain, IsStrict, MVT::f32, dl, DAG);
4389 }
4390
4391 // NOTE: We need a variable that lives across makeLibCall so
4392 // CallOptions.setTypeListBeforeSoften can save a reference to it.
4393 EVT OpVT = Op.getValueType();
4394
4395 RTLIB::Libcall LC =
4396 IsSigned ? RTLIB::getFPTOSINT(OpVT, VT) : RTLIB::getFPTOUINT(OpVT, VT);
4397 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-xint conversion!");
4398 TargetLowering::MakeLibCallOptions CallOptions;
4399 if (getTypeAction(Op.getValueType()) == TargetLowering::TypeSoftenFloat)
4400 CallOptions.setTypeListBeforeSoften(OpVT, VT);
4401 else
4402 CallOptions.setIsSigned(true); // FIXME: Is this needed?
4403 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, VT, Op,
4404 CallOptions, dl, Chain);
4405 SplitInteger(Tmp.first, Lo, Hi);
4406
4407 if (IsStrict)
4408 ReplaceValueWith(SDValue(N, 1), Tmp.second);
4409}
4410
4411void DAGTypeLegalizer::ExpandIntRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo,
4412 SDValue &Hi) {
4413 SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
4414 SplitInteger(Res, Lo, Hi);
4415}
4416
4417void DAGTypeLegalizer::ExpandIntRes_XROUND_XRINT(SDNode *N, SDValue &Lo,
4418 SDValue &Hi) {
4419 SDLoc dl(N);
4420 bool IsStrict = N->isStrictFPOpcode();
4421 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
4422 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
4423
4424 EVT VT = Op.getValueType();
4425
4426 if (VT == MVT::f16) {
4427 // Extend to f32.
4428 VT = MVT::f32;
4429 Op = fpExtendHelper(Op, Chain, IsStrict, VT, dl, DAG);
4430 }
4431
4432 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
4433 if (N->getOpcode() == ISD::LROUND ||
4434 N->getOpcode() == ISD::STRICT_LROUND) {
4435 LC = RTLIB::getLROUND(VT);
4436 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected lround input type!");
4437 } else if (N->getOpcode() == ISD::LRINT ||
4438 N->getOpcode() == ISD::STRICT_LRINT) {
4439 LC = RTLIB::getLRINT(VT);
4440 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected lrint input type!");
4441 } else if (N->getOpcode() == ISD::LLROUND ||
4442 N->getOpcode() == ISD::STRICT_LLROUND) {
4443 LC = RTLIB::getLLROUND(VT);
4444 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected llround input type!");
4445 } else if (N->getOpcode() == ISD::LLRINT ||
4446 N->getOpcode() == ISD::STRICT_LLRINT) {
4447 LC = RTLIB::getLLRINT(VT);
4448 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected llrint input type!");
4449 } else
4450 llvm_unreachable("Unexpected opcode!");
4451
4452 EVT RetVT = N->getValueType(0);
4453
4454 TargetLowering::MakeLibCallOptions CallOptions;
4455 CallOptions.setIsSigned(true);
4456 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RetVT,
4457 Op, CallOptions, dl,
4458 Chain);
4459 SplitInteger(Tmp.first, Lo, Hi);
4460
4461 if (N->isStrictFPOpcode())
4462 ReplaceValueWith(SDValue(N, 1), Tmp.second);
4463}
4464
4465void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
4466 SDValue &Lo, SDValue &Hi) {
4467 assert(!N->isAtomic() && "Should have been a ATOMIC_LOAD?");
4468
4469 if (ISD::isNormalLoad(N)) {
4470 ExpandRes_NormalLoad(N, Lo, Hi);
4471 return;
4472 }
4473
4474 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
4475
4476 EVT VT = N->getValueType(0);
4477 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4478 SDValue Ch = N->getChain();
4479 SDValue Ptr = N->getBasePtr();
4480 ISD::LoadExtType ExtType = N->getExtensionType();
4481 MachineMemOperand::Flags MMOFlags = N->getMemOperand()->getFlags();
4482 AAMDNodes AAInfo = N->getAAInfo();
4483 SDLoc dl(N);
4484
4485 assert(NVT.isByteSized() && "Expanded type not byte sized!");
4486
4487 if (N->getMemoryVT().bitsLE(NVT)) {
4488 EVT MemVT = N->getMemoryVT();
4489
4490 Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(), MemVT,
4491 N->getBaseAlign(), MMOFlags, AAInfo);
4492
4493 // Remember the chain.
4494 Ch = Lo.getValue(1);
4495
4496 if (ExtType == ISD::SEXTLOAD) {
4497 // The high part is obtained by SRA'ing all but one of the bits of the
4498 // lo part.
4499 unsigned LoSize = Lo.getValueSizeInBits();
4500 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
4501 DAG.getShiftAmountConstant(LoSize - 1, NVT, dl));
4502 } else if (ExtType == ISD::ZEXTLOAD) {
4503 // The high part is just a zero.
4504 Hi = DAG.getConstant(0, dl, NVT);
4505 } else {
4506 assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
4507 // The high part is undefined.
4508 Hi = DAG.getUNDEF(NVT);
4509 }
4510 } else if (DAG.getDataLayout().isLittleEndian()) {
4511 // Little-endian - low bits are at low addresses.
4512 Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getPointerInfo(), N->getBaseAlign(),
4513 MMOFlags, AAInfo);
4514
4515 unsigned ExcessBits =
4516 N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
4517 EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
4518
4519 // Increment the pointer to the other half.
4520 unsigned IncrementSize = NVT.getSizeInBits()/8;
4521 Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::getFixed(IncrementSize), dl);
4522 Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr,
4523 N->getPointerInfo().getWithOffset(IncrementSize), NEVT,
4524 N->getBaseAlign(), MMOFlags, AAInfo);
4525
4526 // Build a factor node to remember that this load is independent of the
4527 // other one.
4528 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
4529 Hi.getValue(1));
4530 } else {
4531 // Big-endian - high bits are at low addresses. Favor aligned loads at
4532 // the cost of some bit-fiddling.
4533 EVT MemVT = N->getMemoryVT();
4534 unsigned EBytes = MemVT.getStoreSize();
4535 unsigned IncrementSize = NVT.getSizeInBits()/8;
4536 unsigned ExcessBits = (EBytes - IncrementSize)*8;
4537
4538 // Load both the high bits and maybe some of the low bits.
4539 Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
4540 EVT::getIntegerVT(*DAG.getContext(),
4541 MemVT.getSizeInBits() - ExcessBits),
4542 N->getBaseAlign(), MMOFlags, AAInfo);
4543
4544 // Increment the pointer to the other half.
4545 Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::getFixed(IncrementSize), dl);
4546 // Load the rest of the low bits.
4547 Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr,
4548 N->getPointerInfo().getWithOffset(IncrementSize),
4549 EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
4550 N->getBaseAlign(), MMOFlags, AAInfo);
4551
4552 // Build a factor node to remember that this load is independent of the
4553 // other one.
4554 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
4555 Hi.getValue(1));
4556
4557 if (ExcessBits < NVT.getSizeInBits()) {
4558 // Transfer low bits from the bottom of Hi to the top of Lo.
4559 Lo = DAG.getNode(
4560 ISD::OR, dl, NVT, Lo,
4561 DAG.getNode(ISD::SHL, dl, NVT, Hi,
4562 DAG.getShiftAmountConstant(ExcessBits, NVT, dl)));
4563 // Move high bits to the right position in Hi.
4564 Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, NVT,
4565 Hi,
4566 DAG.getShiftAmountConstant(
4567 NVT.getSizeInBits() - ExcessBits, NVT, dl));
4568 }
4569 }
4570
4571 // Legalize the chain result - switch anything that used the old chain to
4572 // use the new one.
4573 ReplaceValueWith(SDValue(N, 1), Ch);
4574}
4575
4576void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
4577 SDValue &Lo, SDValue &Hi) {
4578 SDLoc dl(N);
4579 SDValue LL, LH, RL, RH;
4580 GetExpandedInteger(N->getOperand(0), LL, LH);
4581 GetExpandedInteger(N->getOperand(1), RL, RH);
4582
4583 SDNodeFlags Flags;
4584 if (N->getOpcode() == ISD::OR)
4585 Flags.setDisjoint(N->getFlags().hasDisjoint());
4586
4587 Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL, Flags);
4588 Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH, Flags);
4589}
4590
4591void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
4592 SDValue &Lo, SDValue &Hi) {
4593 EVT VT = N->getValueType(0);
4594 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4595 SDLoc dl(N);
4596
4597 SDValue LL, LH, RL, RH;
4598 GetExpandedInteger(N->getOperand(0), LL, LH);
4599 GetExpandedInteger(N->getOperand(1), RL, RH);
4600
4601 if (TLI.expandMUL(N, Lo, Hi, NVT, DAG,
4603 LL, LH, RL, RH))
4604 return;
4605
4606 // If nothing else, we can make a libcall.
4607 RTLIB::Libcall LC = RTLIB::getMUL(VT);
4608 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
4609 if (LCImpl == RTLIB::Unsupported) {
4610 // Perform a wide multiplication where the wide type is the original VT and
4611 // the 4 parts are the split arguments.
4612 TLI.forceExpandMultiply(DAG, dl, /*Signed=*/false, Lo, Hi, LL, RL, LH, RH);
4613 return;
4614 }
4615
4616 // Note that we don't need to do a wide MUL here since we don't care about the
4617 // upper half of the result if it exceeds VT.
4618 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4619 TargetLowering::MakeLibCallOptions CallOptions;
4620 CallOptions.setIsSigned(true);
4621 SplitInteger(TLI.makeLibCall(DAG, LCImpl, VT, Ops, CallOptions, dl).first, Lo,
4622 Hi);
4623}
4624
4625void DAGTypeLegalizer::ExpandIntRes_READCOUNTER(SDNode *N, SDValue &Lo,
4626 SDValue &Hi) {
4627 SDLoc DL(N);
4628 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4629 SDVTList VTs = DAG.getVTList(NVT, NVT, MVT::Other);
4630 SDValue R = DAG.getNode(N->getOpcode(), DL, VTs, N->getOperand(0));
4631 Lo = R.getValue(0);
4632 Hi = R.getValue(1);
4633 ReplaceValueWith(SDValue(N, 1), R.getValue(2));
4634}
4635
4636void DAGTypeLegalizer::ExpandIntRes_AVG(SDNode *N, SDValue &Lo, SDValue &Hi) {
4637 SDValue Result = TLI.expandAVG(N, DAG);
4638 SplitInteger(Result, Lo, Hi);
4639}
4640
4641void DAGTypeLegalizer::ExpandIntRes_ADDSUBSAT(SDNode *N, SDValue &Lo,
4642 SDValue &Hi) {
4643 SDValue Result = TLI.expandAddSubSat(N, DAG);
4644 SplitInteger(Result, Lo, Hi);
4645}
4646
4647void DAGTypeLegalizer::ExpandIntRes_SHLSAT(SDNode *N, SDValue &Lo,
4648 SDValue &Hi) {
4649 SDValue Result = TLI.expandShlSat(N, DAG);
4650 SplitInteger(Result, Lo, Hi);
4651}
4652
4653/// This performs an expansion of the integer result for a fixed point
4654/// multiplication. The default expansion performs rounding down towards
4655/// negative infinity, though targets that do care about rounding should specify
4656/// a target hook for rounding and provide their own expansion or lowering of
4657/// fixed point multiplication to be consistent with rounding.
4658void DAGTypeLegalizer::ExpandIntRes_MULFIX(SDNode *N, SDValue &Lo,
4659 SDValue &Hi) {
4660 SDLoc dl(N);
4661 EVT VT = N->getValueType(0);
4662 unsigned VTSize = VT.getScalarSizeInBits();
4663 SDValue LHS = N->getOperand(0);
4664 SDValue RHS = N->getOperand(1);
4665 uint64_t Scale = N->getConstantOperandVal(2);
4666 bool Saturating = (N->getOpcode() == ISD::SMULFIXSAT ||
4667 N->getOpcode() == ISD::UMULFIXSAT);
4668 bool Signed = (N->getOpcode() == ISD::SMULFIX ||
4669 N->getOpcode() == ISD::SMULFIXSAT);
4670
4671 // Handle special case when scale is equal to zero.
4672 if (!Scale) {
4674 if (!Saturating) {
4675 Result = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS);
4676 } else {
4677 EVT BoolVT = getSetCCResultType(VT);
4678 unsigned MulOp = Signed ? ISD::SMULO : ISD::UMULO;
4679 Result = DAG.getNode(MulOp, dl, DAG.getVTList(VT, BoolVT), LHS, RHS);
4680 SDValue Product = Result.getValue(0);
4681 SDValue Overflow = Result.getValue(1);
4682 if (Signed) {
4683 APInt MinVal = APInt::getSignedMinValue(VTSize);
4684 APInt MaxVal = APInt::getSignedMaxValue(VTSize);
4685 SDValue SatMin = DAG.getConstant(MinVal, dl, VT);
4686 SDValue SatMax = DAG.getConstant(MaxVal, dl, VT);
4687 SDValue Zero = DAG.getConstant(0, dl, VT);
4688 // Xor the inputs, if resulting sign bit is 0 the product will be
4689 // positive, else negative.
4690 SDValue Xor = DAG.getNode(ISD::XOR, dl, VT, LHS, RHS);
4691 SDValue ProdNeg = DAG.getSetCC(dl, BoolVT, Xor, Zero, ISD::SETLT);
4692 Result = DAG.getSelect(dl, VT, ProdNeg, SatMin, SatMax);
4693 Result = DAG.getSelect(dl, VT, Overflow, Result, Product);
4694 } else {
4695 // For unsigned multiplication, we only need to check the max since we
4696 // can't really overflow towards zero.
4697 APInt MaxVal = APInt::getMaxValue(VTSize);
4698 SDValue SatMax = DAG.getConstant(MaxVal, dl, VT);
4699 Result = DAG.getSelect(dl, VT, Overflow, SatMax, Product);
4700 }
4701 }
4702 SplitInteger(Result, Lo, Hi);
4703 return;
4704 }
4705
4706 // For SMULFIX[SAT] we only expect to find Scale<VTSize, but this assert will
4707 // cover for unhandled cases below, while still being valid for UMULFIX[SAT].
4708 assert(Scale <= VTSize && "Scale can't be larger than the value type size.");
4709
4710 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4711 SDValue LL, LH, RL, RH;
4712 GetExpandedInteger(LHS, LL, LH);
4713 GetExpandedInteger(RHS, RL, RH);
4715
4716 unsigned LoHiOp = Signed ? ISD::SMUL_LOHI : ISD::UMUL_LOHI;
4717 if (!TLI.expandMUL_LOHI(LoHiOp, VT, dl, LHS, RHS, Result, NVT, DAG,
4719 LL, LH, RL, RH)) {
4720 Result.clear();
4721 Result.resize(4);
4722
4723 SDValue LoTmp, HiTmp;
4724 TLI.forceExpandWideMUL(DAG, dl, Signed, LHS, RHS, LoTmp, HiTmp);
4725 SplitInteger(LoTmp, Result[0], Result[1]);
4726 SplitInteger(HiTmp, Result[2], Result[3]);
4727 }
4728 assert(Result.size() == 4 && "Unexpected number of partlets in the result");
4729
4730 unsigned NVTSize = NVT.getScalarSizeInBits();
4731 assert((VTSize == NVTSize * 2) && "Expected the new value type to be half "
4732 "the size of the current value type");
4733
4734 // After getting the multiplication result in 4 parts, we need to perform a
4735 // shift right by the amount of the scale to get the result in that scale.
4736 //
4737 // Let's say we multiply 2 64 bit numbers. The resulting value can be held in
4738 // 128 bits that are cut into 4 32-bit parts:
4739 //
4740 // HH HL LH LL
4741 // |---32---|---32---|---32---|---32---|
4742 // 128 96 64 32 0
4743 //
4744 // |------VTSize-----|
4745 //
4746 // |NVTSize-|
4747 //
4748 // The resulting Lo and Hi would normally be in LL and LH after the shift. But
4749 // to avoid unneccessary shifting of all 4 parts, we can adjust the shift
4750 // amount and get Lo and Hi using two funnel shifts. Or for the special case
4751 // when Scale is a multiple of NVTSize we can just pick the result without
4752 // shifting.
4753 uint64_t Part0 = Scale / NVTSize; // Part holding lowest bit needed.
4754 if (Scale % NVTSize) {
4755 SDValue ShiftAmount = DAG.getShiftAmountConstant(Scale % NVTSize, NVT, dl);
4756 Lo = DAG.getNode(ISD::FSHR, dl, NVT, Result[Part0 + 1], Result[Part0],
4757 ShiftAmount);
4758 Hi = DAG.getNode(ISD::FSHR, dl, NVT, Result[Part0 + 2], Result[Part0 + 1],
4759 ShiftAmount);
4760 } else {
4761 Lo = Result[Part0];
4762 Hi = Result[Part0 + 1];
4763 }
4764
4765 // Unless saturation is requested we are done. The result is in <Hi,Lo>.
4766 if (!Saturating)
4767 return;
4768
4769 // Can not overflow when there is no integer part.
4770 if (Scale == VTSize)
4771 return;
4772
4773 // To handle saturation we must check for overflow in the multiplication.
4774 //
4775 // Unsigned overflow happened if the upper (VTSize - Scale) bits (of Result)
4776 // aren't all zeroes.
4777 //
4778 // Signed overflow happened if the upper (VTSize - Scale + 1) bits (of Result)
4779 // aren't all ones or all zeroes.
4780 //
4781 // We cannot overflow past HH when multiplying 2 ints of size VTSize, so the
4782 // highest bit of HH determines saturation direction in the event of signed
4783 // saturation.
4784
4785 SDValue ResultHL = Result[2];
4786 SDValue ResultHH = Result[3];
4787
4788 SDValue SatMax, SatMin;
4789 SDValue NVTZero = DAG.getConstant(0, dl, NVT);
4790 SDValue NVTNeg1 = DAG.getAllOnesConstant(dl, NVT);
4791 EVT BoolNVT = getSetCCResultType(NVT);
4792
4793 if (!Signed) {
4794 if (Scale < NVTSize) {
4795 // Overflow happened if ((HH | (HL >> Scale)) != 0).
4796 SDValue HLAdjusted =
4797 DAG.getNode(ISD::SRL, dl, NVT, ResultHL,
4798 DAG.getShiftAmountConstant(Scale, NVT, dl));
4799 SDValue Tmp = DAG.getNode(ISD::OR, dl, NVT, HLAdjusted, ResultHH);
4800 SatMax = DAG.getSetCC(dl, BoolNVT, Tmp, NVTZero, ISD::SETNE);
4801 } else if (Scale == NVTSize) {
4802 // Overflow happened if (HH != 0).
4803 SatMax = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETNE);
4804 } else if (Scale < VTSize) {
4805 // Overflow happened if ((HH >> (Scale - NVTSize)) != 0).
4806 SDValue HLAdjusted =
4807 DAG.getNode(ISD::SRL, dl, NVT, ResultHL,
4808 DAG.getShiftAmountConstant(Scale - NVTSize, NVT, dl));
4809 SatMax = DAG.getSetCC(dl, BoolNVT, HLAdjusted, NVTZero, ISD::SETNE);
4810 } else
4811 llvm_unreachable("Scale must be less or equal to VTSize for UMULFIXSAT"
4812 "(and saturation can't happen with Scale==VTSize).");
4813
4814 Hi = DAG.getSelect(dl, NVT, SatMax, NVTNeg1, Hi);
4815 Lo = DAG.getSelect(dl, NVT, SatMax, NVTNeg1, Lo);
4816 return;
4817 }
4818
4819 if (Scale < NVTSize) {
4820 // The number of overflow bits we can check are VTSize - Scale + 1 (we
4821 // include the sign bit). If these top bits are > 0, then we overflowed past
4822 // the max value. If these top bits are < -1, then we overflowed past the
4823 // min value. Otherwise, we did not overflow.
4824 unsigned OverflowBits = VTSize - Scale + 1;
4825 assert(OverflowBits <= VTSize && OverflowBits > NVTSize &&
4826 "Extent of overflow bits must start within HL");
4827 SDValue HLHiMask = DAG.getConstant(
4828 APInt::getHighBitsSet(NVTSize, OverflowBits - NVTSize), dl, NVT);
4829 SDValue HLLoMask = DAG.getConstant(
4830 APInt::getLowBitsSet(NVTSize, VTSize - OverflowBits), dl, NVT);
4831 // We overflow max if HH > 0 or (HH == 0 && HL > HLLoMask).
4832 SDValue HHGT0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETGT);
4833 SDValue HHEQ0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETEQ);
4834 SDValue HLUGT = DAG.getSetCC(dl, BoolNVT, ResultHL, HLLoMask, ISD::SETUGT);
4835 SatMax = DAG.getNode(ISD::OR, dl, BoolNVT, HHGT0,
4836 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ0, HLUGT));
4837 // We overflow min if HH < -1 or (HH == -1 && HL < HLHiMask).
4838 SDValue HHLT = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETLT);
4839 SDValue HHEQ = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETEQ);
4840 SDValue HLULT = DAG.getSetCC(dl, BoolNVT, ResultHL, HLHiMask, ISD::SETULT);
4841 SatMin = DAG.getNode(ISD::OR, dl, BoolNVT, HHLT,
4842 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ, HLULT));
4843 } else if (Scale == NVTSize) {
4844 // We overflow max if HH > 0 or (HH == 0 && HL sign bit is 1).
4845 SDValue HHGT0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETGT);
4846 SDValue HHEQ0 = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTZero, ISD::SETEQ);
4847 SDValue HLNeg = DAG.getSetCC(dl, BoolNVT, ResultHL, NVTZero, ISD::SETLT);
4848 SatMax = DAG.getNode(ISD::OR, dl, BoolNVT, HHGT0,
4849 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ0, HLNeg));
4850 // We overflow min if HH < -1 or (HH == -1 && HL sign bit is 0).
4851 SDValue HHLT = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETLT);
4852 SDValue HHEQ = DAG.getSetCC(dl, BoolNVT, ResultHH, NVTNeg1, ISD::SETEQ);
4853 SDValue HLPos = DAG.getSetCC(dl, BoolNVT, ResultHL, NVTZero, ISD::SETGE);
4854 SatMin = DAG.getNode(ISD::OR, dl, BoolNVT, HHLT,
4855 DAG.getNode(ISD::AND, dl, BoolNVT, HHEQ, HLPos));
4856 } else if (Scale < VTSize) {
4857 // This is similar to the case when we saturate if Scale < NVTSize, but we
4858 // only need to check HH.
4859 unsigned OverflowBits = VTSize - Scale + 1;
4860 SDValue HHHiMask = DAG.getConstant(
4861 APInt::getHighBitsSet(NVTSize, OverflowBits), dl, NVT);
4862 SDValue HHLoMask = DAG.getConstant(
4863 APInt::getLowBitsSet(NVTSize, NVTSize - OverflowBits), dl, NVT);
4864 SatMax = DAG.getSetCC(dl, BoolNVT, ResultHH, HHLoMask, ISD::SETGT);
4865 SatMin = DAG.getSetCC(dl, BoolNVT, ResultHH, HHHiMask, ISD::SETLT);
4866 } else
4867 llvm_unreachable("Illegal scale for signed fixed point mul.");
4868
4869 // Saturate to signed maximum.
4870 APInt MaxHi = APInt::getSignedMaxValue(NVTSize);
4871 APInt MaxLo = APInt::getAllOnes(NVTSize);
4872 Hi = DAG.getSelect(dl, NVT, SatMax, DAG.getConstant(MaxHi, dl, NVT), Hi);
4873 Lo = DAG.getSelect(dl, NVT, SatMax, DAG.getConstant(MaxLo, dl, NVT), Lo);
4874 // Saturate to signed minimum.
4875 APInt MinHi = APInt::getSignedMinValue(NVTSize);
4876 Hi = DAG.getSelect(dl, NVT, SatMin, DAG.getConstant(MinHi, dl, NVT), Hi);
4877 Lo = DAG.getSelect(dl, NVT, SatMin, NVTZero, Lo);
4878}
4879
4880void DAGTypeLegalizer::ExpandIntRes_DIVFIX(SDNode *N, SDValue &Lo,
4881 SDValue &Hi) {
4882 SDLoc dl(N);
4883 // Try expanding in the existing type first.
4884 SDValue Res = TLI.expandFixedPointDiv(N->getOpcode(), dl, N->getOperand(0),
4885 N->getOperand(1),
4886 N->getConstantOperandVal(2), DAG);
4887
4888 if (!Res)
4889 Res = earlyExpandDIVFIX(N, N->getOperand(0), N->getOperand(1),
4890 N->getConstantOperandVal(2), TLI, DAG);
4891 SplitInteger(Res, Lo, Hi);
4892}
4893
4894void DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node,
4895 SDValue &Lo, SDValue &Hi) {
4896 assert((Node->getOpcode() == ISD::SADDO || Node->getOpcode() == ISD::SSUBO) &&
4897 "Node has unexpected Opcode");
4898 SDValue LHS = Node->getOperand(0);
4899 SDValue RHS = Node->getOperand(1);
4900 SDLoc dl(Node);
4901
4902 SDValue Ovf;
4903
4904 bool IsAdd = Node->getOpcode() == ISD::SADDO;
4905 unsigned CarryOp = IsAdd ? ISD::SADDO_CARRY : ISD::SSUBO_CARRY;
4906
4907 bool HasCarryOp = TLI.isOperationLegalOrCustom(
4908 CarryOp, TLI.getTypeToExpandTo(*DAG.getContext(), LHS.getValueType()));
4909
4910 if (HasCarryOp) {
4911 // Expand the subcomponents.
4912 SDValue LHSL, LHSH, RHSL, RHSH;
4913 GetExpandedInteger(LHS, LHSL, LHSH);
4914 GetExpandedInteger(RHS, RHSL, RHSH);
4915 SDVTList VTList = DAG.getVTList(LHSL.getValueType(), Node->getValueType(1));
4916
4917 Lo = DAG.getNode(IsAdd ? ISD::UADDO : ISD::USUBO, dl, VTList, {LHSL, RHSL});
4918 Hi = DAG.getNode(CarryOp, dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
4919
4920 Ovf = Hi.getValue(1);
4921 } else {
4922 // Expand the result by simply replacing it with the equivalent
4923 // non-overflow-checking operation.
4924 SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
4925 ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
4926 LHS, RHS);
4927 SplitInteger(Sum, Lo, Hi);
4928
4929 // Compute the overflow.
4930 //
4931 // LHSSign -> LHS < 0
4932 // RHSSign -> RHS < 0
4933 // SumSign -> Sum < 0
4934 //
4935 // Add:
4936 // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
4937 // Sub:
4938 // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
4939 //
4940 // To get better codegen we can rewrite this by doing bitwise math on
4941 // the integers and extract the final sign bit at the end. So the
4942 // above becomes:
4943 //
4944 // Add:
4945 // Overflow -> (~(LHS ^ RHS) & (LHS ^ Sum)) < 0
4946 // Sub:
4947 // Overflow -> ((LHS ^ RHS) & (LHS ^ Sum)) < 0
4948 //
4949 // NOTE: This is different than the expansion we do in expandSADDSUBO
4950 // because it is more costly to implement the same overflow predicate with
4951 // SETCC nodes when the integers are split.
4952 EVT VT = LHS.getValueType();
4953 SDValue SignsMatch = DAG.getNode(ISD::XOR, dl, VT, LHS, RHS);
4954 if (IsAdd)
4955 SignsMatch = DAG.getNOT(dl, SignsMatch, VT);
4956
4957 SDValue SumSignNE = DAG.getNode(ISD::XOR, dl, VT, LHS, Sum);
4958 Ovf = DAG.getNode(ISD::AND, dl, VT, SignsMatch, SumSignNE);
4959 EVT OType = Node->getValueType(1);
4960 Ovf = DAG.getSetCC(dl, OType, Ovf, DAG.getConstant(0, dl, VT), ISD::SETLT);
4961 }
4962
4963 // Use the calculated overflow everywhere.
4964 ReplaceValueWith(SDValue(Node, 1), Ovf);
4965}
4966
4967void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
4968 SDValue &Lo, SDValue &Hi) {
4969 EVT VT = N->getValueType(0);
4970 SDLoc dl(N);
4971 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
4972
4973 if (TLI.getOperationAction(ISD::SDIVREM, VT) == TargetLowering::Custom) {
4974 SDValue Res = DAG.getNode(ISD::SDIVREM, dl, DAG.getVTList(VT, VT), Ops);
4975 SplitInteger(Res.getValue(0), Lo, Hi);
4976 return;
4977 }
4978
4979 RTLIB::Libcall LC = RTLIB::getSDIV(VT);
4980 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
4981
4982 TargetLowering::MakeLibCallOptions CallOptions;
4983 CallOptions.setIsSigned(true);
4984 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
4985}
4986
4987void DAGTypeLegalizer::ExpandIntRes_ShiftThroughStack(SDNode *N, SDValue &Lo,
4988 SDValue &Hi) {
4989 SDLoc dl(N);
4990 SDValue Shiftee = N->getOperand(0);
4991 EVT VT = Shiftee.getValueType();
4992 SDValue ShAmt = N->getOperand(1);
4993 EVT ShAmtVT = ShAmt.getValueType();
4994
4995 EVT LoadVT = VT;
4996 do {
4997 LoadVT = TLI.getTypeToTransformTo(*DAG.getContext(), LoadVT);
4998 } while (!TLI.isTypeLegal(LoadVT));
4999
5000 const unsigned ShiftUnitInBits = LoadVT.getStoreSizeInBits();
5001 assert(ShiftUnitInBits <= VT.getScalarSizeInBits());
5002 assert(isPowerOf2_32(ShiftUnitInBits) &&
5003 "Shifting unit is not a a power of two!");
5004
5005 const bool IsOneStepShift =
5006 DAG.computeKnownBits(ShAmt).countMinTrailingZeros() >=
5007 Log2_32(ShiftUnitInBits);
5008
5009 // If we can't do it as one step, we'll have two uses of shift amount,
5010 // and thus must freeze it.
5011 if (!IsOneStepShift)
5012 ShAmt = DAG.getFreeze(ShAmt);
5013
5014 unsigned VTBitWidth = VT.getScalarSizeInBits();
5015 assert(VTBitWidth % 8 == 0 && "Shifting a not byte multiple value?");
5016 unsigned VTByteWidth = VTBitWidth / 8;
5017 assert(isPowerOf2_32(VTByteWidth) &&
5018 "Shiftee type size is not a power of two!");
5019 unsigned StackSlotByteWidth = 2 * VTByteWidth;
5020 unsigned StackSlotBitWidth = 8 * StackSlotByteWidth;
5021 EVT StackSlotVT = EVT::getIntegerVT(*DAG.getContext(), StackSlotBitWidth);
5022
5023 // Get a temporary stack slot 2x the width of our VT.
5024 // FIXME: reuse stack slots?
5025 Align StackAlign = DAG.getReducedAlign(StackSlotVT, /*UseABI=*/false);
5027 DAG.CreateStackTemporary(StackSlotVT.getStoreSize(), StackAlign);
5028 EVT PtrTy = StackPtr.getValueType();
5029 SDValue Ch = DAG.getEntryNode();
5030
5031 MachinePointerInfo StackPtrInfo = MachinePointerInfo::getFixedStack(
5032 DAG.getMachineFunction(),
5033 cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex());
5034
5035 // Extend the value, that is being shifted, to the entire stack slot's width.
5036 SDValue Init;
5037 if (N->getOpcode() != ISD::SHL) {
5038 unsigned WideningOpc =
5039 N->getOpcode() == ISD::SRA ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
5040 Init = DAG.getNode(WideningOpc, dl, StackSlotVT, Shiftee);
5041 } else {
5042 // For left-shifts, pad the Shiftee's LSB with zeros to twice it's width.
5043 SDValue AllZeros = DAG.getConstant(0, dl, VT);
5044 Init = DAG.getNode(ISD::BUILD_PAIR, dl, StackSlotVT, AllZeros, Shiftee);
5045 }
5046 // And spill it into the stack slot.
5047 Ch = DAG.getStore(Ch, dl, Init, StackPtr, StackPtrInfo, StackAlign);
5048
5049 // Now, compute the full-byte offset into stack slot from where we can load.
5050 // We have shift amount, which is in bits. Offset should point to an aligned
5051 // address.
5052 SDNodeFlags Flags;
5053 Flags.setExact(IsOneStepShift);
5054 SDValue SrlTmp = DAG.getNode(
5055 ISD::SRL, dl, ShAmtVT, ShAmt,
5056 DAG.getConstant(Log2_32(ShiftUnitInBits), dl, ShAmtVT), Flags);
5057 SDValue BitOffset =
5058 DAG.getNode(ISD::SHL, dl, ShAmtVT, SrlTmp,
5059 DAG.getConstant(Log2_32(ShiftUnitInBits), dl, ShAmtVT));
5060
5061 SDValue ByteOffset =
5062 DAG.getNode(ISD::SRL, dl, ShAmtVT, BitOffset,
5063 DAG.getConstant(3, dl, ShAmtVT), SDNodeFlags::Exact);
5064 // And clamp it, because OOB load is an immediate UB,
5065 // while shift overflow would have *just* been poison.
5066 ByteOffset = DAG.getNode(ISD::AND, dl, ShAmtVT, ByteOffset,
5067 DAG.getConstant(VTByteWidth - 1, dl, ShAmtVT));
5068 // We have exactly two strategies on indexing into stack slot here:
5069 // 1. upwards starting from the beginning of the slot
5070 // 2. downwards starting from the middle of the slot
5071 // On little-endian machine, we pick 1. for right shifts and 2. for left-shift
5072 // and vice versa on big-endian machine.
5073 bool WillIndexUpwards = N->getOpcode() != ISD::SHL;
5074 if (DAG.getDataLayout().isBigEndian())
5075 WillIndexUpwards = !WillIndexUpwards;
5076
5077 SDValue AdjStackPtr;
5078 if (WillIndexUpwards) {
5079 AdjStackPtr = StackPtr;
5080 } else {
5081 AdjStackPtr = DAG.getMemBasePlusOffset(
5082 StackPtr, DAG.getConstant(VTByteWidth, dl, PtrTy), dl);
5083 ByteOffset = DAG.getNegative(ByteOffset, dl, ShAmtVT);
5084 }
5085
5086 // Get the pointer somewhere into the stack slot from which we need to load.
5087 ByteOffset = DAG.getSExtOrTrunc(ByteOffset, dl, PtrTy);
5088 AdjStackPtr = DAG.getMemBasePlusOffset(AdjStackPtr, ByteOffset, dl);
5089
5090 // And load it! While the load is not legal, legalizing it is obvious.
5091 SDValue Res =
5092 DAG.getLoad(VT, dl, Ch, AdjStackPtr,
5093 MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()),
5094 commonAlignment(StackAlign, LoadVT.getStoreSize()));
5095
5096 // If we may still have a remaining bits to shift by, do so now.
5097 if (!IsOneStepShift) {
5098 SDValue ShAmtRem =
5099 DAG.getNode(ISD::AND, dl, ShAmtVT, ShAmt,
5100 DAG.getConstant(ShiftUnitInBits - 1, dl, ShAmtVT));
5101 Res = DAG.getNode(N->getOpcode(), dl, VT, Res, ShAmtRem);
5102 }
5103
5104 // Finally, split the computed value.
5105 SplitInteger(Res, Lo, Hi);
5106}
5107
5108void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
5109 SDValue &Lo, SDValue &Hi) {
5110 EVT VT = N->getValueType(0);
5111 unsigned Opc = N->getOpcode();
5112 SDLoc dl(N);
5113
5114 // If we can emit an efficient shift operation, do so now. Check to see if
5115 // the RHS is a constant.
5116 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
5117 return ExpandShiftByConstant(N, CN->getAPIntValue(), Lo, Hi);
5118
5119 // If we can determine that the high bit of the shift is zero or one, even if
5120 // the low bits are variable, emit this shift in an optimized form.
5121 if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
5122 return;
5123
5124 // If this target supports shift_PARTS, use it. First, map to the _PARTS opc.
5125 unsigned PartsOpc;
5126 if (Opc == ISD::SHL) {
5127 PartsOpc = ISD::SHL_PARTS;
5128 } else if (Opc == ISD::SRL) {
5129 PartsOpc = ISD::SRL_PARTS;
5130 } else {
5131 assert(Opc == ISD::SRA && "Unknown shift!");
5132 PartsOpc = ISD::SRA_PARTS;
5133 }
5134
5135 // Next check to see if the target supports this SHL_PARTS operation or if it
5136 // will custom expand it. Don't lower this to SHL_PARTS when we optimise for
5137 // size, but create a libcall instead.
5138 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5139 TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
5140 const bool LegalOrCustom =
5141 (Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
5142 Action == TargetLowering::Custom;
5143
5144 unsigned ExpansionFactor = 1;
5145 // That VT->NVT expansion is one step. But will we re-expand NVT?
5146 for (EVT TmpVT = NVT;;) {
5147 EVT NewTMPVT = TLI.getTypeToTransformTo(*DAG.getContext(), TmpVT);
5148 if (NewTMPVT == TmpVT)
5149 break;
5150 TmpVT = NewTMPVT;
5151 ++ExpansionFactor;
5152 }
5153
5155 TLI.preferredShiftLegalizationStrategy(DAG, N, ExpansionFactor);
5156
5158 return ExpandIntRes_ShiftThroughStack(N, Lo, Hi);
5159
5160 if (LegalOrCustom &&
5162 // Expand the subcomponents.
5163 SDValue LHSL, LHSH;
5164 GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
5165 EVT VT = LHSL.getValueType();
5166
5167 // If the shift amount operand is coming from a vector legalization it may
5168 // have an illegal type. Fix that first by casting the operand, otherwise
5169 // the new SHL_PARTS operation would need further legalization.
5170 SDValue ShiftOp = N->getOperand(1);
5171 EVT ShiftTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
5172 if (ShiftOp.getValueType() != ShiftTy)
5173 ShiftOp = DAG.getZExtOrTrunc(ShiftOp, dl, ShiftTy);
5174
5175 SDValue Ops[] = { LHSL, LHSH, ShiftOp };
5176 Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops);
5177 Hi = Lo.getValue(1);
5178 return;
5179 }
5180
5181 // Otherwise, emit a libcall.
5182 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5183 bool isSigned;
5184 if (Opc == ISD::SHL) {
5185 isSigned = false; /*sign irrelevant*/
5186 LC = RTLIB::getSHL(VT);
5187 } else if (Opc == ISD::SRL) {
5188 isSigned = false;
5189 LC = RTLIB::getSRL(VT);
5190 } else {
5191 assert(Opc == ISD::SRA && "Unknown shift!");
5192 isSigned = true;
5193 LC = RTLIB::getSRA(VT);
5194 }
5195
5196 if (RTLIB::LibcallImpl LibcallImpl = DAG.getLibcalls().getLibcallImpl(LC)) {
5197 EVT ShAmtTy =
5198 EVT::getIntegerVT(*DAG.getContext(), DAG.getLibInfo().getIntSize());
5199 SDValue ShAmt = DAG.getZExtOrTrunc(N->getOperand(1), dl, ShAmtTy);
5200 SDValue Ops[2] = {N->getOperand(0), ShAmt};
5201 TargetLowering::MakeLibCallOptions CallOptions;
5202 CallOptions.setIsSigned(isSigned);
5203 SplitInteger(
5204 TLI.makeLibCall(DAG, LibcallImpl, VT, Ops, CallOptions, dl).first, Lo,
5205 Hi);
5206 return;
5207 }
5208
5209 if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi))
5210 llvm_unreachable("Unsupported shift!");
5211}
5212
5213void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
5214 SDValue &Lo, SDValue &Hi) {
5215 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5216 SDLoc dl(N);
5217 SDValue Op = N->getOperand(0);
5218 if (Op.getValueType().bitsLE(NVT)) {
5219 // The low part is sign extension of the input (degenerates to a copy).
5220 Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
5221 // The high part is obtained by SRA'ing all but one of the bits of low part.
5222 unsigned LoSize = NVT.getSizeInBits();
5223 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
5224 DAG.getShiftAmountConstant(LoSize - 1, NVT, dl));
5225 } else {
5226 // For example, extension of an i48 to an i64. The operand type necessarily
5227 // promotes to the result type, so will end up being expanded too.
5228 assert(getTypeAction(Op.getValueType()) ==
5230 "Only know how to promote this result!");
5231 SDValue Res = GetPromotedInteger(Op);
5232 assert(Res.getValueType() == N->getValueType(0) &&
5233 "Operand over promoted?");
5234 // Split the promoted operand. This will simplify when it is expanded.
5235 SplitInteger(Res, Lo, Hi);
5236 unsigned ExcessBits = Op.getValueSizeInBits() - NVT.getSizeInBits();
5237 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
5238 DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
5239 ExcessBits)));
5240 }
5241}
5242
5243void DAGTypeLegalizer::
5244ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
5245 SDLoc dl(N);
5246 GetExpandedInteger(N->getOperand(0), Lo, Hi);
5247 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
5248
5249 if (EVT.bitsLE(Lo.getValueType())) {
5250 // sext_inreg the low part if needed.
5251 Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
5252 N->getOperand(1));
5253
5254 // The high part gets the sign extension from the lo-part. This handles
5255 // things like sextinreg V:i64 from i8.
5256 Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
5257 DAG.getShiftAmountConstant(Hi.getValueSizeInBits() - 1,
5258 Hi.getValueType(), dl));
5259 } else {
5260 // For example, extension of an i48 to an i64. Leave the low part alone,
5261 // sext_inreg the high part.
5262 unsigned ExcessBits = EVT.getSizeInBits() - Lo.getValueSizeInBits();
5263 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
5264 DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
5265 ExcessBits)));
5266 }
5267}
5268
5269void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
5270 SDValue &Lo, SDValue &Hi) {
5271 EVT VT = N->getValueType(0);
5272 SDLoc dl(N);
5273 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
5274
5275 if (TLI.getOperationAction(ISD::SDIVREM, VT) == TargetLowering::Custom) {
5276 SDValue Res = DAG.getNode(ISD::SDIVREM, dl, DAG.getVTList(VT, VT), Ops);
5277 SplitInteger(Res.getValue(1), Lo, Hi);
5278 return;
5279 }
5280
5281 RTLIB::Libcall LC = RTLIB::getSREM(VT);
5282 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
5283
5284 TargetLowering::MakeLibCallOptions CallOptions;
5285 CallOptions.setIsSigned(true);
5286 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5287}
5288
5289void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
5290 SDValue &Lo, SDValue &Hi) {
5291 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5292 SDValue InOp = N->getOperand(0);
5293 EVT InVT = InOp.getValueType();
5294 SDLoc dl(N);
5295 Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, InOp);
5296 Hi = DAG.getNode(ISD::SRL, dl, InVT, InOp,
5297 DAG.getShiftAmountConstant(NVT.getSizeInBits(), InVT, dl));
5298 Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
5299}
5300
5301void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
5302 SDValue &Lo, SDValue &Hi) {
5303 EVT VT = N->getValueType(0);
5304 SDLoc dl(N);
5305
5306 if (N->getOpcode() == ISD::UMULO) {
5307 // This section expands the operation into the following sequence of
5308 // instructions. `iNh` here refers to a type which has half the bit width of
5309 // the type the original operation operated on.
5310 //
5311 // %0 = %LHS.HI != 0 && %RHS.HI != 0
5312 // %1 = { iNh, i1 } @umul.with.overflow.iNh(iNh %LHS.HI, iNh %RHS.LO)
5313 // %2 = { iNh, i1 } @umul.with.overflow.iNh(iNh %RHS.HI, iNh %LHS.LO)
5314 // %3 = mul nuw iN (%LHS.LOW as iN), (%RHS.LOW as iN)
5315 // %4 = add iNh %1.0, %2.0 as iN
5316 // %5 = { iNh, i1 } @uadd.with.overflow.iNh(iNh %4, iNh %3.HIGH)
5317 //
5318 // %lo = %3.LO
5319 // %hi = %5.0
5320 // %ovf = %0 || %1.1 || %2.1 || %5.1
5321 SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
5322 SDValue LHSHigh, LHSLow, RHSHigh, RHSLow;
5323 GetExpandedInteger(LHS, LHSLow, LHSHigh);
5324 GetExpandedInteger(RHS, RHSLow, RHSHigh);
5325 EVT HalfVT = LHSLow.getValueType();
5326 EVT BitVT = N->getValueType(1);
5327 SDVTList VTHalfWithO = DAG.getVTList(HalfVT, BitVT);
5328
5329 SDValue HalfZero = DAG.getConstant(0, dl, HalfVT);
5330 SDValue Overflow = DAG.getNode(ISD::AND, dl, BitVT,
5331 DAG.getSetCC(dl, BitVT, LHSHigh, HalfZero, ISD::SETNE),
5332 DAG.getSetCC(dl, BitVT, RHSHigh, HalfZero, ISD::SETNE));
5333
5334 SDValue One = DAG.getNode(ISD::UMULO, dl, VTHalfWithO, LHSHigh, RHSLow);
5335 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, One.getValue(1));
5336
5337 SDValue Two = DAG.getNode(ISD::UMULO, dl, VTHalfWithO, RHSHigh, LHSLow);
5338 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, Two.getValue(1));
5339
5340 SDValue HighSum = DAG.getNode(ISD::ADD, dl, HalfVT, One, Two);
5341
5342 // Cannot use `UMUL_LOHI` directly, because some 32-bit targets (ARM) do not
5343 // know how to expand `i64,i64 = umul_lohi a, b` and abort (why isn’t this
5344 // operation recursively legalized?).
5345 //
5346 // Many backends understand this pattern and will convert into LOHI
5347 // themselves, if applicable.
5348 SDValue Three = DAG.getNode(ISD::MUL, dl, VT,
5349 DAG.getNode(ISD::ZERO_EXTEND, dl, VT, LHSLow),
5350 DAG.getNode(ISD::ZERO_EXTEND, dl, VT, RHSLow));
5351 SplitInteger(Three, Lo, Hi);
5352
5353 Hi = DAG.getNode(ISD::UADDO, dl, VTHalfWithO, Hi, HighSum);
5354 Overflow = DAG.getNode(ISD::OR, dl, BitVT, Overflow, Hi.getValue(1));
5355 ReplaceValueWith(SDValue(N, 1), Overflow);
5356 return;
5357 }
5358
5359 Type *RetTy = VT.getTypeForEVT(*DAG.getContext());
5360 EVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
5361 Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext());
5362
5363 // Replace this with a libcall that will check overflow.
5364 RTLIB::Libcall LC = RTLIB::getMULO(VT);
5365 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
5366
5367 // If we don't have the libcall or if the function we are compiling is the
5368 // implementation of the expected libcall (avoid inf-loop), expand inline.
5369 if (LCImpl == RTLIB::Unsupported ||
5371 DAG.getMachineFunction().getName()) {
5372 // FIXME: This is not an optimal expansion, but better than crashing.
5373 SDValue MulLo, MulHi;
5374 TLI.forceExpandWideMUL(DAG, dl, /*Signed=*/true, N->getOperand(0),
5375 N->getOperand(1), MulLo, MulHi);
5376 SDValue SRA = DAG.getNode(
5377 ISD::SRA, dl, VT, MulLo,
5378 DAG.getShiftAmountConstant(VT.getScalarSizeInBits() - 1, VT, dl));
5379 SDValue Overflow =
5380 DAG.getSetCC(dl, N->getValueType(1), MulHi, SRA, ISD::SETNE);
5381 SplitInteger(MulLo, Lo, Hi);
5382 ReplaceValueWith(SDValue(N, 1), Overflow);
5383 return;
5384 }
5385
5386 SDValue Temp = DAG.CreateStackTemporary(PtrVT);
5387 // Temporary for the overflow value, default it to zero.
5388 SDValue Chain =
5389 DAG.getStore(DAG.getEntryNode(), dl, DAG.getConstant(0, dl, PtrVT), Temp,
5390 MachinePointerInfo());
5391
5393 for (const SDValue &Op : N->op_values()) {
5394 EVT ArgVT = Op.getValueType();
5395 Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
5396 TargetLowering::ArgListEntry Entry(Op, ArgTy);
5397 Entry.IsSExt = true;
5398 Entry.IsZExt = false;
5399 Args.push_back(Entry);
5400 }
5401
5402 // Also pass the address of the overflow check.
5403 TargetLowering::ArgListEntry Entry(
5404 Temp, PointerType::getUnqual(PtrTy->getContext()));
5405 Entry.IsSExt = true;
5406 Entry.IsZExt = false;
5407 Args.push_back(Entry);
5408
5409 SDValue Func = DAG.getExternalSymbol(LCImpl, PtrVT);
5410
5411 TargetLowering::CallLoweringInfo CLI(DAG);
5412 CLI.setDebugLoc(dl)
5413 .setChain(Chain)
5414 .setLibCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
5415 Func, std::move(Args))
5416 .setSExtResult();
5417
5418 std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
5419
5420 SplitInteger(CallInfo.first, Lo, Hi);
5421 SDValue Temp2 =
5422 DAG.getLoad(PtrVT, dl, CallInfo.second, Temp, MachinePointerInfo());
5423 SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Temp2,
5424 DAG.getConstant(0, dl, PtrVT),
5425 ISD::SETNE);
5426 // Use the overflow from the libcall everywhere.
5427 ReplaceValueWith(SDValue(N, 1), Ofl);
5428}
5429
5430void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
5431 SDValue &Lo, SDValue &Hi) {
5432 EVT VT = N->getValueType(0);
5433 SDLoc dl(N);
5434 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
5435
5436 if (TLI.getOperationAction(ISD::UDIVREM, VT) == TargetLowering::Custom) {
5437 SDValue Res = DAG.getNode(ISD::UDIVREM, dl, DAG.getVTList(VT, VT), Ops);
5438 SplitInteger(Res.getValue(0), Lo, Hi);
5439 return;
5440 }
5441
5442 // Try to expand UDIV by constant.
5443 if (isa<ConstantSDNode>(N->getOperand(1))) {
5444 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5445 // Only if the new type is legal.
5446 if (isTypeLegal(NVT)) {
5447 SDValue InL, InH;
5448 GetExpandedInteger(N->getOperand(0), InL, InH);
5450 if (TLI.expandDIVREMByConstant(N, Result, NVT, DAG, InL, InH)) {
5451 Lo = Result[0];
5452 Hi = Result[1];
5453 return;
5454 }
5455 }
5456 }
5457
5458 RTLIB::Libcall LC = RTLIB::getUDIV(VT);
5459 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
5460
5461 TargetLowering::MakeLibCallOptions CallOptions;
5462 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5463}
5464
5465void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
5466 SDValue &Lo, SDValue &Hi) {
5467 EVT VT = N->getValueType(0);
5468 SDLoc dl(N);
5469 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
5470
5471 if (TLI.getOperationAction(ISD::UDIVREM, VT) == TargetLowering::Custom) {
5472 SDValue Res = DAG.getNode(ISD::UDIVREM, dl, DAG.getVTList(VT, VT), Ops);
5473 SplitInteger(Res.getValue(1), Lo, Hi);
5474 return;
5475 }
5476
5477 // Try to expand UREM by constant.
5478 if (isa<ConstantSDNode>(N->getOperand(1))) {
5479 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5480 // Only if the new type is legal.
5481 if (isTypeLegal(NVT)) {
5482 SDValue InL, InH;
5483 GetExpandedInteger(N->getOperand(0), InL, InH);
5485 if (TLI.expandDIVREMByConstant(N, Result, NVT, DAG, InL, InH)) {
5486 Lo = Result[0];
5487 Hi = Result[1];
5488 return;
5489 }
5490 }
5491 }
5492
5493 RTLIB::Libcall LC = RTLIB::getUREM(VT);
5494 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
5495
5496 TargetLowering::MakeLibCallOptions CallOptions;
5497 SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
5498}
5499
5500void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
5501 SDValue &Lo, SDValue &Hi) {
5502 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5503 SDLoc dl(N);
5504 SDValue Op = N->getOperand(0);
5505 if (Op.getValueType().bitsLE(NVT)) {
5506 // The low part is zero extension of the input (degenerates to a copy).
5507 Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
5508 Hi = DAG.getConstant(0, dl, NVT); // The high part is just a zero.
5509 } else {
5510 // For example, extension of an i48 to an i64. The operand type necessarily
5511 // promotes to the result type, so will end up being expanded too.
5512 assert(getTypeAction(Op.getValueType()) ==
5514 "Only know how to promote this result!");
5515 SDValue Res = GetPromotedInteger(Op);
5516 assert(Res.getValueType() == N->getValueType(0) &&
5517 "Operand over promoted?");
5518 // Split the promoted operand. This will simplify when it is expanded.
5519 SplitInteger(Res, Lo, Hi);
5520 unsigned ExcessBits = Op.getValueSizeInBits() - NVT.getSizeInBits();
5521 Hi = DAG.getZeroExtendInReg(Hi, dl,
5522 EVT::getIntegerVT(*DAG.getContext(),
5523 ExcessBits));
5524 }
5525}
5526
5527void DAGTypeLegalizer::ExpandIntRes_ATOMIC_LOAD(SDNode *N,
5528 SDValue &Lo, SDValue &Hi) {
5529 SDLoc dl(N);
5530 EVT VT = cast<AtomicSDNode>(N)->getMemoryVT();
5531 SDVTList VTs = DAG.getVTList(VT, MVT::i1, MVT::Other);
5532 SDValue Zero = DAG.getConstant(0, dl, VT);
5533 SDValue Swap = DAG.getAtomicCmpSwap(
5535 cast<AtomicSDNode>(N)->getMemoryVT(), VTs, N->getOperand(0),
5536 N->getOperand(1), Zero, Zero, cast<AtomicSDNode>(N)->getMemOperand());
5537
5538 ReplaceValueWith(SDValue(N, 0), Swap.getValue(0));
5539 ReplaceValueWith(SDValue(N, 1), Swap.getValue(2));
5540}
5541
5542void DAGTypeLegalizer::ExpandIntRes_VECREDUCE(SDNode *N,
5543 SDValue &Lo, SDValue &Hi) {
5544 // TODO For VECREDUCE_(AND|OR|XOR) we could split the vector and calculate
5545 // both halves independently.
5546 SDValue Res = TLI.expandVecReduce(N, DAG);
5547 SplitInteger(Res, Lo, Hi);
5548}
5549
5550void DAGTypeLegalizer::ExpandIntRes_Rotate(SDNode *N,
5551 SDValue &Lo, SDValue &Hi) {
5552 // Delegate to funnel-shift expansion.
5553 SDLoc DL(N);
5554 unsigned Opcode = N->getOpcode() == ISD::ROTL ? ISD::FSHL : ISD::FSHR;
5555 SDValue Res = DAG.getNode(Opcode, DL, N->getValueType(0), N->getOperand(0),
5556 N->getOperand(0), N->getOperand(1));
5557 SplitInteger(Res, Lo, Hi);
5558}
5559
5560void DAGTypeLegalizer::ExpandIntRes_FunnelShift(SDNode *N, SDValue &Lo,
5561 SDValue &Hi) {
5562 // Values numbered from least significant to most significant.
5563 SDValue In1, In2, In3, In4;
5564 GetExpandedInteger(N->getOperand(0), In3, In4);
5565 GetExpandedInteger(N->getOperand(1), In1, In2);
5566 EVT HalfVT = In1.getValueType();
5567
5568 SDLoc DL(N);
5569 unsigned Opc = N->getOpcode();
5570 SDValue ShAmt = N->getOperand(2);
5571 EVT ShAmtVT = ShAmt.getValueType();
5572 EVT ShAmtCCVT = getSetCCResultType(ShAmtVT);
5573
5574 // If the shift amount is at least half the bitwidth, swap the inputs.
5575 unsigned HalfVTBits = HalfVT.getScalarSizeInBits();
5576 SDValue AndNode = DAG.getNode(ISD::AND, DL, ShAmtVT, ShAmt,
5577 DAG.getConstant(HalfVTBits, DL, ShAmtVT));
5578 SDValue Cond =
5579 DAG.getSetCC(DL, ShAmtCCVT, AndNode, DAG.getConstant(0, DL, ShAmtVT),
5581
5582 // Expand to a pair of funnel shifts.
5583 EVT NewShAmtVT = TLI.getShiftAmountTy(HalfVT, DAG.getDataLayout());
5584 SDValue NewShAmt = DAG.getAnyExtOrTrunc(ShAmt, DL, NewShAmtVT);
5585
5586 SDValue Select1 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In1, In2);
5587 SDValue Select2 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In2, In3);
5588 SDValue Select3 = DAG.getNode(ISD::SELECT, DL, HalfVT, Cond, In3, In4);
5589 Lo = DAG.getNode(Opc, DL, HalfVT, Select2, Select1, NewShAmt);
5590 Hi = DAG.getNode(Opc, DL, HalfVT, Select3, Select2, NewShAmt);
5591}
5592
5593void DAGTypeLegalizer::ExpandIntRes_CLMUL(SDNode *N, SDValue &Lo, SDValue &Hi) {
5594 if (N->getOpcode() != ISD::CLMUL) {
5595 SDValue Res = TLI.expandCLMUL(N, DAG);
5596 return SplitInteger(Res, Lo, Hi);
5597 }
5598
5599 SDValue LL, LH, RL, RH;
5600 GetExpandedInteger(N->getOperand(0), LL, LH);
5601 GetExpandedInteger(N->getOperand(1), RL, RH);
5602 EVT HalfVT = LL.getValueType();
5603 SDLoc DL(N);
5604
5605 // The low bits are a direct CLMUL of the the low bits.
5606 Lo = DAG.getNode(ISD::CLMUL, DL, HalfVT, LL, RL);
5607
5608 // We compute two Hi-Lo cross-products, XOR them, and XOR it with the overflow
5609 // of the CLMUL of the low bits (given by CLMULH of the low bits) to yield the
5610 // final high bits.
5611 SDValue LoH = DAG.getNode(ISD::CLMULH, DL, HalfVT, LL, RL);
5612 SDValue HiLoCross1 = DAG.getNode(ISD::CLMUL, DL, HalfVT, LL, RH);
5613 SDValue HiLoCross2 = DAG.getNode(ISD::CLMUL, DL, HalfVT, LH, RL);
5614 SDValue HiLoCross = DAG.getNode(ISD::XOR, DL, HalfVT, HiLoCross1, HiLoCross2);
5615 Hi = DAG.getNode(ISD::XOR, DL, HalfVT, LoH, HiLoCross);
5616}
5617
5618void DAGTypeLegalizer::ExpandIntRes_VSCALE(SDNode *N, SDValue &Lo,
5619 SDValue &Hi) {
5620 EVT VT = N->getValueType(0);
5621 EVT HalfVT =
5622 EVT::getIntegerVT(*DAG.getContext(), N->getValueSizeInBits(0) / 2);
5623 SDLoc dl(N);
5624
5625 // We assume VSCALE(1) fits into a legal integer.
5626 APInt One(HalfVT.getSizeInBits(), 1);
5627 SDValue VScaleBase = DAG.getVScale(dl, HalfVT, One);
5628 VScaleBase = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, VScaleBase);
5629 SDValue Res = DAG.getNode(ISD::MUL, dl, VT, VScaleBase, N->getOperand(0));
5630 SplitInteger(Res, Lo, Hi);
5631}
5632
5633void DAGTypeLegalizer::ExpandIntRes_READ_REGISTER(SDNode *N, SDValue &Lo,
5634 SDValue &Hi) {
5635 const Function &Fn = DAG.getMachineFunction().getFunction();
5636 Fn.getContext().diagnose(DiagnosticInfoLegalizationFailure(
5637 "cannot use llvm.read_register with illegal type", Fn, N->getDebugLoc()));
5638 ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
5639 EVT LoVT, HiVT;
5640 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
5641 Lo = DAG.getPOISON(LoVT);
5642 Hi = DAG.getPOISON(HiVT);
5643}
5644
5645void DAGTypeLegalizer::ExpandIntRes_CTTZ_ELTS(SDNode *N, SDValue &Lo,
5646 SDValue &Hi) {
5647 // Assume that the maximum number of vector elements fits in getVectorIdxTy
5648 // and expand to that.
5649 EVT VT = N->getSimpleValueType(0);
5650 EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());
5651 assert(IdxVT.bitsLT(VT) &&
5652 "VectorIdxTy should be smaller than type to be expanded?");
5653
5654 SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N), IdxVT, N->getOperand(0));
5655 Res = DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), VT, Res);
5656 SplitInteger(Res, Lo, Hi);
5657}
5658
5659//===----------------------------------------------------------------------===//
5660// Integer Operand Expansion
5661//===----------------------------------------------------------------------===//
5662
5663/// ExpandIntegerOperand - This method is called when the specified operand of
5664/// the specified node is found to need expansion. At this point, all of the
5665/// result types of the node are known to be legal, but other operands of the
5666/// node may need promotion or expansion as well as the specified one.
5667bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
5668 LLVM_DEBUG(dbgs() << "Expand integer operand: "; N->dump(&DAG));
5669 SDValue Res = SDValue();
5670
5671 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
5672 return false;
5673
5674 switch (N->getOpcode()) {
5675 default:
5676 #ifndef NDEBUG
5677 dbgs() << "ExpandIntegerOperand Op #" << OpNo << ": ";
5678 N->dump(&DAG); dbgs() << "\n";
5679 #endif
5680 report_fatal_error("Do not know how to expand this operator's operand!");
5681
5682 case ISD::BITCAST: Res = ExpandOp_BITCAST(N); break;
5683 case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
5684 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
5685 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
5686 case ISD::FAKE_USE:
5687 Res = ExpandOp_FAKE_USE(N);
5688 break;
5691 Res = TLI.expandLoopDependenceMask(N, DAG);
5692 break;
5693 case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
5694 case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
5695 case ISD::SPLAT_VECTOR: Res = ExpandIntOp_SPLAT_VECTOR(N); break;
5696 case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
5697 case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
5698 case ISD::SETCCCARRY: Res = ExpandIntOp_SETCCCARRY(N); break;
5700 case ISD::SINT_TO_FP:
5702 case ISD::UINT_TO_FP: Res = ExpandIntOp_XINT_TO_FP(N); break;
5703 case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
5704 case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
5705
5706 case ISD::SHL:
5707 case ISD::SRA:
5708 case ISD::SRL:
5709 case ISD::ROTL:
5710 case ISD::ROTR: Res = ExpandIntOp_Shift(N); break;
5711 case ISD::RETURNADDR:
5712 case ISD::FRAMEADDR: Res = ExpandIntOp_RETURNADDR(N); break;
5713
5714 case ISD::SCMP:
5715 case ISD::UCMP: Res = ExpandIntOp_CMP(N); break;
5716
5717 case ISD::ATOMIC_STORE: Res = ExpandIntOp_ATOMIC_STORE(N); break;
5718 case ISD::STACKMAP:
5719 Res = ExpandIntOp_STACKMAP(N, OpNo);
5720 break;
5721 case ISD::PATCHPOINT:
5722 Res = ExpandIntOp_PATCHPOINT(N, OpNo);
5723 break;
5724 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5725 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
5726 Res = ExpandIntOp_VP_STRIDED(N, OpNo);
5727 break;
5729 Res = ExpandIntOp_WRITE_REGISTER(N, OpNo);
5730 break;
5731 }
5732
5733 // If the result is null, the sub-method took care of registering results etc.
5734 if (!Res.getNode()) return false;
5735
5736 // If the result is N, the sub-method updated N in place. Tell the legalizer
5737 // core about this.
5738 if (Res.getNode() == N)
5739 return true;
5740
5741 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
5742 "Invalid operand expansion");
5743
5744 ReplaceValueWith(SDValue(N, 0), Res);
5745 return false;
5746}
5747
5748/// IntegerExpandSetCCOperands - Expand the operands of a comparison. This code
5749/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
5750void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
5751 SDValue &NewRHS,
5752 ISD::CondCode &CCCode,
5753 const SDLoc &dl) {
5754 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5755 GetExpandedInteger(NewLHS, LHSLo, LHSHi);
5756 GetExpandedInteger(NewRHS, RHSLo, RHSHi);
5757
5758 if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
5759 if (RHSLo == RHSHi && isAllOnesConstant(RHSLo)) {
5760 // Equality comparison to -1.
5761 NewLHS = DAG.getNode(ISD::AND, dl, LHSLo.getValueType(), LHSLo, LHSHi);
5762 NewRHS = RHSLo;
5763 return;
5764 }
5765
5766 NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
5767 NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
5768 NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
5769 NewRHS = DAG.getConstant(0, dl, NewLHS.getValueType());
5770 return;
5771 }
5772
5773 // If this is a comparison of the sign bit, just look at the top part.
5774 // X > -1, x < 0
5775 if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
5776 if ((CCCode == ISD::SETLT && CST->isZero()) || // X < 0
5777 (CCCode == ISD::SETGT && CST->isAllOnes())) { // X > -1
5778 NewLHS = LHSHi;
5779 NewRHS = RHSHi;
5780 return;
5781 }
5782
5783 // FIXME: This generated code sucks.
5784 ISD::CondCode LowCC;
5785 switch (CCCode) {
5786 default: llvm_unreachable("Unknown integer setcc!");
5787 case ISD::SETLT:
5788 case ISD::SETULT: LowCC = ISD::SETULT; break;
5789 case ISD::SETGT:
5790 case ISD::SETUGT: LowCC = ISD::SETUGT; break;
5791 case ISD::SETLE:
5792 case ISD::SETULE: LowCC = ISD::SETULE; break;
5793 case ISD::SETGE:
5794 case ISD::SETUGE: LowCC = ISD::SETUGE; break;
5795 }
5796
5797 // LoCmp = lo(op1) < lo(op2) // Always unsigned comparison
5798 // HiCmp = hi(op1) < hi(op2) // Signedness depends on operands
5799 // dest = hi(op1) == hi(op2) ? LoCmp : HiCmp;
5800
5801 // NOTE: on targets without efficient SELECT of bools, we can always use
5802 // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
5803 TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, AfterLegalizeTypes, true,
5804 nullptr);
5805 SDValue LoCmp, HiCmp;
5806 if (TLI.isTypeLegal(LHSLo.getValueType()))
5807 LoCmp = TLI.SimplifySetCC(getSetCCResultType(LHSLo.getValueType()), LHSLo,
5808 RHSLo, LowCC, false, DagCombineInfo, dl);
5809 if (!LoCmp.getNode())
5810 LoCmp = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
5811 RHSLo, LowCC);
5812 if (TLI.isTypeLegal(LHSHi.getValueType()))
5813 HiCmp = TLI.SimplifySetCC(getSetCCResultType(LHSHi.getValueType()), LHSHi,
5814 RHSHi, CCCode, false, DagCombineInfo, dl);
5815 if (!HiCmp.getNode())
5816 HiCmp =
5817 DAG.getNode(ISD::SETCC, dl, getSetCCResultType(LHSHi.getValueType()),
5818 LHSHi, RHSHi, DAG.getCondCode(CCCode));
5819
5820 ConstantSDNode *LoCmpC = dyn_cast<ConstantSDNode>(LoCmp.getNode());
5821 ConstantSDNode *HiCmpC = dyn_cast<ConstantSDNode>(HiCmp.getNode());
5822
5823 bool EqAllowed = ISD::isTrueWhenEqual(CCCode);
5824
5825 // FIXME: Is the HiCmpC->isOne() here correct for
5826 // ZeroOrNegativeOneBooleanContent.
5827 if ((EqAllowed && (HiCmpC && HiCmpC->isZero())) ||
5828 (!EqAllowed &&
5829 ((HiCmpC && HiCmpC->isOne()) || (LoCmpC && LoCmpC->isZero())))) {
5830 // For LE / GE, if high part is known false, ignore the low part.
5831 // For LT / GT: if low part is known false, return the high part.
5832 // if high part is known true, ignore the low part.
5833 NewLHS = HiCmp;
5834 NewRHS = SDValue();
5835 return;
5836 }
5837
5838 if (LHSHi == RHSHi) {
5839 // Comparing the low bits is enough.
5840 NewLHS = LoCmp;
5841 NewRHS = SDValue();
5842 return;
5843 }
5844
5845 // Lower with SETCCCARRY if the target supports it.
5846 EVT HiVT = LHSHi.getValueType();
5847 EVT ExpandVT = TLI.getTypeToExpandTo(*DAG.getContext(), HiVT);
5848 bool HasSETCCCARRY = TLI.isOperationLegalOrCustom(ISD::SETCCCARRY, ExpandVT);
5849
5850 // FIXME: Make all targets support this, then remove the other lowering.
5851 if (HasSETCCCARRY) {
5852 // SETCCCARRY can detect < and >= directly. For > and <=, flip
5853 // operands and condition code.
5854 bool FlipOperands = false;
5855 switch (CCCode) {
5856 case ISD::SETGT: CCCode = ISD::SETLT; FlipOperands = true; break;
5857 case ISD::SETUGT: CCCode = ISD::SETULT; FlipOperands = true; break;
5858 case ISD::SETLE: CCCode = ISD::SETGE; FlipOperands = true; break;
5859 case ISD::SETULE: CCCode = ISD::SETUGE; FlipOperands = true; break;
5860 default: break;
5861 }
5862 if (FlipOperands) {
5863 std::swap(LHSLo, RHSLo);
5864 std::swap(LHSHi, RHSHi);
5865 }
5866 // Perform a wide subtraction, feeding the carry from the low part into
5867 // SETCCCARRY. The SETCCCARRY operation is essentially looking at the high
5868 // part of the result of LHS - RHS. It is negative iff LHS < RHS. It is
5869 // zero or positive iff LHS >= RHS.
5870 EVT LoVT = LHSLo.getValueType();
5871 SDVTList VTList = DAG.getVTList(LoVT, getSetCCResultType(LoVT));
5872 SDValue LowCmp = DAG.getNode(ISD::USUBO, dl, VTList, LHSLo, RHSLo);
5873 SDValue Res = DAG.getNode(ISD::SETCCCARRY, dl, getSetCCResultType(HiVT),
5874 LHSHi, RHSHi, LowCmp.getValue(1),
5875 DAG.getCondCode(CCCode));
5876 NewLHS = Res;
5877 NewRHS = SDValue();
5878 return;
5879 }
5880
5881 NewLHS = TLI.SimplifySetCC(getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ,
5882 false, DagCombineInfo, dl);
5883 if (!NewLHS.getNode())
5884 NewLHS =
5885 DAG.getSetCC(dl, getSetCCResultType(HiVT), LHSHi, RHSHi, ISD::SETEQ);
5886 NewLHS = DAG.getSelect(dl, LoCmp.getValueType(), NewLHS, LoCmp, HiCmp);
5887 NewRHS = SDValue();
5888}
5889
5890SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
5891 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
5892 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
5893 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5894
5895 // If ExpandSetCCOperands returned a scalar, we need to compare the result
5896 // against zero to select between true and false values.
5897 if (!NewRHS.getNode()) {
5898 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
5899 CCCode = ISD::SETNE;
5900 }
5901
5902 // Update N to have the operands specified.
5903 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
5904 DAG.getCondCode(CCCode), NewLHS, NewRHS,
5905 N->getOperand(4)), 0);
5906}
5907
5908SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
5909 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
5910 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
5911 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5912
5913 // If ExpandSetCCOperands returned a scalar, we need to compare the result
5914 // against zero to select between true and false values.
5915 if (!NewRHS.getNode()) {
5916 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
5917 CCCode = ISD::SETNE;
5918 }
5919
5920 // Update N to have the operands specified.
5921 return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
5922 N->getOperand(2), N->getOperand(3),
5923 DAG.getCondCode(CCCode)), 0);
5924}
5925
5926SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
5927 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
5928 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
5929 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
5930
5931 // If ExpandSetCCOperands returned a scalar, use it.
5932 if (!NewRHS.getNode()) {
5933 assert(NewLHS.getValueType() == N->getValueType(0) &&
5934 "Unexpected setcc expansion!");
5935 return NewLHS;
5936 }
5937
5938 // Otherwise, update N to have the operands specified.
5939 return SDValue(
5940 DAG.UpdateNodeOperands(N, NewLHS, NewRHS, DAG.getCondCode(CCCode)), 0);
5941}
5942
5943SDValue DAGTypeLegalizer::ExpandIntOp_SETCCCARRY(SDNode *N) {
5944 SDValue LHS = N->getOperand(0);
5945 SDValue RHS = N->getOperand(1);
5946 SDValue Carry = N->getOperand(2);
5947 SDValue Cond = N->getOperand(3);
5948 SDLoc dl = SDLoc(N);
5949
5950 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5951 GetExpandedInteger(LHS, LHSLo, LHSHi);
5952 GetExpandedInteger(RHS, RHSLo, RHSHi);
5953
5954 // Expand to a USUBO_CARRY for the low part and a SETCCCARRY for the high.
5955 SDVTList VTList = DAG.getVTList(LHSLo.getValueType(), Carry.getValueType());
5956 SDValue LowCmp =
5957 DAG.getNode(ISD::USUBO_CARRY, dl, VTList, LHSLo, RHSLo, Carry);
5958 return DAG.getNode(ISD::SETCCCARRY, dl, N->getValueType(0), LHSHi, RHSHi,
5959 LowCmp.getValue(1), Cond);
5960}
5961
5962SDValue DAGTypeLegalizer::ExpandIntOp_SPLAT_VECTOR(SDNode *N) {
5963 // Split the operand and replace with SPLAT_VECTOR_PARTS.
5964 SDValue Lo, Hi;
5965 GetExpandedInteger(N->getOperand(0), Lo, Hi);
5966 return DAG.getNode(ISD::SPLAT_VECTOR_PARTS, SDLoc(N), N->getValueType(0), Lo,
5967 Hi);
5968}
5969
5970SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
5971 // The value being shifted is legal, but the shift amount is too big.
5972 // It follows that either the result of the shift is undefined, or the
5973 // upper half of the shift amount is zero. Just use the lower half.
5974 SDValue Lo, Hi;
5975 GetExpandedInteger(N->getOperand(1), Lo, Hi);
5976 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0);
5977}
5978
5979SDValue DAGTypeLegalizer::ExpandIntOp_CMP(SDNode *N) {
5980 return TLI.expandCMP(N, DAG);
5981}
5982
5983SDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) {
5984 // The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant. This
5985 // surely makes pretty nice problems on 8/16 bit targets. Just truncate this
5986 // constant to valid type.
5987 SDValue Lo, Hi;
5988 GetExpandedInteger(N->getOperand(0), Lo, Hi);
5989 return SDValue(DAG.UpdateNodeOperands(N, Lo), 0);
5990}
5991
5992SDValue DAGTypeLegalizer::ExpandIntOp_XINT_TO_FP(SDNode *N) {
5993 bool IsStrict = N->isStrictFPOpcode();
5994 bool IsSigned = N->getOpcode() == ISD::SINT_TO_FP ||
5995 N->getOpcode() == ISD::STRICT_SINT_TO_FP;
5996 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
5997 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
5998 EVT DstVT = N->getValueType(0);
5999 RTLIB::Libcall LC = IsSigned ? RTLIB::getSINTTOFP(Op.getValueType(), DstVT)
6000 : RTLIB::getUINTTOFP(Op.getValueType(), DstVT);
6001 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
6002 "Don't know how to expand this XINT_TO_FP!");
6003 TargetLowering::MakeLibCallOptions CallOptions;
6004 CallOptions.setIsSigned(true);
6005 std::pair<SDValue, SDValue> Tmp =
6006 TLI.makeLibCall(DAG, LC, DstVT, Op, CallOptions, SDLoc(N), Chain);
6007
6008 if (!IsStrict)
6009 return Tmp.first;
6010
6011 ReplaceValueWith(SDValue(N, 1), Tmp.second);
6012 ReplaceValueWith(SDValue(N, 0), Tmp.first);
6013 return SDValue();
6014}
6015
6016SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
6017 assert(!N->isAtomic() && "Should have been a ATOMIC_STORE?");
6018
6019 if (ISD::isNormalStore(N))
6020 return ExpandOp_NormalStore(N, OpNo);
6021
6022 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
6023 assert(OpNo == 1 && "Can only expand the stored value so far");
6024
6025 EVT VT = N->getOperand(1).getValueType();
6026 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6027 SDValue Ch = N->getChain();
6028 SDValue Ptr = N->getBasePtr();
6029 MachineMemOperand::Flags MMOFlags = N->getMemOperand()->getFlags();
6030 AAMDNodes AAInfo = N->getAAInfo();
6031 SDLoc dl(N);
6032 SDValue Lo, Hi;
6033
6034 assert(NVT.isByteSized() && "Expanded type not byte sized!");
6035
6036 if (N->getMemoryVT().bitsLE(NVT)) {
6037 GetExpandedInteger(N->getValue(), Lo, Hi);
6038 return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
6039 N->getMemoryVT(), N->getBaseAlign(), MMOFlags,
6040 AAInfo);
6041 }
6042
6043 if (DAG.getDataLayout().isLittleEndian()) {
6044 // Little-endian - low bits are at low addresses.
6045 GetExpandedInteger(N->getValue(), Lo, Hi);
6046
6047 Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getPointerInfo(), N->getBaseAlign(),
6048 MMOFlags, AAInfo);
6049
6050 unsigned ExcessBits =
6051 N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
6052 EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
6053
6054 // Increment the pointer to the other half.
6055 unsigned IncrementSize = NVT.getSizeInBits()/8;
6056 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
6057 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
6058 N->getPointerInfo().getWithOffset(IncrementSize),
6059 NEVT, N->getBaseAlign(), MMOFlags, AAInfo);
6060 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
6061 }
6062
6063 // Big-endian - high bits are at low addresses. Favor aligned stores at
6064 // the cost of some bit-fiddling.
6065 GetExpandedInteger(N->getValue(), Lo, Hi);
6066
6067 EVT ExtVT = N->getMemoryVT();
6068 unsigned EBytes = ExtVT.getStoreSize();
6069 unsigned IncrementSize = NVT.getSizeInBits()/8;
6070 unsigned ExcessBits = (EBytes - IncrementSize)*8;
6071 EVT HiVT = EVT::getIntegerVT(*DAG.getContext(),
6072 ExtVT.getSizeInBits() - ExcessBits);
6073
6074 if (ExcessBits < NVT.getSizeInBits()) {
6075 // Transfer high bits from the top of Lo to the bottom of Hi.
6076 Hi = DAG.getNode(
6077 ISD::SHL, dl, NVT, Hi,
6078 DAG.getShiftAmountConstant(NVT.getSizeInBits() - ExcessBits, NVT, dl));
6079 Hi = DAG.getNode(
6080 ISD::OR, dl, NVT, Hi,
6081 DAG.getNode(ISD::SRL, dl, NVT, Lo,
6082 DAG.getShiftAmountConstant(ExcessBits, NVT, dl)));
6083 }
6084
6085 // Store both the high bits and maybe some of the low bits.
6086 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getPointerInfo(), HiVT,
6087 N->getBaseAlign(), MMOFlags, AAInfo);
6088
6089 // Increment the pointer to the other half.
6090 Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::getFixed(IncrementSize));
6091 // Store the lowest ExcessBits bits in the second half.
6092 Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr,
6093 N->getPointerInfo().getWithOffset(IncrementSize),
6094 EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
6095 N->getBaseAlign(), MMOFlags, AAInfo);
6096 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
6097}
6098
6099SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
6100 SDValue InL, InH;
6101 GetExpandedInteger(N->getOperand(0), InL, InH);
6102 // Just truncate the low part of the source.
6103 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0), InL);
6104}
6105
6106SDValue DAGTypeLegalizer::ExpandIntOp_ATOMIC_STORE(SDNode *N) {
6107 SDLoc dl(N);
6108 SDValue Swap =
6109 DAG.getAtomic(ISD::ATOMIC_SWAP, dl, cast<AtomicSDNode>(N)->getMemoryVT(),
6110 N->getOperand(0), N->getOperand(2), N->getOperand(1),
6111 cast<AtomicSDNode>(N)->getMemOperand());
6112 return Swap.getValue(1);
6113}
6114
6115SDValue DAGTypeLegalizer::ExpandIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) {
6116 assert((N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD && OpNo == 3) ||
6117 (N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE && OpNo == 4));
6118
6119 SDValue Hi; // The upper half is dropped out.
6120 SmallVector<SDValue, 8> NewOps(N->ops());
6121 GetExpandedInteger(NewOps[OpNo], NewOps[OpNo], Hi);
6122
6123 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
6124}
6125
6126SDValue DAGTypeLegalizer::ExpandIntOp_WRITE_REGISTER(SDNode *N, unsigned OpNo) {
6127 const Function &Fn = DAG.getMachineFunction().getFunction();
6128 Fn.getContext().diagnose(DiagnosticInfoLegalizationFailure(
6129 "cannot use llvm.write_register with illegal type", Fn,
6130 N->getDebugLoc()));
6131
6132 return N->getOperand(0);
6133}
6134
6135SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SPLICE(SDNode *N) {
6136 SDLoc dl(N);
6137
6138 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6139 SDValue V1 = GetPromotedInteger(N->getOperand(1));
6140 EVT OutVT = V0.getValueType();
6141
6142 return DAG.getNode(N->getOpcode(), dl, OutVT, V0, V1, N->getOperand(2));
6143}
6144
6145SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_INTERLEAVE_DEINTERLEAVE(SDNode *N) {
6146 SDLoc DL(N);
6147 unsigned Factor = N->getNumOperands();
6148
6150 for (unsigned i = 0; i != Factor; i++)
6151 Ops[i] = GetPromotedInteger(N->getOperand(i));
6152
6153 SmallVector<EVT, 8> ResVTs(Factor, Ops[0].getValueType());
6154 SDValue Res = DAG.getNode(N->getOpcode(), DL, DAG.getVTList(ResVTs), Ops);
6155
6156 for (unsigned i = 0; i != Factor; i++)
6157 SetPromotedInteger(SDValue(N, i), Res.getValue(i));
6158
6159 return SDValue();
6160}
6161
6162SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
6163
6164 EVT OutVT = N->getValueType(0);
6165 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6166 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6167 EVT NOutVTElem = NOutVT.getVectorElementType();
6168
6169 SDLoc dl(N);
6170 SDValue BaseIdx = N->getOperand(1);
6171
6172 // TODO: We may be able to use this for types other than scalable
6173 // vectors and fix those tests that expect BUILD_VECTOR to be used
6174 if (OutVT.isScalableVector()) {
6175 SDValue InOp0 = N->getOperand(0);
6176 EVT InVT = InOp0.getValueType();
6177
6178 // Try and extract from a smaller type so that it eventually falls
6179 // into the promotion code below.
6180 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector ||
6181 getTypeAction(InVT) == TargetLowering::TypeLegal) {
6182 EVT NInVT = InVT.getHalfNumVectorElementsVT(*DAG.getContext());
6183 unsigned NElts = NInVT.getVectorMinNumElements();
6184 uint64_t IdxVal = BaseIdx->getAsZExtVal();
6185
6186 SDValue Step1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NInVT, InOp0,
6187 DAG.getConstant(alignDown(IdxVal, NElts), dl,
6188 BaseIdx.getValueType()));
6189 SDValue Step2 = DAG.getNode(
6190 ISD::EXTRACT_SUBVECTOR, dl, OutVT, Step1,
6191 DAG.getConstant(IdxVal % NElts, dl, BaseIdx.getValueType()));
6192 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Step2);
6193 }
6194
6195 // Try and extract from a widened type.
6196 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
6197 SDValue Ops[] = {GetWidenedVector(InOp0), BaseIdx};
6198 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), OutVT, Ops);
6199 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Ext);
6200 }
6201
6202 // Promote operands and see if this is handled by target lowering,
6203 // Otherwise, use the BUILD_VECTOR approach below
6204 if (getTypeAction(InVT) == TargetLowering::TypePromoteInteger) {
6205 // Collect the (promoted) operands
6206 SDValue Ops[] = { GetPromotedInteger(InOp0), BaseIdx };
6207
6208 EVT PromEltVT = Ops[0].getValueType().getVectorElementType();
6209 assert(PromEltVT.bitsLE(NOutVTElem) &&
6210 "Promoted operand has an element type greater than result");
6211
6212 EVT ExtVT = NOutVT.changeVectorElementType(*DAG.getContext(), PromEltVT);
6213 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), ExtVT, Ops);
6214 return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Ext);
6215 }
6216 }
6217
6218 if (OutVT.isScalableVector())
6219 report_fatal_error("Unable to promote scalable types using BUILD_VECTOR");
6220
6221 SDValue InOp0 = N->getOperand(0);
6222 if (getTypeAction(InOp0.getValueType()) == TargetLowering::TypePromoteInteger)
6223 InOp0 = GetPromotedInteger(InOp0);
6224
6225 EVT InVT = InOp0.getValueType();
6226 EVT InSVT = InVT.getVectorElementType();
6227
6228 unsigned OutNumElems = OutVT.getVectorNumElements();
6230 Ops.reserve(OutNumElems);
6231 for (unsigned i = 0; i != OutNumElems; ++i) {
6232 // Extract the element from the original vector.
6233 SDValue Index = DAG.getNode(ISD::ADD, dl, BaseIdx.getValueType(), BaseIdx,
6234 DAG.getConstant(i, dl, BaseIdx.getValueType()));
6235 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InSVT,
6236 N->getOperand(0), Index);
6237 SDValue Op = DAG.getAnyExtOrTrunc(Ext, dl, NOutVTElem);
6238 // Insert the converted element to the new vector.
6239 Ops.push_back(Op);
6240 }
6241
6242 return DAG.getBuildVector(NOutVT, dl, Ops);
6243}
6244
6245SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_SUBVECTOR(SDNode *N) {
6246 EVT OutVT = N->getValueType(0);
6247 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6248 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6249
6250 SDLoc dl(N);
6251 SDValue Vec = N->getOperand(0);
6252 SDValue SubVec = N->getOperand(1);
6253 SDValue Idx = N->getOperand(2);
6254
6255 EVT SubVecVT = SubVec.getValueType();
6256 EVT NSubVT =
6257 EVT::getVectorVT(*DAG.getContext(), NOutVT.getVectorElementType(),
6258 SubVecVT.getVectorElementCount());
6259
6260 Vec = GetPromotedInteger(Vec);
6261 SubVec = DAG.getNode(ISD::ANY_EXTEND, dl, NSubVT, SubVec);
6262
6263 return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, NOutVT, Vec, SubVec, Idx);
6264}
6265
6266SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_REVERSE(SDNode *N) {
6267 SDLoc dl(N);
6268
6269 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6270 EVT OutVT = V0.getValueType();
6271
6272 return DAG.getNode(ISD::VECTOR_REVERSE, dl, OutVT, V0);
6273}
6274
6275SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) {
6276 ShuffleVectorSDNode *SV = cast<ShuffleVectorSDNode>(N);
6277 EVT VT = N->getValueType(0);
6278 SDLoc dl(N);
6279
6280 ArrayRef<int> NewMask = SV->getMask().slice(0, VT.getVectorNumElements());
6281
6282 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6283 SDValue V1 = GetPromotedInteger(N->getOperand(1));
6284 EVT OutVT = V0.getValueType();
6285
6286 return DAG.getVectorShuffle(OutVT, dl, V0, V1, NewMask);
6287}
6288
6289SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) {
6290 EVT OutVT = N->getValueType(0);
6291 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6292 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6293 unsigned NumElems = N->getNumOperands();
6294 EVT NOutVTElem = NOutVT.getVectorElementType();
6295 TargetLoweringBase::BooleanContent NOutBoolType = TLI.getBooleanContents(NOutVT);
6296 unsigned NOutExtOpc = TargetLowering::getExtendForContent(NOutBoolType);
6297 SDLoc dl(N);
6298
6300 Ops.reserve(NumElems);
6301 for (unsigned i = 0; i != NumElems; ++i) {
6302 SDValue Op = N->getOperand(i);
6303 EVT OpVT = Op.getValueType();
6304 // BUILD_VECTOR integer operand types are allowed to be larger than the
6305 // result's element type. This may still be true after the promotion. For
6306 // example, we might be promoting (<v?i1> = BV <i32>, <i32>, ...) to
6307 // (v?i16 = BV <i32>, <i32>, ...), and we can't any_extend <i32> to <i16>.
6308 if (OpVT.bitsLT(NOutVTElem)) {
6309 unsigned ExtOpc = ISD::ANY_EXTEND;
6310 // Attempt to extend constant bool vectors to match target's BooleanContent.
6311 // While not necessary, this improves chances of the constant correctly
6312 // folding with compare results (e.g. for NOT patterns).
6313 if (OpVT == MVT::i1 && Op.getOpcode() == ISD::Constant)
6314 ExtOpc = NOutExtOpc;
6315 Op = DAG.getNode(ExtOpc, dl, NOutVTElem, Op);
6316 }
6317 Ops.push_back(Op);
6318 }
6319
6320 return DAG.getBuildVector(NOutVT, dl, Ops);
6321}
6322
6323SDValue DAGTypeLegalizer::PromoteIntRes_ScalarOp(SDNode *N) {
6324
6325 SDLoc dl(N);
6326
6327 assert(!N->getOperand(0).getValueType().isVector() &&
6328 "Input must be a scalar");
6329
6330 EVT OutVT = N->getValueType(0);
6331 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6332 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6333 EVT NOutElemVT = NOutVT.getVectorElementType();
6334
6335 SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutElemVT, N->getOperand(0));
6336 return DAG.getNode(N->getOpcode(), dl, NOutVT, Op);
6337}
6338
6339SDValue DAGTypeLegalizer::PromoteIntRes_STEP_VECTOR(SDNode *N) {
6340 SDLoc dl(N);
6341 EVT OutVT = N->getValueType(0);
6342 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6343 assert(NOutVT.isScalableVector() &&
6344 "Type must be promoted to a scalable vector type");
6345 const APInt &StepVal = N->getConstantOperandAPInt(0);
6346 return DAG.getStepVector(dl, NOutVT,
6347 StepVal.sext(NOutVT.getScalarSizeInBits()));
6348}
6349
6350SDValue DAGTypeLegalizer::PromoteIntRes_CONCAT_VECTORS(SDNode *N) {
6351 SDLoc dl(N);
6352
6353 EVT OutVT = N->getValueType(0);
6354 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6355 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6356
6357 unsigned NumOperands = N->getNumOperands();
6358 unsigned NumOutElem = NOutVT.getVectorMinNumElements();
6359 EVT OutElemTy = NOutVT.getVectorElementType();
6360 if (OutVT.isScalableVector()) {
6361 // Find the largest promoted element type for each of the operands.
6362 SDUse *MaxSizedValue = std::max_element(
6363 N->op_begin(), N->op_end(), [](const SDValue &A, const SDValue &B) {
6364 EVT AVT = A.getValueType().getVectorElementType();
6365 EVT BVT = B.getValueType().getVectorElementType();
6366 return AVT.getScalarSizeInBits() < BVT.getScalarSizeInBits();
6367 });
6368 EVT MaxElementVT = MaxSizedValue->getValueType().getVectorElementType();
6369
6370 // Then promote all vectors to the largest element type.
6372 for (unsigned I = 0; I < NumOperands; ++I) {
6373 SDValue Op = N->getOperand(I);
6374 EVT OpVT = Op.getValueType();
6375 if (getTypeAction(OpVT) == TargetLowering::TypePromoteInteger)
6376 Op = GetPromotedInteger(Op);
6377 else
6378 assert(getTypeAction(OpVT) == TargetLowering::TypeLegal &&
6379 "Unhandled legalization type");
6380
6382 MaxElementVT.getScalarSizeInBits())
6383 Op = DAG.getAnyExtOrTrunc(
6384 Op, dl,
6385 OpVT.changeVectorElementType(*DAG.getContext(), MaxElementVT));
6386 Ops.push_back(Op);
6387 }
6388
6389 // Do the CONCAT on the promoted type and finally truncate to (the promoted)
6390 // NOutVT.
6391 return DAG.getAnyExtOrTrunc(
6392 DAG.getNode(
6394 OutVT.changeVectorElementType(*DAG.getContext(), MaxElementVT),
6395 Ops),
6396 dl, NOutVT);
6397 }
6398
6399 unsigned NumElem = N->getOperand(0).getValueType().getVectorNumElements();
6400 assert(NumElem * NumOperands == NumOutElem &&
6401 "Unexpected number of elements");
6402
6403 // Take the elements from the first vector.
6404 SmallVector<SDValue, 8> Ops(NumOutElem);
6405 for (unsigned i = 0; i < NumOperands; ++i) {
6406 SDValue Op = N->getOperand(i);
6407 if (getTypeAction(Op.getValueType()) == TargetLowering::TypePromoteInteger)
6408 Op = GetPromotedInteger(Op);
6409 EVT SclrTy = Op.getValueType().getVectorElementType();
6410 assert(NumElem == Op.getValueType().getVectorNumElements() &&
6411 "Unexpected number of elements");
6412
6413 for (unsigned j = 0; j < NumElem; ++j) {
6414 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy, Op,
6415 DAG.getVectorIdxConstant(j, dl));
6416 Ops[i * NumElem + j] = DAG.getAnyExtOrTrunc(Ext, dl, OutElemTy);
6417 }
6418 }
6419
6420 return DAG.getBuildVector(NOutVT, dl, Ops);
6421}
6422
6423SDValue DAGTypeLegalizer::PromoteIntRes_EXTEND_VECTOR_INREG(SDNode *N) {
6424 EVT VT = N->getValueType(0);
6425 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6426 assert(NVT.isVector() && "This type must be promoted to a vector type");
6427
6428 SDLoc dl(N);
6429
6430 // For operands whose TypeAction is to promote, extend the promoted node
6431 // appropriately (ZERO_EXTEND or SIGN_EXTEND) from the original pre-promotion
6432 // type, and then construct a new *_EXTEND_VECTOR_INREG node to the promote-to
6433 // type..
6434 if (getTypeAction(N->getOperand(0).getValueType())
6436 SDValue Promoted;
6437
6438 switch(N->getOpcode()) {
6440 Promoted = SExtPromotedInteger(N->getOperand(0));
6441 break;
6443 Promoted = ZExtPromotedInteger(N->getOperand(0));
6444 break;
6446 Promoted = GetPromotedInteger(N->getOperand(0));
6447 break;
6448 default:
6449 llvm_unreachable("Node has unexpected Opcode");
6450 }
6451 unsigned NewSize = NVT.getSizeInBits();
6452 if (Promoted.getValueType().getSizeInBits() > NewSize) {
6453 EVT ExtractVT = EVT::getVectorVT(
6454 *DAG.getContext(), Promoted.getValueType().getVectorElementType(),
6455 NewSize / Promoted.getScalarValueSizeInBits());
6456
6457 Promoted = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ExtractVT, Promoted,
6458 DAG.getVectorIdxConstant(0, dl));
6459 }
6460 return DAG.getNode(N->getOpcode(), dl, NVT, Promoted);
6461 }
6462
6463 // Directly extend to the appropriate transform-to type.
6464 return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
6465}
6466
6467SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_FIND_LAST_ACTIVE(SDNode *N) {
6468 EVT VT = N->getValueType(0);
6469 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6470 return DAG.getNode(ISD::VECTOR_FIND_LAST_ACTIVE, SDLoc(N), NVT, N->ops());
6471}
6472
6473SDValue DAGTypeLegalizer::PromoteIntRes_GET_ACTIVE_LANE_MASK(SDNode *N) {
6474 EVT VT = N->getValueType(0);
6475 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6476 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, SDLoc(N), NVT, N->ops());
6477}
6478
6479SDValue DAGTypeLegalizer::PromoteIntRes_PARTIAL_REDUCE_MLA(SDNode *N) {
6480 SDLoc DL(N);
6481 EVT VT = N->getValueType(0);
6482 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6483 SDValue ExtAcc = GetPromotedInteger(N->getOperand(0));
6484 return DAG.getNode(N->getOpcode(), DL, NVT, ExtAcc, N->getOperand(1),
6485 N->getOperand(2));
6486}
6487
6488SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) {
6489 EVT OutVT = N->getValueType(0);
6490 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
6491 assert(NOutVT.isVector() && "This type must be promoted to a vector type");
6492
6493 EVT NOutVTElem = NOutVT.getVectorElementType();
6494
6495 SDLoc dl(N);
6496 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6497
6498 SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl,
6499 NOutVTElem, N->getOperand(1));
6500 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NOutVT,
6501 V0, ConvElem, N->getOperand(2));
6502}
6503
6504SDValue DAGTypeLegalizer::PromoteIntRes_VECREDUCE(SDNode *N) {
6505 // The VECREDUCE result size may be larger than the element size, so
6506 // we can simply change the result type.
6507 SDLoc dl(N);
6508 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6509 return DAG.getNode(N->getOpcode(), dl, NVT, N->ops());
6510}
6511
6512SDValue DAGTypeLegalizer::PromoteIntRes_VP_REDUCE(SDNode *N) {
6513 // The VP_REDUCE result size may be larger than the element size, so we can
6514 // simply change the result type. However the start value and result must be
6515 // the same.
6516 SDLoc DL(N);
6517 SDValue Start = PromoteIntOpVectorReduction(N, N->getOperand(0));
6518 return DAG.getNode(N->getOpcode(), DL, Start.getValueType(), Start,
6519 N->getOperand(1), N->getOperand(2), N->getOperand(3));
6520}
6521
6522SDValue DAGTypeLegalizer::PromoteIntRes_PATCHPOINT(SDNode *N) {
6523 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6524 SDLoc dl(N);
6525
6526 assert(N->getNumValues() == 3 && "Expected 3 values for PATCHPOINT");
6527 SDVTList VTList = DAG.getVTList({NVT, MVT::Other, MVT::Glue});
6528
6529 SmallVector<SDValue> Ops(N->ops());
6530 SDValue Res = DAG.getNode(ISD::PATCHPOINT, dl, VTList, Ops);
6531
6532 // Replace chain and glue uses with the new patchpoint.
6533 SDValue From[] = {SDValue(N, 1), SDValue(N, 2)};
6534 SDValue To[] = {Res.getValue(1), Res.getValue(2)};
6535 DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
6536
6537 return Res.getValue(0);
6538}
6539
6540SDValue DAGTypeLegalizer::PromoteIntRes_READ_REGISTER(SDNode *N) {
6541 const Function &Fn = DAG.getMachineFunction().getFunction();
6542 Fn.getContext().diagnose(DiagnosticInfoLegalizationFailure(
6543 "cannot use llvm.read_register with illegal type", Fn, N->getDebugLoc()));
6544
6545 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6546 ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
6547 return DAG.getPOISON(NVT);
6548}
6549
6550SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
6551 SDLoc dl(N);
6552 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6553 SDValue V1 = DAG.getZExtOrTrunc(N->getOperand(1), dl,
6554 TLI.getVectorIdxTy(DAG.getDataLayout()));
6556 V0->getValueType(0).getScalarType(), V0, V1);
6557
6558 // EXTRACT_VECTOR_ELT can return types which are wider than the incoming
6559 // element types. If this is the case then we need to expand the outgoing
6560 // value and not truncate it.
6561 return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
6562}
6563
6564SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_SUBVECTOR(SDNode *N) {
6565 SDLoc dl(N);
6566 // The result type is equal to the first input operand's type, so the
6567 // type that needs promoting must be the second source vector.
6568 SDValue V0 = N->getOperand(0);
6569 SDValue V1 = GetPromotedInteger(N->getOperand(1));
6570 SDValue Idx = N->getOperand(2);
6571 EVT PromVT = EVT::getVectorVT(*DAG.getContext(),
6574 V0 = DAG.getAnyExtOrTrunc(V0, dl, PromVT);
6575 SDValue Ext = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, PromVT, V0, V1, Idx);
6576 return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
6577}
6578
6579// FIXME: We wouldn't need this if clang could promote short integers
6580// that are arguments to FAKE_USE.
6581SDValue DAGTypeLegalizer::PromoteIntOp_FAKE_USE(SDNode *N) {
6582 SDLoc dl(N);
6583 SDValue V0 = N->getOperand(0);
6584 SDValue V1 = N->getOperand(1);
6585 EVT InVT1 = V1.getValueType();
6586 SDValue VPromoted =
6587 DAG.getNode(ISD::ANY_EXTEND, dl,
6588 TLI.getTypeToTransformTo(*DAG.getContext(), InVT1), V1);
6589 return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), V0, VPromoted);
6590}
6591
6592SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_SUBVECTOR(SDNode *N) {
6593 SDLoc dl(N);
6594 SDValue V0 = GetPromotedInteger(N->getOperand(0));
6595 MVT InVT = V0.getValueType().getSimpleVT();
6596 MVT OutVT = MVT::getVectorVT(InVT.getVectorElementType(),
6597 N->getValueType(0).getVectorNumElements());
6598 SDValue Ext = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OutVT, V0, N->getOperand(1));
6599 return DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), Ext);
6600}
6601
6602SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
6603 SDLoc dl(N);
6604
6605 EVT ResVT = N->getValueType(0);
6606 unsigned NumElems = N->getNumOperands();
6607
6608 if (ResVT.isScalableVector()) {
6609 SDValue ResVec = DAG.getUNDEF(ResVT);
6610
6611 for (unsigned OpIdx = 0; OpIdx < NumElems; ++OpIdx) {
6612 SDValue Op = N->getOperand(OpIdx);
6613 unsigned OpNumElts = Op.getValueType().getVectorMinNumElements();
6614 ResVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, ResVec, Op,
6615 DAG.getIntPtrConstant(OpIdx * OpNumElts, dl));
6616 }
6617
6618 return ResVec;
6619 }
6620
6621 EVT RetSclrTy = N->getValueType(0).getVectorElementType();
6622
6624 NewOps.reserve(NumElems);
6625
6626 // For each incoming vector
6627 for (unsigned VecIdx = 0; VecIdx != NumElems; ++VecIdx) {
6628 SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx));
6629 EVT SclrTy = Incoming->getValueType(0).getVectorElementType();
6630 unsigned NumElem = Incoming->getValueType(0).getVectorNumElements();
6631
6632 for (unsigned i=0; i<NumElem; ++i) {
6633 // Extract element from incoming vector
6634 SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy, Incoming,
6635 DAG.getVectorIdxConstant(i, dl));
6636 SDValue Tr = DAG.getNode(ISD::TRUNCATE, dl, RetSclrTy, Ex);
6637 NewOps.push_back(Tr);
6638 }
6639 }
6640
6641 return DAG.getBuildVector(N->getValueType(0), dl, NewOps);
6642}
6643
6644SDValue DAGTypeLegalizer::ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
6645 assert(OpNo > 1);
6646 SDValue Op = N->getOperand(OpNo);
6647
6648 // FIXME: Non-constant operands are not yet handled:
6649 // - https://github.com/llvm/llvm-project/issues/26431
6650 // - https://github.com/llvm/llvm-project/issues/55957
6651 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
6652 if (!CN)
6653 return SDValue();
6654
6655 // Copy operands before the one being expanded.
6656 SmallVector<SDValue> NewOps;
6657 for (unsigned I = 0; I < OpNo; I++)
6658 NewOps.push_back(N->getOperand(I));
6659
6660 EVT Ty = Op.getValueType();
6661 SDLoc DL = SDLoc(N);
6662 if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
6663 NewOps.push_back(
6664 DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
6665 NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
6666 } else {
6667 // FIXME: https://github.com/llvm/llvm-project/issues/55609
6668 return SDValue();
6669 }
6670
6671 // Copy remaining operands.
6672 for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
6673 NewOps.push_back(N->getOperand(I));
6674
6675 SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
6676
6677 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
6678 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
6679
6680 return SDValue(); // Signal that we have replaced the node already.
6681}
6682
6683SDValue DAGTypeLegalizer::ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
6684 assert(OpNo >= 7);
6685 SDValue Op = N->getOperand(OpNo);
6686
6687 // FIXME: Non-constant operands are not yet handled:
6688 // - https://github.com/llvm/llvm-project/issues/26431
6689 // - https://github.com/llvm/llvm-project/issues/55957
6690 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
6691 if (!CN)
6692 return SDValue();
6693
6694 // Copy operands before the one being expanded.
6695 SmallVector<SDValue> NewOps;
6696 for (unsigned I = 0; I < OpNo; I++)
6697 NewOps.push_back(N->getOperand(I));
6698
6699 EVT Ty = Op.getValueType();
6700 SDLoc DL = SDLoc(N);
6701 if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
6702 NewOps.push_back(
6703 DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
6704 NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
6705 } else {
6706 // FIXME: https://github.com/llvm/llvm-project/issues/55609
6707 return SDValue();
6708 }
6709
6710 // Copy remaining operands.
6711 for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
6712 NewOps.push_back(N->getOperand(I));
6713
6714 SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
6715
6716 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
6717 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
6718
6719 return SDValue(); // Signal that we have replaced the node already.
6720}
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:403
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:308
ElementCount getVectorElementCount() const
Definition ValueTypes.h:358
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:381
bool isByteSized() const
Return true if the bit size is a multiple of 8.
Definition ValueTypes.h:251
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
Definition ValueTypes.h:367
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:393
TypeSize getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value type.
Definition ValueTypes.h:420
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:324
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:331
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
Definition ValueTypes.h:300
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
Definition ValueTypes.h:264
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:182
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:336
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:344
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition ValueTypes.h:316
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
Definition ValueTypes.h:469
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)