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