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