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