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