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