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