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