1f4a2713aSLionel Sambuc //===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements integer type expansion and promotion for LegalizeTypes.
11f4a2713aSLionel Sambuc // Promotion is the act of changing a computation in an illegal type into a
12f4a2713aSLionel Sambuc // computation in a larger type.  For example, implementing i8 arithmetic in an
13f4a2713aSLionel Sambuc // i32 register (often needed on powerpc).
14f4a2713aSLionel Sambuc // Expansion is the act of changing a computation in an illegal type into a
15f4a2713aSLionel Sambuc // computation in two identical registers of a smaller type.  For example,
16f4a2713aSLionel Sambuc // implementing i64 arithmetic in two i32 registers (often needed on 32-bit
17f4a2713aSLionel Sambuc // targets).
18f4a2713aSLionel Sambuc //
19f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
20f4a2713aSLionel Sambuc 
21f4a2713aSLionel Sambuc #include "LegalizeTypes.h"
22f4a2713aSLionel Sambuc #include "llvm/IR/DerivedTypes.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
24f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
25f4a2713aSLionel Sambuc using namespace llvm;
26f4a2713aSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "legalize-types"
28*0a6a1f1dSLionel Sambuc 
29f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
30f4a2713aSLionel Sambuc //  Integer Result Promotion
31f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc /// PromoteIntegerResult - This method is called when a result of a node is
34f4a2713aSLionel Sambuc /// found to be in need of promotion to a larger type.  At this point, the node
35f4a2713aSLionel Sambuc /// may also have invalid operands or may have other results that need
36f4a2713aSLionel Sambuc /// expansion, we just know that (at least) one result needs promotion.
PromoteIntegerResult(SDNode * N,unsigned ResNo)37f4a2713aSLionel Sambuc void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
38f4a2713aSLionel Sambuc   DEBUG(dbgs() << "Promote integer result: "; N->dump(&DAG); dbgs() << "\n");
39f4a2713aSLionel Sambuc   SDValue Res = SDValue();
40f4a2713aSLionel Sambuc 
41f4a2713aSLionel Sambuc   // See if the target wants to custom expand this node.
42f4a2713aSLionel Sambuc   if (CustomLowerNode(N, N->getValueType(ResNo), true))
43f4a2713aSLionel Sambuc     return;
44f4a2713aSLionel Sambuc 
45f4a2713aSLionel Sambuc   switch (N->getOpcode()) {
46f4a2713aSLionel Sambuc   default:
47f4a2713aSLionel Sambuc #ifndef NDEBUG
48f4a2713aSLionel Sambuc     dbgs() << "PromoteIntegerResult #" << ResNo << ": ";
49f4a2713aSLionel Sambuc     N->dump(&DAG); dbgs() << "\n";
50f4a2713aSLionel Sambuc #endif
51f4a2713aSLionel Sambuc     llvm_unreachable("Do not know how to promote this operator!");
52f4a2713aSLionel Sambuc   case ISD::MERGE_VALUES:Res = PromoteIntRes_MERGE_VALUES(N, ResNo); break;
53f4a2713aSLionel Sambuc   case ISD::AssertSext:  Res = PromoteIntRes_AssertSext(N); break;
54f4a2713aSLionel Sambuc   case ISD::AssertZext:  Res = PromoteIntRes_AssertZext(N); break;
55f4a2713aSLionel Sambuc   case ISD::BITCAST:     Res = PromoteIntRes_BITCAST(N); break;
56f4a2713aSLionel Sambuc   case ISD::BSWAP:       Res = PromoteIntRes_BSWAP(N); break;
57f4a2713aSLionel Sambuc   case ISD::BUILD_PAIR:  Res = PromoteIntRes_BUILD_PAIR(N); break;
58f4a2713aSLionel Sambuc   case ISD::Constant:    Res = PromoteIntRes_Constant(N); break;
59f4a2713aSLionel Sambuc   case ISD::CONVERT_RNDSAT:
60f4a2713aSLionel Sambuc                          Res = PromoteIntRes_CONVERT_RNDSAT(N); break;
61f4a2713aSLionel Sambuc   case ISD::CTLZ_ZERO_UNDEF:
62f4a2713aSLionel Sambuc   case ISD::CTLZ:        Res = PromoteIntRes_CTLZ(N); break;
63f4a2713aSLionel Sambuc   case ISD::CTPOP:       Res = PromoteIntRes_CTPOP(N); break;
64f4a2713aSLionel Sambuc   case ISD::CTTZ_ZERO_UNDEF:
65f4a2713aSLionel Sambuc   case ISD::CTTZ:        Res = PromoteIntRes_CTTZ(N); break;
66f4a2713aSLionel Sambuc   case ISD::EXTRACT_VECTOR_ELT:
67f4a2713aSLionel Sambuc                          Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break;
68f4a2713aSLionel Sambuc   case ISD::LOAD:        Res = PromoteIntRes_LOAD(cast<LoadSDNode>(N));break;
69*0a6a1f1dSLionel Sambuc   case ISD::MLOAD:       Res = PromoteIntRes_MLOAD(cast<MaskedLoadSDNode>(N));break;
70f4a2713aSLionel Sambuc   case ISD::SELECT:      Res = PromoteIntRes_SELECT(N); break;
71f4a2713aSLionel Sambuc   case ISD::VSELECT:     Res = PromoteIntRes_VSELECT(N); break;
72f4a2713aSLionel Sambuc   case ISD::SELECT_CC:   Res = PromoteIntRes_SELECT_CC(N); break;
73f4a2713aSLionel Sambuc   case ISD::SETCC:       Res = PromoteIntRes_SETCC(N); break;
74f4a2713aSLionel Sambuc   case ISD::SHL:         Res = PromoteIntRes_SHL(N); break;
75f4a2713aSLionel Sambuc   case ISD::SIGN_EXTEND_INREG:
76f4a2713aSLionel Sambuc                          Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break;
77f4a2713aSLionel Sambuc   case ISD::SRA:         Res = PromoteIntRes_SRA(N); break;
78f4a2713aSLionel Sambuc   case ISD::SRL:         Res = PromoteIntRes_SRL(N); break;
79f4a2713aSLionel Sambuc   case ISD::TRUNCATE:    Res = PromoteIntRes_TRUNCATE(N); break;
80f4a2713aSLionel Sambuc   case ISD::UNDEF:       Res = PromoteIntRes_UNDEF(N); break;
81f4a2713aSLionel Sambuc   case ISD::VAARG:       Res = PromoteIntRes_VAARG(N); break;
82f4a2713aSLionel Sambuc 
83f4a2713aSLionel Sambuc   case ISD::EXTRACT_SUBVECTOR:
84f4a2713aSLionel Sambuc                          Res = PromoteIntRes_EXTRACT_SUBVECTOR(N); break;
85f4a2713aSLionel Sambuc   case ISD::VECTOR_SHUFFLE:
86f4a2713aSLionel Sambuc                          Res = PromoteIntRes_VECTOR_SHUFFLE(N); break;
87f4a2713aSLionel Sambuc   case ISD::INSERT_VECTOR_ELT:
88f4a2713aSLionel Sambuc                          Res = PromoteIntRes_INSERT_VECTOR_ELT(N); break;
89f4a2713aSLionel Sambuc   case ISD::BUILD_VECTOR:
90f4a2713aSLionel Sambuc                          Res = PromoteIntRes_BUILD_VECTOR(N); break;
91f4a2713aSLionel Sambuc   case ISD::SCALAR_TO_VECTOR:
92f4a2713aSLionel Sambuc                          Res = PromoteIntRes_SCALAR_TO_VECTOR(N); break;
93f4a2713aSLionel Sambuc   case ISD::CONCAT_VECTORS:
94f4a2713aSLionel Sambuc                          Res = PromoteIntRes_CONCAT_VECTORS(N); break;
95f4a2713aSLionel Sambuc 
96f4a2713aSLionel Sambuc   case ISD::SIGN_EXTEND:
97f4a2713aSLionel Sambuc   case ISD::ZERO_EXTEND:
98f4a2713aSLionel Sambuc   case ISD::ANY_EXTEND:  Res = PromoteIntRes_INT_EXTEND(N); break;
99f4a2713aSLionel Sambuc 
100f4a2713aSLionel Sambuc   case ISD::FP_TO_SINT:
101f4a2713aSLionel Sambuc   case ISD::FP_TO_UINT:  Res = PromoteIntRes_FP_TO_XINT(N); break;
102f4a2713aSLionel Sambuc 
103*0a6a1f1dSLionel Sambuc   case ISD::FP_TO_FP16:  Res = PromoteIntRes_FP_TO_FP16(N); break;
104f4a2713aSLionel Sambuc 
105f4a2713aSLionel Sambuc   case ISD::AND:
106f4a2713aSLionel Sambuc   case ISD::OR:
107f4a2713aSLionel Sambuc   case ISD::XOR:
108f4a2713aSLionel Sambuc   case ISD::ADD:
109f4a2713aSLionel Sambuc   case ISD::SUB:
110f4a2713aSLionel Sambuc   case ISD::MUL:         Res = PromoteIntRes_SimpleIntBinOp(N); break;
111f4a2713aSLionel Sambuc 
112f4a2713aSLionel Sambuc   case ISD::SDIV:
113f4a2713aSLionel Sambuc   case ISD::SREM:        Res = PromoteIntRes_SDIV(N); break;
114f4a2713aSLionel Sambuc 
115f4a2713aSLionel Sambuc   case ISD::UDIV:
116f4a2713aSLionel Sambuc   case ISD::UREM:        Res = PromoteIntRes_UDIV(N); break;
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc   case ISD::SADDO:
119f4a2713aSLionel Sambuc   case ISD::SSUBO:       Res = PromoteIntRes_SADDSUBO(N, ResNo); break;
120f4a2713aSLionel Sambuc   case ISD::UADDO:
121f4a2713aSLionel Sambuc   case ISD::USUBO:       Res = PromoteIntRes_UADDSUBO(N, ResNo); break;
122f4a2713aSLionel Sambuc   case ISD::SMULO:
123f4a2713aSLionel Sambuc   case ISD::UMULO:       Res = PromoteIntRes_XMULO(N, ResNo); break;
124f4a2713aSLionel Sambuc 
125f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD:
126f4a2713aSLionel Sambuc     Res = PromoteIntRes_Atomic0(cast<AtomicSDNode>(N)); break;
127f4a2713aSLionel Sambuc 
128f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_ADD:
129f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_SUB:
130f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_AND:
131f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_OR:
132f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_XOR:
133f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_NAND:
134f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_MIN:
135f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_MAX:
136f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_UMIN:
137f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_UMAX:
138f4a2713aSLionel Sambuc   case ISD::ATOMIC_SWAP:
139f4a2713aSLionel Sambuc     Res = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break;
140f4a2713aSLionel Sambuc 
141f4a2713aSLionel Sambuc   case ISD::ATOMIC_CMP_SWAP:
142*0a6a1f1dSLionel Sambuc   case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
143*0a6a1f1dSLionel Sambuc     Res = PromoteIntRes_AtomicCmpSwap(cast<AtomicSDNode>(N), ResNo);
144*0a6a1f1dSLionel Sambuc     break;
145f4a2713aSLionel Sambuc   }
146f4a2713aSLionel Sambuc 
147f4a2713aSLionel Sambuc   // If the result is null then the sub-method took care of registering it.
148f4a2713aSLionel Sambuc   if (Res.getNode())
149f4a2713aSLionel Sambuc     SetPromotedInteger(SDValue(N, ResNo), Res);
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc 
PromoteIntRes_MERGE_VALUES(SDNode * N,unsigned ResNo)152f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_MERGE_VALUES(SDNode *N,
153f4a2713aSLionel Sambuc                                                      unsigned ResNo) {
154f4a2713aSLionel Sambuc   SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
155f4a2713aSLionel Sambuc   return GetPromotedInteger(Op);
156f4a2713aSLionel Sambuc }
157f4a2713aSLionel Sambuc 
PromoteIntRes_AssertSext(SDNode * N)158f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
159f4a2713aSLionel Sambuc   // Sign-extend the new bits, and continue the assertion.
160f4a2713aSLionel Sambuc   SDValue Op = SExtPromotedInteger(N->getOperand(0));
161f4a2713aSLionel Sambuc   return DAG.getNode(ISD::AssertSext, SDLoc(N),
162f4a2713aSLionel Sambuc                      Op.getValueType(), Op, N->getOperand(1));
163f4a2713aSLionel Sambuc }
164f4a2713aSLionel Sambuc 
PromoteIntRes_AssertZext(SDNode * N)165f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
166f4a2713aSLionel Sambuc   // Zero the new bits, and continue the assertion.
167f4a2713aSLionel Sambuc   SDValue Op = ZExtPromotedInteger(N->getOperand(0));
168f4a2713aSLionel Sambuc   return DAG.getNode(ISD::AssertZext, SDLoc(N),
169f4a2713aSLionel Sambuc                      Op.getValueType(), Op, N->getOperand(1));
170f4a2713aSLionel Sambuc }
171f4a2713aSLionel Sambuc 
PromoteIntRes_Atomic0(AtomicSDNode * N)172f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_Atomic0(AtomicSDNode *N) {
173f4a2713aSLionel Sambuc   EVT ResVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
174f4a2713aSLionel Sambuc   SDValue Res = DAG.getAtomic(N->getOpcode(), SDLoc(N),
175f4a2713aSLionel Sambuc                               N->getMemoryVT(), ResVT,
176f4a2713aSLionel Sambuc                               N->getChain(), N->getBasePtr(),
177f4a2713aSLionel Sambuc                               N->getMemOperand(), N->getOrdering(),
178f4a2713aSLionel Sambuc                               N->getSynchScope());
179f4a2713aSLionel Sambuc   // Legalized the chain result - switch anything that used the old chain to
180f4a2713aSLionel Sambuc   // use the new one.
181f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
182f4a2713aSLionel Sambuc   return Res;
183f4a2713aSLionel Sambuc }
184f4a2713aSLionel Sambuc 
PromoteIntRes_Atomic1(AtomicSDNode * N)185f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
186f4a2713aSLionel Sambuc   SDValue Op2 = GetPromotedInteger(N->getOperand(2));
187f4a2713aSLionel Sambuc   SDValue Res = DAG.getAtomic(N->getOpcode(), SDLoc(N),
188f4a2713aSLionel Sambuc                               N->getMemoryVT(),
189f4a2713aSLionel Sambuc                               N->getChain(), N->getBasePtr(),
190f4a2713aSLionel Sambuc                               Op2, N->getMemOperand(), N->getOrdering(),
191f4a2713aSLionel Sambuc                               N->getSynchScope());
192f4a2713aSLionel Sambuc   // Legalized the chain result - switch anything that used the old chain to
193f4a2713aSLionel Sambuc   // use the new one.
194f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
195f4a2713aSLionel Sambuc   return Res;
196f4a2713aSLionel Sambuc }
197f4a2713aSLionel Sambuc 
PromoteIntRes_AtomicCmpSwap(AtomicSDNode * N,unsigned ResNo)198*0a6a1f1dSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_AtomicCmpSwap(AtomicSDNode *N,
199*0a6a1f1dSLionel Sambuc                                                       unsigned ResNo) {
200*0a6a1f1dSLionel Sambuc   if (ResNo == 1) {
201*0a6a1f1dSLionel Sambuc     assert(N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS);
202*0a6a1f1dSLionel Sambuc     EVT SVT = getSetCCResultType(N->getOperand(2).getValueType());
203*0a6a1f1dSLionel Sambuc     EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1));
204*0a6a1f1dSLionel Sambuc 
205*0a6a1f1dSLionel Sambuc     // Only use the result of getSetCCResultType if it is legal,
206*0a6a1f1dSLionel Sambuc     // otherwise just use the promoted result type (NVT).
207*0a6a1f1dSLionel Sambuc     if (!TLI.isTypeLegal(SVT))
208*0a6a1f1dSLionel Sambuc       SVT = NVT;
209*0a6a1f1dSLionel Sambuc 
210*0a6a1f1dSLionel Sambuc     SDVTList VTs = DAG.getVTList(N->getValueType(0), SVT, MVT::Other);
211*0a6a1f1dSLionel Sambuc     SDValue Res = DAG.getAtomicCmpSwap(
212*0a6a1f1dSLionel Sambuc         ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, SDLoc(N), N->getMemoryVT(), VTs,
213*0a6a1f1dSLionel Sambuc         N->getChain(), N->getBasePtr(), N->getOperand(2), N->getOperand(3),
214*0a6a1f1dSLionel Sambuc         N->getMemOperand(), N->getSuccessOrdering(), N->getFailureOrdering(),
215*0a6a1f1dSLionel Sambuc         N->getSynchScope());
216*0a6a1f1dSLionel Sambuc     ReplaceValueWith(SDValue(N, 0), Res.getValue(0));
217*0a6a1f1dSLionel Sambuc     ReplaceValueWith(SDValue(N, 2), Res.getValue(2));
218*0a6a1f1dSLionel Sambuc     return Res.getValue(1);
219*0a6a1f1dSLionel Sambuc   }
220*0a6a1f1dSLionel Sambuc 
221f4a2713aSLionel Sambuc   SDValue Op2 = GetPromotedInteger(N->getOperand(2));
222f4a2713aSLionel Sambuc   SDValue Op3 = GetPromotedInteger(N->getOperand(3));
223*0a6a1f1dSLionel Sambuc   SDVTList VTs =
224*0a6a1f1dSLionel Sambuc       DAG.getVTList(Op2.getValueType(), N->getValueType(1), MVT::Other);
225*0a6a1f1dSLionel Sambuc   SDValue Res = DAG.getAtomicCmpSwap(
226*0a6a1f1dSLionel Sambuc       N->getOpcode(), SDLoc(N), N->getMemoryVT(), VTs, N->getChain(),
227*0a6a1f1dSLionel Sambuc       N->getBasePtr(), Op2, Op3, N->getMemOperand(), N->getSuccessOrdering(),
228*0a6a1f1dSLionel Sambuc       N->getFailureOrdering(), N->getSynchScope());
229*0a6a1f1dSLionel Sambuc   // Update the use to N with the newly created Res.
230*0a6a1f1dSLionel Sambuc   for (unsigned i = 1, NumResults = N->getNumValues(); i < NumResults; ++i)
231*0a6a1f1dSLionel Sambuc     ReplaceValueWith(SDValue(N, i), Res.getValue(i));
232f4a2713aSLionel Sambuc   return Res;
233f4a2713aSLionel Sambuc }
234f4a2713aSLionel Sambuc 
PromoteIntRes_BITCAST(SDNode * N)235f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_BITCAST(SDNode *N) {
236f4a2713aSLionel Sambuc   SDValue InOp = N->getOperand(0);
237f4a2713aSLionel Sambuc   EVT InVT = InOp.getValueType();
238f4a2713aSLionel Sambuc   EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
239f4a2713aSLionel Sambuc   EVT OutVT = N->getValueType(0);
240f4a2713aSLionel Sambuc   EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
241f4a2713aSLionel Sambuc   SDLoc dl(N);
242f4a2713aSLionel Sambuc 
243f4a2713aSLionel Sambuc   switch (getTypeAction(InVT)) {
244f4a2713aSLionel Sambuc   case TargetLowering::TypeLegal:
245f4a2713aSLionel Sambuc     break;
246f4a2713aSLionel Sambuc   case TargetLowering::TypePromoteInteger:
247f4a2713aSLionel Sambuc     if (NOutVT.bitsEq(NInVT) && !NOutVT.isVector() && !NInVT.isVector())
248f4a2713aSLionel Sambuc       // The input promotes to the same size.  Convert the promoted value.
249f4a2713aSLionel Sambuc       return DAG.getNode(ISD::BITCAST, dl, NOutVT, GetPromotedInteger(InOp));
250f4a2713aSLionel Sambuc     break;
251f4a2713aSLionel Sambuc   case TargetLowering::TypeSoftenFloat:
252f4a2713aSLionel Sambuc     // Promote the integer operand by hand.
253f4a2713aSLionel Sambuc     return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp));
254f4a2713aSLionel Sambuc   case TargetLowering::TypeExpandInteger:
255f4a2713aSLionel Sambuc   case TargetLowering::TypeExpandFloat:
256f4a2713aSLionel Sambuc     break;
257f4a2713aSLionel Sambuc   case TargetLowering::TypeScalarizeVector:
258f4a2713aSLionel Sambuc     // Convert the element to an integer and promote it by hand.
259f4a2713aSLionel Sambuc     if (!NOutVT.isVector())
260f4a2713aSLionel Sambuc       return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
261f4a2713aSLionel Sambuc                          BitConvertToInteger(GetScalarizedVector(InOp)));
262f4a2713aSLionel Sambuc     break;
263f4a2713aSLionel Sambuc   case TargetLowering::TypeSplitVector: {
264f4a2713aSLionel Sambuc     // For example, i32 = BITCAST v2i16 on alpha.  Convert the split
265f4a2713aSLionel Sambuc     // pieces of the input into integers and reassemble in the final type.
266f4a2713aSLionel Sambuc     SDValue Lo, Hi;
267f4a2713aSLionel Sambuc     GetSplitVector(N->getOperand(0), Lo, Hi);
268f4a2713aSLionel Sambuc     Lo = BitConvertToInteger(Lo);
269f4a2713aSLionel Sambuc     Hi = BitConvertToInteger(Hi);
270f4a2713aSLionel Sambuc 
271f4a2713aSLionel Sambuc     if (TLI.isBigEndian())
272f4a2713aSLionel Sambuc       std::swap(Lo, Hi);
273f4a2713aSLionel Sambuc 
274f4a2713aSLionel Sambuc     InOp = DAG.getNode(ISD::ANY_EXTEND, dl,
275f4a2713aSLionel Sambuc                        EVT::getIntegerVT(*DAG.getContext(),
276f4a2713aSLionel Sambuc                                          NOutVT.getSizeInBits()),
277f4a2713aSLionel Sambuc                        JoinIntegers(Lo, Hi));
278f4a2713aSLionel Sambuc     return DAG.getNode(ISD::BITCAST, dl, NOutVT, InOp);
279f4a2713aSLionel Sambuc   }
280f4a2713aSLionel Sambuc   case TargetLowering::TypeWidenVector:
281f4a2713aSLionel Sambuc     // The input is widened to the same size. Convert to the widened value.
282f4a2713aSLionel Sambuc     // Make sure that the outgoing value is not a vector, because this would
283f4a2713aSLionel Sambuc     // make us bitcast between two vectors which are legalized in different ways.
284f4a2713aSLionel Sambuc     if (NOutVT.bitsEq(NInVT) && !NOutVT.isVector())
285f4a2713aSLionel Sambuc       return DAG.getNode(ISD::BITCAST, dl, NOutVT, GetWidenedVector(InOp));
286f4a2713aSLionel Sambuc   }
287f4a2713aSLionel Sambuc 
288f4a2713aSLionel Sambuc   return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
289f4a2713aSLionel Sambuc                      CreateStackStoreLoad(InOp, OutVT));
290f4a2713aSLionel Sambuc }
291f4a2713aSLionel Sambuc 
PromoteIntRes_BSWAP(SDNode * N)292f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
293f4a2713aSLionel Sambuc   SDValue Op = GetPromotedInteger(N->getOperand(0));
294f4a2713aSLionel Sambuc   EVT OVT = N->getValueType(0);
295f4a2713aSLionel Sambuc   EVT NVT = Op.getValueType();
296f4a2713aSLionel Sambuc   SDLoc dl(N);
297f4a2713aSLionel Sambuc 
298*0a6a1f1dSLionel Sambuc   unsigned DiffBits = NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits();
299f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op),
300*0a6a1f1dSLionel Sambuc                      DAG.getConstant(DiffBits, TLI.getShiftAmountTy(NVT)));
301f4a2713aSLionel Sambuc }
302f4a2713aSLionel Sambuc 
PromoteIntRes_BUILD_PAIR(SDNode * N)303f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
304f4a2713aSLionel Sambuc   // The pair element type may be legal, or may not promote to the same type as
305f4a2713aSLionel Sambuc   // the result, for example i14 = BUILD_PAIR (i7, i7).  Handle all cases.
306f4a2713aSLionel Sambuc   return DAG.getNode(ISD::ANY_EXTEND, SDLoc(N),
307f4a2713aSLionel Sambuc                      TLI.getTypeToTransformTo(*DAG.getContext(),
308f4a2713aSLionel Sambuc                      N->getValueType(0)), JoinIntegers(N->getOperand(0),
309f4a2713aSLionel Sambuc                      N->getOperand(1)));
310f4a2713aSLionel Sambuc }
311f4a2713aSLionel Sambuc 
PromoteIntRes_Constant(SDNode * N)312f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
313f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
314f4a2713aSLionel Sambuc   // FIXME there is no actual debug info here
315f4a2713aSLionel Sambuc   SDLoc dl(N);
316f4a2713aSLionel Sambuc   // Zero extend things like i1, sign extend everything else.  It shouldn't
317f4a2713aSLionel Sambuc   // matter in theory which one we pick, but this tends to give better code?
318f4a2713aSLionel Sambuc   unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
319f4a2713aSLionel Sambuc   SDValue Result = DAG.getNode(Opc, dl,
320f4a2713aSLionel Sambuc                                TLI.getTypeToTransformTo(*DAG.getContext(), VT),
321f4a2713aSLionel Sambuc                                SDValue(N, 0));
322f4a2713aSLionel Sambuc   assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
323f4a2713aSLionel Sambuc   return Result;
324f4a2713aSLionel Sambuc }
325f4a2713aSLionel Sambuc 
PromoteIntRes_CONVERT_RNDSAT(SDNode * N)326f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_CONVERT_RNDSAT(SDNode *N) {
327f4a2713aSLionel Sambuc   ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
328f4a2713aSLionel Sambuc   assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
329f4a2713aSLionel Sambuc            CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
330f4a2713aSLionel Sambuc            CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
331f4a2713aSLionel Sambuc           "can only promote integers");
332f4a2713aSLionel Sambuc   EVT OutVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
333f4a2713aSLionel Sambuc   return DAG.getConvertRndSat(OutVT, SDLoc(N), N->getOperand(0),
334f4a2713aSLionel Sambuc                               N->getOperand(1), N->getOperand(2),
335f4a2713aSLionel Sambuc                               N->getOperand(3), N->getOperand(4), CvtCode);
336f4a2713aSLionel Sambuc }
337f4a2713aSLionel Sambuc 
PromoteIntRes_CTLZ(SDNode * N)338f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
339f4a2713aSLionel Sambuc   // Zero extend to the promoted type and do the count there.
340f4a2713aSLionel Sambuc   SDValue Op = ZExtPromotedInteger(N->getOperand(0));
341f4a2713aSLionel Sambuc   SDLoc dl(N);
342f4a2713aSLionel Sambuc   EVT OVT = N->getValueType(0);
343f4a2713aSLionel Sambuc   EVT NVT = Op.getValueType();
344f4a2713aSLionel Sambuc   Op = DAG.getNode(N->getOpcode(), dl, NVT, Op);
345f4a2713aSLionel Sambuc   // Subtract off the extra leading bits in the bigger type.
346*0a6a1f1dSLionel Sambuc   return DAG.getNode(
347*0a6a1f1dSLionel Sambuc       ISD::SUB, dl, NVT, Op,
348*0a6a1f1dSLionel Sambuc       DAG.getConstant(NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits(),
349*0a6a1f1dSLionel Sambuc                       NVT));
350f4a2713aSLionel Sambuc }
351f4a2713aSLionel Sambuc 
PromoteIntRes_CTPOP(SDNode * N)352f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
353f4a2713aSLionel Sambuc   // Zero extend to the promoted type and do the count there.
354f4a2713aSLionel Sambuc   SDValue Op = ZExtPromotedInteger(N->getOperand(0));
355f4a2713aSLionel Sambuc   return DAG.getNode(ISD::CTPOP, SDLoc(N), Op.getValueType(), Op);
356f4a2713aSLionel Sambuc }
357f4a2713aSLionel Sambuc 
PromoteIntRes_CTTZ(SDNode * N)358f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
359f4a2713aSLionel Sambuc   SDValue Op = GetPromotedInteger(N->getOperand(0));
360f4a2713aSLionel Sambuc   EVT OVT = N->getValueType(0);
361f4a2713aSLionel Sambuc   EVT NVT = Op.getValueType();
362f4a2713aSLionel Sambuc   SDLoc dl(N);
363f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::CTTZ) {
364f4a2713aSLionel Sambuc     // The count is the same in the promoted type except if the original
365f4a2713aSLionel Sambuc     // value was zero.  This can be handled by setting the bit just off
366f4a2713aSLionel Sambuc     // the top of the original type.
367*0a6a1f1dSLionel Sambuc     auto TopBit = APInt::getOneBitSet(NVT.getScalarSizeInBits(),
368*0a6a1f1dSLionel Sambuc                                       OVT.getScalarSizeInBits());
369f4a2713aSLionel Sambuc     Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
370f4a2713aSLionel Sambuc   }
371f4a2713aSLionel Sambuc   return DAG.getNode(N->getOpcode(), dl, NVT, Op);
372f4a2713aSLionel Sambuc }
373f4a2713aSLionel Sambuc 
PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode * N)374f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
375f4a2713aSLionel Sambuc   SDLoc dl(N);
376f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
377f4a2713aSLionel Sambuc   return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0),
378f4a2713aSLionel Sambuc                      N->getOperand(1));
379f4a2713aSLionel Sambuc }
380f4a2713aSLionel Sambuc 
PromoteIntRes_FP_TO_XINT(SDNode * N)381f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
382f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
383f4a2713aSLionel Sambuc   unsigned NewOpc = N->getOpcode();
384f4a2713aSLionel Sambuc   SDLoc dl(N);
385f4a2713aSLionel Sambuc 
386f4a2713aSLionel Sambuc   // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is
387f4a2713aSLionel Sambuc   // not Legal, check to see if we can use FP_TO_SINT instead.  (If both UINT
388f4a2713aSLionel Sambuc   // and SINT conversions are Custom, there is no way to tell which is
389f4a2713aSLionel Sambuc   // preferable. We choose SINT because that's the right thing on PPC.)
390f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::FP_TO_UINT &&
391f4a2713aSLionel Sambuc       !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
392f4a2713aSLionel Sambuc       TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
393f4a2713aSLionel Sambuc     NewOpc = ISD::FP_TO_SINT;
394f4a2713aSLionel Sambuc 
395f4a2713aSLionel Sambuc   SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0));
396f4a2713aSLionel Sambuc 
397f4a2713aSLionel Sambuc   // Assert that the converted value fits in the original type.  If it doesn't
398f4a2713aSLionel Sambuc   // (eg: because the value being converted is too big), then the result of the
399f4a2713aSLionel Sambuc   // original operation was undefined anyway, so the assert is still correct.
400f4a2713aSLionel Sambuc   return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ?
401f4a2713aSLionel Sambuc                      ISD::AssertZext : ISD::AssertSext, dl, NVT, Res,
402f4a2713aSLionel Sambuc                      DAG.getValueType(N->getValueType(0).getScalarType()));
403f4a2713aSLionel Sambuc }
404f4a2713aSLionel Sambuc 
PromoteIntRes_FP_TO_FP16(SDNode * N)405*0a6a1f1dSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_FP16(SDNode *N) {
406f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
407f4a2713aSLionel Sambuc   SDLoc dl(N);
408f4a2713aSLionel Sambuc 
409f4a2713aSLionel Sambuc   SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
410f4a2713aSLionel Sambuc 
411f4a2713aSLionel Sambuc   return DAG.getNode(ISD::AssertZext, dl,
412f4a2713aSLionel Sambuc                      NVT, Res, DAG.getValueType(N->getValueType(0)));
413f4a2713aSLionel Sambuc }
414f4a2713aSLionel Sambuc 
PromoteIntRes_INT_EXTEND(SDNode * N)415f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
416f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
417f4a2713aSLionel Sambuc   SDLoc dl(N);
418f4a2713aSLionel Sambuc 
419f4a2713aSLionel Sambuc   if (getTypeAction(N->getOperand(0).getValueType())
420f4a2713aSLionel Sambuc       == TargetLowering::TypePromoteInteger) {
421f4a2713aSLionel Sambuc     SDValue Res = GetPromotedInteger(N->getOperand(0));
422f4a2713aSLionel Sambuc     assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!");
423f4a2713aSLionel Sambuc 
424f4a2713aSLionel Sambuc     // If the result and operand types are the same after promotion, simplify
425f4a2713aSLionel Sambuc     // to an in-register extension.
426f4a2713aSLionel Sambuc     if (NVT == Res.getValueType()) {
427f4a2713aSLionel Sambuc       // The high bits are not guaranteed to be anything.  Insert an extend.
428f4a2713aSLionel Sambuc       if (N->getOpcode() == ISD::SIGN_EXTEND)
429f4a2713aSLionel Sambuc         return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
430f4a2713aSLionel Sambuc                            DAG.getValueType(N->getOperand(0).getValueType()));
431f4a2713aSLionel Sambuc       if (N->getOpcode() == ISD::ZERO_EXTEND)
432f4a2713aSLionel Sambuc         return DAG.getZeroExtendInReg(Res, dl,
433f4a2713aSLionel Sambuc                       N->getOperand(0).getValueType().getScalarType());
434f4a2713aSLionel Sambuc       assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
435f4a2713aSLionel Sambuc       return Res;
436f4a2713aSLionel Sambuc     }
437f4a2713aSLionel Sambuc   }
438f4a2713aSLionel Sambuc 
439f4a2713aSLionel Sambuc   // Otherwise, just extend the original operand all the way to the larger type.
440f4a2713aSLionel Sambuc   return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
441f4a2713aSLionel Sambuc }
442f4a2713aSLionel Sambuc 
PromoteIntRes_LOAD(LoadSDNode * N)443f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
444f4a2713aSLionel Sambuc   assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
445f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
446f4a2713aSLionel Sambuc   ISD::LoadExtType ExtType =
447f4a2713aSLionel Sambuc     ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
448f4a2713aSLionel Sambuc   SDLoc dl(N);
449f4a2713aSLionel Sambuc   SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
450f4a2713aSLionel Sambuc                                N->getMemoryVT(), N->getMemOperand());
451f4a2713aSLionel Sambuc 
452f4a2713aSLionel Sambuc   // Legalized the chain result - switch anything that used the old chain to
453f4a2713aSLionel Sambuc   // use the new one.
454f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
455f4a2713aSLionel Sambuc   return Res;
456f4a2713aSLionel Sambuc }
457f4a2713aSLionel Sambuc 
PromoteIntRes_MLOAD(MaskedLoadSDNode * N)458*0a6a1f1dSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_MLOAD(MaskedLoadSDNode *N) {
459*0a6a1f1dSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
460*0a6a1f1dSLionel Sambuc   SDValue ExtSrc0 = GetPromotedInteger(N->getSrc0());
461*0a6a1f1dSLionel Sambuc 
462*0a6a1f1dSLionel Sambuc   SDValue Mask = N->getMask();
463*0a6a1f1dSLionel Sambuc   EVT NewMaskVT = getSetCCResultType(NVT);
464*0a6a1f1dSLionel Sambuc   if (NewMaskVT != N->getMask().getValueType())
465*0a6a1f1dSLionel Sambuc     Mask = PromoteTargetBoolean(Mask, NewMaskVT);
466*0a6a1f1dSLionel Sambuc   SDLoc dl(N);
467*0a6a1f1dSLionel Sambuc 
468*0a6a1f1dSLionel Sambuc   SDValue Res = DAG.getMaskedLoad(NVT, dl, N->getChain(), N->getBasePtr(),
469*0a6a1f1dSLionel Sambuc                                   Mask, ExtSrc0, N->getMemoryVT(),
470*0a6a1f1dSLionel Sambuc                                   N->getMemOperand(), ISD::SEXTLOAD);
471*0a6a1f1dSLionel Sambuc   // Legalized the chain result - switch anything that used the old chain to
472*0a6a1f1dSLionel Sambuc   // use the new one.
473*0a6a1f1dSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
474*0a6a1f1dSLionel Sambuc   return Res;
475*0a6a1f1dSLionel Sambuc }
476f4a2713aSLionel Sambuc /// Promote the overflow flag of an overflowing arithmetic node.
PromoteIntRes_Overflow(SDNode * N)477f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
478f4a2713aSLionel Sambuc   // Simply change the return type of the boolean result.
479f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1));
480f4a2713aSLionel Sambuc   EVT ValueVTs[] = { N->getValueType(0), NVT };
481f4a2713aSLionel Sambuc   SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
482f4a2713aSLionel Sambuc   SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N),
483*0a6a1f1dSLionel Sambuc                             DAG.getVTList(ValueVTs), Ops);
484f4a2713aSLionel Sambuc 
485f4a2713aSLionel Sambuc   // Modified the sum result - switch anything that used the old sum to use
486f4a2713aSLionel Sambuc   // the new one.
487f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 0), Res);
488f4a2713aSLionel Sambuc 
489f4a2713aSLionel Sambuc   return SDValue(Res.getNode(), 1);
490f4a2713aSLionel Sambuc }
491f4a2713aSLionel Sambuc 
PromoteIntRes_SADDSUBO(SDNode * N,unsigned ResNo)492f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
493f4a2713aSLionel Sambuc   if (ResNo == 1)
494f4a2713aSLionel Sambuc     return PromoteIntRes_Overflow(N);
495f4a2713aSLionel Sambuc 
496f4a2713aSLionel Sambuc   // The operation overflowed iff the result in the larger type is not the
497f4a2713aSLionel Sambuc   // sign extension of its truncation to the original type.
498f4a2713aSLionel Sambuc   SDValue LHS = SExtPromotedInteger(N->getOperand(0));
499f4a2713aSLionel Sambuc   SDValue RHS = SExtPromotedInteger(N->getOperand(1));
500f4a2713aSLionel Sambuc   EVT OVT = N->getOperand(0).getValueType();
501f4a2713aSLionel Sambuc   EVT NVT = LHS.getValueType();
502f4a2713aSLionel Sambuc   SDLoc dl(N);
503f4a2713aSLionel Sambuc 
504f4a2713aSLionel Sambuc   // Do the arithmetic in the larger type.
505f4a2713aSLionel Sambuc   unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB;
506f4a2713aSLionel Sambuc   SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
507f4a2713aSLionel Sambuc 
508f4a2713aSLionel Sambuc   // Calculate the overflow flag: sign extend the arithmetic result from
509f4a2713aSLionel Sambuc   // the original type.
510f4a2713aSLionel Sambuc   SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
511f4a2713aSLionel Sambuc                             DAG.getValueType(OVT));
512f4a2713aSLionel Sambuc   // Overflowed if and only if this is not equal to Res.
513f4a2713aSLionel Sambuc   Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
514f4a2713aSLionel Sambuc 
515f4a2713aSLionel Sambuc   // Use the calculated overflow everywhere.
516f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Ofl);
517f4a2713aSLionel Sambuc 
518f4a2713aSLionel Sambuc   return Res;
519f4a2713aSLionel Sambuc }
520f4a2713aSLionel Sambuc 
PromoteIntRes_SDIV(SDNode * N)521f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
522f4a2713aSLionel Sambuc   // Sign extend the input.
523f4a2713aSLionel Sambuc   SDValue LHS = SExtPromotedInteger(N->getOperand(0));
524f4a2713aSLionel Sambuc   SDValue RHS = SExtPromotedInteger(N->getOperand(1));
525f4a2713aSLionel Sambuc   return DAG.getNode(N->getOpcode(), SDLoc(N),
526f4a2713aSLionel Sambuc                      LHS.getValueType(), LHS, RHS);
527f4a2713aSLionel Sambuc }
528f4a2713aSLionel Sambuc 
PromoteIntRes_SELECT(SDNode * N)529f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) {
530f4a2713aSLionel Sambuc   SDValue LHS = GetPromotedInteger(N->getOperand(1));
531f4a2713aSLionel Sambuc   SDValue RHS = GetPromotedInteger(N->getOperand(2));
532f4a2713aSLionel Sambuc   return DAG.getSelect(SDLoc(N),
533f4a2713aSLionel Sambuc                        LHS.getValueType(), N->getOperand(0), LHS, RHS);
534f4a2713aSLionel Sambuc }
535f4a2713aSLionel Sambuc 
PromoteIntRes_VSELECT(SDNode * N)536f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_VSELECT(SDNode *N) {
537f4a2713aSLionel Sambuc   SDValue Mask = N->getOperand(0);
538f4a2713aSLionel Sambuc   EVT OpTy = N->getOperand(1).getValueType();
539f4a2713aSLionel Sambuc 
540f4a2713aSLionel Sambuc   // Promote all the way up to the canonical SetCC type.
541*0a6a1f1dSLionel Sambuc   Mask = PromoteTargetBoolean(Mask, OpTy);
542f4a2713aSLionel Sambuc   SDValue LHS = GetPromotedInteger(N->getOperand(1));
543f4a2713aSLionel Sambuc   SDValue RHS = GetPromotedInteger(N->getOperand(2));
544f4a2713aSLionel Sambuc   return DAG.getNode(ISD::VSELECT, SDLoc(N),
545f4a2713aSLionel Sambuc                      LHS.getValueType(), Mask, LHS, RHS);
546f4a2713aSLionel Sambuc }
547f4a2713aSLionel Sambuc 
PromoteIntRes_SELECT_CC(SDNode * N)548f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
549f4a2713aSLionel Sambuc   SDValue LHS = GetPromotedInteger(N->getOperand(2));
550f4a2713aSLionel Sambuc   SDValue RHS = GetPromotedInteger(N->getOperand(3));
551f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SELECT_CC, SDLoc(N),
552f4a2713aSLionel Sambuc                      LHS.getValueType(), N->getOperand(0),
553f4a2713aSLionel Sambuc                      N->getOperand(1), LHS, RHS, N->getOperand(4));
554f4a2713aSLionel Sambuc }
555f4a2713aSLionel Sambuc 
PromoteIntRes_SETCC(SDNode * N)556f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
557f4a2713aSLionel Sambuc   EVT SVT = getSetCCResultType(N->getOperand(0).getValueType());
558f4a2713aSLionel Sambuc 
559f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
560f4a2713aSLionel Sambuc 
561f4a2713aSLionel Sambuc   // Only use the result of getSetCCResultType if it is legal,
562f4a2713aSLionel Sambuc   // otherwise just use the promoted result type (NVT).
563f4a2713aSLionel Sambuc   if (!TLI.isTypeLegal(SVT))
564f4a2713aSLionel Sambuc     SVT = NVT;
565f4a2713aSLionel Sambuc 
566f4a2713aSLionel Sambuc   SDLoc dl(N);
567f4a2713aSLionel Sambuc   assert(SVT.isVector() == N->getOperand(0).getValueType().isVector() &&
568f4a2713aSLionel Sambuc          "Vector compare must return a vector result!");
569f4a2713aSLionel Sambuc 
570f4a2713aSLionel Sambuc   SDValue LHS = N->getOperand(0);
571f4a2713aSLionel Sambuc   SDValue RHS = N->getOperand(1);
572f4a2713aSLionel Sambuc   if (LHS.getValueType() != RHS.getValueType()) {
573f4a2713aSLionel Sambuc     if (getTypeAction(LHS.getValueType()) == TargetLowering::TypePromoteInteger &&
574f4a2713aSLionel Sambuc         !LHS.getValueType().isVector())
575f4a2713aSLionel Sambuc       LHS = GetPromotedInteger(LHS);
576f4a2713aSLionel Sambuc     if (getTypeAction(RHS.getValueType()) == TargetLowering::TypePromoteInteger &&
577f4a2713aSLionel Sambuc         !RHS.getValueType().isVector())
578f4a2713aSLionel Sambuc       RHS = GetPromotedInteger(RHS);
579f4a2713aSLionel Sambuc   }
580f4a2713aSLionel Sambuc 
581f4a2713aSLionel Sambuc   // Get the SETCC result using the canonical SETCC type.
582f4a2713aSLionel Sambuc   SDValue SetCC = DAG.getNode(N->getOpcode(), dl, SVT, LHS, RHS,
583f4a2713aSLionel Sambuc                               N->getOperand(2));
584f4a2713aSLionel Sambuc 
585f4a2713aSLionel Sambuc   assert(NVT.bitsLE(SVT) && "Integer type overpromoted?");
586f4a2713aSLionel Sambuc   // Convert to the expected type.
587f4a2713aSLionel Sambuc   return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC);
588f4a2713aSLionel Sambuc }
589f4a2713aSLionel Sambuc 
PromoteIntRes_SHL(SDNode * N)590f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
591f4a2713aSLionel Sambuc   SDValue Res = GetPromotedInteger(N->getOperand(0));
592f4a2713aSLionel Sambuc   SDValue Amt = N->getOperand(1);
593f4a2713aSLionel Sambuc   Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt;
594f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SHL, SDLoc(N), Res.getValueType(), Res, Amt);
595f4a2713aSLionel Sambuc }
596f4a2713aSLionel Sambuc 
PromoteIntRes_SIGN_EXTEND_INREG(SDNode * N)597f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) {
598f4a2713aSLionel Sambuc   SDValue Op = GetPromotedInteger(N->getOperand(0));
599f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N),
600f4a2713aSLionel Sambuc                      Op.getValueType(), Op, N->getOperand(1));
601f4a2713aSLionel Sambuc }
602f4a2713aSLionel Sambuc 
PromoteIntRes_SimpleIntBinOp(SDNode * N)603f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
604f4a2713aSLionel Sambuc   // The input may have strange things in the top bits of the registers, but
605f4a2713aSLionel Sambuc   // these operations don't care.  They may have weird bits going out, but
606f4a2713aSLionel Sambuc   // that too is okay if they are integer operations.
607f4a2713aSLionel Sambuc   SDValue LHS = GetPromotedInteger(N->getOperand(0));
608f4a2713aSLionel Sambuc   SDValue RHS = GetPromotedInteger(N->getOperand(1));
609f4a2713aSLionel Sambuc   return DAG.getNode(N->getOpcode(), SDLoc(N),
610f4a2713aSLionel Sambuc                      LHS.getValueType(), LHS, RHS);
611f4a2713aSLionel Sambuc }
612f4a2713aSLionel Sambuc 
PromoteIntRes_SRA(SDNode * N)613f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
614f4a2713aSLionel Sambuc   // The input value must be properly sign extended.
615f4a2713aSLionel Sambuc   SDValue Res = SExtPromotedInteger(N->getOperand(0));
616f4a2713aSLionel Sambuc   SDValue Amt = N->getOperand(1);
617f4a2713aSLionel Sambuc   Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt;
618f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SRA, SDLoc(N), Res.getValueType(), Res, Amt);
619f4a2713aSLionel Sambuc }
620f4a2713aSLionel Sambuc 
PromoteIntRes_SRL(SDNode * N)621f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
622f4a2713aSLionel Sambuc   // The input value must be properly zero extended.
623f4a2713aSLionel Sambuc   SDValue Res = ZExtPromotedInteger(N->getOperand(0));
624f4a2713aSLionel Sambuc   SDValue Amt = N->getOperand(1);
625f4a2713aSLionel Sambuc   Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt;
626f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SRL, SDLoc(N), Res.getValueType(), Res, Amt);
627f4a2713aSLionel Sambuc }
628f4a2713aSLionel Sambuc 
PromoteIntRes_TRUNCATE(SDNode * N)629f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
630f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
631f4a2713aSLionel Sambuc   SDValue Res;
632f4a2713aSLionel Sambuc   SDValue InOp = N->getOperand(0);
633f4a2713aSLionel Sambuc   SDLoc dl(N);
634f4a2713aSLionel Sambuc 
635f4a2713aSLionel Sambuc   switch (getTypeAction(InOp.getValueType())) {
636f4a2713aSLionel Sambuc   default: llvm_unreachable("Unknown type action!");
637f4a2713aSLionel Sambuc   case TargetLowering::TypeLegal:
638f4a2713aSLionel Sambuc   case TargetLowering::TypeExpandInteger:
639f4a2713aSLionel Sambuc     Res = InOp;
640f4a2713aSLionel Sambuc     break;
641f4a2713aSLionel Sambuc   case TargetLowering::TypePromoteInteger:
642f4a2713aSLionel Sambuc     Res = GetPromotedInteger(InOp);
643f4a2713aSLionel Sambuc     break;
644f4a2713aSLionel Sambuc   case TargetLowering::TypeSplitVector:
645f4a2713aSLionel Sambuc     EVT InVT = InOp.getValueType();
646f4a2713aSLionel Sambuc     assert(InVT.isVector() && "Cannot split scalar types");
647f4a2713aSLionel Sambuc     unsigned NumElts = InVT.getVectorNumElements();
648f4a2713aSLionel Sambuc     assert(NumElts == NVT.getVectorNumElements() &&
649f4a2713aSLionel Sambuc            "Dst and Src must have the same number of elements");
650f4a2713aSLionel Sambuc     assert(isPowerOf2_32(NumElts) &&
651f4a2713aSLionel Sambuc            "Promoted vector type must be a power of two");
652f4a2713aSLionel Sambuc 
653f4a2713aSLionel Sambuc     SDValue EOp1, EOp2;
654f4a2713aSLionel Sambuc     GetSplitVector(InOp, EOp1, EOp2);
655f4a2713aSLionel Sambuc 
656f4a2713aSLionel Sambuc     EVT HalfNVT = EVT::getVectorVT(*DAG.getContext(), NVT.getScalarType(),
657f4a2713aSLionel Sambuc                                    NumElts/2);
658f4a2713aSLionel Sambuc     EOp1 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp1);
659f4a2713aSLionel Sambuc     EOp2 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp2);
660f4a2713aSLionel Sambuc 
661f4a2713aSLionel Sambuc     return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, EOp1, EOp2);
662f4a2713aSLionel Sambuc   }
663f4a2713aSLionel Sambuc 
664f4a2713aSLionel Sambuc   // Truncate to NVT instead of VT
665f4a2713aSLionel Sambuc   return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res);
666f4a2713aSLionel Sambuc }
667f4a2713aSLionel Sambuc 
PromoteIntRes_UADDSUBO(SDNode * N,unsigned ResNo)668f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
669f4a2713aSLionel Sambuc   if (ResNo == 1)
670f4a2713aSLionel Sambuc     return PromoteIntRes_Overflow(N);
671f4a2713aSLionel Sambuc 
672f4a2713aSLionel Sambuc   // The operation overflowed iff the result in the larger type is not the
673f4a2713aSLionel Sambuc   // zero extension of its truncation to the original type.
674f4a2713aSLionel Sambuc   SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
675f4a2713aSLionel Sambuc   SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
676f4a2713aSLionel Sambuc   EVT OVT = N->getOperand(0).getValueType();
677f4a2713aSLionel Sambuc   EVT NVT = LHS.getValueType();
678f4a2713aSLionel Sambuc   SDLoc dl(N);
679f4a2713aSLionel Sambuc 
680f4a2713aSLionel Sambuc   // Do the arithmetic in the larger type.
681f4a2713aSLionel Sambuc   unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB;
682f4a2713aSLionel Sambuc   SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
683f4a2713aSLionel Sambuc 
684f4a2713aSLionel Sambuc   // Calculate the overflow flag: zero extend the arithmetic result from
685f4a2713aSLionel Sambuc   // the original type.
686f4a2713aSLionel Sambuc   SDValue Ofl = DAG.getZeroExtendInReg(Res, dl, OVT);
687f4a2713aSLionel Sambuc   // Overflowed if and only if this is not equal to Res.
688f4a2713aSLionel Sambuc   Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
689f4a2713aSLionel Sambuc 
690f4a2713aSLionel Sambuc   // Use the calculated overflow everywhere.
691f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Ofl);
692f4a2713aSLionel Sambuc 
693f4a2713aSLionel Sambuc   return Res;
694f4a2713aSLionel Sambuc }
695f4a2713aSLionel Sambuc 
PromoteIntRes_XMULO(SDNode * N,unsigned ResNo)696f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
697f4a2713aSLionel Sambuc   // Promote the overflow bit trivially.
698f4a2713aSLionel Sambuc   if (ResNo == 1)
699f4a2713aSLionel Sambuc     return PromoteIntRes_Overflow(N);
700f4a2713aSLionel Sambuc 
701f4a2713aSLionel Sambuc   SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
702f4a2713aSLionel Sambuc   SDLoc DL(N);
703f4a2713aSLionel Sambuc   EVT SmallVT = LHS.getValueType();
704f4a2713aSLionel Sambuc 
705f4a2713aSLionel Sambuc   // To determine if the result overflowed in a larger type, we extend the
706f4a2713aSLionel Sambuc   // input to the larger type, do the multiply (checking if it overflows),
707f4a2713aSLionel Sambuc   // then also check the high bits of the result to see if overflow happened
708f4a2713aSLionel Sambuc   // there.
709f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::SMULO) {
710f4a2713aSLionel Sambuc     LHS = SExtPromotedInteger(LHS);
711f4a2713aSLionel Sambuc     RHS = SExtPromotedInteger(RHS);
712f4a2713aSLionel Sambuc   } else {
713f4a2713aSLionel Sambuc     LHS = ZExtPromotedInteger(LHS);
714f4a2713aSLionel Sambuc     RHS = ZExtPromotedInteger(RHS);
715f4a2713aSLionel Sambuc   }
716f4a2713aSLionel Sambuc   SDVTList VTs = DAG.getVTList(LHS.getValueType(), N->getValueType(1));
717f4a2713aSLionel Sambuc   SDValue Mul = DAG.getNode(N->getOpcode(), DL, VTs, LHS, RHS);
718f4a2713aSLionel Sambuc 
719f4a2713aSLionel Sambuc   // Overflow occurred if it occurred in the larger type, or if the high part
720f4a2713aSLionel Sambuc   // of the result does not zero/sign-extend the low part.  Check this second
721f4a2713aSLionel Sambuc   // possibility first.
722f4a2713aSLionel Sambuc   SDValue Overflow;
723f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::UMULO) {
724f4a2713aSLionel Sambuc     // Unsigned overflow occurred if the high part is non-zero.
725f4a2713aSLionel Sambuc     SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
726f4a2713aSLionel Sambuc                              DAG.getIntPtrConstant(SmallVT.getSizeInBits()));
727f4a2713aSLionel Sambuc     Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
728f4a2713aSLionel Sambuc                             DAG.getConstant(0, Hi.getValueType()), ISD::SETNE);
729f4a2713aSLionel Sambuc   } else {
730f4a2713aSLionel Sambuc     // Signed overflow occurred if the high part does not sign extend the low.
731f4a2713aSLionel Sambuc     SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(),
732f4a2713aSLionel Sambuc                                Mul, DAG.getValueType(SmallVT));
733f4a2713aSLionel Sambuc     Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE);
734f4a2713aSLionel Sambuc   }
735f4a2713aSLionel Sambuc 
736f4a2713aSLionel Sambuc   // The only other way for overflow to occur is if the multiplication in the
737f4a2713aSLionel Sambuc   // larger type itself overflowed.
738f4a2713aSLionel Sambuc   Overflow = DAG.getNode(ISD::OR, DL, N->getValueType(1), Overflow,
739f4a2713aSLionel Sambuc                          SDValue(Mul.getNode(), 1));
740f4a2713aSLionel Sambuc 
741f4a2713aSLionel Sambuc   // Use the calculated overflow everywhere.
742f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Overflow);
743f4a2713aSLionel Sambuc   return Mul;
744f4a2713aSLionel Sambuc }
745f4a2713aSLionel Sambuc 
PromoteIntRes_UDIV(SDNode * N)746f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
747f4a2713aSLionel Sambuc   // Zero extend the input.
748f4a2713aSLionel Sambuc   SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
749f4a2713aSLionel Sambuc   SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
750f4a2713aSLionel Sambuc   return DAG.getNode(N->getOpcode(), SDLoc(N),
751f4a2713aSLionel Sambuc                      LHS.getValueType(), LHS, RHS);
752f4a2713aSLionel Sambuc }
753f4a2713aSLionel Sambuc 
PromoteIntRes_UNDEF(SDNode * N)754f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
755f4a2713aSLionel Sambuc   return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
756f4a2713aSLionel Sambuc                                                N->getValueType(0)));
757f4a2713aSLionel Sambuc }
758f4a2713aSLionel Sambuc 
PromoteIntRes_VAARG(SDNode * N)759f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
760f4a2713aSLionel Sambuc   SDValue Chain = N->getOperand(0); // Get the chain.
761f4a2713aSLionel Sambuc   SDValue Ptr = N->getOperand(1); // Get the pointer.
762f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
763f4a2713aSLionel Sambuc   SDLoc dl(N);
764f4a2713aSLionel Sambuc 
765f4a2713aSLionel Sambuc   MVT RegVT = TLI.getRegisterType(*DAG.getContext(), VT);
766f4a2713aSLionel Sambuc   unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), VT);
767f4a2713aSLionel Sambuc   // The argument is passed as NumRegs registers of type RegVT.
768f4a2713aSLionel Sambuc 
769f4a2713aSLionel Sambuc   SmallVector<SDValue, 8> Parts(NumRegs);
770f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumRegs; ++i) {
771f4a2713aSLionel Sambuc     Parts[i] = DAG.getVAArg(RegVT, dl, Chain, Ptr, N->getOperand(2),
772f4a2713aSLionel Sambuc                             N->getConstantOperandVal(3));
773f4a2713aSLionel Sambuc     Chain = Parts[i].getValue(1);
774f4a2713aSLionel Sambuc   }
775f4a2713aSLionel Sambuc 
776f4a2713aSLionel Sambuc   // Handle endianness of the load.
777f4a2713aSLionel Sambuc   if (TLI.isBigEndian())
778f4a2713aSLionel Sambuc     std::reverse(Parts.begin(), Parts.end());
779f4a2713aSLionel Sambuc 
780f4a2713aSLionel Sambuc   // Assemble the parts in the promoted type.
781f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
782f4a2713aSLionel Sambuc   SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]);
783f4a2713aSLionel Sambuc   for (unsigned i = 1; i < NumRegs; ++i) {
784f4a2713aSLionel Sambuc     SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]);
785f4a2713aSLionel Sambuc     // Shift it to the right position and "or" it in.
786f4a2713aSLionel Sambuc     Part = DAG.getNode(ISD::SHL, dl, NVT, Part,
787f4a2713aSLionel Sambuc                        DAG.getConstant(i * RegVT.getSizeInBits(),
788f4a2713aSLionel Sambuc                                        TLI.getPointerTy()));
789f4a2713aSLionel Sambuc     Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part);
790f4a2713aSLionel Sambuc   }
791f4a2713aSLionel Sambuc 
792f4a2713aSLionel Sambuc   // Modified the chain result - switch anything that used the old chain to
793f4a2713aSLionel Sambuc   // use the new one.
794f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Chain);
795f4a2713aSLionel Sambuc 
796f4a2713aSLionel Sambuc   return Res;
797f4a2713aSLionel Sambuc }
798f4a2713aSLionel Sambuc 
799f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
800f4a2713aSLionel Sambuc //  Integer Operand Promotion
801f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
802f4a2713aSLionel Sambuc 
803f4a2713aSLionel Sambuc /// PromoteIntegerOperand - This method is called when the specified operand of
804f4a2713aSLionel Sambuc /// the specified node is found to need promotion.  At this point, all of the
805f4a2713aSLionel Sambuc /// result types of the node are known to be legal, but other operands of the
806f4a2713aSLionel Sambuc /// node may need promotion or expansion as well as the specified one.
PromoteIntegerOperand(SDNode * N,unsigned OpNo)807f4a2713aSLionel Sambuc bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
808f4a2713aSLionel Sambuc   DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG); dbgs() << "\n");
809f4a2713aSLionel Sambuc   SDValue Res = SDValue();
810f4a2713aSLionel Sambuc 
811f4a2713aSLionel Sambuc   if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
812f4a2713aSLionel Sambuc     return false;
813f4a2713aSLionel Sambuc 
814f4a2713aSLionel Sambuc   switch (N->getOpcode()) {
815f4a2713aSLionel Sambuc     default:
816f4a2713aSLionel Sambuc   #ifndef NDEBUG
817f4a2713aSLionel Sambuc     dbgs() << "PromoteIntegerOperand Op #" << OpNo << ": ";
818f4a2713aSLionel Sambuc     N->dump(&DAG); dbgs() << "\n";
819f4a2713aSLionel Sambuc   #endif
820f4a2713aSLionel Sambuc     llvm_unreachable("Do not know how to promote this operator's operand!");
821f4a2713aSLionel Sambuc 
822f4a2713aSLionel Sambuc   case ISD::ANY_EXTEND:   Res = PromoteIntOp_ANY_EXTEND(N); break;
823f4a2713aSLionel Sambuc   case ISD::ATOMIC_STORE:
824f4a2713aSLionel Sambuc     Res = PromoteIntOp_ATOMIC_STORE(cast<AtomicSDNode>(N));
825f4a2713aSLionel Sambuc     break;
826f4a2713aSLionel Sambuc   case ISD::BITCAST:      Res = PromoteIntOp_BITCAST(N); break;
827f4a2713aSLionel Sambuc   case ISD::BR_CC:        Res = PromoteIntOp_BR_CC(N, OpNo); break;
828f4a2713aSLionel Sambuc   case ISD::BRCOND:       Res = PromoteIntOp_BRCOND(N, OpNo); break;
829f4a2713aSLionel Sambuc   case ISD::BUILD_PAIR:   Res = PromoteIntOp_BUILD_PAIR(N); break;
830f4a2713aSLionel Sambuc   case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
831f4a2713aSLionel Sambuc   case ISD::CONCAT_VECTORS: Res = PromoteIntOp_CONCAT_VECTORS(N); break;
832f4a2713aSLionel Sambuc   case ISD::EXTRACT_VECTOR_ELT: Res = PromoteIntOp_EXTRACT_VECTOR_ELT(N); break;
833f4a2713aSLionel Sambuc   case ISD::CONVERT_RNDSAT:
834f4a2713aSLionel Sambuc                           Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
835f4a2713aSLionel Sambuc   case ISD::INSERT_VECTOR_ELT:
836f4a2713aSLionel Sambuc                           Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break;
837f4a2713aSLionel Sambuc   case ISD::SCALAR_TO_VECTOR:
838f4a2713aSLionel Sambuc                           Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break;
839f4a2713aSLionel Sambuc   case ISD::VSELECT:
840f4a2713aSLionel Sambuc   case ISD::SELECT:       Res = PromoteIntOp_SELECT(N, OpNo); break;
841f4a2713aSLionel Sambuc   case ISD::SELECT_CC:    Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
842f4a2713aSLionel Sambuc   case ISD::SETCC:        Res = PromoteIntOp_SETCC(N, OpNo); break;
843f4a2713aSLionel Sambuc   case ISD::SIGN_EXTEND:  Res = PromoteIntOp_SIGN_EXTEND(N); break;
844f4a2713aSLionel Sambuc   case ISD::SINT_TO_FP:   Res = PromoteIntOp_SINT_TO_FP(N); break;
845f4a2713aSLionel Sambuc   case ISD::STORE:        Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
846f4a2713aSLionel Sambuc                                                    OpNo); break;
847*0a6a1f1dSLionel Sambuc   case ISD::MSTORE:       Res = PromoteIntOp_MSTORE(cast<MaskedStoreSDNode>(N),
848*0a6a1f1dSLionel Sambuc                                                     OpNo); break;
849*0a6a1f1dSLionel Sambuc   case ISD::MLOAD:        Res = PromoteIntOp_MLOAD(cast<MaskedLoadSDNode>(N),
850*0a6a1f1dSLionel Sambuc                                                     OpNo); break;
851f4a2713aSLionel Sambuc   case ISD::TRUNCATE:     Res = PromoteIntOp_TRUNCATE(N); break;
852*0a6a1f1dSLionel Sambuc   case ISD::FP16_TO_FP:
853f4a2713aSLionel Sambuc   case ISD::UINT_TO_FP:   Res = PromoteIntOp_UINT_TO_FP(N); break;
854f4a2713aSLionel Sambuc   case ISD::ZERO_EXTEND:  Res = PromoteIntOp_ZERO_EXTEND(N); break;
855f4a2713aSLionel Sambuc 
856f4a2713aSLionel Sambuc   case ISD::SHL:
857f4a2713aSLionel Sambuc   case ISD::SRA:
858f4a2713aSLionel Sambuc   case ISD::SRL:
859f4a2713aSLionel Sambuc   case ISD::ROTL:
860f4a2713aSLionel Sambuc   case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
861f4a2713aSLionel Sambuc   }
862f4a2713aSLionel Sambuc 
863f4a2713aSLionel Sambuc   // If the result is null, the sub-method took care of registering results etc.
864f4a2713aSLionel Sambuc   if (!Res.getNode()) return false;
865f4a2713aSLionel Sambuc 
866f4a2713aSLionel Sambuc   // If the result is N, the sub-method updated N in place.  Tell the legalizer
867f4a2713aSLionel Sambuc   // core about this.
868f4a2713aSLionel Sambuc   if (Res.getNode() == N)
869f4a2713aSLionel Sambuc     return true;
870f4a2713aSLionel Sambuc 
871f4a2713aSLionel Sambuc   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
872f4a2713aSLionel Sambuc          "Invalid operand expansion");
873f4a2713aSLionel Sambuc 
874f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 0), Res);
875f4a2713aSLionel Sambuc   return false;
876f4a2713aSLionel Sambuc }
877f4a2713aSLionel Sambuc 
878f4a2713aSLionel Sambuc /// PromoteSetCCOperands - Promote the operands of a comparison.  This code is
879f4a2713aSLionel Sambuc /// shared among BR_CC, SELECT_CC, and SETCC handlers.
PromoteSetCCOperands(SDValue & NewLHS,SDValue & NewRHS,ISD::CondCode CCCode)880f4a2713aSLionel Sambuc void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
881f4a2713aSLionel Sambuc                                             ISD::CondCode CCCode) {
882f4a2713aSLionel Sambuc   // We have to insert explicit sign or zero extends.  Note that we could
883f4a2713aSLionel Sambuc   // insert sign extends for ALL conditions, but zero extend is cheaper on
884f4a2713aSLionel Sambuc   // many machines (an AND instead of two shifts), so prefer it.
885f4a2713aSLionel Sambuc   switch (CCCode) {
886f4a2713aSLionel Sambuc   default: llvm_unreachable("Unknown integer comparison!");
887f4a2713aSLionel Sambuc   case ISD::SETEQ:
888*0a6a1f1dSLionel Sambuc   case ISD::SETNE: {
889*0a6a1f1dSLionel Sambuc     SDValue OpL = GetPromotedInteger(NewLHS);
890*0a6a1f1dSLionel Sambuc     SDValue OpR = GetPromotedInteger(NewRHS);
891*0a6a1f1dSLionel Sambuc 
892*0a6a1f1dSLionel Sambuc     // We would prefer to promote the comparison operand with sign extension,
893*0a6a1f1dSLionel Sambuc     // if we find the operand is actually to truncate an AssertSext. With this
894*0a6a1f1dSLionel Sambuc     // optimization, we can avoid inserting real truncate instruction, which
895*0a6a1f1dSLionel Sambuc     // is redudant eventually.
896*0a6a1f1dSLionel Sambuc     if (OpL->getOpcode() == ISD::AssertSext &&
897*0a6a1f1dSLionel Sambuc         cast<VTSDNode>(OpL->getOperand(1))->getVT() == NewLHS.getValueType() &&
898*0a6a1f1dSLionel Sambuc         OpR->getOpcode() == ISD::AssertSext &&
899*0a6a1f1dSLionel Sambuc         cast<VTSDNode>(OpR->getOperand(1))->getVT() == NewRHS.getValueType()) {
900*0a6a1f1dSLionel Sambuc       NewLHS = OpL;
901*0a6a1f1dSLionel Sambuc       NewRHS = OpR;
902*0a6a1f1dSLionel Sambuc     } else {
903*0a6a1f1dSLionel Sambuc       NewLHS = ZExtPromotedInteger(NewLHS);
904*0a6a1f1dSLionel Sambuc       NewRHS = ZExtPromotedInteger(NewRHS);
905*0a6a1f1dSLionel Sambuc     }
906*0a6a1f1dSLionel Sambuc     break;
907*0a6a1f1dSLionel Sambuc   }
908f4a2713aSLionel Sambuc   case ISD::SETUGE:
909f4a2713aSLionel Sambuc   case ISD::SETUGT:
910f4a2713aSLionel Sambuc   case ISD::SETULE:
911f4a2713aSLionel Sambuc   case ISD::SETULT:
912f4a2713aSLionel Sambuc     // ALL of these operations will work if we either sign or zero extend
913f4a2713aSLionel Sambuc     // the operands (including the unsigned comparisons!).  Zero extend is
914f4a2713aSLionel Sambuc     // usually a simpler/cheaper operation, so prefer it.
915f4a2713aSLionel Sambuc     NewLHS = ZExtPromotedInteger(NewLHS);
916f4a2713aSLionel Sambuc     NewRHS = ZExtPromotedInteger(NewRHS);
917f4a2713aSLionel Sambuc     break;
918f4a2713aSLionel Sambuc   case ISD::SETGE:
919f4a2713aSLionel Sambuc   case ISD::SETGT:
920f4a2713aSLionel Sambuc   case ISD::SETLT:
921f4a2713aSLionel Sambuc   case ISD::SETLE:
922f4a2713aSLionel Sambuc     NewLHS = SExtPromotedInteger(NewLHS);
923f4a2713aSLionel Sambuc     NewRHS = SExtPromotedInteger(NewRHS);
924f4a2713aSLionel Sambuc     break;
925f4a2713aSLionel Sambuc   }
926f4a2713aSLionel Sambuc }
927f4a2713aSLionel Sambuc 
PromoteIntOp_ANY_EXTEND(SDNode * N)928f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
929f4a2713aSLionel Sambuc   SDValue Op = GetPromotedInteger(N->getOperand(0));
930f4a2713aSLionel Sambuc   return DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0), Op);
931f4a2713aSLionel Sambuc }
932f4a2713aSLionel Sambuc 
PromoteIntOp_ATOMIC_STORE(AtomicSDNode * N)933f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N) {
934f4a2713aSLionel Sambuc   SDValue Op2 = GetPromotedInteger(N->getOperand(2));
935f4a2713aSLionel Sambuc   return DAG.getAtomic(N->getOpcode(), SDLoc(N), N->getMemoryVT(),
936f4a2713aSLionel Sambuc                        N->getChain(), N->getBasePtr(), Op2, N->getMemOperand(),
937f4a2713aSLionel Sambuc                        N->getOrdering(), N->getSynchScope());
938f4a2713aSLionel Sambuc }
939f4a2713aSLionel Sambuc 
PromoteIntOp_BITCAST(SDNode * N)940f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_BITCAST(SDNode *N) {
941f4a2713aSLionel Sambuc   // This should only occur in unusual situations like bitcasting to an
942f4a2713aSLionel Sambuc   // x86_fp80, so just turn it into a store+load
943f4a2713aSLionel Sambuc   return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
944f4a2713aSLionel Sambuc }
945f4a2713aSLionel Sambuc 
PromoteIntOp_BR_CC(SDNode * N,unsigned OpNo)946f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
947f4a2713aSLionel Sambuc   assert(OpNo == 2 && "Don't know how to promote this operand!");
948f4a2713aSLionel Sambuc 
949f4a2713aSLionel Sambuc   SDValue LHS = N->getOperand(2);
950f4a2713aSLionel Sambuc   SDValue RHS = N->getOperand(3);
951f4a2713aSLionel Sambuc   PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
952f4a2713aSLionel Sambuc 
953f4a2713aSLionel Sambuc   // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
954f4a2713aSLionel Sambuc   // legal types.
955f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
956f4a2713aSLionel Sambuc                                 N->getOperand(1), LHS, RHS, N->getOperand(4)),
957f4a2713aSLionel Sambuc                  0);
958f4a2713aSLionel Sambuc }
959f4a2713aSLionel Sambuc 
PromoteIntOp_BRCOND(SDNode * N,unsigned OpNo)960f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
961f4a2713aSLionel Sambuc   assert(OpNo == 1 && "only know how to promote condition");
962f4a2713aSLionel Sambuc 
963f4a2713aSLionel Sambuc   // Promote all the way up to the canonical SetCC type.
964*0a6a1f1dSLionel Sambuc   SDValue Cond = PromoteTargetBoolean(N->getOperand(1), MVT::Other);
965f4a2713aSLionel Sambuc 
966f4a2713aSLionel Sambuc   // The chain (Op#0) and basic block destination (Op#2) are always legal types.
967f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Cond,
968f4a2713aSLionel Sambuc                                         N->getOperand(2)), 0);
969f4a2713aSLionel Sambuc }
970f4a2713aSLionel Sambuc 
PromoteIntOp_BUILD_PAIR(SDNode * N)971f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
972f4a2713aSLionel Sambuc   // Since the result type is legal, the operands must promote to it.
973f4a2713aSLionel Sambuc   EVT OVT = N->getOperand(0).getValueType();
974f4a2713aSLionel Sambuc   SDValue Lo = ZExtPromotedInteger(N->getOperand(0));
975f4a2713aSLionel Sambuc   SDValue Hi = GetPromotedInteger(N->getOperand(1));
976f4a2713aSLionel Sambuc   assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
977f4a2713aSLionel Sambuc   SDLoc dl(N);
978f4a2713aSLionel Sambuc 
979f4a2713aSLionel Sambuc   Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi,
980f4a2713aSLionel Sambuc                    DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy()));
981f4a2713aSLionel Sambuc   return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi);
982f4a2713aSLionel Sambuc }
983f4a2713aSLionel Sambuc 
PromoteIntOp_BUILD_VECTOR(SDNode * N)984f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
985f4a2713aSLionel Sambuc   // The vector type is legal but the element type is not.  This implies
986f4a2713aSLionel Sambuc   // that the vector is a power-of-two in length and that the element
987f4a2713aSLionel Sambuc   // type does not have a strange size (eg: it is not i1).
988f4a2713aSLionel Sambuc   EVT VecVT = N->getValueType(0);
989f4a2713aSLionel Sambuc   unsigned NumElts = VecVT.getVectorNumElements();
990f4a2713aSLionel Sambuc   assert(!((NumElts & 1) && (!TLI.isTypeLegal(VecVT))) &&
991f4a2713aSLionel Sambuc          "Legal vector of one illegal element?");
992f4a2713aSLionel Sambuc 
993f4a2713aSLionel Sambuc   // Promote the inserted value.  The type does not need to match the
994f4a2713aSLionel Sambuc   // vector element type.  Check that any extra bits introduced will be
995f4a2713aSLionel Sambuc   // truncated away.
996f4a2713aSLionel Sambuc   assert(N->getOperand(0).getValueType().getSizeInBits() >=
997f4a2713aSLionel Sambuc          N->getValueType(0).getVectorElementType().getSizeInBits() &&
998f4a2713aSLionel Sambuc          "Type of inserted value narrower than vector element type!");
999f4a2713aSLionel Sambuc 
1000f4a2713aSLionel Sambuc   SmallVector<SDValue, 16> NewOps;
1001f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumElts; ++i)
1002f4a2713aSLionel Sambuc     NewOps.push_back(GetPromotedInteger(N->getOperand(i)));
1003f4a2713aSLionel Sambuc 
1004*0a6a1f1dSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
1005f4a2713aSLionel Sambuc }
1006f4a2713aSLionel Sambuc 
PromoteIntOp_CONVERT_RNDSAT(SDNode * N)1007f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) {
1008f4a2713aSLionel Sambuc   ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
1009f4a2713aSLionel Sambuc   assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
1010f4a2713aSLionel Sambuc            CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
1011f4a2713aSLionel Sambuc            CvtCode == ISD::CVT_FS || CvtCode == ISD::CVT_FU) &&
1012f4a2713aSLionel Sambuc            "can only promote integer arguments");
1013f4a2713aSLionel Sambuc   SDValue InOp = GetPromotedInteger(N->getOperand(0));
1014f4a2713aSLionel Sambuc   return DAG.getConvertRndSat(N->getValueType(0), SDLoc(N), InOp,
1015f4a2713aSLionel Sambuc                               N->getOperand(1), N->getOperand(2),
1016f4a2713aSLionel Sambuc                               N->getOperand(3), N->getOperand(4), CvtCode);
1017f4a2713aSLionel Sambuc }
1018f4a2713aSLionel Sambuc 
PromoteIntOp_INSERT_VECTOR_ELT(SDNode * N,unsigned OpNo)1019f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
1020f4a2713aSLionel Sambuc                                                          unsigned OpNo) {
1021f4a2713aSLionel Sambuc   if (OpNo == 1) {
1022f4a2713aSLionel Sambuc     // Promote the inserted value.  This is valid because the type does not
1023f4a2713aSLionel Sambuc     // have to match the vector element type.
1024f4a2713aSLionel Sambuc 
1025f4a2713aSLionel Sambuc     // Check that any extra bits introduced will be truncated away.
1026f4a2713aSLionel Sambuc     assert(N->getOperand(1).getValueType().getSizeInBits() >=
1027f4a2713aSLionel Sambuc            N->getValueType(0).getVectorElementType().getSizeInBits() &&
1028f4a2713aSLionel Sambuc            "Type of inserted value narrower than vector element type!");
1029f4a2713aSLionel Sambuc     return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
1030f4a2713aSLionel Sambuc                                   GetPromotedInteger(N->getOperand(1)),
1031f4a2713aSLionel Sambuc                                   N->getOperand(2)),
1032f4a2713aSLionel Sambuc                    0);
1033f4a2713aSLionel Sambuc   }
1034f4a2713aSLionel Sambuc 
1035f4a2713aSLionel Sambuc   assert(OpNo == 2 && "Different operand and result vector types?");
1036f4a2713aSLionel Sambuc 
1037f4a2713aSLionel Sambuc   // Promote the index.
1038f4a2713aSLionel Sambuc   SDValue Idx = DAG.getZExtOrTrunc(N->getOperand(2), SDLoc(N),
1039f4a2713aSLionel Sambuc                                    TLI.getVectorIdxTy());
1040f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
1041f4a2713aSLionel Sambuc                                 N->getOperand(1), Idx), 0);
1042f4a2713aSLionel Sambuc }
1043f4a2713aSLionel Sambuc 
PromoteIntOp_SCALAR_TO_VECTOR(SDNode * N)1044f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) {
1045f4a2713aSLionel Sambuc   // Integer SCALAR_TO_VECTOR operands are implicitly truncated, so just promote
1046f4a2713aSLionel Sambuc   // the operand in place.
1047f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N,
1048f4a2713aSLionel Sambuc                                 GetPromotedInteger(N->getOperand(0))), 0);
1049f4a2713aSLionel Sambuc }
1050f4a2713aSLionel Sambuc 
PromoteIntOp_SELECT(SDNode * N,unsigned OpNo)1051f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
1052f4a2713aSLionel Sambuc   assert(OpNo == 0 && "Only know how to promote the condition!");
1053f4a2713aSLionel Sambuc   SDValue Cond = N->getOperand(0);
1054f4a2713aSLionel Sambuc   EVT OpTy = N->getOperand(1).getValueType();
1055f4a2713aSLionel Sambuc 
1056f4a2713aSLionel Sambuc   // Promote all the way up to the canonical SetCC type.
1057*0a6a1f1dSLionel Sambuc   EVT OpVT = N->getOpcode() == ISD::SELECT ? OpTy.getScalarType() : OpTy;
1058*0a6a1f1dSLionel Sambuc   Cond = PromoteTargetBoolean(Cond, OpVT);
1059f4a2713aSLionel Sambuc 
1060f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, Cond, N->getOperand(1),
1061f4a2713aSLionel Sambuc                                         N->getOperand(2)), 0);
1062f4a2713aSLionel Sambuc }
1063f4a2713aSLionel Sambuc 
PromoteIntOp_SELECT_CC(SDNode * N,unsigned OpNo)1064f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) {
1065f4a2713aSLionel Sambuc   assert(OpNo == 0 && "Don't know how to promote this operand!");
1066f4a2713aSLionel Sambuc 
1067f4a2713aSLionel Sambuc   SDValue LHS = N->getOperand(0);
1068f4a2713aSLionel Sambuc   SDValue RHS = N->getOperand(1);
1069f4a2713aSLionel Sambuc   PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(4))->get());
1070f4a2713aSLionel Sambuc 
1071f4a2713aSLionel Sambuc   // The CC (#4) and the possible return values (#2 and #3) have legal types.
1072f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2),
1073f4a2713aSLionel Sambuc                                 N->getOperand(3), N->getOperand(4)), 0);
1074f4a2713aSLionel Sambuc }
1075f4a2713aSLionel Sambuc 
PromoteIntOp_SETCC(SDNode * N,unsigned OpNo)1076f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
1077f4a2713aSLionel Sambuc   assert(OpNo == 0 && "Don't know how to promote this operand!");
1078f4a2713aSLionel Sambuc 
1079f4a2713aSLionel Sambuc   SDValue LHS = N->getOperand(0);
1080f4a2713aSLionel Sambuc   SDValue RHS = N->getOperand(1);
1081f4a2713aSLionel Sambuc   PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
1082f4a2713aSLionel Sambuc 
1083f4a2713aSLionel Sambuc   // The CC (#2) is always legal.
1084f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2)), 0);
1085f4a2713aSLionel Sambuc }
1086f4a2713aSLionel Sambuc 
PromoteIntOp_Shift(SDNode * N)1087f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) {
1088f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
1089f4a2713aSLionel Sambuc                                 ZExtPromotedInteger(N->getOperand(1))), 0);
1090f4a2713aSLionel Sambuc }
1091f4a2713aSLionel Sambuc 
PromoteIntOp_SIGN_EXTEND(SDNode * N)1092f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
1093f4a2713aSLionel Sambuc   SDValue Op = GetPromotedInteger(N->getOperand(0));
1094f4a2713aSLionel Sambuc   SDLoc dl(N);
1095f4a2713aSLionel Sambuc   Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
1096f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(),
1097f4a2713aSLionel Sambuc                      Op, DAG.getValueType(N->getOperand(0).getValueType()));
1098f4a2713aSLionel Sambuc }
1099f4a2713aSLionel Sambuc 
PromoteIntOp_SINT_TO_FP(SDNode * N)1100f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) {
1101f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N,
1102f4a2713aSLionel Sambuc                                 SExtPromotedInteger(N->getOperand(0))), 0);
1103f4a2713aSLionel Sambuc }
1104f4a2713aSLionel Sambuc 
PromoteIntOp_STORE(StoreSDNode * N,unsigned OpNo)1105f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
1106f4a2713aSLionel Sambuc   assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
1107f4a2713aSLionel Sambuc   SDValue Ch = N->getChain(), Ptr = N->getBasePtr();
1108f4a2713aSLionel Sambuc   SDLoc dl(N);
1109f4a2713aSLionel Sambuc 
1110f4a2713aSLionel Sambuc   SDValue Val = GetPromotedInteger(N->getValue());  // Get promoted value.
1111f4a2713aSLionel Sambuc 
1112f4a2713aSLionel Sambuc   // Truncate the value and store the result.
1113f4a2713aSLionel Sambuc   return DAG.getTruncStore(Ch, dl, Val, Ptr,
1114f4a2713aSLionel Sambuc                            N->getMemoryVT(), N->getMemOperand());
1115f4a2713aSLionel Sambuc }
1116f4a2713aSLionel Sambuc 
PromoteIntOp_MSTORE(MaskedStoreSDNode * N,unsigned OpNo)1117*0a6a1f1dSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_MSTORE(MaskedStoreSDNode *N, unsigned OpNo){
1118*0a6a1f1dSLionel Sambuc 
1119*0a6a1f1dSLionel Sambuc   assert(OpNo == 2 && "Only know how to promote the mask!");
1120*0a6a1f1dSLionel Sambuc   SDValue DataOp = N->getValue();
1121*0a6a1f1dSLionel Sambuc   EVT DataVT = DataOp.getValueType();
1122*0a6a1f1dSLionel Sambuc   SDValue Mask = N->getMask();
1123*0a6a1f1dSLionel Sambuc   EVT MaskVT = Mask.getValueType();
1124*0a6a1f1dSLionel Sambuc   SDLoc dl(N);
1125*0a6a1f1dSLionel Sambuc 
1126*0a6a1f1dSLionel Sambuc   bool TruncateStore = false;
1127*0a6a1f1dSLionel Sambuc   if (!TLI.isTypeLegal(DataVT)) {
1128*0a6a1f1dSLionel Sambuc     if (getTypeAction(DataVT) == TargetLowering::TypePromoteInteger) {
1129*0a6a1f1dSLionel Sambuc       DataOp = GetPromotedInteger(DataOp);
1130*0a6a1f1dSLionel Sambuc       Mask = PromoteTargetBoolean(Mask, DataOp.getValueType());
1131*0a6a1f1dSLionel Sambuc       TruncateStore = true;
1132*0a6a1f1dSLionel Sambuc     }
1133*0a6a1f1dSLionel Sambuc     else {
1134*0a6a1f1dSLionel Sambuc       assert(getTypeAction(DataVT) == TargetLowering::TypeWidenVector &&
1135*0a6a1f1dSLionel Sambuc              "Unexpected data legalization in MSTORE");
1136*0a6a1f1dSLionel Sambuc       DataOp = GetWidenedVector(DataOp);
1137*0a6a1f1dSLionel Sambuc 
1138*0a6a1f1dSLionel Sambuc       if (getTypeAction(MaskVT) == TargetLowering::TypeWidenVector)
1139*0a6a1f1dSLionel Sambuc         Mask = GetWidenedVector(Mask);
1140*0a6a1f1dSLionel Sambuc       else {
1141*0a6a1f1dSLionel Sambuc         EVT BoolVT = getSetCCResultType(DataOp.getValueType());
1142*0a6a1f1dSLionel Sambuc 
1143*0a6a1f1dSLionel Sambuc         // We can't use ModifyToType() because we should fill the mask with
1144*0a6a1f1dSLionel Sambuc         // zeroes
1145*0a6a1f1dSLionel Sambuc         unsigned WidenNumElts = BoolVT.getVectorNumElements();
1146*0a6a1f1dSLionel Sambuc         unsigned MaskNumElts = MaskVT.getVectorNumElements();
1147*0a6a1f1dSLionel Sambuc 
1148*0a6a1f1dSLionel Sambuc         unsigned NumConcat = WidenNumElts / MaskNumElts;
1149*0a6a1f1dSLionel Sambuc         SmallVector<SDValue, 16> Ops(NumConcat);
1150*0a6a1f1dSLionel Sambuc         SDValue ZeroVal = DAG.getConstant(0, MaskVT);
1151*0a6a1f1dSLionel Sambuc         Ops[0] = Mask;
1152*0a6a1f1dSLionel Sambuc         for (unsigned i = 1; i != NumConcat; ++i)
1153*0a6a1f1dSLionel Sambuc           Ops[i] = ZeroVal;
1154*0a6a1f1dSLionel Sambuc 
1155*0a6a1f1dSLionel Sambuc         Mask = DAG.getNode(ISD::CONCAT_VECTORS, dl, BoolVT, Ops);
1156*0a6a1f1dSLionel Sambuc       }
1157*0a6a1f1dSLionel Sambuc     }
1158*0a6a1f1dSLionel Sambuc   }
1159*0a6a1f1dSLionel Sambuc   else
1160*0a6a1f1dSLionel Sambuc     Mask = PromoteTargetBoolean(N->getMask(), DataOp.getValueType());
1161*0a6a1f1dSLionel Sambuc   return DAG.getMaskedStore(N->getChain(), dl, DataOp, N->getBasePtr(), Mask,
1162*0a6a1f1dSLionel Sambuc                             N->getMemoryVT(), N->getMemOperand(),
1163*0a6a1f1dSLionel Sambuc                             TruncateStore);
1164*0a6a1f1dSLionel Sambuc }
1165*0a6a1f1dSLionel Sambuc 
PromoteIntOp_MLOAD(MaskedLoadSDNode * N,unsigned OpNo)1166*0a6a1f1dSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_MLOAD(MaskedLoadSDNode *N, unsigned OpNo){
1167*0a6a1f1dSLionel Sambuc   assert(OpNo == 2 && "Only know how to promote the mask!");
1168*0a6a1f1dSLionel Sambuc   EVT DataVT = N->getValueType(0);
1169*0a6a1f1dSLionel Sambuc   SDValue Mask = PromoteTargetBoolean(N->getOperand(OpNo), DataVT);
1170*0a6a1f1dSLionel Sambuc   SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
1171*0a6a1f1dSLionel Sambuc   NewOps[OpNo] = Mask;
1172*0a6a1f1dSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
1173*0a6a1f1dSLionel Sambuc }
1174*0a6a1f1dSLionel Sambuc 
PromoteIntOp_TRUNCATE(SDNode * N)1175f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
1176f4a2713aSLionel Sambuc   SDValue Op = GetPromotedInteger(N->getOperand(0));
1177f4a2713aSLionel Sambuc   return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0), Op);
1178f4a2713aSLionel Sambuc }
1179f4a2713aSLionel Sambuc 
PromoteIntOp_UINT_TO_FP(SDNode * N)1180f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
1181f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N,
1182f4a2713aSLionel Sambuc                                 ZExtPromotedInteger(N->getOperand(0))), 0);
1183f4a2713aSLionel Sambuc }
1184f4a2713aSLionel Sambuc 
PromoteIntOp_ZERO_EXTEND(SDNode * N)1185f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
1186f4a2713aSLionel Sambuc   SDLoc dl(N);
1187f4a2713aSLionel Sambuc   SDValue Op = GetPromotedInteger(N->getOperand(0));
1188f4a2713aSLionel Sambuc   Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
1189f4a2713aSLionel Sambuc   return DAG.getZeroExtendInReg(Op, dl,
1190f4a2713aSLionel Sambuc                                 N->getOperand(0).getValueType().getScalarType());
1191f4a2713aSLionel Sambuc }
1192f4a2713aSLionel Sambuc 
1193f4a2713aSLionel Sambuc 
1194f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1195f4a2713aSLionel Sambuc //  Integer Result Expansion
1196f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1197f4a2713aSLionel Sambuc 
1198f4a2713aSLionel Sambuc /// ExpandIntegerResult - This method is called when the specified result of the
1199f4a2713aSLionel Sambuc /// specified node is found to need expansion.  At this point, the node may also
1200f4a2713aSLionel Sambuc /// have invalid operands or may have other results that need promotion, we just
1201f4a2713aSLionel Sambuc /// know that (at least) one result needs expansion.
ExpandIntegerResult(SDNode * N,unsigned ResNo)1202f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
1203f4a2713aSLionel Sambuc   DEBUG(dbgs() << "Expand integer result: "; N->dump(&DAG); dbgs() << "\n");
1204f4a2713aSLionel Sambuc   SDValue Lo, Hi;
1205f4a2713aSLionel Sambuc   Lo = Hi = SDValue();
1206f4a2713aSLionel Sambuc 
1207f4a2713aSLionel Sambuc   // See if the target wants to custom expand this node.
1208f4a2713aSLionel Sambuc   if (CustomLowerNode(N, N->getValueType(ResNo), true))
1209f4a2713aSLionel Sambuc     return;
1210f4a2713aSLionel Sambuc 
1211f4a2713aSLionel Sambuc   switch (N->getOpcode()) {
1212f4a2713aSLionel Sambuc   default:
1213f4a2713aSLionel Sambuc #ifndef NDEBUG
1214f4a2713aSLionel Sambuc     dbgs() << "ExpandIntegerResult #" << ResNo << ": ";
1215f4a2713aSLionel Sambuc     N->dump(&DAG); dbgs() << "\n";
1216f4a2713aSLionel Sambuc #endif
1217f4a2713aSLionel Sambuc     llvm_unreachable("Do not know how to expand the result of this operator!");
1218f4a2713aSLionel Sambuc 
1219f4a2713aSLionel Sambuc   case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
1220f4a2713aSLionel Sambuc   case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
1221f4a2713aSLionel Sambuc   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
1222f4a2713aSLionel Sambuc   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
1223f4a2713aSLionel Sambuc 
1224f4a2713aSLionel Sambuc   case ISD::BITCAST:            ExpandRes_BITCAST(N, Lo, Hi); break;
1225f4a2713aSLionel Sambuc   case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
1226f4a2713aSLionel Sambuc   case ISD::EXTRACT_ELEMENT:    ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
1227f4a2713aSLionel Sambuc   case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
1228f4a2713aSLionel Sambuc   case ISD::VAARG:              ExpandRes_VAARG(N, Lo, Hi); break;
1229f4a2713aSLionel Sambuc 
1230f4a2713aSLionel Sambuc   case ISD::ANY_EXTEND:  ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
1231f4a2713aSLionel Sambuc   case ISD::AssertSext:  ExpandIntRes_AssertSext(N, Lo, Hi); break;
1232f4a2713aSLionel Sambuc   case ISD::AssertZext:  ExpandIntRes_AssertZext(N, Lo, Hi); break;
1233f4a2713aSLionel Sambuc   case ISD::BSWAP:       ExpandIntRes_BSWAP(N, Lo, Hi); break;
1234f4a2713aSLionel Sambuc   case ISD::Constant:    ExpandIntRes_Constant(N, Lo, Hi); break;
1235f4a2713aSLionel Sambuc   case ISD::CTLZ_ZERO_UNDEF:
1236f4a2713aSLionel Sambuc   case ISD::CTLZ:        ExpandIntRes_CTLZ(N, Lo, Hi); break;
1237f4a2713aSLionel Sambuc   case ISD::CTPOP:       ExpandIntRes_CTPOP(N, Lo, Hi); break;
1238f4a2713aSLionel Sambuc   case ISD::CTTZ_ZERO_UNDEF:
1239f4a2713aSLionel Sambuc   case ISD::CTTZ:        ExpandIntRes_CTTZ(N, Lo, Hi); break;
1240f4a2713aSLionel Sambuc   case ISD::FP_TO_SINT:  ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
1241f4a2713aSLionel Sambuc   case ISD::FP_TO_UINT:  ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
1242f4a2713aSLionel Sambuc   case ISD::LOAD:        ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
1243f4a2713aSLionel Sambuc   case ISD::MUL:         ExpandIntRes_MUL(N, Lo, Hi); break;
1244f4a2713aSLionel Sambuc   case ISD::SDIV:        ExpandIntRes_SDIV(N, Lo, Hi); break;
1245f4a2713aSLionel Sambuc   case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
1246f4a2713aSLionel Sambuc   case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
1247f4a2713aSLionel Sambuc   case ISD::SREM:        ExpandIntRes_SREM(N, Lo, Hi); break;
1248f4a2713aSLionel Sambuc   case ISD::TRUNCATE:    ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
1249f4a2713aSLionel Sambuc   case ISD::UDIV:        ExpandIntRes_UDIV(N, Lo, Hi); break;
1250f4a2713aSLionel Sambuc   case ISD::UREM:        ExpandIntRes_UREM(N, Lo, Hi); break;
1251f4a2713aSLionel Sambuc   case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
1252f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD: ExpandIntRes_ATOMIC_LOAD(N, Lo, Hi); break;
1253f4a2713aSLionel Sambuc 
1254f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_ADD:
1255f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_SUB:
1256f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_AND:
1257f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_OR:
1258f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_XOR:
1259f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_NAND:
1260f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_MIN:
1261f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_MAX:
1262f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_UMIN:
1263f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_UMAX:
1264f4a2713aSLionel Sambuc   case ISD::ATOMIC_SWAP:
1265f4a2713aSLionel Sambuc   case ISD::ATOMIC_CMP_SWAP: {
1266f4a2713aSLionel Sambuc     std::pair<SDValue, SDValue> Tmp = ExpandAtomic(N);
1267f4a2713aSLionel Sambuc     SplitInteger(Tmp.first, Lo, Hi);
1268f4a2713aSLionel Sambuc     ReplaceValueWith(SDValue(N, 1), Tmp.second);
1269f4a2713aSLionel Sambuc     break;
1270f4a2713aSLionel Sambuc   }
1271*0a6a1f1dSLionel Sambuc   case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: {
1272*0a6a1f1dSLionel Sambuc     AtomicSDNode *AN = cast<AtomicSDNode>(N);
1273*0a6a1f1dSLionel Sambuc     SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::Other);
1274*0a6a1f1dSLionel Sambuc     SDValue Tmp = DAG.getAtomicCmpSwap(
1275*0a6a1f1dSLionel Sambuc         ISD::ATOMIC_CMP_SWAP, SDLoc(N), AN->getMemoryVT(), VTs,
1276*0a6a1f1dSLionel Sambuc         N->getOperand(0), N->getOperand(1), N->getOperand(2), N->getOperand(3),
1277*0a6a1f1dSLionel Sambuc         AN->getMemOperand(), AN->getSuccessOrdering(), AN->getFailureOrdering(),
1278*0a6a1f1dSLionel Sambuc         AN->getSynchScope());
1279*0a6a1f1dSLionel Sambuc 
1280*0a6a1f1dSLionel Sambuc     // Expanding to the strong ATOMIC_CMP_SWAP node means we can determine
1281*0a6a1f1dSLionel Sambuc     // success simply by comparing the loaded value against the ingoing
1282*0a6a1f1dSLionel Sambuc     // comparison.
1283*0a6a1f1dSLionel Sambuc     SDValue Success = DAG.getSetCC(SDLoc(N), N->getValueType(1), Tmp,
1284*0a6a1f1dSLionel Sambuc                                    N->getOperand(2), ISD::SETEQ);
1285*0a6a1f1dSLionel Sambuc 
1286*0a6a1f1dSLionel Sambuc     SplitInteger(Tmp, Lo, Hi);
1287*0a6a1f1dSLionel Sambuc     ReplaceValueWith(SDValue(N, 1), Success);
1288*0a6a1f1dSLionel Sambuc     ReplaceValueWith(SDValue(N, 2), Tmp.getValue(1));
1289*0a6a1f1dSLionel Sambuc     break;
1290*0a6a1f1dSLionel Sambuc   }
1291f4a2713aSLionel Sambuc 
1292f4a2713aSLionel Sambuc   case ISD::AND:
1293f4a2713aSLionel Sambuc   case ISD::OR:
1294f4a2713aSLionel Sambuc   case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
1295f4a2713aSLionel Sambuc 
1296f4a2713aSLionel Sambuc   case ISD::ADD:
1297f4a2713aSLionel Sambuc   case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
1298f4a2713aSLionel Sambuc 
1299f4a2713aSLionel Sambuc   case ISD::ADDC:
1300f4a2713aSLionel Sambuc   case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
1301f4a2713aSLionel Sambuc 
1302f4a2713aSLionel Sambuc   case ISD::ADDE:
1303f4a2713aSLionel Sambuc   case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
1304f4a2713aSLionel Sambuc 
1305f4a2713aSLionel Sambuc   case ISD::SHL:
1306f4a2713aSLionel Sambuc   case ISD::SRA:
1307f4a2713aSLionel Sambuc   case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
1308f4a2713aSLionel Sambuc 
1309f4a2713aSLionel Sambuc   case ISD::SADDO:
1310f4a2713aSLionel Sambuc   case ISD::SSUBO: ExpandIntRes_SADDSUBO(N, Lo, Hi); break;
1311f4a2713aSLionel Sambuc   case ISD::UADDO:
1312f4a2713aSLionel Sambuc   case ISD::USUBO: ExpandIntRes_UADDSUBO(N, Lo, Hi); break;
1313f4a2713aSLionel Sambuc   case ISD::UMULO:
1314f4a2713aSLionel Sambuc   case ISD::SMULO: ExpandIntRes_XMULO(N, Lo, Hi); break;
1315f4a2713aSLionel Sambuc   }
1316f4a2713aSLionel Sambuc 
1317f4a2713aSLionel Sambuc   // If Lo/Hi is null, the sub-method took care of registering results etc.
1318f4a2713aSLionel Sambuc   if (Lo.getNode())
1319f4a2713aSLionel Sambuc     SetExpandedInteger(SDValue(N, ResNo), Lo, Hi);
1320f4a2713aSLionel Sambuc }
1321f4a2713aSLionel Sambuc 
1322f4a2713aSLionel Sambuc /// Lower an atomic node to the appropriate builtin call.
ExpandAtomic(SDNode * Node)1323f4a2713aSLionel Sambuc std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
1324f4a2713aSLionel Sambuc   unsigned Opc = Node->getOpcode();
1325f4a2713aSLionel Sambuc   MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
1326f4a2713aSLionel Sambuc   RTLIB::Libcall LC;
1327f4a2713aSLionel Sambuc 
1328f4a2713aSLionel Sambuc   switch (Opc) {
1329f4a2713aSLionel Sambuc   default:
1330f4a2713aSLionel Sambuc     llvm_unreachable("Unhandled atomic intrinsic Expand!");
1331f4a2713aSLionel Sambuc   case ISD::ATOMIC_SWAP:
1332f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1333f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1334f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break;
1335f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break;
1336f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break;
1337f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break;
1338f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_LOCK_TEST_AND_SET_16;break;
1339f4a2713aSLionel Sambuc     }
1340f4a2713aSLionel Sambuc     break;
1341f4a2713aSLionel Sambuc   case ISD::ATOMIC_CMP_SWAP:
1342f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1343f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1344f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break;
1345f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break;
1346f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break;
1347f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break;
1348f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_16;break;
1349f4a2713aSLionel Sambuc     }
1350f4a2713aSLionel Sambuc     break;
1351f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_ADD:
1352f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1353f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1354f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_ADD_1; break;
1355f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break;
1356f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break;
1357f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break;
1358f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_ADD_16;break;
1359f4a2713aSLionel Sambuc     }
1360f4a2713aSLionel Sambuc     break;
1361f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_SUB:
1362f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1363f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1364f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_SUB_1; break;
1365f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break;
1366f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break;
1367f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break;
1368f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_SUB_16;break;
1369f4a2713aSLionel Sambuc     }
1370f4a2713aSLionel Sambuc     break;
1371f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_AND:
1372f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1373f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1374f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_AND_1; break;
1375f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break;
1376f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break;
1377f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break;
1378f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_AND_16;break;
1379f4a2713aSLionel Sambuc     }
1380f4a2713aSLionel Sambuc     break;
1381f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_OR:
1382f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1383f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1384f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_OR_1; break;
1385f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break;
1386f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break;
1387f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break;
1388f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_OR_16;break;
1389f4a2713aSLionel Sambuc     }
1390f4a2713aSLionel Sambuc     break;
1391f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_XOR:
1392f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1393f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1394f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_XOR_1; break;
1395f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break;
1396f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break;
1397f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break;
1398f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_XOR_16;break;
1399f4a2713aSLionel Sambuc     }
1400f4a2713aSLionel Sambuc     break;
1401f4a2713aSLionel Sambuc   case ISD::ATOMIC_LOAD_NAND:
1402f4a2713aSLionel Sambuc     switch (VT.SimpleTy) {
1403f4a2713aSLionel Sambuc     default: llvm_unreachable("Unexpected value type for atomic!");
1404f4a2713aSLionel Sambuc     case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_NAND_1; break;
1405f4a2713aSLionel Sambuc     case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break;
1406f4a2713aSLionel Sambuc     case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break;
1407f4a2713aSLionel Sambuc     case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break;
1408f4a2713aSLionel Sambuc     case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_NAND_16;break;
1409f4a2713aSLionel Sambuc     }
1410f4a2713aSLionel Sambuc     break;
1411f4a2713aSLionel Sambuc   }
1412f4a2713aSLionel Sambuc 
1413f4a2713aSLionel Sambuc   return ExpandChainLibCall(LC, Node, false);
1414f4a2713aSLionel Sambuc }
1415f4a2713aSLionel Sambuc 
1416f4a2713aSLionel Sambuc /// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
1417f4a2713aSLionel Sambuc /// and the shift amount is a constant 'Amt'.  Expand the operation.
ExpandShiftByConstant(SDNode * N,unsigned Amt,SDValue & Lo,SDValue & Hi)1418f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
1419f4a2713aSLionel Sambuc                                              SDValue &Lo, SDValue &Hi) {
1420*0a6a1f1dSLionel Sambuc   assert(Amt && "Expected zero shifts to be already optimized away.");
1421f4a2713aSLionel Sambuc   SDLoc DL(N);
1422f4a2713aSLionel Sambuc   // Expand the incoming operand to be shifted, so that we have its parts
1423f4a2713aSLionel Sambuc   SDValue InL, InH;
1424f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), InL, InH);
1425f4a2713aSLionel Sambuc 
1426f4a2713aSLionel Sambuc   EVT NVT = InL.getValueType();
1427f4a2713aSLionel Sambuc   unsigned VTBits = N->getValueType(0).getSizeInBits();
1428f4a2713aSLionel Sambuc   unsigned NVTBits = NVT.getSizeInBits();
1429f4a2713aSLionel Sambuc   EVT ShTy = N->getOperand(1).getValueType();
1430f4a2713aSLionel Sambuc 
1431f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::SHL) {
1432f4a2713aSLionel Sambuc     if (Amt > VTBits) {
1433f4a2713aSLionel Sambuc       Lo = Hi = DAG.getConstant(0, NVT);
1434f4a2713aSLionel Sambuc     } else if (Amt > NVTBits) {
1435f4a2713aSLionel Sambuc       Lo = DAG.getConstant(0, NVT);
1436f4a2713aSLionel Sambuc       Hi = DAG.getNode(ISD::SHL, DL,
1437f4a2713aSLionel Sambuc                        NVT, InL, DAG.getConstant(Amt-NVTBits, ShTy));
1438f4a2713aSLionel Sambuc     } else if (Amt == NVTBits) {
1439f4a2713aSLionel Sambuc       Lo = DAG.getConstant(0, NVT);
1440f4a2713aSLionel Sambuc       Hi = InL;
1441f4a2713aSLionel Sambuc     } else if (Amt == 1 &&
1442f4a2713aSLionel Sambuc                TLI.isOperationLegalOrCustom(ISD::ADDC,
1443f4a2713aSLionel Sambuc                               TLI.getTypeToExpandTo(*DAG.getContext(), NVT))) {
1444f4a2713aSLionel Sambuc       // Emit this X << 1 as X+X.
1445f4a2713aSLionel Sambuc       SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
1446f4a2713aSLionel Sambuc       SDValue LoOps[2] = { InL, InL };
1447*0a6a1f1dSLionel Sambuc       Lo = DAG.getNode(ISD::ADDC, DL, VTList, LoOps);
1448f4a2713aSLionel Sambuc       SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
1449*0a6a1f1dSLionel Sambuc       Hi = DAG.getNode(ISD::ADDE, DL, VTList, HiOps);
1450f4a2713aSLionel Sambuc     } else {
1451f4a2713aSLionel Sambuc       Lo = DAG.getNode(ISD::SHL, DL, NVT, InL, DAG.getConstant(Amt, ShTy));
1452f4a2713aSLionel Sambuc       Hi = DAG.getNode(ISD::OR, DL, NVT,
1453f4a2713aSLionel Sambuc                        DAG.getNode(ISD::SHL, DL, NVT, InH,
1454f4a2713aSLionel Sambuc                                    DAG.getConstant(Amt, ShTy)),
1455f4a2713aSLionel Sambuc                        DAG.getNode(ISD::SRL, DL, NVT, InL,
1456f4a2713aSLionel Sambuc                                    DAG.getConstant(NVTBits-Amt, ShTy)));
1457f4a2713aSLionel Sambuc     }
1458f4a2713aSLionel Sambuc     return;
1459f4a2713aSLionel Sambuc   }
1460f4a2713aSLionel Sambuc 
1461f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::SRL) {
1462f4a2713aSLionel Sambuc     if (Amt > VTBits) {
1463f4a2713aSLionel Sambuc       Lo = DAG.getConstant(0, NVT);
1464f4a2713aSLionel Sambuc       Hi = DAG.getConstant(0, NVT);
1465f4a2713aSLionel Sambuc     } else if (Amt > NVTBits) {
1466f4a2713aSLionel Sambuc       Lo = DAG.getNode(ISD::SRL, DL,
1467f4a2713aSLionel Sambuc                        NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
1468f4a2713aSLionel Sambuc       Hi = DAG.getConstant(0, NVT);
1469f4a2713aSLionel Sambuc     } else if (Amt == NVTBits) {
1470f4a2713aSLionel Sambuc       Lo = InH;
1471f4a2713aSLionel Sambuc       Hi = DAG.getConstant(0, NVT);
1472f4a2713aSLionel Sambuc     } else {
1473f4a2713aSLionel Sambuc       Lo = DAG.getNode(ISD::OR, DL, NVT,
1474f4a2713aSLionel Sambuc                        DAG.getNode(ISD::SRL, DL, NVT, InL,
1475f4a2713aSLionel Sambuc                                    DAG.getConstant(Amt, ShTy)),
1476f4a2713aSLionel Sambuc                        DAG.getNode(ISD::SHL, DL, NVT, InH,
1477f4a2713aSLionel Sambuc                                    DAG.getConstant(NVTBits-Amt, ShTy)));
1478f4a2713aSLionel Sambuc       Hi = DAG.getNode(ISD::SRL, DL, NVT, InH, DAG.getConstant(Amt, ShTy));
1479f4a2713aSLionel Sambuc     }
1480f4a2713aSLionel Sambuc     return;
1481f4a2713aSLionel Sambuc   }
1482f4a2713aSLionel Sambuc 
1483f4a2713aSLionel Sambuc   assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
1484f4a2713aSLionel Sambuc   if (Amt > VTBits) {
1485f4a2713aSLionel Sambuc     Hi = Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
1486f4a2713aSLionel Sambuc                           DAG.getConstant(NVTBits-1, ShTy));
1487f4a2713aSLionel Sambuc   } else if (Amt > NVTBits) {
1488f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
1489f4a2713aSLionel Sambuc                      DAG.getConstant(Amt-NVTBits, ShTy));
1490f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
1491f4a2713aSLionel Sambuc                      DAG.getConstant(NVTBits-1, ShTy));
1492f4a2713aSLionel Sambuc   } else if (Amt == NVTBits) {
1493f4a2713aSLionel Sambuc     Lo = InH;
1494f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
1495f4a2713aSLionel Sambuc                      DAG.getConstant(NVTBits-1, ShTy));
1496f4a2713aSLionel Sambuc   } else {
1497f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::OR, DL, NVT,
1498f4a2713aSLionel Sambuc                      DAG.getNode(ISD::SRL, DL, NVT, InL,
1499f4a2713aSLionel Sambuc                                  DAG.getConstant(Amt, ShTy)),
1500f4a2713aSLionel Sambuc                      DAG.getNode(ISD::SHL, DL, NVT, InH,
1501f4a2713aSLionel Sambuc                                  DAG.getConstant(NVTBits-Amt, ShTy)));
1502f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SRA, DL, NVT, InH, DAG.getConstant(Amt, ShTy));
1503f4a2713aSLionel Sambuc   }
1504f4a2713aSLionel Sambuc }
1505f4a2713aSLionel Sambuc 
1506f4a2713aSLionel Sambuc /// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
1507f4a2713aSLionel Sambuc /// this shift based on knowledge of the high bit of the shift amount.  If we
1508f4a2713aSLionel Sambuc /// can tell this, we know that it is >= 32 or < 32, without knowing the actual
1509f4a2713aSLionel Sambuc /// shift amount.
1510f4a2713aSLionel Sambuc bool DAGTypeLegalizer::
ExpandShiftWithKnownAmountBit(SDNode * N,SDValue & Lo,SDValue & Hi)1511f4a2713aSLionel Sambuc ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
1512f4a2713aSLionel Sambuc   SDValue Amt = N->getOperand(1);
1513f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1514f4a2713aSLionel Sambuc   EVT ShTy = Amt.getValueType();
1515f4a2713aSLionel Sambuc   unsigned ShBits = ShTy.getScalarType().getSizeInBits();
1516f4a2713aSLionel Sambuc   unsigned NVTBits = NVT.getScalarType().getSizeInBits();
1517f4a2713aSLionel Sambuc   assert(isPowerOf2_32(NVTBits) &&
1518f4a2713aSLionel Sambuc          "Expanded integer type size not a power of two!");
1519f4a2713aSLionel Sambuc   SDLoc dl(N);
1520f4a2713aSLionel Sambuc 
1521f4a2713aSLionel Sambuc   APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
1522f4a2713aSLionel Sambuc   APInt KnownZero, KnownOne;
1523*0a6a1f1dSLionel Sambuc   DAG.computeKnownBits(N->getOperand(1), KnownZero, KnownOne);
1524f4a2713aSLionel Sambuc 
1525f4a2713aSLionel Sambuc   // If we don't know anything about the high bits, exit.
1526f4a2713aSLionel Sambuc   if (((KnownZero|KnownOne) & HighBitMask) == 0)
1527f4a2713aSLionel Sambuc     return false;
1528f4a2713aSLionel Sambuc 
1529f4a2713aSLionel Sambuc   // Get the incoming operand to be shifted.
1530f4a2713aSLionel Sambuc   SDValue InL, InH;
1531f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), InL, InH);
1532f4a2713aSLionel Sambuc 
1533f4a2713aSLionel Sambuc   // If we know that any of the high bits of the shift amount are one, then we
1534f4a2713aSLionel Sambuc   // can do this as a couple of simple shifts.
1535f4a2713aSLionel Sambuc   if (KnownOne.intersects(HighBitMask)) {
1536f4a2713aSLionel Sambuc     // Mask out the high bit, which we know is set.
1537f4a2713aSLionel Sambuc     Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
1538f4a2713aSLionel Sambuc                       DAG.getConstant(~HighBitMask, ShTy));
1539f4a2713aSLionel Sambuc 
1540f4a2713aSLionel Sambuc     switch (N->getOpcode()) {
1541f4a2713aSLionel Sambuc     default: llvm_unreachable("Unknown shift");
1542f4a2713aSLionel Sambuc     case ISD::SHL:
1543f4a2713aSLionel Sambuc       Lo = DAG.getConstant(0, NVT);              // Low part is zero.
1544f4a2713aSLionel Sambuc       Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
1545f4a2713aSLionel Sambuc       return true;
1546f4a2713aSLionel Sambuc     case ISD::SRL:
1547f4a2713aSLionel Sambuc       Hi = DAG.getConstant(0, NVT);              // Hi part is zero.
1548f4a2713aSLionel Sambuc       Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
1549f4a2713aSLionel Sambuc       return true;
1550f4a2713aSLionel Sambuc     case ISD::SRA:
1551f4a2713aSLionel Sambuc       Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,       // Sign extend high part.
1552f4a2713aSLionel Sambuc                        DAG.getConstant(NVTBits-1, ShTy));
1553f4a2713aSLionel Sambuc       Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
1554f4a2713aSLionel Sambuc       return true;
1555f4a2713aSLionel Sambuc     }
1556f4a2713aSLionel Sambuc   }
1557f4a2713aSLionel Sambuc 
1558f4a2713aSLionel Sambuc   // If we know that all of the high bits of the shift amount are zero, then we
1559f4a2713aSLionel Sambuc   // can do this as a couple of simple shifts.
1560f4a2713aSLionel Sambuc   if ((KnownZero & HighBitMask) == HighBitMask) {
1561f4a2713aSLionel Sambuc     // Calculate 31-x. 31 is used instead of 32 to avoid creating an undefined
1562f4a2713aSLionel Sambuc     // shift if x is zero.  We can use XOR here because x is known to be smaller
1563f4a2713aSLionel Sambuc     // than 32.
1564f4a2713aSLionel Sambuc     SDValue Amt2 = DAG.getNode(ISD::XOR, dl, ShTy, Amt,
1565f4a2713aSLionel Sambuc                                DAG.getConstant(NVTBits-1, ShTy));
1566f4a2713aSLionel Sambuc 
1567f4a2713aSLionel Sambuc     unsigned Op1, Op2;
1568f4a2713aSLionel Sambuc     switch (N->getOpcode()) {
1569f4a2713aSLionel Sambuc     default: llvm_unreachable("Unknown shift");
1570f4a2713aSLionel Sambuc     case ISD::SHL:  Op1 = ISD::SHL; Op2 = ISD::SRL; break;
1571f4a2713aSLionel Sambuc     case ISD::SRL:
1572f4a2713aSLionel Sambuc     case ISD::SRA:  Op1 = ISD::SRL; Op2 = ISD::SHL; break;
1573f4a2713aSLionel Sambuc     }
1574f4a2713aSLionel Sambuc 
1575f4a2713aSLionel Sambuc     // When shifting right the arithmetic for Lo and Hi is swapped.
1576f4a2713aSLionel Sambuc     if (N->getOpcode() != ISD::SHL)
1577f4a2713aSLionel Sambuc       std::swap(InL, InH);
1578f4a2713aSLionel Sambuc 
1579f4a2713aSLionel Sambuc     // Use a little trick to get the bits that move from Lo to Hi. First
1580f4a2713aSLionel Sambuc     // shift by one bit.
1581f4a2713aSLionel Sambuc     SDValue Sh1 = DAG.getNode(Op2, dl, NVT, InL, DAG.getConstant(1, ShTy));
1582f4a2713aSLionel Sambuc     // Then compute the remaining shift with amount-1.
1583f4a2713aSLionel Sambuc     SDValue Sh2 = DAG.getNode(Op2, dl, NVT, Sh1, Amt2);
1584f4a2713aSLionel Sambuc 
1585f4a2713aSLionel Sambuc     Lo = DAG.getNode(N->getOpcode(), dl, NVT, InL, Amt);
1586f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::OR, dl, NVT, DAG.getNode(Op1, dl, NVT, InH, Amt),Sh2);
1587f4a2713aSLionel Sambuc 
1588f4a2713aSLionel Sambuc     if (N->getOpcode() != ISD::SHL)
1589f4a2713aSLionel Sambuc       std::swap(Hi, Lo);
1590f4a2713aSLionel Sambuc     return true;
1591f4a2713aSLionel Sambuc   }
1592f4a2713aSLionel Sambuc 
1593f4a2713aSLionel Sambuc   return false;
1594f4a2713aSLionel Sambuc }
1595f4a2713aSLionel Sambuc 
1596f4a2713aSLionel Sambuc /// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift
1597f4a2713aSLionel Sambuc /// of any size.
1598f4a2713aSLionel Sambuc bool DAGTypeLegalizer::
ExpandShiftWithUnknownAmountBit(SDNode * N,SDValue & Lo,SDValue & Hi)1599f4a2713aSLionel Sambuc ExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
1600f4a2713aSLionel Sambuc   SDValue Amt = N->getOperand(1);
1601f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1602f4a2713aSLionel Sambuc   EVT ShTy = Amt.getValueType();
1603f4a2713aSLionel Sambuc   unsigned NVTBits = NVT.getSizeInBits();
1604f4a2713aSLionel Sambuc   assert(isPowerOf2_32(NVTBits) &&
1605f4a2713aSLionel Sambuc          "Expanded integer type size not a power of two!");
1606f4a2713aSLionel Sambuc   SDLoc dl(N);
1607f4a2713aSLionel Sambuc 
1608f4a2713aSLionel Sambuc   // Get the incoming operand to be shifted.
1609f4a2713aSLionel Sambuc   SDValue InL, InH;
1610f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), InL, InH);
1611f4a2713aSLionel Sambuc 
1612f4a2713aSLionel Sambuc   SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy);
1613f4a2713aSLionel Sambuc   SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode);
1614f4a2713aSLionel Sambuc   SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
1615f4a2713aSLionel Sambuc   SDValue isShort = DAG.getSetCC(dl, getSetCCResultType(ShTy),
1616f4a2713aSLionel Sambuc                                  Amt, NVBitsNode, ISD::SETULT);
1617f4a2713aSLionel Sambuc 
1618f4a2713aSLionel Sambuc   SDValue LoS, HiS, LoL, HiL;
1619f4a2713aSLionel Sambuc   switch (N->getOpcode()) {
1620f4a2713aSLionel Sambuc   default: llvm_unreachable("Unknown shift");
1621f4a2713aSLionel Sambuc   case ISD::SHL:
1622f4a2713aSLionel Sambuc     // Short: ShAmt < NVTBits
1623f4a2713aSLionel Sambuc     LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
1624f4a2713aSLionel Sambuc     HiS = DAG.getNode(ISD::OR, dl, NVT,
1625f4a2713aSLionel Sambuc                       DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
1626f4a2713aSLionel Sambuc     // FIXME: If Amt is zero, the following shift generates an undefined result
1627f4a2713aSLionel Sambuc     // on some architectures.
1628f4a2713aSLionel Sambuc                       DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack));
1629f4a2713aSLionel Sambuc 
1630f4a2713aSLionel Sambuc     // Long: ShAmt >= NVTBits
1631f4a2713aSLionel Sambuc     LoL = DAG.getConstant(0, NVT);                        // Lo part is zero.
1632f4a2713aSLionel Sambuc     HiL = DAG.getNode(ISD::SHL, dl, NVT, InL, AmtExcess); // Hi from Lo part.
1633f4a2713aSLionel Sambuc 
1634f4a2713aSLionel Sambuc     Lo = DAG.getSelect(dl, NVT, isShort, LoS, LoL);
1635f4a2713aSLionel Sambuc     Hi = DAG.getSelect(dl, NVT, isShort, HiS, HiL);
1636f4a2713aSLionel Sambuc     return true;
1637f4a2713aSLionel Sambuc   case ISD::SRL:
1638f4a2713aSLionel Sambuc     // Short: ShAmt < NVTBits
1639f4a2713aSLionel Sambuc     HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
1640f4a2713aSLionel Sambuc     LoS = DAG.getNode(ISD::OR, dl, NVT,
1641f4a2713aSLionel Sambuc                       DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
1642f4a2713aSLionel Sambuc     // FIXME: If Amt is zero, the following shift generates an undefined result
1643f4a2713aSLionel Sambuc     // on some architectures.
1644f4a2713aSLionel Sambuc                       DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
1645f4a2713aSLionel Sambuc 
1646f4a2713aSLionel Sambuc     // Long: ShAmt >= NVTBits
1647f4a2713aSLionel Sambuc     HiL = DAG.getConstant(0, NVT);                        // Hi part is zero.
1648f4a2713aSLionel Sambuc     LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part.
1649f4a2713aSLionel Sambuc 
1650f4a2713aSLionel Sambuc     Lo = DAG.getSelect(dl, NVT, isShort, LoS, LoL);
1651f4a2713aSLionel Sambuc     Hi = DAG.getSelect(dl, NVT, isShort, HiS, HiL);
1652f4a2713aSLionel Sambuc     return true;
1653f4a2713aSLionel Sambuc   case ISD::SRA:
1654f4a2713aSLionel Sambuc     // Short: ShAmt < NVTBits
1655f4a2713aSLionel Sambuc     HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
1656f4a2713aSLionel Sambuc     LoS = DAG.getNode(ISD::OR, dl, NVT,
1657f4a2713aSLionel Sambuc                       DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
1658f4a2713aSLionel Sambuc     // FIXME: If Amt is zero, the following shift generates an undefined result
1659f4a2713aSLionel Sambuc     // on some architectures.
1660f4a2713aSLionel Sambuc                       DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
1661f4a2713aSLionel Sambuc 
1662f4a2713aSLionel Sambuc     // Long: ShAmt >= NVTBits
1663f4a2713aSLionel Sambuc     HiL = DAG.getNode(ISD::SRA, dl, NVT, InH,             // Sign of Hi part.
1664f4a2713aSLionel Sambuc                       DAG.getConstant(NVTBits-1, ShTy));
1665f4a2713aSLionel Sambuc     LoL = DAG.getNode(ISD::SRA, dl, NVT, InH, AmtExcess); // Lo from Hi part.
1666f4a2713aSLionel Sambuc 
1667f4a2713aSLionel Sambuc     Lo = DAG.getSelect(dl, NVT, isShort, LoS, LoL);
1668f4a2713aSLionel Sambuc     Hi = DAG.getSelect(dl, NVT, isShort, HiS, HiL);
1669f4a2713aSLionel Sambuc     return true;
1670f4a2713aSLionel Sambuc   }
1671f4a2713aSLionel Sambuc }
1672f4a2713aSLionel Sambuc 
ExpandIntRes_ADDSUB(SDNode * N,SDValue & Lo,SDValue & Hi)1673f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
1674f4a2713aSLionel Sambuc                                            SDValue &Lo, SDValue &Hi) {
1675f4a2713aSLionel Sambuc   SDLoc dl(N);
1676f4a2713aSLionel Sambuc   // Expand the subcomponents.
1677f4a2713aSLionel Sambuc   SDValue LHSL, LHSH, RHSL, RHSH;
1678f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
1679f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1680f4a2713aSLionel Sambuc 
1681f4a2713aSLionel Sambuc   EVT NVT = LHSL.getValueType();
1682f4a2713aSLionel Sambuc   SDValue LoOps[2] = { LHSL, RHSL };
1683f4a2713aSLionel Sambuc   SDValue HiOps[3] = { LHSH, RHSH };
1684f4a2713aSLionel Sambuc 
1685f4a2713aSLionel Sambuc   // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support
1686f4a2713aSLionel Sambuc   // them.  TODO: Teach operation legalization how to expand unsupported
1687f4a2713aSLionel Sambuc   // ADDC/ADDE/SUBC/SUBE.  The problem is that these operations generate
1688f4a2713aSLionel Sambuc   // a carry of type MVT::Glue, but there doesn't seem to be any way to
1689f4a2713aSLionel Sambuc   // generate a value of this type in the expanded code sequence.
1690f4a2713aSLionel Sambuc   bool hasCarry =
1691f4a2713aSLionel Sambuc     TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
1692f4a2713aSLionel Sambuc                                    ISD::ADDC : ISD::SUBC,
1693f4a2713aSLionel Sambuc                                  TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
1694f4a2713aSLionel Sambuc 
1695f4a2713aSLionel Sambuc   if (hasCarry) {
1696f4a2713aSLionel Sambuc     SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
1697f4a2713aSLionel Sambuc     if (N->getOpcode() == ISD::ADD) {
1698*0a6a1f1dSLionel Sambuc       Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps);
1699f4a2713aSLionel Sambuc       HiOps[2] = Lo.getValue(1);
1700*0a6a1f1dSLionel Sambuc       Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps);
1701f4a2713aSLionel Sambuc     } else {
1702*0a6a1f1dSLionel Sambuc       Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps);
1703f4a2713aSLionel Sambuc       HiOps[2] = Lo.getValue(1);
1704*0a6a1f1dSLionel Sambuc       Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps);
1705f4a2713aSLionel Sambuc     }
1706f4a2713aSLionel Sambuc     return;
1707f4a2713aSLionel Sambuc   }
1708f4a2713aSLionel Sambuc 
1709f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::ADD) {
1710*0a6a1f1dSLionel Sambuc     Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps);
1711*0a6a1f1dSLionel Sambuc     Hi = DAG.getNode(ISD::ADD, dl, NVT, makeArrayRef(HiOps, 2));
1712f4a2713aSLionel Sambuc     SDValue Cmp1 = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo, LoOps[0],
1713f4a2713aSLionel Sambuc                                 ISD::SETULT);
1714f4a2713aSLionel Sambuc     SDValue Carry1 = DAG.getSelect(dl, NVT, Cmp1,
1715f4a2713aSLionel Sambuc                                    DAG.getConstant(1, NVT),
1716f4a2713aSLionel Sambuc                                    DAG.getConstant(0, NVT));
1717f4a2713aSLionel Sambuc     SDValue Cmp2 = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo, LoOps[1],
1718f4a2713aSLionel Sambuc                                 ISD::SETULT);
1719f4a2713aSLionel Sambuc     SDValue Carry2 = DAG.getSelect(dl, NVT, Cmp2,
1720f4a2713aSLionel Sambuc                                    DAG.getConstant(1, NVT), Carry1);
1721f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2);
1722f4a2713aSLionel Sambuc   } else {
1723*0a6a1f1dSLionel Sambuc     Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps);
1724*0a6a1f1dSLionel Sambuc     Hi = DAG.getNode(ISD::SUB, dl, NVT, makeArrayRef(HiOps, 2));
1725f4a2713aSLionel Sambuc     SDValue Cmp =
1726f4a2713aSLionel Sambuc       DAG.getSetCC(dl, getSetCCResultType(LoOps[0].getValueType()),
1727f4a2713aSLionel Sambuc                    LoOps[0], LoOps[1], ISD::SETULT);
1728f4a2713aSLionel Sambuc     SDValue Borrow = DAG.getSelect(dl, NVT, Cmp,
1729f4a2713aSLionel Sambuc                                    DAG.getConstant(1, NVT),
1730f4a2713aSLionel Sambuc                                    DAG.getConstant(0, NVT));
1731f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
1732f4a2713aSLionel Sambuc   }
1733f4a2713aSLionel Sambuc }
1734f4a2713aSLionel Sambuc 
ExpandIntRes_ADDSUBC(SDNode * N,SDValue & Lo,SDValue & Hi)1735f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
1736f4a2713aSLionel Sambuc                                             SDValue &Lo, SDValue &Hi) {
1737f4a2713aSLionel Sambuc   // Expand the subcomponents.
1738f4a2713aSLionel Sambuc   SDValue LHSL, LHSH, RHSL, RHSH;
1739f4a2713aSLionel Sambuc   SDLoc dl(N);
1740f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
1741f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1742f4a2713aSLionel Sambuc   SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
1743f4a2713aSLionel Sambuc   SDValue LoOps[2] = { LHSL, RHSL };
1744f4a2713aSLionel Sambuc   SDValue HiOps[3] = { LHSH, RHSH };
1745f4a2713aSLionel Sambuc 
1746f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::ADDC) {
1747*0a6a1f1dSLionel Sambuc     Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps);
1748f4a2713aSLionel Sambuc     HiOps[2] = Lo.getValue(1);
1749*0a6a1f1dSLionel Sambuc     Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps);
1750f4a2713aSLionel Sambuc   } else {
1751*0a6a1f1dSLionel Sambuc     Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps);
1752f4a2713aSLionel Sambuc     HiOps[2] = Lo.getValue(1);
1753*0a6a1f1dSLionel Sambuc     Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps);
1754f4a2713aSLionel Sambuc   }
1755f4a2713aSLionel Sambuc 
1756f4a2713aSLionel Sambuc   // Legalized the flag result - switch anything that used the old flag to
1757f4a2713aSLionel Sambuc   // use the new one.
1758f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
1759f4a2713aSLionel Sambuc }
1760f4a2713aSLionel Sambuc 
ExpandIntRes_ADDSUBE(SDNode * N,SDValue & Lo,SDValue & Hi)1761f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
1762f4a2713aSLionel Sambuc                                             SDValue &Lo, SDValue &Hi) {
1763f4a2713aSLionel Sambuc   // Expand the subcomponents.
1764f4a2713aSLionel Sambuc   SDValue LHSL, LHSH, RHSL, RHSH;
1765f4a2713aSLionel Sambuc   SDLoc dl(N);
1766f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
1767f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1768f4a2713aSLionel Sambuc   SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
1769f4a2713aSLionel Sambuc   SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
1770f4a2713aSLionel Sambuc   SDValue HiOps[3] = { LHSH, RHSH };
1771f4a2713aSLionel Sambuc 
1772*0a6a1f1dSLionel Sambuc   Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps);
1773f4a2713aSLionel Sambuc   HiOps[2] = Lo.getValue(1);
1774*0a6a1f1dSLionel Sambuc   Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps);
1775f4a2713aSLionel Sambuc 
1776f4a2713aSLionel Sambuc   // Legalized the flag result - switch anything that used the old flag to
1777f4a2713aSLionel Sambuc   // use the new one.
1778f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
1779f4a2713aSLionel Sambuc }
1780f4a2713aSLionel Sambuc 
ExpandIntRes_MERGE_VALUES(SDNode * N,unsigned ResNo,SDValue & Lo,SDValue & Hi)1781f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
1782f4a2713aSLionel Sambuc                                                  SDValue &Lo, SDValue &Hi) {
1783f4a2713aSLionel Sambuc   SDValue Res = DisintegrateMERGE_VALUES(N, ResNo);
1784f4a2713aSLionel Sambuc   SplitInteger(Res, Lo, Hi);
1785f4a2713aSLionel Sambuc }
1786f4a2713aSLionel Sambuc 
ExpandIntRes_ANY_EXTEND(SDNode * N,SDValue & Lo,SDValue & Hi)1787f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
1788f4a2713aSLionel Sambuc                                                SDValue &Lo, SDValue &Hi) {
1789f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1790f4a2713aSLionel Sambuc   SDLoc dl(N);
1791f4a2713aSLionel Sambuc   SDValue Op = N->getOperand(0);
1792f4a2713aSLionel Sambuc   if (Op.getValueType().bitsLE(NVT)) {
1793f4a2713aSLionel Sambuc     // The low part is any extension of the input (which degenerates to a copy).
1794f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op);
1795f4a2713aSLionel Sambuc     Hi = DAG.getUNDEF(NVT);   // The high part is undefined.
1796f4a2713aSLionel Sambuc   } else {
1797f4a2713aSLionel Sambuc     // For example, extension of an i48 to an i64.  The operand type necessarily
1798f4a2713aSLionel Sambuc     // promotes to the result type, so will end up being expanded too.
1799f4a2713aSLionel Sambuc     assert(getTypeAction(Op.getValueType()) ==
1800f4a2713aSLionel Sambuc            TargetLowering::TypePromoteInteger &&
1801f4a2713aSLionel Sambuc            "Only know how to promote this result!");
1802f4a2713aSLionel Sambuc     SDValue Res = GetPromotedInteger(Op);
1803f4a2713aSLionel Sambuc     assert(Res.getValueType() == N->getValueType(0) &&
1804f4a2713aSLionel Sambuc            "Operand over promoted?");
1805f4a2713aSLionel Sambuc     // Split the promoted operand.  This will simplify when it is expanded.
1806f4a2713aSLionel Sambuc     SplitInteger(Res, Lo, Hi);
1807f4a2713aSLionel Sambuc   }
1808f4a2713aSLionel Sambuc }
1809f4a2713aSLionel Sambuc 
ExpandIntRes_AssertSext(SDNode * N,SDValue & Lo,SDValue & Hi)1810f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
1811f4a2713aSLionel Sambuc                                                SDValue &Lo, SDValue &Hi) {
1812f4a2713aSLionel Sambuc   SDLoc dl(N);
1813f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Lo, Hi);
1814f4a2713aSLionel Sambuc   EVT NVT = Lo.getValueType();
1815f4a2713aSLionel Sambuc   EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
1816f4a2713aSLionel Sambuc   unsigned NVTBits = NVT.getSizeInBits();
1817f4a2713aSLionel Sambuc   unsigned EVTBits = EVT.getSizeInBits();
1818f4a2713aSLionel Sambuc 
1819f4a2713aSLionel Sambuc   if (NVTBits < EVTBits) {
1820f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi,
1821f4a2713aSLionel Sambuc                      DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
1822f4a2713aSLionel Sambuc                                                         EVTBits - NVTBits)));
1823f4a2713aSLionel Sambuc   } else {
1824f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
1825f4a2713aSLionel Sambuc     // The high part replicates the sign bit of Lo, make it explicit.
1826f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
1827f4a2713aSLionel Sambuc                      DAG.getConstant(NVTBits-1, TLI.getPointerTy()));
1828f4a2713aSLionel Sambuc   }
1829f4a2713aSLionel Sambuc }
1830f4a2713aSLionel Sambuc 
ExpandIntRes_AssertZext(SDNode * N,SDValue & Lo,SDValue & Hi)1831f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
1832f4a2713aSLionel Sambuc                                                SDValue &Lo, SDValue &Hi) {
1833f4a2713aSLionel Sambuc   SDLoc dl(N);
1834f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Lo, Hi);
1835f4a2713aSLionel Sambuc   EVT NVT = Lo.getValueType();
1836f4a2713aSLionel Sambuc   EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
1837f4a2713aSLionel Sambuc   unsigned NVTBits = NVT.getSizeInBits();
1838f4a2713aSLionel Sambuc   unsigned EVTBits = EVT.getSizeInBits();
1839f4a2713aSLionel Sambuc 
1840f4a2713aSLionel Sambuc   if (NVTBits < EVTBits) {
1841f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi,
1842f4a2713aSLionel Sambuc                      DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
1843f4a2713aSLionel Sambuc                                                         EVTBits - NVTBits)));
1844f4a2713aSLionel Sambuc   } else {
1845f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT));
1846f4a2713aSLionel Sambuc     // The high part must be zero, make it explicit.
1847f4a2713aSLionel Sambuc     Hi = DAG.getConstant(0, NVT);
1848f4a2713aSLionel Sambuc   }
1849f4a2713aSLionel Sambuc }
1850f4a2713aSLionel Sambuc 
ExpandIntRes_BSWAP(SDNode * N,SDValue & Lo,SDValue & Hi)1851f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
1852f4a2713aSLionel Sambuc                                           SDValue &Lo, SDValue &Hi) {
1853f4a2713aSLionel Sambuc   SDLoc dl(N);
1854f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Hi, Lo);  // Note swapped operands.
1855f4a2713aSLionel Sambuc   Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo);
1856f4a2713aSLionel Sambuc   Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
1857f4a2713aSLionel Sambuc }
1858f4a2713aSLionel Sambuc 
ExpandIntRes_Constant(SDNode * N,SDValue & Lo,SDValue & Hi)1859f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
1860f4a2713aSLionel Sambuc                                              SDValue &Lo, SDValue &Hi) {
1861f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1862f4a2713aSLionel Sambuc   unsigned NBitWidth = NVT.getSizeInBits();
1863*0a6a1f1dSLionel Sambuc   auto Constant = cast<ConstantSDNode>(N);
1864*0a6a1f1dSLionel Sambuc   const APInt &Cst = Constant->getAPIntValue();
1865*0a6a1f1dSLionel Sambuc   bool IsTarget = Constant->isTargetOpcode();
1866*0a6a1f1dSLionel Sambuc   bool IsOpaque = Constant->isOpaque();
1867*0a6a1f1dSLionel Sambuc   Lo = DAG.getConstant(Cst.trunc(NBitWidth), NVT, IsTarget, IsOpaque);
1868*0a6a1f1dSLionel Sambuc   Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT, IsTarget,
1869*0a6a1f1dSLionel Sambuc                        IsOpaque);
1870f4a2713aSLionel Sambuc }
1871f4a2713aSLionel Sambuc 
ExpandIntRes_CTLZ(SDNode * N,SDValue & Lo,SDValue & Hi)1872f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
1873f4a2713aSLionel Sambuc                                          SDValue &Lo, SDValue &Hi) {
1874f4a2713aSLionel Sambuc   SDLoc dl(N);
1875f4a2713aSLionel Sambuc   // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
1876f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Lo, Hi);
1877f4a2713aSLionel Sambuc   EVT NVT = Lo.getValueType();
1878f4a2713aSLionel Sambuc 
1879f4a2713aSLionel Sambuc   SDValue HiNotZero = DAG.getSetCC(dl, getSetCCResultType(NVT), Hi,
1880f4a2713aSLionel Sambuc                                    DAG.getConstant(0, NVT), ISD::SETNE);
1881f4a2713aSLionel Sambuc 
1882f4a2713aSLionel Sambuc   SDValue LoLZ = DAG.getNode(N->getOpcode(), dl, NVT, Lo);
1883f4a2713aSLionel Sambuc   SDValue HiLZ = DAG.getNode(ISD::CTLZ_ZERO_UNDEF, dl, NVT, Hi);
1884f4a2713aSLionel Sambuc 
1885f4a2713aSLionel Sambuc   Lo = DAG.getSelect(dl, NVT, HiNotZero, HiLZ,
1886f4a2713aSLionel Sambuc                      DAG.getNode(ISD::ADD, dl, NVT, LoLZ,
1887f4a2713aSLionel Sambuc                                  DAG.getConstant(NVT.getSizeInBits(), NVT)));
1888f4a2713aSLionel Sambuc   Hi = DAG.getConstant(0, NVT);
1889f4a2713aSLionel Sambuc }
1890f4a2713aSLionel Sambuc 
ExpandIntRes_CTPOP(SDNode * N,SDValue & Lo,SDValue & Hi)1891f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
1892f4a2713aSLionel Sambuc                                           SDValue &Lo, SDValue &Hi) {
1893f4a2713aSLionel Sambuc   SDLoc dl(N);
1894f4a2713aSLionel Sambuc   // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
1895f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Lo, Hi);
1896f4a2713aSLionel Sambuc   EVT NVT = Lo.getValueType();
1897f4a2713aSLionel Sambuc   Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, dl, NVT, Lo),
1898f4a2713aSLionel Sambuc                    DAG.getNode(ISD::CTPOP, dl, NVT, Hi));
1899f4a2713aSLionel Sambuc   Hi = DAG.getConstant(0, NVT);
1900f4a2713aSLionel Sambuc }
1901f4a2713aSLionel Sambuc 
ExpandIntRes_CTTZ(SDNode * N,SDValue & Lo,SDValue & Hi)1902f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
1903f4a2713aSLionel Sambuc                                          SDValue &Lo, SDValue &Hi) {
1904f4a2713aSLionel Sambuc   SDLoc dl(N);
1905f4a2713aSLionel Sambuc   // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
1906f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Lo, Hi);
1907f4a2713aSLionel Sambuc   EVT NVT = Lo.getValueType();
1908f4a2713aSLionel Sambuc 
1909f4a2713aSLionel Sambuc   SDValue LoNotZero = DAG.getSetCC(dl, getSetCCResultType(NVT), Lo,
1910f4a2713aSLionel Sambuc                                    DAG.getConstant(0, NVT), ISD::SETNE);
1911f4a2713aSLionel Sambuc 
1912f4a2713aSLionel Sambuc   SDValue LoLZ = DAG.getNode(ISD::CTTZ_ZERO_UNDEF, dl, NVT, Lo);
1913f4a2713aSLionel Sambuc   SDValue HiLZ = DAG.getNode(N->getOpcode(), dl, NVT, Hi);
1914f4a2713aSLionel Sambuc 
1915f4a2713aSLionel Sambuc   Lo = DAG.getSelect(dl, NVT, LoNotZero, LoLZ,
1916f4a2713aSLionel Sambuc                      DAG.getNode(ISD::ADD, dl, NVT, HiLZ,
1917f4a2713aSLionel Sambuc                                  DAG.getConstant(NVT.getSizeInBits(), NVT)));
1918f4a2713aSLionel Sambuc   Hi = DAG.getConstant(0, NVT);
1919f4a2713aSLionel Sambuc }
1920f4a2713aSLionel Sambuc 
ExpandIntRes_FP_TO_SINT(SDNode * N,SDValue & Lo,SDValue & Hi)1921f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo,
1922f4a2713aSLionel Sambuc                                                SDValue &Hi) {
1923f4a2713aSLionel Sambuc   SDLoc dl(N);
1924f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
1925f4a2713aSLionel Sambuc   SDValue Op = N->getOperand(0);
1926f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT);
1927f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!");
1928f4a2713aSLionel Sambuc   SplitInteger(TLI.makeLibCall(DAG, LC, VT, &Op, 1, true/*irrelevant*/,
1929f4a2713aSLionel Sambuc                                dl).first,
1930f4a2713aSLionel Sambuc                Lo, Hi);
1931f4a2713aSLionel Sambuc }
1932f4a2713aSLionel Sambuc 
ExpandIntRes_FP_TO_UINT(SDNode * N,SDValue & Lo,SDValue & Hi)1933f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo,
1934f4a2713aSLionel Sambuc                                                SDValue &Hi) {
1935f4a2713aSLionel Sambuc   SDLoc dl(N);
1936f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
1937f4a2713aSLionel Sambuc   SDValue Op = N->getOperand(0);
1938f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT);
1939f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!");
1940f4a2713aSLionel Sambuc   SplitInteger(TLI.makeLibCall(DAG, LC, VT, &Op, 1, false/*irrelevant*/,
1941f4a2713aSLionel Sambuc                                dl).first,
1942f4a2713aSLionel Sambuc                Lo, Hi);
1943f4a2713aSLionel Sambuc }
1944f4a2713aSLionel Sambuc 
ExpandIntRes_LOAD(LoadSDNode * N,SDValue & Lo,SDValue & Hi)1945f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
1946f4a2713aSLionel Sambuc                                          SDValue &Lo, SDValue &Hi) {
1947f4a2713aSLionel Sambuc   if (ISD::isNormalLoad(N)) {
1948f4a2713aSLionel Sambuc     ExpandRes_NormalLoad(N, Lo, Hi);
1949f4a2713aSLionel Sambuc     return;
1950f4a2713aSLionel Sambuc   }
1951f4a2713aSLionel Sambuc 
1952f4a2713aSLionel Sambuc   assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
1953f4a2713aSLionel Sambuc 
1954f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
1955f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1956f4a2713aSLionel Sambuc   SDValue Ch  = N->getChain();
1957f4a2713aSLionel Sambuc   SDValue Ptr = N->getBasePtr();
1958f4a2713aSLionel Sambuc   ISD::LoadExtType ExtType = N->getExtensionType();
1959f4a2713aSLionel Sambuc   unsigned Alignment = N->getAlignment();
1960f4a2713aSLionel Sambuc   bool isVolatile = N->isVolatile();
1961f4a2713aSLionel Sambuc   bool isNonTemporal = N->isNonTemporal();
1962f4a2713aSLionel Sambuc   bool isInvariant = N->isInvariant();
1963*0a6a1f1dSLionel Sambuc   AAMDNodes AAInfo = N->getAAInfo();
1964f4a2713aSLionel Sambuc   SDLoc dl(N);
1965f4a2713aSLionel Sambuc 
1966f4a2713aSLionel Sambuc   assert(NVT.isByteSized() && "Expanded type not byte sized!");
1967f4a2713aSLionel Sambuc 
1968f4a2713aSLionel Sambuc   if (N->getMemoryVT().bitsLE(NVT)) {
1969f4a2713aSLionel Sambuc     EVT MemVT = N->getMemoryVT();
1970f4a2713aSLionel Sambuc 
1971f4a2713aSLionel Sambuc     Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
1972*0a6a1f1dSLionel Sambuc                         MemVT, isVolatile, isNonTemporal, isInvariant,
1973*0a6a1f1dSLionel Sambuc                         Alignment, AAInfo);
1974f4a2713aSLionel Sambuc 
1975f4a2713aSLionel Sambuc     // Remember the chain.
1976f4a2713aSLionel Sambuc     Ch = Lo.getValue(1);
1977f4a2713aSLionel Sambuc 
1978f4a2713aSLionel Sambuc     if (ExtType == ISD::SEXTLOAD) {
1979f4a2713aSLionel Sambuc       // The high part is obtained by SRA'ing all but one of the bits of the
1980f4a2713aSLionel Sambuc       // lo part.
1981f4a2713aSLionel Sambuc       unsigned LoSize = Lo.getValueType().getSizeInBits();
1982f4a2713aSLionel Sambuc       Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
1983f4a2713aSLionel Sambuc                        DAG.getConstant(LoSize-1, TLI.getPointerTy()));
1984f4a2713aSLionel Sambuc     } else if (ExtType == ISD::ZEXTLOAD) {
1985f4a2713aSLionel Sambuc       // The high part is just a zero.
1986f4a2713aSLionel Sambuc       Hi = DAG.getConstant(0, NVT);
1987f4a2713aSLionel Sambuc     } else {
1988f4a2713aSLionel Sambuc       assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
1989f4a2713aSLionel Sambuc       // The high part is undefined.
1990f4a2713aSLionel Sambuc       Hi = DAG.getUNDEF(NVT);
1991f4a2713aSLionel Sambuc     }
1992f4a2713aSLionel Sambuc   } else if (TLI.isLittleEndian()) {
1993f4a2713aSLionel Sambuc     // Little-endian - low bits are at low addresses.
1994f4a2713aSLionel Sambuc     Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getPointerInfo(),
1995f4a2713aSLionel Sambuc                      isVolatile, isNonTemporal, isInvariant, Alignment,
1996*0a6a1f1dSLionel Sambuc                      AAInfo);
1997f4a2713aSLionel Sambuc 
1998f4a2713aSLionel Sambuc     unsigned ExcessBits =
1999f4a2713aSLionel Sambuc       N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
2000f4a2713aSLionel Sambuc     EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
2001f4a2713aSLionel Sambuc 
2002f4a2713aSLionel Sambuc     // Increment the pointer to the other half.
2003f4a2713aSLionel Sambuc     unsigned IncrementSize = NVT.getSizeInBits()/8;
2004f4a2713aSLionel Sambuc     Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
2005f4a2713aSLionel Sambuc                       DAG.getConstant(IncrementSize, Ptr.getValueType()));
2006f4a2713aSLionel Sambuc     Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr,
2007f4a2713aSLionel Sambuc                         N->getPointerInfo().getWithOffset(IncrementSize), NEVT,
2008*0a6a1f1dSLionel Sambuc                         isVolatile, isNonTemporal, isInvariant,
2009*0a6a1f1dSLionel Sambuc                         MinAlign(Alignment, IncrementSize), AAInfo);
2010f4a2713aSLionel Sambuc 
2011f4a2713aSLionel Sambuc     // Build a factor node to remember that this load is independent of the
2012f4a2713aSLionel Sambuc     // other one.
2013f4a2713aSLionel Sambuc     Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
2014f4a2713aSLionel Sambuc                      Hi.getValue(1));
2015f4a2713aSLionel Sambuc   } else {
2016f4a2713aSLionel Sambuc     // Big-endian - high bits are at low addresses.  Favor aligned loads at
2017f4a2713aSLionel Sambuc     // the cost of some bit-fiddling.
2018f4a2713aSLionel Sambuc     EVT MemVT = N->getMemoryVT();
2019f4a2713aSLionel Sambuc     unsigned EBytes = MemVT.getStoreSize();
2020f4a2713aSLionel Sambuc     unsigned IncrementSize = NVT.getSizeInBits()/8;
2021f4a2713aSLionel Sambuc     unsigned ExcessBits = (EBytes - IncrementSize)*8;
2022f4a2713aSLionel Sambuc 
2023f4a2713aSLionel Sambuc     // Load both the high bits and maybe some of the low bits.
2024f4a2713aSLionel Sambuc     Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
2025f4a2713aSLionel Sambuc                         EVT::getIntegerVT(*DAG.getContext(),
2026f4a2713aSLionel Sambuc                                           MemVT.getSizeInBits() - ExcessBits),
2027*0a6a1f1dSLionel Sambuc                         isVolatile, isNonTemporal, isInvariant, Alignment,
2028*0a6a1f1dSLionel Sambuc                         AAInfo);
2029f4a2713aSLionel Sambuc 
2030f4a2713aSLionel Sambuc     // Increment the pointer to the other half.
2031f4a2713aSLionel Sambuc     Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
2032f4a2713aSLionel Sambuc                       DAG.getConstant(IncrementSize, Ptr.getValueType()));
2033f4a2713aSLionel Sambuc     // Load the rest of the low bits.
2034f4a2713aSLionel Sambuc     Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr,
2035f4a2713aSLionel Sambuc                         N->getPointerInfo().getWithOffset(IncrementSize),
2036f4a2713aSLionel Sambuc                         EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
2037*0a6a1f1dSLionel Sambuc                         isVolatile, isNonTemporal, isInvariant,
2038*0a6a1f1dSLionel Sambuc                         MinAlign(Alignment, IncrementSize), AAInfo);
2039f4a2713aSLionel Sambuc 
2040f4a2713aSLionel Sambuc     // Build a factor node to remember that this load is independent of the
2041f4a2713aSLionel Sambuc     // other one.
2042f4a2713aSLionel Sambuc     Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
2043f4a2713aSLionel Sambuc                      Hi.getValue(1));
2044f4a2713aSLionel Sambuc 
2045f4a2713aSLionel Sambuc     if (ExcessBits < NVT.getSizeInBits()) {
2046f4a2713aSLionel Sambuc       // Transfer low bits from the bottom of Hi to the top of Lo.
2047f4a2713aSLionel Sambuc       Lo = DAG.getNode(ISD::OR, dl, NVT, Lo,
2048f4a2713aSLionel Sambuc                        DAG.getNode(ISD::SHL, dl, NVT, Hi,
2049f4a2713aSLionel Sambuc                                    DAG.getConstant(ExcessBits,
2050f4a2713aSLionel Sambuc                                                    TLI.getPointerTy())));
2051f4a2713aSLionel Sambuc       // Move high bits to the right position in Hi.
2052f4a2713aSLionel Sambuc       Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl,
2053f4a2713aSLionel Sambuc                        NVT, Hi,
2054f4a2713aSLionel Sambuc                        DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
2055f4a2713aSLionel Sambuc                                        TLI.getPointerTy()));
2056f4a2713aSLionel Sambuc     }
2057f4a2713aSLionel Sambuc   }
2058f4a2713aSLionel Sambuc 
2059f4a2713aSLionel Sambuc   // Legalized the chain result - switch anything that used the old chain to
2060f4a2713aSLionel Sambuc   // use the new one.
2061f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Ch);
2062f4a2713aSLionel Sambuc }
2063f4a2713aSLionel Sambuc 
ExpandIntRes_Logical(SDNode * N,SDValue & Lo,SDValue & Hi)2064f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
2065f4a2713aSLionel Sambuc                                             SDValue &Lo, SDValue &Hi) {
2066f4a2713aSLionel Sambuc   SDLoc dl(N);
2067f4a2713aSLionel Sambuc   SDValue LL, LH, RL, RH;
2068f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), LL, LH);
2069f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(1), RL, RH);
2070f4a2713aSLionel Sambuc   Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL);
2071f4a2713aSLionel Sambuc   Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH);
2072f4a2713aSLionel Sambuc }
2073f4a2713aSLionel Sambuc 
ExpandIntRes_MUL(SDNode * N,SDValue & Lo,SDValue & Hi)2074f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
2075f4a2713aSLionel Sambuc                                         SDValue &Lo, SDValue &Hi) {
2076f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
2077f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2078f4a2713aSLionel Sambuc   SDLoc dl(N);
2079f4a2713aSLionel Sambuc 
2080f4a2713aSLionel Sambuc   SDValue LL, LH, RL, RH;
2081f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), LL, LH);
2082f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(1), RL, RH);
2083f4a2713aSLionel Sambuc 
2084*0a6a1f1dSLionel Sambuc   if (TLI.expandMUL(N, Lo, Hi, NVT, DAG, LL, LH, RL, RH))
2085f4a2713aSLionel Sambuc     return;
2086f4a2713aSLionel Sambuc 
2087f4a2713aSLionel Sambuc   // If nothing else, we can make a libcall.
2088f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2089f4a2713aSLionel Sambuc   if (VT == MVT::i16)
2090f4a2713aSLionel Sambuc     LC = RTLIB::MUL_I16;
2091f4a2713aSLionel Sambuc   else if (VT == MVT::i32)
2092f4a2713aSLionel Sambuc     LC = RTLIB::MUL_I32;
2093f4a2713aSLionel Sambuc   else if (VT == MVT::i64)
2094f4a2713aSLionel Sambuc     LC = RTLIB::MUL_I64;
2095f4a2713aSLionel Sambuc   else if (VT == MVT::i128)
2096f4a2713aSLionel Sambuc     LC = RTLIB::MUL_I128;
2097f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!");
2098f4a2713aSLionel Sambuc 
2099f4a2713aSLionel Sambuc   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2100f4a2713aSLionel Sambuc   SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, 2, true/*irrelevant*/,
2101f4a2713aSLionel Sambuc                                dl).first,
2102f4a2713aSLionel Sambuc                Lo, Hi);
2103f4a2713aSLionel Sambuc }
2104f4a2713aSLionel Sambuc 
ExpandIntRes_SADDSUBO(SDNode * Node,SDValue & Lo,SDValue & Hi)2105f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node,
2106f4a2713aSLionel Sambuc                                              SDValue &Lo, SDValue &Hi) {
2107f4a2713aSLionel Sambuc   SDValue LHS = Node->getOperand(0);
2108f4a2713aSLionel Sambuc   SDValue RHS = Node->getOperand(1);
2109f4a2713aSLionel Sambuc   SDLoc dl(Node);
2110f4a2713aSLionel Sambuc 
2111f4a2713aSLionel Sambuc   // Expand the result by simply replacing it with the equivalent
2112f4a2713aSLionel Sambuc   // non-overflow-checking operation.
2113f4a2713aSLionel Sambuc   SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
2114f4a2713aSLionel Sambuc                             ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
2115f4a2713aSLionel Sambuc                             LHS, RHS);
2116f4a2713aSLionel Sambuc   SplitInteger(Sum, Lo, Hi);
2117f4a2713aSLionel Sambuc 
2118f4a2713aSLionel Sambuc   // Compute the overflow.
2119f4a2713aSLionel Sambuc   //
2120f4a2713aSLionel Sambuc   //   LHSSign -> LHS >= 0
2121f4a2713aSLionel Sambuc   //   RHSSign -> RHS >= 0
2122f4a2713aSLionel Sambuc   //   SumSign -> Sum >= 0
2123f4a2713aSLionel Sambuc   //
2124f4a2713aSLionel Sambuc   //   Add:
2125f4a2713aSLionel Sambuc   //   Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
2126f4a2713aSLionel Sambuc   //   Sub:
2127f4a2713aSLionel Sambuc   //   Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
2128f4a2713aSLionel Sambuc   //
2129f4a2713aSLionel Sambuc   EVT OType = Node->getValueType(1);
2130f4a2713aSLionel Sambuc   SDValue Zero = DAG.getConstant(0, LHS.getValueType());
2131f4a2713aSLionel Sambuc 
2132f4a2713aSLionel Sambuc   SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE);
2133f4a2713aSLionel Sambuc   SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE);
2134f4a2713aSLionel Sambuc   SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
2135f4a2713aSLionel Sambuc                                     Node->getOpcode() == ISD::SADDO ?
2136f4a2713aSLionel Sambuc                                     ISD::SETEQ : ISD::SETNE);
2137f4a2713aSLionel Sambuc 
2138f4a2713aSLionel Sambuc   SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE);
2139f4a2713aSLionel Sambuc   SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
2140f4a2713aSLionel Sambuc 
2141f4a2713aSLionel Sambuc   SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE);
2142f4a2713aSLionel Sambuc 
2143f4a2713aSLionel Sambuc   // Use the calculated overflow everywhere.
2144f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(Node, 1), Cmp);
2145f4a2713aSLionel Sambuc }
2146f4a2713aSLionel Sambuc 
ExpandIntRes_SDIV(SDNode * N,SDValue & Lo,SDValue & Hi)2147f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
2148f4a2713aSLionel Sambuc                                          SDValue &Lo, SDValue &Hi) {
2149f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
2150f4a2713aSLionel Sambuc   SDLoc dl(N);
2151f4a2713aSLionel Sambuc 
2152f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2153f4a2713aSLionel Sambuc   if (VT == MVT::i16)
2154f4a2713aSLionel Sambuc     LC = RTLIB::SDIV_I16;
2155f4a2713aSLionel Sambuc   else if (VT == MVT::i32)
2156f4a2713aSLionel Sambuc     LC = RTLIB::SDIV_I32;
2157f4a2713aSLionel Sambuc   else if (VT == MVT::i64)
2158f4a2713aSLionel Sambuc     LC = RTLIB::SDIV_I64;
2159f4a2713aSLionel Sambuc   else if (VT == MVT::i128)
2160f4a2713aSLionel Sambuc     LC = RTLIB::SDIV_I128;
2161f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
2162f4a2713aSLionel Sambuc 
2163f4a2713aSLionel Sambuc   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2164f4a2713aSLionel Sambuc   SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, 2, true, dl).first, Lo, Hi);
2165f4a2713aSLionel Sambuc }
2166f4a2713aSLionel Sambuc 
ExpandIntRes_Shift(SDNode * N,SDValue & Lo,SDValue & Hi)2167f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
2168f4a2713aSLionel Sambuc                                           SDValue &Lo, SDValue &Hi) {
2169f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
2170f4a2713aSLionel Sambuc   SDLoc dl(N);
2171f4a2713aSLionel Sambuc 
2172f4a2713aSLionel Sambuc   // If we can emit an efficient shift operation, do so now.  Check to see if
2173f4a2713aSLionel Sambuc   // the RHS is a constant.
2174f4a2713aSLionel Sambuc   if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
2175f4a2713aSLionel Sambuc     return ExpandShiftByConstant(N, CN->getZExtValue(), Lo, Hi);
2176f4a2713aSLionel Sambuc 
2177f4a2713aSLionel Sambuc   // If we can determine that the high bit of the shift is zero or one, even if
2178f4a2713aSLionel Sambuc   // the low bits are variable, emit this shift in an optimized form.
2179f4a2713aSLionel Sambuc   if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
2180f4a2713aSLionel Sambuc     return;
2181f4a2713aSLionel Sambuc 
2182f4a2713aSLionel Sambuc   // If this target supports shift_PARTS, use it.  First, map to the _PARTS opc.
2183f4a2713aSLionel Sambuc   unsigned PartsOpc;
2184f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::SHL) {
2185f4a2713aSLionel Sambuc     PartsOpc = ISD::SHL_PARTS;
2186f4a2713aSLionel Sambuc   } else if (N->getOpcode() == ISD::SRL) {
2187f4a2713aSLionel Sambuc     PartsOpc = ISD::SRL_PARTS;
2188f4a2713aSLionel Sambuc   } else {
2189f4a2713aSLionel Sambuc     assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
2190f4a2713aSLionel Sambuc     PartsOpc = ISD::SRA_PARTS;
2191f4a2713aSLionel Sambuc   }
2192f4a2713aSLionel Sambuc 
2193f4a2713aSLionel Sambuc   // Next check to see if the target supports this SHL_PARTS operation or if it
2194f4a2713aSLionel Sambuc   // will custom expand it.
2195f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2196f4a2713aSLionel Sambuc   TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
2197f4a2713aSLionel Sambuc   if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
2198f4a2713aSLionel Sambuc       Action == TargetLowering::Custom) {
2199f4a2713aSLionel Sambuc     // Expand the subcomponents.
2200f4a2713aSLionel Sambuc     SDValue LHSL, LHSH;
2201f4a2713aSLionel Sambuc     GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
2202f4a2713aSLionel Sambuc     EVT VT = LHSL.getValueType();
2203f4a2713aSLionel Sambuc 
2204f4a2713aSLionel Sambuc     // If the shift amount operand is coming from a vector legalization it may
2205f4a2713aSLionel Sambuc     // have an illegal type.  Fix that first by casting the operand, otherwise
2206f4a2713aSLionel Sambuc     // the new SHL_PARTS operation would need further legalization.
2207f4a2713aSLionel Sambuc     SDValue ShiftOp = N->getOperand(1);
2208f4a2713aSLionel Sambuc     EVT ShiftTy = TLI.getShiftAmountTy(VT);
2209f4a2713aSLionel Sambuc     assert(ShiftTy.getScalarType().getSizeInBits() >=
2210f4a2713aSLionel Sambuc            Log2_32_Ceil(VT.getScalarType().getSizeInBits()) &&
2211f4a2713aSLionel Sambuc            "ShiftAmountTy is too small to cover the range of this type!");
2212f4a2713aSLionel Sambuc     if (ShiftOp.getValueType() != ShiftTy)
2213f4a2713aSLionel Sambuc       ShiftOp = DAG.getZExtOrTrunc(ShiftOp, dl, ShiftTy);
2214f4a2713aSLionel Sambuc 
2215f4a2713aSLionel Sambuc     SDValue Ops[] = { LHSL, LHSH, ShiftOp };
2216*0a6a1f1dSLionel Sambuc     Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops);
2217f4a2713aSLionel Sambuc     Hi = Lo.getValue(1);
2218f4a2713aSLionel Sambuc     return;
2219f4a2713aSLionel Sambuc   }
2220f4a2713aSLionel Sambuc 
2221f4a2713aSLionel Sambuc   // Otherwise, emit a libcall.
2222f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2223f4a2713aSLionel Sambuc   bool isSigned;
2224f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::SHL) {
2225f4a2713aSLionel Sambuc     isSigned = false; /*sign irrelevant*/
2226f4a2713aSLionel Sambuc     if (VT == MVT::i16)
2227f4a2713aSLionel Sambuc       LC = RTLIB::SHL_I16;
2228f4a2713aSLionel Sambuc     else if (VT == MVT::i32)
2229f4a2713aSLionel Sambuc       LC = RTLIB::SHL_I32;
2230f4a2713aSLionel Sambuc     else if (VT == MVT::i64)
2231f4a2713aSLionel Sambuc       LC = RTLIB::SHL_I64;
2232f4a2713aSLionel Sambuc     else if (VT == MVT::i128)
2233f4a2713aSLionel Sambuc       LC = RTLIB::SHL_I128;
2234f4a2713aSLionel Sambuc   } else if (N->getOpcode() == ISD::SRL) {
2235f4a2713aSLionel Sambuc     isSigned = false;
2236f4a2713aSLionel Sambuc     if (VT == MVT::i16)
2237f4a2713aSLionel Sambuc       LC = RTLIB::SRL_I16;
2238f4a2713aSLionel Sambuc     else if (VT == MVT::i32)
2239f4a2713aSLionel Sambuc       LC = RTLIB::SRL_I32;
2240f4a2713aSLionel Sambuc     else if (VT == MVT::i64)
2241f4a2713aSLionel Sambuc       LC = RTLIB::SRL_I64;
2242f4a2713aSLionel Sambuc     else if (VT == MVT::i128)
2243f4a2713aSLionel Sambuc       LC = RTLIB::SRL_I128;
2244f4a2713aSLionel Sambuc   } else {
2245f4a2713aSLionel Sambuc     assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
2246f4a2713aSLionel Sambuc     isSigned = true;
2247f4a2713aSLionel Sambuc     if (VT == MVT::i16)
2248f4a2713aSLionel Sambuc       LC = RTLIB::SRA_I16;
2249f4a2713aSLionel Sambuc     else if (VT == MVT::i32)
2250f4a2713aSLionel Sambuc       LC = RTLIB::SRA_I32;
2251f4a2713aSLionel Sambuc     else if (VT == MVT::i64)
2252f4a2713aSLionel Sambuc       LC = RTLIB::SRA_I64;
2253f4a2713aSLionel Sambuc     else if (VT == MVT::i128)
2254f4a2713aSLionel Sambuc       LC = RTLIB::SRA_I128;
2255f4a2713aSLionel Sambuc   }
2256f4a2713aSLionel Sambuc 
2257f4a2713aSLionel Sambuc   if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
2258f4a2713aSLionel Sambuc     SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2259f4a2713aSLionel Sambuc     SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, 2, isSigned, dl).first, Lo,
2260f4a2713aSLionel Sambuc                  Hi);
2261f4a2713aSLionel Sambuc     return;
2262f4a2713aSLionel Sambuc   }
2263f4a2713aSLionel Sambuc 
2264f4a2713aSLionel Sambuc   if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi))
2265f4a2713aSLionel Sambuc     llvm_unreachable("Unsupported shift!");
2266f4a2713aSLionel Sambuc }
2267f4a2713aSLionel Sambuc 
ExpandIntRes_SIGN_EXTEND(SDNode * N,SDValue & Lo,SDValue & Hi)2268f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
2269f4a2713aSLionel Sambuc                                                 SDValue &Lo, SDValue &Hi) {
2270f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2271f4a2713aSLionel Sambuc   SDLoc dl(N);
2272f4a2713aSLionel Sambuc   SDValue Op = N->getOperand(0);
2273f4a2713aSLionel Sambuc   if (Op.getValueType().bitsLE(NVT)) {
2274f4a2713aSLionel Sambuc     // The low part is sign extension of the input (degenerates to a copy).
2275f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
2276f4a2713aSLionel Sambuc     // The high part is obtained by SRA'ing all but one of the bits of low part.
2277f4a2713aSLionel Sambuc     unsigned LoSize = NVT.getSizeInBits();
2278f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
2279f4a2713aSLionel Sambuc                      DAG.getConstant(LoSize-1, TLI.getPointerTy()));
2280f4a2713aSLionel Sambuc   } else {
2281f4a2713aSLionel Sambuc     // For example, extension of an i48 to an i64.  The operand type necessarily
2282f4a2713aSLionel Sambuc     // promotes to the result type, so will end up being expanded too.
2283f4a2713aSLionel Sambuc     assert(getTypeAction(Op.getValueType()) ==
2284f4a2713aSLionel Sambuc            TargetLowering::TypePromoteInteger &&
2285f4a2713aSLionel Sambuc            "Only know how to promote this result!");
2286f4a2713aSLionel Sambuc     SDValue Res = GetPromotedInteger(Op);
2287f4a2713aSLionel Sambuc     assert(Res.getValueType() == N->getValueType(0) &&
2288f4a2713aSLionel Sambuc            "Operand over promoted?");
2289f4a2713aSLionel Sambuc     // Split the promoted operand.  This will simplify when it is expanded.
2290f4a2713aSLionel Sambuc     SplitInteger(Res, Lo, Hi);
2291f4a2713aSLionel Sambuc     unsigned ExcessBits =
2292f4a2713aSLionel Sambuc       Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
2293f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
2294f4a2713aSLionel Sambuc                      DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
2295f4a2713aSLionel Sambuc                                                         ExcessBits)));
2296f4a2713aSLionel Sambuc   }
2297f4a2713aSLionel Sambuc }
2298f4a2713aSLionel Sambuc 
2299f4a2713aSLionel Sambuc void DAGTypeLegalizer::
ExpandIntRes_SIGN_EXTEND_INREG(SDNode * N,SDValue & Lo,SDValue & Hi)2300f4a2713aSLionel Sambuc ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
2301f4a2713aSLionel Sambuc   SDLoc dl(N);
2302f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Lo, Hi);
2303f4a2713aSLionel Sambuc   EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
2304f4a2713aSLionel Sambuc 
2305f4a2713aSLionel Sambuc   if (EVT.bitsLE(Lo.getValueType())) {
2306f4a2713aSLionel Sambuc     // sext_inreg the low part if needed.
2307f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
2308f4a2713aSLionel Sambuc                      N->getOperand(1));
2309f4a2713aSLionel Sambuc 
2310f4a2713aSLionel Sambuc     // The high part gets the sign extension from the lo-part.  This handles
2311f4a2713aSLionel Sambuc     // things like sextinreg V:i64 from i8.
2312f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
2313f4a2713aSLionel Sambuc                      DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
2314f4a2713aSLionel Sambuc                                      TLI.getPointerTy()));
2315f4a2713aSLionel Sambuc   } else {
2316f4a2713aSLionel Sambuc     // For example, extension of an i48 to an i64.  Leave the low part alone,
2317f4a2713aSLionel Sambuc     // sext_inreg the high part.
2318f4a2713aSLionel Sambuc     unsigned ExcessBits =
2319f4a2713aSLionel Sambuc       EVT.getSizeInBits() - Lo.getValueType().getSizeInBits();
2320f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
2321f4a2713aSLionel Sambuc                      DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
2322f4a2713aSLionel Sambuc                                                         ExcessBits)));
2323f4a2713aSLionel Sambuc   }
2324f4a2713aSLionel Sambuc }
2325f4a2713aSLionel Sambuc 
ExpandIntRes_SREM(SDNode * N,SDValue & Lo,SDValue & Hi)2326f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
2327f4a2713aSLionel Sambuc                                          SDValue &Lo, SDValue &Hi) {
2328f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
2329f4a2713aSLionel Sambuc   SDLoc dl(N);
2330f4a2713aSLionel Sambuc 
2331f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2332f4a2713aSLionel Sambuc   if (VT == MVT::i16)
2333f4a2713aSLionel Sambuc     LC = RTLIB::SREM_I16;
2334f4a2713aSLionel Sambuc   else if (VT == MVT::i32)
2335f4a2713aSLionel Sambuc     LC = RTLIB::SREM_I32;
2336f4a2713aSLionel Sambuc   else if (VT == MVT::i64)
2337f4a2713aSLionel Sambuc     LC = RTLIB::SREM_I64;
2338f4a2713aSLionel Sambuc   else if (VT == MVT::i128)
2339f4a2713aSLionel Sambuc     LC = RTLIB::SREM_I128;
2340f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
2341f4a2713aSLionel Sambuc 
2342f4a2713aSLionel Sambuc   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2343f4a2713aSLionel Sambuc   SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, 2, true, dl).first, Lo, Hi);
2344f4a2713aSLionel Sambuc }
2345f4a2713aSLionel Sambuc 
ExpandIntRes_TRUNCATE(SDNode * N,SDValue & Lo,SDValue & Hi)2346f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
2347f4a2713aSLionel Sambuc                                              SDValue &Lo, SDValue &Hi) {
2348f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2349f4a2713aSLionel Sambuc   SDLoc dl(N);
2350f4a2713aSLionel Sambuc   Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
2351f4a2713aSLionel Sambuc   Hi = DAG.getNode(ISD::SRL, dl,
2352f4a2713aSLionel Sambuc                    N->getOperand(0).getValueType(), N->getOperand(0),
2353f4a2713aSLionel Sambuc                    DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy()));
2354f4a2713aSLionel Sambuc   Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
2355f4a2713aSLionel Sambuc }
2356f4a2713aSLionel Sambuc 
ExpandIntRes_UADDSUBO(SDNode * N,SDValue & Lo,SDValue & Hi)2357f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_UADDSUBO(SDNode *N,
2358f4a2713aSLionel Sambuc                                              SDValue &Lo, SDValue &Hi) {
2359f4a2713aSLionel Sambuc   SDValue LHS = N->getOperand(0);
2360f4a2713aSLionel Sambuc   SDValue RHS = N->getOperand(1);
2361f4a2713aSLionel Sambuc   SDLoc dl(N);
2362f4a2713aSLionel Sambuc 
2363f4a2713aSLionel Sambuc   // Expand the result by simply replacing it with the equivalent
2364f4a2713aSLionel Sambuc   // non-overflow-checking operation.
2365f4a2713aSLionel Sambuc   SDValue Sum = DAG.getNode(N->getOpcode() == ISD::UADDO ?
2366f4a2713aSLionel Sambuc                             ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
2367f4a2713aSLionel Sambuc                             LHS, RHS);
2368f4a2713aSLionel Sambuc   SplitInteger(Sum, Lo, Hi);
2369f4a2713aSLionel Sambuc 
2370f4a2713aSLionel Sambuc   // Calculate the overflow: addition overflows iff a + b < a, and subtraction
2371f4a2713aSLionel Sambuc   // overflows iff a - b > a.
2372f4a2713aSLionel Sambuc   SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Sum, LHS,
2373f4a2713aSLionel Sambuc                              N->getOpcode () == ISD::UADDO ?
2374f4a2713aSLionel Sambuc                              ISD::SETULT : ISD::SETUGT);
2375f4a2713aSLionel Sambuc 
2376f4a2713aSLionel Sambuc   // Use the calculated overflow everywhere.
2377f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Ofl);
2378f4a2713aSLionel Sambuc }
2379f4a2713aSLionel Sambuc 
ExpandIntRes_XMULO(SDNode * N,SDValue & Lo,SDValue & Hi)2380f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
2381f4a2713aSLionel Sambuc                                           SDValue &Lo, SDValue &Hi) {
2382f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
2383f4a2713aSLionel Sambuc   SDLoc dl(N);
2384f4a2713aSLionel Sambuc 
2385f4a2713aSLionel Sambuc   // A divide for UMULO should be faster than a function call.
2386f4a2713aSLionel Sambuc   if (N->getOpcode() == ISD::UMULO) {
2387f4a2713aSLionel Sambuc     SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
2388f4a2713aSLionel Sambuc 
2389f4a2713aSLionel Sambuc     SDValue MUL = DAG.getNode(ISD::MUL, dl, LHS.getValueType(), LHS, RHS);
2390f4a2713aSLionel Sambuc     SplitInteger(MUL, Lo, Hi);
2391f4a2713aSLionel Sambuc 
2392f4a2713aSLionel Sambuc     // A divide for UMULO will be faster than a function call. Select to
2393f4a2713aSLionel Sambuc     // make sure we aren't using 0.
2394f4a2713aSLionel Sambuc     SDValue isZero = DAG.getSetCC(dl, getSetCCResultType(VT),
2395f4a2713aSLionel Sambuc                                   RHS, DAG.getConstant(0, VT), ISD::SETEQ);
2396f4a2713aSLionel Sambuc     SDValue NotZero = DAG.getSelect(dl, VT, isZero,
2397f4a2713aSLionel Sambuc                                     DAG.getConstant(1, VT), RHS);
2398f4a2713aSLionel Sambuc     SDValue DIV = DAG.getNode(ISD::UDIV, dl, VT, MUL, NotZero);
2399f4a2713aSLionel Sambuc     SDValue Overflow = DAG.getSetCC(dl, N->getValueType(1), DIV, LHS,
2400f4a2713aSLionel Sambuc                                     ISD::SETNE);
2401f4a2713aSLionel Sambuc     Overflow = DAG.getSelect(dl, N->getValueType(1), isZero,
2402f4a2713aSLionel Sambuc                              DAG.getConstant(0, N->getValueType(1)),
2403f4a2713aSLionel Sambuc                              Overflow);
2404f4a2713aSLionel Sambuc     ReplaceValueWith(SDValue(N, 1), Overflow);
2405f4a2713aSLionel Sambuc     return;
2406f4a2713aSLionel Sambuc   }
2407f4a2713aSLionel Sambuc 
2408f4a2713aSLionel Sambuc   Type *RetTy = VT.getTypeForEVT(*DAG.getContext());
2409f4a2713aSLionel Sambuc   EVT PtrVT = TLI.getPointerTy();
2410f4a2713aSLionel Sambuc   Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext());
2411f4a2713aSLionel Sambuc 
2412f4a2713aSLionel Sambuc   // Replace this with a libcall that will check overflow.
2413f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2414f4a2713aSLionel Sambuc   if (VT == MVT::i32)
2415f4a2713aSLionel Sambuc     LC = RTLIB::MULO_I32;
2416f4a2713aSLionel Sambuc   else if (VT == MVT::i64)
2417f4a2713aSLionel Sambuc     LC = RTLIB::MULO_I64;
2418f4a2713aSLionel Sambuc   else if (VT == MVT::i128)
2419f4a2713aSLionel Sambuc     LC = RTLIB::MULO_I128;
2420f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XMULO!");
2421f4a2713aSLionel Sambuc 
2422f4a2713aSLionel Sambuc   SDValue Temp = DAG.CreateStackTemporary(PtrVT);
2423f4a2713aSLionel Sambuc   // Temporary for the overflow value, default it to zero.
2424f4a2713aSLionel Sambuc   SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl,
2425f4a2713aSLionel Sambuc                                DAG.getConstant(0, PtrVT), Temp,
2426f4a2713aSLionel Sambuc                                MachinePointerInfo(), false, false, 0);
2427f4a2713aSLionel Sambuc 
2428f4a2713aSLionel Sambuc   TargetLowering::ArgListTy Args;
2429f4a2713aSLionel Sambuc   TargetLowering::ArgListEntry Entry;
2430f4a2713aSLionel Sambuc   for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
2431f4a2713aSLionel Sambuc     EVT ArgVT = N->getOperand(i).getValueType();
2432f4a2713aSLionel Sambuc     Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
2433f4a2713aSLionel Sambuc     Entry.Node = N->getOperand(i);
2434f4a2713aSLionel Sambuc     Entry.Ty = ArgTy;
2435f4a2713aSLionel Sambuc     Entry.isSExt = true;
2436f4a2713aSLionel Sambuc     Entry.isZExt = false;
2437f4a2713aSLionel Sambuc     Args.push_back(Entry);
2438f4a2713aSLionel Sambuc   }
2439f4a2713aSLionel Sambuc 
2440f4a2713aSLionel Sambuc   // Also pass the address of the overflow check.
2441f4a2713aSLionel Sambuc   Entry.Node = Temp;
2442f4a2713aSLionel Sambuc   Entry.Ty = PtrTy->getPointerTo();
2443f4a2713aSLionel Sambuc   Entry.isSExt = true;
2444f4a2713aSLionel Sambuc   Entry.isZExt = false;
2445f4a2713aSLionel Sambuc   Args.push_back(Entry);
2446f4a2713aSLionel Sambuc 
2447f4a2713aSLionel Sambuc   SDValue Func = DAG.getExternalSymbol(TLI.getLibcallName(LC), PtrVT);
2448*0a6a1f1dSLionel Sambuc 
2449*0a6a1f1dSLionel Sambuc   TargetLowering::CallLoweringInfo CLI(DAG);
2450*0a6a1f1dSLionel Sambuc   CLI.setDebugLoc(dl).setChain(Chain)
2451*0a6a1f1dSLionel Sambuc     .setCallee(TLI.getLibcallCallingConv(LC), RetTy, Func, std::move(Args), 0)
2452*0a6a1f1dSLionel Sambuc     .setSExtResult();
2453*0a6a1f1dSLionel Sambuc 
2454f4a2713aSLionel Sambuc   std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
2455f4a2713aSLionel Sambuc 
2456f4a2713aSLionel Sambuc   SplitInteger(CallInfo.first, Lo, Hi);
2457f4a2713aSLionel Sambuc   SDValue Temp2 = DAG.getLoad(PtrVT, dl, CallInfo.second, Temp,
2458f4a2713aSLionel Sambuc                               MachinePointerInfo(), false, false, false, 0);
2459f4a2713aSLionel Sambuc   SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Temp2,
2460f4a2713aSLionel Sambuc                              DAG.getConstant(0, PtrVT),
2461f4a2713aSLionel Sambuc                              ISD::SETNE);
2462f4a2713aSLionel Sambuc   // Use the overflow from the libcall everywhere.
2463f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Ofl);
2464f4a2713aSLionel Sambuc }
2465f4a2713aSLionel Sambuc 
ExpandIntRes_UDIV(SDNode * N,SDValue & Lo,SDValue & Hi)2466f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
2467f4a2713aSLionel Sambuc                                          SDValue &Lo, SDValue &Hi) {
2468f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
2469f4a2713aSLionel Sambuc   SDLoc dl(N);
2470f4a2713aSLionel Sambuc 
2471f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2472f4a2713aSLionel Sambuc   if (VT == MVT::i16)
2473f4a2713aSLionel Sambuc     LC = RTLIB::UDIV_I16;
2474f4a2713aSLionel Sambuc   else if (VT == MVT::i32)
2475f4a2713aSLionel Sambuc     LC = RTLIB::UDIV_I32;
2476f4a2713aSLionel Sambuc   else if (VT == MVT::i64)
2477f4a2713aSLionel Sambuc     LC = RTLIB::UDIV_I64;
2478f4a2713aSLionel Sambuc   else if (VT == MVT::i128)
2479f4a2713aSLionel Sambuc     LC = RTLIB::UDIV_I128;
2480f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
2481f4a2713aSLionel Sambuc 
2482f4a2713aSLionel Sambuc   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2483f4a2713aSLionel Sambuc   SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, 2, false, dl).first, Lo, Hi);
2484f4a2713aSLionel Sambuc }
2485f4a2713aSLionel Sambuc 
ExpandIntRes_UREM(SDNode * N,SDValue & Lo,SDValue & Hi)2486f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
2487f4a2713aSLionel Sambuc                                          SDValue &Lo, SDValue &Hi) {
2488f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
2489f4a2713aSLionel Sambuc   SDLoc dl(N);
2490f4a2713aSLionel Sambuc 
2491f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2492f4a2713aSLionel Sambuc   if (VT == MVT::i16)
2493f4a2713aSLionel Sambuc     LC = RTLIB::UREM_I16;
2494f4a2713aSLionel Sambuc   else if (VT == MVT::i32)
2495f4a2713aSLionel Sambuc     LC = RTLIB::UREM_I32;
2496f4a2713aSLionel Sambuc   else if (VT == MVT::i64)
2497f4a2713aSLionel Sambuc     LC = RTLIB::UREM_I64;
2498f4a2713aSLionel Sambuc   else if (VT == MVT::i128)
2499f4a2713aSLionel Sambuc     LC = RTLIB::UREM_I128;
2500f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
2501f4a2713aSLionel Sambuc 
2502f4a2713aSLionel Sambuc   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2503f4a2713aSLionel Sambuc   SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, 2, false, dl).first, Lo, Hi);
2504f4a2713aSLionel Sambuc }
2505f4a2713aSLionel Sambuc 
ExpandIntRes_ZERO_EXTEND(SDNode * N,SDValue & Lo,SDValue & Hi)2506f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
2507f4a2713aSLionel Sambuc                                                 SDValue &Lo, SDValue &Hi) {
2508f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2509f4a2713aSLionel Sambuc   SDLoc dl(N);
2510f4a2713aSLionel Sambuc   SDValue Op = N->getOperand(0);
2511f4a2713aSLionel Sambuc   if (Op.getValueType().bitsLE(NVT)) {
2512f4a2713aSLionel Sambuc     // The low part is zero extension of the input (degenerates to a copy).
2513f4a2713aSLionel Sambuc     Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
2514f4a2713aSLionel Sambuc     Hi = DAG.getConstant(0, NVT);   // The high part is just a zero.
2515f4a2713aSLionel Sambuc   } else {
2516f4a2713aSLionel Sambuc     // For example, extension of an i48 to an i64.  The operand type necessarily
2517f4a2713aSLionel Sambuc     // promotes to the result type, so will end up being expanded too.
2518f4a2713aSLionel Sambuc     assert(getTypeAction(Op.getValueType()) ==
2519f4a2713aSLionel Sambuc            TargetLowering::TypePromoteInteger &&
2520f4a2713aSLionel Sambuc            "Only know how to promote this result!");
2521f4a2713aSLionel Sambuc     SDValue Res = GetPromotedInteger(Op);
2522f4a2713aSLionel Sambuc     assert(Res.getValueType() == N->getValueType(0) &&
2523f4a2713aSLionel Sambuc            "Operand over promoted?");
2524f4a2713aSLionel Sambuc     // Split the promoted operand.  This will simplify when it is expanded.
2525f4a2713aSLionel Sambuc     SplitInteger(Res, Lo, Hi);
2526f4a2713aSLionel Sambuc     unsigned ExcessBits =
2527f4a2713aSLionel Sambuc       Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
2528f4a2713aSLionel Sambuc     Hi = DAG.getZeroExtendInReg(Hi, dl,
2529f4a2713aSLionel Sambuc                                 EVT::getIntegerVT(*DAG.getContext(),
2530f4a2713aSLionel Sambuc                                                   ExcessBits));
2531f4a2713aSLionel Sambuc   }
2532f4a2713aSLionel Sambuc }
2533f4a2713aSLionel Sambuc 
ExpandIntRes_ATOMIC_LOAD(SDNode * N,SDValue & Lo,SDValue & Hi)2534f4a2713aSLionel Sambuc void DAGTypeLegalizer::ExpandIntRes_ATOMIC_LOAD(SDNode *N,
2535f4a2713aSLionel Sambuc                                                 SDValue &Lo, SDValue &Hi) {
2536f4a2713aSLionel Sambuc   SDLoc dl(N);
2537f4a2713aSLionel Sambuc   EVT VT = cast<AtomicSDNode>(N)->getMemoryVT();
2538*0a6a1f1dSLionel Sambuc   SDVTList VTs = DAG.getVTList(VT, MVT::i1, MVT::Other);
2539f4a2713aSLionel Sambuc   SDValue Zero = DAG.getConstant(0, VT);
2540*0a6a1f1dSLionel Sambuc   SDValue Swap = DAG.getAtomicCmpSwap(
2541*0a6a1f1dSLionel Sambuc       ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, dl,
2542*0a6a1f1dSLionel Sambuc       cast<AtomicSDNode>(N)->getMemoryVT(), VTs, N->getOperand(0),
2543*0a6a1f1dSLionel Sambuc       N->getOperand(1), Zero, Zero, cast<AtomicSDNode>(N)->getMemOperand(),
2544*0a6a1f1dSLionel Sambuc       cast<AtomicSDNode>(N)->getOrdering(),
2545f4a2713aSLionel Sambuc       cast<AtomicSDNode>(N)->getOrdering(),
2546f4a2713aSLionel Sambuc       cast<AtomicSDNode>(N)->getSynchScope());
2547*0a6a1f1dSLionel Sambuc 
2548f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 0), Swap.getValue(0));
2549*0a6a1f1dSLionel Sambuc   ReplaceValueWith(SDValue(N, 1), Swap.getValue(2));
2550f4a2713aSLionel Sambuc }
2551f4a2713aSLionel Sambuc 
2552f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2553f4a2713aSLionel Sambuc //  Integer Operand Expansion
2554f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2555f4a2713aSLionel Sambuc 
2556f4a2713aSLionel Sambuc /// ExpandIntegerOperand - This method is called when the specified operand of
2557f4a2713aSLionel Sambuc /// the specified node is found to need expansion.  At this point, all of the
2558f4a2713aSLionel Sambuc /// result types of the node are known to be legal, but other operands of the
2559f4a2713aSLionel Sambuc /// node may need promotion or expansion as well as the specified one.
ExpandIntegerOperand(SDNode * N,unsigned OpNo)2560f4a2713aSLionel Sambuc bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
2561f4a2713aSLionel Sambuc   DEBUG(dbgs() << "Expand integer operand: "; N->dump(&DAG); dbgs() << "\n");
2562f4a2713aSLionel Sambuc   SDValue Res = SDValue();
2563f4a2713aSLionel Sambuc 
2564f4a2713aSLionel Sambuc   if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
2565f4a2713aSLionel Sambuc     return false;
2566f4a2713aSLionel Sambuc 
2567f4a2713aSLionel Sambuc   switch (N->getOpcode()) {
2568f4a2713aSLionel Sambuc   default:
2569f4a2713aSLionel Sambuc   #ifndef NDEBUG
2570f4a2713aSLionel Sambuc     dbgs() << "ExpandIntegerOperand Op #" << OpNo << ": ";
2571f4a2713aSLionel Sambuc     N->dump(&DAG); dbgs() << "\n";
2572f4a2713aSLionel Sambuc   #endif
2573f4a2713aSLionel Sambuc     llvm_unreachable("Do not know how to expand this operator's operand!");
2574f4a2713aSLionel Sambuc 
2575f4a2713aSLionel Sambuc   case ISD::BITCAST:           Res = ExpandOp_BITCAST(N); break;
2576f4a2713aSLionel Sambuc   case ISD::BR_CC:             Res = ExpandIntOp_BR_CC(N); break;
2577f4a2713aSLionel Sambuc   case ISD::BUILD_VECTOR:      Res = ExpandOp_BUILD_VECTOR(N); break;
2578f4a2713aSLionel Sambuc   case ISD::EXTRACT_ELEMENT:   Res = ExpandOp_EXTRACT_ELEMENT(N); break;
2579f4a2713aSLionel Sambuc   case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
2580f4a2713aSLionel Sambuc   case ISD::SCALAR_TO_VECTOR:  Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
2581f4a2713aSLionel Sambuc   case ISD::SELECT_CC:         Res = ExpandIntOp_SELECT_CC(N); break;
2582f4a2713aSLionel Sambuc   case ISD::SETCC:             Res = ExpandIntOp_SETCC(N); break;
2583f4a2713aSLionel Sambuc   case ISD::SINT_TO_FP:        Res = ExpandIntOp_SINT_TO_FP(N); break;
2584f4a2713aSLionel Sambuc   case ISD::STORE:   Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
2585f4a2713aSLionel Sambuc   case ISD::TRUNCATE:          Res = ExpandIntOp_TRUNCATE(N); break;
2586f4a2713aSLionel Sambuc   case ISD::UINT_TO_FP:        Res = ExpandIntOp_UINT_TO_FP(N); break;
2587f4a2713aSLionel Sambuc 
2588f4a2713aSLionel Sambuc   case ISD::SHL:
2589f4a2713aSLionel Sambuc   case ISD::SRA:
2590f4a2713aSLionel Sambuc   case ISD::SRL:
2591f4a2713aSLionel Sambuc   case ISD::ROTL:
2592f4a2713aSLionel Sambuc   case ISD::ROTR:              Res = ExpandIntOp_Shift(N); break;
2593f4a2713aSLionel Sambuc   case ISD::RETURNADDR:
2594f4a2713aSLionel Sambuc   case ISD::FRAMEADDR:         Res = ExpandIntOp_RETURNADDR(N); break;
2595f4a2713aSLionel Sambuc 
2596f4a2713aSLionel Sambuc   case ISD::ATOMIC_STORE:      Res = ExpandIntOp_ATOMIC_STORE(N); break;
2597f4a2713aSLionel Sambuc   }
2598f4a2713aSLionel Sambuc 
2599f4a2713aSLionel Sambuc   // If the result is null, the sub-method took care of registering results etc.
2600f4a2713aSLionel Sambuc   if (!Res.getNode()) return false;
2601f4a2713aSLionel Sambuc 
2602f4a2713aSLionel Sambuc   // If the result is N, the sub-method updated N in place.  Tell the legalizer
2603f4a2713aSLionel Sambuc   // core about this.
2604f4a2713aSLionel Sambuc   if (Res.getNode() == N)
2605f4a2713aSLionel Sambuc     return true;
2606f4a2713aSLionel Sambuc 
2607f4a2713aSLionel Sambuc   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
2608f4a2713aSLionel Sambuc          "Invalid operand expansion");
2609f4a2713aSLionel Sambuc 
2610f4a2713aSLionel Sambuc   ReplaceValueWith(SDValue(N, 0), Res);
2611f4a2713aSLionel Sambuc   return false;
2612f4a2713aSLionel Sambuc }
2613f4a2713aSLionel Sambuc 
2614f4a2713aSLionel Sambuc /// IntegerExpandSetCCOperands - Expand the operands of a comparison.  This code
2615f4a2713aSLionel Sambuc /// is shared among BR_CC, SELECT_CC, and SETCC handlers.
IntegerExpandSetCCOperands(SDValue & NewLHS,SDValue & NewRHS,ISD::CondCode & CCCode,SDLoc dl)2616f4a2713aSLionel Sambuc void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
2617f4a2713aSLionel Sambuc                                                   SDValue &NewRHS,
2618f4a2713aSLionel Sambuc                                                   ISD::CondCode &CCCode,
2619f4a2713aSLionel Sambuc                                                   SDLoc dl) {
2620f4a2713aSLionel Sambuc   SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2621f4a2713aSLionel Sambuc   GetExpandedInteger(NewLHS, LHSLo, LHSHi);
2622f4a2713aSLionel Sambuc   GetExpandedInteger(NewRHS, RHSLo, RHSHi);
2623f4a2713aSLionel Sambuc 
2624f4a2713aSLionel Sambuc   if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
2625f4a2713aSLionel Sambuc     if (RHSLo == RHSHi) {
2626f4a2713aSLionel Sambuc       if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) {
2627f4a2713aSLionel Sambuc         if (RHSCST->isAllOnesValue()) {
2628f4a2713aSLionel Sambuc           // Equality comparison to -1.
2629f4a2713aSLionel Sambuc           NewLHS = DAG.getNode(ISD::AND, dl,
2630f4a2713aSLionel Sambuc                                LHSLo.getValueType(), LHSLo, LHSHi);
2631f4a2713aSLionel Sambuc           NewRHS = RHSLo;
2632f4a2713aSLionel Sambuc           return;
2633f4a2713aSLionel Sambuc         }
2634f4a2713aSLionel Sambuc       }
2635f4a2713aSLionel Sambuc     }
2636f4a2713aSLionel Sambuc 
2637f4a2713aSLionel Sambuc     NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
2638f4a2713aSLionel Sambuc     NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
2639f4a2713aSLionel Sambuc     NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
2640f4a2713aSLionel Sambuc     NewRHS = DAG.getConstant(0, NewLHS.getValueType());
2641f4a2713aSLionel Sambuc     return;
2642f4a2713aSLionel Sambuc   }
2643f4a2713aSLionel Sambuc 
2644f4a2713aSLionel Sambuc   // If this is a comparison of the sign bit, just look at the top part.
2645f4a2713aSLionel Sambuc   // X > -1,  x < 0
2646f4a2713aSLionel Sambuc   if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
2647f4a2713aSLionel Sambuc     if ((CCCode == ISD::SETLT && CST->isNullValue()) ||     // X < 0
2648f4a2713aSLionel Sambuc         (CCCode == ISD::SETGT && CST->isAllOnesValue())) {  // X > -1
2649f4a2713aSLionel Sambuc       NewLHS = LHSHi;
2650f4a2713aSLionel Sambuc       NewRHS = RHSHi;
2651f4a2713aSLionel Sambuc       return;
2652f4a2713aSLionel Sambuc     }
2653f4a2713aSLionel Sambuc 
2654f4a2713aSLionel Sambuc   // FIXME: This generated code sucks.
2655f4a2713aSLionel Sambuc   ISD::CondCode LowCC;
2656f4a2713aSLionel Sambuc   switch (CCCode) {
2657f4a2713aSLionel Sambuc   default: llvm_unreachable("Unknown integer setcc!");
2658f4a2713aSLionel Sambuc   case ISD::SETLT:
2659f4a2713aSLionel Sambuc   case ISD::SETULT: LowCC = ISD::SETULT; break;
2660f4a2713aSLionel Sambuc   case ISD::SETGT:
2661f4a2713aSLionel Sambuc   case ISD::SETUGT: LowCC = ISD::SETUGT; break;
2662f4a2713aSLionel Sambuc   case ISD::SETLE:
2663f4a2713aSLionel Sambuc   case ISD::SETULE: LowCC = ISD::SETULE; break;
2664f4a2713aSLionel Sambuc   case ISD::SETGE:
2665f4a2713aSLionel Sambuc   case ISD::SETUGE: LowCC = ISD::SETUGE; break;
2666f4a2713aSLionel Sambuc   }
2667f4a2713aSLionel Sambuc 
2668f4a2713aSLionel Sambuc   // Tmp1 = lo(op1) < lo(op2)   // Always unsigned comparison
2669f4a2713aSLionel Sambuc   // Tmp2 = hi(op1) < hi(op2)   // Signedness depends on operands
2670f4a2713aSLionel Sambuc   // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
2671f4a2713aSLionel Sambuc 
2672f4a2713aSLionel Sambuc   // NOTE: on targets without efficient SELECT of bools, we can always use
2673f4a2713aSLionel Sambuc   // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
2674*0a6a1f1dSLionel Sambuc   TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, AfterLegalizeTypes, true,
2675*0a6a1f1dSLionel Sambuc                                                  nullptr);
2676f4a2713aSLionel Sambuc   SDValue Tmp1, Tmp2;
2677*0a6a1f1dSLionel Sambuc   if (TLI.isTypeLegal(LHSLo.getValueType()) &&
2678*0a6a1f1dSLionel Sambuc       TLI.isTypeLegal(RHSLo.getValueType()))
2679f4a2713aSLionel Sambuc     Tmp1 = TLI.SimplifySetCC(getSetCCResultType(LHSLo.getValueType()),
2680f4a2713aSLionel Sambuc                              LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl);
2681f4a2713aSLionel Sambuc   if (!Tmp1.getNode())
2682f4a2713aSLionel Sambuc     Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()),
2683f4a2713aSLionel Sambuc                         LHSLo, RHSLo, LowCC);
2684*0a6a1f1dSLionel Sambuc   if (TLI.isTypeLegal(LHSHi.getValueType()) &&
2685*0a6a1f1dSLionel Sambuc       TLI.isTypeLegal(RHSHi.getValueType()))
2686f4a2713aSLionel Sambuc     Tmp2 = TLI.SimplifySetCC(getSetCCResultType(LHSHi.getValueType()),
2687f4a2713aSLionel Sambuc                              LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl);
2688f4a2713aSLionel Sambuc   if (!Tmp2.getNode())
2689f4a2713aSLionel Sambuc     Tmp2 = DAG.getNode(ISD::SETCC, dl,
2690f4a2713aSLionel Sambuc                        getSetCCResultType(LHSHi.getValueType()),
2691f4a2713aSLionel Sambuc                        LHSHi, RHSHi, DAG.getCondCode(CCCode));
2692f4a2713aSLionel Sambuc 
2693f4a2713aSLionel Sambuc   ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode());
2694f4a2713aSLionel Sambuc   ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode());
2695f4a2713aSLionel Sambuc   if ((Tmp1C && Tmp1C->isNullValue()) ||
2696f4a2713aSLionel Sambuc       (Tmp2C && Tmp2C->isNullValue() &&
2697f4a2713aSLionel Sambuc        (CCCode == ISD::SETLE || CCCode == ISD::SETGE ||
2698f4a2713aSLionel Sambuc         CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) ||
2699f4a2713aSLionel Sambuc       (Tmp2C && Tmp2C->getAPIntValue() == 1 &&
2700f4a2713aSLionel Sambuc        (CCCode == ISD::SETLT || CCCode == ISD::SETGT ||
2701f4a2713aSLionel Sambuc         CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) {
2702f4a2713aSLionel Sambuc     // low part is known false, returns high part.
2703f4a2713aSLionel Sambuc     // For LE / GE, if high part is known false, ignore the low part.
2704f4a2713aSLionel Sambuc     // For LT / GT, if high part is known true, ignore the low part.
2705f4a2713aSLionel Sambuc     NewLHS = Tmp2;
2706f4a2713aSLionel Sambuc     NewRHS = SDValue();
2707f4a2713aSLionel Sambuc     return;
2708f4a2713aSLionel Sambuc   }
2709f4a2713aSLionel Sambuc 
2710f4a2713aSLionel Sambuc   NewLHS = TLI.SimplifySetCC(getSetCCResultType(LHSHi.getValueType()),
2711f4a2713aSLionel Sambuc                              LHSHi, RHSHi, ISD::SETEQ, false,
2712f4a2713aSLionel Sambuc                              DagCombineInfo, dl);
2713f4a2713aSLionel Sambuc   if (!NewLHS.getNode())
2714f4a2713aSLionel Sambuc     NewLHS = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()),
2715f4a2713aSLionel Sambuc                           LHSHi, RHSHi, ISD::SETEQ);
2716f4a2713aSLionel Sambuc   NewLHS = DAG.getSelect(dl, Tmp1.getValueType(),
2717f4a2713aSLionel Sambuc                          NewLHS, Tmp1, Tmp2);
2718f4a2713aSLionel Sambuc   NewRHS = SDValue();
2719f4a2713aSLionel Sambuc }
2720f4a2713aSLionel Sambuc 
ExpandIntOp_BR_CC(SDNode * N)2721f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
2722f4a2713aSLionel Sambuc   SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
2723f4a2713aSLionel Sambuc   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
2724f4a2713aSLionel Sambuc   IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
2725f4a2713aSLionel Sambuc 
2726f4a2713aSLionel Sambuc   // If ExpandSetCCOperands returned a scalar, we need to compare the result
2727f4a2713aSLionel Sambuc   // against zero to select between true and false values.
2728*0a6a1f1dSLionel Sambuc   if (!NewRHS.getNode()) {
2729f4a2713aSLionel Sambuc     NewRHS = DAG.getConstant(0, NewLHS.getValueType());
2730f4a2713aSLionel Sambuc     CCCode = ISD::SETNE;
2731f4a2713aSLionel Sambuc   }
2732f4a2713aSLionel Sambuc 
2733f4a2713aSLionel Sambuc   // Update N to have the operands specified.
2734f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2735f4a2713aSLionel Sambuc                                 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2736f4a2713aSLionel Sambuc                                 N->getOperand(4)), 0);
2737f4a2713aSLionel Sambuc }
2738f4a2713aSLionel Sambuc 
ExpandIntOp_SELECT_CC(SDNode * N)2739f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
2740f4a2713aSLionel Sambuc   SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
2741f4a2713aSLionel Sambuc   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
2742f4a2713aSLionel Sambuc   IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
2743f4a2713aSLionel Sambuc 
2744f4a2713aSLionel Sambuc   // If ExpandSetCCOperands returned a scalar, we need to compare the result
2745f4a2713aSLionel Sambuc   // against zero to select between true and false values.
2746*0a6a1f1dSLionel Sambuc   if (!NewRHS.getNode()) {
2747f4a2713aSLionel Sambuc     NewRHS = DAG.getConstant(0, NewLHS.getValueType());
2748f4a2713aSLionel Sambuc     CCCode = ISD::SETNE;
2749f4a2713aSLionel Sambuc   }
2750f4a2713aSLionel Sambuc 
2751f4a2713aSLionel Sambuc   // Update N to have the operands specified.
2752f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
2753f4a2713aSLionel Sambuc                                 N->getOperand(2), N->getOperand(3),
2754f4a2713aSLionel Sambuc                                 DAG.getCondCode(CCCode)), 0);
2755f4a2713aSLionel Sambuc }
2756f4a2713aSLionel Sambuc 
ExpandIntOp_SETCC(SDNode * N)2757f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
2758f4a2713aSLionel Sambuc   SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
2759f4a2713aSLionel Sambuc   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
2760f4a2713aSLionel Sambuc   IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N));
2761f4a2713aSLionel Sambuc 
2762f4a2713aSLionel Sambuc   // If ExpandSetCCOperands returned a scalar, use it.
2763*0a6a1f1dSLionel Sambuc   if (!NewRHS.getNode()) {
2764f4a2713aSLionel Sambuc     assert(NewLHS.getValueType() == N->getValueType(0) &&
2765f4a2713aSLionel Sambuc            "Unexpected setcc expansion!");
2766f4a2713aSLionel Sambuc     return NewLHS;
2767f4a2713aSLionel Sambuc   }
2768f4a2713aSLionel Sambuc 
2769f4a2713aSLionel Sambuc   // Otherwise, update N to have the operands specified.
2770f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
2771f4a2713aSLionel Sambuc                                 DAG.getCondCode(CCCode)), 0);
2772f4a2713aSLionel Sambuc }
2773f4a2713aSLionel Sambuc 
ExpandIntOp_Shift(SDNode * N)2774f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
2775f4a2713aSLionel Sambuc   // The value being shifted is legal, but the shift amount is too big.
2776f4a2713aSLionel Sambuc   // It follows that either the result of the shift is undefined, or the
2777f4a2713aSLionel Sambuc   // upper half of the shift amount is zero.  Just use the lower half.
2778f4a2713aSLionel Sambuc   SDValue Lo, Hi;
2779f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(1), Lo, Hi);
2780f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0);
2781f4a2713aSLionel Sambuc }
2782f4a2713aSLionel Sambuc 
ExpandIntOp_RETURNADDR(SDNode * N)2783f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) {
2784f4a2713aSLionel Sambuc   // The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant.  This
2785f4a2713aSLionel Sambuc   // surely makes pretty nice problems on 8/16 bit targets. Just truncate this
2786f4a2713aSLionel Sambuc   // constant to valid type.
2787f4a2713aSLionel Sambuc   SDValue Lo, Hi;
2788f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), Lo, Hi);
2789f4a2713aSLionel Sambuc   return SDValue(DAG.UpdateNodeOperands(N, Lo), 0);
2790f4a2713aSLionel Sambuc }
2791f4a2713aSLionel Sambuc 
ExpandIntOp_SINT_TO_FP(SDNode * N)2792f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) {
2793f4a2713aSLionel Sambuc   SDValue Op = N->getOperand(0);
2794f4a2713aSLionel Sambuc   EVT DstVT = N->getValueType(0);
2795f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT);
2796f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL &&
2797f4a2713aSLionel Sambuc          "Don't know how to expand this SINT_TO_FP!");
2798f4a2713aSLionel Sambuc   return TLI.makeLibCall(DAG, LC, DstVT, &Op, 1, true, SDLoc(N)).first;
2799f4a2713aSLionel Sambuc }
2800f4a2713aSLionel Sambuc 
ExpandIntOp_STORE(StoreSDNode * N,unsigned OpNo)2801f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
2802f4a2713aSLionel Sambuc   if (ISD::isNormalStore(N))
2803f4a2713aSLionel Sambuc     return ExpandOp_NormalStore(N, OpNo);
2804f4a2713aSLionel Sambuc 
2805f4a2713aSLionel Sambuc   assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
2806f4a2713aSLionel Sambuc   assert(OpNo == 1 && "Can only expand the stored value so far");
2807f4a2713aSLionel Sambuc 
2808f4a2713aSLionel Sambuc   EVT VT = N->getOperand(1).getValueType();
2809f4a2713aSLionel Sambuc   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2810f4a2713aSLionel Sambuc   SDValue Ch  = N->getChain();
2811f4a2713aSLionel Sambuc   SDValue Ptr = N->getBasePtr();
2812f4a2713aSLionel Sambuc   unsigned Alignment = N->getAlignment();
2813f4a2713aSLionel Sambuc   bool isVolatile = N->isVolatile();
2814f4a2713aSLionel Sambuc   bool isNonTemporal = N->isNonTemporal();
2815*0a6a1f1dSLionel Sambuc   AAMDNodes AAInfo = N->getAAInfo();
2816f4a2713aSLionel Sambuc   SDLoc dl(N);
2817f4a2713aSLionel Sambuc   SDValue Lo, Hi;
2818f4a2713aSLionel Sambuc 
2819f4a2713aSLionel Sambuc   assert(NVT.isByteSized() && "Expanded type not byte sized!");
2820f4a2713aSLionel Sambuc 
2821f4a2713aSLionel Sambuc   if (N->getMemoryVT().bitsLE(NVT)) {
2822f4a2713aSLionel Sambuc     GetExpandedInteger(N->getValue(), Lo, Hi);
2823f4a2713aSLionel Sambuc     return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
2824f4a2713aSLionel Sambuc                              N->getMemoryVT(), isVolatile, isNonTemporal,
2825*0a6a1f1dSLionel Sambuc                              Alignment, AAInfo);
2826f4a2713aSLionel Sambuc   }
2827f4a2713aSLionel Sambuc 
2828f4a2713aSLionel Sambuc   if (TLI.isLittleEndian()) {
2829f4a2713aSLionel Sambuc     // Little-endian - low bits are at low addresses.
2830f4a2713aSLionel Sambuc     GetExpandedInteger(N->getValue(), Lo, Hi);
2831f4a2713aSLionel Sambuc 
2832f4a2713aSLionel Sambuc     Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
2833*0a6a1f1dSLionel Sambuc                       isVolatile, isNonTemporal, Alignment, AAInfo);
2834f4a2713aSLionel Sambuc 
2835f4a2713aSLionel Sambuc     unsigned ExcessBits =
2836f4a2713aSLionel Sambuc       N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
2837f4a2713aSLionel Sambuc     EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
2838f4a2713aSLionel Sambuc 
2839f4a2713aSLionel Sambuc     // Increment the pointer to the other half.
2840f4a2713aSLionel Sambuc     unsigned IncrementSize = NVT.getSizeInBits()/8;
2841f4a2713aSLionel Sambuc     Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
2842f4a2713aSLionel Sambuc                       DAG.getConstant(IncrementSize, Ptr.getValueType()));
2843f4a2713aSLionel Sambuc     Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
2844f4a2713aSLionel Sambuc                            N->getPointerInfo().getWithOffset(IncrementSize),
2845f4a2713aSLionel Sambuc                            NEVT, isVolatile, isNonTemporal,
2846*0a6a1f1dSLionel Sambuc                            MinAlign(Alignment, IncrementSize), AAInfo);
2847f4a2713aSLionel Sambuc     return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2848f4a2713aSLionel Sambuc   }
2849f4a2713aSLionel Sambuc 
2850f4a2713aSLionel Sambuc   // Big-endian - high bits are at low addresses.  Favor aligned stores at
2851f4a2713aSLionel Sambuc   // the cost of some bit-fiddling.
2852f4a2713aSLionel Sambuc   GetExpandedInteger(N->getValue(), Lo, Hi);
2853f4a2713aSLionel Sambuc 
2854f4a2713aSLionel Sambuc   EVT ExtVT = N->getMemoryVT();
2855f4a2713aSLionel Sambuc   unsigned EBytes = ExtVT.getStoreSize();
2856f4a2713aSLionel Sambuc   unsigned IncrementSize = NVT.getSizeInBits()/8;
2857f4a2713aSLionel Sambuc   unsigned ExcessBits = (EBytes - IncrementSize)*8;
2858f4a2713aSLionel Sambuc   EVT HiVT = EVT::getIntegerVT(*DAG.getContext(),
2859f4a2713aSLionel Sambuc                                ExtVT.getSizeInBits() - ExcessBits);
2860f4a2713aSLionel Sambuc 
2861f4a2713aSLionel Sambuc   if (ExcessBits < NVT.getSizeInBits()) {
2862f4a2713aSLionel Sambuc     // Transfer high bits from the top of Lo to the bottom of Hi.
2863f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
2864f4a2713aSLionel Sambuc                      DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
2865f4a2713aSLionel Sambuc                                      TLI.getPointerTy()));
2866f4a2713aSLionel Sambuc     Hi = DAG.getNode(ISD::OR, dl, NVT, Hi,
2867f4a2713aSLionel Sambuc                      DAG.getNode(ISD::SRL, dl, NVT, Lo,
2868f4a2713aSLionel Sambuc                                  DAG.getConstant(ExcessBits,
2869f4a2713aSLionel Sambuc                                                  TLI.getPointerTy())));
2870f4a2713aSLionel Sambuc   }
2871f4a2713aSLionel Sambuc 
2872f4a2713aSLionel Sambuc   // Store both the high bits and maybe some of the low bits.
2873f4a2713aSLionel Sambuc   Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getPointerInfo(),
2874*0a6a1f1dSLionel Sambuc                          HiVT, isVolatile, isNonTemporal, Alignment, AAInfo);
2875f4a2713aSLionel Sambuc 
2876f4a2713aSLionel Sambuc   // Increment the pointer to the other half.
2877f4a2713aSLionel Sambuc   Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
2878f4a2713aSLionel Sambuc                     DAG.getConstant(IncrementSize, Ptr.getValueType()));
2879f4a2713aSLionel Sambuc   // Store the lowest ExcessBits bits in the second half.
2880f4a2713aSLionel Sambuc   Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr,
2881f4a2713aSLionel Sambuc                          N->getPointerInfo().getWithOffset(IncrementSize),
2882f4a2713aSLionel Sambuc                          EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
2883f4a2713aSLionel Sambuc                          isVolatile, isNonTemporal,
2884*0a6a1f1dSLionel Sambuc                          MinAlign(Alignment, IncrementSize), AAInfo);
2885f4a2713aSLionel Sambuc   return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2886f4a2713aSLionel Sambuc }
2887f4a2713aSLionel Sambuc 
ExpandIntOp_TRUNCATE(SDNode * N)2888f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
2889f4a2713aSLionel Sambuc   SDValue InL, InH;
2890f4a2713aSLionel Sambuc   GetExpandedInteger(N->getOperand(0), InL, InH);
2891f4a2713aSLionel Sambuc   // Just truncate the low part of the source.
2892f4a2713aSLionel Sambuc   return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0), InL);
2893f4a2713aSLionel Sambuc }
2894f4a2713aSLionel Sambuc 
ExpandIntOp_UINT_TO_FP(SDNode * N)2895f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
2896f4a2713aSLionel Sambuc   SDValue Op = N->getOperand(0);
2897f4a2713aSLionel Sambuc   EVT SrcVT = Op.getValueType();
2898f4a2713aSLionel Sambuc   EVT DstVT = N->getValueType(0);
2899f4a2713aSLionel Sambuc   SDLoc dl(N);
2900f4a2713aSLionel Sambuc 
2901f4a2713aSLionel Sambuc   // The following optimization is valid only if every value in SrcVT (when
2902f4a2713aSLionel Sambuc   // treated as signed) is representable in DstVT.  Check that the mantissa
2903f4a2713aSLionel Sambuc   // size of DstVT is >= than the number of bits in SrcVT -1.
2904f4a2713aSLionel Sambuc   const fltSemantics &sem = DAG.EVTToAPFloatSemantics(DstVT);
2905f4a2713aSLionel Sambuc   if (APFloat::semanticsPrecision(sem) >= SrcVT.getSizeInBits()-1 &&
2906f4a2713aSLionel Sambuc       TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
2907f4a2713aSLionel Sambuc     // Do a signed conversion then adjust the result.
2908f4a2713aSLionel Sambuc     SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op);
2909f4a2713aSLionel Sambuc     SignedConv = TLI.LowerOperation(SignedConv, DAG);
2910f4a2713aSLionel Sambuc 
2911f4a2713aSLionel Sambuc     // The result of the signed conversion needs adjusting if the 'sign bit' of
2912f4a2713aSLionel Sambuc     // the incoming integer was set.  To handle this, we dynamically test to see
2913f4a2713aSLionel Sambuc     // if it is set, and, if so, add a fudge factor.
2914f4a2713aSLionel Sambuc 
2915f4a2713aSLionel Sambuc     const uint64_t F32TwoE32  = 0x4F800000ULL;
2916f4a2713aSLionel Sambuc     const uint64_t F32TwoE64  = 0x5F800000ULL;
2917f4a2713aSLionel Sambuc     const uint64_t F32TwoE128 = 0x7F800000ULL;
2918f4a2713aSLionel Sambuc 
2919f4a2713aSLionel Sambuc     APInt FF(32, 0);
2920f4a2713aSLionel Sambuc     if (SrcVT == MVT::i32)
2921f4a2713aSLionel Sambuc       FF = APInt(32, F32TwoE32);
2922f4a2713aSLionel Sambuc     else if (SrcVT == MVT::i64)
2923f4a2713aSLionel Sambuc       FF = APInt(32, F32TwoE64);
2924f4a2713aSLionel Sambuc     else if (SrcVT == MVT::i128)
2925f4a2713aSLionel Sambuc       FF = APInt(32, F32TwoE128);
2926f4a2713aSLionel Sambuc     else
2927f4a2713aSLionel Sambuc       llvm_unreachable("Unsupported UINT_TO_FP!");
2928f4a2713aSLionel Sambuc 
2929f4a2713aSLionel Sambuc     // Check whether the sign bit is set.
2930f4a2713aSLionel Sambuc     SDValue Lo, Hi;
2931f4a2713aSLionel Sambuc     GetExpandedInteger(Op, Lo, Hi);
2932f4a2713aSLionel Sambuc     SDValue SignSet = DAG.getSetCC(dl,
2933f4a2713aSLionel Sambuc                                    getSetCCResultType(Hi.getValueType()),
2934f4a2713aSLionel Sambuc                                    Hi, DAG.getConstant(0, Hi.getValueType()),
2935f4a2713aSLionel Sambuc                                    ISD::SETLT);
2936f4a2713aSLionel Sambuc 
2937f4a2713aSLionel Sambuc     // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits.
2938f4a2713aSLionel Sambuc     SDValue FudgePtr = DAG.getConstantPool(
2939f4a2713aSLionel Sambuc                                ConstantInt::get(*DAG.getContext(), FF.zext(64)),
2940f4a2713aSLionel Sambuc                                            TLI.getPointerTy());
2941f4a2713aSLionel Sambuc 
2942f4a2713aSLionel Sambuc     // Get a pointer to FF if the sign bit was set, or to 0 otherwise.
2943f4a2713aSLionel Sambuc     SDValue Zero = DAG.getIntPtrConstant(0);
2944f4a2713aSLionel Sambuc     SDValue Four = DAG.getIntPtrConstant(4);
2945f4a2713aSLionel Sambuc     if (TLI.isBigEndian()) std::swap(Zero, Four);
2946f4a2713aSLionel Sambuc     SDValue Offset = DAG.getSelect(dl, Zero.getValueType(), SignSet,
2947f4a2713aSLionel Sambuc                                    Zero, Four);
2948f4a2713aSLionel Sambuc     unsigned Alignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment();
2949f4a2713aSLionel Sambuc     FudgePtr = DAG.getNode(ISD::ADD, dl, FudgePtr.getValueType(),
2950f4a2713aSLionel Sambuc                            FudgePtr, Offset);
2951f4a2713aSLionel Sambuc     Alignment = std::min(Alignment, 4u);
2952f4a2713aSLionel Sambuc 
2953f4a2713aSLionel Sambuc     // Load the value out, extending it from f32 to the destination float type.
2954f4a2713aSLionel Sambuc     // FIXME: Avoid the extend by constructing the right constant pool?
2955f4a2713aSLionel Sambuc     SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(),
2956f4a2713aSLionel Sambuc                                    FudgePtr,
2957f4a2713aSLionel Sambuc                                    MachinePointerInfo::getConstantPool(),
2958f4a2713aSLionel Sambuc                                    MVT::f32,
2959*0a6a1f1dSLionel Sambuc                                    false, false, false, Alignment);
2960f4a2713aSLionel Sambuc     return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge);
2961f4a2713aSLionel Sambuc   }
2962f4a2713aSLionel Sambuc 
2963f4a2713aSLionel Sambuc   // Otherwise, use a libcall.
2964f4a2713aSLionel Sambuc   RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT);
2965f4a2713aSLionel Sambuc   assert(LC != RTLIB::UNKNOWN_LIBCALL &&
2966f4a2713aSLionel Sambuc          "Don't know how to expand this UINT_TO_FP!");
2967f4a2713aSLionel Sambuc   return TLI.makeLibCall(DAG, LC, DstVT, &Op, 1, true, dl).first;
2968f4a2713aSLionel Sambuc }
2969f4a2713aSLionel Sambuc 
ExpandIntOp_ATOMIC_STORE(SDNode * N)2970f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::ExpandIntOp_ATOMIC_STORE(SDNode *N) {
2971f4a2713aSLionel Sambuc   SDLoc dl(N);
2972f4a2713aSLionel Sambuc   SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl,
2973f4a2713aSLionel Sambuc                                cast<AtomicSDNode>(N)->getMemoryVT(),
2974f4a2713aSLionel Sambuc                                N->getOperand(0),
2975f4a2713aSLionel Sambuc                                N->getOperand(1), N->getOperand(2),
2976f4a2713aSLionel Sambuc                                cast<AtomicSDNode>(N)->getMemOperand(),
2977f4a2713aSLionel Sambuc                                cast<AtomicSDNode>(N)->getOrdering(),
2978f4a2713aSLionel Sambuc                                cast<AtomicSDNode>(N)->getSynchScope());
2979f4a2713aSLionel Sambuc   return Swap.getValue(1);
2980f4a2713aSLionel Sambuc }
2981f4a2713aSLionel Sambuc 
2982f4a2713aSLionel Sambuc 
PromoteIntRes_EXTRACT_SUBVECTOR(SDNode * N)2983f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
2984f4a2713aSLionel Sambuc   SDValue InOp0 = N->getOperand(0);
2985f4a2713aSLionel Sambuc   EVT InVT = InOp0.getValueType();
2986f4a2713aSLionel Sambuc 
2987f4a2713aSLionel Sambuc   EVT OutVT = N->getValueType(0);
2988f4a2713aSLionel Sambuc   EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2989f4a2713aSLionel Sambuc   assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2990f4a2713aSLionel Sambuc   unsigned OutNumElems = OutVT.getVectorNumElements();
2991f4a2713aSLionel Sambuc   EVT NOutVTElem = NOutVT.getVectorElementType();
2992f4a2713aSLionel Sambuc 
2993f4a2713aSLionel Sambuc   SDLoc dl(N);
2994f4a2713aSLionel Sambuc   SDValue BaseIdx = N->getOperand(1);
2995f4a2713aSLionel Sambuc 
2996f4a2713aSLionel Sambuc   SmallVector<SDValue, 8> Ops;
2997f4a2713aSLionel Sambuc   Ops.reserve(OutNumElems);
2998f4a2713aSLionel Sambuc   for (unsigned i = 0; i != OutNumElems; ++i) {
2999f4a2713aSLionel Sambuc 
3000f4a2713aSLionel Sambuc     // Extract the element from the original vector.
3001f4a2713aSLionel Sambuc     SDValue Index = DAG.getNode(ISD::ADD, dl, BaseIdx.getValueType(),
3002f4a2713aSLionel Sambuc       BaseIdx, DAG.getConstant(i, BaseIdx.getValueType()));
3003f4a2713aSLionel Sambuc     SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
3004f4a2713aSLionel Sambuc       InVT.getVectorElementType(), N->getOperand(0), Index);
3005f4a2713aSLionel Sambuc 
3006f4a2713aSLionel Sambuc     SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, Ext);
3007f4a2713aSLionel Sambuc     // Insert the converted element to the new vector.
3008f4a2713aSLionel Sambuc     Ops.push_back(Op);
3009f4a2713aSLionel Sambuc   }
3010f4a2713aSLionel Sambuc 
3011*0a6a1f1dSLionel Sambuc   return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, Ops);
3012f4a2713aSLionel Sambuc }
3013f4a2713aSLionel Sambuc 
3014f4a2713aSLionel Sambuc 
PromoteIntRes_VECTOR_SHUFFLE(SDNode * N)3015f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) {
3016f4a2713aSLionel Sambuc   ShuffleVectorSDNode *SV = cast<ShuffleVectorSDNode>(N);
3017f4a2713aSLionel Sambuc   EVT VT = N->getValueType(0);
3018f4a2713aSLionel Sambuc   SDLoc dl(N);
3019f4a2713aSLionel Sambuc 
3020f4a2713aSLionel Sambuc   unsigned NumElts = VT.getVectorNumElements();
3021f4a2713aSLionel Sambuc   SmallVector<int, 8> NewMask;
3022f4a2713aSLionel Sambuc   for (unsigned i = 0; i != NumElts; ++i) {
3023f4a2713aSLionel Sambuc     NewMask.push_back(SV->getMaskElt(i));
3024f4a2713aSLionel Sambuc   }
3025f4a2713aSLionel Sambuc 
3026f4a2713aSLionel Sambuc   SDValue V0 = GetPromotedInteger(N->getOperand(0));
3027f4a2713aSLionel Sambuc   SDValue V1 = GetPromotedInteger(N->getOperand(1));
3028f4a2713aSLionel Sambuc   EVT OutVT = V0.getValueType();
3029f4a2713aSLionel Sambuc 
3030f4a2713aSLionel Sambuc   return DAG.getVectorShuffle(OutVT, dl, V0, V1, &NewMask[0]);
3031f4a2713aSLionel Sambuc }
3032f4a2713aSLionel Sambuc 
3033f4a2713aSLionel Sambuc 
PromoteIntRes_BUILD_VECTOR(SDNode * N)3034f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) {
3035f4a2713aSLionel Sambuc   EVT OutVT = N->getValueType(0);
3036f4a2713aSLionel Sambuc   EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
3037f4a2713aSLionel Sambuc   assert(NOutVT.isVector() && "This type must be promoted to a vector type");
3038f4a2713aSLionel Sambuc   unsigned NumElems = N->getNumOperands();
3039f4a2713aSLionel Sambuc   EVT NOutVTElem = NOutVT.getVectorElementType();
3040f4a2713aSLionel Sambuc 
3041f4a2713aSLionel Sambuc   SDLoc dl(N);
3042f4a2713aSLionel Sambuc 
3043f4a2713aSLionel Sambuc   SmallVector<SDValue, 8> Ops;
3044f4a2713aSLionel Sambuc   Ops.reserve(NumElems);
3045f4a2713aSLionel Sambuc   for (unsigned i = 0; i != NumElems; ++i) {
3046f4a2713aSLionel Sambuc     SDValue Op;
3047f4a2713aSLionel Sambuc     // BUILD_VECTOR integer operand types are allowed to be larger than the
3048f4a2713aSLionel Sambuc     // result's element type. This may still be true after the promotion. For
3049f4a2713aSLionel Sambuc     // example, we might be promoting (<v?i1> = BV <i32>, <i32>, ...) to
3050f4a2713aSLionel Sambuc     // (v?i16 = BV <i32>, <i32>, ...), and we can't any_extend <i32> to <i16>.
3051f4a2713aSLionel Sambuc     if (N->getOperand(i).getValueType().bitsLT(NOutVTElem))
3052f4a2713aSLionel Sambuc       Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(i));
3053f4a2713aSLionel Sambuc     else
3054f4a2713aSLionel Sambuc       Op = N->getOperand(i);
3055f4a2713aSLionel Sambuc     Ops.push_back(Op);
3056f4a2713aSLionel Sambuc   }
3057f4a2713aSLionel Sambuc 
3058*0a6a1f1dSLionel Sambuc   return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, Ops);
3059f4a2713aSLionel Sambuc }
3060f4a2713aSLionel Sambuc 
PromoteIntRes_SCALAR_TO_VECTOR(SDNode * N)3061f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_SCALAR_TO_VECTOR(SDNode *N) {
3062f4a2713aSLionel Sambuc 
3063f4a2713aSLionel Sambuc   SDLoc dl(N);
3064f4a2713aSLionel Sambuc 
3065f4a2713aSLionel Sambuc   assert(!N->getOperand(0).getValueType().isVector() &&
3066f4a2713aSLionel Sambuc          "Input must be a scalar");
3067f4a2713aSLionel Sambuc 
3068f4a2713aSLionel Sambuc   EVT OutVT = N->getValueType(0);
3069f4a2713aSLionel Sambuc   EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
3070f4a2713aSLionel Sambuc   assert(NOutVT.isVector() && "This type must be promoted to a vector type");
3071f4a2713aSLionel Sambuc   EVT NOutVTElem = NOutVT.getVectorElementType();
3072f4a2713aSLionel Sambuc 
3073f4a2713aSLionel Sambuc   SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(0));
3074f4a2713aSLionel Sambuc 
3075f4a2713aSLionel Sambuc   return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NOutVT, Op);
3076f4a2713aSLionel Sambuc }
3077f4a2713aSLionel Sambuc 
PromoteIntRes_CONCAT_VECTORS(SDNode * N)3078f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_CONCAT_VECTORS(SDNode *N) {
3079f4a2713aSLionel Sambuc   SDLoc dl(N);
3080f4a2713aSLionel Sambuc 
3081f4a2713aSLionel Sambuc   EVT OutVT = N->getValueType(0);
3082f4a2713aSLionel Sambuc   EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
3083f4a2713aSLionel Sambuc   assert(NOutVT.isVector() && "This type must be promoted to a vector type");
3084f4a2713aSLionel Sambuc 
3085f4a2713aSLionel Sambuc   EVT InElemTy = OutVT.getVectorElementType();
3086f4a2713aSLionel Sambuc   EVT OutElemTy = NOutVT.getVectorElementType();
3087f4a2713aSLionel Sambuc 
3088f4a2713aSLionel Sambuc   unsigned NumElem = N->getOperand(0).getValueType().getVectorNumElements();
3089f4a2713aSLionel Sambuc   unsigned NumOutElem = NOutVT.getVectorNumElements();
3090f4a2713aSLionel Sambuc   unsigned NumOperands = N->getNumOperands();
3091f4a2713aSLionel Sambuc   assert(NumElem * NumOperands == NumOutElem &&
3092f4a2713aSLionel Sambuc          "Unexpected number of elements");
3093f4a2713aSLionel Sambuc 
3094f4a2713aSLionel Sambuc   // Take the elements from the first vector.
3095f4a2713aSLionel Sambuc   SmallVector<SDValue, 8> Ops(NumOutElem);
3096f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumOperands; ++i) {
3097f4a2713aSLionel Sambuc     SDValue Op = N->getOperand(i);
3098f4a2713aSLionel Sambuc     for (unsigned j = 0; j < NumElem; ++j) {
3099f4a2713aSLionel Sambuc       SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
3100f4a2713aSLionel Sambuc                                 InElemTy, Op, DAG.getConstant(j,
3101f4a2713aSLionel Sambuc                                               TLI.getVectorIdxTy()));
3102f4a2713aSLionel Sambuc       Ops[i * NumElem + j] = DAG.getNode(ISD::ANY_EXTEND, dl, OutElemTy, Ext);
3103f4a2713aSLionel Sambuc     }
3104f4a2713aSLionel Sambuc   }
3105f4a2713aSLionel Sambuc 
3106*0a6a1f1dSLionel Sambuc   return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, Ops);
3107f4a2713aSLionel Sambuc }
3108f4a2713aSLionel Sambuc 
PromoteIntRes_INSERT_VECTOR_ELT(SDNode * N)3109f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) {
3110f4a2713aSLionel Sambuc   EVT OutVT = N->getValueType(0);
3111f4a2713aSLionel Sambuc   EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
3112f4a2713aSLionel Sambuc   assert(NOutVT.isVector() && "This type must be promoted to a vector type");
3113f4a2713aSLionel Sambuc 
3114f4a2713aSLionel Sambuc   EVT NOutVTElem = NOutVT.getVectorElementType();
3115f4a2713aSLionel Sambuc 
3116f4a2713aSLionel Sambuc   SDLoc dl(N);
3117f4a2713aSLionel Sambuc   SDValue V0 = GetPromotedInteger(N->getOperand(0));
3118f4a2713aSLionel Sambuc 
3119f4a2713aSLionel Sambuc   SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl,
3120f4a2713aSLionel Sambuc     NOutVTElem, N->getOperand(1));
3121f4a2713aSLionel Sambuc   return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NOutVT,
3122f4a2713aSLionel Sambuc     V0, ConvElem, N->getOperand(2));
3123f4a2713aSLionel Sambuc }
3124f4a2713aSLionel Sambuc 
PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode * N)3125f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
3126f4a2713aSLionel Sambuc   SDLoc dl(N);
3127f4a2713aSLionel Sambuc   SDValue V0 = GetPromotedInteger(N->getOperand(0));
3128f4a2713aSLionel Sambuc   SDValue V1 = DAG.getZExtOrTrunc(N->getOperand(1), dl, TLI.getVectorIdxTy());
3129f4a2713aSLionel Sambuc   SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
3130f4a2713aSLionel Sambuc     V0->getValueType(0).getScalarType(), V0, V1);
3131f4a2713aSLionel Sambuc 
3132f4a2713aSLionel Sambuc   // EXTRACT_VECTOR_ELT can return types which are wider than the incoming
3133f4a2713aSLionel Sambuc   // element types. If this is the case then we need to expand the outgoing
3134f4a2713aSLionel Sambuc   // value and not truncate it.
3135f4a2713aSLionel Sambuc   return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
3136f4a2713aSLionel Sambuc }
3137f4a2713aSLionel Sambuc 
PromoteIntOp_CONCAT_VECTORS(SDNode * N)3138f4a2713aSLionel Sambuc SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
3139f4a2713aSLionel Sambuc   SDLoc dl(N);
3140f4a2713aSLionel Sambuc   unsigned NumElems = N->getNumOperands();
3141f4a2713aSLionel Sambuc 
3142f4a2713aSLionel Sambuc   EVT RetSclrTy = N->getValueType(0).getVectorElementType();
3143f4a2713aSLionel Sambuc 
3144f4a2713aSLionel Sambuc   SmallVector<SDValue, 8> NewOps;
3145f4a2713aSLionel Sambuc   NewOps.reserve(NumElems);
3146f4a2713aSLionel Sambuc 
3147f4a2713aSLionel Sambuc   // For each incoming vector
3148f4a2713aSLionel Sambuc   for (unsigned VecIdx = 0; VecIdx != NumElems; ++VecIdx) {
3149f4a2713aSLionel Sambuc     SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx));
3150f4a2713aSLionel Sambuc     EVT SclrTy = Incoming->getValueType(0).getVectorElementType();
3151f4a2713aSLionel Sambuc     unsigned NumElem = Incoming->getValueType(0).getVectorNumElements();
3152f4a2713aSLionel Sambuc 
3153f4a2713aSLionel Sambuc     for (unsigned i=0; i<NumElem; ++i) {
3154f4a2713aSLionel Sambuc       // Extract element from incoming vector
3155f4a2713aSLionel Sambuc       SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy,
3156f4a2713aSLionel Sambuc       Incoming, DAG.getConstant(i, TLI.getVectorIdxTy()));
3157f4a2713aSLionel Sambuc       SDValue Tr = DAG.getNode(ISD::TRUNCATE, dl, RetSclrTy, Ex);
3158f4a2713aSLionel Sambuc       NewOps.push_back(Tr);
3159f4a2713aSLionel Sambuc     }
3160f4a2713aSLionel Sambuc   }
3161f4a2713aSLionel Sambuc 
3162*0a6a1f1dSLionel Sambuc   return DAG.getNode(ISD::BUILD_VECTOR, dl,  N->getValueType(0), NewOps);
3163f4a2713aSLionel Sambuc }
3164