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