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