xref: /aosp_15_r20/external/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SelectionDAG.cpp - Implement the SelectionDAG data structures -----===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This implements the SelectionDAG class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SelectionDAG.h"
15*9880d681SAndroid Build Coastguard Worker #include "SDNodeDbgValue.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/APSInt.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallSet.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallingConv.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalAlias.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Mutex.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetIntrinsicInfo.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
49*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
50*9880d681SAndroid Build Coastguard Worker #include <algorithm>
51*9880d681SAndroid Build Coastguard Worker #include <cmath>
52*9880d681SAndroid Build Coastguard Worker #include <utility>
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker using namespace llvm;
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker /// makeVTList - Return an instance of the SDVTList struct initialized with the
57*9880d681SAndroid Build Coastguard Worker /// specified members.
makeVTList(const EVT * VTs,unsigned NumVTs)58*9880d681SAndroid Build Coastguard Worker static SDVTList makeVTList(const EVT *VTs, unsigned NumVTs) {
59*9880d681SAndroid Build Coastguard Worker   SDVTList Res = {VTs, NumVTs};
60*9880d681SAndroid Build Coastguard Worker   return Res;
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker // Default null implementations of the callbacks.
NodeDeleted(SDNode *,SDNode *)64*9880d681SAndroid Build Coastguard Worker void SelectionDAG::DAGUpdateListener::NodeDeleted(SDNode*, SDNode*) {}
NodeUpdated(SDNode *)65*9880d681SAndroid Build Coastguard Worker void SelectionDAG::DAGUpdateListener::NodeUpdated(SDNode*) {}
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
68*9880d681SAndroid Build Coastguard Worker //                              ConstantFPSDNode Class
69*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker /// isExactlyValue - We don't rely on operator== working on double values, as
72*9880d681SAndroid Build Coastguard Worker /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
73*9880d681SAndroid Build Coastguard Worker /// As such, this method can be used to do an exact bit-for-bit comparison of
74*9880d681SAndroid Build Coastguard Worker /// two floating point values.
isExactlyValue(const APFloat & V) const75*9880d681SAndroid Build Coastguard Worker bool ConstantFPSDNode::isExactlyValue(const APFloat& V) const {
76*9880d681SAndroid Build Coastguard Worker   return getValueAPF().bitwiseIsEqual(V);
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker 
isValueValidForType(EVT VT,const APFloat & Val)79*9880d681SAndroid Build Coastguard Worker bool ConstantFPSDNode::isValueValidForType(EVT VT,
80*9880d681SAndroid Build Coastguard Worker                                            const APFloat& Val) {
81*9880d681SAndroid Build Coastguard Worker   assert(VT.isFloatingPoint() && "Can only convert between FP types");
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker   // convert modifies in place, so make a copy.
84*9880d681SAndroid Build Coastguard Worker   APFloat Val2 = APFloat(Val);
85*9880d681SAndroid Build Coastguard Worker   bool losesInfo;
86*9880d681SAndroid Build Coastguard Worker   (void) Val2.convert(SelectionDAG::EVTToAPFloatSemantics(VT),
87*9880d681SAndroid Build Coastguard Worker                       APFloat::rmNearestTiesToEven,
88*9880d681SAndroid Build Coastguard Worker                       &losesInfo);
89*9880d681SAndroid Build Coastguard Worker   return !losesInfo;
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
93*9880d681SAndroid Build Coastguard Worker //                              ISD Namespace
94*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
95*9880d681SAndroid Build Coastguard Worker 
isConstantSplatVector(const SDNode * N,APInt & SplatVal)96*9880d681SAndroid Build Coastguard Worker bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
97*9880d681SAndroid Build Coastguard Worker   auto *BV = dyn_cast<BuildVectorSDNode>(N);
98*9880d681SAndroid Build Coastguard Worker   if (!BV)
99*9880d681SAndroid Build Coastguard Worker     return false;
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker   APInt SplatUndef;
102*9880d681SAndroid Build Coastguard Worker   unsigned SplatBitSize;
103*9880d681SAndroid Build Coastguard Worker   bool HasUndefs;
104*9880d681SAndroid Build Coastguard Worker   EVT EltVT = N->getValueType(0).getVectorElementType();
105*9880d681SAndroid Build Coastguard Worker   return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs) &&
106*9880d681SAndroid Build Coastguard Worker          EltVT.getSizeInBits() >= SplatBitSize;
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker 
109*9880d681SAndroid Build Coastguard Worker // FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be
110*9880d681SAndroid Build Coastguard Worker // specializations of the more general isConstantSplatVector()?
111*9880d681SAndroid Build Coastguard Worker 
isBuildVectorAllOnes(const SDNode * N)112*9880d681SAndroid Build Coastguard Worker bool ISD::isBuildVectorAllOnes(const SDNode *N) {
113*9880d681SAndroid Build Coastguard Worker   // Look through a bit convert.
114*9880d681SAndroid Build Coastguard Worker   while (N->getOpcode() == ISD::BITCAST)
115*9880d681SAndroid Build Coastguard Worker     N = N->getOperand(0).getNode();
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker   if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   unsigned i = 0, e = N->getNumOperands();
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   // Skip over all of the undef values.
122*9880d681SAndroid Build Coastguard Worker   while (i != e && N->getOperand(i).isUndef())
123*9880d681SAndroid Build Coastguard Worker     ++i;
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker   // Do not accept an all-undef vector.
126*9880d681SAndroid Build Coastguard Worker   if (i == e) return false;
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   // Do not accept build_vectors that aren't all constants or which have non-~0
129*9880d681SAndroid Build Coastguard Worker   // elements. We have to be a bit careful here, as the type of the constant
130*9880d681SAndroid Build Coastguard Worker   // may not be the same as the type of the vector elements due to type
131*9880d681SAndroid Build Coastguard Worker   // legalization (the elements are promoted to a legal type for the target and
132*9880d681SAndroid Build Coastguard Worker   // a vector of a type may be legal when the base element type is not).
133*9880d681SAndroid Build Coastguard Worker   // We only want to check enough bits to cover the vector elements, because
134*9880d681SAndroid Build Coastguard Worker   // we care if the resultant vector is all ones, not whether the individual
135*9880d681SAndroid Build Coastguard Worker   // constants are.
136*9880d681SAndroid Build Coastguard Worker   SDValue NotZero = N->getOperand(i);
137*9880d681SAndroid Build Coastguard Worker   unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits();
138*9880d681SAndroid Build Coastguard Worker   if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(NotZero)) {
139*9880d681SAndroid Build Coastguard Worker     if (CN->getAPIntValue().countTrailingOnes() < EltSize)
140*9880d681SAndroid Build Coastguard Worker       return false;
141*9880d681SAndroid Build Coastguard Worker   } else if (ConstantFPSDNode *CFPN = dyn_cast<ConstantFPSDNode>(NotZero)) {
142*9880d681SAndroid Build Coastguard Worker     if (CFPN->getValueAPF().bitcastToAPInt().countTrailingOnes() < EltSize)
143*9880d681SAndroid Build Coastguard Worker       return false;
144*9880d681SAndroid Build Coastguard Worker   } else
145*9880d681SAndroid Build Coastguard Worker     return false;
146*9880d681SAndroid Build Coastguard Worker 
147*9880d681SAndroid Build Coastguard Worker   // Okay, we have at least one ~0 value, check to see if the rest match or are
148*9880d681SAndroid Build Coastguard Worker   // undefs. Even with the above element type twiddling, this should be OK, as
149*9880d681SAndroid Build Coastguard Worker   // the same type legalization should have applied to all the elements.
150*9880d681SAndroid Build Coastguard Worker   for (++i; i != e; ++i)
151*9880d681SAndroid Build Coastguard Worker     if (N->getOperand(i) != NotZero && !N->getOperand(i).isUndef())
152*9880d681SAndroid Build Coastguard Worker       return false;
153*9880d681SAndroid Build Coastguard Worker   return true;
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker 
isBuildVectorAllZeros(const SDNode * N)156*9880d681SAndroid Build Coastguard Worker bool ISD::isBuildVectorAllZeros(const SDNode *N) {
157*9880d681SAndroid Build Coastguard Worker   // Look through a bit convert.
158*9880d681SAndroid Build Coastguard Worker   while (N->getOpcode() == ISD::BITCAST)
159*9880d681SAndroid Build Coastguard Worker     N = N->getOperand(0).getNode();
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker   if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker   bool IsAllUndef = true;
164*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : N->op_values()) {
165*9880d681SAndroid Build Coastguard Worker     if (Op.isUndef())
166*9880d681SAndroid Build Coastguard Worker       continue;
167*9880d681SAndroid Build Coastguard Worker     IsAllUndef = false;
168*9880d681SAndroid Build Coastguard Worker     // Do not accept build_vectors that aren't all constants or which have non-0
169*9880d681SAndroid Build Coastguard Worker     // elements. We have to be a bit careful here, as the type of the constant
170*9880d681SAndroid Build Coastguard Worker     // may not be the same as the type of the vector elements due to type
171*9880d681SAndroid Build Coastguard Worker     // legalization (the elements are promoted to a legal type for the target
172*9880d681SAndroid Build Coastguard Worker     // and a vector of a type may be legal when the base element type is not).
173*9880d681SAndroid Build Coastguard Worker     // We only want to check enough bits to cover the vector elements, because
174*9880d681SAndroid Build Coastguard Worker     // we care if the resultant vector is all zeros, not whether the individual
175*9880d681SAndroid Build Coastguard Worker     // constants are.
176*9880d681SAndroid Build Coastguard Worker     unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits();
177*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op)) {
178*9880d681SAndroid Build Coastguard Worker       if (CN->getAPIntValue().countTrailingZeros() < EltSize)
179*9880d681SAndroid Build Coastguard Worker         return false;
180*9880d681SAndroid Build Coastguard Worker     } else if (ConstantFPSDNode *CFPN = dyn_cast<ConstantFPSDNode>(Op)) {
181*9880d681SAndroid Build Coastguard Worker       if (CFPN->getValueAPF().bitcastToAPInt().countTrailingZeros() < EltSize)
182*9880d681SAndroid Build Coastguard Worker         return false;
183*9880d681SAndroid Build Coastguard Worker     } else
184*9880d681SAndroid Build Coastguard Worker       return false;
185*9880d681SAndroid Build Coastguard Worker   }
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker   // Do not accept an all-undef vector.
188*9880d681SAndroid Build Coastguard Worker   if (IsAllUndef)
189*9880d681SAndroid Build Coastguard Worker     return false;
190*9880d681SAndroid Build Coastguard Worker   return true;
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker 
isBuildVectorOfConstantSDNodes(const SDNode * N)193*9880d681SAndroid Build Coastguard Worker bool ISD::isBuildVectorOfConstantSDNodes(const SDNode *N) {
194*9880d681SAndroid Build Coastguard Worker   if (N->getOpcode() != ISD::BUILD_VECTOR)
195*9880d681SAndroid Build Coastguard Worker     return false;
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : N->op_values()) {
198*9880d681SAndroid Build Coastguard Worker     if (Op.isUndef())
199*9880d681SAndroid Build Coastguard Worker       continue;
200*9880d681SAndroid Build Coastguard Worker     if (!isa<ConstantSDNode>(Op))
201*9880d681SAndroid Build Coastguard Worker       return false;
202*9880d681SAndroid Build Coastguard Worker   }
203*9880d681SAndroid Build Coastguard Worker   return true;
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker 
isBuildVectorOfConstantFPSDNodes(const SDNode * N)206*9880d681SAndroid Build Coastguard Worker bool ISD::isBuildVectorOfConstantFPSDNodes(const SDNode *N) {
207*9880d681SAndroid Build Coastguard Worker   if (N->getOpcode() != ISD::BUILD_VECTOR)
208*9880d681SAndroid Build Coastguard Worker     return false;
209*9880d681SAndroid Build Coastguard Worker 
210*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : N->op_values()) {
211*9880d681SAndroid Build Coastguard Worker     if (Op.isUndef())
212*9880d681SAndroid Build Coastguard Worker       continue;
213*9880d681SAndroid Build Coastguard Worker     if (!isa<ConstantFPSDNode>(Op))
214*9880d681SAndroid Build Coastguard Worker       return false;
215*9880d681SAndroid Build Coastguard Worker   }
216*9880d681SAndroid Build Coastguard Worker   return true;
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker 
allOperandsUndef(const SDNode * N)219*9880d681SAndroid Build Coastguard Worker bool ISD::allOperandsUndef(const SDNode *N) {
220*9880d681SAndroid Build Coastguard Worker   // Return false if the node has no operands.
221*9880d681SAndroid Build Coastguard Worker   // This is "logically inconsistent" with the definition of "all" but
222*9880d681SAndroid Build Coastguard Worker   // is probably the desired behavior.
223*9880d681SAndroid Build Coastguard Worker   if (N->getNumOperands() == 0)
224*9880d681SAndroid Build Coastguard Worker     return false;
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : N->op_values())
227*9880d681SAndroid Build Coastguard Worker     if (!Op.isUndef())
228*9880d681SAndroid Build Coastguard Worker       return false;
229*9880d681SAndroid Build Coastguard Worker 
230*9880d681SAndroid Build Coastguard Worker   return true;
231*9880d681SAndroid Build Coastguard Worker }
232*9880d681SAndroid Build Coastguard Worker 
getExtForLoadExtType(bool IsFP,ISD::LoadExtType ExtType)233*9880d681SAndroid Build Coastguard Worker ISD::NodeType ISD::getExtForLoadExtType(bool IsFP, ISD::LoadExtType ExtType) {
234*9880d681SAndroid Build Coastguard Worker   switch (ExtType) {
235*9880d681SAndroid Build Coastguard Worker   case ISD::EXTLOAD:
236*9880d681SAndroid Build Coastguard Worker     return IsFP ? ISD::FP_EXTEND : ISD::ANY_EXTEND;
237*9880d681SAndroid Build Coastguard Worker   case ISD::SEXTLOAD:
238*9880d681SAndroid Build Coastguard Worker     return ISD::SIGN_EXTEND;
239*9880d681SAndroid Build Coastguard Worker   case ISD::ZEXTLOAD:
240*9880d681SAndroid Build Coastguard Worker     return ISD::ZERO_EXTEND;
241*9880d681SAndroid Build Coastguard Worker   default:
242*9880d681SAndroid Build Coastguard Worker     break;
243*9880d681SAndroid Build Coastguard Worker   }
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Invalid LoadExtType");
246*9880d681SAndroid Build Coastguard Worker }
247*9880d681SAndroid Build Coastguard Worker 
getSetCCSwappedOperands(ISD::CondCode Operation)248*9880d681SAndroid Build Coastguard Worker ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) {
249*9880d681SAndroid Build Coastguard Worker   // To perform this operation, we just need to swap the L and G bits of the
250*9880d681SAndroid Build Coastguard Worker   // operation.
251*9880d681SAndroid Build Coastguard Worker   unsigned OldL = (Operation >> 2) & 1;
252*9880d681SAndroid Build Coastguard Worker   unsigned OldG = (Operation >> 1) & 1;
253*9880d681SAndroid Build Coastguard Worker   return ISD::CondCode((Operation & ~6) |  // Keep the N, U, E bits
254*9880d681SAndroid Build Coastguard Worker                        (OldL << 1) |       // New G bit
255*9880d681SAndroid Build Coastguard Worker                        (OldG << 2));       // New L bit.
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker 
getSetCCInverse(ISD::CondCode Op,bool isInteger)258*9880d681SAndroid Build Coastguard Worker ISD::CondCode ISD::getSetCCInverse(ISD::CondCode Op, bool isInteger) {
259*9880d681SAndroid Build Coastguard Worker   unsigned Operation = Op;
260*9880d681SAndroid Build Coastguard Worker   if (isInteger)
261*9880d681SAndroid Build Coastguard Worker     Operation ^= 7;   // Flip L, G, E bits, but not U.
262*9880d681SAndroid Build Coastguard Worker   else
263*9880d681SAndroid Build Coastguard Worker     Operation ^= 15;  // Flip all of the condition bits.
264*9880d681SAndroid Build Coastguard Worker 
265*9880d681SAndroid Build Coastguard Worker   if (Operation > ISD::SETTRUE2)
266*9880d681SAndroid Build Coastguard Worker     Operation &= ~8;  // Don't let N and U bits get set.
267*9880d681SAndroid Build Coastguard Worker 
268*9880d681SAndroid Build Coastguard Worker   return ISD::CondCode(Operation);
269*9880d681SAndroid Build Coastguard Worker }
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker 
272*9880d681SAndroid Build Coastguard Worker /// For an integer comparison, return 1 if the comparison is a signed operation
273*9880d681SAndroid Build Coastguard Worker /// and 2 if the result is an unsigned comparison. Return zero if the operation
274*9880d681SAndroid Build Coastguard Worker /// does not depend on the sign of the input (setne and seteq).
isSignedOp(ISD::CondCode Opcode)275*9880d681SAndroid Build Coastguard Worker static int isSignedOp(ISD::CondCode Opcode) {
276*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
277*9880d681SAndroid Build Coastguard Worker   default: llvm_unreachable("Illegal integer setcc operation!");
278*9880d681SAndroid Build Coastguard Worker   case ISD::SETEQ:
279*9880d681SAndroid Build Coastguard Worker   case ISD::SETNE: return 0;
280*9880d681SAndroid Build Coastguard Worker   case ISD::SETLT:
281*9880d681SAndroid Build Coastguard Worker   case ISD::SETLE:
282*9880d681SAndroid Build Coastguard Worker   case ISD::SETGT:
283*9880d681SAndroid Build Coastguard Worker   case ISD::SETGE: return 1;
284*9880d681SAndroid Build Coastguard Worker   case ISD::SETULT:
285*9880d681SAndroid Build Coastguard Worker   case ISD::SETULE:
286*9880d681SAndroid Build Coastguard Worker   case ISD::SETUGT:
287*9880d681SAndroid Build Coastguard Worker   case ISD::SETUGE: return 2;
288*9880d681SAndroid Build Coastguard Worker   }
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker 
getSetCCOrOperation(ISD::CondCode Op1,ISD::CondCode Op2,bool isInteger)291*9880d681SAndroid Build Coastguard Worker ISD::CondCode ISD::getSetCCOrOperation(ISD::CondCode Op1, ISD::CondCode Op2,
292*9880d681SAndroid Build Coastguard Worker                                        bool isInteger) {
293*9880d681SAndroid Build Coastguard Worker   if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
294*9880d681SAndroid Build Coastguard Worker     // Cannot fold a signed integer setcc with an unsigned integer setcc.
295*9880d681SAndroid Build Coastguard Worker     return ISD::SETCC_INVALID;
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker   unsigned Op = Op1 | Op2;  // Combine all of the condition bits.
298*9880d681SAndroid Build Coastguard Worker 
299*9880d681SAndroid Build Coastguard Worker   // If the N and U bits get set then the resultant comparison DOES suddenly
300*9880d681SAndroid Build Coastguard Worker   // care about orderedness, and is true when ordered.
301*9880d681SAndroid Build Coastguard Worker   if (Op > ISD::SETTRUE2)
302*9880d681SAndroid Build Coastguard Worker     Op &= ~16;     // Clear the U bit if the N bit is set.
303*9880d681SAndroid Build Coastguard Worker 
304*9880d681SAndroid Build Coastguard Worker   // Canonicalize illegal integer setcc's.
305*9880d681SAndroid Build Coastguard Worker   if (isInteger && Op == ISD::SETUNE)  // e.g. SETUGT | SETULT
306*9880d681SAndroid Build Coastguard Worker     Op = ISD::SETNE;
307*9880d681SAndroid Build Coastguard Worker 
308*9880d681SAndroid Build Coastguard Worker   return ISD::CondCode(Op);
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker 
getSetCCAndOperation(ISD::CondCode Op1,ISD::CondCode Op2,bool isInteger)311*9880d681SAndroid Build Coastguard Worker ISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2,
312*9880d681SAndroid Build Coastguard Worker                                         bool isInteger) {
313*9880d681SAndroid Build Coastguard Worker   if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
314*9880d681SAndroid Build Coastguard Worker     // Cannot fold a signed setcc with an unsigned setcc.
315*9880d681SAndroid Build Coastguard Worker     return ISD::SETCC_INVALID;
316*9880d681SAndroid Build Coastguard Worker 
317*9880d681SAndroid Build Coastguard Worker   // Combine all of the condition bits.
318*9880d681SAndroid Build Coastguard Worker   ISD::CondCode Result = ISD::CondCode(Op1 & Op2);
319*9880d681SAndroid Build Coastguard Worker 
320*9880d681SAndroid Build Coastguard Worker   // Canonicalize illegal integer setcc's.
321*9880d681SAndroid Build Coastguard Worker   if (isInteger) {
322*9880d681SAndroid Build Coastguard Worker     switch (Result) {
323*9880d681SAndroid Build Coastguard Worker     default: break;
324*9880d681SAndroid Build Coastguard Worker     case ISD::SETUO : Result = ISD::SETFALSE; break;  // SETUGT & SETULT
325*9880d681SAndroid Build Coastguard Worker     case ISD::SETOEQ:                                 // SETEQ  & SETU[LG]E
326*9880d681SAndroid Build Coastguard Worker     case ISD::SETUEQ: Result = ISD::SETEQ   ; break;  // SETUGE & SETULE
327*9880d681SAndroid Build Coastguard Worker     case ISD::SETOLT: Result = ISD::SETULT  ; break;  // SETULT & SETNE
328*9880d681SAndroid Build Coastguard Worker     case ISD::SETOGT: Result = ISD::SETUGT  ; break;  // SETUGT & SETNE
329*9880d681SAndroid Build Coastguard Worker     }
330*9880d681SAndroid Build Coastguard Worker   }
331*9880d681SAndroid Build Coastguard Worker 
332*9880d681SAndroid Build Coastguard Worker   return Result;
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker 
335*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
336*9880d681SAndroid Build Coastguard Worker //                           SDNode Profile Support
337*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
338*9880d681SAndroid Build Coastguard Worker 
339*9880d681SAndroid Build Coastguard Worker /// AddNodeIDOpcode - Add the node opcode to the NodeID data.
340*9880d681SAndroid Build Coastguard Worker ///
AddNodeIDOpcode(FoldingSetNodeID & ID,unsigned OpC)341*9880d681SAndroid Build Coastguard Worker static void AddNodeIDOpcode(FoldingSetNodeID &ID, unsigned OpC)  {
342*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(OpC);
343*9880d681SAndroid Build Coastguard Worker }
344*9880d681SAndroid Build Coastguard Worker 
345*9880d681SAndroid Build Coastguard Worker /// AddNodeIDValueTypes - Value type lists are intern'd so we can represent them
346*9880d681SAndroid Build Coastguard Worker /// solely with their pointer.
AddNodeIDValueTypes(FoldingSetNodeID & ID,SDVTList VTList)347*9880d681SAndroid Build Coastguard Worker static void AddNodeIDValueTypes(FoldingSetNodeID &ID, SDVTList VTList) {
348*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(VTList.VTs);
349*9880d681SAndroid Build Coastguard Worker }
350*9880d681SAndroid Build Coastguard Worker 
351*9880d681SAndroid Build Coastguard Worker /// AddNodeIDOperands - Various routines for adding operands to the NodeID data.
352*9880d681SAndroid Build Coastguard Worker ///
AddNodeIDOperands(FoldingSetNodeID & ID,ArrayRef<SDValue> Ops)353*9880d681SAndroid Build Coastguard Worker static void AddNodeIDOperands(FoldingSetNodeID &ID,
354*9880d681SAndroid Build Coastguard Worker                               ArrayRef<SDValue> Ops) {
355*9880d681SAndroid Build Coastguard Worker   for (auto& Op : Ops) {
356*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(Op.getNode());
357*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(Op.getResNo());
358*9880d681SAndroid Build Coastguard Worker   }
359*9880d681SAndroid Build Coastguard Worker }
360*9880d681SAndroid Build Coastguard Worker 
361*9880d681SAndroid Build Coastguard Worker /// AddNodeIDOperands - Various routines for adding operands to the NodeID data.
362*9880d681SAndroid Build Coastguard Worker ///
AddNodeIDOperands(FoldingSetNodeID & ID,ArrayRef<SDUse> Ops)363*9880d681SAndroid Build Coastguard Worker static void AddNodeIDOperands(FoldingSetNodeID &ID,
364*9880d681SAndroid Build Coastguard Worker                               ArrayRef<SDUse> Ops) {
365*9880d681SAndroid Build Coastguard Worker   for (auto& Op : Ops) {
366*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(Op.getNode());
367*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(Op.getResNo());
368*9880d681SAndroid Build Coastguard Worker   }
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker 
AddNodeIDNode(FoldingSetNodeID & ID,unsigned short OpC,SDVTList VTList,ArrayRef<SDValue> OpList)371*9880d681SAndroid Build Coastguard Worker static void AddNodeIDNode(FoldingSetNodeID &ID, unsigned short OpC,
372*9880d681SAndroid Build Coastguard Worker                           SDVTList VTList, ArrayRef<SDValue> OpList) {
373*9880d681SAndroid Build Coastguard Worker   AddNodeIDOpcode(ID, OpC);
374*9880d681SAndroid Build Coastguard Worker   AddNodeIDValueTypes(ID, VTList);
375*9880d681SAndroid Build Coastguard Worker   AddNodeIDOperands(ID, OpList);
376*9880d681SAndroid Build Coastguard Worker }
377*9880d681SAndroid Build Coastguard Worker 
378*9880d681SAndroid Build Coastguard Worker /// If this is an SDNode with special info, add this info to the NodeID data.
AddNodeIDCustom(FoldingSetNodeID & ID,const SDNode * N)379*9880d681SAndroid Build Coastguard Worker static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
380*9880d681SAndroid Build Coastguard Worker   switch (N->getOpcode()) {
381*9880d681SAndroid Build Coastguard Worker   case ISD::TargetExternalSymbol:
382*9880d681SAndroid Build Coastguard Worker   case ISD::ExternalSymbol:
383*9880d681SAndroid Build Coastguard Worker   case ISD::MCSymbol:
384*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Should only be used on nodes with operands");
385*9880d681SAndroid Build Coastguard Worker   default: break;  // Normal nodes don't need extra info.
386*9880d681SAndroid Build Coastguard Worker   case ISD::TargetConstant:
387*9880d681SAndroid Build Coastguard Worker   case ISD::Constant: {
388*9880d681SAndroid Build Coastguard Worker     const ConstantSDNode *C = cast<ConstantSDNode>(N);
389*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(C->getConstantIntValue());
390*9880d681SAndroid Build Coastguard Worker     ID.AddBoolean(C->isOpaque());
391*9880d681SAndroid Build Coastguard Worker     break;
392*9880d681SAndroid Build Coastguard Worker   }
393*9880d681SAndroid Build Coastguard Worker   case ISD::TargetConstantFP:
394*9880d681SAndroid Build Coastguard Worker   case ISD::ConstantFP: {
395*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(cast<ConstantFPSDNode>(N)->getConstantFPValue());
396*9880d681SAndroid Build Coastguard Worker     break;
397*9880d681SAndroid Build Coastguard Worker   }
398*9880d681SAndroid Build Coastguard Worker   case ISD::TargetGlobalAddress:
399*9880d681SAndroid Build Coastguard Worker   case ISD::GlobalAddress:
400*9880d681SAndroid Build Coastguard Worker   case ISD::TargetGlobalTLSAddress:
401*9880d681SAndroid Build Coastguard Worker   case ISD::GlobalTLSAddress: {
402*9880d681SAndroid Build Coastguard Worker     const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
403*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(GA->getGlobal());
404*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(GA->getOffset());
405*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(GA->getTargetFlags());
406*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(GA->getAddressSpace());
407*9880d681SAndroid Build Coastguard Worker     break;
408*9880d681SAndroid Build Coastguard Worker   }
409*9880d681SAndroid Build Coastguard Worker   case ISD::BasicBlock:
410*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(cast<BasicBlockSDNode>(N)->getBasicBlock());
411*9880d681SAndroid Build Coastguard Worker     break;
412*9880d681SAndroid Build Coastguard Worker   case ISD::Register:
413*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(cast<RegisterSDNode>(N)->getReg());
414*9880d681SAndroid Build Coastguard Worker     break;
415*9880d681SAndroid Build Coastguard Worker   case ISD::RegisterMask:
416*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(cast<RegisterMaskSDNode>(N)->getRegMask());
417*9880d681SAndroid Build Coastguard Worker     break;
418*9880d681SAndroid Build Coastguard Worker   case ISD::SRCVALUE:
419*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(cast<SrcValueSDNode>(N)->getValue());
420*9880d681SAndroid Build Coastguard Worker     break;
421*9880d681SAndroid Build Coastguard Worker   case ISD::FrameIndex:
422*9880d681SAndroid Build Coastguard Worker   case ISD::TargetFrameIndex:
423*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(cast<FrameIndexSDNode>(N)->getIndex());
424*9880d681SAndroid Build Coastguard Worker     break;
425*9880d681SAndroid Build Coastguard Worker   case ISD::JumpTable:
426*9880d681SAndroid Build Coastguard Worker   case ISD::TargetJumpTable:
427*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(cast<JumpTableSDNode>(N)->getIndex());
428*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(cast<JumpTableSDNode>(N)->getTargetFlags());
429*9880d681SAndroid Build Coastguard Worker     break;
430*9880d681SAndroid Build Coastguard Worker   case ISD::ConstantPool:
431*9880d681SAndroid Build Coastguard Worker   case ISD::TargetConstantPool: {
432*9880d681SAndroid Build Coastguard Worker     const ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
433*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(CP->getAlignment());
434*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(CP->getOffset());
435*9880d681SAndroid Build Coastguard Worker     if (CP->isMachineConstantPoolEntry())
436*9880d681SAndroid Build Coastguard Worker       CP->getMachineCPVal()->addSelectionDAGCSEId(ID);
437*9880d681SAndroid Build Coastguard Worker     else
438*9880d681SAndroid Build Coastguard Worker       ID.AddPointer(CP->getConstVal());
439*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(CP->getTargetFlags());
440*9880d681SAndroid Build Coastguard Worker     break;
441*9880d681SAndroid Build Coastguard Worker   }
442*9880d681SAndroid Build Coastguard Worker   case ISD::TargetIndex: {
443*9880d681SAndroid Build Coastguard Worker     const TargetIndexSDNode *TI = cast<TargetIndexSDNode>(N);
444*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(TI->getIndex());
445*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(TI->getOffset());
446*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(TI->getTargetFlags());
447*9880d681SAndroid Build Coastguard Worker     break;
448*9880d681SAndroid Build Coastguard Worker   }
449*9880d681SAndroid Build Coastguard Worker   case ISD::LOAD: {
450*9880d681SAndroid Build Coastguard Worker     const LoadSDNode *LD = cast<LoadSDNode>(N);
451*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(LD->getMemoryVT().getRawBits());
452*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(LD->getRawSubclassData());
453*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(LD->getPointerInfo().getAddrSpace());
454*9880d681SAndroid Build Coastguard Worker     break;
455*9880d681SAndroid Build Coastguard Worker   }
456*9880d681SAndroid Build Coastguard Worker   case ISD::STORE: {
457*9880d681SAndroid Build Coastguard Worker     const StoreSDNode *ST = cast<StoreSDNode>(N);
458*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(ST->getMemoryVT().getRawBits());
459*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(ST->getRawSubclassData());
460*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(ST->getPointerInfo().getAddrSpace());
461*9880d681SAndroid Build Coastguard Worker     break;
462*9880d681SAndroid Build Coastguard Worker   }
463*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_CMP_SWAP:
464*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
465*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_SWAP:
466*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_ADD:
467*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_SUB:
468*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_AND:
469*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_OR:
470*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_XOR:
471*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_NAND:
472*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_MIN:
473*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_MAX:
474*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_UMIN:
475*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_UMAX:
476*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD:
477*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_STORE: {
478*9880d681SAndroid Build Coastguard Worker     const AtomicSDNode *AT = cast<AtomicSDNode>(N);
479*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(AT->getMemoryVT().getRawBits());
480*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(AT->getRawSubclassData());
481*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(AT->getPointerInfo().getAddrSpace());
482*9880d681SAndroid Build Coastguard Worker     break;
483*9880d681SAndroid Build Coastguard Worker   }
484*9880d681SAndroid Build Coastguard Worker   case ISD::PREFETCH: {
485*9880d681SAndroid Build Coastguard Worker     const MemSDNode *PF = cast<MemSDNode>(N);
486*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(PF->getPointerInfo().getAddrSpace());
487*9880d681SAndroid Build Coastguard Worker     break;
488*9880d681SAndroid Build Coastguard Worker   }
489*9880d681SAndroid Build Coastguard Worker   case ISD::VECTOR_SHUFFLE: {
490*9880d681SAndroid Build Coastguard Worker     const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
491*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = N->getValueType(0).getVectorNumElements();
492*9880d681SAndroid Build Coastguard Worker          i != e; ++i)
493*9880d681SAndroid Build Coastguard Worker       ID.AddInteger(SVN->getMaskElt(i));
494*9880d681SAndroid Build Coastguard Worker     break;
495*9880d681SAndroid Build Coastguard Worker   }
496*9880d681SAndroid Build Coastguard Worker   case ISD::TargetBlockAddress:
497*9880d681SAndroid Build Coastguard Worker   case ISD::BlockAddress: {
498*9880d681SAndroid Build Coastguard Worker     const BlockAddressSDNode *BA = cast<BlockAddressSDNode>(N);
499*9880d681SAndroid Build Coastguard Worker     ID.AddPointer(BA->getBlockAddress());
500*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(BA->getOffset());
501*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(BA->getTargetFlags());
502*9880d681SAndroid Build Coastguard Worker     break;
503*9880d681SAndroid Build Coastguard Worker   }
504*9880d681SAndroid Build Coastguard Worker   } // end switch (N->getOpcode())
505*9880d681SAndroid Build Coastguard Worker 
506*9880d681SAndroid Build Coastguard Worker   // Target specific memory nodes could also have address spaces to check.
507*9880d681SAndroid Build Coastguard Worker   if (N->isTargetMemoryOpcode())
508*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(cast<MemSDNode>(N)->getPointerInfo().getAddrSpace());
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker 
511*9880d681SAndroid Build Coastguard Worker /// AddNodeIDNode - Generic routine for adding a nodes info to the NodeID
512*9880d681SAndroid Build Coastguard Worker /// data.
AddNodeIDNode(FoldingSetNodeID & ID,const SDNode * N)513*9880d681SAndroid Build Coastguard Worker static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {
514*9880d681SAndroid Build Coastguard Worker   AddNodeIDOpcode(ID, N->getOpcode());
515*9880d681SAndroid Build Coastguard Worker   // Add the return value info.
516*9880d681SAndroid Build Coastguard Worker   AddNodeIDValueTypes(ID, N->getVTList());
517*9880d681SAndroid Build Coastguard Worker   // Add the operand info.
518*9880d681SAndroid Build Coastguard Worker   AddNodeIDOperands(ID, N->ops());
519*9880d681SAndroid Build Coastguard Worker 
520*9880d681SAndroid Build Coastguard Worker   // Handle SDNode leafs with special info.
521*9880d681SAndroid Build Coastguard Worker   AddNodeIDCustom(ID, N);
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker 
524*9880d681SAndroid Build Coastguard Worker /// encodeMemSDNodeFlags - Generic routine for computing a value for use in
525*9880d681SAndroid Build Coastguard Worker /// the CSE map that carries volatility, temporalness, indexing mode, and
526*9880d681SAndroid Build Coastguard Worker /// extension/truncation information.
527*9880d681SAndroid Build Coastguard Worker ///
528*9880d681SAndroid Build Coastguard Worker static inline unsigned
encodeMemSDNodeFlags(int ConvType,ISD::MemIndexedMode AM,bool isVolatile,bool isNonTemporal,bool isInvariant)529*9880d681SAndroid Build Coastguard Worker encodeMemSDNodeFlags(int ConvType, ISD::MemIndexedMode AM, bool isVolatile,
530*9880d681SAndroid Build Coastguard Worker                      bool isNonTemporal, bool isInvariant) {
531*9880d681SAndroid Build Coastguard Worker   assert((ConvType & 3) == ConvType &&
532*9880d681SAndroid Build Coastguard Worker          "ConvType may not require more than 2 bits!");
533*9880d681SAndroid Build Coastguard Worker   assert((AM & 7) == AM &&
534*9880d681SAndroid Build Coastguard Worker          "AM may not require more than 3 bits!");
535*9880d681SAndroid Build Coastguard Worker   return ConvType |
536*9880d681SAndroid Build Coastguard Worker          (AM << 2) |
537*9880d681SAndroid Build Coastguard Worker          (isVolatile << 5) |
538*9880d681SAndroid Build Coastguard Worker          (isNonTemporal << 6) |
539*9880d681SAndroid Build Coastguard Worker          (isInvariant << 7);
540*9880d681SAndroid Build Coastguard Worker }
541*9880d681SAndroid Build Coastguard Worker 
542*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
543*9880d681SAndroid Build Coastguard Worker //                              SelectionDAG Class
544*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
545*9880d681SAndroid Build Coastguard Worker 
546*9880d681SAndroid Build Coastguard Worker /// doNotCSE - Return true if CSE should not be performed for this node.
doNotCSE(SDNode * N)547*9880d681SAndroid Build Coastguard Worker static bool doNotCSE(SDNode *N) {
548*9880d681SAndroid Build Coastguard Worker   if (N->getValueType(0) == MVT::Glue)
549*9880d681SAndroid Build Coastguard Worker     return true; // Never CSE anything that produces a flag.
550*9880d681SAndroid Build Coastguard Worker 
551*9880d681SAndroid Build Coastguard Worker   switch (N->getOpcode()) {
552*9880d681SAndroid Build Coastguard Worker   default: break;
553*9880d681SAndroid Build Coastguard Worker   case ISD::HANDLENODE:
554*9880d681SAndroid Build Coastguard Worker   case ISD::EH_LABEL:
555*9880d681SAndroid Build Coastguard Worker     return true;   // Never CSE these nodes.
556*9880d681SAndroid Build Coastguard Worker   }
557*9880d681SAndroid Build Coastguard Worker 
558*9880d681SAndroid Build Coastguard Worker   // Check that remaining values produced are not flags.
559*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
560*9880d681SAndroid Build Coastguard Worker     if (N->getValueType(i) == MVT::Glue)
561*9880d681SAndroid Build Coastguard Worker       return true; // Never CSE anything that produces a flag.
562*9880d681SAndroid Build Coastguard Worker 
563*9880d681SAndroid Build Coastguard Worker   return false;
564*9880d681SAndroid Build Coastguard Worker }
565*9880d681SAndroid Build Coastguard Worker 
566*9880d681SAndroid Build Coastguard Worker /// RemoveDeadNodes - This method deletes all unreachable nodes in the
567*9880d681SAndroid Build Coastguard Worker /// SelectionDAG.
RemoveDeadNodes()568*9880d681SAndroid Build Coastguard Worker void SelectionDAG::RemoveDeadNodes() {
569*9880d681SAndroid Build Coastguard Worker   // Create a dummy node (which is not added to allnodes), that adds a reference
570*9880d681SAndroid Build Coastguard Worker   // to the root node, preventing it from being deleted.
571*9880d681SAndroid Build Coastguard Worker   HandleSDNode Dummy(getRoot());
572*9880d681SAndroid Build Coastguard Worker 
573*9880d681SAndroid Build Coastguard Worker   SmallVector<SDNode*, 128> DeadNodes;
574*9880d681SAndroid Build Coastguard Worker 
575*9880d681SAndroid Build Coastguard Worker   // Add all obviously-dead nodes to the DeadNodes worklist.
576*9880d681SAndroid Build Coastguard Worker   for (SDNode &Node : allnodes())
577*9880d681SAndroid Build Coastguard Worker     if (Node.use_empty())
578*9880d681SAndroid Build Coastguard Worker       DeadNodes.push_back(&Node);
579*9880d681SAndroid Build Coastguard Worker 
580*9880d681SAndroid Build Coastguard Worker   RemoveDeadNodes(DeadNodes);
581*9880d681SAndroid Build Coastguard Worker 
582*9880d681SAndroid Build Coastguard Worker   // If the root changed (e.g. it was a dead load, update the root).
583*9880d681SAndroid Build Coastguard Worker   setRoot(Dummy.getValue());
584*9880d681SAndroid Build Coastguard Worker }
585*9880d681SAndroid Build Coastguard Worker 
586*9880d681SAndroid Build Coastguard Worker /// RemoveDeadNodes - This method deletes the unreachable nodes in the
587*9880d681SAndroid Build Coastguard Worker /// given list, and any nodes that become unreachable as a result.
RemoveDeadNodes(SmallVectorImpl<SDNode * > & DeadNodes)588*9880d681SAndroid Build Coastguard Worker void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes) {
589*9880d681SAndroid Build Coastguard Worker 
590*9880d681SAndroid Build Coastguard Worker   // Process the worklist, deleting the nodes and adding their uses to the
591*9880d681SAndroid Build Coastguard Worker   // worklist.
592*9880d681SAndroid Build Coastguard Worker   while (!DeadNodes.empty()) {
593*9880d681SAndroid Build Coastguard Worker     SDNode *N = DeadNodes.pop_back_val();
594*9880d681SAndroid Build Coastguard Worker 
595*9880d681SAndroid Build Coastguard Worker     for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next)
596*9880d681SAndroid Build Coastguard Worker       DUL->NodeDeleted(N, nullptr);
597*9880d681SAndroid Build Coastguard Worker 
598*9880d681SAndroid Build Coastguard Worker     // Take the node out of the appropriate CSE map.
599*9880d681SAndroid Build Coastguard Worker     RemoveNodeFromCSEMaps(N);
600*9880d681SAndroid Build Coastguard Worker 
601*9880d681SAndroid Build Coastguard Worker     // Next, brutally remove the operand list.  This is safe to do, as there are
602*9880d681SAndroid Build Coastguard Worker     // no cycles in the graph.
603*9880d681SAndroid Build Coastguard Worker     for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) {
604*9880d681SAndroid Build Coastguard Worker       SDUse &Use = *I++;
605*9880d681SAndroid Build Coastguard Worker       SDNode *Operand = Use.getNode();
606*9880d681SAndroid Build Coastguard Worker       Use.set(SDValue());
607*9880d681SAndroid Build Coastguard Worker 
608*9880d681SAndroid Build Coastguard Worker       // Now that we removed this operand, see if there are no uses of it left.
609*9880d681SAndroid Build Coastguard Worker       if (Operand->use_empty())
610*9880d681SAndroid Build Coastguard Worker         DeadNodes.push_back(Operand);
611*9880d681SAndroid Build Coastguard Worker     }
612*9880d681SAndroid Build Coastguard Worker 
613*9880d681SAndroid Build Coastguard Worker     DeallocateNode(N);
614*9880d681SAndroid Build Coastguard Worker   }
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker 
RemoveDeadNode(SDNode * N)617*9880d681SAndroid Build Coastguard Worker void SelectionDAG::RemoveDeadNode(SDNode *N){
618*9880d681SAndroid Build Coastguard Worker   SmallVector<SDNode*, 16> DeadNodes(1, N);
619*9880d681SAndroid Build Coastguard Worker 
620*9880d681SAndroid Build Coastguard Worker   // Create a dummy node that adds a reference to the root node, preventing
621*9880d681SAndroid Build Coastguard Worker   // it from being deleted.  (This matters if the root is an operand of the
622*9880d681SAndroid Build Coastguard Worker   // dead node.)
623*9880d681SAndroid Build Coastguard Worker   HandleSDNode Dummy(getRoot());
624*9880d681SAndroid Build Coastguard Worker 
625*9880d681SAndroid Build Coastguard Worker   RemoveDeadNodes(DeadNodes);
626*9880d681SAndroid Build Coastguard Worker }
627*9880d681SAndroid Build Coastguard Worker 
DeleteNode(SDNode * N)628*9880d681SAndroid Build Coastguard Worker void SelectionDAG::DeleteNode(SDNode *N) {
629*9880d681SAndroid Build Coastguard Worker   // First take this out of the appropriate CSE map.
630*9880d681SAndroid Build Coastguard Worker   RemoveNodeFromCSEMaps(N);
631*9880d681SAndroid Build Coastguard Worker 
632*9880d681SAndroid Build Coastguard Worker   // Finally, remove uses due to operands of this node, remove from the
633*9880d681SAndroid Build Coastguard Worker   // AllNodes list, and delete the node.
634*9880d681SAndroid Build Coastguard Worker   DeleteNodeNotInCSEMaps(N);
635*9880d681SAndroid Build Coastguard Worker }
636*9880d681SAndroid Build Coastguard Worker 
DeleteNodeNotInCSEMaps(SDNode * N)637*9880d681SAndroid Build Coastguard Worker void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) {
638*9880d681SAndroid Build Coastguard Worker   assert(N->getIterator() != AllNodes.begin() &&
639*9880d681SAndroid Build Coastguard Worker          "Cannot delete the entry node!");
640*9880d681SAndroid Build Coastguard Worker   assert(N->use_empty() && "Cannot delete a node that is not dead!");
641*9880d681SAndroid Build Coastguard Worker 
642*9880d681SAndroid Build Coastguard Worker   // Drop all of the operands and decrement used node's use counts.
643*9880d681SAndroid Build Coastguard Worker   N->DropOperands();
644*9880d681SAndroid Build Coastguard Worker 
645*9880d681SAndroid Build Coastguard Worker   DeallocateNode(N);
646*9880d681SAndroid Build Coastguard Worker }
647*9880d681SAndroid Build Coastguard Worker 
erase(const SDNode * Node)648*9880d681SAndroid Build Coastguard Worker void SDDbgInfo::erase(const SDNode *Node) {
649*9880d681SAndroid Build Coastguard Worker   DbgValMapType::iterator I = DbgValMap.find(Node);
650*9880d681SAndroid Build Coastguard Worker   if (I == DbgValMap.end())
651*9880d681SAndroid Build Coastguard Worker     return;
652*9880d681SAndroid Build Coastguard Worker   for (auto &Val: I->second)
653*9880d681SAndroid Build Coastguard Worker     Val->setIsInvalidated();
654*9880d681SAndroid Build Coastguard Worker   DbgValMap.erase(I);
655*9880d681SAndroid Build Coastguard Worker }
656*9880d681SAndroid Build Coastguard Worker 
DeallocateNode(SDNode * N)657*9880d681SAndroid Build Coastguard Worker void SelectionDAG::DeallocateNode(SDNode *N) {
658*9880d681SAndroid Build Coastguard Worker   // If we have operands, deallocate them.
659*9880d681SAndroid Build Coastguard Worker   removeOperands(N);
660*9880d681SAndroid Build Coastguard Worker 
661*9880d681SAndroid Build Coastguard Worker   // Set the opcode to DELETED_NODE to help catch bugs when node
662*9880d681SAndroid Build Coastguard Worker   // memory is reallocated.
663*9880d681SAndroid Build Coastguard Worker   N->NodeType = ISD::DELETED_NODE;
664*9880d681SAndroid Build Coastguard Worker 
665*9880d681SAndroid Build Coastguard Worker   NodeAllocator.Deallocate(AllNodes.remove(N));
666*9880d681SAndroid Build Coastguard Worker 
667*9880d681SAndroid Build Coastguard Worker   // If any of the SDDbgValue nodes refer to this SDNode, invalidate
668*9880d681SAndroid Build Coastguard Worker   // them and forget about that node.
669*9880d681SAndroid Build Coastguard Worker   DbgInfo->erase(N);
670*9880d681SAndroid Build Coastguard Worker }
671*9880d681SAndroid Build Coastguard Worker 
672*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
673*9880d681SAndroid Build Coastguard Worker /// VerifySDNode - Sanity check the given SDNode.  Aborts if it is invalid.
VerifySDNode(SDNode * N)674*9880d681SAndroid Build Coastguard Worker static void VerifySDNode(SDNode *N) {
675*9880d681SAndroid Build Coastguard Worker   switch (N->getOpcode()) {
676*9880d681SAndroid Build Coastguard Worker   default:
677*9880d681SAndroid Build Coastguard Worker     break;
678*9880d681SAndroid Build Coastguard Worker   case ISD::BUILD_PAIR: {
679*9880d681SAndroid Build Coastguard Worker     EVT VT = N->getValueType(0);
680*9880d681SAndroid Build Coastguard Worker     assert(N->getNumValues() == 1 && "Too many results!");
681*9880d681SAndroid Build Coastguard Worker     assert(!VT.isVector() && (VT.isInteger() || VT.isFloatingPoint()) &&
682*9880d681SAndroid Build Coastguard Worker            "Wrong return type!");
683*9880d681SAndroid Build Coastguard Worker     assert(N->getNumOperands() == 2 && "Wrong number of operands!");
684*9880d681SAndroid Build Coastguard Worker     assert(N->getOperand(0).getValueType() == N->getOperand(1).getValueType() &&
685*9880d681SAndroid Build Coastguard Worker            "Mismatched operand types!");
686*9880d681SAndroid Build Coastguard Worker     assert(N->getOperand(0).getValueType().isInteger() == VT.isInteger() &&
687*9880d681SAndroid Build Coastguard Worker            "Wrong operand type!");
688*9880d681SAndroid Build Coastguard Worker     assert(VT.getSizeInBits() == 2 * N->getOperand(0).getValueSizeInBits() &&
689*9880d681SAndroid Build Coastguard Worker            "Wrong return type size");
690*9880d681SAndroid Build Coastguard Worker     break;
691*9880d681SAndroid Build Coastguard Worker   }
692*9880d681SAndroid Build Coastguard Worker   case ISD::BUILD_VECTOR: {
693*9880d681SAndroid Build Coastguard Worker     assert(N->getNumValues() == 1 && "Too many results!");
694*9880d681SAndroid Build Coastguard Worker     assert(N->getValueType(0).isVector() && "Wrong return type!");
695*9880d681SAndroid Build Coastguard Worker     assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() &&
696*9880d681SAndroid Build Coastguard Worker            "Wrong number of operands!");
697*9880d681SAndroid Build Coastguard Worker     EVT EltVT = N->getValueType(0).getVectorElementType();
698*9880d681SAndroid Build Coastguard Worker     for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
699*9880d681SAndroid Build Coastguard Worker       assert((I->getValueType() == EltVT ||
700*9880d681SAndroid Build Coastguard Worker              (EltVT.isInteger() && I->getValueType().isInteger() &&
701*9880d681SAndroid Build Coastguard Worker               EltVT.bitsLE(I->getValueType()))) &&
702*9880d681SAndroid Build Coastguard Worker             "Wrong operand type!");
703*9880d681SAndroid Build Coastguard Worker       assert(I->getValueType() == N->getOperand(0).getValueType() &&
704*9880d681SAndroid Build Coastguard Worker              "Operands must all have the same type");
705*9880d681SAndroid Build Coastguard Worker     }
706*9880d681SAndroid Build Coastguard Worker     break;
707*9880d681SAndroid Build Coastguard Worker   }
708*9880d681SAndroid Build Coastguard Worker   }
709*9880d681SAndroid Build Coastguard Worker }
710*9880d681SAndroid Build Coastguard Worker #endif // NDEBUG
711*9880d681SAndroid Build Coastguard Worker 
712*9880d681SAndroid Build Coastguard Worker /// \brief Insert a newly allocated node into the DAG.
713*9880d681SAndroid Build Coastguard Worker ///
714*9880d681SAndroid Build Coastguard Worker /// Handles insertion into the all nodes list and CSE map, as well as
715*9880d681SAndroid Build Coastguard Worker /// verification and other common operations when a new node is allocated.
InsertNode(SDNode * N)716*9880d681SAndroid Build Coastguard Worker void SelectionDAG::InsertNode(SDNode *N) {
717*9880d681SAndroid Build Coastguard Worker   AllNodes.push_back(N);
718*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
719*9880d681SAndroid Build Coastguard Worker   N->PersistentId = NextPersistentId++;
720*9880d681SAndroid Build Coastguard Worker   VerifySDNode(N);
721*9880d681SAndroid Build Coastguard Worker #endif
722*9880d681SAndroid Build Coastguard Worker }
723*9880d681SAndroid Build Coastguard Worker 
724*9880d681SAndroid Build Coastguard Worker /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
725*9880d681SAndroid Build Coastguard Worker /// correspond to it.  This is useful when we're about to delete or repurpose
726*9880d681SAndroid Build Coastguard Worker /// the node.  We don't want future request for structurally identical nodes
727*9880d681SAndroid Build Coastguard Worker /// to return N anymore.
RemoveNodeFromCSEMaps(SDNode * N)728*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
729*9880d681SAndroid Build Coastguard Worker   bool Erased = false;
730*9880d681SAndroid Build Coastguard Worker   switch (N->getOpcode()) {
731*9880d681SAndroid Build Coastguard Worker   case ISD::HANDLENODE: return false;  // noop.
732*9880d681SAndroid Build Coastguard Worker   case ISD::CONDCODE:
733*9880d681SAndroid Build Coastguard Worker     assert(CondCodeNodes[cast<CondCodeSDNode>(N)->get()] &&
734*9880d681SAndroid Build Coastguard Worker            "Cond code doesn't exist!");
735*9880d681SAndroid Build Coastguard Worker     Erased = CondCodeNodes[cast<CondCodeSDNode>(N)->get()] != nullptr;
736*9880d681SAndroid Build Coastguard Worker     CondCodeNodes[cast<CondCodeSDNode>(N)->get()] = nullptr;
737*9880d681SAndroid Build Coastguard Worker     break;
738*9880d681SAndroid Build Coastguard Worker   case ISD::ExternalSymbol:
739*9880d681SAndroid Build Coastguard Worker     Erased = ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
740*9880d681SAndroid Build Coastguard Worker     break;
741*9880d681SAndroid Build Coastguard Worker   case ISD::TargetExternalSymbol: {
742*9880d681SAndroid Build Coastguard Worker     ExternalSymbolSDNode *ESN = cast<ExternalSymbolSDNode>(N);
743*9880d681SAndroid Build Coastguard Worker     Erased = TargetExternalSymbols.erase(
744*9880d681SAndroid Build Coastguard Worker                std::pair<std::string,unsigned char>(ESN->getSymbol(),
745*9880d681SAndroid Build Coastguard Worker                                                     ESN->getTargetFlags()));
746*9880d681SAndroid Build Coastguard Worker     break;
747*9880d681SAndroid Build Coastguard Worker   }
748*9880d681SAndroid Build Coastguard Worker   case ISD::MCSymbol: {
749*9880d681SAndroid Build Coastguard Worker     auto *MCSN = cast<MCSymbolSDNode>(N);
750*9880d681SAndroid Build Coastguard Worker     Erased = MCSymbols.erase(MCSN->getMCSymbol());
751*9880d681SAndroid Build Coastguard Worker     break;
752*9880d681SAndroid Build Coastguard Worker   }
753*9880d681SAndroid Build Coastguard Worker   case ISD::VALUETYPE: {
754*9880d681SAndroid Build Coastguard Worker     EVT VT = cast<VTSDNode>(N)->getVT();
755*9880d681SAndroid Build Coastguard Worker     if (VT.isExtended()) {
756*9880d681SAndroid Build Coastguard Worker       Erased = ExtendedValueTypeNodes.erase(VT);
757*9880d681SAndroid Build Coastguard Worker     } else {
758*9880d681SAndroid Build Coastguard Worker       Erased = ValueTypeNodes[VT.getSimpleVT().SimpleTy] != nullptr;
759*9880d681SAndroid Build Coastguard Worker       ValueTypeNodes[VT.getSimpleVT().SimpleTy] = nullptr;
760*9880d681SAndroid Build Coastguard Worker     }
761*9880d681SAndroid Build Coastguard Worker     break;
762*9880d681SAndroid Build Coastguard Worker   }
763*9880d681SAndroid Build Coastguard Worker   default:
764*9880d681SAndroid Build Coastguard Worker     // Remove it from the CSE Map.
765*9880d681SAndroid Build Coastguard Worker     assert(N->getOpcode() != ISD::DELETED_NODE && "DELETED_NODE in CSEMap!");
766*9880d681SAndroid Build Coastguard Worker     assert(N->getOpcode() != ISD::EntryToken && "EntryToken in CSEMap!");
767*9880d681SAndroid Build Coastguard Worker     Erased = CSEMap.RemoveNode(N);
768*9880d681SAndroid Build Coastguard Worker     break;
769*9880d681SAndroid Build Coastguard Worker   }
770*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
771*9880d681SAndroid Build Coastguard Worker   // Verify that the node was actually in one of the CSE maps, unless it has a
772*9880d681SAndroid Build Coastguard Worker   // flag result (which cannot be CSE'd) or is one of the special cases that are
773*9880d681SAndroid Build Coastguard Worker   // not subject to CSE.
774*9880d681SAndroid Build Coastguard Worker   if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Glue &&
775*9880d681SAndroid Build Coastguard Worker       !N->isMachineOpcode() && !doNotCSE(N)) {
776*9880d681SAndroid Build Coastguard Worker     N->dump(this);
777*9880d681SAndroid Build Coastguard Worker     dbgs() << "\n";
778*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Node is not in map!");
779*9880d681SAndroid Build Coastguard Worker   }
780*9880d681SAndroid Build Coastguard Worker #endif
781*9880d681SAndroid Build Coastguard Worker   return Erased;
782*9880d681SAndroid Build Coastguard Worker }
783*9880d681SAndroid Build Coastguard Worker 
784*9880d681SAndroid Build Coastguard Worker /// AddModifiedNodeToCSEMaps - The specified node has been removed from the CSE
785*9880d681SAndroid Build Coastguard Worker /// maps and modified in place. Add it back to the CSE maps, unless an identical
786*9880d681SAndroid Build Coastguard Worker /// node already exists, in which case transfer all its users to the existing
787*9880d681SAndroid Build Coastguard Worker /// node. This transfer can potentially trigger recursive merging.
788*9880d681SAndroid Build Coastguard Worker ///
789*9880d681SAndroid Build Coastguard Worker void
AddModifiedNodeToCSEMaps(SDNode * N)790*9880d681SAndroid Build Coastguard Worker SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N) {
791*9880d681SAndroid Build Coastguard Worker   // For node types that aren't CSE'd, just act as if no identical node
792*9880d681SAndroid Build Coastguard Worker   // already exists.
793*9880d681SAndroid Build Coastguard Worker   if (!doNotCSE(N)) {
794*9880d681SAndroid Build Coastguard Worker     SDNode *Existing = CSEMap.GetOrInsertNode(N);
795*9880d681SAndroid Build Coastguard Worker     if (Existing != N) {
796*9880d681SAndroid Build Coastguard Worker       // If there was already an existing matching node, use ReplaceAllUsesWith
797*9880d681SAndroid Build Coastguard Worker       // to replace the dead one with the existing one.  This can cause
798*9880d681SAndroid Build Coastguard Worker       // recursive merging of other unrelated nodes down the line.
799*9880d681SAndroid Build Coastguard Worker       ReplaceAllUsesWith(N, Existing);
800*9880d681SAndroid Build Coastguard Worker 
801*9880d681SAndroid Build Coastguard Worker       // N is now dead. Inform the listeners and delete it.
802*9880d681SAndroid Build Coastguard Worker       for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next)
803*9880d681SAndroid Build Coastguard Worker         DUL->NodeDeleted(N, Existing);
804*9880d681SAndroid Build Coastguard Worker       DeleteNodeNotInCSEMaps(N);
805*9880d681SAndroid Build Coastguard Worker       return;
806*9880d681SAndroid Build Coastguard Worker     }
807*9880d681SAndroid Build Coastguard Worker   }
808*9880d681SAndroid Build Coastguard Worker 
809*9880d681SAndroid Build Coastguard Worker   // If the node doesn't already exist, we updated it.  Inform listeners.
810*9880d681SAndroid Build Coastguard Worker   for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next)
811*9880d681SAndroid Build Coastguard Worker     DUL->NodeUpdated(N);
812*9880d681SAndroid Build Coastguard Worker }
813*9880d681SAndroid Build Coastguard Worker 
814*9880d681SAndroid Build Coastguard Worker /// FindModifiedNodeSlot - Find a slot for the specified node if its operands
815*9880d681SAndroid Build Coastguard Worker /// were replaced with those specified.  If this node is never memoized,
816*9880d681SAndroid Build Coastguard Worker /// return null, otherwise return a pointer to the slot it would take.  If a
817*9880d681SAndroid Build Coastguard Worker /// node already exists with these operands, the slot will be non-null.
FindModifiedNodeSlot(SDNode * N,SDValue Op,void * & InsertPos)818*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDValue Op,
819*9880d681SAndroid Build Coastguard Worker                                            void *&InsertPos) {
820*9880d681SAndroid Build Coastguard Worker   if (doNotCSE(N))
821*9880d681SAndroid Build Coastguard Worker     return nullptr;
822*9880d681SAndroid Build Coastguard Worker 
823*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op };
824*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
825*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops);
826*9880d681SAndroid Build Coastguard Worker   AddNodeIDCustom(ID, N);
827*9880d681SAndroid Build Coastguard Worker   SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos);
828*9880d681SAndroid Build Coastguard Worker   if (Node)
829*9880d681SAndroid Build Coastguard Worker     if (const SDNodeFlags *Flags = N->getFlags())
830*9880d681SAndroid Build Coastguard Worker       Node->intersectFlagsWith(Flags);
831*9880d681SAndroid Build Coastguard Worker   return Node;
832*9880d681SAndroid Build Coastguard Worker }
833*9880d681SAndroid Build Coastguard Worker 
834*9880d681SAndroid Build Coastguard Worker /// FindModifiedNodeSlot - Find a slot for the specified node if its operands
835*9880d681SAndroid Build Coastguard Worker /// were replaced with those specified.  If this node is never memoized,
836*9880d681SAndroid Build Coastguard Worker /// return null, otherwise return a pointer to the slot it would take.  If a
837*9880d681SAndroid Build Coastguard Worker /// node already exists with these operands, the slot will be non-null.
FindModifiedNodeSlot(SDNode * N,SDValue Op1,SDValue Op2,void * & InsertPos)838*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,
839*9880d681SAndroid Build Coastguard Worker                                            SDValue Op1, SDValue Op2,
840*9880d681SAndroid Build Coastguard Worker                                            void *&InsertPos) {
841*9880d681SAndroid Build Coastguard Worker   if (doNotCSE(N))
842*9880d681SAndroid Build Coastguard Worker     return nullptr;
843*9880d681SAndroid Build Coastguard Worker 
844*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2 };
845*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
846*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops);
847*9880d681SAndroid Build Coastguard Worker   AddNodeIDCustom(ID, N);
848*9880d681SAndroid Build Coastguard Worker   SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos);
849*9880d681SAndroid Build Coastguard Worker   if (Node)
850*9880d681SAndroid Build Coastguard Worker     if (const SDNodeFlags *Flags = N->getFlags())
851*9880d681SAndroid Build Coastguard Worker       Node->intersectFlagsWith(Flags);
852*9880d681SAndroid Build Coastguard Worker   return Node;
853*9880d681SAndroid Build Coastguard Worker }
854*9880d681SAndroid Build Coastguard Worker 
855*9880d681SAndroid Build Coastguard Worker 
856*9880d681SAndroid Build Coastguard Worker /// FindModifiedNodeSlot - Find a slot for the specified node if its operands
857*9880d681SAndroid Build Coastguard Worker /// were replaced with those specified.  If this node is never memoized,
858*9880d681SAndroid Build Coastguard Worker /// return null, otherwise return a pointer to the slot it would take.  If a
859*9880d681SAndroid Build Coastguard Worker /// node already exists with these operands, the slot will be non-null.
FindModifiedNodeSlot(SDNode * N,ArrayRef<SDValue> Ops,void * & InsertPos)860*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, ArrayRef<SDValue> Ops,
861*9880d681SAndroid Build Coastguard Worker                                            void *&InsertPos) {
862*9880d681SAndroid Build Coastguard Worker   if (doNotCSE(N))
863*9880d681SAndroid Build Coastguard Worker     return nullptr;
864*9880d681SAndroid Build Coastguard Worker 
865*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
866*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops);
867*9880d681SAndroid Build Coastguard Worker   AddNodeIDCustom(ID, N);
868*9880d681SAndroid Build Coastguard Worker   SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos);
869*9880d681SAndroid Build Coastguard Worker   if (Node)
870*9880d681SAndroid Build Coastguard Worker     if (const SDNodeFlags *Flags = N->getFlags())
871*9880d681SAndroid Build Coastguard Worker       Node->intersectFlagsWith(Flags);
872*9880d681SAndroid Build Coastguard Worker   return Node;
873*9880d681SAndroid Build Coastguard Worker }
874*9880d681SAndroid Build Coastguard Worker 
getEVTAlignment(EVT VT) const875*9880d681SAndroid Build Coastguard Worker unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
876*9880d681SAndroid Build Coastguard Worker   Type *Ty = VT == MVT::iPTR ?
877*9880d681SAndroid Build Coastguard Worker                    PointerType::get(Type::getInt8Ty(*getContext()), 0) :
878*9880d681SAndroid Build Coastguard Worker                    VT.getTypeForEVT(*getContext());
879*9880d681SAndroid Build Coastguard Worker 
880*9880d681SAndroid Build Coastguard Worker   return getDataLayout().getABITypeAlignment(Ty);
881*9880d681SAndroid Build Coastguard Worker }
882*9880d681SAndroid Build Coastguard Worker 
883*9880d681SAndroid Build Coastguard Worker // EntryNode could meaningfully have debug info if we can find it...
SelectionDAG(const TargetMachine & tm,CodeGenOpt::Level OL)884*9880d681SAndroid Build Coastguard Worker SelectionDAG::SelectionDAG(const TargetMachine &tm, CodeGenOpt::Level OL)
885*9880d681SAndroid Build Coastguard Worker     : TM(tm), TSI(nullptr), TLI(nullptr), OptLevel(OL),
886*9880d681SAndroid Build Coastguard Worker       EntryNode(ISD::EntryToken, 0, DebugLoc(), getVTList(MVT::Other)),
887*9880d681SAndroid Build Coastguard Worker       Root(getEntryNode()), NewNodesMustHaveLegalTypes(false),
888*9880d681SAndroid Build Coastguard Worker       UpdateListeners(nullptr) {
889*9880d681SAndroid Build Coastguard Worker   InsertNode(&EntryNode);
890*9880d681SAndroid Build Coastguard Worker   DbgInfo = new SDDbgInfo();
891*9880d681SAndroid Build Coastguard Worker }
892*9880d681SAndroid Build Coastguard Worker 
init(MachineFunction & mf)893*9880d681SAndroid Build Coastguard Worker void SelectionDAG::init(MachineFunction &mf) {
894*9880d681SAndroid Build Coastguard Worker   MF = &mf;
895*9880d681SAndroid Build Coastguard Worker   TLI = getSubtarget().getTargetLowering();
896*9880d681SAndroid Build Coastguard Worker   TSI = getSubtarget().getSelectionDAGInfo();
897*9880d681SAndroid Build Coastguard Worker   Context = &mf.getFunction()->getContext();
898*9880d681SAndroid Build Coastguard Worker }
899*9880d681SAndroid Build Coastguard Worker 
~SelectionDAG()900*9880d681SAndroid Build Coastguard Worker SelectionDAG::~SelectionDAG() {
901*9880d681SAndroid Build Coastguard Worker   assert(!UpdateListeners && "Dangling registered DAGUpdateListeners");
902*9880d681SAndroid Build Coastguard Worker   allnodes_clear();
903*9880d681SAndroid Build Coastguard Worker   OperandRecycler.clear(OperandAllocator);
904*9880d681SAndroid Build Coastguard Worker   delete DbgInfo;
905*9880d681SAndroid Build Coastguard Worker }
906*9880d681SAndroid Build Coastguard Worker 
allnodes_clear()907*9880d681SAndroid Build Coastguard Worker void SelectionDAG::allnodes_clear() {
908*9880d681SAndroid Build Coastguard Worker   assert(&*AllNodes.begin() == &EntryNode);
909*9880d681SAndroid Build Coastguard Worker   AllNodes.remove(AllNodes.begin());
910*9880d681SAndroid Build Coastguard Worker   while (!AllNodes.empty())
911*9880d681SAndroid Build Coastguard Worker     DeallocateNode(&AllNodes.front());
912*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
913*9880d681SAndroid Build Coastguard Worker   NextPersistentId = 0;
914*9880d681SAndroid Build Coastguard Worker #endif
915*9880d681SAndroid Build Coastguard Worker }
916*9880d681SAndroid Build Coastguard Worker 
GetBinarySDNode(unsigned Opcode,const SDLoc & DL,SDVTList VTs,SDValue N1,SDValue N2,const SDNodeFlags * Flags)917*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::GetBinarySDNode(unsigned Opcode, const SDLoc &DL,
918*9880d681SAndroid Build Coastguard Worker                                       SDVTList VTs, SDValue N1, SDValue N2,
919*9880d681SAndroid Build Coastguard Worker                                       const SDNodeFlags *Flags) {
920*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {N1, N2};
921*9880d681SAndroid Build Coastguard Worker 
922*9880d681SAndroid Build Coastguard Worker   if (isBinOpWithFlags(Opcode)) {
923*9880d681SAndroid Build Coastguard Worker     // If no flags were passed in, use a default flags object.
924*9880d681SAndroid Build Coastguard Worker     SDNodeFlags F;
925*9880d681SAndroid Build Coastguard Worker     if (Flags == nullptr)
926*9880d681SAndroid Build Coastguard Worker       Flags = &F;
927*9880d681SAndroid Build Coastguard Worker 
928*9880d681SAndroid Build Coastguard Worker     auto *FN = newSDNode<BinaryWithFlagsSDNode>(Opcode, DL.getIROrder(),
929*9880d681SAndroid Build Coastguard Worker                                                 DL.getDebugLoc(), VTs, *Flags);
930*9880d681SAndroid Build Coastguard Worker     createOperands(FN, Ops);
931*9880d681SAndroid Build Coastguard Worker 
932*9880d681SAndroid Build Coastguard Worker     return FN;
933*9880d681SAndroid Build Coastguard Worker   }
934*9880d681SAndroid Build Coastguard Worker 
935*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
936*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
937*9880d681SAndroid Build Coastguard Worker   return N;
938*9880d681SAndroid Build Coastguard Worker }
939*9880d681SAndroid Build Coastguard Worker 
FindNodeOrInsertPos(const FoldingSetNodeID & ID,void * & InsertPos)940*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::FindNodeOrInsertPos(const FoldingSetNodeID &ID,
941*9880d681SAndroid Build Coastguard Worker                                           void *&InsertPos) {
942*9880d681SAndroid Build Coastguard Worker   SDNode *N = CSEMap.FindNodeOrInsertPos(ID, InsertPos);
943*9880d681SAndroid Build Coastguard Worker   if (N) {
944*9880d681SAndroid Build Coastguard Worker     switch (N->getOpcode()) {
945*9880d681SAndroid Build Coastguard Worker     default: break;
946*9880d681SAndroid Build Coastguard Worker     case ISD::Constant:
947*9880d681SAndroid Build Coastguard Worker     case ISD::ConstantFP:
948*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Querying for Constant and ConstantFP nodes requires "
949*9880d681SAndroid Build Coastguard Worker                        "debug location.  Use another overload.");
950*9880d681SAndroid Build Coastguard Worker     }
951*9880d681SAndroid Build Coastguard Worker   }
952*9880d681SAndroid Build Coastguard Worker   return N;
953*9880d681SAndroid Build Coastguard Worker }
954*9880d681SAndroid Build Coastguard Worker 
FindNodeOrInsertPos(const FoldingSetNodeID & ID,const SDLoc & DL,void * & InsertPos)955*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::FindNodeOrInsertPos(const FoldingSetNodeID &ID,
956*9880d681SAndroid Build Coastguard Worker                                           const SDLoc &DL, void *&InsertPos) {
957*9880d681SAndroid Build Coastguard Worker   SDNode *N = CSEMap.FindNodeOrInsertPos(ID, InsertPos);
958*9880d681SAndroid Build Coastguard Worker   if (N) {
959*9880d681SAndroid Build Coastguard Worker     switch (N->getOpcode()) {
960*9880d681SAndroid Build Coastguard Worker     case ISD::Constant:
961*9880d681SAndroid Build Coastguard Worker     case ISD::ConstantFP:
962*9880d681SAndroid Build Coastguard Worker       // Erase debug location from the node if the node is used at several
963*9880d681SAndroid Build Coastguard Worker       // different places. Do not propagate one location to all uses as it
964*9880d681SAndroid Build Coastguard Worker       // will cause a worse single stepping debugging experience.
965*9880d681SAndroid Build Coastguard Worker       if (N->getDebugLoc() != DL.getDebugLoc())
966*9880d681SAndroid Build Coastguard Worker         N->setDebugLoc(DebugLoc());
967*9880d681SAndroid Build Coastguard Worker       break;
968*9880d681SAndroid Build Coastguard Worker     default:
969*9880d681SAndroid Build Coastguard Worker       // When the node's point of use is located earlier in the instruction
970*9880d681SAndroid Build Coastguard Worker       // sequence than its prior point of use, update its debug info to the
971*9880d681SAndroid Build Coastguard Worker       // earlier location.
972*9880d681SAndroid Build Coastguard Worker       if (DL.getIROrder() && DL.getIROrder() < N->getIROrder())
973*9880d681SAndroid Build Coastguard Worker         N->setDebugLoc(DL.getDebugLoc());
974*9880d681SAndroid Build Coastguard Worker       break;
975*9880d681SAndroid Build Coastguard Worker     }
976*9880d681SAndroid Build Coastguard Worker   }
977*9880d681SAndroid Build Coastguard Worker   return N;
978*9880d681SAndroid Build Coastguard Worker }
979*9880d681SAndroid Build Coastguard Worker 
clear()980*9880d681SAndroid Build Coastguard Worker void SelectionDAG::clear() {
981*9880d681SAndroid Build Coastguard Worker   allnodes_clear();
982*9880d681SAndroid Build Coastguard Worker   OperandRecycler.clear(OperandAllocator);
983*9880d681SAndroid Build Coastguard Worker   OperandAllocator.Reset();
984*9880d681SAndroid Build Coastguard Worker   CSEMap.clear();
985*9880d681SAndroid Build Coastguard Worker 
986*9880d681SAndroid Build Coastguard Worker   ExtendedValueTypeNodes.clear();
987*9880d681SAndroid Build Coastguard Worker   ExternalSymbols.clear();
988*9880d681SAndroid Build Coastguard Worker   TargetExternalSymbols.clear();
989*9880d681SAndroid Build Coastguard Worker   MCSymbols.clear();
990*9880d681SAndroid Build Coastguard Worker   std::fill(CondCodeNodes.begin(), CondCodeNodes.end(),
991*9880d681SAndroid Build Coastguard Worker             static_cast<CondCodeSDNode*>(nullptr));
992*9880d681SAndroid Build Coastguard Worker   std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(),
993*9880d681SAndroid Build Coastguard Worker             static_cast<SDNode*>(nullptr));
994*9880d681SAndroid Build Coastguard Worker 
995*9880d681SAndroid Build Coastguard Worker   EntryNode.UseList = nullptr;
996*9880d681SAndroid Build Coastguard Worker   InsertNode(&EntryNode);
997*9880d681SAndroid Build Coastguard Worker   Root = getEntryNode();
998*9880d681SAndroid Build Coastguard Worker   DbgInfo->clear();
999*9880d681SAndroid Build Coastguard Worker }
1000*9880d681SAndroid Build Coastguard Worker 
getAnyExtOrTrunc(SDValue Op,const SDLoc & DL,EVT VT)1001*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT) {
1002*9880d681SAndroid Build Coastguard Worker   return VT.bitsGT(Op.getValueType()) ?
1003*9880d681SAndroid Build Coastguard Worker     getNode(ISD::ANY_EXTEND, DL, VT, Op) :
1004*9880d681SAndroid Build Coastguard Worker     getNode(ISD::TRUNCATE, DL, VT, Op);
1005*9880d681SAndroid Build Coastguard Worker }
1006*9880d681SAndroid Build Coastguard Worker 
getSExtOrTrunc(SDValue Op,const SDLoc & DL,EVT VT)1007*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT) {
1008*9880d681SAndroid Build Coastguard Worker   return VT.bitsGT(Op.getValueType()) ?
1009*9880d681SAndroid Build Coastguard Worker     getNode(ISD::SIGN_EXTEND, DL, VT, Op) :
1010*9880d681SAndroid Build Coastguard Worker     getNode(ISD::TRUNCATE, DL, VT, Op);
1011*9880d681SAndroid Build Coastguard Worker }
1012*9880d681SAndroid Build Coastguard Worker 
getZExtOrTrunc(SDValue Op,const SDLoc & DL,EVT VT)1013*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT) {
1014*9880d681SAndroid Build Coastguard Worker   return VT.bitsGT(Op.getValueType()) ?
1015*9880d681SAndroid Build Coastguard Worker     getNode(ISD::ZERO_EXTEND, DL, VT, Op) :
1016*9880d681SAndroid Build Coastguard Worker     getNode(ISD::TRUNCATE, DL, VT, Op);
1017*9880d681SAndroid Build Coastguard Worker }
1018*9880d681SAndroid Build Coastguard Worker 
getBoolExtOrTrunc(SDValue Op,const SDLoc & SL,EVT VT,EVT OpVT)1019*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT,
1020*9880d681SAndroid Build Coastguard Worker                                         EVT OpVT) {
1021*9880d681SAndroid Build Coastguard Worker   if (VT.bitsLE(Op.getValueType()))
1022*9880d681SAndroid Build Coastguard Worker     return getNode(ISD::TRUNCATE, SL, VT, Op);
1023*9880d681SAndroid Build Coastguard Worker 
1024*9880d681SAndroid Build Coastguard Worker   TargetLowering::BooleanContent BType = TLI->getBooleanContents(OpVT);
1025*9880d681SAndroid Build Coastguard Worker   return getNode(TLI->getExtendForContent(BType), SL, VT, Op);
1026*9880d681SAndroid Build Coastguard Worker }
1027*9880d681SAndroid Build Coastguard Worker 
getZeroExtendInReg(SDValue Op,const SDLoc & DL,EVT VT)1028*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT) {
1029*9880d681SAndroid Build Coastguard Worker   assert(!VT.isVector() &&
1030*9880d681SAndroid Build Coastguard Worker          "getZeroExtendInReg should use the vector element type instead of "
1031*9880d681SAndroid Build Coastguard Worker          "the vector type!");
1032*9880d681SAndroid Build Coastguard Worker   if (Op.getValueType() == VT) return Op;
1033*9880d681SAndroid Build Coastguard Worker   unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits();
1034*9880d681SAndroid Build Coastguard Worker   APInt Imm = APInt::getLowBitsSet(BitWidth,
1035*9880d681SAndroid Build Coastguard Worker                                    VT.getSizeInBits());
1036*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::AND, DL, Op.getValueType(), Op,
1037*9880d681SAndroid Build Coastguard Worker                  getConstant(Imm, DL, Op.getValueType()));
1038*9880d681SAndroid Build Coastguard Worker }
1039*9880d681SAndroid Build Coastguard Worker 
getAnyExtendVectorInReg(SDValue Op,const SDLoc & DL,EVT VT)1040*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAnyExtendVectorInReg(SDValue Op, const SDLoc &DL,
1041*9880d681SAndroid Build Coastguard Worker                                               EVT VT) {
1042*9880d681SAndroid Build Coastguard Worker   assert(VT.isVector() && "This DAG node is restricted to vector types.");
1043*9880d681SAndroid Build Coastguard Worker   assert(VT.getSizeInBits() == Op.getValueType().getSizeInBits() &&
1044*9880d681SAndroid Build Coastguard Worker          "The sizes of the input and result must match in order to perform the "
1045*9880d681SAndroid Build Coastguard Worker          "extend in-register.");
1046*9880d681SAndroid Build Coastguard Worker   assert(VT.getVectorNumElements() < Op.getValueType().getVectorNumElements() &&
1047*9880d681SAndroid Build Coastguard Worker          "The destination vector type must have fewer lanes than the input.");
1048*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, VT, Op);
1049*9880d681SAndroid Build Coastguard Worker }
1050*9880d681SAndroid Build Coastguard Worker 
getSignExtendVectorInReg(SDValue Op,const SDLoc & DL,EVT VT)1051*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getSignExtendVectorInReg(SDValue Op, const SDLoc &DL,
1052*9880d681SAndroid Build Coastguard Worker                                                EVT VT) {
1053*9880d681SAndroid Build Coastguard Worker   assert(VT.isVector() && "This DAG node is restricted to vector types.");
1054*9880d681SAndroid Build Coastguard Worker   assert(VT.getSizeInBits() == Op.getValueType().getSizeInBits() &&
1055*9880d681SAndroid Build Coastguard Worker          "The sizes of the input and result must match in order to perform the "
1056*9880d681SAndroid Build Coastguard Worker          "extend in-register.");
1057*9880d681SAndroid Build Coastguard Worker   assert(VT.getVectorNumElements() < Op.getValueType().getVectorNumElements() &&
1058*9880d681SAndroid Build Coastguard Worker          "The destination vector type must have fewer lanes than the input.");
1059*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, VT, Op);
1060*9880d681SAndroid Build Coastguard Worker }
1061*9880d681SAndroid Build Coastguard Worker 
getZeroExtendVectorInReg(SDValue Op,const SDLoc & DL,EVT VT)1062*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getZeroExtendVectorInReg(SDValue Op, const SDLoc &DL,
1063*9880d681SAndroid Build Coastguard Worker                                                EVT VT) {
1064*9880d681SAndroid Build Coastguard Worker   assert(VT.isVector() && "This DAG node is restricted to vector types.");
1065*9880d681SAndroid Build Coastguard Worker   assert(VT.getSizeInBits() == Op.getValueType().getSizeInBits() &&
1066*9880d681SAndroid Build Coastguard Worker          "The sizes of the input and result must match in order to perform the "
1067*9880d681SAndroid Build Coastguard Worker          "extend in-register.");
1068*9880d681SAndroid Build Coastguard Worker   assert(VT.getVectorNumElements() < Op.getValueType().getVectorNumElements() &&
1069*9880d681SAndroid Build Coastguard Worker          "The destination vector type must have fewer lanes than the input.");
1070*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::ZERO_EXTEND_VECTOR_INREG, DL, VT, Op);
1071*9880d681SAndroid Build Coastguard Worker }
1072*9880d681SAndroid Build Coastguard Worker 
1073*9880d681SAndroid Build Coastguard Worker /// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
1074*9880d681SAndroid Build Coastguard Worker ///
getNOT(const SDLoc & DL,SDValue Val,EVT VT)1075*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNOT(const SDLoc &DL, SDValue Val, EVT VT) {
1076*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getScalarType();
1077*9880d681SAndroid Build Coastguard Worker   SDValue NegOne =
1078*9880d681SAndroid Build Coastguard Worker     getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), DL, VT);
1079*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::XOR, DL, VT, Val, NegOne);
1080*9880d681SAndroid Build Coastguard Worker }
1081*9880d681SAndroid Build Coastguard Worker 
getLogicalNOT(const SDLoc & DL,SDValue Val,EVT VT)1082*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT) {
1083*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getScalarType();
1084*9880d681SAndroid Build Coastguard Worker   SDValue TrueValue;
1085*9880d681SAndroid Build Coastguard Worker   switch (TLI->getBooleanContents(VT)) {
1086*9880d681SAndroid Build Coastguard Worker     case TargetLowering::ZeroOrOneBooleanContent:
1087*9880d681SAndroid Build Coastguard Worker     case TargetLowering::UndefinedBooleanContent:
1088*9880d681SAndroid Build Coastguard Worker       TrueValue = getConstant(1, DL, VT);
1089*9880d681SAndroid Build Coastguard Worker       break;
1090*9880d681SAndroid Build Coastguard Worker     case TargetLowering::ZeroOrNegativeOneBooleanContent:
1091*9880d681SAndroid Build Coastguard Worker       TrueValue = getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), DL,
1092*9880d681SAndroid Build Coastguard Worker                               VT);
1093*9880d681SAndroid Build Coastguard Worker       break;
1094*9880d681SAndroid Build Coastguard Worker   }
1095*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::XOR, DL, VT, Val, TrueValue);
1096*9880d681SAndroid Build Coastguard Worker }
1097*9880d681SAndroid Build Coastguard Worker 
getConstant(uint64_t Val,const SDLoc & DL,EVT VT,bool isT,bool isO)1098*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstant(uint64_t Val, const SDLoc &DL, EVT VT,
1099*9880d681SAndroid Build Coastguard Worker                                   bool isT, bool isO) {
1100*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getScalarType();
1101*9880d681SAndroid Build Coastguard Worker   assert((EltVT.getSizeInBits() >= 64 ||
1102*9880d681SAndroid Build Coastguard Worker          (uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
1103*9880d681SAndroid Build Coastguard Worker          "getConstant with a uint64_t value that doesn't fit in the type!");
1104*9880d681SAndroid Build Coastguard Worker   return getConstant(APInt(EltVT.getSizeInBits(), Val), DL, VT, isT, isO);
1105*9880d681SAndroid Build Coastguard Worker }
1106*9880d681SAndroid Build Coastguard Worker 
getConstant(const APInt & Val,const SDLoc & DL,EVT VT,bool isT,bool isO)1107*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstant(const APInt &Val, const SDLoc &DL, EVT VT,
1108*9880d681SAndroid Build Coastguard Worker                                   bool isT, bool isO) {
1109*9880d681SAndroid Build Coastguard Worker   return getConstant(*ConstantInt::get(*Context, Val), DL, VT, isT, isO);
1110*9880d681SAndroid Build Coastguard Worker }
1111*9880d681SAndroid Build Coastguard Worker 
getConstant(const ConstantInt & Val,const SDLoc & DL,EVT VT,bool isT,bool isO)1112*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstant(const ConstantInt &Val, const SDLoc &DL,
1113*9880d681SAndroid Build Coastguard Worker                                   EVT VT, bool isT, bool isO) {
1114*9880d681SAndroid Build Coastguard Worker   assert(VT.isInteger() && "Cannot create FP integer constant!");
1115*9880d681SAndroid Build Coastguard Worker 
1116*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getScalarType();
1117*9880d681SAndroid Build Coastguard Worker   const ConstantInt *Elt = &Val;
1118*9880d681SAndroid Build Coastguard Worker 
1119*9880d681SAndroid Build Coastguard Worker   // In some cases the vector type is legal but the element type is illegal and
1120*9880d681SAndroid Build Coastguard Worker   // needs to be promoted, for example v8i8 on ARM.  In this case, promote the
1121*9880d681SAndroid Build Coastguard Worker   // inserted value (the type does not need to match the vector element type).
1122*9880d681SAndroid Build Coastguard Worker   // Any extra bits introduced will be truncated away.
1123*9880d681SAndroid Build Coastguard Worker   if (VT.isVector() && TLI->getTypeAction(*getContext(), EltVT) ==
1124*9880d681SAndroid Build Coastguard Worker       TargetLowering::TypePromoteInteger) {
1125*9880d681SAndroid Build Coastguard Worker    EltVT = TLI->getTypeToTransformTo(*getContext(), EltVT);
1126*9880d681SAndroid Build Coastguard Worker    APInt NewVal = Elt->getValue().zext(EltVT.getSizeInBits());
1127*9880d681SAndroid Build Coastguard Worker    Elt = ConstantInt::get(*getContext(), NewVal);
1128*9880d681SAndroid Build Coastguard Worker   }
1129*9880d681SAndroid Build Coastguard Worker   // In other cases the element type is illegal and needs to be expanded, for
1130*9880d681SAndroid Build Coastguard Worker   // example v2i64 on MIPS32. In this case, find the nearest legal type, split
1131*9880d681SAndroid Build Coastguard Worker   // the value into n parts and use a vector type with n-times the elements.
1132*9880d681SAndroid Build Coastguard Worker   // Then bitcast to the type requested.
1133*9880d681SAndroid Build Coastguard Worker   // Legalizing constants too early makes the DAGCombiner's job harder so we
1134*9880d681SAndroid Build Coastguard Worker   // only legalize if the DAG tells us we must produce legal types.
1135*9880d681SAndroid Build Coastguard Worker   else if (NewNodesMustHaveLegalTypes && VT.isVector() &&
1136*9880d681SAndroid Build Coastguard Worker            TLI->getTypeAction(*getContext(), EltVT) ==
1137*9880d681SAndroid Build Coastguard Worker            TargetLowering::TypeExpandInteger) {
1138*9880d681SAndroid Build Coastguard Worker     const APInt &NewVal = Elt->getValue();
1139*9880d681SAndroid Build Coastguard Worker     EVT ViaEltVT = TLI->getTypeToTransformTo(*getContext(), EltVT);
1140*9880d681SAndroid Build Coastguard Worker     unsigned ViaEltSizeInBits = ViaEltVT.getSizeInBits();
1141*9880d681SAndroid Build Coastguard Worker     unsigned ViaVecNumElts = VT.getSizeInBits() / ViaEltSizeInBits;
1142*9880d681SAndroid Build Coastguard Worker     EVT ViaVecVT = EVT::getVectorVT(*getContext(), ViaEltVT, ViaVecNumElts);
1143*9880d681SAndroid Build Coastguard Worker 
1144*9880d681SAndroid Build Coastguard Worker     // Check the temporary vector is the correct size. If this fails then
1145*9880d681SAndroid Build Coastguard Worker     // getTypeToTransformTo() probably returned a type whose size (in bits)
1146*9880d681SAndroid Build Coastguard Worker     // isn't a power-of-2 factor of the requested type size.
1147*9880d681SAndroid Build Coastguard Worker     assert(ViaVecVT.getSizeInBits() == VT.getSizeInBits());
1148*9880d681SAndroid Build Coastguard Worker 
1149*9880d681SAndroid Build Coastguard Worker     SmallVector<SDValue, 2> EltParts;
1150*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0; i < ViaVecNumElts / VT.getVectorNumElements(); ++i) {
1151*9880d681SAndroid Build Coastguard Worker       EltParts.push_back(getConstant(NewVal.lshr(i * ViaEltSizeInBits)
1152*9880d681SAndroid Build Coastguard Worker                                            .trunc(ViaEltSizeInBits), DL,
1153*9880d681SAndroid Build Coastguard Worker                                      ViaEltVT, isT, isO));
1154*9880d681SAndroid Build Coastguard Worker     }
1155*9880d681SAndroid Build Coastguard Worker 
1156*9880d681SAndroid Build Coastguard Worker     // EltParts is currently in little endian order. If we actually want
1157*9880d681SAndroid Build Coastguard Worker     // big-endian order then reverse it now.
1158*9880d681SAndroid Build Coastguard Worker     if (getDataLayout().isBigEndian())
1159*9880d681SAndroid Build Coastguard Worker       std::reverse(EltParts.begin(), EltParts.end());
1160*9880d681SAndroid Build Coastguard Worker 
1161*9880d681SAndroid Build Coastguard Worker     // The elements must be reversed when the element order is different
1162*9880d681SAndroid Build Coastguard Worker     // to the endianness of the elements (because the BITCAST is itself a
1163*9880d681SAndroid Build Coastguard Worker     // vector shuffle in this situation). However, we do not need any code to
1164*9880d681SAndroid Build Coastguard Worker     // perform this reversal because getConstant() is producing a vector
1165*9880d681SAndroid Build Coastguard Worker     // splat.
1166*9880d681SAndroid Build Coastguard Worker     // This situation occurs in MIPS MSA.
1167*9880d681SAndroid Build Coastguard Worker 
1168*9880d681SAndroid Build Coastguard Worker     SmallVector<SDValue, 8> Ops;
1169*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0; i < VT.getVectorNumElements(); ++i)
1170*9880d681SAndroid Build Coastguard Worker       Ops.insert(Ops.end(), EltParts.begin(), EltParts.end());
1171*9880d681SAndroid Build Coastguard Worker 
1172*9880d681SAndroid Build Coastguard Worker     SDValue Result = getNode(ISD::BITCAST, DL, VT,
1173*9880d681SAndroid Build Coastguard Worker                              getNode(ISD::BUILD_VECTOR, DL, ViaVecVT, Ops));
1174*9880d681SAndroid Build Coastguard Worker     return Result;
1175*9880d681SAndroid Build Coastguard Worker   }
1176*9880d681SAndroid Build Coastguard Worker 
1177*9880d681SAndroid Build Coastguard Worker   assert(Elt->getBitWidth() == EltVT.getSizeInBits() &&
1178*9880d681SAndroid Build Coastguard Worker          "APInt size does not match type size!");
1179*9880d681SAndroid Build Coastguard Worker   unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant;
1180*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1181*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(EltVT), None);
1182*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(Elt);
1183*9880d681SAndroid Build Coastguard Worker   ID.AddBoolean(isO);
1184*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1185*9880d681SAndroid Build Coastguard Worker   SDNode *N = nullptr;
1186*9880d681SAndroid Build Coastguard Worker   if ((N = FindNodeOrInsertPos(ID, DL, IP)))
1187*9880d681SAndroid Build Coastguard Worker     if (!VT.isVector())
1188*9880d681SAndroid Build Coastguard Worker       return SDValue(N, 0);
1189*9880d681SAndroid Build Coastguard Worker 
1190*9880d681SAndroid Build Coastguard Worker   if (!N) {
1191*9880d681SAndroid Build Coastguard Worker     N = newSDNode<ConstantSDNode>(isT, isO, Elt, DL.getDebugLoc(), EltVT);
1192*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
1193*9880d681SAndroid Build Coastguard Worker     InsertNode(N);
1194*9880d681SAndroid Build Coastguard Worker   }
1195*9880d681SAndroid Build Coastguard Worker 
1196*9880d681SAndroid Build Coastguard Worker   SDValue Result(N, 0);
1197*9880d681SAndroid Build Coastguard Worker   if (VT.isVector())
1198*9880d681SAndroid Build Coastguard Worker     Result = getSplatBuildVector(VT, DL, Result);
1199*9880d681SAndroid Build Coastguard Worker   return Result;
1200*9880d681SAndroid Build Coastguard Worker }
1201*9880d681SAndroid Build Coastguard Worker 
getIntPtrConstant(uint64_t Val,const SDLoc & DL,bool isTarget)1202*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getIntPtrConstant(uint64_t Val, const SDLoc &DL,
1203*9880d681SAndroid Build Coastguard Worker                                         bool isTarget) {
1204*9880d681SAndroid Build Coastguard Worker   return getConstant(Val, DL, TLI->getPointerTy(getDataLayout()), isTarget);
1205*9880d681SAndroid Build Coastguard Worker }
1206*9880d681SAndroid Build Coastguard Worker 
getConstantFP(const APFloat & V,const SDLoc & DL,EVT VT,bool isTarget)1207*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstantFP(const APFloat &V, const SDLoc &DL, EVT VT,
1208*9880d681SAndroid Build Coastguard Worker                                     bool isTarget) {
1209*9880d681SAndroid Build Coastguard Worker   return getConstantFP(*ConstantFP::get(*getContext(), V), DL, VT, isTarget);
1210*9880d681SAndroid Build Coastguard Worker }
1211*9880d681SAndroid Build Coastguard Worker 
getConstantFP(const ConstantFP & V,const SDLoc & DL,EVT VT,bool isTarget)1212*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstantFP(const ConstantFP &V, const SDLoc &DL,
1213*9880d681SAndroid Build Coastguard Worker                                     EVT VT, bool isTarget) {
1214*9880d681SAndroid Build Coastguard Worker   assert(VT.isFloatingPoint() && "Cannot create integer FP constant!");
1215*9880d681SAndroid Build Coastguard Worker 
1216*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getScalarType();
1217*9880d681SAndroid Build Coastguard Worker 
1218*9880d681SAndroid Build Coastguard Worker   // Do the map lookup using the actual bit pattern for the floating point
1219*9880d681SAndroid Build Coastguard Worker   // value, so that we don't have problems with 0.0 comparing equal to -0.0, and
1220*9880d681SAndroid Build Coastguard Worker   // we don't have issues with SNANs.
1221*9880d681SAndroid Build Coastguard Worker   unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP;
1222*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1223*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(EltVT), None);
1224*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(&V);
1225*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1226*9880d681SAndroid Build Coastguard Worker   SDNode *N = nullptr;
1227*9880d681SAndroid Build Coastguard Worker   if ((N = FindNodeOrInsertPos(ID, DL, IP)))
1228*9880d681SAndroid Build Coastguard Worker     if (!VT.isVector())
1229*9880d681SAndroid Build Coastguard Worker       return SDValue(N, 0);
1230*9880d681SAndroid Build Coastguard Worker 
1231*9880d681SAndroid Build Coastguard Worker   if (!N) {
1232*9880d681SAndroid Build Coastguard Worker     N = newSDNode<ConstantFPSDNode>(isTarget, &V, DL.getDebugLoc(), EltVT);
1233*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
1234*9880d681SAndroid Build Coastguard Worker     InsertNode(N);
1235*9880d681SAndroid Build Coastguard Worker   }
1236*9880d681SAndroid Build Coastguard Worker 
1237*9880d681SAndroid Build Coastguard Worker   SDValue Result(N, 0);
1238*9880d681SAndroid Build Coastguard Worker   if (VT.isVector())
1239*9880d681SAndroid Build Coastguard Worker     Result = getSplatBuildVector(VT, DL, Result);
1240*9880d681SAndroid Build Coastguard Worker   return Result;
1241*9880d681SAndroid Build Coastguard Worker }
1242*9880d681SAndroid Build Coastguard Worker 
getConstantFP(double Val,const SDLoc & DL,EVT VT,bool isTarget)1243*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstantFP(double Val, const SDLoc &DL, EVT VT,
1244*9880d681SAndroid Build Coastguard Worker                                     bool isTarget) {
1245*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getScalarType();
1246*9880d681SAndroid Build Coastguard Worker   if (EltVT == MVT::f32)
1247*9880d681SAndroid Build Coastguard Worker     return getConstantFP(APFloat((float)Val), DL, VT, isTarget);
1248*9880d681SAndroid Build Coastguard Worker   else if (EltVT == MVT::f64)
1249*9880d681SAndroid Build Coastguard Worker     return getConstantFP(APFloat(Val), DL, VT, isTarget);
1250*9880d681SAndroid Build Coastguard Worker   else if (EltVT == MVT::f80 || EltVT == MVT::f128 || EltVT == MVT::ppcf128 ||
1251*9880d681SAndroid Build Coastguard Worker            EltVT == MVT::f16) {
1252*9880d681SAndroid Build Coastguard Worker     bool Ignored;
1253*9880d681SAndroid Build Coastguard Worker     APFloat APF = APFloat(Val);
1254*9880d681SAndroid Build Coastguard Worker     APF.convert(EVTToAPFloatSemantics(EltVT), APFloat::rmNearestTiesToEven,
1255*9880d681SAndroid Build Coastguard Worker                 &Ignored);
1256*9880d681SAndroid Build Coastguard Worker     return getConstantFP(APF, DL, VT, isTarget);
1257*9880d681SAndroid Build Coastguard Worker   } else
1258*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unsupported type in getConstantFP");
1259*9880d681SAndroid Build Coastguard Worker }
1260*9880d681SAndroid Build Coastguard Worker 
getGlobalAddress(const GlobalValue * GV,const SDLoc & DL,EVT VT,int64_t Offset,bool isTargetGA,unsigned char TargetFlags)1261*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, const SDLoc &DL,
1262*9880d681SAndroid Build Coastguard Worker                                        EVT VT, int64_t Offset, bool isTargetGA,
1263*9880d681SAndroid Build Coastguard Worker                                        unsigned char TargetFlags) {
1264*9880d681SAndroid Build Coastguard Worker   assert((TargetFlags == 0 || isTargetGA) &&
1265*9880d681SAndroid Build Coastguard Worker          "Cannot set target flags on target-independent globals");
1266*9880d681SAndroid Build Coastguard Worker 
1267*9880d681SAndroid Build Coastguard Worker   // Truncate (with sign-extension) the offset value to the pointer size.
1268*9880d681SAndroid Build Coastguard Worker   unsigned BitWidth = getDataLayout().getPointerTypeSizeInBits(GV->getType());
1269*9880d681SAndroid Build Coastguard Worker   if (BitWidth < 64)
1270*9880d681SAndroid Build Coastguard Worker     Offset = SignExtend64(Offset, BitWidth);
1271*9880d681SAndroid Build Coastguard Worker 
1272*9880d681SAndroid Build Coastguard Worker   unsigned Opc;
1273*9880d681SAndroid Build Coastguard Worker   if (GV->isThreadLocal())
1274*9880d681SAndroid Build Coastguard Worker     Opc = isTargetGA ? ISD::TargetGlobalTLSAddress : ISD::GlobalTLSAddress;
1275*9880d681SAndroid Build Coastguard Worker   else
1276*9880d681SAndroid Build Coastguard Worker     Opc = isTargetGA ? ISD::TargetGlobalAddress : ISD::GlobalAddress;
1277*9880d681SAndroid Build Coastguard Worker 
1278*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1279*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(VT), None);
1280*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(GV);
1281*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Offset);
1282*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(TargetFlags);
1283*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(GV->getType()->getAddressSpace());
1284*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1285*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
1286*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1287*9880d681SAndroid Build Coastguard Worker 
1288*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<GlobalAddressSDNode>(
1289*9880d681SAndroid Build Coastguard Worker       Opc, DL.getIROrder(), DL.getDebugLoc(), GV, VT, Offset, TargetFlags);
1290*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1291*9880d681SAndroid Build Coastguard Worker     InsertNode(N);
1292*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1293*9880d681SAndroid Build Coastguard Worker }
1294*9880d681SAndroid Build Coastguard Worker 
getFrameIndex(int FI,EVT VT,bool isTarget)1295*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getFrameIndex(int FI, EVT VT, bool isTarget) {
1296*9880d681SAndroid Build Coastguard Worker   unsigned Opc = isTarget ? ISD::TargetFrameIndex : ISD::FrameIndex;
1297*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1298*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(VT), None);
1299*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(FI);
1300*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1301*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1302*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1303*9880d681SAndroid Build Coastguard Worker 
1304*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<FrameIndexSDNode>(FI, VT, isTarget);
1305*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1306*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1307*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1308*9880d681SAndroid Build Coastguard Worker }
1309*9880d681SAndroid Build Coastguard Worker 
getJumpTable(int JTI,EVT VT,bool isTarget,unsigned char TargetFlags)1310*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getJumpTable(int JTI, EVT VT, bool isTarget,
1311*9880d681SAndroid Build Coastguard Worker                                    unsigned char TargetFlags) {
1312*9880d681SAndroid Build Coastguard Worker   assert((TargetFlags == 0 || isTarget) &&
1313*9880d681SAndroid Build Coastguard Worker          "Cannot set target flags on target-independent jump tables");
1314*9880d681SAndroid Build Coastguard Worker   unsigned Opc = isTarget ? ISD::TargetJumpTable : ISD::JumpTable;
1315*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1316*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(VT), None);
1317*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(JTI);
1318*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(TargetFlags);
1319*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1320*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1321*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1322*9880d681SAndroid Build Coastguard Worker 
1323*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<JumpTableSDNode>(JTI, VT, isTarget, TargetFlags);
1324*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1325*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1326*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1327*9880d681SAndroid Build Coastguard Worker }
1328*9880d681SAndroid Build Coastguard Worker 
getConstantPool(const Constant * C,EVT VT,unsigned Alignment,int Offset,bool isTarget,unsigned char TargetFlags)1329*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstantPool(const Constant *C, EVT VT,
1330*9880d681SAndroid Build Coastguard Worker                                       unsigned Alignment, int Offset,
1331*9880d681SAndroid Build Coastguard Worker                                       bool isTarget,
1332*9880d681SAndroid Build Coastguard Worker                                       unsigned char TargetFlags) {
1333*9880d681SAndroid Build Coastguard Worker   assert((TargetFlags == 0 || isTarget) &&
1334*9880d681SAndroid Build Coastguard Worker          "Cannot set target flags on target-independent globals");
1335*9880d681SAndroid Build Coastguard Worker   if (Alignment == 0)
1336*9880d681SAndroid Build Coastguard Worker     Alignment = getDataLayout().getPrefTypeAlignment(C->getType());
1337*9880d681SAndroid Build Coastguard Worker   unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
1338*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1339*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(VT), None);
1340*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Alignment);
1341*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Offset);
1342*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(C);
1343*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(TargetFlags);
1344*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1345*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1346*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1347*9880d681SAndroid Build Coastguard Worker 
1348*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<ConstantPoolSDNode>(isTarget, C, VT, Offset, Alignment,
1349*9880d681SAndroid Build Coastguard Worker                                           TargetFlags);
1350*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1351*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1352*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1353*9880d681SAndroid Build Coastguard Worker }
1354*9880d681SAndroid Build Coastguard Worker 
1355*9880d681SAndroid Build Coastguard Worker 
getConstantPool(MachineConstantPoolValue * C,EVT VT,unsigned Alignment,int Offset,bool isTarget,unsigned char TargetFlags)1356*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT,
1357*9880d681SAndroid Build Coastguard Worker                                       unsigned Alignment, int Offset,
1358*9880d681SAndroid Build Coastguard Worker                                       bool isTarget,
1359*9880d681SAndroid Build Coastguard Worker                                       unsigned char TargetFlags) {
1360*9880d681SAndroid Build Coastguard Worker   assert((TargetFlags == 0 || isTarget) &&
1361*9880d681SAndroid Build Coastguard Worker          "Cannot set target flags on target-independent globals");
1362*9880d681SAndroid Build Coastguard Worker   if (Alignment == 0)
1363*9880d681SAndroid Build Coastguard Worker     Alignment = getDataLayout().getPrefTypeAlignment(C->getType());
1364*9880d681SAndroid Build Coastguard Worker   unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
1365*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1366*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(VT), None);
1367*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Alignment);
1368*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Offset);
1369*9880d681SAndroid Build Coastguard Worker   C->addSelectionDAGCSEId(ID);
1370*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(TargetFlags);
1371*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1372*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1373*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1374*9880d681SAndroid Build Coastguard Worker 
1375*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<ConstantPoolSDNode>(isTarget, C, VT, Offset, Alignment,
1376*9880d681SAndroid Build Coastguard Worker                                           TargetFlags);
1377*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1378*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1379*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1380*9880d681SAndroid Build Coastguard Worker }
1381*9880d681SAndroid Build Coastguard Worker 
getTargetIndex(int Index,EVT VT,int64_t Offset,unsigned char TargetFlags)1382*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getTargetIndex(int Index, EVT VT, int64_t Offset,
1383*9880d681SAndroid Build Coastguard Worker                                      unsigned char TargetFlags) {
1384*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1385*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::TargetIndex, getVTList(VT), None);
1386*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Index);
1387*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Offset);
1388*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(TargetFlags);
1389*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1390*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1391*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1392*9880d681SAndroid Build Coastguard Worker 
1393*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<TargetIndexSDNode>(Index, VT, Offset, TargetFlags);
1394*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1395*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1396*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1397*9880d681SAndroid Build Coastguard Worker }
1398*9880d681SAndroid Build Coastguard Worker 
getBasicBlock(MachineBasicBlock * MBB)1399*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
1400*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1401*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::BasicBlock, getVTList(MVT::Other), None);
1402*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(MBB);
1403*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1404*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1405*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1406*9880d681SAndroid Build Coastguard Worker 
1407*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<BasicBlockSDNode>(MBB);
1408*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1409*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1410*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1411*9880d681SAndroid Build Coastguard Worker }
1412*9880d681SAndroid Build Coastguard Worker 
getValueType(EVT VT)1413*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getValueType(EVT VT) {
1414*9880d681SAndroid Build Coastguard Worker   if (VT.isSimple() && (unsigned)VT.getSimpleVT().SimpleTy >=
1415*9880d681SAndroid Build Coastguard Worker       ValueTypeNodes.size())
1416*9880d681SAndroid Build Coastguard Worker     ValueTypeNodes.resize(VT.getSimpleVT().SimpleTy+1);
1417*9880d681SAndroid Build Coastguard Worker 
1418*9880d681SAndroid Build Coastguard Worker   SDNode *&N = VT.isExtended() ?
1419*9880d681SAndroid Build Coastguard Worker     ExtendedValueTypeNodes[VT] : ValueTypeNodes[VT.getSimpleVT().SimpleTy];
1420*9880d681SAndroid Build Coastguard Worker 
1421*9880d681SAndroid Build Coastguard Worker   if (N) return SDValue(N, 0);
1422*9880d681SAndroid Build Coastguard Worker   N = newSDNode<VTSDNode>(VT);
1423*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1424*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1425*9880d681SAndroid Build Coastguard Worker }
1426*9880d681SAndroid Build Coastguard Worker 
getExternalSymbol(const char * Sym,EVT VT)1427*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getExternalSymbol(const char *Sym, EVT VT) {
1428*9880d681SAndroid Build Coastguard Worker   SDNode *&N = ExternalSymbols[Sym];
1429*9880d681SAndroid Build Coastguard Worker   if (N) return SDValue(N, 0);
1430*9880d681SAndroid Build Coastguard Worker   N = newSDNode<ExternalSymbolSDNode>(false, Sym, 0, VT);
1431*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1432*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1433*9880d681SAndroid Build Coastguard Worker }
1434*9880d681SAndroid Build Coastguard Worker 
getMCSymbol(MCSymbol * Sym,EVT VT)1435*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMCSymbol(MCSymbol *Sym, EVT VT) {
1436*9880d681SAndroid Build Coastguard Worker   SDNode *&N = MCSymbols[Sym];
1437*9880d681SAndroid Build Coastguard Worker   if (N)
1438*9880d681SAndroid Build Coastguard Worker     return SDValue(N, 0);
1439*9880d681SAndroid Build Coastguard Worker   N = newSDNode<MCSymbolSDNode>(Sym, VT);
1440*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1441*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1442*9880d681SAndroid Build Coastguard Worker }
1443*9880d681SAndroid Build Coastguard Worker 
getTargetExternalSymbol(const char * Sym,EVT VT,unsigned char TargetFlags)1444*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, EVT VT,
1445*9880d681SAndroid Build Coastguard Worker                                               unsigned char TargetFlags) {
1446*9880d681SAndroid Build Coastguard Worker   SDNode *&N =
1447*9880d681SAndroid Build Coastguard Worker     TargetExternalSymbols[std::pair<std::string,unsigned char>(Sym,
1448*9880d681SAndroid Build Coastguard Worker                                                                TargetFlags)];
1449*9880d681SAndroid Build Coastguard Worker   if (N) return SDValue(N, 0);
1450*9880d681SAndroid Build Coastguard Worker   N = newSDNode<ExternalSymbolSDNode>(true, Sym, TargetFlags, VT);
1451*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1452*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1453*9880d681SAndroid Build Coastguard Worker }
1454*9880d681SAndroid Build Coastguard Worker 
getCondCode(ISD::CondCode Cond)1455*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
1456*9880d681SAndroid Build Coastguard Worker   if ((unsigned)Cond >= CondCodeNodes.size())
1457*9880d681SAndroid Build Coastguard Worker     CondCodeNodes.resize(Cond+1);
1458*9880d681SAndroid Build Coastguard Worker 
1459*9880d681SAndroid Build Coastguard Worker   if (!CondCodeNodes[Cond]) {
1460*9880d681SAndroid Build Coastguard Worker     auto *N = newSDNode<CondCodeSDNode>(Cond);
1461*9880d681SAndroid Build Coastguard Worker     CondCodeNodes[Cond] = N;
1462*9880d681SAndroid Build Coastguard Worker     InsertNode(N);
1463*9880d681SAndroid Build Coastguard Worker   }
1464*9880d681SAndroid Build Coastguard Worker 
1465*9880d681SAndroid Build Coastguard Worker   return SDValue(CondCodeNodes[Cond], 0);
1466*9880d681SAndroid Build Coastguard Worker }
1467*9880d681SAndroid Build Coastguard Worker 
1468*9880d681SAndroid Build Coastguard Worker /// Swaps the values of N1 and N2. Swaps all indices in the shuffle mask M that
1469*9880d681SAndroid Build Coastguard Worker /// point at N1 to point at N2 and indices that point at N2 to point at N1.
commuteShuffle(SDValue & N1,SDValue & N2,MutableArrayRef<int> M)1470*9880d681SAndroid Build Coastguard Worker static void commuteShuffle(SDValue &N1, SDValue &N2, MutableArrayRef<int> M) {
1471*9880d681SAndroid Build Coastguard Worker   std::swap(N1, N2);
1472*9880d681SAndroid Build Coastguard Worker   ShuffleVectorSDNode::commuteMask(M);
1473*9880d681SAndroid Build Coastguard Worker }
1474*9880d681SAndroid Build Coastguard Worker 
getVectorShuffle(EVT VT,const SDLoc & dl,SDValue N1,SDValue N2,ArrayRef<int> Mask)1475*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1,
1476*9880d681SAndroid Build Coastguard Worker                                        SDValue N2, ArrayRef<int> Mask) {
1477*9880d681SAndroid Build Coastguard Worker   assert(VT.getVectorNumElements() == Mask.size() &&
1478*9880d681SAndroid Build Coastguard Worker            "Must have the same number of vector elements as mask elements!");
1479*9880d681SAndroid Build Coastguard Worker   assert(VT == N1.getValueType() && VT == N2.getValueType() &&
1480*9880d681SAndroid Build Coastguard Worker          "Invalid VECTOR_SHUFFLE");
1481*9880d681SAndroid Build Coastguard Worker 
1482*9880d681SAndroid Build Coastguard Worker   // Canonicalize shuffle undef, undef -> undef
1483*9880d681SAndroid Build Coastguard Worker   if (N1.isUndef() && N2.isUndef())
1484*9880d681SAndroid Build Coastguard Worker     return getUNDEF(VT);
1485*9880d681SAndroid Build Coastguard Worker 
1486*9880d681SAndroid Build Coastguard Worker   // Validate that all indices in Mask are within the range of the elements
1487*9880d681SAndroid Build Coastguard Worker   // input to the shuffle.
1488*9880d681SAndroid Build Coastguard Worker   int NElts = Mask.size();
1489*9880d681SAndroid Build Coastguard Worker   assert(all_of(Mask, [&](int M) { return M < (NElts * 2); }) &&
1490*9880d681SAndroid Build Coastguard Worker          "Index out of range");
1491*9880d681SAndroid Build Coastguard Worker 
1492*9880d681SAndroid Build Coastguard Worker   // Copy the mask so we can do any needed cleanup.
1493*9880d681SAndroid Build Coastguard Worker   SmallVector<int, 8> MaskVec(Mask.begin(), Mask.end());
1494*9880d681SAndroid Build Coastguard Worker 
1495*9880d681SAndroid Build Coastguard Worker   // Canonicalize shuffle v, v -> v, undef
1496*9880d681SAndroid Build Coastguard Worker   if (N1 == N2) {
1497*9880d681SAndroid Build Coastguard Worker     N2 = getUNDEF(VT);
1498*9880d681SAndroid Build Coastguard Worker     for (int i = 0; i != NElts; ++i)
1499*9880d681SAndroid Build Coastguard Worker       if (MaskVec[i] >= NElts) MaskVec[i] -= NElts;
1500*9880d681SAndroid Build Coastguard Worker   }
1501*9880d681SAndroid Build Coastguard Worker 
1502*9880d681SAndroid Build Coastguard Worker   // Canonicalize shuffle undef, v -> v, undef.  Commute the shuffle mask.
1503*9880d681SAndroid Build Coastguard Worker   if (N1.isUndef())
1504*9880d681SAndroid Build Coastguard Worker     commuteShuffle(N1, N2, MaskVec);
1505*9880d681SAndroid Build Coastguard Worker 
1506*9880d681SAndroid Build Coastguard Worker   // If shuffling a splat, try to blend the splat instead. We do this here so
1507*9880d681SAndroid Build Coastguard Worker   // that even when this arises during lowering we don't have to re-handle it.
1508*9880d681SAndroid Build Coastguard Worker   auto BlendSplat = [&](BuildVectorSDNode *BV, int Offset) {
1509*9880d681SAndroid Build Coastguard Worker     BitVector UndefElements;
1510*9880d681SAndroid Build Coastguard Worker     SDValue Splat = BV->getSplatValue(&UndefElements);
1511*9880d681SAndroid Build Coastguard Worker     if (!Splat)
1512*9880d681SAndroid Build Coastguard Worker       return;
1513*9880d681SAndroid Build Coastguard Worker 
1514*9880d681SAndroid Build Coastguard Worker     for (int i = 0; i < NElts; ++i) {
1515*9880d681SAndroid Build Coastguard Worker       if (MaskVec[i] < Offset || MaskVec[i] >= (Offset + NElts))
1516*9880d681SAndroid Build Coastguard Worker         continue;
1517*9880d681SAndroid Build Coastguard Worker 
1518*9880d681SAndroid Build Coastguard Worker       // If this input comes from undef, mark it as such.
1519*9880d681SAndroid Build Coastguard Worker       if (UndefElements[MaskVec[i] - Offset]) {
1520*9880d681SAndroid Build Coastguard Worker         MaskVec[i] = -1;
1521*9880d681SAndroid Build Coastguard Worker         continue;
1522*9880d681SAndroid Build Coastguard Worker       }
1523*9880d681SAndroid Build Coastguard Worker 
1524*9880d681SAndroid Build Coastguard Worker       // If we can blend a non-undef lane, use that instead.
1525*9880d681SAndroid Build Coastguard Worker       if (!UndefElements[i])
1526*9880d681SAndroid Build Coastguard Worker         MaskVec[i] = i + Offset;
1527*9880d681SAndroid Build Coastguard Worker     }
1528*9880d681SAndroid Build Coastguard Worker   };
1529*9880d681SAndroid Build Coastguard Worker   if (auto *N1BV = dyn_cast<BuildVectorSDNode>(N1))
1530*9880d681SAndroid Build Coastguard Worker     BlendSplat(N1BV, 0);
1531*9880d681SAndroid Build Coastguard Worker   if (auto *N2BV = dyn_cast<BuildVectorSDNode>(N2))
1532*9880d681SAndroid Build Coastguard Worker     BlendSplat(N2BV, NElts);
1533*9880d681SAndroid Build Coastguard Worker 
1534*9880d681SAndroid Build Coastguard Worker   // Canonicalize all index into lhs, -> shuffle lhs, undef
1535*9880d681SAndroid Build Coastguard Worker   // Canonicalize all index into rhs, -> shuffle rhs, undef
1536*9880d681SAndroid Build Coastguard Worker   bool AllLHS = true, AllRHS = true;
1537*9880d681SAndroid Build Coastguard Worker   bool N2Undef = N2.isUndef();
1538*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i != NElts; ++i) {
1539*9880d681SAndroid Build Coastguard Worker     if (MaskVec[i] >= NElts) {
1540*9880d681SAndroid Build Coastguard Worker       if (N2Undef)
1541*9880d681SAndroid Build Coastguard Worker         MaskVec[i] = -1;
1542*9880d681SAndroid Build Coastguard Worker       else
1543*9880d681SAndroid Build Coastguard Worker         AllLHS = false;
1544*9880d681SAndroid Build Coastguard Worker     } else if (MaskVec[i] >= 0) {
1545*9880d681SAndroid Build Coastguard Worker       AllRHS = false;
1546*9880d681SAndroid Build Coastguard Worker     }
1547*9880d681SAndroid Build Coastguard Worker   }
1548*9880d681SAndroid Build Coastguard Worker   if (AllLHS && AllRHS)
1549*9880d681SAndroid Build Coastguard Worker     return getUNDEF(VT);
1550*9880d681SAndroid Build Coastguard Worker   if (AllLHS && !N2Undef)
1551*9880d681SAndroid Build Coastguard Worker     N2 = getUNDEF(VT);
1552*9880d681SAndroid Build Coastguard Worker   if (AllRHS) {
1553*9880d681SAndroid Build Coastguard Worker     N1 = getUNDEF(VT);
1554*9880d681SAndroid Build Coastguard Worker     commuteShuffle(N1, N2, MaskVec);
1555*9880d681SAndroid Build Coastguard Worker   }
1556*9880d681SAndroid Build Coastguard Worker   // Reset our undef status after accounting for the mask.
1557*9880d681SAndroid Build Coastguard Worker   N2Undef = N2.isUndef();
1558*9880d681SAndroid Build Coastguard Worker   // Re-check whether both sides ended up undef.
1559*9880d681SAndroid Build Coastguard Worker   if (N1.isUndef() && N2Undef)
1560*9880d681SAndroid Build Coastguard Worker     return getUNDEF(VT);
1561*9880d681SAndroid Build Coastguard Worker 
1562*9880d681SAndroid Build Coastguard Worker   // If Identity shuffle return that node.
1563*9880d681SAndroid Build Coastguard Worker   bool Identity = true, AllSame = true;
1564*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i != NElts; ++i) {
1565*9880d681SAndroid Build Coastguard Worker     if (MaskVec[i] >= 0 && MaskVec[i] != i) Identity = false;
1566*9880d681SAndroid Build Coastguard Worker     if (MaskVec[i] != MaskVec[0]) AllSame = false;
1567*9880d681SAndroid Build Coastguard Worker   }
1568*9880d681SAndroid Build Coastguard Worker   if (Identity && NElts)
1569*9880d681SAndroid Build Coastguard Worker     return N1;
1570*9880d681SAndroid Build Coastguard Worker 
1571*9880d681SAndroid Build Coastguard Worker   // Shuffling a constant splat doesn't change the result.
1572*9880d681SAndroid Build Coastguard Worker   if (N2Undef) {
1573*9880d681SAndroid Build Coastguard Worker     SDValue V = N1;
1574*9880d681SAndroid Build Coastguard Worker 
1575*9880d681SAndroid Build Coastguard Worker     // Look through any bitcasts. We check that these don't change the number
1576*9880d681SAndroid Build Coastguard Worker     // (and size) of elements and just changes their types.
1577*9880d681SAndroid Build Coastguard Worker     while (V.getOpcode() == ISD::BITCAST)
1578*9880d681SAndroid Build Coastguard Worker       V = V->getOperand(0);
1579*9880d681SAndroid Build Coastguard Worker 
1580*9880d681SAndroid Build Coastguard Worker     // A splat should always show up as a build vector node.
1581*9880d681SAndroid Build Coastguard Worker     if (auto *BV = dyn_cast<BuildVectorSDNode>(V)) {
1582*9880d681SAndroid Build Coastguard Worker       BitVector UndefElements;
1583*9880d681SAndroid Build Coastguard Worker       SDValue Splat = BV->getSplatValue(&UndefElements);
1584*9880d681SAndroid Build Coastguard Worker       // If this is a splat of an undef, shuffling it is also undef.
1585*9880d681SAndroid Build Coastguard Worker       if (Splat && Splat.isUndef())
1586*9880d681SAndroid Build Coastguard Worker         return getUNDEF(VT);
1587*9880d681SAndroid Build Coastguard Worker 
1588*9880d681SAndroid Build Coastguard Worker       bool SameNumElts =
1589*9880d681SAndroid Build Coastguard Worker           V.getValueType().getVectorNumElements() == VT.getVectorNumElements();
1590*9880d681SAndroid Build Coastguard Worker 
1591*9880d681SAndroid Build Coastguard Worker       // We only have a splat which can skip shuffles if there is a splatted
1592*9880d681SAndroid Build Coastguard Worker       // value and no undef lanes rearranged by the shuffle.
1593*9880d681SAndroid Build Coastguard Worker       if (Splat && UndefElements.none()) {
1594*9880d681SAndroid Build Coastguard Worker         // Splat of <x, x, ..., x>, return <x, x, ..., x>, provided that the
1595*9880d681SAndroid Build Coastguard Worker         // number of elements match or the value splatted is a zero constant.
1596*9880d681SAndroid Build Coastguard Worker         if (SameNumElts)
1597*9880d681SAndroid Build Coastguard Worker           return N1;
1598*9880d681SAndroid Build Coastguard Worker         if (auto *C = dyn_cast<ConstantSDNode>(Splat))
1599*9880d681SAndroid Build Coastguard Worker           if (C->isNullValue())
1600*9880d681SAndroid Build Coastguard Worker             return N1;
1601*9880d681SAndroid Build Coastguard Worker       }
1602*9880d681SAndroid Build Coastguard Worker 
1603*9880d681SAndroid Build Coastguard Worker       // If the shuffle itself creates a splat, build the vector directly.
1604*9880d681SAndroid Build Coastguard Worker       if (AllSame && SameNumElts) {
1605*9880d681SAndroid Build Coastguard Worker         EVT BuildVT = BV->getValueType(0);
1606*9880d681SAndroid Build Coastguard Worker         const SDValue &Splatted = BV->getOperand(MaskVec[0]);
1607*9880d681SAndroid Build Coastguard Worker         SDValue NewBV = getSplatBuildVector(BuildVT, dl, Splatted);
1608*9880d681SAndroid Build Coastguard Worker 
1609*9880d681SAndroid Build Coastguard Worker         // We may have jumped through bitcasts, so the type of the
1610*9880d681SAndroid Build Coastguard Worker         // BUILD_VECTOR may not match the type of the shuffle.
1611*9880d681SAndroid Build Coastguard Worker         if (BuildVT != VT)
1612*9880d681SAndroid Build Coastguard Worker           NewBV = getNode(ISD::BITCAST, dl, VT, NewBV);
1613*9880d681SAndroid Build Coastguard Worker         return NewBV;
1614*9880d681SAndroid Build Coastguard Worker       }
1615*9880d681SAndroid Build Coastguard Worker     }
1616*9880d681SAndroid Build Coastguard Worker   }
1617*9880d681SAndroid Build Coastguard Worker 
1618*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1619*9880d681SAndroid Build Coastguard Worker   SDValue Ops[2] = { N1, N2 };
1620*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::VECTOR_SHUFFLE, getVTList(VT), Ops);
1621*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i != NElts; ++i)
1622*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(MaskVec[i]);
1623*9880d681SAndroid Build Coastguard Worker 
1624*9880d681SAndroid Build Coastguard Worker   void* IP = nullptr;
1625*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP))
1626*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1627*9880d681SAndroid Build Coastguard Worker 
1628*9880d681SAndroid Build Coastguard Worker   // Allocate the mask array for the node out of the BumpPtrAllocator, since
1629*9880d681SAndroid Build Coastguard Worker   // SDNode doesn't have access to it.  This memory will be "leaked" when
1630*9880d681SAndroid Build Coastguard Worker   // the node is deallocated, but recovered when the NodeAllocator is released.
1631*9880d681SAndroid Build Coastguard Worker   int *MaskAlloc = OperandAllocator.Allocate<int>(NElts);
1632*9880d681SAndroid Build Coastguard Worker   std::copy(MaskVec.begin(), MaskVec.end(), MaskAlloc);
1633*9880d681SAndroid Build Coastguard Worker 
1634*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<ShuffleVectorSDNode>(VT, dl.getIROrder(),
1635*9880d681SAndroid Build Coastguard Worker                                            dl.getDebugLoc(), MaskAlloc);
1636*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
1637*9880d681SAndroid Build Coastguard Worker 
1638*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1639*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1640*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1641*9880d681SAndroid Build Coastguard Worker }
1642*9880d681SAndroid Build Coastguard Worker 
getCommutedVectorShuffle(const ShuffleVectorSDNode & SV)1643*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getCommutedVectorShuffle(const ShuffleVectorSDNode &SV) {
1644*9880d681SAndroid Build Coastguard Worker   MVT VT = SV.getSimpleValueType(0);
1645*9880d681SAndroid Build Coastguard Worker   SmallVector<int, 8> MaskVec(SV.getMask().begin(), SV.getMask().end());
1646*9880d681SAndroid Build Coastguard Worker   ShuffleVectorSDNode::commuteMask(MaskVec);
1647*9880d681SAndroid Build Coastguard Worker 
1648*9880d681SAndroid Build Coastguard Worker   SDValue Op0 = SV.getOperand(0);
1649*9880d681SAndroid Build Coastguard Worker   SDValue Op1 = SV.getOperand(1);
1650*9880d681SAndroid Build Coastguard Worker   return getVectorShuffle(VT, SDLoc(&SV), Op1, Op0, MaskVec);
1651*9880d681SAndroid Build Coastguard Worker }
1652*9880d681SAndroid Build Coastguard Worker 
getConvertRndSat(EVT VT,const SDLoc & dl,SDValue Val,SDValue DTy,SDValue STy,SDValue Rnd,SDValue Sat,ISD::CvtCode Code)1653*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getConvertRndSat(EVT VT, const SDLoc &dl, SDValue Val,
1654*9880d681SAndroid Build Coastguard Worker                                        SDValue DTy, SDValue STy, SDValue Rnd,
1655*9880d681SAndroid Build Coastguard Worker                                        SDValue Sat, ISD::CvtCode Code) {
1656*9880d681SAndroid Build Coastguard Worker   // If the src and dest types are the same and the conversion is between
1657*9880d681SAndroid Build Coastguard Worker   // integer types of the same sign or two floats, no conversion is necessary.
1658*9880d681SAndroid Build Coastguard Worker   if (DTy == STy &&
1659*9880d681SAndroid Build Coastguard Worker       (Code == ISD::CVT_UU || Code == ISD::CVT_SS || Code == ISD::CVT_FF))
1660*9880d681SAndroid Build Coastguard Worker     return Val;
1661*9880d681SAndroid Build Coastguard Worker 
1662*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1663*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Val, DTy, STy, Rnd, Sat };
1664*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::CONVERT_RNDSAT, getVTList(VT), Ops);
1665*9880d681SAndroid Build Coastguard Worker   void* IP = nullptr;
1666*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP))
1667*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1668*9880d681SAndroid Build Coastguard Worker 
1669*9880d681SAndroid Build Coastguard Worker   auto *N =
1670*9880d681SAndroid Build Coastguard Worker       newSDNode<CvtRndSatSDNode>(VT, dl.getIROrder(), dl.getDebugLoc(), Code);
1671*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
1672*9880d681SAndroid Build Coastguard Worker 
1673*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1674*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1675*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1676*9880d681SAndroid Build Coastguard Worker }
1677*9880d681SAndroid Build Coastguard Worker 
getRegister(unsigned RegNo,EVT VT)1678*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getRegister(unsigned RegNo, EVT VT) {
1679*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1680*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::Register, getVTList(VT), None);
1681*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(RegNo);
1682*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1683*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1684*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1685*9880d681SAndroid Build Coastguard Worker 
1686*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<RegisterSDNode>(RegNo, VT);
1687*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1688*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1689*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1690*9880d681SAndroid Build Coastguard Worker }
1691*9880d681SAndroid Build Coastguard Worker 
getRegisterMask(const uint32_t * RegMask)1692*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getRegisterMask(const uint32_t *RegMask) {
1693*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1694*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::RegisterMask, getVTList(MVT::Untyped), None);
1695*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(RegMask);
1696*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1697*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1698*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1699*9880d681SAndroid Build Coastguard Worker 
1700*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<RegisterMaskSDNode>(RegMask);
1701*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1702*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1703*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1704*9880d681SAndroid Build Coastguard Worker }
1705*9880d681SAndroid Build Coastguard Worker 
getEHLabel(const SDLoc & dl,SDValue Root,MCSymbol * Label)1706*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getEHLabel(const SDLoc &dl, SDValue Root,
1707*9880d681SAndroid Build Coastguard Worker                                  MCSymbol *Label) {
1708*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1709*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Root };
1710*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::EH_LABEL, getVTList(MVT::Other), Ops);
1711*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(Label);
1712*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1713*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1714*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1715*9880d681SAndroid Build Coastguard Worker 
1716*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<EHLabelSDNode>(dl.getIROrder(), dl.getDebugLoc(), Label);
1717*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
1718*9880d681SAndroid Build Coastguard Worker 
1719*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1720*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1721*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1722*9880d681SAndroid Build Coastguard Worker }
1723*9880d681SAndroid Build Coastguard Worker 
getBlockAddress(const BlockAddress * BA,EVT VT,int64_t Offset,bool isTarget,unsigned char TargetFlags)1724*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT,
1725*9880d681SAndroid Build Coastguard Worker                                       int64_t Offset,
1726*9880d681SAndroid Build Coastguard Worker                                       bool isTarget,
1727*9880d681SAndroid Build Coastguard Worker                                       unsigned char TargetFlags) {
1728*9880d681SAndroid Build Coastguard Worker   unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;
1729*9880d681SAndroid Build Coastguard Worker 
1730*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1731*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opc, getVTList(VT), None);
1732*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(BA);
1733*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(Offset);
1734*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(TargetFlags);
1735*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1736*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1737*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1738*9880d681SAndroid Build Coastguard Worker 
1739*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<BlockAddressSDNode>(Opc, VT, BA, Offset, TargetFlags);
1740*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1741*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1742*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1743*9880d681SAndroid Build Coastguard Worker }
1744*9880d681SAndroid Build Coastguard Worker 
getSrcValue(const Value * V)1745*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getSrcValue(const Value *V) {
1746*9880d681SAndroid Build Coastguard Worker   assert((!V || V->getType()->isPointerTy()) &&
1747*9880d681SAndroid Build Coastguard Worker          "SrcValue is not a pointer?");
1748*9880d681SAndroid Build Coastguard Worker 
1749*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1750*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::SRCVALUE, getVTList(MVT::Other), None);
1751*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(V);
1752*9880d681SAndroid Build Coastguard Worker 
1753*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1754*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1755*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1756*9880d681SAndroid Build Coastguard Worker 
1757*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<SrcValueSDNode>(V);
1758*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1759*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1760*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1761*9880d681SAndroid Build Coastguard Worker }
1762*9880d681SAndroid Build Coastguard Worker 
getMDNode(const MDNode * MD)1763*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMDNode(const MDNode *MD) {
1764*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1765*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::MDNODE_SDNODE, getVTList(MVT::Other), None);
1766*9880d681SAndroid Build Coastguard Worker   ID.AddPointer(MD);
1767*9880d681SAndroid Build Coastguard Worker 
1768*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1769*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, IP))
1770*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1771*9880d681SAndroid Build Coastguard Worker 
1772*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<MDNodeSDNode>(MD);
1773*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1774*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1775*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1776*9880d681SAndroid Build Coastguard Worker }
1777*9880d681SAndroid Build Coastguard Worker 
getBitcast(EVT VT,SDValue V)1778*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getBitcast(EVT VT, SDValue V) {
1779*9880d681SAndroid Build Coastguard Worker   if (VT == V.getValueType())
1780*9880d681SAndroid Build Coastguard Worker     return V;
1781*9880d681SAndroid Build Coastguard Worker 
1782*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::BITCAST, SDLoc(V), VT, V);
1783*9880d681SAndroid Build Coastguard Worker }
1784*9880d681SAndroid Build Coastguard Worker 
getAddrSpaceCast(const SDLoc & dl,EVT VT,SDValue Ptr,unsigned SrcAS,unsigned DestAS)1785*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr,
1786*9880d681SAndroid Build Coastguard Worker                                        unsigned SrcAS, unsigned DestAS) {
1787*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {Ptr};
1788*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
1789*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::ADDRSPACECAST, getVTList(VT), Ops);
1790*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(SrcAS);
1791*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(DestAS);
1792*9880d681SAndroid Build Coastguard Worker 
1793*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
1794*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP))
1795*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
1796*9880d681SAndroid Build Coastguard Worker 
1797*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<AddrSpaceCastSDNode>(dl.getIROrder(), dl.getDebugLoc(),
1798*9880d681SAndroid Build Coastguard Worker                                            VT, SrcAS, DestAS);
1799*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
1800*9880d681SAndroid Build Coastguard Worker 
1801*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
1802*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
1803*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
1804*9880d681SAndroid Build Coastguard Worker }
1805*9880d681SAndroid Build Coastguard Worker 
1806*9880d681SAndroid Build Coastguard Worker /// getShiftAmountOperand - Return the specified value casted to
1807*9880d681SAndroid Build Coastguard Worker /// the target's desired shift amount type.
getShiftAmountOperand(EVT LHSTy,SDValue Op)1808*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getShiftAmountOperand(EVT LHSTy, SDValue Op) {
1809*9880d681SAndroid Build Coastguard Worker   EVT OpTy = Op.getValueType();
1810*9880d681SAndroid Build Coastguard Worker   EVT ShTy = TLI->getShiftAmountTy(LHSTy, getDataLayout());
1811*9880d681SAndroid Build Coastguard Worker   if (OpTy == ShTy || OpTy.isVector()) return Op;
1812*9880d681SAndroid Build Coastguard Worker 
1813*9880d681SAndroid Build Coastguard Worker   return getZExtOrTrunc(Op, SDLoc(Op), ShTy);
1814*9880d681SAndroid Build Coastguard Worker }
1815*9880d681SAndroid Build Coastguard Worker 
expandVAArg(SDNode * Node)1816*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::expandVAArg(SDNode *Node) {
1817*9880d681SAndroid Build Coastguard Worker   SDLoc dl(Node);
1818*9880d681SAndroid Build Coastguard Worker   const TargetLowering &TLI = getTargetLoweringInfo();
1819*9880d681SAndroid Build Coastguard Worker   const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
1820*9880d681SAndroid Build Coastguard Worker   EVT VT = Node->getValueType(0);
1821*9880d681SAndroid Build Coastguard Worker   SDValue Tmp1 = Node->getOperand(0);
1822*9880d681SAndroid Build Coastguard Worker   SDValue Tmp2 = Node->getOperand(1);
1823*9880d681SAndroid Build Coastguard Worker   unsigned Align = Node->getConstantOperandVal(3);
1824*9880d681SAndroid Build Coastguard Worker 
1825*9880d681SAndroid Build Coastguard Worker   SDValue VAListLoad =
1826*9880d681SAndroid Build Coastguard Worker     getLoad(TLI.getPointerTy(getDataLayout()), dl, Tmp1, Tmp2,
1827*9880d681SAndroid Build Coastguard Worker             MachinePointerInfo(V), false, false, false, 0);
1828*9880d681SAndroid Build Coastguard Worker   SDValue VAList = VAListLoad;
1829*9880d681SAndroid Build Coastguard Worker 
1830*9880d681SAndroid Build Coastguard Worker   if (Align > TLI.getMinStackArgumentAlignment()) {
1831*9880d681SAndroid Build Coastguard Worker     assert(((Align & (Align-1)) == 0) && "Expected Align to be a power of 2");
1832*9880d681SAndroid Build Coastguard Worker 
1833*9880d681SAndroid Build Coastguard Worker     VAList = getNode(ISD::ADD, dl, VAList.getValueType(), VAList,
1834*9880d681SAndroid Build Coastguard Worker                      getConstant(Align - 1, dl, VAList.getValueType()));
1835*9880d681SAndroid Build Coastguard Worker 
1836*9880d681SAndroid Build Coastguard Worker     VAList = getNode(ISD::AND, dl, VAList.getValueType(), VAList,
1837*9880d681SAndroid Build Coastguard Worker                      getConstant(-(int64_t)Align, dl, VAList.getValueType()));
1838*9880d681SAndroid Build Coastguard Worker   }
1839*9880d681SAndroid Build Coastguard Worker 
1840*9880d681SAndroid Build Coastguard Worker   // Increment the pointer, VAList, to the next vaarg
1841*9880d681SAndroid Build Coastguard Worker   Tmp1 = getNode(ISD::ADD, dl, VAList.getValueType(), VAList,
1842*9880d681SAndroid Build Coastguard Worker                  getConstant(getDataLayout().getTypeAllocSize(
1843*9880d681SAndroid Build Coastguard Worker                                                VT.getTypeForEVT(*getContext())),
1844*9880d681SAndroid Build Coastguard Worker                              dl, VAList.getValueType()));
1845*9880d681SAndroid Build Coastguard Worker   // Store the incremented VAList to the legalized pointer
1846*9880d681SAndroid Build Coastguard Worker   Tmp1 = getStore(VAListLoad.getValue(1), dl, Tmp1, Tmp2,
1847*9880d681SAndroid Build Coastguard Worker                   MachinePointerInfo(V), false, false, 0);
1848*9880d681SAndroid Build Coastguard Worker   // Load the actual argument out of the pointer VAList
1849*9880d681SAndroid Build Coastguard Worker   return getLoad(VT, dl, Tmp1, VAList, MachinePointerInfo(),
1850*9880d681SAndroid Build Coastguard Worker                  false, false, false, 0);
1851*9880d681SAndroid Build Coastguard Worker }
1852*9880d681SAndroid Build Coastguard Worker 
expandVACopy(SDNode * Node)1853*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::expandVACopy(SDNode *Node) {
1854*9880d681SAndroid Build Coastguard Worker   SDLoc dl(Node);
1855*9880d681SAndroid Build Coastguard Worker   const TargetLowering &TLI = getTargetLoweringInfo();
1856*9880d681SAndroid Build Coastguard Worker   // This defaults to loading a pointer from the input and storing it to the
1857*9880d681SAndroid Build Coastguard Worker   // output, returning the chain.
1858*9880d681SAndroid Build Coastguard Worker   const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue();
1859*9880d681SAndroid Build Coastguard Worker   const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue();
1860*9880d681SAndroid Build Coastguard Worker   SDValue Tmp1 = getLoad(TLI.getPointerTy(getDataLayout()), dl,
1861*9880d681SAndroid Build Coastguard Worker                          Node->getOperand(0), Node->getOperand(2),
1862*9880d681SAndroid Build Coastguard Worker                          MachinePointerInfo(VS), false, false, false, 0);
1863*9880d681SAndroid Build Coastguard Worker   return getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1),
1864*9880d681SAndroid Build Coastguard Worker                   MachinePointerInfo(VD), false, false, 0);
1865*9880d681SAndroid Build Coastguard Worker }
1866*9880d681SAndroid Build Coastguard Worker 
CreateStackTemporary(EVT VT,unsigned minAlign)1867*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) {
1868*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *FrameInfo = getMachineFunction().getFrameInfo();
1869*9880d681SAndroid Build Coastguard Worker   unsigned ByteSize = VT.getStoreSize();
1870*9880d681SAndroid Build Coastguard Worker   Type *Ty = VT.getTypeForEVT(*getContext());
1871*9880d681SAndroid Build Coastguard Worker   unsigned StackAlign =
1872*9880d681SAndroid Build Coastguard Worker       std::max((unsigned)getDataLayout().getPrefTypeAlignment(Ty), minAlign);
1873*9880d681SAndroid Build Coastguard Worker 
1874*9880d681SAndroid Build Coastguard Worker   int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign, false);
1875*9880d681SAndroid Build Coastguard Worker   return getFrameIndex(FrameIdx, TLI->getPointerTy(getDataLayout()));
1876*9880d681SAndroid Build Coastguard Worker }
1877*9880d681SAndroid Build Coastguard Worker 
CreateStackTemporary(EVT VT1,EVT VT2)1878*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::CreateStackTemporary(EVT VT1, EVT VT2) {
1879*9880d681SAndroid Build Coastguard Worker   unsigned Bytes = std::max(VT1.getStoreSize(), VT2.getStoreSize());
1880*9880d681SAndroid Build Coastguard Worker   Type *Ty1 = VT1.getTypeForEVT(*getContext());
1881*9880d681SAndroid Build Coastguard Worker   Type *Ty2 = VT2.getTypeForEVT(*getContext());
1882*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = getDataLayout();
1883*9880d681SAndroid Build Coastguard Worker   unsigned Align =
1884*9880d681SAndroid Build Coastguard Worker       std::max(DL.getPrefTypeAlignment(Ty1), DL.getPrefTypeAlignment(Ty2));
1885*9880d681SAndroid Build Coastguard Worker 
1886*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *FrameInfo = getMachineFunction().getFrameInfo();
1887*9880d681SAndroid Build Coastguard Worker   int FrameIdx = FrameInfo->CreateStackObject(Bytes, Align, false);
1888*9880d681SAndroid Build Coastguard Worker   return getFrameIndex(FrameIdx, TLI->getPointerTy(getDataLayout()));
1889*9880d681SAndroid Build Coastguard Worker }
1890*9880d681SAndroid Build Coastguard Worker 
FoldSetCC(EVT VT,SDValue N1,SDValue N2,ISD::CondCode Cond,const SDLoc & dl)1891*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
1892*9880d681SAndroid Build Coastguard Worker                                 ISD::CondCode Cond, const SDLoc &dl) {
1893*9880d681SAndroid Build Coastguard Worker   // These setcc operations always fold.
1894*9880d681SAndroid Build Coastguard Worker   switch (Cond) {
1895*9880d681SAndroid Build Coastguard Worker   default: break;
1896*9880d681SAndroid Build Coastguard Worker   case ISD::SETFALSE:
1897*9880d681SAndroid Build Coastguard Worker   case ISD::SETFALSE2: return getConstant(0, dl, VT);
1898*9880d681SAndroid Build Coastguard Worker   case ISD::SETTRUE:
1899*9880d681SAndroid Build Coastguard Worker   case ISD::SETTRUE2: {
1900*9880d681SAndroid Build Coastguard Worker     TargetLowering::BooleanContent Cnt =
1901*9880d681SAndroid Build Coastguard Worker         TLI->getBooleanContents(N1->getValueType(0));
1902*9880d681SAndroid Build Coastguard Worker     return getConstant(
1903*9880d681SAndroid Build Coastguard Worker         Cnt == TargetLowering::ZeroOrNegativeOneBooleanContent ? -1ULL : 1, dl,
1904*9880d681SAndroid Build Coastguard Worker         VT);
1905*9880d681SAndroid Build Coastguard Worker   }
1906*9880d681SAndroid Build Coastguard Worker 
1907*9880d681SAndroid Build Coastguard Worker   case ISD::SETOEQ:
1908*9880d681SAndroid Build Coastguard Worker   case ISD::SETOGT:
1909*9880d681SAndroid Build Coastguard Worker   case ISD::SETOGE:
1910*9880d681SAndroid Build Coastguard Worker   case ISD::SETOLT:
1911*9880d681SAndroid Build Coastguard Worker   case ISD::SETOLE:
1912*9880d681SAndroid Build Coastguard Worker   case ISD::SETONE:
1913*9880d681SAndroid Build Coastguard Worker   case ISD::SETO:
1914*9880d681SAndroid Build Coastguard Worker   case ISD::SETUO:
1915*9880d681SAndroid Build Coastguard Worker   case ISD::SETUEQ:
1916*9880d681SAndroid Build Coastguard Worker   case ISD::SETUNE:
1917*9880d681SAndroid Build Coastguard Worker     assert(!N1.getValueType().isInteger() && "Illegal setcc for integer!");
1918*9880d681SAndroid Build Coastguard Worker     break;
1919*9880d681SAndroid Build Coastguard Worker   }
1920*9880d681SAndroid Build Coastguard Worker 
1921*9880d681SAndroid Build Coastguard Worker   if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2)) {
1922*9880d681SAndroid Build Coastguard Worker     const APInt &C2 = N2C->getAPIntValue();
1923*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1)) {
1924*9880d681SAndroid Build Coastguard Worker       const APInt &C1 = N1C->getAPIntValue();
1925*9880d681SAndroid Build Coastguard Worker 
1926*9880d681SAndroid Build Coastguard Worker       switch (Cond) {
1927*9880d681SAndroid Build Coastguard Worker       default: llvm_unreachable("Unknown integer setcc!");
1928*9880d681SAndroid Build Coastguard Worker       case ISD::SETEQ:  return getConstant(C1 == C2, dl, VT);
1929*9880d681SAndroid Build Coastguard Worker       case ISD::SETNE:  return getConstant(C1 != C2, dl, VT);
1930*9880d681SAndroid Build Coastguard Worker       case ISD::SETULT: return getConstant(C1.ult(C2), dl, VT);
1931*9880d681SAndroid Build Coastguard Worker       case ISD::SETUGT: return getConstant(C1.ugt(C2), dl, VT);
1932*9880d681SAndroid Build Coastguard Worker       case ISD::SETULE: return getConstant(C1.ule(C2), dl, VT);
1933*9880d681SAndroid Build Coastguard Worker       case ISD::SETUGE: return getConstant(C1.uge(C2), dl, VT);
1934*9880d681SAndroid Build Coastguard Worker       case ISD::SETLT:  return getConstant(C1.slt(C2), dl, VT);
1935*9880d681SAndroid Build Coastguard Worker       case ISD::SETGT:  return getConstant(C1.sgt(C2), dl, VT);
1936*9880d681SAndroid Build Coastguard Worker       case ISD::SETLE:  return getConstant(C1.sle(C2), dl, VT);
1937*9880d681SAndroid Build Coastguard Worker       case ISD::SETGE:  return getConstant(C1.sge(C2), dl, VT);
1938*9880d681SAndroid Build Coastguard Worker       }
1939*9880d681SAndroid Build Coastguard Worker     }
1940*9880d681SAndroid Build Coastguard Worker   }
1941*9880d681SAndroid Build Coastguard Worker   if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1)) {
1942*9880d681SAndroid Build Coastguard Worker     if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2)) {
1943*9880d681SAndroid Build Coastguard Worker       APFloat::cmpResult R = N1C->getValueAPF().compare(N2C->getValueAPF());
1944*9880d681SAndroid Build Coastguard Worker       switch (Cond) {
1945*9880d681SAndroid Build Coastguard Worker       default: break;
1946*9880d681SAndroid Build Coastguard Worker       case ISD::SETEQ:  if (R==APFloat::cmpUnordered)
1947*9880d681SAndroid Build Coastguard Worker                           return getUNDEF(VT);
1948*9880d681SAndroid Build Coastguard Worker                         // fall through
1949*9880d681SAndroid Build Coastguard Worker       case ISD::SETOEQ: return getConstant(R==APFloat::cmpEqual, dl, VT);
1950*9880d681SAndroid Build Coastguard Worker       case ISD::SETNE:  if (R==APFloat::cmpUnordered)
1951*9880d681SAndroid Build Coastguard Worker                           return getUNDEF(VT);
1952*9880d681SAndroid Build Coastguard Worker                         // fall through
1953*9880d681SAndroid Build Coastguard Worker       case ISD::SETONE: return getConstant(R==APFloat::cmpGreaterThan ||
1954*9880d681SAndroid Build Coastguard Worker                                            R==APFloat::cmpLessThan, dl, VT);
1955*9880d681SAndroid Build Coastguard Worker       case ISD::SETLT:  if (R==APFloat::cmpUnordered)
1956*9880d681SAndroid Build Coastguard Worker                           return getUNDEF(VT);
1957*9880d681SAndroid Build Coastguard Worker                         // fall through
1958*9880d681SAndroid Build Coastguard Worker       case ISD::SETOLT: return getConstant(R==APFloat::cmpLessThan, dl, VT);
1959*9880d681SAndroid Build Coastguard Worker       case ISD::SETGT:  if (R==APFloat::cmpUnordered)
1960*9880d681SAndroid Build Coastguard Worker                           return getUNDEF(VT);
1961*9880d681SAndroid Build Coastguard Worker                         // fall through
1962*9880d681SAndroid Build Coastguard Worker       case ISD::SETOGT: return getConstant(R==APFloat::cmpGreaterThan, dl, VT);
1963*9880d681SAndroid Build Coastguard Worker       case ISD::SETLE:  if (R==APFloat::cmpUnordered)
1964*9880d681SAndroid Build Coastguard Worker                           return getUNDEF(VT);
1965*9880d681SAndroid Build Coastguard Worker                         // fall through
1966*9880d681SAndroid Build Coastguard Worker       case ISD::SETOLE: return getConstant(R==APFloat::cmpLessThan ||
1967*9880d681SAndroid Build Coastguard Worker                                            R==APFloat::cmpEqual, dl, VT);
1968*9880d681SAndroid Build Coastguard Worker       case ISD::SETGE:  if (R==APFloat::cmpUnordered)
1969*9880d681SAndroid Build Coastguard Worker                           return getUNDEF(VT);
1970*9880d681SAndroid Build Coastguard Worker                         // fall through
1971*9880d681SAndroid Build Coastguard Worker       case ISD::SETOGE: return getConstant(R==APFloat::cmpGreaterThan ||
1972*9880d681SAndroid Build Coastguard Worker                                            R==APFloat::cmpEqual, dl, VT);
1973*9880d681SAndroid Build Coastguard Worker       case ISD::SETO:   return getConstant(R!=APFloat::cmpUnordered, dl, VT);
1974*9880d681SAndroid Build Coastguard Worker       case ISD::SETUO:  return getConstant(R==APFloat::cmpUnordered, dl, VT);
1975*9880d681SAndroid Build Coastguard Worker       case ISD::SETUEQ: return getConstant(R==APFloat::cmpUnordered ||
1976*9880d681SAndroid Build Coastguard Worker                                            R==APFloat::cmpEqual, dl, VT);
1977*9880d681SAndroid Build Coastguard Worker       case ISD::SETUNE: return getConstant(R!=APFloat::cmpEqual, dl, VT);
1978*9880d681SAndroid Build Coastguard Worker       case ISD::SETULT: return getConstant(R==APFloat::cmpUnordered ||
1979*9880d681SAndroid Build Coastguard Worker                                            R==APFloat::cmpLessThan, dl, VT);
1980*9880d681SAndroid Build Coastguard Worker       case ISD::SETUGT: return getConstant(R==APFloat::cmpGreaterThan ||
1981*9880d681SAndroid Build Coastguard Worker                                            R==APFloat::cmpUnordered, dl, VT);
1982*9880d681SAndroid Build Coastguard Worker       case ISD::SETULE: return getConstant(R!=APFloat::cmpGreaterThan, dl, VT);
1983*9880d681SAndroid Build Coastguard Worker       case ISD::SETUGE: return getConstant(R!=APFloat::cmpLessThan, dl, VT);
1984*9880d681SAndroid Build Coastguard Worker       }
1985*9880d681SAndroid Build Coastguard Worker     } else {
1986*9880d681SAndroid Build Coastguard Worker       // Ensure that the constant occurs on the RHS.
1987*9880d681SAndroid Build Coastguard Worker       ISD::CondCode SwappedCond = ISD::getSetCCSwappedOperands(Cond);
1988*9880d681SAndroid Build Coastguard Worker       MVT CompVT = N1.getValueType().getSimpleVT();
1989*9880d681SAndroid Build Coastguard Worker       if (!TLI->isCondCodeLegal(SwappedCond, CompVT))
1990*9880d681SAndroid Build Coastguard Worker         return SDValue();
1991*9880d681SAndroid Build Coastguard Worker 
1992*9880d681SAndroid Build Coastguard Worker       return getSetCC(dl, VT, N2, N1, SwappedCond);
1993*9880d681SAndroid Build Coastguard Worker     }
1994*9880d681SAndroid Build Coastguard Worker   }
1995*9880d681SAndroid Build Coastguard Worker 
1996*9880d681SAndroid Build Coastguard Worker   // Could not fold it.
1997*9880d681SAndroid Build Coastguard Worker   return SDValue();
1998*9880d681SAndroid Build Coastguard Worker }
1999*9880d681SAndroid Build Coastguard Worker 
2000*9880d681SAndroid Build Coastguard Worker /// SignBitIsZero - Return true if the sign bit of Op is known to be zero.  We
2001*9880d681SAndroid Build Coastguard Worker /// use this predicate to simplify operations downstream.
SignBitIsZero(SDValue Op,unsigned Depth) const2002*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::SignBitIsZero(SDValue Op, unsigned Depth) const {
2003*9880d681SAndroid Build Coastguard Worker   // This predicate is not safe for vector operations.
2004*9880d681SAndroid Build Coastguard Worker   if (Op.getValueType().isVector())
2005*9880d681SAndroid Build Coastguard Worker     return false;
2006*9880d681SAndroid Build Coastguard Worker 
2007*9880d681SAndroid Build Coastguard Worker   unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits();
2008*9880d681SAndroid Build Coastguard Worker   return MaskedValueIsZero(Op, APInt::getSignBit(BitWidth), Depth);
2009*9880d681SAndroid Build Coastguard Worker }
2010*9880d681SAndroid Build Coastguard Worker 
2011*9880d681SAndroid Build Coastguard Worker /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero.  We use
2012*9880d681SAndroid Build Coastguard Worker /// this predicate to simplify operations downstream.  Mask is known to be zero
2013*9880d681SAndroid Build Coastguard Worker /// for bits that V cannot have.
MaskedValueIsZero(SDValue Op,const APInt & Mask,unsigned Depth) const2014*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::MaskedValueIsZero(SDValue Op, const APInt &Mask,
2015*9880d681SAndroid Build Coastguard Worker                                      unsigned Depth) const {
2016*9880d681SAndroid Build Coastguard Worker   APInt KnownZero, KnownOne;
2017*9880d681SAndroid Build Coastguard Worker   computeKnownBits(Op, KnownZero, KnownOne, Depth);
2018*9880d681SAndroid Build Coastguard Worker   return (KnownZero & Mask) == Mask;
2019*9880d681SAndroid Build Coastguard Worker }
2020*9880d681SAndroid Build Coastguard Worker 
2021*9880d681SAndroid Build Coastguard Worker /// Determine which bits of Op are known to be either zero or one and return
2022*9880d681SAndroid Build Coastguard Worker /// them in the KnownZero/KnownOne bitsets.
computeKnownBits(SDValue Op,APInt & KnownZero,APInt & KnownOne,unsigned Depth) const2023*9880d681SAndroid Build Coastguard Worker void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero,
2024*9880d681SAndroid Build Coastguard Worker                                     APInt &KnownOne, unsigned Depth) const {
2025*9880d681SAndroid Build Coastguard Worker   unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits();
2026*9880d681SAndroid Build Coastguard Worker 
2027*9880d681SAndroid Build Coastguard Worker   KnownZero = KnownOne = APInt(BitWidth, 0);   // Don't know anything.
2028*9880d681SAndroid Build Coastguard Worker   if (Depth == 6)
2029*9880d681SAndroid Build Coastguard Worker     return;  // Limit search depth.
2030*9880d681SAndroid Build Coastguard Worker 
2031*9880d681SAndroid Build Coastguard Worker   APInt KnownZero2, KnownOne2;
2032*9880d681SAndroid Build Coastguard Worker 
2033*9880d681SAndroid Build Coastguard Worker   switch (Op.getOpcode()) {
2034*9880d681SAndroid Build Coastguard Worker   case ISD::Constant:
2035*9880d681SAndroid Build Coastguard Worker     // We know all of the bits for a constant!
2036*9880d681SAndroid Build Coastguard Worker     KnownOne = cast<ConstantSDNode>(Op)->getAPIntValue();
2037*9880d681SAndroid Build Coastguard Worker     KnownZero = ~KnownOne;
2038*9880d681SAndroid Build Coastguard Worker     break;
2039*9880d681SAndroid Build Coastguard Worker   case ISD::AND:
2040*9880d681SAndroid Build Coastguard Worker     // If either the LHS or the RHS are Zero, the result is zero.
2041*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
2042*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
2043*9880d681SAndroid Build Coastguard Worker 
2044*9880d681SAndroid Build Coastguard Worker     // Output known-1 bits are only known if set in both the LHS & RHS.
2045*9880d681SAndroid Build Coastguard Worker     KnownOne &= KnownOne2;
2046*9880d681SAndroid Build Coastguard Worker     // Output known-0 are known to be clear if zero in either the LHS | RHS.
2047*9880d681SAndroid Build Coastguard Worker     KnownZero |= KnownZero2;
2048*9880d681SAndroid Build Coastguard Worker     break;
2049*9880d681SAndroid Build Coastguard Worker   case ISD::OR:
2050*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
2051*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
2052*9880d681SAndroid Build Coastguard Worker 
2053*9880d681SAndroid Build Coastguard Worker     // Output known-0 bits are only known if clear in both the LHS & RHS.
2054*9880d681SAndroid Build Coastguard Worker     KnownZero &= KnownZero2;
2055*9880d681SAndroid Build Coastguard Worker     // Output known-1 are known to be set if set in either the LHS | RHS.
2056*9880d681SAndroid Build Coastguard Worker     KnownOne |= KnownOne2;
2057*9880d681SAndroid Build Coastguard Worker     break;
2058*9880d681SAndroid Build Coastguard Worker   case ISD::XOR: {
2059*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
2060*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
2061*9880d681SAndroid Build Coastguard Worker 
2062*9880d681SAndroid Build Coastguard Worker     // Output known-0 bits are known if clear or set in both the LHS & RHS.
2063*9880d681SAndroid Build Coastguard Worker     APInt KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
2064*9880d681SAndroid Build Coastguard Worker     // Output known-1 are known to be set if set in only one of the LHS, RHS.
2065*9880d681SAndroid Build Coastguard Worker     KnownOne = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
2066*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZeroOut;
2067*9880d681SAndroid Build Coastguard Worker     break;
2068*9880d681SAndroid Build Coastguard Worker   }
2069*9880d681SAndroid Build Coastguard Worker   case ISD::MUL: {
2070*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
2071*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
2072*9880d681SAndroid Build Coastguard Worker 
2073*9880d681SAndroid Build Coastguard Worker     // If low bits are zero in either operand, output low known-0 bits.
2074*9880d681SAndroid Build Coastguard Worker     // Also compute a conserative estimate for high known-0 bits.
2075*9880d681SAndroid Build Coastguard Worker     // More trickiness is possible, but this is sufficient for the
2076*9880d681SAndroid Build Coastguard Worker     // interesting case of alignment computation.
2077*9880d681SAndroid Build Coastguard Worker     KnownOne.clearAllBits();
2078*9880d681SAndroid Build Coastguard Worker     unsigned TrailZ = KnownZero.countTrailingOnes() +
2079*9880d681SAndroid Build Coastguard Worker                       KnownZero2.countTrailingOnes();
2080*9880d681SAndroid Build Coastguard Worker     unsigned LeadZ =  std::max(KnownZero.countLeadingOnes() +
2081*9880d681SAndroid Build Coastguard Worker                                KnownZero2.countLeadingOnes(),
2082*9880d681SAndroid Build Coastguard Worker                                BitWidth) - BitWidth;
2083*9880d681SAndroid Build Coastguard Worker 
2084*9880d681SAndroid Build Coastguard Worker     TrailZ = std::min(TrailZ, BitWidth);
2085*9880d681SAndroid Build Coastguard Worker     LeadZ = std::min(LeadZ, BitWidth);
2086*9880d681SAndroid Build Coastguard Worker     KnownZero = APInt::getLowBitsSet(BitWidth, TrailZ) |
2087*9880d681SAndroid Build Coastguard Worker                 APInt::getHighBitsSet(BitWidth, LeadZ);
2088*9880d681SAndroid Build Coastguard Worker     break;
2089*9880d681SAndroid Build Coastguard Worker   }
2090*9880d681SAndroid Build Coastguard Worker   case ISD::UDIV: {
2091*9880d681SAndroid Build Coastguard Worker     // For the purposes of computing leading zeros we can conservatively
2092*9880d681SAndroid Build Coastguard Worker     // treat a udiv as a logical right shift by the power of 2 known to
2093*9880d681SAndroid Build Coastguard Worker     // be less than the denominator.
2094*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
2095*9880d681SAndroid Build Coastguard Worker     unsigned LeadZ = KnownZero2.countLeadingOnes();
2096*9880d681SAndroid Build Coastguard Worker 
2097*9880d681SAndroid Build Coastguard Worker     KnownOne2.clearAllBits();
2098*9880d681SAndroid Build Coastguard Worker     KnownZero2.clearAllBits();
2099*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);
2100*9880d681SAndroid Build Coastguard Worker     unsigned RHSUnknownLeadingOnes = KnownOne2.countLeadingZeros();
2101*9880d681SAndroid Build Coastguard Worker     if (RHSUnknownLeadingOnes != BitWidth)
2102*9880d681SAndroid Build Coastguard Worker       LeadZ = std::min(BitWidth,
2103*9880d681SAndroid Build Coastguard Worker                        LeadZ + BitWidth - RHSUnknownLeadingOnes - 1);
2104*9880d681SAndroid Build Coastguard Worker 
2105*9880d681SAndroid Build Coastguard Worker     KnownZero = APInt::getHighBitsSet(BitWidth, LeadZ);
2106*9880d681SAndroid Build Coastguard Worker     break;
2107*9880d681SAndroid Build Coastguard Worker   }
2108*9880d681SAndroid Build Coastguard Worker   case ISD::SELECT:
2109*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(2), KnownZero, KnownOne, Depth+1);
2110*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);
2111*9880d681SAndroid Build Coastguard Worker 
2112*9880d681SAndroid Build Coastguard Worker     // Only known if known in both the LHS and RHS.
2113*9880d681SAndroid Build Coastguard Worker     KnownOne &= KnownOne2;
2114*9880d681SAndroid Build Coastguard Worker     KnownZero &= KnownZero2;
2115*9880d681SAndroid Build Coastguard Worker     break;
2116*9880d681SAndroid Build Coastguard Worker   case ISD::SELECT_CC:
2117*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(3), KnownZero, KnownOne, Depth+1);
2118*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(2), KnownZero2, KnownOne2, Depth+1);
2119*9880d681SAndroid Build Coastguard Worker 
2120*9880d681SAndroid Build Coastguard Worker     // Only known if known in both the LHS and RHS.
2121*9880d681SAndroid Build Coastguard Worker     KnownOne &= KnownOne2;
2122*9880d681SAndroid Build Coastguard Worker     KnownZero &= KnownZero2;
2123*9880d681SAndroid Build Coastguard Worker     break;
2124*9880d681SAndroid Build Coastguard Worker   case ISD::SADDO:
2125*9880d681SAndroid Build Coastguard Worker   case ISD::UADDO:
2126*9880d681SAndroid Build Coastguard Worker   case ISD::SSUBO:
2127*9880d681SAndroid Build Coastguard Worker   case ISD::USUBO:
2128*9880d681SAndroid Build Coastguard Worker   case ISD::SMULO:
2129*9880d681SAndroid Build Coastguard Worker   case ISD::UMULO:
2130*9880d681SAndroid Build Coastguard Worker     if (Op.getResNo() != 1)
2131*9880d681SAndroid Build Coastguard Worker       break;
2132*9880d681SAndroid Build Coastguard Worker     // The boolean result conforms to getBooleanContents.
2133*9880d681SAndroid Build Coastguard Worker     // If we know the result of a setcc has the top bits zero, use this info.
2134*9880d681SAndroid Build Coastguard Worker     // We know that we have an integer-based boolean since these operations
2135*9880d681SAndroid Build Coastguard Worker     // are only available for integer.
2136*9880d681SAndroid Build Coastguard Worker     if (TLI->getBooleanContents(Op.getValueType().isVector(), false) ==
2137*9880d681SAndroid Build Coastguard Worker             TargetLowering::ZeroOrOneBooleanContent &&
2138*9880d681SAndroid Build Coastguard Worker         BitWidth > 1)
2139*9880d681SAndroid Build Coastguard Worker       KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
2140*9880d681SAndroid Build Coastguard Worker     break;
2141*9880d681SAndroid Build Coastguard Worker   case ISD::SETCC:
2142*9880d681SAndroid Build Coastguard Worker     // If we know the result of a setcc has the top bits zero, use this info.
2143*9880d681SAndroid Build Coastguard Worker     if (TLI->getBooleanContents(Op.getOperand(0).getValueType()) ==
2144*9880d681SAndroid Build Coastguard Worker             TargetLowering::ZeroOrOneBooleanContent &&
2145*9880d681SAndroid Build Coastguard Worker         BitWidth > 1)
2146*9880d681SAndroid Build Coastguard Worker       KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
2147*9880d681SAndroid Build Coastguard Worker     break;
2148*9880d681SAndroid Build Coastguard Worker   case ISD::SHL:
2149*9880d681SAndroid Build Coastguard Worker     // (shl X, C1) & C2 == 0   iff   (X & C2 >>u C1) == 0
2150*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2151*9880d681SAndroid Build Coastguard Worker       unsigned ShAmt = SA->getZExtValue();
2152*9880d681SAndroid Build Coastguard Worker 
2153*9880d681SAndroid Build Coastguard Worker       // If the shift count is an invalid immediate, don't do anything.
2154*9880d681SAndroid Build Coastguard Worker       if (ShAmt >= BitWidth)
2155*9880d681SAndroid Build Coastguard Worker         break;
2156*9880d681SAndroid Build Coastguard Worker 
2157*9880d681SAndroid Build Coastguard Worker       computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2158*9880d681SAndroid Build Coastguard Worker       KnownZero <<= ShAmt;
2159*9880d681SAndroid Build Coastguard Worker       KnownOne  <<= ShAmt;
2160*9880d681SAndroid Build Coastguard Worker       // low bits known zero.
2161*9880d681SAndroid Build Coastguard Worker       KnownZero |= APInt::getLowBitsSet(BitWidth, ShAmt);
2162*9880d681SAndroid Build Coastguard Worker     }
2163*9880d681SAndroid Build Coastguard Worker     break;
2164*9880d681SAndroid Build Coastguard Worker   case ISD::SRL:
2165*9880d681SAndroid Build Coastguard Worker     // (ushr X, C1) & C2 == 0   iff  (-1 >> C1) & C2 == 0
2166*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2167*9880d681SAndroid Build Coastguard Worker       unsigned ShAmt = SA->getZExtValue();
2168*9880d681SAndroid Build Coastguard Worker 
2169*9880d681SAndroid Build Coastguard Worker       // If the shift count is an invalid immediate, don't do anything.
2170*9880d681SAndroid Build Coastguard Worker       if (ShAmt >= BitWidth)
2171*9880d681SAndroid Build Coastguard Worker         break;
2172*9880d681SAndroid Build Coastguard Worker 
2173*9880d681SAndroid Build Coastguard Worker       computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2174*9880d681SAndroid Build Coastguard Worker       KnownZero = KnownZero.lshr(ShAmt);
2175*9880d681SAndroid Build Coastguard Worker       KnownOne  = KnownOne.lshr(ShAmt);
2176*9880d681SAndroid Build Coastguard Worker 
2177*9880d681SAndroid Build Coastguard Worker       APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
2178*9880d681SAndroid Build Coastguard Worker       KnownZero |= HighBits;  // High bits known zero.
2179*9880d681SAndroid Build Coastguard Worker     }
2180*9880d681SAndroid Build Coastguard Worker     break;
2181*9880d681SAndroid Build Coastguard Worker   case ISD::SRA:
2182*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2183*9880d681SAndroid Build Coastguard Worker       unsigned ShAmt = SA->getZExtValue();
2184*9880d681SAndroid Build Coastguard Worker 
2185*9880d681SAndroid Build Coastguard Worker       // If the shift count is an invalid immediate, don't do anything.
2186*9880d681SAndroid Build Coastguard Worker       if (ShAmt >= BitWidth)
2187*9880d681SAndroid Build Coastguard Worker         break;
2188*9880d681SAndroid Build Coastguard Worker 
2189*9880d681SAndroid Build Coastguard Worker       // If any of the demanded bits are produced by the sign extension, we also
2190*9880d681SAndroid Build Coastguard Worker       // demand the input sign bit.
2191*9880d681SAndroid Build Coastguard Worker       APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
2192*9880d681SAndroid Build Coastguard Worker 
2193*9880d681SAndroid Build Coastguard Worker       computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2194*9880d681SAndroid Build Coastguard Worker       KnownZero = KnownZero.lshr(ShAmt);
2195*9880d681SAndroid Build Coastguard Worker       KnownOne  = KnownOne.lshr(ShAmt);
2196*9880d681SAndroid Build Coastguard Worker 
2197*9880d681SAndroid Build Coastguard Worker       // Handle the sign bits.
2198*9880d681SAndroid Build Coastguard Worker       APInt SignBit = APInt::getSignBit(BitWidth);
2199*9880d681SAndroid Build Coastguard Worker       SignBit = SignBit.lshr(ShAmt);  // Adjust to where it is now in the mask.
2200*9880d681SAndroid Build Coastguard Worker 
2201*9880d681SAndroid Build Coastguard Worker       if (KnownZero.intersects(SignBit)) {
2202*9880d681SAndroid Build Coastguard Worker         KnownZero |= HighBits;  // New bits are known zero.
2203*9880d681SAndroid Build Coastguard Worker       } else if (KnownOne.intersects(SignBit)) {
2204*9880d681SAndroid Build Coastguard Worker         KnownOne  |= HighBits;  // New bits are known one.
2205*9880d681SAndroid Build Coastguard Worker       }
2206*9880d681SAndroid Build Coastguard Worker     }
2207*9880d681SAndroid Build Coastguard Worker     break;
2208*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND_INREG: {
2209*9880d681SAndroid Build Coastguard Worker     EVT EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
2210*9880d681SAndroid Build Coastguard Worker     unsigned EBits = EVT.getScalarType().getSizeInBits();
2211*9880d681SAndroid Build Coastguard Worker 
2212*9880d681SAndroid Build Coastguard Worker     // Sign extension.  Compute the demanded bits in the result that are not
2213*9880d681SAndroid Build Coastguard Worker     // present in the input.
2214*9880d681SAndroid Build Coastguard Worker     APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - EBits);
2215*9880d681SAndroid Build Coastguard Worker 
2216*9880d681SAndroid Build Coastguard Worker     APInt InSignBit = APInt::getSignBit(EBits);
2217*9880d681SAndroid Build Coastguard Worker     APInt InputDemandedBits = APInt::getLowBitsSet(BitWidth, EBits);
2218*9880d681SAndroid Build Coastguard Worker 
2219*9880d681SAndroid Build Coastguard Worker     // If the sign extended bits are demanded, we know that the sign
2220*9880d681SAndroid Build Coastguard Worker     // bit is demanded.
2221*9880d681SAndroid Build Coastguard Worker     InSignBit = InSignBit.zext(BitWidth);
2222*9880d681SAndroid Build Coastguard Worker     if (NewBits.getBoolValue())
2223*9880d681SAndroid Build Coastguard Worker       InputDemandedBits |= InSignBit;
2224*9880d681SAndroid Build Coastguard Worker 
2225*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2226*9880d681SAndroid Build Coastguard Worker     KnownOne &= InputDemandedBits;
2227*9880d681SAndroid Build Coastguard Worker     KnownZero &= InputDemandedBits;
2228*9880d681SAndroid Build Coastguard Worker 
2229*9880d681SAndroid Build Coastguard Worker     // If the sign bit of the input is known set or clear, then we know the
2230*9880d681SAndroid Build Coastguard Worker     // top bits of the result.
2231*9880d681SAndroid Build Coastguard Worker     if (KnownZero.intersects(InSignBit)) {         // Input sign bit known clear
2232*9880d681SAndroid Build Coastguard Worker       KnownZero |= NewBits;
2233*9880d681SAndroid Build Coastguard Worker       KnownOne  &= ~NewBits;
2234*9880d681SAndroid Build Coastguard Worker     } else if (KnownOne.intersects(InSignBit)) {   // Input sign bit known set
2235*9880d681SAndroid Build Coastguard Worker       KnownOne  |= NewBits;
2236*9880d681SAndroid Build Coastguard Worker       KnownZero &= ~NewBits;
2237*9880d681SAndroid Build Coastguard Worker     } else {                              // Input sign bit unknown
2238*9880d681SAndroid Build Coastguard Worker       KnownZero &= ~NewBits;
2239*9880d681SAndroid Build Coastguard Worker       KnownOne  &= ~NewBits;
2240*9880d681SAndroid Build Coastguard Worker     }
2241*9880d681SAndroid Build Coastguard Worker     break;
2242*9880d681SAndroid Build Coastguard Worker   }
2243*9880d681SAndroid Build Coastguard Worker   case ISD::CTTZ:
2244*9880d681SAndroid Build Coastguard Worker   case ISD::CTTZ_ZERO_UNDEF:
2245*9880d681SAndroid Build Coastguard Worker   case ISD::CTLZ:
2246*9880d681SAndroid Build Coastguard Worker   case ISD::CTLZ_ZERO_UNDEF:
2247*9880d681SAndroid Build Coastguard Worker   case ISD::CTPOP: {
2248*9880d681SAndroid Build Coastguard Worker     unsigned LowBits = Log2_32(BitWidth)+1;
2249*9880d681SAndroid Build Coastguard Worker     KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
2250*9880d681SAndroid Build Coastguard Worker     KnownOne.clearAllBits();
2251*9880d681SAndroid Build Coastguard Worker     break;
2252*9880d681SAndroid Build Coastguard Worker   }
2253*9880d681SAndroid Build Coastguard Worker   case ISD::LOAD: {
2254*9880d681SAndroid Build Coastguard Worker     LoadSDNode *LD = cast<LoadSDNode>(Op);
2255*9880d681SAndroid Build Coastguard Worker     // If this is a ZEXTLoad and we are looking at the loaded value.
2256*9880d681SAndroid Build Coastguard Worker     if (ISD::isZEXTLoad(Op.getNode()) && Op.getResNo() == 0) {
2257*9880d681SAndroid Build Coastguard Worker       EVT VT = LD->getMemoryVT();
2258*9880d681SAndroid Build Coastguard Worker       unsigned MemBits = VT.getScalarType().getSizeInBits();
2259*9880d681SAndroid Build Coastguard Worker       KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
2260*9880d681SAndroid Build Coastguard Worker     } else if (const MDNode *Ranges = LD->getRanges()) {
2261*9880d681SAndroid Build Coastguard Worker       if (LD->getExtensionType() == ISD::NON_EXTLOAD)
2262*9880d681SAndroid Build Coastguard Worker         computeKnownBitsFromRangeMetadata(*Ranges, KnownZero, KnownOne);
2263*9880d681SAndroid Build Coastguard Worker     }
2264*9880d681SAndroid Build Coastguard Worker     break;
2265*9880d681SAndroid Build Coastguard Worker   }
2266*9880d681SAndroid Build Coastguard Worker   case ISD::ZERO_EXTEND: {
2267*9880d681SAndroid Build Coastguard Worker     EVT InVT = Op.getOperand(0).getValueType();
2268*9880d681SAndroid Build Coastguard Worker     unsigned InBits = InVT.getScalarType().getSizeInBits();
2269*9880d681SAndroid Build Coastguard Worker     APInt NewBits   = APInt::getHighBitsSet(BitWidth, BitWidth - InBits);
2270*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.trunc(InBits);
2271*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.trunc(InBits);
2272*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2273*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.zext(BitWidth);
2274*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.zext(BitWidth);
2275*9880d681SAndroid Build Coastguard Worker     KnownZero |= NewBits;
2276*9880d681SAndroid Build Coastguard Worker     break;
2277*9880d681SAndroid Build Coastguard Worker   }
2278*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND: {
2279*9880d681SAndroid Build Coastguard Worker     EVT InVT = Op.getOperand(0).getValueType();
2280*9880d681SAndroid Build Coastguard Worker     unsigned InBits = InVT.getScalarType().getSizeInBits();
2281*9880d681SAndroid Build Coastguard Worker     APInt NewBits   = APInt::getHighBitsSet(BitWidth, BitWidth - InBits);
2282*9880d681SAndroid Build Coastguard Worker 
2283*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.trunc(InBits);
2284*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.trunc(InBits);
2285*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2286*9880d681SAndroid Build Coastguard Worker 
2287*9880d681SAndroid Build Coastguard Worker     // Note if the sign bit is known to be zero or one.
2288*9880d681SAndroid Build Coastguard Worker     bool SignBitKnownZero = KnownZero.isNegative();
2289*9880d681SAndroid Build Coastguard Worker     bool SignBitKnownOne  = KnownOne.isNegative();
2290*9880d681SAndroid Build Coastguard Worker 
2291*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.zext(BitWidth);
2292*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.zext(BitWidth);
2293*9880d681SAndroid Build Coastguard Worker 
2294*9880d681SAndroid Build Coastguard Worker     // If the sign bit is known zero or one, the top bits match.
2295*9880d681SAndroid Build Coastguard Worker     if (SignBitKnownZero)
2296*9880d681SAndroid Build Coastguard Worker       KnownZero |= NewBits;
2297*9880d681SAndroid Build Coastguard Worker     else if (SignBitKnownOne)
2298*9880d681SAndroid Build Coastguard Worker       KnownOne  |= NewBits;
2299*9880d681SAndroid Build Coastguard Worker     break;
2300*9880d681SAndroid Build Coastguard Worker   }
2301*9880d681SAndroid Build Coastguard Worker   case ISD::ANY_EXTEND: {
2302*9880d681SAndroid Build Coastguard Worker     EVT InVT = Op.getOperand(0).getValueType();
2303*9880d681SAndroid Build Coastguard Worker     unsigned InBits = InVT.getScalarType().getSizeInBits();
2304*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.trunc(InBits);
2305*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.trunc(InBits);
2306*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2307*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.zext(BitWidth);
2308*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.zext(BitWidth);
2309*9880d681SAndroid Build Coastguard Worker     break;
2310*9880d681SAndroid Build Coastguard Worker   }
2311*9880d681SAndroid Build Coastguard Worker   case ISD::TRUNCATE: {
2312*9880d681SAndroid Build Coastguard Worker     EVT InVT = Op.getOperand(0).getValueType();
2313*9880d681SAndroid Build Coastguard Worker     unsigned InBits = InVT.getScalarType().getSizeInBits();
2314*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.zext(InBits);
2315*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.zext(InBits);
2316*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2317*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.trunc(BitWidth);
2318*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.trunc(BitWidth);
2319*9880d681SAndroid Build Coastguard Worker     break;
2320*9880d681SAndroid Build Coastguard Worker   }
2321*9880d681SAndroid Build Coastguard Worker   case ISD::AssertZext: {
2322*9880d681SAndroid Build Coastguard Worker     EVT VT = cast<VTSDNode>(Op.getOperand(1))->getVT();
2323*9880d681SAndroid Build Coastguard Worker     APInt InMask = APInt::getLowBitsSet(BitWidth, VT.getSizeInBits());
2324*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2325*9880d681SAndroid Build Coastguard Worker     KnownZero |= (~InMask);
2326*9880d681SAndroid Build Coastguard Worker     KnownOne  &= (~KnownZero);
2327*9880d681SAndroid Build Coastguard Worker     break;
2328*9880d681SAndroid Build Coastguard Worker   }
2329*9880d681SAndroid Build Coastguard Worker   case ISD::FGETSIGN:
2330*9880d681SAndroid Build Coastguard Worker     // All bits are zero except the low bit.
2331*9880d681SAndroid Build Coastguard Worker     KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - 1);
2332*9880d681SAndroid Build Coastguard Worker     break;
2333*9880d681SAndroid Build Coastguard Worker 
2334*9880d681SAndroid Build Coastguard Worker   case ISD::SUB: {
2335*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *CLHS = dyn_cast<ConstantSDNode>(Op.getOperand(0))) {
2336*9880d681SAndroid Build Coastguard Worker       // We know that the top bits of C-X are clear if X contains less bits
2337*9880d681SAndroid Build Coastguard Worker       // than C (i.e. no wrap-around can happen).  For example, 20-X is
2338*9880d681SAndroid Build Coastguard Worker       // positive if we can prove that X is >= 0 and < 16.
2339*9880d681SAndroid Build Coastguard Worker       if (CLHS->getAPIntValue().isNonNegative()) {
2340*9880d681SAndroid Build Coastguard Worker         unsigned NLZ = (CLHS->getAPIntValue()+1).countLeadingZeros();
2341*9880d681SAndroid Build Coastguard Worker         // NLZ can't be BitWidth with no sign bit
2342*9880d681SAndroid Build Coastguard Worker         APInt MaskV = APInt::getHighBitsSet(BitWidth, NLZ+1);
2343*9880d681SAndroid Build Coastguard Worker         computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);
2344*9880d681SAndroid Build Coastguard Worker 
2345*9880d681SAndroid Build Coastguard Worker         // If all of the MaskV bits are known to be zero, then we know the
2346*9880d681SAndroid Build Coastguard Worker         // output top bits are zero, because we now know that the output is
2347*9880d681SAndroid Build Coastguard Worker         // from [0-C].
2348*9880d681SAndroid Build Coastguard Worker         if ((KnownZero2 & MaskV) == MaskV) {
2349*9880d681SAndroid Build Coastguard Worker           unsigned NLZ2 = CLHS->getAPIntValue().countLeadingZeros();
2350*9880d681SAndroid Build Coastguard Worker           // Top bits known zero.
2351*9880d681SAndroid Build Coastguard Worker           KnownZero = APInt::getHighBitsSet(BitWidth, NLZ2);
2352*9880d681SAndroid Build Coastguard Worker         }
2353*9880d681SAndroid Build Coastguard Worker       }
2354*9880d681SAndroid Build Coastguard Worker     }
2355*9880d681SAndroid Build Coastguard Worker   }
2356*9880d681SAndroid Build Coastguard Worker   // fall through
2357*9880d681SAndroid Build Coastguard Worker   case ISD::ADD:
2358*9880d681SAndroid Build Coastguard Worker   case ISD::ADDE: {
2359*9880d681SAndroid Build Coastguard Worker     // Output known-0 bits are known if clear or set in both the low clear bits
2360*9880d681SAndroid Build Coastguard Worker     // common to both LHS & RHS.  For example, 8+(X<<3) is known to have the
2361*9880d681SAndroid Build Coastguard Worker     // low 3 bits clear.
2362*9880d681SAndroid Build Coastguard Worker     // Output known-0 bits are also known if the top bits of each input are
2363*9880d681SAndroid Build Coastguard Worker     // known to be clear. For example, if one input has the top 10 bits clear
2364*9880d681SAndroid Build Coastguard Worker     // and the other has the top 8 bits clear, we know the top 7 bits of the
2365*9880d681SAndroid Build Coastguard Worker     // output must be clear.
2366*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
2367*9880d681SAndroid Build Coastguard Worker     unsigned KnownZeroHigh = KnownZero2.countLeadingOnes();
2368*9880d681SAndroid Build Coastguard Worker     unsigned KnownZeroLow = KnownZero2.countTrailingOnes();
2369*9880d681SAndroid Build Coastguard Worker 
2370*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);
2371*9880d681SAndroid Build Coastguard Worker     KnownZeroHigh = std::min(KnownZeroHigh,
2372*9880d681SAndroid Build Coastguard Worker                              KnownZero2.countLeadingOnes());
2373*9880d681SAndroid Build Coastguard Worker     KnownZeroLow = std::min(KnownZeroLow,
2374*9880d681SAndroid Build Coastguard Worker                             KnownZero2.countTrailingOnes());
2375*9880d681SAndroid Build Coastguard Worker 
2376*9880d681SAndroid Build Coastguard Worker     if (Op.getOpcode() == ISD::ADD) {
2377*9880d681SAndroid Build Coastguard Worker       KnownZero |= APInt::getLowBitsSet(BitWidth, KnownZeroLow);
2378*9880d681SAndroid Build Coastguard Worker       if (KnownZeroHigh > 1)
2379*9880d681SAndroid Build Coastguard Worker         KnownZero |= APInt::getHighBitsSet(BitWidth, KnownZeroHigh - 1);
2380*9880d681SAndroid Build Coastguard Worker       break;
2381*9880d681SAndroid Build Coastguard Worker     }
2382*9880d681SAndroid Build Coastguard Worker 
2383*9880d681SAndroid Build Coastguard Worker     // With ADDE, a carry bit may be added in, so we can only use this
2384*9880d681SAndroid Build Coastguard Worker     // information if we know (at least) that the low two bits are clear.  We
2385*9880d681SAndroid Build Coastguard Worker     // then return to the caller that the low bit is unknown but that other bits
2386*9880d681SAndroid Build Coastguard Worker     // are known zero.
2387*9880d681SAndroid Build Coastguard Worker     if (KnownZeroLow >= 2) // ADDE
2388*9880d681SAndroid Build Coastguard Worker       KnownZero |= APInt::getBitsSet(BitWidth, 1, KnownZeroLow);
2389*9880d681SAndroid Build Coastguard Worker     break;
2390*9880d681SAndroid Build Coastguard Worker   }
2391*9880d681SAndroid Build Coastguard Worker   case ISD::SREM:
2392*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *Rem = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2393*9880d681SAndroid Build Coastguard Worker       const APInt &RA = Rem->getAPIntValue().abs();
2394*9880d681SAndroid Build Coastguard Worker       if (RA.isPowerOf2()) {
2395*9880d681SAndroid Build Coastguard Worker         APInt LowBits = RA - 1;
2396*9880d681SAndroid Build Coastguard Worker         computeKnownBits(Op.getOperand(0), KnownZero2,KnownOne2,Depth+1);
2397*9880d681SAndroid Build Coastguard Worker 
2398*9880d681SAndroid Build Coastguard Worker         // The low bits of the first operand are unchanged by the srem.
2399*9880d681SAndroid Build Coastguard Worker         KnownZero = KnownZero2 & LowBits;
2400*9880d681SAndroid Build Coastguard Worker         KnownOne = KnownOne2 & LowBits;
2401*9880d681SAndroid Build Coastguard Worker 
2402*9880d681SAndroid Build Coastguard Worker         // If the first operand is non-negative or has all low bits zero, then
2403*9880d681SAndroid Build Coastguard Worker         // the upper bits are all zero.
2404*9880d681SAndroid Build Coastguard Worker         if (KnownZero2[BitWidth-1] || ((KnownZero2 & LowBits) == LowBits))
2405*9880d681SAndroid Build Coastguard Worker           KnownZero |= ~LowBits;
2406*9880d681SAndroid Build Coastguard Worker 
2407*9880d681SAndroid Build Coastguard Worker         // If the first operand is negative and not all low bits are zero, then
2408*9880d681SAndroid Build Coastguard Worker         // the upper bits are all one.
2409*9880d681SAndroid Build Coastguard Worker         if (KnownOne2[BitWidth-1] && ((KnownOne2 & LowBits) != 0))
2410*9880d681SAndroid Build Coastguard Worker           KnownOne |= ~LowBits;
2411*9880d681SAndroid Build Coastguard Worker         assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
2412*9880d681SAndroid Build Coastguard Worker       }
2413*9880d681SAndroid Build Coastguard Worker     }
2414*9880d681SAndroid Build Coastguard Worker     break;
2415*9880d681SAndroid Build Coastguard Worker   case ISD::UREM: {
2416*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *Rem = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2417*9880d681SAndroid Build Coastguard Worker       const APInt &RA = Rem->getAPIntValue();
2418*9880d681SAndroid Build Coastguard Worker       if (RA.isPowerOf2()) {
2419*9880d681SAndroid Build Coastguard Worker         APInt LowBits = (RA - 1);
2420*9880d681SAndroid Build Coastguard Worker         computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth + 1);
2421*9880d681SAndroid Build Coastguard Worker 
2422*9880d681SAndroid Build Coastguard Worker         // The upper bits are all zero, the lower ones are unchanged.
2423*9880d681SAndroid Build Coastguard Worker         KnownZero = KnownZero2 | ~LowBits;
2424*9880d681SAndroid Build Coastguard Worker         KnownOne = KnownOne2 & LowBits;
2425*9880d681SAndroid Build Coastguard Worker         break;
2426*9880d681SAndroid Build Coastguard Worker       }
2427*9880d681SAndroid Build Coastguard Worker     }
2428*9880d681SAndroid Build Coastguard Worker 
2429*9880d681SAndroid Build Coastguard Worker     // Since the result is less than or equal to either operand, any leading
2430*9880d681SAndroid Build Coastguard Worker     // zero bits in either operand must also exist in the result.
2431*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2432*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);
2433*9880d681SAndroid Build Coastguard Worker 
2434*9880d681SAndroid Build Coastguard Worker     uint32_t Leaders = std::max(KnownZero.countLeadingOnes(),
2435*9880d681SAndroid Build Coastguard Worker                                 KnownZero2.countLeadingOnes());
2436*9880d681SAndroid Build Coastguard Worker     KnownOne.clearAllBits();
2437*9880d681SAndroid Build Coastguard Worker     KnownZero = APInt::getHighBitsSet(BitWidth, Leaders);
2438*9880d681SAndroid Build Coastguard Worker     break;
2439*9880d681SAndroid Build Coastguard Worker   }
2440*9880d681SAndroid Build Coastguard Worker   case ISD::EXTRACT_ELEMENT: {
2441*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2442*9880d681SAndroid Build Coastguard Worker     const unsigned Index =
2443*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
2444*9880d681SAndroid Build Coastguard Worker     const unsigned BitWidth = Op.getValueType().getSizeInBits();
2445*9880d681SAndroid Build Coastguard Worker 
2446*9880d681SAndroid Build Coastguard Worker     // Remove low part of known bits mask
2447*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.getHiBits(KnownZero.getBitWidth() - Index * BitWidth);
2448*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.getHiBits(KnownOne.getBitWidth() - Index * BitWidth);
2449*9880d681SAndroid Build Coastguard Worker 
2450*9880d681SAndroid Build Coastguard Worker     // Remove high part of known bit mask
2451*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero.trunc(BitWidth);
2452*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne.trunc(BitWidth);
2453*9880d681SAndroid Build Coastguard Worker     break;
2454*9880d681SAndroid Build Coastguard Worker   }
2455*9880d681SAndroid Build Coastguard Worker   case ISD::BSWAP: {
2456*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
2457*9880d681SAndroid Build Coastguard Worker     KnownZero = KnownZero2.byteSwap();
2458*9880d681SAndroid Build Coastguard Worker     KnownOne = KnownOne2.byteSwap();
2459*9880d681SAndroid Build Coastguard Worker     break;
2460*9880d681SAndroid Build Coastguard Worker   }
2461*9880d681SAndroid Build Coastguard Worker   case ISD::SMIN:
2462*9880d681SAndroid Build Coastguard Worker   case ISD::SMAX:
2463*9880d681SAndroid Build Coastguard Worker   case ISD::UMIN:
2464*9880d681SAndroid Build Coastguard Worker   case ISD::UMAX: {
2465*9880d681SAndroid Build Coastguard Worker     APInt Op0Zero, Op0One;
2466*9880d681SAndroid Build Coastguard Worker     APInt Op1Zero, Op1One;
2467*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(0), Op0Zero, Op0One, Depth);
2468*9880d681SAndroid Build Coastguard Worker     computeKnownBits(Op.getOperand(1), Op1Zero, Op1One, Depth);
2469*9880d681SAndroid Build Coastguard Worker 
2470*9880d681SAndroid Build Coastguard Worker     KnownZero = Op0Zero & Op1Zero;
2471*9880d681SAndroid Build Coastguard Worker     KnownOne = Op0One & Op1One;
2472*9880d681SAndroid Build Coastguard Worker     break;
2473*9880d681SAndroid Build Coastguard Worker   }
2474*9880d681SAndroid Build Coastguard Worker   case ISD::FrameIndex:
2475*9880d681SAndroid Build Coastguard Worker   case ISD::TargetFrameIndex:
2476*9880d681SAndroid Build Coastguard Worker     if (unsigned Align = InferPtrAlignment(Op)) {
2477*9880d681SAndroid Build Coastguard Worker       // The low bits are known zero if the pointer is aligned.
2478*9880d681SAndroid Build Coastguard Worker       KnownZero = APInt::getLowBitsSet(BitWidth, Log2_32(Align));
2479*9880d681SAndroid Build Coastguard Worker       break;
2480*9880d681SAndroid Build Coastguard Worker     }
2481*9880d681SAndroid Build Coastguard Worker     break;
2482*9880d681SAndroid Build Coastguard Worker 
2483*9880d681SAndroid Build Coastguard Worker   default:
2484*9880d681SAndroid Build Coastguard Worker     if (Op.getOpcode() < ISD::BUILTIN_OP_END)
2485*9880d681SAndroid Build Coastguard Worker       break;
2486*9880d681SAndroid Build Coastguard Worker     // Fallthrough
2487*9880d681SAndroid Build Coastguard Worker   case ISD::INTRINSIC_WO_CHAIN:
2488*9880d681SAndroid Build Coastguard Worker   case ISD::INTRINSIC_W_CHAIN:
2489*9880d681SAndroid Build Coastguard Worker   case ISD::INTRINSIC_VOID:
2490*9880d681SAndroid Build Coastguard Worker     // Allow the target to implement this method for its nodes.
2491*9880d681SAndroid Build Coastguard Worker     TLI->computeKnownBitsForTargetNode(Op, KnownZero, KnownOne, *this, Depth);
2492*9880d681SAndroid Build Coastguard Worker     break;
2493*9880d681SAndroid Build Coastguard Worker   }
2494*9880d681SAndroid Build Coastguard Worker 
2495*9880d681SAndroid Build Coastguard Worker   assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
2496*9880d681SAndroid Build Coastguard Worker }
2497*9880d681SAndroid Build Coastguard Worker 
isKnownToBeAPowerOfTwo(SDValue Val) const2498*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val) const {
2499*9880d681SAndroid Build Coastguard Worker   // A left-shift of a constant one will have exactly one bit set because
2500*9880d681SAndroid Build Coastguard Worker   // shifting the bit off the end is undefined.
2501*9880d681SAndroid Build Coastguard Worker   if (Val.getOpcode() == ISD::SHL) {
2502*9880d681SAndroid Build Coastguard Worker     auto *C = dyn_cast<ConstantSDNode>(Val.getOperand(0));
2503*9880d681SAndroid Build Coastguard Worker     if (C && C->getAPIntValue() == 1)
2504*9880d681SAndroid Build Coastguard Worker       return true;
2505*9880d681SAndroid Build Coastguard Worker   }
2506*9880d681SAndroid Build Coastguard Worker 
2507*9880d681SAndroid Build Coastguard Worker   // Similarly, a logical right-shift of a constant sign-bit will have exactly
2508*9880d681SAndroid Build Coastguard Worker   // one bit set.
2509*9880d681SAndroid Build Coastguard Worker   if (Val.getOpcode() == ISD::SRL) {
2510*9880d681SAndroid Build Coastguard Worker     auto *C = dyn_cast<ConstantSDNode>(Val.getOperand(0));
2511*9880d681SAndroid Build Coastguard Worker     if (C && C->getAPIntValue().isSignBit())
2512*9880d681SAndroid Build Coastguard Worker       return true;
2513*9880d681SAndroid Build Coastguard Worker   }
2514*9880d681SAndroid Build Coastguard Worker 
2515*9880d681SAndroid Build Coastguard Worker   // More could be done here, though the above checks are enough
2516*9880d681SAndroid Build Coastguard Worker   // to handle some common cases.
2517*9880d681SAndroid Build Coastguard Worker 
2518*9880d681SAndroid Build Coastguard Worker   // Fall back to computeKnownBits to catch other known cases.
2519*9880d681SAndroid Build Coastguard Worker   EVT OpVT = Val.getValueType();
2520*9880d681SAndroid Build Coastguard Worker   unsigned BitWidth = OpVT.getScalarType().getSizeInBits();
2521*9880d681SAndroid Build Coastguard Worker   APInt KnownZero, KnownOne;
2522*9880d681SAndroid Build Coastguard Worker   computeKnownBits(Val, KnownZero, KnownOne);
2523*9880d681SAndroid Build Coastguard Worker   return (KnownZero.countPopulation() == BitWidth - 1) &&
2524*9880d681SAndroid Build Coastguard Worker          (KnownOne.countPopulation() == 1);
2525*9880d681SAndroid Build Coastguard Worker }
2526*9880d681SAndroid Build Coastguard Worker 
ComputeNumSignBits(SDValue Op,unsigned Depth) const2527*9880d681SAndroid Build Coastguard Worker unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const {
2528*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
2529*9880d681SAndroid Build Coastguard Worker   assert(VT.isInteger() && "Invalid VT!");
2530*9880d681SAndroid Build Coastguard Worker   unsigned VTBits = VT.getScalarType().getSizeInBits();
2531*9880d681SAndroid Build Coastguard Worker   unsigned Tmp, Tmp2;
2532*9880d681SAndroid Build Coastguard Worker   unsigned FirstAnswer = 1;
2533*9880d681SAndroid Build Coastguard Worker 
2534*9880d681SAndroid Build Coastguard Worker   if (Depth == 6)
2535*9880d681SAndroid Build Coastguard Worker     return 1;  // Limit search depth.
2536*9880d681SAndroid Build Coastguard Worker 
2537*9880d681SAndroid Build Coastguard Worker   switch (Op.getOpcode()) {
2538*9880d681SAndroid Build Coastguard Worker   default: break;
2539*9880d681SAndroid Build Coastguard Worker   case ISD::AssertSext:
2540*9880d681SAndroid Build Coastguard Worker     Tmp = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits();
2541*9880d681SAndroid Build Coastguard Worker     return VTBits-Tmp+1;
2542*9880d681SAndroid Build Coastguard Worker   case ISD::AssertZext:
2543*9880d681SAndroid Build Coastguard Worker     Tmp = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits();
2544*9880d681SAndroid Build Coastguard Worker     return VTBits-Tmp;
2545*9880d681SAndroid Build Coastguard Worker 
2546*9880d681SAndroid Build Coastguard Worker   case ISD::Constant: {
2547*9880d681SAndroid Build Coastguard Worker     const APInt &Val = cast<ConstantSDNode>(Op)->getAPIntValue();
2548*9880d681SAndroid Build Coastguard Worker     return Val.getNumSignBits();
2549*9880d681SAndroid Build Coastguard Worker   }
2550*9880d681SAndroid Build Coastguard Worker 
2551*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND:
2552*9880d681SAndroid Build Coastguard Worker     Tmp =
2553*9880d681SAndroid Build Coastguard Worker         VTBits-Op.getOperand(0).getValueType().getScalarType().getSizeInBits();
2554*9880d681SAndroid Build Coastguard Worker     return ComputeNumSignBits(Op.getOperand(0), Depth+1) + Tmp;
2555*9880d681SAndroid Build Coastguard Worker 
2556*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND_INREG:
2557*9880d681SAndroid Build Coastguard Worker     // Max of the input and what this extends.
2558*9880d681SAndroid Build Coastguard Worker     Tmp =
2559*9880d681SAndroid Build Coastguard Worker       cast<VTSDNode>(Op.getOperand(1))->getVT().getScalarType().getSizeInBits();
2560*9880d681SAndroid Build Coastguard Worker     Tmp = VTBits-Tmp+1;
2561*9880d681SAndroid Build Coastguard Worker 
2562*9880d681SAndroid Build Coastguard Worker     Tmp2 = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2563*9880d681SAndroid Build Coastguard Worker     return std::max(Tmp, Tmp2);
2564*9880d681SAndroid Build Coastguard Worker 
2565*9880d681SAndroid Build Coastguard Worker   case ISD::SRA:
2566*9880d681SAndroid Build Coastguard Worker     Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2567*9880d681SAndroid Build Coastguard Worker     // SRA X, C   -> adds C sign bits.
2568*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2569*9880d681SAndroid Build Coastguard Worker       Tmp += C->getZExtValue();
2570*9880d681SAndroid Build Coastguard Worker       if (Tmp > VTBits) Tmp = VTBits;
2571*9880d681SAndroid Build Coastguard Worker     }
2572*9880d681SAndroid Build Coastguard Worker     return Tmp;
2573*9880d681SAndroid Build Coastguard Worker   case ISD::SHL:
2574*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2575*9880d681SAndroid Build Coastguard Worker       // shl destroys sign bits.
2576*9880d681SAndroid Build Coastguard Worker       Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2577*9880d681SAndroid Build Coastguard Worker       if (C->getZExtValue() >= VTBits ||      // Bad shift.
2578*9880d681SAndroid Build Coastguard Worker           C->getZExtValue() >= Tmp) break;    // Shifted all sign bits out.
2579*9880d681SAndroid Build Coastguard Worker       return Tmp - C->getZExtValue();
2580*9880d681SAndroid Build Coastguard Worker     }
2581*9880d681SAndroid Build Coastguard Worker     break;
2582*9880d681SAndroid Build Coastguard Worker   case ISD::AND:
2583*9880d681SAndroid Build Coastguard Worker   case ISD::OR:
2584*9880d681SAndroid Build Coastguard Worker   case ISD::XOR:    // NOT is handled here.
2585*9880d681SAndroid Build Coastguard Worker     // Logical binary ops preserve the number of sign bits at the worst.
2586*9880d681SAndroid Build Coastguard Worker     Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2587*9880d681SAndroid Build Coastguard Worker     if (Tmp != 1) {
2588*9880d681SAndroid Build Coastguard Worker       Tmp2 = ComputeNumSignBits(Op.getOperand(1), Depth+1);
2589*9880d681SAndroid Build Coastguard Worker       FirstAnswer = std::min(Tmp, Tmp2);
2590*9880d681SAndroid Build Coastguard Worker       // We computed what we know about the sign bits as our first
2591*9880d681SAndroid Build Coastguard Worker       // answer. Now proceed to the generic code that uses
2592*9880d681SAndroid Build Coastguard Worker       // computeKnownBits, and pick whichever answer is better.
2593*9880d681SAndroid Build Coastguard Worker     }
2594*9880d681SAndroid Build Coastguard Worker     break;
2595*9880d681SAndroid Build Coastguard Worker 
2596*9880d681SAndroid Build Coastguard Worker   case ISD::SELECT:
2597*9880d681SAndroid Build Coastguard Worker     Tmp = ComputeNumSignBits(Op.getOperand(1), Depth+1);
2598*9880d681SAndroid Build Coastguard Worker     if (Tmp == 1) return 1;  // Early out.
2599*9880d681SAndroid Build Coastguard Worker     Tmp2 = ComputeNumSignBits(Op.getOperand(2), Depth+1);
2600*9880d681SAndroid Build Coastguard Worker     return std::min(Tmp, Tmp2);
2601*9880d681SAndroid Build Coastguard Worker   case ISD::SELECT_CC:
2602*9880d681SAndroid Build Coastguard Worker     Tmp = ComputeNumSignBits(Op.getOperand(2), Depth+1);
2603*9880d681SAndroid Build Coastguard Worker     if (Tmp == 1) return 1;  // Early out.
2604*9880d681SAndroid Build Coastguard Worker     Tmp2 = ComputeNumSignBits(Op.getOperand(3), Depth+1);
2605*9880d681SAndroid Build Coastguard Worker     return std::min(Tmp, Tmp2);
2606*9880d681SAndroid Build Coastguard Worker   case ISD::SMIN:
2607*9880d681SAndroid Build Coastguard Worker   case ISD::SMAX:
2608*9880d681SAndroid Build Coastguard Worker   case ISD::UMIN:
2609*9880d681SAndroid Build Coastguard Worker   case ISD::UMAX:
2610*9880d681SAndroid Build Coastguard Worker     Tmp = ComputeNumSignBits(Op.getOperand(0), Depth + 1);
2611*9880d681SAndroid Build Coastguard Worker     if (Tmp == 1)
2612*9880d681SAndroid Build Coastguard Worker       return 1;  // Early out.
2613*9880d681SAndroid Build Coastguard Worker     Tmp2 = ComputeNumSignBits(Op.getOperand(1), Depth + 1);
2614*9880d681SAndroid Build Coastguard Worker     return std::min(Tmp, Tmp2);
2615*9880d681SAndroid Build Coastguard Worker   case ISD::SADDO:
2616*9880d681SAndroid Build Coastguard Worker   case ISD::UADDO:
2617*9880d681SAndroid Build Coastguard Worker   case ISD::SSUBO:
2618*9880d681SAndroid Build Coastguard Worker   case ISD::USUBO:
2619*9880d681SAndroid Build Coastguard Worker   case ISD::SMULO:
2620*9880d681SAndroid Build Coastguard Worker   case ISD::UMULO:
2621*9880d681SAndroid Build Coastguard Worker     if (Op.getResNo() != 1)
2622*9880d681SAndroid Build Coastguard Worker       break;
2623*9880d681SAndroid Build Coastguard Worker     // The boolean result conforms to getBooleanContents.  Fall through.
2624*9880d681SAndroid Build Coastguard Worker     // If setcc returns 0/-1, all bits are sign bits.
2625*9880d681SAndroid Build Coastguard Worker     // We know that we have an integer-based boolean since these operations
2626*9880d681SAndroid Build Coastguard Worker     // are only available for integer.
2627*9880d681SAndroid Build Coastguard Worker     if (TLI->getBooleanContents(Op.getValueType().isVector(), false) ==
2628*9880d681SAndroid Build Coastguard Worker         TargetLowering::ZeroOrNegativeOneBooleanContent)
2629*9880d681SAndroid Build Coastguard Worker       return VTBits;
2630*9880d681SAndroid Build Coastguard Worker     break;
2631*9880d681SAndroid Build Coastguard Worker   case ISD::SETCC:
2632*9880d681SAndroid Build Coastguard Worker     // If setcc returns 0/-1, all bits are sign bits.
2633*9880d681SAndroid Build Coastguard Worker     if (TLI->getBooleanContents(Op.getOperand(0).getValueType()) ==
2634*9880d681SAndroid Build Coastguard Worker         TargetLowering::ZeroOrNegativeOneBooleanContent)
2635*9880d681SAndroid Build Coastguard Worker       return VTBits;
2636*9880d681SAndroid Build Coastguard Worker     break;
2637*9880d681SAndroid Build Coastguard Worker   case ISD::ROTL:
2638*9880d681SAndroid Build Coastguard Worker   case ISD::ROTR:
2639*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
2640*9880d681SAndroid Build Coastguard Worker       unsigned RotAmt = C->getZExtValue() & (VTBits-1);
2641*9880d681SAndroid Build Coastguard Worker 
2642*9880d681SAndroid Build Coastguard Worker       // Handle rotate right by N like a rotate left by 32-N.
2643*9880d681SAndroid Build Coastguard Worker       if (Op.getOpcode() == ISD::ROTR)
2644*9880d681SAndroid Build Coastguard Worker         RotAmt = (VTBits-RotAmt) & (VTBits-1);
2645*9880d681SAndroid Build Coastguard Worker 
2646*9880d681SAndroid Build Coastguard Worker       // If we aren't rotating out all of the known-in sign bits, return the
2647*9880d681SAndroid Build Coastguard Worker       // number that are left.  This handles rotl(sext(x), 1) for example.
2648*9880d681SAndroid Build Coastguard Worker       Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2649*9880d681SAndroid Build Coastguard Worker       if (Tmp > RotAmt+1) return Tmp-RotAmt;
2650*9880d681SAndroid Build Coastguard Worker     }
2651*9880d681SAndroid Build Coastguard Worker     break;
2652*9880d681SAndroid Build Coastguard Worker   case ISD::ADD:
2653*9880d681SAndroid Build Coastguard Worker     // Add can have at most one carry bit.  Thus we know that the output
2654*9880d681SAndroid Build Coastguard Worker     // is, at worst, one more bit than the inputs.
2655*9880d681SAndroid Build Coastguard Worker     Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2656*9880d681SAndroid Build Coastguard Worker     if (Tmp == 1) return 1;  // Early out.
2657*9880d681SAndroid Build Coastguard Worker 
2658*9880d681SAndroid Build Coastguard Worker     // Special case decrementing a value (ADD X, -1):
2659*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *CRHS = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
2660*9880d681SAndroid Build Coastguard Worker       if (CRHS->isAllOnesValue()) {
2661*9880d681SAndroid Build Coastguard Worker         APInt KnownZero, KnownOne;
2662*9880d681SAndroid Build Coastguard Worker         computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
2663*9880d681SAndroid Build Coastguard Worker 
2664*9880d681SAndroid Build Coastguard Worker         // If the input is known to be 0 or 1, the output is 0/-1, which is all
2665*9880d681SAndroid Build Coastguard Worker         // sign bits set.
2666*9880d681SAndroid Build Coastguard Worker         if ((KnownZero | APInt(VTBits, 1)).isAllOnesValue())
2667*9880d681SAndroid Build Coastguard Worker           return VTBits;
2668*9880d681SAndroid Build Coastguard Worker 
2669*9880d681SAndroid Build Coastguard Worker         // If we are subtracting one from a positive number, there is no carry
2670*9880d681SAndroid Build Coastguard Worker         // out of the result.
2671*9880d681SAndroid Build Coastguard Worker         if (KnownZero.isNegative())
2672*9880d681SAndroid Build Coastguard Worker           return Tmp;
2673*9880d681SAndroid Build Coastguard Worker       }
2674*9880d681SAndroid Build Coastguard Worker 
2675*9880d681SAndroid Build Coastguard Worker     Tmp2 = ComputeNumSignBits(Op.getOperand(1), Depth+1);
2676*9880d681SAndroid Build Coastguard Worker     if (Tmp2 == 1) return 1;
2677*9880d681SAndroid Build Coastguard Worker     return std::min(Tmp, Tmp2)-1;
2678*9880d681SAndroid Build Coastguard Worker 
2679*9880d681SAndroid Build Coastguard Worker   case ISD::SUB:
2680*9880d681SAndroid Build Coastguard Worker     Tmp2 = ComputeNumSignBits(Op.getOperand(1), Depth+1);
2681*9880d681SAndroid Build Coastguard Worker     if (Tmp2 == 1) return 1;
2682*9880d681SAndroid Build Coastguard Worker 
2683*9880d681SAndroid Build Coastguard Worker     // Handle NEG.
2684*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *CLHS = dyn_cast<ConstantSDNode>(Op.getOperand(0)))
2685*9880d681SAndroid Build Coastguard Worker       if (CLHS->isNullValue()) {
2686*9880d681SAndroid Build Coastguard Worker         APInt KnownZero, KnownOne;
2687*9880d681SAndroid Build Coastguard Worker         computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
2688*9880d681SAndroid Build Coastguard Worker         // If the input is known to be 0 or 1, the output is 0/-1, which is all
2689*9880d681SAndroid Build Coastguard Worker         // sign bits set.
2690*9880d681SAndroid Build Coastguard Worker         if ((KnownZero | APInt(VTBits, 1)).isAllOnesValue())
2691*9880d681SAndroid Build Coastguard Worker           return VTBits;
2692*9880d681SAndroid Build Coastguard Worker 
2693*9880d681SAndroid Build Coastguard Worker         // If the input is known to be positive (the sign bit is known clear),
2694*9880d681SAndroid Build Coastguard Worker         // the output of the NEG has the same number of sign bits as the input.
2695*9880d681SAndroid Build Coastguard Worker         if (KnownZero.isNegative())
2696*9880d681SAndroid Build Coastguard Worker           return Tmp2;
2697*9880d681SAndroid Build Coastguard Worker 
2698*9880d681SAndroid Build Coastguard Worker         // Otherwise, we treat this like a SUB.
2699*9880d681SAndroid Build Coastguard Worker       }
2700*9880d681SAndroid Build Coastguard Worker 
2701*9880d681SAndroid Build Coastguard Worker     // Sub can have at most one carry bit.  Thus we know that the output
2702*9880d681SAndroid Build Coastguard Worker     // is, at worst, one more bit than the inputs.
2703*9880d681SAndroid Build Coastguard Worker     Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2704*9880d681SAndroid Build Coastguard Worker     if (Tmp == 1) return 1;  // Early out.
2705*9880d681SAndroid Build Coastguard Worker     return std::min(Tmp, Tmp2)-1;
2706*9880d681SAndroid Build Coastguard Worker   case ISD::TRUNCATE:
2707*9880d681SAndroid Build Coastguard Worker     // FIXME: it's tricky to do anything useful for this, but it is an important
2708*9880d681SAndroid Build Coastguard Worker     // case for targets like X86.
2709*9880d681SAndroid Build Coastguard Worker     break;
2710*9880d681SAndroid Build Coastguard Worker   case ISD::EXTRACT_ELEMENT: {
2711*9880d681SAndroid Build Coastguard Worker     const int KnownSign = ComputeNumSignBits(Op.getOperand(0), Depth+1);
2712*9880d681SAndroid Build Coastguard Worker     const int BitWidth = Op.getValueType().getSizeInBits();
2713*9880d681SAndroid Build Coastguard Worker     const int Items =
2714*9880d681SAndroid Build Coastguard Worker       Op.getOperand(0).getValueType().getSizeInBits() / BitWidth;
2715*9880d681SAndroid Build Coastguard Worker 
2716*9880d681SAndroid Build Coastguard Worker     // Get reverse index (starting from 1), Op1 value indexes elements from
2717*9880d681SAndroid Build Coastguard Worker     // little end. Sign starts at big end.
2718*9880d681SAndroid Build Coastguard Worker     const int rIndex = Items - 1 -
2719*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
2720*9880d681SAndroid Build Coastguard Worker 
2721*9880d681SAndroid Build Coastguard Worker     // If the sign portion ends in our element the subtraction gives correct
2722*9880d681SAndroid Build Coastguard Worker     // result. Otherwise it gives either negative or > bitwidth result
2723*9880d681SAndroid Build Coastguard Worker     return std::max(std::min(KnownSign - rIndex * BitWidth, BitWidth), 0);
2724*9880d681SAndroid Build Coastguard Worker   }
2725*9880d681SAndroid Build Coastguard Worker   }
2726*9880d681SAndroid Build Coastguard Worker 
2727*9880d681SAndroid Build Coastguard Worker   // If we are looking at the loaded value of the SDNode.
2728*9880d681SAndroid Build Coastguard Worker   if (Op.getResNo() == 0) {
2729*9880d681SAndroid Build Coastguard Worker     // Handle LOADX separately here. EXTLOAD case will fallthrough.
2730*9880d681SAndroid Build Coastguard Worker     if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Op)) {
2731*9880d681SAndroid Build Coastguard Worker       unsigned ExtType = LD->getExtensionType();
2732*9880d681SAndroid Build Coastguard Worker       switch (ExtType) {
2733*9880d681SAndroid Build Coastguard Worker         default: break;
2734*9880d681SAndroid Build Coastguard Worker         case ISD::SEXTLOAD:    // '17' bits known
2735*9880d681SAndroid Build Coastguard Worker           Tmp = LD->getMemoryVT().getScalarType().getSizeInBits();
2736*9880d681SAndroid Build Coastguard Worker           return VTBits-Tmp+1;
2737*9880d681SAndroid Build Coastguard Worker         case ISD::ZEXTLOAD:    // '16' bits known
2738*9880d681SAndroid Build Coastguard Worker           Tmp = LD->getMemoryVT().getScalarType().getSizeInBits();
2739*9880d681SAndroid Build Coastguard Worker           return VTBits-Tmp;
2740*9880d681SAndroid Build Coastguard Worker       }
2741*9880d681SAndroid Build Coastguard Worker     }
2742*9880d681SAndroid Build Coastguard Worker   }
2743*9880d681SAndroid Build Coastguard Worker 
2744*9880d681SAndroid Build Coastguard Worker   // Allow the target to implement this method for its nodes.
2745*9880d681SAndroid Build Coastguard Worker   if (Op.getOpcode() >= ISD::BUILTIN_OP_END ||
2746*9880d681SAndroid Build Coastguard Worker       Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
2747*9880d681SAndroid Build Coastguard Worker       Op.getOpcode() == ISD::INTRINSIC_W_CHAIN ||
2748*9880d681SAndroid Build Coastguard Worker       Op.getOpcode() == ISD::INTRINSIC_VOID) {
2749*9880d681SAndroid Build Coastguard Worker     unsigned NumBits = TLI->ComputeNumSignBitsForTargetNode(Op, *this, Depth);
2750*9880d681SAndroid Build Coastguard Worker     if (NumBits > 1) FirstAnswer = std::max(FirstAnswer, NumBits);
2751*9880d681SAndroid Build Coastguard Worker   }
2752*9880d681SAndroid Build Coastguard Worker 
2753*9880d681SAndroid Build Coastguard Worker   // Finally, if we can prove that the top bits of the result are 0's or 1's,
2754*9880d681SAndroid Build Coastguard Worker   // use this information.
2755*9880d681SAndroid Build Coastguard Worker   APInt KnownZero, KnownOne;
2756*9880d681SAndroid Build Coastguard Worker   computeKnownBits(Op, KnownZero, KnownOne, Depth);
2757*9880d681SAndroid Build Coastguard Worker 
2758*9880d681SAndroid Build Coastguard Worker   APInt Mask;
2759*9880d681SAndroid Build Coastguard Worker   if (KnownZero.isNegative()) {        // sign bit is 0
2760*9880d681SAndroid Build Coastguard Worker     Mask = KnownZero;
2761*9880d681SAndroid Build Coastguard Worker   } else if (KnownOne.isNegative()) {  // sign bit is 1;
2762*9880d681SAndroid Build Coastguard Worker     Mask = KnownOne;
2763*9880d681SAndroid Build Coastguard Worker   } else {
2764*9880d681SAndroid Build Coastguard Worker     // Nothing known.
2765*9880d681SAndroid Build Coastguard Worker     return FirstAnswer;
2766*9880d681SAndroid Build Coastguard Worker   }
2767*9880d681SAndroid Build Coastguard Worker 
2768*9880d681SAndroid Build Coastguard Worker   // Okay, we know that the sign bit in Mask is set.  Use CLZ to determine
2769*9880d681SAndroid Build Coastguard Worker   // the number of identical bits in the top of the input value.
2770*9880d681SAndroid Build Coastguard Worker   Mask = ~Mask;
2771*9880d681SAndroid Build Coastguard Worker   Mask <<= Mask.getBitWidth()-VTBits;
2772*9880d681SAndroid Build Coastguard Worker   // Return # leading zeros.  We use 'min' here in case Val was zero before
2773*9880d681SAndroid Build Coastguard Worker   // shifting.  We don't want to return '64' as for an i32 "0".
2774*9880d681SAndroid Build Coastguard Worker   return std::max(FirstAnswer, std::min(VTBits, Mask.countLeadingZeros()));
2775*9880d681SAndroid Build Coastguard Worker }
2776*9880d681SAndroid Build Coastguard Worker 
isBaseWithConstantOffset(SDValue Op) const2777*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::isBaseWithConstantOffset(SDValue Op) const {
2778*9880d681SAndroid Build Coastguard Worker   if ((Op.getOpcode() != ISD::ADD && Op.getOpcode() != ISD::OR) ||
2779*9880d681SAndroid Build Coastguard Worker       !isa<ConstantSDNode>(Op.getOperand(1)))
2780*9880d681SAndroid Build Coastguard Worker     return false;
2781*9880d681SAndroid Build Coastguard Worker 
2782*9880d681SAndroid Build Coastguard Worker   if (Op.getOpcode() == ISD::OR &&
2783*9880d681SAndroid Build Coastguard Worker       !MaskedValueIsZero(Op.getOperand(0),
2784*9880d681SAndroid Build Coastguard Worker                      cast<ConstantSDNode>(Op.getOperand(1))->getAPIntValue()))
2785*9880d681SAndroid Build Coastguard Worker     return false;
2786*9880d681SAndroid Build Coastguard Worker 
2787*9880d681SAndroid Build Coastguard Worker   return true;
2788*9880d681SAndroid Build Coastguard Worker }
2789*9880d681SAndroid Build Coastguard Worker 
isKnownNeverNaN(SDValue Op) const2790*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::isKnownNeverNaN(SDValue Op) const {
2791*9880d681SAndroid Build Coastguard Worker   // If we're told that NaNs won't happen, assume they won't.
2792*9880d681SAndroid Build Coastguard Worker   if (getTarget().Options.NoNaNsFPMath)
2793*9880d681SAndroid Build Coastguard Worker     return true;
2794*9880d681SAndroid Build Coastguard Worker 
2795*9880d681SAndroid Build Coastguard Worker   // If the value is a constant, we can obviously see if it is a NaN or not.
2796*9880d681SAndroid Build Coastguard Worker   if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Op))
2797*9880d681SAndroid Build Coastguard Worker     return !C->getValueAPF().isNaN();
2798*9880d681SAndroid Build Coastguard Worker 
2799*9880d681SAndroid Build Coastguard Worker   // TODO: Recognize more cases here.
2800*9880d681SAndroid Build Coastguard Worker 
2801*9880d681SAndroid Build Coastguard Worker   return false;
2802*9880d681SAndroid Build Coastguard Worker }
2803*9880d681SAndroid Build Coastguard Worker 
isKnownNeverZero(SDValue Op) const2804*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::isKnownNeverZero(SDValue Op) const {
2805*9880d681SAndroid Build Coastguard Worker   // If the value is a constant, we can obviously see if it is a zero or not.
2806*9880d681SAndroid Build Coastguard Worker   if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Op))
2807*9880d681SAndroid Build Coastguard Worker     return !C->isZero();
2808*9880d681SAndroid Build Coastguard Worker 
2809*9880d681SAndroid Build Coastguard Worker   // TODO: Recognize more cases here.
2810*9880d681SAndroid Build Coastguard Worker   switch (Op.getOpcode()) {
2811*9880d681SAndroid Build Coastguard Worker   default: break;
2812*9880d681SAndroid Build Coastguard Worker   case ISD::OR:
2813*9880d681SAndroid Build Coastguard Worker     if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
2814*9880d681SAndroid Build Coastguard Worker       return !C->isNullValue();
2815*9880d681SAndroid Build Coastguard Worker     break;
2816*9880d681SAndroid Build Coastguard Worker   }
2817*9880d681SAndroid Build Coastguard Worker 
2818*9880d681SAndroid Build Coastguard Worker   return false;
2819*9880d681SAndroid Build Coastguard Worker }
2820*9880d681SAndroid Build Coastguard Worker 
isEqualTo(SDValue A,SDValue B) const2821*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
2822*9880d681SAndroid Build Coastguard Worker   // Check the obvious case.
2823*9880d681SAndroid Build Coastguard Worker   if (A == B) return true;
2824*9880d681SAndroid Build Coastguard Worker 
2825*9880d681SAndroid Build Coastguard Worker   // For for negative and positive zero.
2826*9880d681SAndroid Build Coastguard Worker   if (const ConstantFPSDNode *CA = dyn_cast<ConstantFPSDNode>(A))
2827*9880d681SAndroid Build Coastguard Worker     if (const ConstantFPSDNode *CB = dyn_cast<ConstantFPSDNode>(B))
2828*9880d681SAndroid Build Coastguard Worker       if (CA->isZero() && CB->isZero()) return true;
2829*9880d681SAndroid Build Coastguard Worker 
2830*9880d681SAndroid Build Coastguard Worker   // Otherwise they may not be equal.
2831*9880d681SAndroid Build Coastguard Worker   return false;
2832*9880d681SAndroid Build Coastguard Worker }
2833*9880d681SAndroid Build Coastguard Worker 
haveNoCommonBitsSet(SDValue A,SDValue B) const2834*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::haveNoCommonBitsSet(SDValue A, SDValue B) const {
2835*9880d681SAndroid Build Coastguard Worker   assert(A.getValueType() == B.getValueType() &&
2836*9880d681SAndroid Build Coastguard Worker          "Values must have the same type");
2837*9880d681SAndroid Build Coastguard Worker   APInt AZero, AOne;
2838*9880d681SAndroid Build Coastguard Worker   APInt BZero, BOne;
2839*9880d681SAndroid Build Coastguard Worker   computeKnownBits(A, AZero, AOne);
2840*9880d681SAndroid Build Coastguard Worker   computeKnownBits(B, BZero, BOne);
2841*9880d681SAndroid Build Coastguard Worker   return (AZero | BZero).isAllOnesValue();
2842*9880d681SAndroid Build Coastguard Worker }
2843*9880d681SAndroid Build Coastguard Worker 
FoldCONCAT_VECTORS(const SDLoc & DL,EVT VT,ArrayRef<SDValue> Ops,llvm::SelectionDAG & DAG)2844*9880d681SAndroid Build Coastguard Worker static SDValue FoldCONCAT_VECTORS(const SDLoc &DL, EVT VT,
2845*9880d681SAndroid Build Coastguard Worker                                   ArrayRef<SDValue> Ops,
2846*9880d681SAndroid Build Coastguard Worker                                   llvm::SelectionDAG &DAG) {
2847*9880d681SAndroid Build Coastguard Worker   if (Ops.size() == 1)
2848*9880d681SAndroid Build Coastguard Worker     return Ops[0];
2849*9880d681SAndroid Build Coastguard Worker 
2850*9880d681SAndroid Build Coastguard Worker   // Concat of UNDEFs is UNDEF.
2851*9880d681SAndroid Build Coastguard Worker   if (llvm::all_of(Ops, [](SDValue Op) { return Op.isUndef(); }))
2852*9880d681SAndroid Build Coastguard Worker     return DAG.getUNDEF(VT);
2853*9880d681SAndroid Build Coastguard Worker 
2854*9880d681SAndroid Build Coastguard Worker   // A CONCAT_VECTOR with all UNDEF/BUILD_VECTOR operands can be
2855*9880d681SAndroid Build Coastguard Worker   // simplified to one big BUILD_VECTOR.
2856*9880d681SAndroid Build Coastguard Worker   // FIXME: Add support for SCALAR_TO_VECTOR as well.
2857*9880d681SAndroid Build Coastguard Worker   EVT SVT = VT.getScalarType();
2858*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 16> Elts;
2859*9880d681SAndroid Build Coastguard Worker   for (SDValue Op : Ops) {
2860*9880d681SAndroid Build Coastguard Worker     EVT OpVT = Op.getValueType();
2861*9880d681SAndroid Build Coastguard Worker     if (Op.isUndef())
2862*9880d681SAndroid Build Coastguard Worker       Elts.append(OpVT.getVectorNumElements(), DAG.getUNDEF(SVT));
2863*9880d681SAndroid Build Coastguard Worker     else if (Op.getOpcode() == ISD::BUILD_VECTOR)
2864*9880d681SAndroid Build Coastguard Worker       Elts.append(Op->op_begin(), Op->op_end());
2865*9880d681SAndroid Build Coastguard Worker     else
2866*9880d681SAndroid Build Coastguard Worker       return SDValue();
2867*9880d681SAndroid Build Coastguard Worker   }
2868*9880d681SAndroid Build Coastguard Worker 
2869*9880d681SAndroid Build Coastguard Worker   // BUILD_VECTOR requires all inputs to be of the same type, find the
2870*9880d681SAndroid Build Coastguard Worker   // maximum type and extend them all.
2871*9880d681SAndroid Build Coastguard Worker   for (SDValue Op : Elts)
2872*9880d681SAndroid Build Coastguard Worker     SVT = (SVT.bitsLT(Op.getValueType()) ? Op.getValueType() : SVT);
2873*9880d681SAndroid Build Coastguard Worker 
2874*9880d681SAndroid Build Coastguard Worker   if (SVT.bitsGT(VT.getScalarType()))
2875*9880d681SAndroid Build Coastguard Worker     for (SDValue &Op : Elts)
2876*9880d681SAndroid Build Coastguard Worker       Op = DAG.getTargetLoweringInfo().isZExtFree(Op.getValueType(), SVT)
2877*9880d681SAndroid Build Coastguard Worker                ? DAG.getZExtOrTrunc(Op, DL, SVT)
2878*9880d681SAndroid Build Coastguard Worker                : DAG.getSExtOrTrunc(Op, DL, SVT);
2879*9880d681SAndroid Build Coastguard Worker 
2880*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Elts);
2881*9880d681SAndroid Build Coastguard Worker }
2882*9880d681SAndroid Build Coastguard Worker 
2883*9880d681SAndroid Build Coastguard Worker /// Gets or creates the specified node.
getNode(unsigned Opcode,const SDLoc & DL,EVT VT)2884*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) {
2885*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
2886*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opcode, getVTList(VT), None);
2887*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
2888*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
2889*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
2890*9880d681SAndroid Build Coastguard Worker 
2891*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(),
2892*9880d681SAndroid Build Coastguard Worker                               getVTList(VT));
2893*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
2894*9880d681SAndroid Build Coastguard Worker 
2895*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
2896*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
2897*9880d681SAndroid Build Coastguard Worker }
2898*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,EVT VT,SDValue Operand)2899*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
2900*9880d681SAndroid Build Coastguard Worker                               SDValue Operand) {
2901*9880d681SAndroid Build Coastguard Worker   // Constant fold unary operations with an integer constant operand. Even
2902*9880d681SAndroid Build Coastguard Worker   // opaque constant will be folded, because the folding of unary operations
2903*9880d681SAndroid Build Coastguard Worker   // doesn't create new constants with different values. Nevertheless, the
2904*9880d681SAndroid Build Coastguard Worker   // opaque flag is preserved during folding to prevent future folding with
2905*9880d681SAndroid Build Coastguard Worker   // other constants.
2906*9880d681SAndroid Build Coastguard Worker   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Operand)) {
2907*9880d681SAndroid Build Coastguard Worker     const APInt &Val = C->getAPIntValue();
2908*9880d681SAndroid Build Coastguard Worker     switch (Opcode) {
2909*9880d681SAndroid Build Coastguard Worker     default: break;
2910*9880d681SAndroid Build Coastguard Worker     case ISD::SIGN_EXTEND:
2911*9880d681SAndroid Build Coastguard Worker       return getConstant(Val.sextOrTrunc(VT.getSizeInBits()), DL, VT,
2912*9880d681SAndroid Build Coastguard Worker                          C->isTargetOpcode(), C->isOpaque());
2913*9880d681SAndroid Build Coastguard Worker     case ISD::ANY_EXTEND:
2914*9880d681SAndroid Build Coastguard Worker     case ISD::ZERO_EXTEND:
2915*9880d681SAndroid Build Coastguard Worker     case ISD::TRUNCATE:
2916*9880d681SAndroid Build Coastguard Worker       return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), DL, VT,
2917*9880d681SAndroid Build Coastguard Worker                          C->isTargetOpcode(), C->isOpaque());
2918*9880d681SAndroid Build Coastguard Worker     case ISD::UINT_TO_FP:
2919*9880d681SAndroid Build Coastguard Worker     case ISD::SINT_TO_FP: {
2920*9880d681SAndroid Build Coastguard Worker       APFloat apf(EVTToAPFloatSemantics(VT),
2921*9880d681SAndroid Build Coastguard Worker                   APInt::getNullValue(VT.getSizeInBits()));
2922*9880d681SAndroid Build Coastguard Worker       (void)apf.convertFromAPInt(Val,
2923*9880d681SAndroid Build Coastguard Worker                                  Opcode==ISD::SINT_TO_FP,
2924*9880d681SAndroid Build Coastguard Worker                                  APFloat::rmNearestTiesToEven);
2925*9880d681SAndroid Build Coastguard Worker       return getConstantFP(apf, DL, VT);
2926*9880d681SAndroid Build Coastguard Worker     }
2927*9880d681SAndroid Build Coastguard Worker     case ISD::BITCAST:
2928*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::f16 && C->getValueType(0) == MVT::i16)
2929*9880d681SAndroid Build Coastguard Worker         return getConstantFP(APFloat(APFloat::IEEEhalf, Val), DL, VT);
2930*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::f32 && C->getValueType(0) == MVT::i32)
2931*9880d681SAndroid Build Coastguard Worker         return getConstantFP(APFloat(APFloat::IEEEsingle, Val), DL, VT);
2932*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::f64 && C->getValueType(0) == MVT::i64)
2933*9880d681SAndroid Build Coastguard Worker         return getConstantFP(APFloat(APFloat::IEEEdouble, Val), DL, VT);
2934*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::f128 && C->getValueType(0) == MVT::i128)
2935*9880d681SAndroid Build Coastguard Worker         return getConstantFP(APFloat(APFloat::IEEEquad, Val), DL, VT);
2936*9880d681SAndroid Build Coastguard Worker       break;
2937*9880d681SAndroid Build Coastguard Worker     case ISD::BSWAP:
2938*9880d681SAndroid Build Coastguard Worker       return getConstant(Val.byteSwap(), DL, VT, C->isTargetOpcode(),
2939*9880d681SAndroid Build Coastguard Worker                          C->isOpaque());
2940*9880d681SAndroid Build Coastguard Worker     case ISD::CTPOP:
2941*9880d681SAndroid Build Coastguard Worker       return getConstant(Val.countPopulation(), DL, VT, C->isTargetOpcode(),
2942*9880d681SAndroid Build Coastguard Worker                          C->isOpaque());
2943*9880d681SAndroid Build Coastguard Worker     case ISD::CTLZ:
2944*9880d681SAndroid Build Coastguard Worker     case ISD::CTLZ_ZERO_UNDEF:
2945*9880d681SAndroid Build Coastguard Worker       return getConstant(Val.countLeadingZeros(), DL, VT, C->isTargetOpcode(),
2946*9880d681SAndroid Build Coastguard Worker                          C->isOpaque());
2947*9880d681SAndroid Build Coastguard Worker     case ISD::CTTZ:
2948*9880d681SAndroid Build Coastguard Worker     case ISD::CTTZ_ZERO_UNDEF:
2949*9880d681SAndroid Build Coastguard Worker       return getConstant(Val.countTrailingZeros(), DL, VT, C->isTargetOpcode(),
2950*9880d681SAndroid Build Coastguard Worker                          C->isOpaque());
2951*9880d681SAndroid Build Coastguard Worker     }
2952*9880d681SAndroid Build Coastguard Worker   }
2953*9880d681SAndroid Build Coastguard Worker 
2954*9880d681SAndroid Build Coastguard Worker   // Constant fold unary operations with a floating point constant operand.
2955*9880d681SAndroid Build Coastguard Worker   if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Operand)) {
2956*9880d681SAndroid Build Coastguard Worker     APFloat V = C->getValueAPF();    // make copy
2957*9880d681SAndroid Build Coastguard Worker     switch (Opcode) {
2958*9880d681SAndroid Build Coastguard Worker     case ISD::FNEG:
2959*9880d681SAndroid Build Coastguard Worker       V.changeSign();
2960*9880d681SAndroid Build Coastguard Worker       return getConstantFP(V, DL, VT);
2961*9880d681SAndroid Build Coastguard Worker     case ISD::FABS:
2962*9880d681SAndroid Build Coastguard Worker       V.clearSign();
2963*9880d681SAndroid Build Coastguard Worker       return getConstantFP(V, DL, VT);
2964*9880d681SAndroid Build Coastguard Worker     case ISD::FCEIL: {
2965*9880d681SAndroid Build Coastguard Worker       APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardPositive);
2966*9880d681SAndroid Build Coastguard Worker       if (fs == APFloat::opOK || fs == APFloat::opInexact)
2967*9880d681SAndroid Build Coastguard Worker         return getConstantFP(V, DL, VT);
2968*9880d681SAndroid Build Coastguard Worker       break;
2969*9880d681SAndroid Build Coastguard Worker     }
2970*9880d681SAndroid Build Coastguard Worker     case ISD::FTRUNC: {
2971*9880d681SAndroid Build Coastguard Worker       APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardZero);
2972*9880d681SAndroid Build Coastguard Worker       if (fs == APFloat::opOK || fs == APFloat::opInexact)
2973*9880d681SAndroid Build Coastguard Worker         return getConstantFP(V, DL, VT);
2974*9880d681SAndroid Build Coastguard Worker       break;
2975*9880d681SAndroid Build Coastguard Worker     }
2976*9880d681SAndroid Build Coastguard Worker     case ISD::FFLOOR: {
2977*9880d681SAndroid Build Coastguard Worker       APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardNegative);
2978*9880d681SAndroid Build Coastguard Worker       if (fs == APFloat::opOK || fs == APFloat::opInexact)
2979*9880d681SAndroid Build Coastguard Worker         return getConstantFP(V, DL, VT);
2980*9880d681SAndroid Build Coastguard Worker       break;
2981*9880d681SAndroid Build Coastguard Worker     }
2982*9880d681SAndroid Build Coastguard Worker     case ISD::FP_EXTEND: {
2983*9880d681SAndroid Build Coastguard Worker       bool ignored;
2984*9880d681SAndroid Build Coastguard Worker       // This can return overflow, underflow, or inexact; we don't care.
2985*9880d681SAndroid Build Coastguard Worker       // FIXME need to be more flexible about rounding mode.
2986*9880d681SAndroid Build Coastguard Worker       (void)V.convert(EVTToAPFloatSemantics(VT),
2987*9880d681SAndroid Build Coastguard Worker                       APFloat::rmNearestTiesToEven, &ignored);
2988*9880d681SAndroid Build Coastguard Worker       return getConstantFP(V, DL, VT);
2989*9880d681SAndroid Build Coastguard Worker     }
2990*9880d681SAndroid Build Coastguard Worker     case ISD::FP_TO_SINT:
2991*9880d681SAndroid Build Coastguard Worker     case ISD::FP_TO_UINT: {
2992*9880d681SAndroid Build Coastguard Worker       integerPart x[2];
2993*9880d681SAndroid Build Coastguard Worker       bool ignored;
2994*9880d681SAndroid Build Coastguard Worker       static_assert(integerPartWidth >= 64, "APFloat parts too small!");
2995*9880d681SAndroid Build Coastguard Worker       // FIXME need to be more flexible about rounding mode.
2996*9880d681SAndroid Build Coastguard Worker       APFloat::opStatus s = V.convertToInteger(x, VT.getSizeInBits(),
2997*9880d681SAndroid Build Coastguard Worker                             Opcode==ISD::FP_TO_SINT,
2998*9880d681SAndroid Build Coastguard Worker                             APFloat::rmTowardZero, &ignored);
2999*9880d681SAndroid Build Coastguard Worker       if (s==APFloat::opInvalidOp)     // inexact is OK, in fact usual
3000*9880d681SAndroid Build Coastguard Worker         break;
3001*9880d681SAndroid Build Coastguard Worker       APInt api(VT.getSizeInBits(), x);
3002*9880d681SAndroid Build Coastguard Worker       return getConstant(api, DL, VT);
3003*9880d681SAndroid Build Coastguard Worker     }
3004*9880d681SAndroid Build Coastguard Worker     case ISD::BITCAST:
3005*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::i16 && C->getValueType(0) == MVT::f16)
3006*9880d681SAndroid Build Coastguard Worker         return getConstant((uint16_t)V.bitcastToAPInt().getZExtValue(), DL, VT);
3007*9880d681SAndroid Build Coastguard Worker       else if (VT == MVT::i32 && C->getValueType(0) == MVT::f32)
3008*9880d681SAndroid Build Coastguard Worker         return getConstant((uint32_t)V.bitcastToAPInt().getZExtValue(), DL, VT);
3009*9880d681SAndroid Build Coastguard Worker       else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64)
3010*9880d681SAndroid Build Coastguard Worker         return getConstant(V.bitcastToAPInt().getZExtValue(), DL, VT);
3011*9880d681SAndroid Build Coastguard Worker       break;
3012*9880d681SAndroid Build Coastguard Worker     }
3013*9880d681SAndroid Build Coastguard Worker   }
3014*9880d681SAndroid Build Coastguard Worker 
3015*9880d681SAndroid Build Coastguard Worker   // Constant fold unary operations with a vector integer or float operand.
3016*9880d681SAndroid Build Coastguard Worker   if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(Operand)) {
3017*9880d681SAndroid Build Coastguard Worker     if (BV->isConstant()) {
3018*9880d681SAndroid Build Coastguard Worker       switch (Opcode) {
3019*9880d681SAndroid Build Coastguard Worker       default:
3020*9880d681SAndroid Build Coastguard Worker         // FIXME: Entirely reasonable to perform folding of other unary
3021*9880d681SAndroid Build Coastguard Worker         // operations here as the need arises.
3022*9880d681SAndroid Build Coastguard Worker         break;
3023*9880d681SAndroid Build Coastguard Worker       case ISD::FNEG:
3024*9880d681SAndroid Build Coastguard Worker       case ISD::FABS:
3025*9880d681SAndroid Build Coastguard Worker       case ISD::FCEIL:
3026*9880d681SAndroid Build Coastguard Worker       case ISD::FTRUNC:
3027*9880d681SAndroid Build Coastguard Worker       case ISD::FFLOOR:
3028*9880d681SAndroid Build Coastguard Worker       case ISD::FP_EXTEND:
3029*9880d681SAndroid Build Coastguard Worker       case ISD::FP_TO_SINT:
3030*9880d681SAndroid Build Coastguard Worker       case ISD::FP_TO_UINT:
3031*9880d681SAndroid Build Coastguard Worker       case ISD::TRUNCATE:
3032*9880d681SAndroid Build Coastguard Worker       case ISD::UINT_TO_FP:
3033*9880d681SAndroid Build Coastguard Worker       case ISD::SINT_TO_FP:
3034*9880d681SAndroid Build Coastguard Worker       case ISD::BSWAP:
3035*9880d681SAndroid Build Coastguard Worker       case ISD::CTLZ:
3036*9880d681SAndroid Build Coastguard Worker       case ISD::CTLZ_ZERO_UNDEF:
3037*9880d681SAndroid Build Coastguard Worker       case ISD::CTTZ:
3038*9880d681SAndroid Build Coastguard Worker       case ISD::CTTZ_ZERO_UNDEF:
3039*9880d681SAndroid Build Coastguard Worker       case ISD::CTPOP: {
3040*9880d681SAndroid Build Coastguard Worker         SDValue Ops = { Operand };
3041*9880d681SAndroid Build Coastguard Worker         if (SDValue Fold = FoldConstantVectorArithmetic(Opcode, DL, VT, Ops))
3042*9880d681SAndroid Build Coastguard Worker           return Fold;
3043*9880d681SAndroid Build Coastguard Worker       }
3044*9880d681SAndroid Build Coastguard Worker       }
3045*9880d681SAndroid Build Coastguard Worker     }
3046*9880d681SAndroid Build Coastguard Worker   }
3047*9880d681SAndroid Build Coastguard Worker 
3048*9880d681SAndroid Build Coastguard Worker   unsigned OpOpcode = Operand.getNode()->getOpcode();
3049*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
3050*9880d681SAndroid Build Coastguard Worker   case ISD::TokenFactor:
3051*9880d681SAndroid Build Coastguard Worker   case ISD::MERGE_VALUES:
3052*9880d681SAndroid Build Coastguard Worker   case ISD::CONCAT_VECTORS:
3053*9880d681SAndroid Build Coastguard Worker     return Operand;         // Factor, merge or concat of one node?  No need.
3054*9880d681SAndroid Build Coastguard Worker   case ISD::FP_ROUND: llvm_unreachable("Invalid method to make FP_ROUND node");
3055*9880d681SAndroid Build Coastguard Worker   case ISD::FP_EXTEND:
3056*9880d681SAndroid Build Coastguard Worker     assert(VT.isFloatingPoint() &&
3057*9880d681SAndroid Build Coastguard Worker            Operand.getValueType().isFloatingPoint() && "Invalid FP cast!");
3058*9880d681SAndroid Build Coastguard Worker     if (Operand.getValueType() == VT) return Operand;  // noop conversion.
3059*9880d681SAndroid Build Coastguard Worker     assert((!VT.isVector() ||
3060*9880d681SAndroid Build Coastguard Worker             VT.getVectorNumElements() ==
3061*9880d681SAndroid Build Coastguard Worker             Operand.getValueType().getVectorNumElements()) &&
3062*9880d681SAndroid Build Coastguard Worker            "Vector element count mismatch!");
3063*9880d681SAndroid Build Coastguard Worker     assert(Operand.getValueType().bitsLT(VT) &&
3064*9880d681SAndroid Build Coastguard Worker            "Invalid fpext node, dst < src!");
3065*9880d681SAndroid Build Coastguard Worker     if (Operand.isUndef())
3066*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3067*9880d681SAndroid Build Coastguard Worker     break;
3068*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND:
3069*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && Operand.getValueType().isInteger() &&
3070*9880d681SAndroid Build Coastguard Worker            "Invalid SIGN_EXTEND!");
3071*9880d681SAndroid Build Coastguard Worker     if (Operand.getValueType() == VT) return Operand;   // noop extension
3072*9880d681SAndroid Build Coastguard Worker     assert((!VT.isVector() ||
3073*9880d681SAndroid Build Coastguard Worker             VT.getVectorNumElements() ==
3074*9880d681SAndroid Build Coastguard Worker             Operand.getValueType().getVectorNumElements()) &&
3075*9880d681SAndroid Build Coastguard Worker            "Vector element count mismatch!");
3076*9880d681SAndroid Build Coastguard Worker     assert(Operand.getValueType().bitsLT(VT) &&
3077*9880d681SAndroid Build Coastguard Worker            "Invalid sext node, dst < src!");
3078*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND)
3079*9880d681SAndroid Build Coastguard Worker       return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0));
3080*9880d681SAndroid Build Coastguard Worker     else if (OpOpcode == ISD::UNDEF)
3081*9880d681SAndroid Build Coastguard Worker       // sext(undef) = 0, because the top bits will all be the same.
3082*9880d681SAndroid Build Coastguard Worker       return getConstant(0, DL, VT);
3083*9880d681SAndroid Build Coastguard Worker     break;
3084*9880d681SAndroid Build Coastguard Worker   case ISD::ZERO_EXTEND:
3085*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && Operand.getValueType().isInteger() &&
3086*9880d681SAndroid Build Coastguard Worker            "Invalid ZERO_EXTEND!");
3087*9880d681SAndroid Build Coastguard Worker     if (Operand.getValueType() == VT) return Operand;   // noop extension
3088*9880d681SAndroid Build Coastguard Worker     assert((!VT.isVector() ||
3089*9880d681SAndroid Build Coastguard Worker             VT.getVectorNumElements() ==
3090*9880d681SAndroid Build Coastguard Worker             Operand.getValueType().getVectorNumElements()) &&
3091*9880d681SAndroid Build Coastguard Worker            "Vector element count mismatch!");
3092*9880d681SAndroid Build Coastguard Worker     assert(Operand.getValueType().bitsLT(VT) &&
3093*9880d681SAndroid Build Coastguard Worker            "Invalid zext node, dst < src!");
3094*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::ZERO_EXTEND)   // (zext (zext x)) -> (zext x)
3095*9880d681SAndroid Build Coastguard Worker       return getNode(ISD::ZERO_EXTEND, DL, VT,
3096*9880d681SAndroid Build Coastguard Worker                      Operand.getNode()->getOperand(0));
3097*9880d681SAndroid Build Coastguard Worker     else if (OpOpcode == ISD::UNDEF)
3098*9880d681SAndroid Build Coastguard Worker       // zext(undef) = 0, because the top bits will be zero.
3099*9880d681SAndroid Build Coastguard Worker       return getConstant(0, DL, VT);
3100*9880d681SAndroid Build Coastguard Worker     break;
3101*9880d681SAndroid Build Coastguard Worker   case ISD::ANY_EXTEND:
3102*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && Operand.getValueType().isInteger() &&
3103*9880d681SAndroid Build Coastguard Worker            "Invalid ANY_EXTEND!");
3104*9880d681SAndroid Build Coastguard Worker     if (Operand.getValueType() == VT) return Operand;   // noop extension
3105*9880d681SAndroid Build Coastguard Worker     assert((!VT.isVector() ||
3106*9880d681SAndroid Build Coastguard Worker             VT.getVectorNumElements() ==
3107*9880d681SAndroid Build Coastguard Worker             Operand.getValueType().getVectorNumElements()) &&
3108*9880d681SAndroid Build Coastguard Worker            "Vector element count mismatch!");
3109*9880d681SAndroid Build Coastguard Worker     assert(Operand.getValueType().bitsLT(VT) &&
3110*9880d681SAndroid Build Coastguard Worker            "Invalid anyext node, dst < src!");
3111*9880d681SAndroid Build Coastguard Worker 
3112*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND ||
3113*9880d681SAndroid Build Coastguard Worker         OpOpcode == ISD::ANY_EXTEND)
3114*9880d681SAndroid Build Coastguard Worker       // (ext (zext x)) -> (zext x)  and  (ext (sext x)) -> (sext x)
3115*9880d681SAndroid Build Coastguard Worker       return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0));
3116*9880d681SAndroid Build Coastguard Worker     else if (OpOpcode == ISD::UNDEF)
3117*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3118*9880d681SAndroid Build Coastguard Worker 
3119*9880d681SAndroid Build Coastguard Worker     // (ext (trunx x)) -> x
3120*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::TRUNCATE) {
3121*9880d681SAndroid Build Coastguard Worker       SDValue OpOp = Operand.getNode()->getOperand(0);
3122*9880d681SAndroid Build Coastguard Worker       if (OpOp.getValueType() == VT)
3123*9880d681SAndroid Build Coastguard Worker         return OpOp;
3124*9880d681SAndroid Build Coastguard Worker     }
3125*9880d681SAndroid Build Coastguard Worker     break;
3126*9880d681SAndroid Build Coastguard Worker   case ISD::TRUNCATE:
3127*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && Operand.getValueType().isInteger() &&
3128*9880d681SAndroid Build Coastguard Worker            "Invalid TRUNCATE!");
3129*9880d681SAndroid Build Coastguard Worker     if (Operand.getValueType() == VT) return Operand;   // noop truncate
3130*9880d681SAndroid Build Coastguard Worker     assert((!VT.isVector() ||
3131*9880d681SAndroid Build Coastguard Worker             VT.getVectorNumElements() ==
3132*9880d681SAndroid Build Coastguard Worker             Operand.getValueType().getVectorNumElements()) &&
3133*9880d681SAndroid Build Coastguard Worker            "Vector element count mismatch!");
3134*9880d681SAndroid Build Coastguard Worker     assert(Operand.getValueType().bitsGT(VT) &&
3135*9880d681SAndroid Build Coastguard Worker            "Invalid truncate node, src < dst!");
3136*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::TRUNCATE)
3137*9880d681SAndroid Build Coastguard Worker       return getNode(ISD::TRUNCATE, DL, VT, Operand.getNode()->getOperand(0));
3138*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND ||
3139*9880d681SAndroid Build Coastguard Worker         OpOpcode == ISD::ANY_EXTEND) {
3140*9880d681SAndroid Build Coastguard Worker       // If the source is smaller than the dest, we still need an extend.
3141*9880d681SAndroid Build Coastguard Worker       if (Operand.getNode()->getOperand(0).getValueType().getScalarType()
3142*9880d681SAndroid Build Coastguard Worker             .bitsLT(VT.getScalarType()))
3143*9880d681SAndroid Build Coastguard Worker         return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0));
3144*9880d681SAndroid Build Coastguard Worker       if (Operand.getNode()->getOperand(0).getValueType().bitsGT(VT))
3145*9880d681SAndroid Build Coastguard Worker         return getNode(ISD::TRUNCATE, DL, VT, Operand.getNode()->getOperand(0));
3146*9880d681SAndroid Build Coastguard Worker       return Operand.getNode()->getOperand(0);
3147*9880d681SAndroid Build Coastguard Worker     }
3148*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::UNDEF)
3149*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3150*9880d681SAndroid Build Coastguard Worker     break;
3151*9880d681SAndroid Build Coastguard Worker   case ISD::BSWAP:
3152*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && VT == Operand.getValueType() &&
3153*9880d681SAndroid Build Coastguard Worker            "Invalid BSWAP!");
3154*9880d681SAndroid Build Coastguard Worker     assert((VT.getScalarSizeInBits() % 16 == 0) &&
3155*9880d681SAndroid Build Coastguard Worker            "BSWAP types must be a multiple of 16 bits!");
3156*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::UNDEF)
3157*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3158*9880d681SAndroid Build Coastguard Worker     break;
3159*9880d681SAndroid Build Coastguard Worker   case ISD::BITREVERSE:
3160*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && VT == Operand.getValueType() &&
3161*9880d681SAndroid Build Coastguard Worker            "Invalid BITREVERSE!");
3162*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::UNDEF)
3163*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3164*9880d681SAndroid Build Coastguard Worker     break;
3165*9880d681SAndroid Build Coastguard Worker   case ISD::BITCAST:
3166*9880d681SAndroid Build Coastguard Worker     // Basic sanity checking.
3167*9880d681SAndroid Build Coastguard Worker     assert(VT.getSizeInBits() == Operand.getValueType().getSizeInBits()
3168*9880d681SAndroid Build Coastguard Worker            && "Cannot BITCAST between types of different sizes!");
3169*9880d681SAndroid Build Coastguard Worker     if (VT == Operand.getValueType()) return Operand;  // noop conversion.
3170*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::BITCAST)  // bitconv(bitconv(x)) -> bitconv(x)
3171*9880d681SAndroid Build Coastguard Worker       return getNode(ISD::BITCAST, DL, VT, Operand.getOperand(0));
3172*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::UNDEF)
3173*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3174*9880d681SAndroid Build Coastguard Worker     break;
3175*9880d681SAndroid Build Coastguard Worker   case ISD::SCALAR_TO_VECTOR:
3176*9880d681SAndroid Build Coastguard Worker     assert(VT.isVector() && !Operand.getValueType().isVector() &&
3177*9880d681SAndroid Build Coastguard Worker            (VT.getVectorElementType() == Operand.getValueType() ||
3178*9880d681SAndroid Build Coastguard Worker             (VT.getVectorElementType().isInteger() &&
3179*9880d681SAndroid Build Coastguard Worker              Operand.getValueType().isInteger() &&
3180*9880d681SAndroid Build Coastguard Worker              VT.getVectorElementType().bitsLE(Operand.getValueType()))) &&
3181*9880d681SAndroid Build Coastguard Worker            "Illegal SCALAR_TO_VECTOR node!");
3182*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::UNDEF)
3183*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3184*9880d681SAndroid Build Coastguard Worker     // scalar_to_vector(extract_vector_elt V, 0) -> V, top bits are undefined.
3185*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::EXTRACT_VECTOR_ELT &&
3186*9880d681SAndroid Build Coastguard Worker         isa<ConstantSDNode>(Operand.getOperand(1)) &&
3187*9880d681SAndroid Build Coastguard Worker         Operand.getConstantOperandVal(1) == 0 &&
3188*9880d681SAndroid Build Coastguard Worker         Operand.getOperand(0).getValueType() == VT)
3189*9880d681SAndroid Build Coastguard Worker       return Operand.getOperand(0);
3190*9880d681SAndroid Build Coastguard Worker     break;
3191*9880d681SAndroid Build Coastguard Worker   case ISD::FNEG:
3192*9880d681SAndroid Build Coastguard Worker     // -(X-Y) -> (Y-X) is unsafe because when X==Y, -0.0 != +0.0
3193*9880d681SAndroid Build Coastguard Worker     if (getTarget().Options.UnsafeFPMath && OpOpcode == ISD::FSUB)
3194*9880d681SAndroid Build Coastguard Worker       // FIXME: FNEG has no fast-math-flags to propagate; use the FSUB's flags?
3195*9880d681SAndroid Build Coastguard Worker       return getNode(ISD::FSUB, DL, VT, Operand.getNode()->getOperand(1),
3196*9880d681SAndroid Build Coastguard Worker                        Operand.getNode()->getOperand(0),
3197*9880d681SAndroid Build Coastguard Worker                        &cast<BinaryWithFlagsSDNode>(Operand.getNode())->Flags);
3198*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::FNEG)  // --X -> X
3199*9880d681SAndroid Build Coastguard Worker       return Operand.getNode()->getOperand(0);
3200*9880d681SAndroid Build Coastguard Worker     break;
3201*9880d681SAndroid Build Coastguard Worker   case ISD::FABS:
3202*9880d681SAndroid Build Coastguard Worker     if (OpOpcode == ISD::FNEG)  // abs(-X) -> abs(X)
3203*9880d681SAndroid Build Coastguard Worker       return getNode(ISD::FABS, DL, VT, Operand.getNode()->getOperand(0));
3204*9880d681SAndroid Build Coastguard Worker     break;
3205*9880d681SAndroid Build Coastguard Worker   }
3206*9880d681SAndroid Build Coastguard Worker 
3207*9880d681SAndroid Build Coastguard Worker   SDNode *N;
3208*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
3209*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {Operand};
3210*9880d681SAndroid Build Coastguard Worker   if (VT != MVT::Glue) { // Don't CSE flag producing nodes
3211*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
3212*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opcode, VTs, Ops);
3213*9880d681SAndroid Build Coastguard Worker     void *IP = nullptr;
3214*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
3215*9880d681SAndroid Build Coastguard Worker       return SDValue(E, 0);
3216*9880d681SAndroid Build Coastguard Worker 
3217*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
3218*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
3219*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
3220*9880d681SAndroid Build Coastguard Worker   } else {
3221*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
3222*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
3223*9880d681SAndroid Build Coastguard Worker   }
3224*9880d681SAndroid Build Coastguard Worker 
3225*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
3226*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
3227*9880d681SAndroid Build Coastguard Worker }
3228*9880d681SAndroid Build Coastguard Worker 
FoldValue(unsigned Opcode,const APInt & C1,const APInt & C2)3229*9880d681SAndroid Build Coastguard Worker static std::pair<APInt, bool> FoldValue(unsigned Opcode, const APInt &C1,
3230*9880d681SAndroid Build Coastguard Worker                                         const APInt &C2) {
3231*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
3232*9880d681SAndroid Build Coastguard Worker   case ISD::ADD:  return std::make_pair(C1 + C2, true);
3233*9880d681SAndroid Build Coastguard Worker   case ISD::SUB:  return std::make_pair(C1 - C2, true);
3234*9880d681SAndroid Build Coastguard Worker   case ISD::MUL:  return std::make_pair(C1 * C2, true);
3235*9880d681SAndroid Build Coastguard Worker   case ISD::AND:  return std::make_pair(C1 & C2, true);
3236*9880d681SAndroid Build Coastguard Worker   case ISD::OR:   return std::make_pair(C1 | C2, true);
3237*9880d681SAndroid Build Coastguard Worker   case ISD::XOR:  return std::make_pair(C1 ^ C2, true);
3238*9880d681SAndroid Build Coastguard Worker   case ISD::SHL:  return std::make_pair(C1 << C2, true);
3239*9880d681SAndroid Build Coastguard Worker   case ISD::SRL:  return std::make_pair(C1.lshr(C2), true);
3240*9880d681SAndroid Build Coastguard Worker   case ISD::SRA:  return std::make_pair(C1.ashr(C2), true);
3241*9880d681SAndroid Build Coastguard Worker   case ISD::ROTL: return std::make_pair(C1.rotl(C2), true);
3242*9880d681SAndroid Build Coastguard Worker   case ISD::ROTR: return std::make_pair(C1.rotr(C2), true);
3243*9880d681SAndroid Build Coastguard Worker   case ISD::SMIN: return std::make_pair(C1.sle(C2) ? C1 : C2, true);
3244*9880d681SAndroid Build Coastguard Worker   case ISD::SMAX: return std::make_pair(C1.sge(C2) ? C1 : C2, true);
3245*9880d681SAndroid Build Coastguard Worker   case ISD::UMIN: return std::make_pair(C1.ule(C2) ? C1 : C2, true);
3246*9880d681SAndroid Build Coastguard Worker   case ISD::UMAX: return std::make_pair(C1.uge(C2) ? C1 : C2, true);
3247*9880d681SAndroid Build Coastguard Worker   case ISD::UDIV:
3248*9880d681SAndroid Build Coastguard Worker     if (!C2.getBoolValue())
3249*9880d681SAndroid Build Coastguard Worker       break;
3250*9880d681SAndroid Build Coastguard Worker     return std::make_pair(C1.udiv(C2), true);
3251*9880d681SAndroid Build Coastguard Worker   case ISD::UREM:
3252*9880d681SAndroid Build Coastguard Worker     if (!C2.getBoolValue())
3253*9880d681SAndroid Build Coastguard Worker       break;
3254*9880d681SAndroid Build Coastguard Worker     return std::make_pair(C1.urem(C2), true);
3255*9880d681SAndroid Build Coastguard Worker   case ISD::SDIV:
3256*9880d681SAndroid Build Coastguard Worker     if (!C2.getBoolValue())
3257*9880d681SAndroid Build Coastguard Worker       break;
3258*9880d681SAndroid Build Coastguard Worker     return std::make_pair(C1.sdiv(C2), true);
3259*9880d681SAndroid Build Coastguard Worker   case ISD::SREM:
3260*9880d681SAndroid Build Coastguard Worker     if (!C2.getBoolValue())
3261*9880d681SAndroid Build Coastguard Worker       break;
3262*9880d681SAndroid Build Coastguard Worker     return std::make_pair(C1.srem(C2), true);
3263*9880d681SAndroid Build Coastguard Worker   }
3264*9880d681SAndroid Build Coastguard Worker   return std::make_pair(APInt(1, 0), false);
3265*9880d681SAndroid Build Coastguard Worker }
3266*9880d681SAndroid Build Coastguard Worker 
FoldConstantArithmetic(unsigned Opcode,const SDLoc & DL,EVT VT,const ConstantSDNode * Cst1,const ConstantSDNode * Cst2)3267*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
3268*9880d681SAndroid Build Coastguard Worker                                              EVT VT, const ConstantSDNode *Cst1,
3269*9880d681SAndroid Build Coastguard Worker                                              const ConstantSDNode *Cst2) {
3270*9880d681SAndroid Build Coastguard Worker   if (Cst1->isOpaque() || Cst2->isOpaque())
3271*9880d681SAndroid Build Coastguard Worker     return SDValue();
3272*9880d681SAndroid Build Coastguard Worker 
3273*9880d681SAndroid Build Coastguard Worker   std::pair<APInt, bool> Folded = FoldValue(Opcode, Cst1->getAPIntValue(),
3274*9880d681SAndroid Build Coastguard Worker                                             Cst2->getAPIntValue());
3275*9880d681SAndroid Build Coastguard Worker   if (!Folded.second)
3276*9880d681SAndroid Build Coastguard Worker     return SDValue();
3277*9880d681SAndroid Build Coastguard Worker   return getConstant(Folded.first, DL, VT);
3278*9880d681SAndroid Build Coastguard Worker }
3279*9880d681SAndroid Build Coastguard Worker 
FoldSymbolOffset(unsigned Opcode,EVT VT,const GlobalAddressSDNode * GA,const SDNode * N2)3280*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::FoldSymbolOffset(unsigned Opcode, EVT VT,
3281*9880d681SAndroid Build Coastguard Worker                                        const GlobalAddressSDNode *GA,
3282*9880d681SAndroid Build Coastguard Worker                                        const SDNode *N2) {
3283*9880d681SAndroid Build Coastguard Worker   if (GA->getOpcode() != ISD::GlobalAddress)
3284*9880d681SAndroid Build Coastguard Worker     return SDValue();
3285*9880d681SAndroid Build Coastguard Worker   if (!TLI->isOffsetFoldingLegal(GA))
3286*9880d681SAndroid Build Coastguard Worker     return SDValue();
3287*9880d681SAndroid Build Coastguard Worker   const ConstantSDNode *Cst2 = dyn_cast<ConstantSDNode>(N2);
3288*9880d681SAndroid Build Coastguard Worker   if (!Cst2)
3289*9880d681SAndroid Build Coastguard Worker     return SDValue();
3290*9880d681SAndroid Build Coastguard Worker   int64_t Offset = Cst2->getSExtValue();
3291*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
3292*9880d681SAndroid Build Coastguard Worker   case ISD::ADD: break;
3293*9880d681SAndroid Build Coastguard Worker   case ISD::SUB: Offset = -uint64_t(Offset); break;
3294*9880d681SAndroid Build Coastguard Worker   default: return SDValue();
3295*9880d681SAndroid Build Coastguard Worker   }
3296*9880d681SAndroid Build Coastguard Worker   return getGlobalAddress(GA->getGlobal(), SDLoc(Cst2), VT,
3297*9880d681SAndroid Build Coastguard Worker                           GA->getOffset() + uint64_t(Offset));
3298*9880d681SAndroid Build Coastguard Worker }
3299*9880d681SAndroid Build Coastguard Worker 
FoldConstantArithmetic(unsigned Opcode,const SDLoc & DL,EVT VT,SDNode * Cst1,SDNode * Cst2)3300*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
3301*9880d681SAndroid Build Coastguard Worker                                              EVT VT, SDNode *Cst1,
3302*9880d681SAndroid Build Coastguard Worker                                              SDNode *Cst2) {
3303*9880d681SAndroid Build Coastguard Worker   // If the opcode is a target-specific ISD node, there's nothing we can
3304*9880d681SAndroid Build Coastguard Worker   // do here and the operand rules may not line up with the below, so
3305*9880d681SAndroid Build Coastguard Worker   // bail early.
3306*9880d681SAndroid Build Coastguard Worker   if (Opcode >= ISD::BUILTIN_OP_END)
3307*9880d681SAndroid Build Coastguard Worker     return SDValue();
3308*9880d681SAndroid Build Coastguard Worker 
3309*9880d681SAndroid Build Coastguard Worker   // Handle the case of two scalars.
3310*9880d681SAndroid Build Coastguard Worker   if (const ConstantSDNode *Scalar1 = dyn_cast<ConstantSDNode>(Cst1)) {
3311*9880d681SAndroid Build Coastguard Worker     if (const ConstantSDNode *Scalar2 = dyn_cast<ConstantSDNode>(Cst2)) {
3312*9880d681SAndroid Build Coastguard Worker       SDValue Folded = FoldConstantArithmetic(Opcode, DL, VT, Scalar1, Scalar2);
3313*9880d681SAndroid Build Coastguard Worker       assert((!Folded || !VT.isVector()) &&
3314*9880d681SAndroid Build Coastguard Worker              "Can't fold vectors ops with scalar operands");
3315*9880d681SAndroid Build Coastguard Worker       return Folded;
3316*9880d681SAndroid Build Coastguard Worker     }
3317*9880d681SAndroid Build Coastguard Worker   }
3318*9880d681SAndroid Build Coastguard Worker 
3319*9880d681SAndroid Build Coastguard Worker   // fold (add Sym, c) -> Sym+c
3320*9880d681SAndroid Build Coastguard Worker   if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Cst1))
3321*9880d681SAndroid Build Coastguard Worker     return FoldSymbolOffset(Opcode, VT, GA, Cst2);
3322*9880d681SAndroid Build Coastguard Worker   if (isCommutativeBinOp(Opcode))
3323*9880d681SAndroid Build Coastguard Worker     if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Cst2))
3324*9880d681SAndroid Build Coastguard Worker       return FoldSymbolOffset(Opcode, VT, GA, Cst1);
3325*9880d681SAndroid Build Coastguard Worker 
3326*9880d681SAndroid Build Coastguard Worker   // For vectors extract each constant element into Inputs so we can constant
3327*9880d681SAndroid Build Coastguard Worker   // fold them individually.
3328*9880d681SAndroid Build Coastguard Worker   BuildVectorSDNode *BV1 = dyn_cast<BuildVectorSDNode>(Cst1);
3329*9880d681SAndroid Build Coastguard Worker   BuildVectorSDNode *BV2 = dyn_cast<BuildVectorSDNode>(Cst2);
3330*9880d681SAndroid Build Coastguard Worker   if (!BV1 || !BV2)
3331*9880d681SAndroid Build Coastguard Worker     return SDValue();
3332*9880d681SAndroid Build Coastguard Worker 
3333*9880d681SAndroid Build Coastguard Worker   assert(BV1->getNumOperands() == BV2->getNumOperands() && "Out of sync!");
3334*9880d681SAndroid Build Coastguard Worker 
3335*9880d681SAndroid Build Coastguard Worker   EVT SVT = VT.getScalarType();
3336*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 4> Outputs;
3337*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = BV1->getNumOperands(); I != E; ++I) {
3338*9880d681SAndroid Build Coastguard Worker     ConstantSDNode *V1 = dyn_cast<ConstantSDNode>(BV1->getOperand(I));
3339*9880d681SAndroid Build Coastguard Worker     ConstantSDNode *V2 = dyn_cast<ConstantSDNode>(BV2->getOperand(I));
3340*9880d681SAndroid Build Coastguard Worker     if (!V1 || !V2) // Not a constant, bail.
3341*9880d681SAndroid Build Coastguard Worker       return SDValue();
3342*9880d681SAndroid Build Coastguard Worker 
3343*9880d681SAndroid Build Coastguard Worker     if (V1->isOpaque() || V2->isOpaque())
3344*9880d681SAndroid Build Coastguard Worker       return SDValue();
3345*9880d681SAndroid Build Coastguard Worker 
3346*9880d681SAndroid Build Coastguard Worker     // Avoid BUILD_VECTOR nodes that perform implicit truncation.
3347*9880d681SAndroid Build Coastguard Worker     // FIXME: This is valid and could be handled by truncating the APInts.
3348*9880d681SAndroid Build Coastguard Worker     if (V1->getValueType(0) != SVT || V2->getValueType(0) != SVT)
3349*9880d681SAndroid Build Coastguard Worker       return SDValue();
3350*9880d681SAndroid Build Coastguard Worker 
3351*9880d681SAndroid Build Coastguard Worker     // Fold one vector element.
3352*9880d681SAndroid Build Coastguard Worker     std::pair<APInt, bool> Folded = FoldValue(Opcode, V1->getAPIntValue(),
3353*9880d681SAndroid Build Coastguard Worker                                               V2->getAPIntValue());
3354*9880d681SAndroid Build Coastguard Worker     if (!Folded.second)
3355*9880d681SAndroid Build Coastguard Worker       return SDValue();
3356*9880d681SAndroid Build Coastguard Worker     Outputs.push_back(getConstant(Folded.first, DL, SVT));
3357*9880d681SAndroid Build Coastguard Worker   }
3358*9880d681SAndroid Build Coastguard Worker 
3359*9880d681SAndroid Build Coastguard Worker   assert(VT.getVectorNumElements() == Outputs.size() &&
3360*9880d681SAndroid Build Coastguard Worker          "Vector size mismatch!");
3361*9880d681SAndroid Build Coastguard Worker 
3362*9880d681SAndroid Build Coastguard Worker   // We may have a vector type but a scalar result. Create a splat.
3363*9880d681SAndroid Build Coastguard Worker   Outputs.resize(VT.getVectorNumElements(), Outputs.back());
3364*9880d681SAndroid Build Coastguard Worker 
3365*9880d681SAndroid Build Coastguard Worker   // Build a big vector out of the scalar elements we generated.
3366*9880d681SAndroid Build Coastguard Worker   return getBuildVector(VT, SDLoc(), Outputs);
3367*9880d681SAndroid Build Coastguard Worker }
3368*9880d681SAndroid Build Coastguard Worker 
FoldConstantVectorArithmetic(unsigned Opcode,const SDLoc & DL,EVT VT,ArrayRef<SDValue> Ops,const SDNodeFlags * Flags)3369*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::FoldConstantVectorArithmetic(unsigned Opcode,
3370*9880d681SAndroid Build Coastguard Worker                                                    const SDLoc &DL, EVT VT,
3371*9880d681SAndroid Build Coastguard Worker                                                    ArrayRef<SDValue> Ops,
3372*9880d681SAndroid Build Coastguard Worker                                                    const SDNodeFlags *Flags) {
3373*9880d681SAndroid Build Coastguard Worker   // If the opcode is a target-specific ISD node, there's nothing we can
3374*9880d681SAndroid Build Coastguard Worker   // do here and the operand rules may not line up with the below, so
3375*9880d681SAndroid Build Coastguard Worker   // bail early.
3376*9880d681SAndroid Build Coastguard Worker   if (Opcode >= ISD::BUILTIN_OP_END)
3377*9880d681SAndroid Build Coastguard Worker     return SDValue();
3378*9880d681SAndroid Build Coastguard Worker 
3379*9880d681SAndroid Build Coastguard Worker   // We can only fold vectors - maybe merge with FoldConstantArithmetic someday?
3380*9880d681SAndroid Build Coastguard Worker   if (!VT.isVector())
3381*9880d681SAndroid Build Coastguard Worker     return SDValue();
3382*9880d681SAndroid Build Coastguard Worker 
3383*9880d681SAndroid Build Coastguard Worker   unsigned NumElts = VT.getVectorNumElements();
3384*9880d681SAndroid Build Coastguard Worker 
3385*9880d681SAndroid Build Coastguard Worker   auto IsScalarOrSameVectorSize = [&](const SDValue &Op) {
3386*9880d681SAndroid Build Coastguard Worker     return !Op.getValueType().isVector() ||
3387*9880d681SAndroid Build Coastguard Worker            Op.getValueType().getVectorNumElements() == NumElts;
3388*9880d681SAndroid Build Coastguard Worker   };
3389*9880d681SAndroid Build Coastguard Worker 
3390*9880d681SAndroid Build Coastguard Worker   auto IsConstantBuildVectorOrUndef = [&](const SDValue &Op) {
3391*9880d681SAndroid Build Coastguard Worker     BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(Op);
3392*9880d681SAndroid Build Coastguard Worker     return (Op.isUndef()) || (Op.getOpcode() == ISD::CONDCODE) ||
3393*9880d681SAndroid Build Coastguard Worker            (BV && BV->isConstant());
3394*9880d681SAndroid Build Coastguard Worker   };
3395*9880d681SAndroid Build Coastguard Worker 
3396*9880d681SAndroid Build Coastguard Worker   // All operands must be vector types with the same number of elements as
3397*9880d681SAndroid Build Coastguard Worker   // the result type and must be either UNDEF or a build vector of constant
3398*9880d681SAndroid Build Coastguard Worker   // or UNDEF scalars.
3399*9880d681SAndroid Build Coastguard Worker   if (!std::all_of(Ops.begin(), Ops.end(), IsConstantBuildVectorOrUndef) ||
3400*9880d681SAndroid Build Coastguard Worker       !std::all_of(Ops.begin(), Ops.end(), IsScalarOrSameVectorSize))
3401*9880d681SAndroid Build Coastguard Worker     return SDValue();
3402*9880d681SAndroid Build Coastguard Worker 
3403*9880d681SAndroid Build Coastguard Worker   // If we are comparing vectors, then the result needs to be a i1 boolean
3404*9880d681SAndroid Build Coastguard Worker   // that is then sign-extended back to the legal result type.
3405*9880d681SAndroid Build Coastguard Worker   EVT SVT = (Opcode == ISD::SETCC ? MVT::i1 : VT.getScalarType());
3406*9880d681SAndroid Build Coastguard Worker 
3407*9880d681SAndroid Build Coastguard Worker   // Find legal integer scalar type for constant promotion and
3408*9880d681SAndroid Build Coastguard Worker   // ensure that its scalar size is at least as large as source.
3409*9880d681SAndroid Build Coastguard Worker   EVT LegalSVT = VT.getScalarType();
3410*9880d681SAndroid Build Coastguard Worker   if (LegalSVT.isInteger()) {
3411*9880d681SAndroid Build Coastguard Worker     LegalSVT = TLI->getTypeToTransformTo(*getContext(), LegalSVT);
3412*9880d681SAndroid Build Coastguard Worker     if (LegalSVT.bitsLT(VT.getScalarType()))
3413*9880d681SAndroid Build Coastguard Worker       return SDValue();
3414*9880d681SAndroid Build Coastguard Worker   }
3415*9880d681SAndroid Build Coastguard Worker 
3416*9880d681SAndroid Build Coastguard Worker   // Constant fold each scalar lane separately.
3417*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 4> ScalarResults;
3418*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i != NumElts; i++) {
3419*9880d681SAndroid Build Coastguard Worker     SmallVector<SDValue, 4> ScalarOps;
3420*9880d681SAndroid Build Coastguard Worker     for (SDValue Op : Ops) {
3421*9880d681SAndroid Build Coastguard Worker       EVT InSVT = Op.getValueType().getScalarType();
3422*9880d681SAndroid Build Coastguard Worker       BuildVectorSDNode *InBV = dyn_cast<BuildVectorSDNode>(Op);
3423*9880d681SAndroid Build Coastguard Worker       if (!InBV) {
3424*9880d681SAndroid Build Coastguard Worker         // We've checked that this is UNDEF or a constant of some kind.
3425*9880d681SAndroid Build Coastguard Worker         if (Op.isUndef())
3426*9880d681SAndroid Build Coastguard Worker           ScalarOps.push_back(getUNDEF(InSVT));
3427*9880d681SAndroid Build Coastguard Worker         else
3428*9880d681SAndroid Build Coastguard Worker           ScalarOps.push_back(Op);
3429*9880d681SAndroid Build Coastguard Worker         continue;
3430*9880d681SAndroid Build Coastguard Worker       }
3431*9880d681SAndroid Build Coastguard Worker 
3432*9880d681SAndroid Build Coastguard Worker       SDValue ScalarOp = InBV->getOperand(i);
3433*9880d681SAndroid Build Coastguard Worker       EVT ScalarVT = ScalarOp.getValueType();
3434*9880d681SAndroid Build Coastguard Worker 
3435*9880d681SAndroid Build Coastguard Worker       // Build vector (integer) scalar operands may need implicit
3436*9880d681SAndroid Build Coastguard Worker       // truncation - do this before constant folding.
3437*9880d681SAndroid Build Coastguard Worker       if (ScalarVT.isInteger() && ScalarVT.bitsGT(InSVT))
3438*9880d681SAndroid Build Coastguard Worker         ScalarOp = getNode(ISD::TRUNCATE, DL, InSVT, ScalarOp);
3439*9880d681SAndroid Build Coastguard Worker 
3440*9880d681SAndroid Build Coastguard Worker       ScalarOps.push_back(ScalarOp);
3441*9880d681SAndroid Build Coastguard Worker     }
3442*9880d681SAndroid Build Coastguard Worker 
3443*9880d681SAndroid Build Coastguard Worker     // Constant fold the scalar operands.
3444*9880d681SAndroid Build Coastguard Worker     SDValue ScalarResult = getNode(Opcode, DL, SVT, ScalarOps, Flags);
3445*9880d681SAndroid Build Coastguard Worker 
3446*9880d681SAndroid Build Coastguard Worker     // Legalize the (integer) scalar constant if necessary.
3447*9880d681SAndroid Build Coastguard Worker     if (LegalSVT != SVT)
3448*9880d681SAndroid Build Coastguard Worker       ScalarResult = getNode(ISD::SIGN_EXTEND, DL, LegalSVT, ScalarResult);
3449*9880d681SAndroid Build Coastguard Worker 
3450*9880d681SAndroid Build Coastguard Worker     // Scalar folding only succeeded if the result is a constant or UNDEF.
3451*9880d681SAndroid Build Coastguard Worker     if (!ScalarResult.isUndef() && ScalarResult.getOpcode() != ISD::Constant &&
3452*9880d681SAndroid Build Coastguard Worker         ScalarResult.getOpcode() != ISD::ConstantFP)
3453*9880d681SAndroid Build Coastguard Worker       return SDValue();
3454*9880d681SAndroid Build Coastguard Worker     ScalarResults.push_back(ScalarResult);
3455*9880d681SAndroid Build Coastguard Worker   }
3456*9880d681SAndroid Build Coastguard Worker 
3457*9880d681SAndroid Build Coastguard Worker   return getBuildVector(VT, DL, ScalarResults);
3458*9880d681SAndroid Build Coastguard Worker }
3459*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,EVT VT,SDValue N1,SDValue N2,const SDNodeFlags * Flags)3460*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
3461*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2,
3462*9880d681SAndroid Build Coastguard Worker                               const SDNodeFlags *Flags) {
3463*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
3464*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
3465*9880d681SAndroid Build Coastguard Worker   ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
3466*9880d681SAndroid Build Coastguard Worker   ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2);
3467*9880d681SAndroid Build Coastguard Worker 
3468*9880d681SAndroid Build Coastguard Worker   // Canonicalize constant to RHS if commutative.
3469*9880d681SAndroid Build Coastguard Worker   if (isCommutativeBinOp(Opcode)) {
3470*9880d681SAndroid Build Coastguard Worker     if (N1C && !N2C) {
3471*9880d681SAndroid Build Coastguard Worker       std::swap(N1C, N2C);
3472*9880d681SAndroid Build Coastguard Worker       std::swap(N1, N2);
3473*9880d681SAndroid Build Coastguard Worker     } else if (N1CFP && !N2CFP) {
3474*9880d681SAndroid Build Coastguard Worker       std::swap(N1CFP, N2CFP);
3475*9880d681SAndroid Build Coastguard Worker       std::swap(N1, N2);
3476*9880d681SAndroid Build Coastguard Worker     }
3477*9880d681SAndroid Build Coastguard Worker   }
3478*9880d681SAndroid Build Coastguard Worker 
3479*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
3480*9880d681SAndroid Build Coastguard Worker   default: break;
3481*9880d681SAndroid Build Coastguard Worker   case ISD::TokenFactor:
3482*9880d681SAndroid Build Coastguard Worker     assert(VT == MVT::Other && N1.getValueType() == MVT::Other &&
3483*9880d681SAndroid Build Coastguard Worker            N2.getValueType() == MVT::Other && "Invalid token factor!");
3484*9880d681SAndroid Build Coastguard Worker     // Fold trivial token factors.
3485*9880d681SAndroid Build Coastguard Worker     if (N1.getOpcode() == ISD::EntryToken) return N2;
3486*9880d681SAndroid Build Coastguard Worker     if (N2.getOpcode() == ISD::EntryToken) return N1;
3487*9880d681SAndroid Build Coastguard Worker     if (N1 == N2) return N1;
3488*9880d681SAndroid Build Coastguard Worker     break;
3489*9880d681SAndroid Build Coastguard Worker   case ISD::CONCAT_VECTORS: {
3490*9880d681SAndroid Build Coastguard Worker     // Attempt to fold CONCAT_VECTORS into BUILD_VECTOR or UNDEF.
3491*9880d681SAndroid Build Coastguard Worker     SDValue Ops[] = {N1, N2};
3492*9880d681SAndroid Build Coastguard Worker     if (SDValue V = FoldCONCAT_VECTORS(DL, VT, Ops, *this))
3493*9880d681SAndroid Build Coastguard Worker       return V;
3494*9880d681SAndroid Build Coastguard Worker     break;
3495*9880d681SAndroid Build Coastguard Worker   }
3496*9880d681SAndroid Build Coastguard Worker   case ISD::AND:
3497*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && "This operator does not apply to FP types!");
3498*9880d681SAndroid Build Coastguard Worker     assert(N1.getValueType() == N2.getValueType() &&
3499*9880d681SAndroid Build Coastguard Worker            N1.getValueType() == VT && "Binary operator types must match!");
3500*9880d681SAndroid Build Coastguard Worker     // (X & 0) -> 0.  This commonly occurs when legalizing i64 values, so it's
3501*9880d681SAndroid Build Coastguard Worker     // worth handling here.
3502*9880d681SAndroid Build Coastguard Worker     if (N2C && N2C->isNullValue())
3503*9880d681SAndroid Build Coastguard Worker       return N2;
3504*9880d681SAndroid Build Coastguard Worker     if (N2C && N2C->isAllOnesValue())  // X & -1 -> X
3505*9880d681SAndroid Build Coastguard Worker       return N1;
3506*9880d681SAndroid Build Coastguard Worker     break;
3507*9880d681SAndroid Build Coastguard Worker   case ISD::OR:
3508*9880d681SAndroid Build Coastguard Worker   case ISD::XOR:
3509*9880d681SAndroid Build Coastguard Worker   case ISD::ADD:
3510*9880d681SAndroid Build Coastguard Worker   case ISD::SUB:
3511*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && "This operator does not apply to FP types!");
3512*9880d681SAndroid Build Coastguard Worker     assert(N1.getValueType() == N2.getValueType() &&
3513*9880d681SAndroid Build Coastguard Worker            N1.getValueType() == VT && "Binary operator types must match!");
3514*9880d681SAndroid Build Coastguard Worker     // (X ^|+- 0) -> X.  This commonly occurs when legalizing i64 values, so
3515*9880d681SAndroid Build Coastguard Worker     // it's worth handling here.
3516*9880d681SAndroid Build Coastguard Worker     if (N2C && N2C->isNullValue())
3517*9880d681SAndroid Build Coastguard Worker       return N1;
3518*9880d681SAndroid Build Coastguard Worker     break;
3519*9880d681SAndroid Build Coastguard Worker   case ISD::UDIV:
3520*9880d681SAndroid Build Coastguard Worker   case ISD::UREM:
3521*9880d681SAndroid Build Coastguard Worker   case ISD::MULHU:
3522*9880d681SAndroid Build Coastguard Worker   case ISD::MULHS:
3523*9880d681SAndroid Build Coastguard Worker   case ISD::MUL:
3524*9880d681SAndroid Build Coastguard Worker   case ISD::SDIV:
3525*9880d681SAndroid Build Coastguard Worker   case ISD::SREM:
3526*9880d681SAndroid Build Coastguard Worker   case ISD::SMIN:
3527*9880d681SAndroid Build Coastguard Worker   case ISD::SMAX:
3528*9880d681SAndroid Build Coastguard Worker   case ISD::UMIN:
3529*9880d681SAndroid Build Coastguard Worker   case ISD::UMAX:
3530*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && "This operator does not apply to FP types!");
3531*9880d681SAndroid Build Coastguard Worker     assert(N1.getValueType() == N2.getValueType() &&
3532*9880d681SAndroid Build Coastguard Worker            N1.getValueType() == VT && "Binary operator types must match!");
3533*9880d681SAndroid Build Coastguard Worker     break;
3534*9880d681SAndroid Build Coastguard Worker   case ISD::FADD:
3535*9880d681SAndroid Build Coastguard Worker   case ISD::FSUB:
3536*9880d681SAndroid Build Coastguard Worker   case ISD::FMUL:
3537*9880d681SAndroid Build Coastguard Worker   case ISD::FDIV:
3538*9880d681SAndroid Build Coastguard Worker   case ISD::FREM:
3539*9880d681SAndroid Build Coastguard Worker     if (getTarget().Options.UnsafeFPMath) {
3540*9880d681SAndroid Build Coastguard Worker       if (Opcode == ISD::FADD) {
3541*9880d681SAndroid Build Coastguard Worker         // x+0 --> x
3542*9880d681SAndroid Build Coastguard Worker         if (N2CFP && N2CFP->getValueAPF().isZero())
3543*9880d681SAndroid Build Coastguard Worker           return N1;
3544*9880d681SAndroid Build Coastguard Worker       } else if (Opcode == ISD::FSUB) {
3545*9880d681SAndroid Build Coastguard Worker         // x-0 --> x
3546*9880d681SAndroid Build Coastguard Worker         if (N2CFP && N2CFP->getValueAPF().isZero())
3547*9880d681SAndroid Build Coastguard Worker           return N1;
3548*9880d681SAndroid Build Coastguard Worker       } else if (Opcode == ISD::FMUL) {
3549*9880d681SAndroid Build Coastguard Worker         // x*0 --> 0
3550*9880d681SAndroid Build Coastguard Worker         if (N2CFP && N2CFP->isZero())
3551*9880d681SAndroid Build Coastguard Worker           return N2;
3552*9880d681SAndroid Build Coastguard Worker         // x*1 --> x
3553*9880d681SAndroid Build Coastguard Worker         if (N2CFP && N2CFP->isExactlyValue(1.0))
3554*9880d681SAndroid Build Coastguard Worker           return N1;
3555*9880d681SAndroid Build Coastguard Worker       }
3556*9880d681SAndroid Build Coastguard Worker     }
3557*9880d681SAndroid Build Coastguard Worker     assert(VT.isFloatingPoint() && "This operator only applies to FP types!");
3558*9880d681SAndroid Build Coastguard Worker     assert(N1.getValueType() == N2.getValueType() &&
3559*9880d681SAndroid Build Coastguard Worker            N1.getValueType() == VT && "Binary operator types must match!");
3560*9880d681SAndroid Build Coastguard Worker     break;
3561*9880d681SAndroid Build Coastguard Worker   case ISD::FCOPYSIGN:   // N1 and result must match.  N1/N2 need not match.
3562*9880d681SAndroid Build Coastguard Worker     assert(N1.getValueType() == VT &&
3563*9880d681SAndroid Build Coastguard Worker            N1.getValueType().isFloatingPoint() &&
3564*9880d681SAndroid Build Coastguard Worker            N2.getValueType().isFloatingPoint() &&
3565*9880d681SAndroid Build Coastguard Worker            "Invalid FCOPYSIGN!");
3566*9880d681SAndroid Build Coastguard Worker     break;
3567*9880d681SAndroid Build Coastguard Worker   case ISD::SHL:
3568*9880d681SAndroid Build Coastguard Worker   case ISD::SRA:
3569*9880d681SAndroid Build Coastguard Worker   case ISD::SRL:
3570*9880d681SAndroid Build Coastguard Worker   case ISD::ROTL:
3571*9880d681SAndroid Build Coastguard Worker   case ISD::ROTR:
3572*9880d681SAndroid Build Coastguard Worker     assert(VT == N1.getValueType() &&
3573*9880d681SAndroid Build Coastguard Worker            "Shift operators return type must be the same as their first arg");
3574*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && N2.getValueType().isInteger() &&
3575*9880d681SAndroid Build Coastguard Worker            "Shifts only work on integers");
3576*9880d681SAndroid Build Coastguard Worker     assert((!VT.isVector() || VT == N2.getValueType()) &&
3577*9880d681SAndroid Build Coastguard Worker            "Vector shift amounts must be in the same as their first arg");
3578*9880d681SAndroid Build Coastguard Worker     // Verify that the shift amount VT is bit enough to hold valid shift
3579*9880d681SAndroid Build Coastguard Worker     // amounts.  This catches things like trying to shift an i1024 value by an
3580*9880d681SAndroid Build Coastguard Worker     // i8, which is easy to fall into in generic code that uses
3581*9880d681SAndroid Build Coastguard Worker     // TLI.getShiftAmount().
3582*9880d681SAndroid Build Coastguard Worker     assert(N2.getValueType().getSizeInBits() >=
3583*9880d681SAndroid Build Coastguard Worker                    Log2_32_Ceil(N1.getValueType().getSizeInBits()) &&
3584*9880d681SAndroid Build Coastguard Worker            "Invalid use of small shift amount with oversized value!");
3585*9880d681SAndroid Build Coastguard Worker 
3586*9880d681SAndroid Build Coastguard Worker     // Always fold shifts of i1 values so the code generator doesn't need to
3587*9880d681SAndroid Build Coastguard Worker     // handle them.  Since we know the size of the shift has to be less than the
3588*9880d681SAndroid Build Coastguard Worker     // size of the value, the shift/rotate count is guaranteed to be zero.
3589*9880d681SAndroid Build Coastguard Worker     if (VT == MVT::i1)
3590*9880d681SAndroid Build Coastguard Worker       return N1;
3591*9880d681SAndroid Build Coastguard Worker     if (N2C && N2C->isNullValue())
3592*9880d681SAndroid Build Coastguard Worker       return N1;
3593*9880d681SAndroid Build Coastguard Worker     break;
3594*9880d681SAndroid Build Coastguard Worker   case ISD::FP_ROUND_INREG: {
3595*9880d681SAndroid Build Coastguard Worker     EVT EVT = cast<VTSDNode>(N2)->getVT();
3596*9880d681SAndroid Build Coastguard Worker     assert(VT == N1.getValueType() && "Not an inreg round!");
3597*9880d681SAndroid Build Coastguard Worker     assert(VT.isFloatingPoint() && EVT.isFloatingPoint() &&
3598*9880d681SAndroid Build Coastguard Worker            "Cannot FP_ROUND_INREG integer types");
3599*9880d681SAndroid Build Coastguard Worker     assert(EVT.isVector() == VT.isVector() &&
3600*9880d681SAndroid Build Coastguard Worker            "FP_ROUND_INREG type should be vector iff the operand "
3601*9880d681SAndroid Build Coastguard Worker            "type is vector!");
3602*9880d681SAndroid Build Coastguard Worker     assert((!EVT.isVector() ||
3603*9880d681SAndroid Build Coastguard Worker             EVT.getVectorNumElements() == VT.getVectorNumElements()) &&
3604*9880d681SAndroid Build Coastguard Worker            "Vector element counts must match in FP_ROUND_INREG");
3605*9880d681SAndroid Build Coastguard Worker     assert(EVT.bitsLE(VT) && "Not rounding down!");
3606*9880d681SAndroid Build Coastguard Worker     (void)EVT;
3607*9880d681SAndroid Build Coastguard Worker     if (cast<VTSDNode>(N2)->getVT() == VT) return N1;  // Not actually rounding.
3608*9880d681SAndroid Build Coastguard Worker     break;
3609*9880d681SAndroid Build Coastguard Worker   }
3610*9880d681SAndroid Build Coastguard Worker   case ISD::FP_ROUND:
3611*9880d681SAndroid Build Coastguard Worker     assert(VT.isFloatingPoint() &&
3612*9880d681SAndroid Build Coastguard Worker            N1.getValueType().isFloatingPoint() &&
3613*9880d681SAndroid Build Coastguard Worker            VT.bitsLE(N1.getValueType()) &&
3614*9880d681SAndroid Build Coastguard Worker            N2C && "Invalid FP_ROUND!");
3615*9880d681SAndroid Build Coastguard Worker     if (N1.getValueType() == VT) return N1;  // noop conversion.
3616*9880d681SAndroid Build Coastguard Worker     break;
3617*9880d681SAndroid Build Coastguard Worker   case ISD::AssertSext:
3618*9880d681SAndroid Build Coastguard Worker   case ISD::AssertZext: {
3619*9880d681SAndroid Build Coastguard Worker     EVT EVT = cast<VTSDNode>(N2)->getVT();
3620*9880d681SAndroid Build Coastguard Worker     assert(VT == N1.getValueType() && "Not an inreg extend!");
3621*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && EVT.isInteger() &&
3622*9880d681SAndroid Build Coastguard Worker            "Cannot *_EXTEND_INREG FP types");
3623*9880d681SAndroid Build Coastguard Worker     assert(!EVT.isVector() &&
3624*9880d681SAndroid Build Coastguard Worker            "AssertSExt/AssertZExt type should be the vector element type "
3625*9880d681SAndroid Build Coastguard Worker            "rather than the vector type!");
3626*9880d681SAndroid Build Coastguard Worker     assert(EVT.bitsLE(VT) && "Not extending!");
3627*9880d681SAndroid Build Coastguard Worker     if (VT == EVT) return N1; // noop assertion.
3628*9880d681SAndroid Build Coastguard Worker     break;
3629*9880d681SAndroid Build Coastguard Worker   }
3630*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND_INREG: {
3631*9880d681SAndroid Build Coastguard Worker     EVT EVT = cast<VTSDNode>(N2)->getVT();
3632*9880d681SAndroid Build Coastguard Worker     assert(VT == N1.getValueType() && "Not an inreg extend!");
3633*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() && EVT.isInteger() &&
3634*9880d681SAndroid Build Coastguard Worker            "Cannot *_EXTEND_INREG FP types");
3635*9880d681SAndroid Build Coastguard Worker     assert(EVT.isVector() == VT.isVector() &&
3636*9880d681SAndroid Build Coastguard Worker            "SIGN_EXTEND_INREG type should be vector iff the operand "
3637*9880d681SAndroid Build Coastguard Worker            "type is vector!");
3638*9880d681SAndroid Build Coastguard Worker     assert((!EVT.isVector() ||
3639*9880d681SAndroid Build Coastguard Worker             EVT.getVectorNumElements() == VT.getVectorNumElements()) &&
3640*9880d681SAndroid Build Coastguard Worker            "Vector element counts must match in SIGN_EXTEND_INREG");
3641*9880d681SAndroid Build Coastguard Worker     assert(EVT.bitsLE(VT) && "Not extending!");
3642*9880d681SAndroid Build Coastguard Worker     if (EVT == VT) return N1;  // Not actually extending
3643*9880d681SAndroid Build Coastguard Worker 
3644*9880d681SAndroid Build Coastguard Worker     auto SignExtendInReg = [&](APInt Val) {
3645*9880d681SAndroid Build Coastguard Worker       unsigned FromBits = EVT.getScalarType().getSizeInBits();
3646*9880d681SAndroid Build Coastguard Worker       Val <<= Val.getBitWidth() - FromBits;
3647*9880d681SAndroid Build Coastguard Worker       Val = Val.ashr(Val.getBitWidth() - FromBits);
3648*9880d681SAndroid Build Coastguard Worker       return getConstant(Val, DL, VT.getScalarType());
3649*9880d681SAndroid Build Coastguard Worker     };
3650*9880d681SAndroid Build Coastguard Worker 
3651*9880d681SAndroid Build Coastguard Worker     if (N1C) {
3652*9880d681SAndroid Build Coastguard Worker       const APInt &Val = N1C->getAPIntValue();
3653*9880d681SAndroid Build Coastguard Worker       return SignExtendInReg(Val);
3654*9880d681SAndroid Build Coastguard Worker     }
3655*9880d681SAndroid Build Coastguard Worker     if (ISD::isBuildVectorOfConstantSDNodes(N1.getNode())) {
3656*9880d681SAndroid Build Coastguard Worker       SmallVector<SDValue, 8> Ops;
3657*9880d681SAndroid Build Coastguard Worker       for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
3658*9880d681SAndroid Build Coastguard Worker         SDValue Op = N1.getOperand(i);
3659*9880d681SAndroid Build Coastguard Worker         if (Op.isUndef()) {
3660*9880d681SAndroid Build Coastguard Worker           Ops.push_back(getUNDEF(VT.getScalarType()));
3661*9880d681SAndroid Build Coastguard Worker           continue;
3662*9880d681SAndroid Build Coastguard Worker         }
3663*9880d681SAndroid Build Coastguard Worker         if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
3664*9880d681SAndroid Build Coastguard Worker           APInt Val = C->getAPIntValue();
3665*9880d681SAndroid Build Coastguard Worker           Val = Val.zextOrTrunc(VT.getScalarSizeInBits());
3666*9880d681SAndroid Build Coastguard Worker           Ops.push_back(SignExtendInReg(Val));
3667*9880d681SAndroid Build Coastguard Worker           continue;
3668*9880d681SAndroid Build Coastguard Worker         }
3669*9880d681SAndroid Build Coastguard Worker         break;
3670*9880d681SAndroid Build Coastguard Worker       }
3671*9880d681SAndroid Build Coastguard Worker       if (Ops.size() == VT.getVectorNumElements())
3672*9880d681SAndroid Build Coastguard Worker         return getBuildVector(VT, DL, Ops);
3673*9880d681SAndroid Build Coastguard Worker     }
3674*9880d681SAndroid Build Coastguard Worker     break;
3675*9880d681SAndroid Build Coastguard Worker   }
3676*9880d681SAndroid Build Coastguard Worker   case ISD::EXTRACT_VECTOR_ELT:
3677*9880d681SAndroid Build Coastguard Worker     // EXTRACT_VECTOR_ELT of an UNDEF is an UNDEF.
3678*9880d681SAndroid Build Coastguard Worker     if (N1.isUndef())
3679*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3680*9880d681SAndroid Build Coastguard Worker 
3681*9880d681SAndroid Build Coastguard Worker     // EXTRACT_VECTOR_ELT of out-of-bounds element is an UNDEF
3682*9880d681SAndroid Build Coastguard Worker     if (N2C && N2C->getZExtValue() >= N1.getValueType().getVectorNumElements())
3683*9880d681SAndroid Build Coastguard Worker       return getUNDEF(VT);
3684*9880d681SAndroid Build Coastguard Worker 
3685*9880d681SAndroid Build Coastguard Worker     // EXTRACT_VECTOR_ELT of CONCAT_VECTORS is often formed while lowering is
3686*9880d681SAndroid Build Coastguard Worker     // expanding copies of large vectors from registers.
3687*9880d681SAndroid Build Coastguard Worker     if (N2C &&
3688*9880d681SAndroid Build Coastguard Worker         N1.getOpcode() == ISD::CONCAT_VECTORS &&
3689*9880d681SAndroid Build Coastguard Worker         N1.getNumOperands() > 0) {
3690*9880d681SAndroid Build Coastguard Worker       unsigned Factor =
3691*9880d681SAndroid Build Coastguard Worker         N1.getOperand(0).getValueType().getVectorNumElements();
3692*9880d681SAndroid Build Coastguard Worker       return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT,
3693*9880d681SAndroid Build Coastguard Worker                      N1.getOperand(N2C->getZExtValue() / Factor),
3694*9880d681SAndroid Build Coastguard Worker                      getConstant(N2C->getZExtValue() % Factor, DL,
3695*9880d681SAndroid Build Coastguard Worker                                  N2.getValueType()));
3696*9880d681SAndroid Build Coastguard Worker     }
3697*9880d681SAndroid Build Coastguard Worker 
3698*9880d681SAndroid Build Coastguard Worker     // EXTRACT_VECTOR_ELT of BUILD_VECTOR is often formed while lowering is
3699*9880d681SAndroid Build Coastguard Worker     // expanding large vector constants.
3700*9880d681SAndroid Build Coastguard Worker     if (N2C && N1.getOpcode() == ISD::BUILD_VECTOR) {
3701*9880d681SAndroid Build Coastguard Worker       SDValue Elt = N1.getOperand(N2C->getZExtValue());
3702*9880d681SAndroid Build Coastguard Worker 
3703*9880d681SAndroid Build Coastguard Worker       if (VT != Elt.getValueType())
3704*9880d681SAndroid Build Coastguard Worker         // If the vector element type is not legal, the BUILD_VECTOR operands
3705*9880d681SAndroid Build Coastguard Worker         // are promoted and implicitly truncated, and the result implicitly
3706*9880d681SAndroid Build Coastguard Worker         // extended. Make that explicit here.
3707*9880d681SAndroid Build Coastguard Worker         Elt = getAnyExtOrTrunc(Elt, DL, VT);
3708*9880d681SAndroid Build Coastguard Worker 
3709*9880d681SAndroid Build Coastguard Worker       return Elt;
3710*9880d681SAndroid Build Coastguard Worker     }
3711*9880d681SAndroid Build Coastguard Worker 
3712*9880d681SAndroid Build Coastguard Worker     // EXTRACT_VECTOR_ELT of INSERT_VECTOR_ELT is often formed when vector
3713*9880d681SAndroid Build Coastguard Worker     // operations are lowered to scalars.
3714*9880d681SAndroid Build Coastguard Worker     if (N1.getOpcode() == ISD::INSERT_VECTOR_ELT) {
3715*9880d681SAndroid Build Coastguard Worker       // If the indices are the same, return the inserted element else
3716*9880d681SAndroid Build Coastguard Worker       // if the indices are known different, extract the element from
3717*9880d681SAndroid Build Coastguard Worker       // the original vector.
3718*9880d681SAndroid Build Coastguard Worker       SDValue N1Op2 = N1.getOperand(2);
3719*9880d681SAndroid Build Coastguard Worker       ConstantSDNode *N1Op2C = dyn_cast<ConstantSDNode>(N1Op2);
3720*9880d681SAndroid Build Coastguard Worker 
3721*9880d681SAndroid Build Coastguard Worker       if (N1Op2C && N2C) {
3722*9880d681SAndroid Build Coastguard Worker         if (N1Op2C->getZExtValue() == N2C->getZExtValue()) {
3723*9880d681SAndroid Build Coastguard Worker           if (VT == N1.getOperand(1).getValueType())
3724*9880d681SAndroid Build Coastguard Worker             return N1.getOperand(1);
3725*9880d681SAndroid Build Coastguard Worker           else
3726*9880d681SAndroid Build Coastguard Worker             return getSExtOrTrunc(N1.getOperand(1), DL, VT);
3727*9880d681SAndroid Build Coastguard Worker         }
3728*9880d681SAndroid Build Coastguard Worker 
3729*9880d681SAndroid Build Coastguard Worker         return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(0), N2);
3730*9880d681SAndroid Build Coastguard Worker       }
3731*9880d681SAndroid Build Coastguard Worker     }
3732*9880d681SAndroid Build Coastguard Worker     break;
3733*9880d681SAndroid Build Coastguard Worker   case ISD::EXTRACT_ELEMENT:
3734*9880d681SAndroid Build Coastguard Worker     assert(N2C && (unsigned)N2C->getZExtValue() < 2 && "Bad EXTRACT_ELEMENT!");
3735*9880d681SAndroid Build Coastguard Worker     assert(!N1.getValueType().isVector() && !VT.isVector() &&
3736*9880d681SAndroid Build Coastguard Worker            (N1.getValueType().isInteger() == VT.isInteger()) &&
3737*9880d681SAndroid Build Coastguard Worker            N1.getValueType() != VT &&
3738*9880d681SAndroid Build Coastguard Worker            "Wrong types for EXTRACT_ELEMENT!");
3739*9880d681SAndroid Build Coastguard Worker 
3740*9880d681SAndroid Build Coastguard Worker     // EXTRACT_ELEMENT of BUILD_PAIR is often formed while legalize is expanding
3741*9880d681SAndroid Build Coastguard Worker     // 64-bit integers into 32-bit parts.  Instead of building the extract of
3742*9880d681SAndroid Build Coastguard Worker     // the BUILD_PAIR, only to have legalize rip it apart, just do it now.
3743*9880d681SAndroid Build Coastguard Worker     if (N1.getOpcode() == ISD::BUILD_PAIR)
3744*9880d681SAndroid Build Coastguard Worker       return N1.getOperand(N2C->getZExtValue());
3745*9880d681SAndroid Build Coastguard Worker 
3746*9880d681SAndroid Build Coastguard Worker     // EXTRACT_ELEMENT of a constant int is also very common.
3747*9880d681SAndroid Build Coastguard Worker     if (N1C) {
3748*9880d681SAndroid Build Coastguard Worker       unsigned ElementSize = VT.getSizeInBits();
3749*9880d681SAndroid Build Coastguard Worker       unsigned Shift = ElementSize * N2C->getZExtValue();
3750*9880d681SAndroid Build Coastguard Worker       APInt ShiftedVal = N1C->getAPIntValue().lshr(Shift);
3751*9880d681SAndroid Build Coastguard Worker       return getConstant(ShiftedVal.trunc(ElementSize), DL, VT);
3752*9880d681SAndroid Build Coastguard Worker     }
3753*9880d681SAndroid Build Coastguard Worker     break;
3754*9880d681SAndroid Build Coastguard Worker   case ISD::EXTRACT_SUBVECTOR:
3755*9880d681SAndroid Build Coastguard Worker     if (VT.isSimple() && N1.getValueType().isSimple()) {
3756*9880d681SAndroid Build Coastguard Worker       assert(VT.isVector() && N1.getValueType().isVector() &&
3757*9880d681SAndroid Build Coastguard Worker              "Extract subvector VTs must be a vectors!");
3758*9880d681SAndroid Build Coastguard Worker       assert(VT.getVectorElementType() ==
3759*9880d681SAndroid Build Coastguard Worker              N1.getValueType().getVectorElementType() &&
3760*9880d681SAndroid Build Coastguard Worker              "Extract subvector VTs must have the same element type!");
3761*9880d681SAndroid Build Coastguard Worker       assert(VT.getSimpleVT() <= N1.getSimpleValueType() &&
3762*9880d681SAndroid Build Coastguard Worker              "Extract subvector must be from larger vector to smaller vector!");
3763*9880d681SAndroid Build Coastguard Worker 
3764*9880d681SAndroid Build Coastguard Worker       if (N2C) {
3765*9880d681SAndroid Build Coastguard Worker         assert((VT.getVectorNumElements() + N2C->getZExtValue()
3766*9880d681SAndroid Build Coastguard Worker                 <= N1.getValueType().getVectorNumElements())
3767*9880d681SAndroid Build Coastguard Worker                && "Extract subvector overflow!");
3768*9880d681SAndroid Build Coastguard Worker       }
3769*9880d681SAndroid Build Coastguard Worker 
3770*9880d681SAndroid Build Coastguard Worker       // Trivial extraction.
3771*9880d681SAndroid Build Coastguard Worker       if (VT.getSimpleVT() == N1.getSimpleValueType())
3772*9880d681SAndroid Build Coastguard Worker         return N1;
3773*9880d681SAndroid Build Coastguard Worker     }
3774*9880d681SAndroid Build Coastguard Worker     break;
3775*9880d681SAndroid Build Coastguard Worker   }
3776*9880d681SAndroid Build Coastguard Worker 
3777*9880d681SAndroid Build Coastguard Worker   // Perform trivial constant folding.
3778*9880d681SAndroid Build Coastguard Worker   if (SDValue SV =
3779*9880d681SAndroid Build Coastguard Worker           FoldConstantArithmetic(Opcode, DL, VT, N1.getNode(), N2.getNode()))
3780*9880d681SAndroid Build Coastguard Worker     return SV;
3781*9880d681SAndroid Build Coastguard Worker 
3782*9880d681SAndroid Build Coastguard Worker   // Constant fold FP operations.
3783*9880d681SAndroid Build Coastguard Worker   bool HasFPExceptions = TLI->hasFloatingPointExceptions();
3784*9880d681SAndroid Build Coastguard Worker   if (N1CFP) {
3785*9880d681SAndroid Build Coastguard Worker     if (N2CFP) {
3786*9880d681SAndroid Build Coastguard Worker       APFloat V1 = N1CFP->getValueAPF(), V2 = N2CFP->getValueAPF();
3787*9880d681SAndroid Build Coastguard Worker       APFloat::opStatus s;
3788*9880d681SAndroid Build Coastguard Worker       switch (Opcode) {
3789*9880d681SAndroid Build Coastguard Worker       case ISD::FADD:
3790*9880d681SAndroid Build Coastguard Worker         s = V1.add(V2, APFloat::rmNearestTiesToEven);
3791*9880d681SAndroid Build Coastguard Worker         if (!HasFPExceptions || s != APFloat::opInvalidOp)
3792*9880d681SAndroid Build Coastguard Worker           return getConstantFP(V1, DL, VT);
3793*9880d681SAndroid Build Coastguard Worker         break;
3794*9880d681SAndroid Build Coastguard Worker       case ISD::FSUB:
3795*9880d681SAndroid Build Coastguard Worker         s = V1.subtract(V2, APFloat::rmNearestTiesToEven);
3796*9880d681SAndroid Build Coastguard Worker         if (!HasFPExceptions || s!=APFloat::opInvalidOp)
3797*9880d681SAndroid Build Coastguard Worker           return getConstantFP(V1, DL, VT);
3798*9880d681SAndroid Build Coastguard Worker         break;
3799*9880d681SAndroid Build Coastguard Worker       case ISD::FMUL:
3800*9880d681SAndroid Build Coastguard Worker         s = V1.multiply(V2, APFloat::rmNearestTiesToEven);
3801*9880d681SAndroid Build Coastguard Worker         if (!HasFPExceptions || s!=APFloat::opInvalidOp)
3802*9880d681SAndroid Build Coastguard Worker           return getConstantFP(V1, DL, VT);
3803*9880d681SAndroid Build Coastguard Worker         break;
3804*9880d681SAndroid Build Coastguard Worker       case ISD::FDIV:
3805*9880d681SAndroid Build Coastguard Worker         s = V1.divide(V2, APFloat::rmNearestTiesToEven);
3806*9880d681SAndroid Build Coastguard Worker         if (!HasFPExceptions || (s!=APFloat::opInvalidOp &&
3807*9880d681SAndroid Build Coastguard Worker                                  s!=APFloat::opDivByZero)) {
3808*9880d681SAndroid Build Coastguard Worker           return getConstantFP(V1, DL, VT);
3809*9880d681SAndroid Build Coastguard Worker         }
3810*9880d681SAndroid Build Coastguard Worker         break;
3811*9880d681SAndroid Build Coastguard Worker       case ISD::FREM :
3812*9880d681SAndroid Build Coastguard Worker         s = V1.mod(V2);
3813*9880d681SAndroid Build Coastguard Worker         if (!HasFPExceptions || (s!=APFloat::opInvalidOp &&
3814*9880d681SAndroid Build Coastguard Worker                                  s!=APFloat::opDivByZero)) {
3815*9880d681SAndroid Build Coastguard Worker           return getConstantFP(V1, DL, VT);
3816*9880d681SAndroid Build Coastguard Worker         }
3817*9880d681SAndroid Build Coastguard Worker         break;
3818*9880d681SAndroid Build Coastguard Worker       case ISD::FCOPYSIGN:
3819*9880d681SAndroid Build Coastguard Worker         V1.copySign(V2);
3820*9880d681SAndroid Build Coastguard Worker         return getConstantFP(V1, DL, VT);
3821*9880d681SAndroid Build Coastguard Worker       default: break;
3822*9880d681SAndroid Build Coastguard Worker       }
3823*9880d681SAndroid Build Coastguard Worker     }
3824*9880d681SAndroid Build Coastguard Worker 
3825*9880d681SAndroid Build Coastguard Worker     if (Opcode == ISD::FP_ROUND) {
3826*9880d681SAndroid Build Coastguard Worker       APFloat V = N1CFP->getValueAPF();    // make copy
3827*9880d681SAndroid Build Coastguard Worker       bool ignored;
3828*9880d681SAndroid Build Coastguard Worker       // This can return overflow, underflow, or inexact; we don't care.
3829*9880d681SAndroid Build Coastguard Worker       // FIXME need to be more flexible about rounding mode.
3830*9880d681SAndroid Build Coastguard Worker       (void)V.convert(EVTToAPFloatSemantics(VT),
3831*9880d681SAndroid Build Coastguard Worker                       APFloat::rmNearestTiesToEven, &ignored);
3832*9880d681SAndroid Build Coastguard Worker       return getConstantFP(V, DL, VT);
3833*9880d681SAndroid Build Coastguard Worker     }
3834*9880d681SAndroid Build Coastguard Worker   }
3835*9880d681SAndroid Build Coastguard Worker 
3836*9880d681SAndroid Build Coastguard Worker   // Canonicalize an UNDEF to the RHS, even over a constant.
3837*9880d681SAndroid Build Coastguard Worker   if (N1.isUndef()) {
3838*9880d681SAndroid Build Coastguard Worker     if (isCommutativeBinOp(Opcode)) {
3839*9880d681SAndroid Build Coastguard Worker       std::swap(N1, N2);
3840*9880d681SAndroid Build Coastguard Worker     } else {
3841*9880d681SAndroid Build Coastguard Worker       switch (Opcode) {
3842*9880d681SAndroid Build Coastguard Worker       case ISD::FP_ROUND_INREG:
3843*9880d681SAndroid Build Coastguard Worker       case ISD::SIGN_EXTEND_INREG:
3844*9880d681SAndroid Build Coastguard Worker       case ISD::SUB:
3845*9880d681SAndroid Build Coastguard Worker       case ISD::FSUB:
3846*9880d681SAndroid Build Coastguard Worker       case ISD::FDIV:
3847*9880d681SAndroid Build Coastguard Worker       case ISD::FREM:
3848*9880d681SAndroid Build Coastguard Worker       case ISD::SRA:
3849*9880d681SAndroid Build Coastguard Worker         return N1;     // fold op(undef, arg2) -> undef
3850*9880d681SAndroid Build Coastguard Worker       case ISD::UDIV:
3851*9880d681SAndroid Build Coastguard Worker       case ISD::SDIV:
3852*9880d681SAndroid Build Coastguard Worker       case ISD::UREM:
3853*9880d681SAndroid Build Coastguard Worker       case ISD::SREM:
3854*9880d681SAndroid Build Coastguard Worker       case ISD::SRL:
3855*9880d681SAndroid Build Coastguard Worker       case ISD::SHL:
3856*9880d681SAndroid Build Coastguard Worker         if (!VT.isVector())
3857*9880d681SAndroid Build Coastguard Worker           return getConstant(0, DL, VT);    // fold op(undef, arg2) -> 0
3858*9880d681SAndroid Build Coastguard Worker         // For vectors, we can't easily build an all zero vector, just return
3859*9880d681SAndroid Build Coastguard Worker         // the LHS.
3860*9880d681SAndroid Build Coastguard Worker         return N2;
3861*9880d681SAndroid Build Coastguard Worker       }
3862*9880d681SAndroid Build Coastguard Worker     }
3863*9880d681SAndroid Build Coastguard Worker   }
3864*9880d681SAndroid Build Coastguard Worker 
3865*9880d681SAndroid Build Coastguard Worker   // Fold a bunch of operators when the RHS is undef.
3866*9880d681SAndroid Build Coastguard Worker   if (N2.isUndef()) {
3867*9880d681SAndroid Build Coastguard Worker     switch (Opcode) {
3868*9880d681SAndroid Build Coastguard Worker     case ISD::XOR:
3869*9880d681SAndroid Build Coastguard Worker       if (N1.isUndef())
3870*9880d681SAndroid Build Coastguard Worker         // Handle undef ^ undef -> 0 special case. This is a common
3871*9880d681SAndroid Build Coastguard Worker         // idiom (misuse).
3872*9880d681SAndroid Build Coastguard Worker         return getConstant(0, DL, VT);
3873*9880d681SAndroid Build Coastguard Worker       // fallthrough
3874*9880d681SAndroid Build Coastguard Worker     case ISD::ADD:
3875*9880d681SAndroid Build Coastguard Worker     case ISD::ADDC:
3876*9880d681SAndroid Build Coastguard Worker     case ISD::ADDE:
3877*9880d681SAndroid Build Coastguard Worker     case ISD::SUB:
3878*9880d681SAndroid Build Coastguard Worker     case ISD::UDIV:
3879*9880d681SAndroid Build Coastguard Worker     case ISD::SDIV:
3880*9880d681SAndroid Build Coastguard Worker     case ISD::UREM:
3881*9880d681SAndroid Build Coastguard Worker     case ISD::SREM:
3882*9880d681SAndroid Build Coastguard Worker       return N2;       // fold op(arg1, undef) -> undef
3883*9880d681SAndroid Build Coastguard Worker     case ISD::FADD:
3884*9880d681SAndroid Build Coastguard Worker     case ISD::FSUB:
3885*9880d681SAndroid Build Coastguard Worker     case ISD::FMUL:
3886*9880d681SAndroid Build Coastguard Worker     case ISD::FDIV:
3887*9880d681SAndroid Build Coastguard Worker     case ISD::FREM:
3888*9880d681SAndroid Build Coastguard Worker       if (getTarget().Options.UnsafeFPMath)
3889*9880d681SAndroid Build Coastguard Worker         return N2;
3890*9880d681SAndroid Build Coastguard Worker       break;
3891*9880d681SAndroid Build Coastguard Worker     case ISD::MUL:
3892*9880d681SAndroid Build Coastguard Worker     case ISD::AND:
3893*9880d681SAndroid Build Coastguard Worker     case ISD::SRL:
3894*9880d681SAndroid Build Coastguard Worker     case ISD::SHL:
3895*9880d681SAndroid Build Coastguard Worker       if (!VT.isVector())
3896*9880d681SAndroid Build Coastguard Worker         return getConstant(0, DL, VT);  // fold op(arg1, undef) -> 0
3897*9880d681SAndroid Build Coastguard Worker       // For vectors, we can't easily build an all zero vector, just return
3898*9880d681SAndroid Build Coastguard Worker       // the LHS.
3899*9880d681SAndroid Build Coastguard Worker       return N1;
3900*9880d681SAndroid Build Coastguard Worker     case ISD::OR:
3901*9880d681SAndroid Build Coastguard Worker       if (!VT.isVector())
3902*9880d681SAndroid Build Coastguard Worker         return getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), DL, VT);
3903*9880d681SAndroid Build Coastguard Worker       // For vectors, we can't easily build an all one vector, just return
3904*9880d681SAndroid Build Coastguard Worker       // the LHS.
3905*9880d681SAndroid Build Coastguard Worker       return N1;
3906*9880d681SAndroid Build Coastguard Worker     case ISD::SRA:
3907*9880d681SAndroid Build Coastguard Worker       return N1;
3908*9880d681SAndroid Build Coastguard Worker     }
3909*9880d681SAndroid Build Coastguard Worker   }
3910*9880d681SAndroid Build Coastguard Worker 
3911*9880d681SAndroid Build Coastguard Worker   // Memoize this node if possible.
3912*9880d681SAndroid Build Coastguard Worker   SDNode *N;
3913*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
3914*9880d681SAndroid Build Coastguard Worker   if (VT != MVT::Glue) {
3915*9880d681SAndroid Build Coastguard Worker     SDValue Ops[] = {N1, N2};
3916*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
3917*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opcode, VTs, Ops);
3918*9880d681SAndroid Build Coastguard Worker     void *IP = nullptr;
3919*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
3920*9880d681SAndroid Build Coastguard Worker       if (Flags)
3921*9880d681SAndroid Build Coastguard Worker         E->intersectFlagsWith(Flags);
3922*9880d681SAndroid Build Coastguard Worker       return SDValue(E, 0);
3923*9880d681SAndroid Build Coastguard Worker     }
3924*9880d681SAndroid Build Coastguard Worker 
3925*9880d681SAndroid Build Coastguard Worker     N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, Flags);
3926*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
3927*9880d681SAndroid Build Coastguard Worker   } else {
3928*9880d681SAndroid Build Coastguard Worker     N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, Flags);
3929*9880d681SAndroid Build Coastguard Worker   }
3930*9880d681SAndroid Build Coastguard Worker 
3931*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
3932*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
3933*9880d681SAndroid Build Coastguard Worker }
3934*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,EVT VT,SDValue N1,SDValue N2,SDValue N3)3935*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
3936*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2, SDValue N3) {
3937*9880d681SAndroid Build Coastguard Worker   // Perform various simplifications.
3938*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
3939*9880d681SAndroid Build Coastguard Worker   case ISD::FMA: {
3940*9880d681SAndroid Build Coastguard Worker     ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
3941*9880d681SAndroid Build Coastguard Worker     ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2);
3942*9880d681SAndroid Build Coastguard Worker     ConstantFPSDNode *N3CFP = dyn_cast<ConstantFPSDNode>(N3);
3943*9880d681SAndroid Build Coastguard Worker     if (N1CFP && N2CFP && N3CFP) {
3944*9880d681SAndroid Build Coastguard Worker       APFloat  V1 = N1CFP->getValueAPF();
3945*9880d681SAndroid Build Coastguard Worker       const APFloat &V2 = N2CFP->getValueAPF();
3946*9880d681SAndroid Build Coastguard Worker       const APFloat &V3 = N3CFP->getValueAPF();
3947*9880d681SAndroid Build Coastguard Worker       APFloat::opStatus s =
3948*9880d681SAndroid Build Coastguard Worker         V1.fusedMultiplyAdd(V2, V3, APFloat::rmNearestTiesToEven);
3949*9880d681SAndroid Build Coastguard Worker       if (!TLI->hasFloatingPointExceptions() || s != APFloat::opInvalidOp)
3950*9880d681SAndroid Build Coastguard Worker         return getConstantFP(V1, DL, VT);
3951*9880d681SAndroid Build Coastguard Worker     }
3952*9880d681SAndroid Build Coastguard Worker     break;
3953*9880d681SAndroid Build Coastguard Worker   }
3954*9880d681SAndroid Build Coastguard Worker   case ISD::CONCAT_VECTORS: {
3955*9880d681SAndroid Build Coastguard Worker     // Attempt to fold CONCAT_VECTORS into BUILD_VECTOR or UNDEF.
3956*9880d681SAndroid Build Coastguard Worker     SDValue Ops[] = {N1, N2, N3};
3957*9880d681SAndroid Build Coastguard Worker     if (SDValue V = FoldCONCAT_VECTORS(DL, VT, Ops, *this))
3958*9880d681SAndroid Build Coastguard Worker       return V;
3959*9880d681SAndroid Build Coastguard Worker     break;
3960*9880d681SAndroid Build Coastguard Worker   }
3961*9880d681SAndroid Build Coastguard Worker   case ISD::SETCC: {
3962*9880d681SAndroid Build Coastguard Worker     // Use FoldSetCC to simplify SETCC's.
3963*9880d681SAndroid Build Coastguard Worker     if (SDValue V = FoldSetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get(), DL))
3964*9880d681SAndroid Build Coastguard Worker       return V;
3965*9880d681SAndroid Build Coastguard Worker     // Vector constant folding.
3966*9880d681SAndroid Build Coastguard Worker     SDValue Ops[] = {N1, N2, N3};
3967*9880d681SAndroid Build Coastguard Worker     if (SDValue V = FoldConstantVectorArithmetic(Opcode, DL, VT, Ops))
3968*9880d681SAndroid Build Coastguard Worker       return V;
3969*9880d681SAndroid Build Coastguard Worker     break;
3970*9880d681SAndroid Build Coastguard Worker   }
3971*9880d681SAndroid Build Coastguard Worker   case ISD::SELECT:
3972*9880d681SAndroid Build Coastguard Worker     if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1)) {
3973*9880d681SAndroid Build Coastguard Worker      if (N1C->getZExtValue())
3974*9880d681SAndroid Build Coastguard Worker        return N2;             // select true, X, Y -> X
3975*9880d681SAndroid Build Coastguard Worker      return N3;             // select false, X, Y -> Y
3976*9880d681SAndroid Build Coastguard Worker     }
3977*9880d681SAndroid Build Coastguard Worker 
3978*9880d681SAndroid Build Coastguard Worker     if (N2 == N3) return N2;   // select C, X, X -> X
3979*9880d681SAndroid Build Coastguard Worker     break;
3980*9880d681SAndroid Build Coastguard Worker   case ISD::VECTOR_SHUFFLE:
3981*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("should use getVectorShuffle constructor!");
3982*9880d681SAndroid Build Coastguard Worker   case ISD::INSERT_SUBVECTOR: {
3983*9880d681SAndroid Build Coastguard Worker     SDValue Index = N3;
3984*9880d681SAndroid Build Coastguard Worker     if (VT.isSimple() && N1.getValueType().isSimple()
3985*9880d681SAndroid Build Coastguard Worker         && N2.getValueType().isSimple()) {
3986*9880d681SAndroid Build Coastguard Worker       assert(VT.isVector() && N1.getValueType().isVector() &&
3987*9880d681SAndroid Build Coastguard Worker              N2.getValueType().isVector() &&
3988*9880d681SAndroid Build Coastguard Worker              "Insert subvector VTs must be a vectors");
3989*9880d681SAndroid Build Coastguard Worker       assert(VT == N1.getValueType() &&
3990*9880d681SAndroid Build Coastguard Worker              "Dest and insert subvector source types must match!");
3991*9880d681SAndroid Build Coastguard Worker       assert(N2.getSimpleValueType() <= N1.getSimpleValueType() &&
3992*9880d681SAndroid Build Coastguard Worker              "Insert subvector must be from smaller vector to larger vector!");
3993*9880d681SAndroid Build Coastguard Worker       if (isa<ConstantSDNode>(Index)) {
3994*9880d681SAndroid Build Coastguard Worker         assert((N2.getValueType().getVectorNumElements() +
3995*9880d681SAndroid Build Coastguard Worker                 cast<ConstantSDNode>(Index)->getZExtValue()
3996*9880d681SAndroid Build Coastguard Worker                 <= VT.getVectorNumElements())
3997*9880d681SAndroid Build Coastguard Worker                && "Insert subvector overflow!");
3998*9880d681SAndroid Build Coastguard Worker       }
3999*9880d681SAndroid Build Coastguard Worker 
4000*9880d681SAndroid Build Coastguard Worker       // Trivial insertion.
4001*9880d681SAndroid Build Coastguard Worker       if (VT.getSimpleVT() == N2.getSimpleValueType())
4002*9880d681SAndroid Build Coastguard Worker         return N2;
4003*9880d681SAndroid Build Coastguard Worker     }
4004*9880d681SAndroid Build Coastguard Worker     break;
4005*9880d681SAndroid Build Coastguard Worker   }
4006*9880d681SAndroid Build Coastguard Worker   case ISD::BITCAST:
4007*9880d681SAndroid Build Coastguard Worker     // Fold bit_convert nodes from a type to themselves.
4008*9880d681SAndroid Build Coastguard Worker     if (N1.getValueType() == VT)
4009*9880d681SAndroid Build Coastguard Worker       return N1;
4010*9880d681SAndroid Build Coastguard Worker     break;
4011*9880d681SAndroid Build Coastguard Worker   }
4012*9880d681SAndroid Build Coastguard Worker 
4013*9880d681SAndroid Build Coastguard Worker   // Memoize node if it doesn't produce a flag.
4014*9880d681SAndroid Build Coastguard Worker   SDNode *N;
4015*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
4016*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {N1, N2, N3};
4017*9880d681SAndroid Build Coastguard Worker   if (VT != MVT::Glue) {
4018*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
4019*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opcode, VTs, Ops);
4020*9880d681SAndroid Build Coastguard Worker     void *IP = nullptr;
4021*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
4022*9880d681SAndroid Build Coastguard Worker       return SDValue(E, 0);
4023*9880d681SAndroid Build Coastguard Worker 
4024*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
4025*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
4026*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
4027*9880d681SAndroid Build Coastguard Worker   } else {
4028*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
4029*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
4030*9880d681SAndroid Build Coastguard Worker   }
4031*9880d681SAndroid Build Coastguard Worker 
4032*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
4033*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
4034*9880d681SAndroid Build Coastguard Worker }
4035*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,EVT VT,SDValue N1,SDValue N2,SDValue N3,SDValue N4)4036*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
4037*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2, SDValue N3, SDValue N4) {
4038*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { N1, N2, N3, N4 };
4039*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VT, Ops);
4040*9880d681SAndroid Build Coastguard Worker }
4041*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,EVT VT,SDValue N1,SDValue N2,SDValue N3,SDValue N4,SDValue N5)4042*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
4043*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2, SDValue N3, SDValue N4,
4044*9880d681SAndroid Build Coastguard Worker                               SDValue N5) {
4045*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { N1, N2, N3, N4, N5 };
4046*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VT, Ops);
4047*9880d681SAndroid Build Coastguard Worker }
4048*9880d681SAndroid Build Coastguard Worker 
4049*9880d681SAndroid Build Coastguard Worker /// getStackArgumentTokenFactor - Compute a TokenFactor to force all
4050*9880d681SAndroid Build Coastguard Worker /// the incoming stack arguments to be loaded from the stack.
getStackArgumentTokenFactor(SDValue Chain)4051*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getStackArgumentTokenFactor(SDValue Chain) {
4052*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> ArgChains;
4053*9880d681SAndroid Build Coastguard Worker 
4054*9880d681SAndroid Build Coastguard Worker   // Include the original chain at the beginning of the list. When this is
4055*9880d681SAndroid Build Coastguard Worker   // used by target LowerCall hooks, this helps legalize find the
4056*9880d681SAndroid Build Coastguard Worker   // CALLSEQ_BEGIN node.
4057*9880d681SAndroid Build Coastguard Worker   ArgChains.push_back(Chain);
4058*9880d681SAndroid Build Coastguard Worker 
4059*9880d681SAndroid Build Coastguard Worker   // Add a chain value for each stack argument.
4060*9880d681SAndroid Build Coastguard Worker   for (SDNode::use_iterator U = getEntryNode().getNode()->use_begin(),
4061*9880d681SAndroid Build Coastguard Worker        UE = getEntryNode().getNode()->use_end(); U != UE; ++U)
4062*9880d681SAndroid Build Coastguard Worker     if (LoadSDNode *L = dyn_cast<LoadSDNode>(*U))
4063*9880d681SAndroid Build Coastguard Worker       if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(L->getBasePtr()))
4064*9880d681SAndroid Build Coastguard Worker         if (FI->getIndex() < 0)
4065*9880d681SAndroid Build Coastguard Worker           ArgChains.push_back(SDValue(L, 1));
4066*9880d681SAndroid Build Coastguard Worker 
4067*9880d681SAndroid Build Coastguard Worker   // Build a tokenfactor for all the chains.
4068*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, ArgChains);
4069*9880d681SAndroid Build Coastguard Worker }
4070*9880d681SAndroid Build Coastguard Worker 
4071*9880d681SAndroid Build Coastguard Worker /// getMemsetValue - Vectorized representation of the memset value
4072*9880d681SAndroid Build Coastguard Worker /// operand.
getMemsetValue(SDValue Value,EVT VT,SelectionDAG & DAG,const SDLoc & dl)4073*9880d681SAndroid Build Coastguard Worker static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
4074*9880d681SAndroid Build Coastguard Worker                               const SDLoc &dl) {
4075*9880d681SAndroid Build Coastguard Worker   assert(!Value.isUndef());
4076*9880d681SAndroid Build Coastguard Worker 
4077*9880d681SAndroid Build Coastguard Worker   unsigned NumBits = VT.getScalarType().getSizeInBits();
4078*9880d681SAndroid Build Coastguard Worker   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Value)) {
4079*9880d681SAndroid Build Coastguard Worker     assert(C->getAPIntValue().getBitWidth() == 8);
4080*9880d681SAndroid Build Coastguard Worker     APInt Val = APInt::getSplat(NumBits, C->getAPIntValue());
4081*9880d681SAndroid Build Coastguard Worker     if (VT.isInteger())
4082*9880d681SAndroid Build Coastguard Worker       return DAG.getConstant(Val, dl, VT);
4083*9880d681SAndroid Build Coastguard Worker     return DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(VT), Val), dl,
4084*9880d681SAndroid Build Coastguard Worker                              VT);
4085*9880d681SAndroid Build Coastguard Worker   }
4086*9880d681SAndroid Build Coastguard Worker 
4087*9880d681SAndroid Build Coastguard Worker   assert(Value.getValueType() == MVT::i8 && "memset with non-byte fill value?");
4088*9880d681SAndroid Build Coastguard Worker   EVT IntVT = VT.getScalarType();
4089*9880d681SAndroid Build Coastguard Worker   if (!IntVT.isInteger())
4090*9880d681SAndroid Build Coastguard Worker     IntVT = EVT::getIntegerVT(*DAG.getContext(), IntVT.getSizeInBits());
4091*9880d681SAndroid Build Coastguard Worker 
4092*9880d681SAndroid Build Coastguard Worker   Value = DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, Value);
4093*9880d681SAndroid Build Coastguard Worker   if (NumBits > 8) {
4094*9880d681SAndroid Build Coastguard Worker     // Use a multiplication with 0x010101... to extend the input to the
4095*9880d681SAndroid Build Coastguard Worker     // required length.
4096*9880d681SAndroid Build Coastguard Worker     APInt Magic = APInt::getSplat(NumBits, APInt(8, 0x01));
4097*9880d681SAndroid Build Coastguard Worker     Value = DAG.getNode(ISD::MUL, dl, IntVT, Value,
4098*9880d681SAndroid Build Coastguard Worker                         DAG.getConstant(Magic, dl, IntVT));
4099*9880d681SAndroid Build Coastguard Worker   }
4100*9880d681SAndroid Build Coastguard Worker 
4101*9880d681SAndroid Build Coastguard Worker   if (VT != Value.getValueType() && !VT.isInteger())
4102*9880d681SAndroid Build Coastguard Worker     Value = DAG.getBitcast(VT.getScalarType(), Value);
4103*9880d681SAndroid Build Coastguard Worker   if (VT != Value.getValueType())
4104*9880d681SAndroid Build Coastguard Worker     Value = DAG.getSplatBuildVector(VT, dl, Value);
4105*9880d681SAndroid Build Coastguard Worker 
4106*9880d681SAndroid Build Coastguard Worker   return Value;
4107*9880d681SAndroid Build Coastguard Worker }
4108*9880d681SAndroid Build Coastguard Worker 
4109*9880d681SAndroid Build Coastguard Worker /// getMemsetStringVal - Similar to getMemsetValue. Except this is only
4110*9880d681SAndroid Build Coastguard Worker /// used when a memcpy is turned into a memset when the source is a constant
4111*9880d681SAndroid Build Coastguard Worker /// string ptr.
getMemsetStringVal(EVT VT,const SDLoc & dl,SelectionDAG & DAG,const TargetLowering & TLI,StringRef Str)4112*9880d681SAndroid Build Coastguard Worker static SDValue getMemsetStringVal(EVT VT, const SDLoc &dl, SelectionDAG &DAG,
4113*9880d681SAndroid Build Coastguard Worker                                   const TargetLowering &TLI, StringRef Str) {
4114*9880d681SAndroid Build Coastguard Worker   // Handle vector with all elements zero.
4115*9880d681SAndroid Build Coastguard Worker   if (Str.empty()) {
4116*9880d681SAndroid Build Coastguard Worker     if (VT.isInteger())
4117*9880d681SAndroid Build Coastguard Worker       return DAG.getConstant(0, dl, VT);
4118*9880d681SAndroid Build Coastguard Worker     else if (VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f128)
4119*9880d681SAndroid Build Coastguard Worker       return DAG.getConstantFP(0.0, dl, VT);
4120*9880d681SAndroid Build Coastguard Worker     else if (VT.isVector()) {
4121*9880d681SAndroid Build Coastguard Worker       unsigned NumElts = VT.getVectorNumElements();
4122*9880d681SAndroid Build Coastguard Worker       MVT EltVT = (VT.getVectorElementType() == MVT::f32) ? MVT::i32 : MVT::i64;
4123*9880d681SAndroid Build Coastguard Worker       return DAG.getNode(ISD::BITCAST, dl, VT,
4124*9880d681SAndroid Build Coastguard Worker                          DAG.getConstant(0, dl,
4125*9880d681SAndroid Build Coastguard Worker                                          EVT::getVectorVT(*DAG.getContext(),
4126*9880d681SAndroid Build Coastguard Worker                                                           EltVT, NumElts)));
4127*9880d681SAndroid Build Coastguard Worker     } else
4128*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Expected type!");
4129*9880d681SAndroid Build Coastguard Worker   }
4130*9880d681SAndroid Build Coastguard Worker 
4131*9880d681SAndroid Build Coastguard Worker   assert(!VT.isVector() && "Can't handle vector type here!");
4132*9880d681SAndroid Build Coastguard Worker   unsigned NumVTBits = VT.getSizeInBits();
4133*9880d681SAndroid Build Coastguard Worker   unsigned NumVTBytes = NumVTBits / 8;
4134*9880d681SAndroid Build Coastguard Worker   unsigned NumBytes = std::min(NumVTBytes, unsigned(Str.size()));
4135*9880d681SAndroid Build Coastguard Worker 
4136*9880d681SAndroid Build Coastguard Worker   APInt Val(NumVTBits, 0);
4137*9880d681SAndroid Build Coastguard Worker   if (DAG.getDataLayout().isLittleEndian()) {
4138*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0; i != NumBytes; ++i)
4139*9880d681SAndroid Build Coastguard Worker       Val |= (uint64_t)(unsigned char)Str[i] << i*8;
4140*9880d681SAndroid Build Coastguard Worker   } else {
4141*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0; i != NumBytes; ++i)
4142*9880d681SAndroid Build Coastguard Worker       Val |= (uint64_t)(unsigned char)Str[i] << (NumVTBytes-i-1)*8;
4143*9880d681SAndroid Build Coastguard Worker   }
4144*9880d681SAndroid Build Coastguard Worker 
4145*9880d681SAndroid Build Coastguard Worker   // If the "cost" of materializing the integer immediate is less than the cost
4146*9880d681SAndroid Build Coastguard Worker   // of a load, then it is cost effective to turn the load into the immediate.
4147*9880d681SAndroid Build Coastguard Worker   Type *Ty = VT.getTypeForEVT(*DAG.getContext());
4148*9880d681SAndroid Build Coastguard Worker   if (TLI.shouldConvertConstantLoadToIntImm(Val, Ty))
4149*9880d681SAndroid Build Coastguard Worker     return DAG.getConstant(Val, dl, VT);
4150*9880d681SAndroid Build Coastguard Worker   return SDValue(nullptr, 0);
4151*9880d681SAndroid Build Coastguard Worker }
4152*9880d681SAndroid Build Coastguard Worker 
getMemBasePlusOffset(SDValue Base,unsigned Offset,const SDLoc & DL)4153*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMemBasePlusOffset(SDValue Base, unsigned Offset,
4154*9880d681SAndroid Build Coastguard Worker                                            const SDLoc &DL) {
4155*9880d681SAndroid Build Coastguard Worker   EVT VT = Base.getValueType();
4156*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::ADD, DL, VT, Base, getConstant(Offset, DL, VT));
4157*9880d681SAndroid Build Coastguard Worker }
4158*9880d681SAndroid Build Coastguard Worker 
4159*9880d681SAndroid Build Coastguard Worker /// isMemSrcFromString - Returns true if memcpy source is a string constant.
4160*9880d681SAndroid Build Coastguard Worker ///
isMemSrcFromString(SDValue Src,StringRef & Str)4161*9880d681SAndroid Build Coastguard Worker static bool isMemSrcFromString(SDValue Src, StringRef &Str) {
4162*9880d681SAndroid Build Coastguard Worker   uint64_t SrcDelta = 0;
4163*9880d681SAndroid Build Coastguard Worker   GlobalAddressSDNode *G = nullptr;
4164*9880d681SAndroid Build Coastguard Worker   if (Src.getOpcode() == ISD::GlobalAddress)
4165*9880d681SAndroid Build Coastguard Worker     G = cast<GlobalAddressSDNode>(Src);
4166*9880d681SAndroid Build Coastguard Worker   else if (Src.getOpcode() == ISD::ADD &&
4167*9880d681SAndroid Build Coastguard Worker            Src.getOperand(0).getOpcode() == ISD::GlobalAddress &&
4168*9880d681SAndroid Build Coastguard Worker            Src.getOperand(1).getOpcode() == ISD::Constant) {
4169*9880d681SAndroid Build Coastguard Worker     G = cast<GlobalAddressSDNode>(Src.getOperand(0));
4170*9880d681SAndroid Build Coastguard Worker     SrcDelta = cast<ConstantSDNode>(Src.getOperand(1))->getZExtValue();
4171*9880d681SAndroid Build Coastguard Worker   }
4172*9880d681SAndroid Build Coastguard Worker   if (!G)
4173*9880d681SAndroid Build Coastguard Worker     return false;
4174*9880d681SAndroid Build Coastguard Worker 
4175*9880d681SAndroid Build Coastguard Worker   return getConstantStringInfo(G->getGlobal(), Str,
4176*9880d681SAndroid Build Coastguard Worker                                SrcDelta + G->getOffset(), false);
4177*9880d681SAndroid Build Coastguard Worker }
4178*9880d681SAndroid Build Coastguard Worker 
4179*9880d681SAndroid Build Coastguard Worker /// Determines the optimal series of memory ops to replace the memset / memcpy.
4180*9880d681SAndroid Build Coastguard Worker /// Return true if the number of memory ops is below the threshold (Limit).
4181*9880d681SAndroid Build Coastguard Worker /// It returns the types of the sequence of memory ops to perform
4182*9880d681SAndroid Build Coastguard Worker /// memset / memcpy by reference.
FindOptimalMemOpLowering(std::vector<EVT> & MemOps,unsigned Limit,uint64_t Size,unsigned DstAlign,unsigned SrcAlign,bool IsMemset,bool ZeroMemset,bool MemcpyStrSrc,bool AllowOverlap,unsigned DstAS,unsigned SrcAS,SelectionDAG & DAG,const TargetLowering & TLI)4183*9880d681SAndroid Build Coastguard Worker static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
4184*9880d681SAndroid Build Coastguard Worker                                      unsigned Limit, uint64_t Size,
4185*9880d681SAndroid Build Coastguard Worker                                      unsigned DstAlign, unsigned SrcAlign,
4186*9880d681SAndroid Build Coastguard Worker                                      bool IsMemset,
4187*9880d681SAndroid Build Coastguard Worker                                      bool ZeroMemset,
4188*9880d681SAndroid Build Coastguard Worker                                      bool MemcpyStrSrc,
4189*9880d681SAndroid Build Coastguard Worker                                      bool AllowOverlap,
4190*9880d681SAndroid Build Coastguard Worker                                      unsigned DstAS, unsigned SrcAS,
4191*9880d681SAndroid Build Coastguard Worker                                      SelectionDAG &DAG,
4192*9880d681SAndroid Build Coastguard Worker                                      const TargetLowering &TLI) {
4193*9880d681SAndroid Build Coastguard Worker   assert((SrcAlign == 0 || SrcAlign >= DstAlign) &&
4194*9880d681SAndroid Build Coastguard Worker          "Expecting memcpy / memset source to meet alignment requirement!");
4195*9880d681SAndroid Build Coastguard Worker   // If 'SrcAlign' is zero, that means the memory operation does not need to
4196*9880d681SAndroid Build Coastguard Worker   // load the value, i.e. memset or memcpy from constant string. Otherwise,
4197*9880d681SAndroid Build Coastguard Worker   // it's the inferred alignment of the source. 'DstAlign', on the other hand,
4198*9880d681SAndroid Build Coastguard Worker   // is the specified alignment of the memory operation. If it is zero, that
4199*9880d681SAndroid Build Coastguard Worker   // means it's possible to change the alignment of the destination.
4200*9880d681SAndroid Build Coastguard Worker   // 'MemcpyStrSrc' indicates whether the memcpy source is constant so it does
4201*9880d681SAndroid Build Coastguard Worker   // not need to be loaded.
4202*9880d681SAndroid Build Coastguard Worker   EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign,
4203*9880d681SAndroid Build Coastguard Worker                                    IsMemset, ZeroMemset, MemcpyStrSrc,
4204*9880d681SAndroid Build Coastguard Worker                                    DAG.getMachineFunction());
4205*9880d681SAndroid Build Coastguard Worker 
4206*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::Other) {
4207*9880d681SAndroid Build Coastguard Worker     if (DstAlign >= DAG.getDataLayout().getPointerPrefAlignment(DstAS) ||
4208*9880d681SAndroid Build Coastguard Worker         TLI.allowsMisalignedMemoryAccesses(VT, DstAS, DstAlign)) {
4209*9880d681SAndroid Build Coastguard Worker       VT = TLI.getPointerTy(DAG.getDataLayout(), DstAS);
4210*9880d681SAndroid Build Coastguard Worker     } else {
4211*9880d681SAndroid Build Coastguard Worker       switch (DstAlign & 7) {
4212*9880d681SAndroid Build Coastguard Worker       case 0:  VT = MVT::i64; break;
4213*9880d681SAndroid Build Coastguard Worker       case 4:  VT = MVT::i32; break;
4214*9880d681SAndroid Build Coastguard Worker       case 2:  VT = MVT::i16; break;
4215*9880d681SAndroid Build Coastguard Worker       default: VT = MVT::i8;  break;
4216*9880d681SAndroid Build Coastguard Worker       }
4217*9880d681SAndroid Build Coastguard Worker     }
4218*9880d681SAndroid Build Coastguard Worker 
4219*9880d681SAndroid Build Coastguard Worker     MVT LVT = MVT::i64;
4220*9880d681SAndroid Build Coastguard Worker     while (!TLI.isTypeLegal(LVT))
4221*9880d681SAndroid Build Coastguard Worker       LVT = (MVT::SimpleValueType)(LVT.SimpleTy - 1);
4222*9880d681SAndroid Build Coastguard Worker     assert(LVT.isInteger());
4223*9880d681SAndroid Build Coastguard Worker 
4224*9880d681SAndroid Build Coastguard Worker     if (VT.bitsGT(LVT))
4225*9880d681SAndroid Build Coastguard Worker       VT = LVT;
4226*9880d681SAndroid Build Coastguard Worker   }
4227*9880d681SAndroid Build Coastguard Worker 
4228*9880d681SAndroid Build Coastguard Worker   unsigned NumMemOps = 0;
4229*9880d681SAndroid Build Coastguard Worker   while (Size != 0) {
4230*9880d681SAndroid Build Coastguard Worker     unsigned VTSize = VT.getSizeInBits() / 8;
4231*9880d681SAndroid Build Coastguard Worker     while (VTSize > Size) {
4232*9880d681SAndroid Build Coastguard Worker       // For now, only use non-vector load / store's for the left-over pieces.
4233*9880d681SAndroid Build Coastguard Worker       EVT NewVT = VT;
4234*9880d681SAndroid Build Coastguard Worker       unsigned NewVTSize;
4235*9880d681SAndroid Build Coastguard Worker 
4236*9880d681SAndroid Build Coastguard Worker       bool Found = false;
4237*9880d681SAndroid Build Coastguard Worker       if (VT.isVector() || VT.isFloatingPoint()) {
4238*9880d681SAndroid Build Coastguard Worker         NewVT = (VT.getSizeInBits() > 64) ? MVT::i64 : MVT::i32;
4239*9880d681SAndroid Build Coastguard Worker         if (TLI.isOperationLegalOrCustom(ISD::STORE, NewVT) &&
4240*9880d681SAndroid Build Coastguard Worker             TLI.isSafeMemOpType(NewVT.getSimpleVT()))
4241*9880d681SAndroid Build Coastguard Worker           Found = true;
4242*9880d681SAndroid Build Coastguard Worker         else if (NewVT == MVT::i64 &&
4243*9880d681SAndroid Build Coastguard Worker                  TLI.isOperationLegalOrCustom(ISD::STORE, MVT::f64) &&
4244*9880d681SAndroid Build Coastguard Worker                  TLI.isSafeMemOpType(MVT::f64)) {
4245*9880d681SAndroid Build Coastguard Worker           // i64 is usually not legal on 32-bit targets, but f64 may be.
4246*9880d681SAndroid Build Coastguard Worker           NewVT = MVT::f64;
4247*9880d681SAndroid Build Coastguard Worker           Found = true;
4248*9880d681SAndroid Build Coastguard Worker         }
4249*9880d681SAndroid Build Coastguard Worker       }
4250*9880d681SAndroid Build Coastguard Worker 
4251*9880d681SAndroid Build Coastguard Worker       if (!Found) {
4252*9880d681SAndroid Build Coastguard Worker         do {
4253*9880d681SAndroid Build Coastguard Worker           NewVT = (MVT::SimpleValueType)(NewVT.getSimpleVT().SimpleTy - 1);
4254*9880d681SAndroid Build Coastguard Worker           if (NewVT == MVT::i8)
4255*9880d681SAndroid Build Coastguard Worker             break;
4256*9880d681SAndroid Build Coastguard Worker         } while (!TLI.isSafeMemOpType(NewVT.getSimpleVT()));
4257*9880d681SAndroid Build Coastguard Worker       }
4258*9880d681SAndroid Build Coastguard Worker       NewVTSize = NewVT.getSizeInBits() / 8;
4259*9880d681SAndroid Build Coastguard Worker 
4260*9880d681SAndroid Build Coastguard Worker       // If the new VT cannot cover all of the remaining bits, then consider
4261*9880d681SAndroid Build Coastguard Worker       // issuing a (or a pair of) unaligned and overlapping load / store.
4262*9880d681SAndroid Build Coastguard Worker       // FIXME: Only does this for 64-bit or more since we don't have proper
4263*9880d681SAndroid Build Coastguard Worker       // cost model for unaligned load / store.
4264*9880d681SAndroid Build Coastguard Worker       bool Fast;
4265*9880d681SAndroid Build Coastguard Worker       if (NumMemOps && AllowOverlap &&
4266*9880d681SAndroid Build Coastguard Worker           VTSize >= 8 && NewVTSize < Size &&
4267*9880d681SAndroid Build Coastguard Worker           TLI.allowsMisalignedMemoryAccesses(VT, DstAS, DstAlign, &Fast) && Fast)
4268*9880d681SAndroid Build Coastguard Worker         VTSize = Size;
4269*9880d681SAndroid Build Coastguard Worker       else {
4270*9880d681SAndroid Build Coastguard Worker         VT = NewVT;
4271*9880d681SAndroid Build Coastguard Worker         VTSize = NewVTSize;
4272*9880d681SAndroid Build Coastguard Worker       }
4273*9880d681SAndroid Build Coastguard Worker     }
4274*9880d681SAndroid Build Coastguard Worker 
4275*9880d681SAndroid Build Coastguard Worker     if (++NumMemOps > Limit)
4276*9880d681SAndroid Build Coastguard Worker       return false;
4277*9880d681SAndroid Build Coastguard Worker 
4278*9880d681SAndroid Build Coastguard Worker     MemOps.push_back(VT);
4279*9880d681SAndroid Build Coastguard Worker     Size -= VTSize;
4280*9880d681SAndroid Build Coastguard Worker   }
4281*9880d681SAndroid Build Coastguard Worker 
4282*9880d681SAndroid Build Coastguard Worker   return true;
4283*9880d681SAndroid Build Coastguard Worker }
4284*9880d681SAndroid Build Coastguard Worker 
shouldLowerMemFuncForSize(const MachineFunction & MF)4285*9880d681SAndroid Build Coastguard Worker static bool shouldLowerMemFuncForSize(const MachineFunction &MF) {
4286*9880d681SAndroid Build Coastguard Worker   // On Darwin, -Os means optimize for size without hurting performance, so
4287*9880d681SAndroid Build Coastguard Worker   // only really optimize for size when -Oz (MinSize) is used.
4288*9880d681SAndroid Build Coastguard Worker   if (MF.getTarget().getTargetTriple().isOSDarwin())
4289*9880d681SAndroid Build Coastguard Worker     return MF.getFunction()->optForMinSize();
4290*9880d681SAndroid Build Coastguard Worker   return MF.getFunction()->optForSize();
4291*9880d681SAndroid Build Coastguard Worker }
4292*9880d681SAndroid Build Coastguard Worker 
getMemcpyLoadsAndStores(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,uint64_t Size,unsigned Align,bool isVol,bool AlwaysInline,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo)4293*9880d681SAndroid Build Coastguard Worker static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
4294*9880d681SAndroid Build Coastguard Worker                                        SDValue Chain, SDValue Dst, SDValue Src,
4295*9880d681SAndroid Build Coastguard Worker                                        uint64_t Size, unsigned Align,
4296*9880d681SAndroid Build Coastguard Worker                                        bool isVol, bool AlwaysInline,
4297*9880d681SAndroid Build Coastguard Worker                                        MachinePointerInfo DstPtrInfo,
4298*9880d681SAndroid Build Coastguard Worker                                        MachinePointerInfo SrcPtrInfo) {
4299*9880d681SAndroid Build Coastguard Worker   // Turn a memcpy of undef to nop.
4300*9880d681SAndroid Build Coastguard Worker   if (Src.isUndef())
4301*9880d681SAndroid Build Coastguard Worker     return Chain;
4302*9880d681SAndroid Build Coastguard Worker 
4303*9880d681SAndroid Build Coastguard Worker   // Expand memcpy to a series of load and store ops if the size operand falls
4304*9880d681SAndroid Build Coastguard Worker   // below a certain threshold.
4305*9880d681SAndroid Build Coastguard Worker   // TODO: In the AlwaysInline case, if the size is big then generate a loop
4306*9880d681SAndroid Build Coastguard Worker   // rather than maybe a humongous number of loads and stores.
4307*9880d681SAndroid Build Coastguard Worker   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
4308*9880d681SAndroid Build Coastguard Worker   std::vector<EVT> MemOps;
4309*9880d681SAndroid Build Coastguard Worker   bool DstAlignCanChange = false;
4310*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
4311*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
4312*9880d681SAndroid Build Coastguard Worker   bool OptSize = shouldLowerMemFuncForSize(MF);
4313*9880d681SAndroid Build Coastguard Worker   FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
4314*9880d681SAndroid Build Coastguard Worker   if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
4315*9880d681SAndroid Build Coastguard Worker     DstAlignCanChange = true;
4316*9880d681SAndroid Build Coastguard Worker   unsigned SrcAlign = DAG.InferPtrAlignment(Src);
4317*9880d681SAndroid Build Coastguard Worker   if (Align > SrcAlign)
4318*9880d681SAndroid Build Coastguard Worker     SrcAlign = Align;
4319*9880d681SAndroid Build Coastguard Worker   StringRef Str;
4320*9880d681SAndroid Build Coastguard Worker   bool CopyFromStr = isMemSrcFromString(Src, Str);
4321*9880d681SAndroid Build Coastguard Worker   bool isZeroStr = CopyFromStr && Str.empty();
4322*9880d681SAndroid Build Coastguard Worker   unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemcpy(OptSize);
4323*9880d681SAndroid Build Coastguard Worker 
4324*9880d681SAndroid Build Coastguard Worker   if (!FindOptimalMemOpLowering(MemOps, Limit, Size,
4325*9880d681SAndroid Build Coastguard Worker                                 (DstAlignCanChange ? 0 : Align),
4326*9880d681SAndroid Build Coastguard Worker                                 (isZeroStr ? 0 : SrcAlign),
4327*9880d681SAndroid Build Coastguard Worker                                 false, false, CopyFromStr, true,
4328*9880d681SAndroid Build Coastguard Worker                                 DstPtrInfo.getAddrSpace(),
4329*9880d681SAndroid Build Coastguard Worker                                 SrcPtrInfo.getAddrSpace(),
4330*9880d681SAndroid Build Coastguard Worker                                 DAG, TLI))
4331*9880d681SAndroid Build Coastguard Worker     return SDValue();
4332*9880d681SAndroid Build Coastguard Worker 
4333*9880d681SAndroid Build Coastguard Worker   if (DstAlignCanChange) {
4334*9880d681SAndroid Build Coastguard Worker     Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
4335*9880d681SAndroid Build Coastguard Worker     unsigned NewAlign = (unsigned)DAG.getDataLayout().getABITypeAlignment(Ty);
4336*9880d681SAndroid Build Coastguard Worker 
4337*9880d681SAndroid Build Coastguard Worker     // Don't promote to an alignment that would require dynamic stack
4338*9880d681SAndroid Build Coastguard Worker     // realignment.
4339*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
4340*9880d681SAndroid Build Coastguard Worker     if (!TRI->needsStackRealignment(MF))
4341*9880d681SAndroid Build Coastguard Worker       while (NewAlign > Align &&
4342*9880d681SAndroid Build Coastguard Worker              DAG.getDataLayout().exceedsNaturalStackAlignment(NewAlign))
4343*9880d681SAndroid Build Coastguard Worker           NewAlign /= 2;
4344*9880d681SAndroid Build Coastguard Worker 
4345*9880d681SAndroid Build Coastguard Worker     if (NewAlign > Align) {
4346*9880d681SAndroid Build Coastguard Worker       // Give the stack frame object a larger alignment if needed.
4347*9880d681SAndroid Build Coastguard Worker       if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
4348*9880d681SAndroid Build Coastguard Worker         MFI->setObjectAlignment(FI->getIndex(), NewAlign);
4349*9880d681SAndroid Build Coastguard Worker       Align = NewAlign;
4350*9880d681SAndroid Build Coastguard Worker     }
4351*9880d681SAndroid Build Coastguard Worker   }
4352*9880d681SAndroid Build Coastguard Worker 
4353*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> OutChains;
4354*9880d681SAndroid Build Coastguard Worker   unsigned NumMemOps = MemOps.size();
4355*9880d681SAndroid Build Coastguard Worker   uint64_t SrcOff = 0, DstOff = 0;
4356*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i != NumMemOps; ++i) {
4357*9880d681SAndroid Build Coastguard Worker     EVT VT = MemOps[i];
4358*9880d681SAndroid Build Coastguard Worker     unsigned VTSize = VT.getSizeInBits() / 8;
4359*9880d681SAndroid Build Coastguard Worker     SDValue Value, Store;
4360*9880d681SAndroid Build Coastguard Worker 
4361*9880d681SAndroid Build Coastguard Worker     if (VTSize > Size) {
4362*9880d681SAndroid Build Coastguard Worker       // Issuing an unaligned load / store pair  that overlaps with the previous
4363*9880d681SAndroid Build Coastguard Worker       // pair. Adjust the offset accordingly.
4364*9880d681SAndroid Build Coastguard Worker       assert(i == NumMemOps-1 && i != 0);
4365*9880d681SAndroid Build Coastguard Worker       SrcOff -= VTSize - Size;
4366*9880d681SAndroid Build Coastguard Worker       DstOff -= VTSize - Size;
4367*9880d681SAndroid Build Coastguard Worker     }
4368*9880d681SAndroid Build Coastguard Worker 
4369*9880d681SAndroid Build Coastguard Worker     if (CopyFromStr &&
4370*9880d681SAndroid Build Coastguard Worker         (isZeroStr || (VT.isInteger() && !VT.isVector()))) {
4371*9880d681SAndroid Build Coastguard Worker       // It's unlikely a store of a vector immediate can be done in a single
4372*9880d681SAndroid Build Coastguard Worker       // instruction. It would require a load from a constantpool first.
4373*9880d681SAndroid Build Coastguard Worker       // We only handle zero vectors here.
4374*9880d681SAndroid Build Coastguard Worker       // FIXME: Handle other cases where store of vector immediate is done in
4375*9880d681SAndroid Build Coastguard Worker       // a single instruction.
4376*9880d681SAndroid Build Coastguard Worker       Value = getMemsetStringVal(VT, dl, DAG, TLI, Str.substr(SrcOff));
4377*9880d681SAndroid Build Coastguard Worker       if (Value.getNode())
4378*9880d681SAndroid Build Coastguard Worker         Store = DAG.getStore(Chain, dl, Value,
4379*9880d681SAndroid Build Coastguard Worker                              DAG.getMemBasePlusOffset(Dst, DstOff, dl),
4380*9880d681SAndroid Build Coastguard Worker                              DstPtrInfo.getWithOffset(DstOff), isVol,
4381*9880d681SAndroid Build Coastguard Worker                              false, Align);
4382*9880d681SAndroid Build Coastguard Worker     }
4383*9880d681SAndroid Build Coastguard Worker 
4384*9880d681SAndroid Build Coastguard Worker     if (!Store.getNode()) {
4385*9880d681SAndroid Build Coastguard Worker       // The type might not be legal for the target.  This should only happen
4386*9880d681SAndroid Build Coastguard Worker       // if the type is smaller than a legal type, as on PPC, so the right
4387*9880d681SAndroid Build Coastguard Worker       // thing to do is generate a LoadExt/StoreTrunc pair.  These simplify
4388*9880d681SAndroid Build Coastguard Worker       // to Load/Store if NVT==VT.
4389*9880d681SAndroid Build Coastguard Worker       // FIXME does the case above also need this?
4390*9880d681SAndroid Build Coastguard Worker       EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4391*9880d681SAndroid Build Coastguard Worker       assert(NVT.bitsGE(VT));
4392*9880d681SAndroid Build Coastguard Worker       Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
4393*9880d681SAndroid Build Coastguard Worker                              DAG.getMemBasePlusOffset(Src, SrcOff, dl),
4394*9880d681SAndroid Build Coastguard Worker                              SrcPtrInfo.getWithOffset(SrcOff), VT, isVol, false,
4395*9880d681SAndroid Build Coastguard Worker                              false, MinAlign(SrcAlign, SrcOff));
4396*9880d681SAndroid Build Coastguard Worker       OutChains.push_back(Value.getValue(1));
4397*9880d681SAndroid Build Coastguard Worker       Store = DAG.getTruncStore(Chain, dl, Value,
4398*9880d681SAndroid Build Coastguard Worker                                 DAG.getMemBasePlusOffset(Dst, DstOff, dl),
4399*9880d681SAndroid Build Coastguard Worker                                 DstPtrInfo.getWithOffset(DstOff), VT, isVol,
4400*9880d681SAndroid Build Coastguard Worker                                 false, Align);
4401*9880d681SAndroid Build Coastguard Worker     }
4402*9880d681SAndroid Build Coastguard Worker     OutChains.push_back(Store);
4403*9880d681SAndroid Build Coastguard Worker     SrcOff += VTSize;
4404*9880d681SAndroid Build Coastguard Worker     DstOff += VTSize;
4405*9880d681SAndroid Build Coastguard Worker     Size -= VTSize;
4406*9880d681SAndroid Build Coastguard Worker   }
4407*9880d681SAndroid Build Coastguard Worker 
4408*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
4409*9880d681SAndroid Build Coastguard Worker }
4410*9880d681SAndroid Build Coastguard Worker 
getMemmoveLoadsAndStores(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,uint64_t Size,unsigned Align,bool isVol,bool AlwaysInline,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo)4411*9880d681SAndroid Build Coastguard Worker static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
4412*9880d681SAndroid Build Coastguard Worker                                         SDValue Chain, SDValue Dst, SDValue Src,
4413*9880d681SAndroid Build Coastguard Worker                                         uint64_t Size, unsigned Align,
4414*9880d681SAndroid Build Coastguard Worker                                         bool isVol, bool AlwaysInline,
4415*9880d681SAndroid Build Coastguard Worker                                         MachinePointerInfo DstPtrInfo,
4416*9880d681SAndroid Build Coastguard Worker                                         MachinePointerInfo SrcPtrInfo) {
4417*9880d681SAndroid Build Coastguard Worker   // Turn a memmove of undef to nop.
4418*9880d681SAndroid Build Coastguard Worker   if (Src.isUndef())
4419*9880d681SAndroid Build Coastguard Worker     return Chain;
4420*9880d681SAndroid Build Coastguard Worker 
4421*9880d681SAndroid Build Coastguard Worker   // Expand memmove to a series of load and store ops if the size operand falls
4422*9880d681SAndroid Build Coastguard Worker   // below a certain threshold.
4423*9880d681SAndroid Build Coastguard Worker   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
4424*9880d681SAndroid Build Coastguard Worker   std::vector<EVT> MemOps;
4425*9880d681SAndroid Build Coastguard Worker   bool DstAlignCanChange = false;
4426*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
4427*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
4428*9880d681SAndroid Build Coastguard Worker   bool OptSize = shouldLowerMemFuncForSize(MF);
4429*9880d681SAndroid Build Coastguard Worker   FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
4430*9880d681SAndroid Build Coastguard Worker   if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
4431*9880d681SAndroid Build Coastguard Worker     DstAlignCanChange = true;
4432*9880d681SAndroid Build Coastguard Worker   unsigned SrcAlign = DAG.InferPtrAlignment(Src);
4433*9880d681SAndroid Build Coastguard Worker   if (Align > SrcAlign)
4434*9880d681SAndroid Build Coastguard Worker     SrcAlign = Align;
4435*9880d681SAndroid Build Coastguard Worker   unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemmove(OptSize);
4436*9880d681SAndroid Build Coastguard Worker 
4437*9880d681SAndroid Build Coastguard Worker   if (!FindOptimalMemOpLowering(MemOps, Limit, Size,
4438*9880d681SAndroid Build Coastguard Worker                                 (DstAlignCanChange ? 0 : Align), SrcAlign,
4439*9880d681SAndroid Build Coastguard Worker                                 false, false, false, false,
4440*9880d681SAndroid Build Coastguard Worker                                 DstPtrInfo.getAddrSpace(),
4441*9880d681SAndroid Build Coastguard Worker                                 SrcPtrInfo.getAddrSpace(),
4442*9880d681SAndroid Build Coastguard Worker                                 DAG, TLI))
4443*9880d681SAndroid Build Coastguard Worker     return SDValue();
4444*9880d681SAndroid Build Coastguard Worker 
4445*9880d681SAndroid Build Coastguard Worker   if (DstAlignCanChange) {
4446*9880d681SAndroid Build Coastguard Worker     Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
4447*9880d681SAndroid Build Coastguard Worker     unsigned NewAlign = (unsigned)DAG.getDataLayout().getABITypeAlignment(Ty);
4448*9880d681SAndroid Build Coastguard Worker     if (NewAlign > Align) {
4449*9880d681SAndroid Build Coastguard Worker       // Give the stack frame object a larger alignment if needed.
4450*9880d681SAndroid Build Coastguard Worker       if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
4451*9880d681SAndroid Build Coastguard Worker         MFI->setObjectAlignment(FI->getIndex(), NewAlign);
4452*9880d681SAndroid Build Coastguard Worker       Align = NewAlign;
4453*9880d681SAndroid Build Coastguard Worker     }
4454*9880d681SAndroid Build Coastguard Worker   }
4455*9880d681SAndroid Build Coastguard Worker 
4456*9880d681SAndroid Build Coastguard Worker   uint64_t SrcOff = 0, DstOff = 0;
4457*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> LoadValues;
4458*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> LoadChains;
4459*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> OutChains;
4460*9880d681SAndroid Build Coastguard Worker   unsigned NumMemOps = MemOps.size();
4461*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumMemOps; i++) {
4462*9880d681SAndroid Build Coastguard Worker     EVT VT = MemOps[i];
4463*9880d681SAndroid Build Coastguard Worker     unsigned VTSize = VT.getSizeInBits() / 8;
4464*9880d681SAndroid Build Coastguard Worker     SDValue Value;
4465*9880d681SAndroid Build Coastguard Worker 
4466*9880d681SAndroid Build Coastguard Worker     Value = DAG.getLoad(VT, dl, Chain,
4467*9880d681SAndroid Build Coastguard Worker                         DAG.getMemBasePlusOffset(Src, SrcOff, dl),
4468*9880d681SAndroid Build Coastguard Worker                         SrcPtrInfo.getWithOffset(SrcOff), isVol,
4469*9880d681SAndroid Build Coastguard Worker                         false, false, SrcAlign);
4470*9880d681SAndroid Build Coastguard Worker     LoadValues.push_back(Value);
4471*9880d681SAndroid Build Coastguard Worker     LoadChains.push_back(Value.getValue(1));
4472*9880d681SAndroid Build Coastguard Worker     SrcOff += VTSize;
4473*9880d681SAndroid Build Coastguard Worker   }
4474*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);
4475*9880d681SAndroid Build Coastguard Worker   OutChains.clear();
4476*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumMemOps; i++) {
4477*9880d681SAndroid Build Coastguard Worker     EVT VT = MemOps[i];
4478*9880d681SAndroid Build Coastguard Worker     unsigned VTSize = VT.getSizeInBits() / 8;
4479*9880d681SAndroid Build Coastguard Worker     SDValue Store;
4480*9880d681SAndroid Build Coastguard Worker 
4481*9880d681SAndroid Build Coastguard Worker     Store = DAG.getStore(Chain, dl, LoadValues[i],
4482*9880d681SAndroid Build Coastguard Worker                          DAG.getMemBasePlusOffset(Dst, DstOff, dl),
4483*9880d681SAndroid Build Coastguard Worker                          DstPtrInfo.getWithOffset(DstOff), isVol, false, Align);
4484*9880d681SAndroid Build Coastguard Worker     OutChains.push_back(Store);
4485*9880d681SAndroid Build Coastguard Worker     DstOff += VTSize;
4486*9880d681SAndroid Build Coastguard Worker   }
4487*9880d681SAndroid Build Coastguard Worker 
4488*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
4489*9880d681SAndroid Build Coastguard Worker }
4490*9880d681SAndroid Build Coastguard Worker 
4491*9880d681SAndroid Build Coastguard Worker /// \brief Lower the call to 'memset' intrinsic function into a series of store
4492*9880d681SAndroid Build Coastguard Worker /// operations.
4493*9880d681SAndroid Build Coastguard Worker ///
4494*9880d681SAndroid Build Coastguard Worker /// \param DAG Selection DAG where lowered code is placed.
4495*9880d681SAndroid Build Coastguard Worker /// \param dl Link to corresponding IR location.
4496*9880d681SAndroid Build Coastguard Worker /// \param Chain Control flow dependency.
4497*9880d681SAndroid Build Coastguard Worker /// \param Dst Pointer to destination memory location.
4498*9880d681SAndroid Build Coastguard Worker /// \param Src Value of byte to write into the memory.
4499*9880d681SAndroid Build Coastguard Worker /// \param Size Number of bytes to write.
4500*9880d681SAndroid Build Coastguard Worker /// \param Align Alignment of the destination in bytes.
4501*9880d681SAndroid Build Coastguard Worker /// \param isVol True if destination is volatile.
4502*9880d681SAndroid Build Coastguard Worker /// \param DstPtrInfo IR information on the memory pointer.
4503*9880d681SAndroid Build Coastguard Worker /// \returns New head in the control flow, if lowering was successful, empty
4504*9880d681SAndroid Build Coastguard Worker /// SDValue otherwise.
4505*9880d681SAndroid Build Coastguard Worker ///
4506*9880d681SAndroid Build Coastguard Worker /// The function tries to replace 'llvm.memset' intrinsic with several store
4507*9880d681SAndroid Build Coastguard Worker /// operations and value calculation code. This is usually profitable for small
4508*9880d681SAndroid Build Coastguard Worker /// memory size.
getMemsetStores(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,uint64_t Size,unsigned Align,bool isVol,MachinePointerInfo DstPtrInfo)4509*9880d681SAndroid Build Coastguard Worker static SDValue getMemsetStores(SelectionDAG &DAG, const SDLoc &dl,
4510*9880d681SAndroid Build Coastguard Worker                                SDValue Chain, SDValue Dst, SDValue Src,
4511*9880d681SAndroid Build Coastguard Worker                                uint64_t Size, unsigned Align, bool isVol,
4512*9880d681SAndroid Build Coastguard Worker                                MachinePointerInfo DstPtrInfo) {
4513*9880d681SAndroid Build Coastguard Worker   // Turn a memset of undef to nop.
4514*9880d681SAndroid Build Coastguard Worker   if (Src.isUndef())
4515*9880d681SAndroid Build Coastguard Worker     return Chain;
4516*9880d681SAndroid Build Coastguard Worker 
4517*9880d681SAndroid Build Coastguard Worker   // Expand memset to a series of load/store ops if the size operand
4518*9880d681SAndroid Build Coastguard Worker   // falls below a certain threshold.
4519*9880d681SAndroid Build Coastguard Worker   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
4520*9880d681SAndroid Build Coastguard Worker   std::vector<EVT> MemOps;
4521*9880d681SAndroid Build Coastguard Worker   bool DstAlignCanChange = false;
4522*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
4523*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
4524*9880d681SAndroid Build Coastguard Worker   bool OptSize = shouldLowerMemFuncForSize(MF);
4525*9880d681SAndroid Build Coastguard Worker   FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
4526*9880d681SAndroid Build Coastguard Worker   if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
4527*9880d681SAndroid Build Coastguard Worker     DstAlignCanChange = true;
4528*9880d681SAndroid Build Coastguard Worker   bool IsZeroVal =
4529*9880d681SAndroid Build Coastguard Worker     isa<ConstantSDNode>(Src) && cast<ConstantSDNode>(Src)->isNullValue();
4530*9880d681SAndroid Build Coastguard Worker   if (!FindOptimalMemOpLowering(MemOps, TLI.getMaxStoresPerMemset(OptSize),
4531*9880d681SAndroid Build Coastguard Worker                                 Size, (DstAlignCanChange ? 0 : Align), 0,
4532*9880d681SAndroid Build Coastguard Worker                                 true, IsZeroVal, false, true,
4533*9880d681SAndroid Build Coastguard Worker                                 DstPtrInfo.getAddrSpace(), ~0u,
4534*9880d681SAndroid Build Coastguard Worker                                 DAG, TLI))
4535*9880d681SAndroid Build Coastguard Worker     return SDValue();
4536*9880d681SAndroid Build Coastguard Worker 
4537*9880d681SAndroid Build Coastguard Worker   if (DstAlignCanChange) {
4538*9880d681SAndroid Build Coastguard Worker     Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
4539*9880d681SAndroid Build Coastguard Worker     unsigned NewAlign = (unsigned)DAG.getDataLayout().getABITypeAlignment(Ty);
4540*9880d681SAndroid Build Coastguard Worker     if (NewAlign > Align) {
4541*9880d681SAndroid Build Coastguard Worker       // Give the stack frame object a larger alignment if needed.
4542*9880d681SAndroid Build Coastguard Worker       if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
4543*9880d681SAndroid Build Coastguard Worker         MFI->setObjectAlignment(FI->getIndex(), NewAlign);
4544*9880d681SAndroid Build Coastguard Worker       Align = NewAlign;
4545*9880d681SAndroid Build Coastguard Worker     }
4546*9880d681SAndroid Build Coastguard Worker   }
4547*9880d681SAndroid Build Coastguard Worker 
4548*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> OutChains;
4549*9880d681SAndroid Build Coastguard Worker   uint64_t DstOff = 0;
4550*9880d681SAndroid Build Coastguard Worker   unsigned NumMemOps = MemOps.size();
4551*9880d681SAndroid Build Coastguard Worker 
4552*9880d681SAndroid Build Coastguard Worker   // Find the largest store and generate the bit pattern for it.
4553*9880d681SAndroid Build Coastguard Worker   EVT LargestVT = MemOps[0];
4554*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 1; i < NumMemOps; i++)
4555*9880d681SAndroid Build Coastguard Worker     if (MemOps[i].bitsGT(LargestVT))
4556*9880d681SAndroid Build Coastguard Worker       LargestVT = MemOps[i];
4557*9880d681SAndroid Build Coastguard Worker   SDValue MemSetValue = getMemsetValue(Src, LargestVT, DAG, dl);
4558*9880d681SAndroid Build Coastguard Worker 
4559*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumMemOps; i++) {
4560*9880d681SAndroid Build Coastguard Worker     EVT VT = MemOps[i];
4561*9880d681SAndroid Build Coastguard Worker     unsigned VTSize = VT.getSizeInBits() / 8;
4562*9880d681SAndroid Build Coastguard Worker     if (VTSize > Size) {
4563*9880d681SAndroid Build Coastguard Worker       // Issuing an unaligned load / store pair  that overlaps with the previous
4564*9880d681SAndroid Build Coastguard Worker       // pair. Adjust the offset accordingly.
4565*9880d681SAndroid Build Coastguard Worker       assert(i == NumMemOps-1 && i != 0);
4566*9880d681SAndroid Build Coastguard Worker       DstOff -= VTSize - Size;
4567*9880d681SAndroid Build Coastguard Worker     }
4568*9880d681SAndroid Build Coastguard Worker 
4569*9880d681SAndroid Build Coastguard Worker     // If this store is smaller than the largest store see whether we can get
4570*9880d681SAndroid Build Coastguard Worker     // the smaller value for free with a truncate.
4571*9880d681SAndroid Build Coastguard Worker     SDValue Value = MemSetValue;
4572*9880d681SAndroid Build Coastguard Worker     if (VT.bitsLT(LargestVT)) {
4573*9880d681SAndroid Build Coastguard Worker       if (!LargestVT.isVector() && !VT.isVector() &&
4574*9880d681SAndroid Build Coastguard Worker           TLI.isTruncateFree(LargestVT, VT))
4575*9880d681SAndroid Build Coastguard Worker         Value = DAG.getNode(ISD::TRUNCATE, dl, VT, MemSetValue);
4576*9880d681SAndroid Build Coastguard Worker       else
4577*9880d681SAndroid Build Coastguard Worker         Value = getMemsetValue(Src, VT, DAG, dl);
4578*9880d681SAndroid Build Coastguard Worker     }
4579*9880d681SAndroid Build Coastguard Worker     assert(Value.getValueType() == VT && "Value with wrong type.");
4580*9880d681SAndroid Build Coastguard Worker     SDValue Store = DAG.getStore(Chain, dl, Value,
4581*9880d681SAndroid Build Coastguard Worker                                  DAG.getMemBasePlusOffset(Dst, DstOff, dl),
4582*9880d681SAndroid Build Coastguard Worker                                  DstPtrInfo.getWithOffset(DstOff),
4583*9880d681SAndroid Build Coastguard Worker                                  isVol, false, Align);
4584*9880d681SAndroid Build Coastguard Worker     OutChains.push_back(Store);
4585*9880d681SAndroid Build Coastguard Worker     DstOff += VT.getSizeInBits() / 8;
4586*9880d681SAndroid Build Coastguard Worker     Size -= VTSize;
4587*9880d681SAndroid Build Coastguard Worker   }
4588*9880d681SAndroid Build Coastguard Worker 
4589*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
4590*9880d681SAndroid Build Coastguard Worker }
4591*9880d681SAndroid Build Coastguard Worker 
checkAddrSpaceIsValidForLibcall(const TargetLowering * TLI,unsigned AS)4592*9880d681SAndroid Build Coastguard Worker static void checkAddrSpaceIsValidForLibcall(const TargetLowering *TLI,
4593*9880d681SAndroid Build Coastguard Worker                                             unsigned AS) {
4594*9880d681SAndroid Build Coastguard Worker   // Lowering memcpy / memset / memmove intrinsics to calls is only valid if all
4595*9880d681SAndroid Build Coastguard Worker   // pointer operands can be losslessly bitcasted to pointers of address space 0
4596*9880d681SAndroid Build Coastguard Worker   if (AS != 0 && !TLI->isNoopAddrSpaceCast(AS, 0)) {
4597*9880d681SAndroid Build Coastguard Worker     report_fatal_error("cannot lower memory intrinsic in address space " +
4598*9880d681SAndroid Build Coastguard Worker                        Twine(AS));
4599*9880d681SAndroid Build Coastguard Worker   }
4600*9880d681SAndroid Build Coastguard Worker }
4601*9880d681SAndroid Build Coastguard Worker 
getMemcpy(SDValue Chain,const SDLoc & dl,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,bool isVol,bool AlwaysInline,bool isTailCall,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo)4602*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst,
4603*9880d681SAndroid Build Coastguard Worker                                 SDValue Src, SDValue Size, unsigned Align,
4604*9880d681SAndroid Build Coastguard Worker                                 bool isVol, bool AlwaysInline, bool isTailCall,
4605*9880d681SAndroid Build Coastguard Worker                                 MachinePointerInfo DstPtrInfo,
4606*9880d681SAndroid Build Coastguard Worker                                 MachinePointerInfo SrcPtrInfo) {
4607*9880d681SAndroid Build Coastguard Worker   assert(Align && "The SDAG layer expects explicit alignment and reserves 0");
4608*9880d681SAndroid Build Coastguard Worker 
4609*9880d681SAndroid Build Coastguard Worker   // Check to see if we should lower the memcpy to loads and stores first.
4610*9880d681SAndroid Build Coastguard Worker   // For cases within the target-specified limits, this is the best choice.
4611*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
4612*9880d681SAndroid Build Coastguard Worker   if (ConstantSize) {
4613*9880d681SAndroid Build Coastguard Worker     // Memcpy with size zero? Just return the original chain.
4614*9880d681SAndroid Build Coastguard Worker     if (ConstantSize->isNullValue())
4615*9880d681SAndroid Build Coastguard Worker       return Chain;
4616*9880d681SAndroid Build Coastguard Worker 
4617*9880d681SAndroid Build Coastguard Worker     SDValue Result = getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
4618*9880d681SAndroid Build Coastguard Worker                                              ConstantSize->getZExtValue(),Align,
4619*9880d681SAndroid Build Coastguard Worker                                 isVol, false, DstPtrInfo, SrcPtrInfo);
4620*9880d681SAndroid Build Coastguard Worker     if (Result.getNode())
4621*9880d681SAndroid Build Coastguard Worker       return Result;
4622*9880d681SAndroid Build Coastguard Worker   }
4623*9880d681SAndroid Build Coastguard Worker 
4624*9880d681SAndroid Build Coastguard Worker   // Then check to see if we should lower the memcpy with target-specific
4625*9880d681SAndroid Build Coastguard Worker   // code. If the target chooses to do this, this is the next best.
4626*9880d681SAndroid Build Coastguard Worker   if (TSI) {
4627*9880d681SAndroid Build Coastguard Worker     SDValue Result = TSI->EmitTargetCodeForMemcpy(
4628*9880d681SAndroid Build Coastguard Worker         *this, dl, Chain, Dst, Src, Size, Align, isVol, AlwaysInline,
4629*9880d681SAndroid Build Coastguard Worker         DstPtrInfo, SrcPtrInfo);
4630*9880d681SAndroid Build Coastguard Worker     if (Result.getNode())
4631*9880d681SAndroid Build Coastguard Worker       return Result;
4632*9880d681SAndroid Build Coastguard Worker   }
4633*9880d681SAndroid Build Coastguard Worker 
4634*9880d681SAndroid Build Coastguard Worker   // If we really need inline code and the target declined to provide it,
4635*9880d681SAndroid Build Coastguard Worker   // use a (potentially long) sequence of loads and stores.
4636*9880d681SAndroid Build Coastguard Worker   if (AlwaysInline) {
4637*9880d681SAndroid Build Coastguard Worker     assert(ConstantSize && "AlwaysInline requires a constant size!");
4638*9880d681SAndroid Build Coastguard Worker     return getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
4639*9880d681SAndroid Build Coastguard Worker                                    ConstantSize->getZExtValue(), Align, isVol,
4640*9880d681SAndroid Build Coastguard Worker                                    true, DstPtrInfo, SrcPtrInfo);
4641*9880d681SAndroid Build Coastguard Worker   }
4642*9880d681SAndroid Build Coastguard Worker 
4643*9880d681SAndroid Build Coastguard Worker   checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace());
4644*9880d681SAndroid Build Coastguard Worker   checkAddrSpaceIsValidForLibcall(TLI, SrcPtrInfo.getAddrSpace());
4645*9880d681SAndroid Build Coastguard Worker 
4646*9880d681SAndroid Build Coastguard Worker   // FIXME: If the memcpy is volatile (isVol), lowering it to a plain libc
4647*9880d681SAndroid Build Coastguard Worker   // memcpy is not guaranteed to be safe. libc memcpys aren't required to
4648*9880d681SAndroid Build Coastguard Worker   // respect volatile, so they may do things like read or write memory
4649*9880d681SAndroid Build Coastguard Worker   // beyond the given memory regions. But fixing this isn't easy, and most
4650*9880d681SAndroid Build Coastguard Worker   // people don't care.
4651*9880d681SAndroid Build Coastguard Worker 
4652*9880d681SAndroid Build Coastguard Worker   // Emit a library call.
4653*9880d681SAndroid Build Coastguard Worker   TargetLowering::ArgListTy Args;
4654*9880d681SAndroid Build Coastguard Worker   TargetLowering::ArgListEntry Entry;
4655*9880d681SAndroid Build Coastguard Worker   Entry.Ty = getDataLayout().getIntPtrType(*getContext());
4656*9880d681SAndroid Build Coastguard Worker   Entry.Node = Dst; Args.push_back(Entry);
4657*9880d681SAndroid Build Coastguard Worker   Entry.Node = Src; Args.push_back(Entry);
4658*9880d681SAndroid Build Coastguard Worker   Entry.Node = Size; Args.push_back(Entry);
4659*9880d681SAndroid Build Coastguard Worker   // FIXME: pass in SDLoc
4660*9880d681SAndroid Build Coastguard Worker   TargetLowering::CallLoweringInfo CLI(*this);
4661*9880d681SAndroid Build Coastguard Worker   CLI.setDebugLoc(dl)
4662*9880d681SAndroid Build Coastguard Worker       .setChain(Chain)
4663*9880d681SAndroid Build Coastguard Worker       .setCallee(TLI->getLibcallCallingConv(RTLIB::MEMCPY),
4664*9880d681SAndroid Build Coastguard Worker                  Dst.getValueType().getTypeForEVT(*getContext()),
4665*9880d681SAndroid Build Coastguard Worker                  getExternalSymbol(TLI->getLibcallName(RTLIB::MEMCPY),
4666*9880d681SAndroid Build Coastguard Worker                                    TLI->getPointerTy(getDataLayout())),
4667*9880d681SAndroid Build Coastguard Worker                  std::move(Args))
4668*9880d681SAndroid Build Coastguard Worker       .setDiscardResult()
4669*9880d681SAndroid Build Coastguard Worker       .setTailCall(isTailCall);
4670*9880d681SAndroid Build Coastguard Worker 
4671*9880d681SAndroid Build Coastguard Worker   std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI);
4672*9880d681SAndroid Build Coastguard Worker   return CallResult.second;
4673*9880d681SAndroid Build Coastguard Worker }
4674*9880d681SAndroid Build Coastguard Worker 
getMemmove(SDValue Chain,const SDLoc & dl,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,bool isVol,bool isTailCall,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo)4675*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst,
4676*9880d681SAndroid Build Coastguard Worker                                  SDValue Src, SDValue Size, unsigned Align,
4677*9880d681SAndroid Build Coastguard Worker                                  bool isVol, bool isTailCall,
4678*9880d681SAndroid Build Coastguard Worker                                  MachinePointerInfo DstPtrInfo,
4679*9880d681SAndroid Build Coastguard Worker                                  MachinePointerInfo SrcPtrInfo) {
4680*9880d681SAndroid Build Coastguard Worker   assert(Align && "The SDAG layer expects explicit alignment and reserves 0");
4681*9880d681SAndroid Build Coastguard Worker 
4682*9880d681SAndroid Build Coastguard Worker   // Check to see if we should lower the memmove to loads and stores first.
4683*9880d681SAndroid Build Coastguard Worker   // For cases within the target-specified limits, this is the best choice.
4684*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
4685*9880d681SAndroid Build Coastguard Worker   if (ConstantSize) {
4686*9880d681SAndroid Build Coastguard Worker     // Memmove with size zero? Just return the original chain.
4687*9880d681SAndroid Build Coastguard Worker     if (ConstantSize->isNullValue())
4688*9880d681SAndroid Build Coastguard Worker       return Chain;
4689*9880d681SAndroid Build Coastguard Worker 
4690*9880d681SAndroid Build Coastguard Worker     SDValue Result =
4691*9880d681SAndroid Build Coastguard Worker       getMemmoveLoadsAndStores(*this, dl, Chain, Dst, Src,
4692*9880d681SAndroid Build Coastguard Worker                                ConstantSize->getZExtValue(), Align, isVol,
4693*9880d681SAndroid Build Coastguard Worker                                false, DstPtrInfo, SrcPtrInfo);
4694*9880d681SAndroid Build Coastguard Worker     if (Result.getNode())
4695*9880d681SAndroid Build Coastguard Worker       return Result;
4696*9880d681SAndroid Build Coastguard Worker   }
4697*9880d681SAndroid Build Coastguard Worker 
4698*9880d681SAndroid Build Coastguard Worker   // Then check to see if we should lower the memmove with target-specific
4699*9880d681SAndroid Build Coastguard Worker   // code. If the target chooses to do this, this is the next best.
4700*9880d681SAndroid Build Coastguard Worker   if (TSI) {
4701*9880d681SAndroid Build Coastguard Worker     SDValue Result = TSI->EmitTargetCodeForMemmove(
4702*9880d681SAndroid Build Coastguard Worker         *this, dl, Chain, Dst, Src, Size, Align, isVol, DstPtrInfo, SrcPtrInfo);
4703*9880d681SAndroid Build Coastguard Worker     if (Result.getNode())
4704*9880d681SAndroid Build Coastguard Worker       return Result;
4705*9880d681SAndroid Build Coastguard Worker   }
4706*9880d681SAndroid Build Coastguard Worker 
4707*9880d681SAndroid Build Coastguard Worker   checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace());
4708*9880d681SAndroid Build Coastguard Worker   checkAddrSpaceIsValidForLibcall(TLI, SrcPtrInfo.getAddrSpace());
4709*9880d681SAndroid Build Coastguard Worker 
4710*9880d681SAndroid Build Coastguard Worker   // FIXME: If the memmove is volatile, lowering it to plain libc memmove may
4711*9880d681SAndroid Build Coastguard Worker   // not be safe.  See memcpy above for more details.
4712*9880d681SAndroid Build Coastguard Worker 
4713*9880d681SAndroid Build Coastguard Worker   // Emit a library call.
4714*9880d681SAndroid Build Coastguard Worker   TargetLowering::ArgListTy Args;
4715*9880d681SAndroid Build Coastguard Worker   TargetLowering::ArgListEntry Entry;
4716*9880d681SAndroid Build Coastguard Worker   Entry.Ty = getDataLayout().getIntPtrType(*getContext());
4717*9880d681SAndroid Build Coastguard Worker   Entry.Node = Dst; Args.push_back(Entry);
4718*9880d681SAndroid Build Coastguard Worker   Entry.Node = Src; Args.push_back(Entry);
4719*9880d681SAndroid Build Coastguard Worker   Entry.Node = Size; Args.push_back(Entry);
4720*9880d681SAndroid Build Coastguard Worker   // FIXME:  pass in SDLoc
4721*9880d681SAndroid Build Coastguard Worker   TargetLowering::CallLoweringInfo CLI(*this);
4722*9880d681SAndroid Build Coastguard Worker   CLI.setDebugLoc(dl)
4723*9880d681SAndroid Build Coastguard Worker       .setChain(Chain)
4724*9880d681SAndroid Build Coastguard Worker       .setCallee(TLI->getLibcallCallingConv(RTLIB::MEMMOVE),
4725*9880d681SAndroid Build Coastguard Worker                  Dst.getValueType().getTypeForEVT(*getContext()),
4726*9880d681SAndroid Build Coastguard Worker                  getExternalSymbol(TLI->getLibcallName(RTLIB::MEMMOVE),
4727*9880d681SAndroid Build Coastguard Worker                                    TLI->getPointerTy(getDataLayout())),
4728*9880d681SAndroid Build Coastguard Worker                  std::move(Args))
4729*9880d681SAndroid Build Coastguard Worker       .setDiscardResult()
4730*9880d681SAndroid Build Coastguard Worker       .setTailCall(isTailCall);
4731*9880d681SAndroid Build Coastguard Worker 
4732*9880d681SAndroid Build Coastguard Worker   std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI);
4733*9880d681SAndroid Build Coastguard Worker   return CallResult.second;
4734*9880d681SAndroid Build Coastguard Worker }
4735*9880d681SAndroid Build Coastguard Worker 
getMemset(SDValue Chain,const SDLoc & dl,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,bool isVol,bool isTailCall,MachinePointerInfo DstPtrInfo)4736*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst,
4737*9880d681SAndroid Build Coastguard Worker                                 SDValue Src, SDValue Size, unsigned Align,
4738*9880d681SAndroid Build Coastguard Worker                                 bool isVol, bool isTailCall,
4739*9880d681SAndroid Build Coastguard Worker                                 MachinePointerInfo DstPtrInfo) {
4740*9880d681SAndroid Build Coastguard Worker   assert(Align && "The SDAG layer expects explicit alignment and reserves 0");
4741*9880d681SAndroid Build Coastguard Worker 
4742*9880d681SAndroid Build Coastguard Worker   // Check to see if we should lower the memset to stores first.
4743*9880d681SAndroid Build Coastguard Worker   // For cases within the target-specified limits, this is the best choice.
4744*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
4745*9880d681SAndroid Build Coastguard Worker   if (ConstantSize) {
4746*9880d681SAndroid Build Coastguard Worker     // Memset with size zero? Just return the original chain.
4747*9880d681SAndroid Build Coastguard Worker     if (ConstantSize->isNullValue())
4748*9880d681SAndroid Build Coastguard Worker       return Chain;
4749*9880d681SAndroid Build Coastguard Worker 
4750*9880d681SAndroid Build Coastguard Worker     SDValue Result =
4751*9880d681SAndroid Build Coastguard Worker       getMemsetStores(*this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(),
4752*9880d681SAndroid Build Coastguard Worker                       Align, isVol, DstPtrInfo);
4753*9880d681SAndroid Build Coastguard Worker 
4754*9880d681SAndroid Build Coastguard Worker     if (Result.getNode())
4755*9880d681SAndroid Build Coastguard Worker       return Result;
4756*9880d681SAndroid Build Coastguard Worker   }
4757*9880d681SAndroid Build Coastguard Worker 
4758*9880d681SAndroid Build Coastguard Worker   // Then check to see if we should lower the memset with target-specific
4759*9880d681SAndroid Build Coastguard Worker   // code. If the target chooses to do this, this is the next best.
4760*9880d681SAndroid Build Coastguard Worker   if (TSI) {
4761*9880d681SAndroid Build Coastguard Worker     SDValue Result = TSI->EmitTargetCodeForMemset(
4762*9880d681SAndroid Build Coastguard Worker         *this, dl, Chain, Dst, Src, Size, Align, isVol, DstPtrInfo);
4763*9880d681SAndroid Build Coastguard Worker     if (Result.getNode())
4764*9880d681SAndroid Build Coastguard Worker       return Result;
4765*9880d681SAndroid Build Coastguard Worker   }
4766*9880d681SAndroid Build Coastguard Worker 
4767*9880d681SAndroid Build Coastguard Worker   checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace());
4768*9880d681SAndroid Build Coastguard Worker 
4769*9880d681SAndroid Build Coastguard Worker   // Emit a library call.
4770*9880d681SAndroid Build Coastguard Worker   Type *IntPtrTy = getDataLayout().getIntPtrType(*getContext());
4771*9880d681SAndroid Build Coastguard Worker   TargetLowering::ArgListTy Args;
4772*9880d681SAndroid Build Coastguard Worker   TargetLowering::ArgListEntry Entry;
4773*9880d681SAndroid Build Coastguard Worker   Entry.Node = Dst; Entry.Ty = IntPtrTy;
4774*9880d681SAndroid Build Coastguard Worker   Args.push_back(Entry);
4775*9880d681SAndroid Build Coastguard Worker   Entry.Node = Src;
4776*9880d681SAndroid Build Coastguard Worker   Entry.Ty = Src.getValueType().getTypeForEVT(*getContext());
4777*9880d681SAndroid Build Coastguard Worker   Args.push_back(Entry);
4778*9880d681SAndroid Build Coastguard Worker   Entry.Node = Size;
4779*9880d681SAndroid Build Coastguard Worker   Entry.Ty = IntPtrTy;
4780*9880d681SAndroid Build Coastguard Worker   Args.push_back(Entry);
4781*9880d681SAndroid Build Coastguard Worker 
4782*9880d681SAndroid Build Coastguard Worker   // FIXME: pass in SDLoc
4783*9880d681SAndroid Build Coastguard Worker   TargetLowering::CallLoweringInfo CLI(*this);
4784*9880d681SAndroid Build Coastguard Worker   CLI.setDebugLoc(dl)
4785*9880d681SAndroid Build Coastguard Worker       .setChain(Chain)
4786*9880d681SAndroid Build Coastguard Worker       .setCallee(TLI->getLibcallCallingConv(RTLIB::MEMSET),
4787*9880d681SAndroid Build Coastguard Worker                  Dst.getValueType().getTypeForEVT(*getContext()),
4788*9880d681SAndroid Build Coastguard Worker                  getExternalSymbol(TLI->getLibcallName(RTLIB::MEMSET),
4789*9880d681SAndroid Build Coastguard Worker                                    TLI->getPointerTy(getDataLayout())),
4790*9880d681SAndroid Build Coastguard Worker                  std::move(Args))
4791*9880d681SAndroid Build Coastguard Worker       .setDiscardResult()
4792*9880d681SAndroid Build Coastguard Worker       .setTailCall(isTailCall);
4793*9880d681SAndroid Build Coastguard Worker 
4794*9880d681SAndroid Build Coastguard Worker   std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI);
4795*9880d681SAndroid Build Coastguard Worker   return CallResult.second;
4796*9880d681SAndroid Build Coastguard Worker }
4797*9880d681SAndroid Build Coastguard Worker 
getAtomic(unsigned Opcode,const SDLoc & dl,EVT MemVT,SDVTList VTList,ArrayRef<SDValue> Ops,MachineMemOperand * MMO,AtomicOrdering SuccessOrdering,AtomicOrdering FailureOrdering,SynchronizationScope SynchScope)4798*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
4799*9880d681SAndroid Build Coastguard Worker                                 SDVTList VTList, ArrayRef<SDValue> Ops,
4800*9880d681SAndroid Build Coastguard Worker                                 MachineMemOperand *MMO,
4801*9880d681SAndroid Build Coastguard Worker                                 AtomicOrdering SuccessOrdering,
4802*9880d681SAndroid Build Coastguard Worker                                 AtomicOrdering FailureOrdering,
4803*9880d681SAndroid Build Coastguard Worker                                 SynchronizationScope SynchScope) {
4804*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
4805*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MemVT.getRawBits());
4806*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, Opcode, VTList, Ops);
4807*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
4808*9880d681SAndroid Build Coastguard Worker   void* IP = nullptr;
4809*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
4810*9880d681SAndroid Build Coastguard Worker     cast<AtomicSDNode>(E)->refineAlignment(MMO);
4811*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
4812*9880d681SAndroid Build Coastguard Worker   }
4813*9880d681SAndroid Build Coastguard Worker 
4814*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<AtomicSDNode>(Opcode, dl.getIROrder(), dl.getDebugLoc(),
4815*9880d681SAndroid Build Coastguard Worker                                     VTList, MemVT, MMO, SuccessOrdering,
4816*9880d681SAndroid Build Coastguard Worker                                     FailureOrdering, SynchScope);
4817*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
4818*9880d681SAndroid Build Coastguard Worker 
4819*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
4820*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
4821*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
4822*9880d681SAndroid Build Coastguard Worker }
4823*9880d681SAndroid Build Coastguard Worker 
getAtomic(unsigned Opcode,const SDLoc & dl,EVT MemVT,SDVTList VTList,ArrayRef<SDValue> Ops,MachineMemOperand * MMO,AtomicOrdering Ordering,SynchronizationScope SynchScope)4824*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
4825*9880d681SAndroid Build Coastguard Worker                                 SDVTList VTList, ArrayRef<SDValue> Ops,
4826*9880d681SAndroid Build Coastguard Worker                                 MachineMemOperand *MMO, AtomicOrdering Ordering,
4827*9880d681SAndroid Build Coastguard Worker                                 SynchronizationScope SynchScope) {
4828*9880d681SAndroid Build Coastguard Worker   return getAtomic(Opcode, dl, MemVT, VTList, Ops, MMO, Ordering,
4829*9880d681SAndroid Build Coastguard Worker                    Ordering, SynchScope);
4830*9880d681SAndroid Build Coastguard Worker }
4831*9880d681SAndroid Build Coastguard Worker 
getAtomicCmpSwap(unsigned Opcode,const SDLoc & dl,EVT MemVT,SDVTList VTs,SDValue Chain,SDValue Ptr,SDValue Cmp,SDValue Swp,MachinePointerInfo PtrInfo,unsigned Alignment,AtomicOrdering SuccessOrdering,AtomicOrdering FailureOrdering,SynchronizationScope SynchScope)4832*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAtomicCmpSwap(
4833*9880d681SAndroid Build Coastguard Worker     unsigned Opcode, const SDLoc &dl, EVT MemVT, SDVTList VTs, SDValue Chain,
4834*9880d681SAndroid Build Coastguard Worker     SDValue Ptr, SDValue Cmp, SDValue Swp, MachinePointerInfo PtrInfo,
4835*9880d681SAndroid Build Coastguard Worker     unsigned Alignment, AtomicOrdering SuccessOrdering,
4836*9880d681SAndroid Build Coastguard Worker     AtomicOrdering FailureOrdering, SynchronizationScope SynchScope) {
4837*9880d681SAndroid Build Coastguard Worker   assert(Opcode == ISD::ATOMIC_CMP_SWAP ||
4838*9880d681SAndroid Build Coastguard Worker          Opcode == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS);
4839*9880d681SAndroid Build Coastguard Worker   assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types");
4840*9880d681SAndroid Build Coastguard Worker 
4841*9880d681SAndroid Build Coastguard Worker   if (Alignment == 0)  // Ensure that codegen never sees alignment 0
4842*9880d681SAndroid Build Coastguard Worker     Alignment = getEVTAlignment(MemVT);
4843*9880d681SAndroid Build Coastguard Worker 
4844*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = getMachineFunction();
4845*9880d681SAndroid Build Coastguard Worker 
4846*9880d681SAndroid Build Coastguard Worker   // FIXME: Volatile isn't really correct; we should keep track of atomic
4847*9880d681SAndroid Build Coastguard Worker   // orderings in the memoperand.
4848*9880d681SAndroid Build Coastguard Worker   unsigned Flags = MachineMemOperand::MOVolatile;
4849*9880d681SAndroid Build Coastguard Worker   Flags |= MachineMemOperand::MOLoad;
4850*9880d681SAndroid Build Coastguard Worker   Flags |= MachineMemOperand::MOStore;
4851*9880d681SAndroid Build Coastguard Worker 
4852*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO =
4853*9880d681SAndroid Build Coastguard Worker     MF.getMachineMemOperand(PtrInfo, Flags, MemVT.getStoreSize(), Alignment);
4854*9880d681SAndroid Build Coastguard Worker 
4855*9880d681SAndroid Build Coastguard Worker   return getAtomicCmpSwap(Opcode, dl, MemVT, VTs, Chain, Ptr, Cmp, Swp, MMO,
4856*9880d681SAndroid Build Coastguard Worker                           SuccessOrdering, FailureOrdering, SynchScope);
4857*9880d681SAndroid Build Coastguard Worker }
4858*9880d681SAndroid Build Coastguard Worker 
getAtomicCmpSwap(unsigned Opcode,const SDLoc & dl,EVT MemVT,SDVTList VTs,SDValue Chain,SDValue Ptr,SDValue Cmp,SDValue Swp,MachineMemOperand * MMO,AtomicOrdering SuccessOrdering,AtomicOrdering FailureOrdering,SynchronizationScope SynchScope)4859*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl,
4860*9880d681SAndroid Build Coastguard Worker                                        EVT MemVT, SDVTList VTs, SDValue Chain,
4861*9880d681SAndroid Build Coastguard Worker                                        SDValue Ptr, SDValue Cmp, SDValue Swp,
4862*9880d681SAndroid Build Coastguard Worker                                        MachineMemOperand *MMO,
4863*9880d681SAndroid Build Coastguard Worker                                        AtomicOrdering SuccessOrdering,
4864*9880d681SAndroid Build Coastguard Worker                                        AtomicOrdering FailureOrdering,
4865*9880d681SAndroid Build Coastguard Worker                                        SynchronizationScope SynchScope) {
4866*9880d681SAndroid Build Coastguard Worker   assert(Opcode == ISD::ATOMIC_CMP_SWAP ||
4867*9880d681SAndroid Build Coastguard Worker          Opcode == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS);
4868*9880d681SAndroid Build Coastguard Worker   assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types");
4869*9880d681SAndroid Build Coastguard Worker 
4870*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {Chain, Ptr, Cmp, Swp};
4871*9880d681SAndroid Build Coastguard Worker   return getAtomic(Opcode, dl, MemVT, VTs, Ops, MMO,
4872*9880d681SAndroid Build Coastguard Worker                    SuccessOrdering, FailureOrdering, SynchScope);
4873*9880d681SAndroid Build Coastguard Worker }
4874*9880d681SAndroid Build Coastguard Worker 
getAtomic(unsigned Opcode,const SDLoc & dl,EVT MemVT,SDValue Chain,SDValue Ptr,SDValue Val,const Value * PtrVal,unsigned Alignment,AtomicOrdering Ordering,SynchronizationScope SynchScope)4875*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
4876*9880d681SAndroid Build Coastguard Worker                                 SDValue Chain, SDValue Ptr, SDValue Val,
4877*9880d681SAndroid Build Coastguard Worker                                 const Value *PtrVal, unsigned Alignment,
4878*9880d681SAndroid Build Coastguard Worker                                 AtomicOrdering Ordering,
4879*9880d681SAndroid Build Coastguard Worker                                 SynchronizationScope SynchScope) {
4880*9880d681SAndroid Build Coastguard Worker   if (Alignment == 0)  // Ensure that codegen never sees alignment 0
4881*9880d681SAndroid Build Coastguard Worker     Alignment = getEVTAlignment(MemVT);
4882*9880d681SAndroid Build Coastguard Worker 
4883*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = getMachineFunction();
4884*9880d681SAndroid Build Coastguard Worker   // An atomic store does not load. An atomic load does not store.
4885*9880d681SAndroid Build Coastguard Worker   // (An atomicrmw obviously both loads and stores.)
4886*9880d681SAndroid Build Coastguard Worker   // For now, atomics are considered to be volatile always, and they are
4887*9880d681SAndroid Build Coastguard Worker   // chained as such.
4888*9880d681SAndroid Build Coastguard Worker   // FIXME: Volatile isn't really correct; we should keep track of atomic
4889*9880d681SAndroid Build Coastguard Worker   // orderings in the memoperand.
4890*9880d681SAndroid Build Coastguard Worker   unsigned Flags = MachineMemOperand::MOVolatile;
4891*9880d681SAndroid Build Coastguard Worker   if (Opcode != ISD::ATOMIC_STORE)
4892*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOLoad;
4893*9880d681SAndroid Build Coastguard Worker   if (Opcode != ISD::ATOMIC_LOAD)
4894*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOStore;
4895*9880d681SAndroid Build Coastguard Worker 
4896*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO =
4897*9880d681SAndroid Build Coastguard Worker     MF.getMachineMemOperand(MachinePointerInfo(PtrVal), Flags,
4898*9880d681SAndroid Build Coastguard Worker                             MemVT.getStoreSize(), Alignment);
4899*9880d681SAndroid Build Coastguard Worker 
4900*9880d681SAndroid Build Coastguard Worker   return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Val, MMO,
4901*9880d681SAndroid Build Coastguard Worker                    Ordering, SynchScope);
4902*9880d681SAndroid Build Coastguard Worker }
4903*9880d681SAndroid Build Coastguard Worker 
getAtomic(unsigned Opcode,const SDLoc & dl,EVT MemVT,SDValue Chain,SDValue Ptr,SDValue Val,MachineMemOperand * MMO,AtomicOrdering Ordering,SynchronizationScope SynchScope)4904*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
4905*9880d681SAndroid Build Coastguard Worker                                 SDValue Chain, SDValue Ptr, SDValue Val,
4906*9880d681SAndroid Build Coastguard Worker                                 MachineMemOperand *MMO, AtomicOrdering Ordering,
4907*9880d681SAndroid Build Coastguard Worker                                 SynchronizationScope SynchScope) {
4908*9880d681SAndroid Build Coastguard Worker   assert((Opcode == ISD::ATOMIC_LOAD_ADD ||
4909*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_SUB ||
4910*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_AND ||
4911*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_OR ||
4912*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_XOR ||
4913*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_NAND ||
4914*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_MIN ||
4915*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_MAX ||
4916*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_UMIN ||
4917*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_LOAD_UMAX ||
4918*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_SWAP ||
4919*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::ATOMIC_STORE) &&
4920*9880d681SAndroid Build Coastguard Worker          "Invalid Atomic Op");
4921*9880d681SAndroid Build Coastguard Worker 
4922*9880d681SAndroid Build Coastguard Worker   EVT VT = Val.getValueType();
4923*9880d681SAndroid Build Coastguard Worker 
4924*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = Opcode == ISD::ATOMIC_STORE ? getVTList(MVT::Other) :
4925*9880d681SAndroid Build Coastguard Worker                                                getVTList(VT, MVT::Other);
4926*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {Chain, Ptr, Val};
4927*9880d681SAndroid Build Coastguard Worker   return getAtomic(Opcode, dl, MemVT, VTs, Ops, MMO, Ordering, SynchScope);
4928*9880d681SAndroid Build Coastguard Worker }
4929*9880d681SAndroid Build Coastguard Worker 
getAtomic(unsigned Opcode,const SDLoc & dl,EVT MemVT,EVT VT,SDValue Chain,SDValue Ptr,MachineMemOperand * MMO,AtomicOrdering Ordering,SynchronizationScope SynchScope)4930*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
4931*9880d681SAndroid Build Coastguard Worker                                 EVT VT, SDValue Chain, SDValue Ptr,
4932*9880d681SAndroid Build Coastguard Worker                                 MachineMemOperand *MMO, AtomicOrdering Ordering,
4933*9880d681SAndroid Build Coastguard Worker                                 SynchronizationScope SynchScope) {
4934*9880d681SAndroid Build Coastguard Worker   assert(Opcode == ISD::ATOMIC_LOAD && "Invalid Atomic Op");
4935*9880d681SAndroid Build Coastguard Worker 
4936*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT, MVT::Other);
4937*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {Chain, Ptr};
4938*9880d681SAndroid Build Coastguard Worker   return getAtomic(Opcode, dl, MemVT, VTs, Ops, MMO, Ordering, SynchScope);
4939*9880d681SAndroid Build Coastguard Worker }
4940*9880d681SAndroid Build Coastguard Worker 
4941*9880d681SAndroid Build Coastguard Worker /// getMergeValues - Create a MERGE_VALUES node from the given operands.
getMergeValues(ArrayRef<SDValue> Ops,const SDLoc & dl)4942*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMergeValues(ArrayRef<SDValue> Ops, const SDLoc &dl) {
4943*9880d681SAndroid Build Coastguard Worker   if (Ops.size() == 1)
4944*9880d681SAndroid Build Coastguard Worker     return Ops[0];
4945*9880d681SAndroid Build Coastguard Worker 
4946*9880d681SAndroid Build Coastguard Worker   SmallVector<EVT, 4> VTs;
4947*9880d681SAndroid Build Coastguard Worker   VTs.reserve(Ops.size());
4948*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < Ops.size(); ++i)
4949*9880d681SAndroid Build Coastguard Worker     VTs.push_back(Ops[i].getValueType());
4950*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::MERGE_VALUES, dl, getVTList(VTs), Ops);
4951*9880d681SAndroid Build Coastguard Worker }
4952*9880d681SAndroid Build Coastguard Worker 
getMemIntrinsicNode(unsigned Opcode,const SDLoc & dl,SDVTList VTList,ArrayRef<SDValue> Ops,EVT MemVT,MachinePointerInfo PtrInfo,unsigned Align,bool Vol,bool ReadMem,bool WriteMem,unsigned Size)4953*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMemIntrinsicNode(
4954*9880d681SAndroid Build Coastguard Worker     unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef<SDValue> Ops,
4955*9880d681SAndroid Build Coastguard Worker     EVT MemVT, MachinePointerInfo PtrInfo, unsigned Align, bool Vol,
4956*9880d681SAndroid Build Coastguard Worker     bool ReadMem, bool WriteMem, unsigned Size) {
4957*9880d681SAndroid Build Coastguard Worker   if (Align == 0)  // Ensure that codegen never sees alignment 0
4958*9880d681SAndroid Build Coastguard Worker     Align = getEVTAlignment(MemVT);
4959*9880d681SAndroid Build Coastguard Worker 
4960*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = getMachineFunction();
4961*9880d681SAndroid Build Coastguard Worker   unsigned Flags = 0;
4962*9880d681SAndroid Build Coastguard Worker   if (WriteMem)
4963*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOStore;
4964*9880d681SAndroid Build Coastguard Worker   if (ReadMem)
4965*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOLoad;
4966*9880d681SAndroid Build Coastguard Worker   if (Vol)
4967*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOVolatile;
4968*9880d681SAndroid Build Coastguard Worker   if (!Size)
4969*9880d681SAndroid Build Coastguard Worker     Size = MemVT.getStoreSize();
4970*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO =
4971*9880d681SAndroid Build Coastguard Worker     MF.getMachineMemOperand(PtrInfo, Flags, Size, Align);
4972*9880d681SAndroid Build Coastguard Worker 
4973*9880d681SAndroid Build Coastguard Worker   return getMemIntrinsicNode(Opcode, dl, VTList, Ops, MemVT, MMO);
4974*9880d681SAndroid Build Coastguard Worker }
4975*9880d681SAndroid Build Coastguard Worker 
getMemIntrinsicNode(unsigned Opcode,const SDLoc & dl,SDVTList VTList,ArrayRef<SDValue> Ops,EVT MemVT,MachineMemOperand * MMO)4976*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl,
4977*9880d681SAndroid Build Coastguard Worker                                           SDVTList VTList,
4978*9880d681SAndroid Build Coastguard Worker                                           ArrayRef<SDValue> Ops, EVT MemVT,
4979*9880d681SAndroid Build Coastguard Worker                                           MachineMemOperand *MMO) {
4980*9880d681SAndroid Build Coastguard Worker   assert((Opcode == ISD::INTRINSIC_VOID ||
4981*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::INTRINSIC_W_CHAIN ||
4982*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::PREFETCH ||
4983*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::LIFETIME_START ||
4984*9880d681SAndroid Build Coastguard Worker           Opcode == ISD::LIFETIME_END ||
4985*9880d681SAndroid Build Coastguard Worker           (Opcode <= INT_MAX &&
4986*9880d681SAndroid Build Coastguard Worker            (int)Opcode >= ISD::FIRST_TARGET_MEMORY_OPCODE)) &&
4987*9880d681SAndroid Build Coastguard Worker          "Opcode is not a memory-accessing opcode!");
4988*9880d681SAndroid Build Coastguard Worker 
4989*9880d681SAndroid Build Coastguard Worker   // Memoize the node unless it returns a flag.
4990*9880d681SAndroid Build Coastguard Worker   MemIntrinsicSDNode *N;
4991*9880d681SAndroid Build Coastguard Worker   if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) {
4992*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
4993*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opcode, VTList, Ops);
4994*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
4995*9880d681SAndroid Build Coastguard Worker     void *IP = nullptr;
4996*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
4997*9880d681SAndroid Build Coastguard Worker       cast<MemIntrinsicSDNode>(E)->refineAlignment(MMO);
4998*9880d681SAndroid Build Coastguard Worker       return SDValue(E, 0);
4999*9880d681SAndroid Build Coastguard Worker     }
5000*9880d681SAndroid Build Coastguard Worker 
5001*9880d681SAndroid Build Coastguard Worker     N = newSDNode<MemIntrinsicSDNode>(Opcode, dl.getIROrder(), dl.getDebugLoc(),
5002*9880d681SAndroid Build Coastguard Worker                                       VTList, MemVT, MMO);
5003*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
5004*9880d681SAndroid Build Coastguard Worker 
5005*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5006*9880d681SAndroid Build Coastguard Worker   } else {
5007*9880d681SAndroid Build Coastguard Worker     N = newSDNode<MemIntrinsicSDNode>(Opcode, dl.getIROrder(), dl.getDebugLoc(),
5008*9880d681SAndroid Build Coastguard Worker                                       VTList, MemVT, MMO);
5009*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
5010*9880d681SAndroid Build Coastguard Worker   }
5011*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5012*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5013*9880d681SAndroid Build Coastguard Worker }
5014*9880d681SAndroid Build Coastguard Worker 
5015*9880d681SAndroid Build Coastguard Worker /// InferPointerInfo - If the specified ptr/offset is a frame index, infer a
5016*9880d681SAndroid Build Coastguard Worker /// MachinePointerInfo record from it.  This is particularly useful because the
5017*9880d681SAndroid Build Coastguard Worker /// code generator has many cases where it doesn't bother passing in a
5018*9880d681SAndroid Build Coastguard Worker /// MachinePointerInfo to getLoad or getStore when it has "FI+Cst".
InferPointerInfo(SelectionDAG & DAG,SDValue Ptr,int64_t Offset=0)5019*9880d681SAndroid Build Coastguard Worker static MachinePointerInfo InferPointerInfo(SelectionDAG &DAG, SDValue Ptr,
5020*9880d681SAndroid Build Coastguard Worker                                            int64_t Offset = 0) {
5021*9880d681SAndroid Build Coastguard Worker   // If this is FI+Offset, we can model it.
5022*9880d681SAndroid Build Coastguard Worker   if (const FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Ptr))
5023*9880d681SAndroid Build Coastguard Worker     return MachinePointerInfo::getFixedStack(DAG.getMachineFunction(),
5024*9880d681SAndroid Build Coastguard Worker                                              FI->getIndex(), Offset);
5025*9880d681SAndroid Build Coastguard Worker 
5026*9880d681SAndroid Build Coastguard Worker   // If this is (FI+Offset1)+Offset2, we can model it.
5027*9880d681SAndroid Build Coastguard Worker   if (Ptr.getOpcode() != ISD::ADD ||
5028*9880d681SAndroid Build Coastguard Worker       !isa<ConstantSDNode>(Ptr.getOperand(1)) ||
5029*9880d681SAndroid Build Coastguard Worker       !isa<FrameIndexSDNode>(Ptr.getOperand(0)))
5030*9880d681SAndroid Build Coastguard Worker     return MachinePointerInfo();
5031*9880d681SAndroid Build Coastguard Worker 
5032*9880d681SAndroid Build Coastguard Worker   int FI = cast<FrameIndexSDNode>(Ptr.getOperand(0))->getIndex();
5033*9880d681SAndroid Build Coastguard Worker   return MachinePointerInfo::getFixedStack(
5034*9880d681SAndroid Build Coastguard Worker       DAG.getMachineFunction(), FI,
5035*9880d681SAndroid Build Coastguard Worker       Offset + cast<ConstantSDNode>(Ptr.getOperand(1))->getSExtValue());
5036*9880d681SAndroid Build Coastguard Worker }
5037*9880d681SAndroid Build Coastguard Worker 
5038*9880d681SAndroid Build Coastguard Worker /// InferPointerInfo - If the specified ptr/offset is a frame index, infer a
5039*9880d681SAndroid Build Coastguard Worker /// MachinePointerInfo record from it.  This is particularly useful because the
5040*9880d681SAndroid Build Coastguard Worker /// code generator has many cases where it doesn't bother passing in a
5041*9880d681SAndroid Build Coastguard Worker /// MachinePointerInfo to getLoad or getStore when it has "FI+Cst".
InferPointerInfo(SelectionDAG & DAG,SDValue Ptr,SDValue OffsetOp)5042*9880d681SAndroid Build Coastguard Worker static MachinePointerInfo InferPointerInfo(SelectionDAG &DAG, SDValue Ptr,
5043*9880d681SAndroid Build Coastguard Worker                                            SDValue OffsetOp) {
5044*9880d681SAndroid Build Coastguard Worker   // If the 'Offset' value isn't a constant, we can't handle this.
5045*9880d681SAndroid Build Coastguard Worker   if (ConstantSDNode *OffsetNode = dyn_cast<ConstantSDNode>(OffsetOp))
5046*9880d681SAndroid Build Coastguard Worker     return InferPointerInfo(DAG, Ptr, OffsetNode->getSExtValue());
5047*9880d681SAndroid Build Coastguard Worker   if (OffsetOp.isUndef())
5048*9880d681SAndroid Build Coastguard Worker     return InferPointerInfo(DAG, Ptr);
5049*9880d681SAndroid Build Coastguard Worker   return MachinePointerInfo();
5050*9880d681SAndroid Build Coastguard Worker }
5051*9880d681SAndroid Build Coastguard Worker 
getLoad(ISD::MemIndexedMode AM,ISD::LoadExtType ExtType,EVT VT,const SDLoc & dl,SDValue Chain,SDValue Ptr,SDValue Offset,MachinePointerInfo PtrInfo,EVT MemVT,bool isVolatile,bool isNonTemporal,bool isInvariant,unsigned Alignment,const AAMDNodes & AAInfo,const MDNode * Ranges)5052*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
5053*9880d681SAndroid Build Coastguard Worker                               EVT VT, const SDLoc &dl, SDValue Chain,
5054*9880d681SAndroid Build Coastguard Worker                               SDValue Ptr, SDValue Offset,
5055*9880d681SAndroid Build Coastguard Worker                               MachinePointerInfo PtrInfo, EVT MemVT,
5056*9880d681SAndroid Build Coastguard Worker                               bool isVolatile, bool isNonTemporal,
5057*9880d681SAndroid Build Coastguard Worker                               bool isInvariant, unsigned Alignment,
5058*9880d681SAndroid Build Coastguard Worker                               const AAMDNodes &AAInfo, const MDNode *Ranges) {
5059*9880d681SAndroid Build Coastguard Worker   assert(Chain.getValueType() == MVT::Other &&
5060*9880d681SAndroid Build Coastguard Worker         "Invalid chain type");
5061*9880d681SAndroid Build Coastguard Worker   if (Alignment == 0)  // Ensure that codegen never sees alignment 0
5062*9880d681SAndroid Build Coastguard Worker     Alignment = getEVTAlignment(VT);
5063*9880d681SAndroid Build Coastguard Worker 
5064*9880d681SAndroid Build Coastguard Worker   unsigned Flags = MachineMemOperand::MOLoad;
5065*9880d681SAndroid Build Coastguard Worker   if (isVolatile)
5066*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOVolatile;
5067*9880d681SAndroid Build Coastguard Worker   if (isNonTemporal)
5068*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MONonTemporal;
5069*9880d681SAndroid Build Coastguard Worker   if (isInvariant)
5070*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOInvariant;
5071*9880d681SAndroid Build Coastguard Worker 
5072*9880d681SAndroid Build Coastguard Worker   // If we don't have a PtrInfo, infer the trivial frame index case to simplify
5073*9880d681SAndroid Build Coastguard Worker   // clients.
5074*9880d681SAndroid Build Coastguard Worker   if (PtrInfo.V.isNull())
5075*9880d681SAndroid Build Coastguard Worker     PtrInfo = InferPointerInfo(*this, Ptr, Offset);
5076*9880d681SAndroid Build Coastguard Worker 
5077*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = getMachineFunction();
5078*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO =
5079*9880d681SAndroid Build Coastguard Worker     MF.getMachineMemOperand(PtrInfo, Flags, MemVT.getStoreSize(), Alignment,
5080*9880d681SAndroid Build Coastguard Worker                             AAInfo, Ranges);
5081*9880d681SAndroid Build Coastguard Worker   return getLoad(AM, ExtType, VT, dl, Chain, Ptr, Offset, MemVT, MMO);
5082*9880d681SAndroid Build Coastguard Worker }
5083*9880d681SAndroid Build Coastguard Worker 
getLoad(ISD::MemIndexedMode AM,ISD::LoadExtType ExtType,EVT VT,const SDLoc & dl,SDValue Chain,SDValue Ptr,SDValue Offset,EVT MemVT,MachineMemOperand * MMO)5084*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
5085*9880d681SAndroid Build Coastguard Worker                               EVT VT, const SDLoc &dl, SDValue Chain,
5086*9880d681SAndroid Build Coastguard Worker                               SDValue Ptr, SDValue Offset, EVT MemVT,
5087*9880d681SAndroid Build Coastguard Worker                               MachineMemOperand *MMO) {
5088*9880d681SAndroid Build Coastguard Worker   if (VT == MemVT) {
5089*9880d681SAndroid Build Coastguard Worker     ExtType = ISD::NON_EXTLOAD;
5090*9880d681SAndroid Build Coastguard Worker   } else if (ExtType == ISD::NON_EXTLOAD) {
5091*9880d681SAndroid Build Coastguard Worker     assert(VT == MemVT && "Non-extending load from different memory type!");
5092*9880d681SAndroid Build Coastguard Worker   } else {
5093*9880d681SAndroid Build Coastguard Worker     // Extending load.
5094*9880d681SAndroid Build Coastguard Worker     assert(MemVT.getScalarType().bitsLT(VT.getScalarType()) &&
5095*9880d681SAndroid Build Coastguard Worker            "Should only be an extending load, not truncating!");
5096*9880d681SAndroid Build Coastguard Worker     assert(VT.isInteger() == MemVT.isInteger() &&
5097*9880d681SAndroid Build Coastguard Worker            "Cannot convert from FP to Int or Int -> FP!");
5098*9880d681SAndroid Build Coastguard Worker     assert(VT.isVector() == MemVT.isVector() &&
5099*9880d681SAndroid Build Coastguard Worker            "Cannot use an ext load to convert to or from a vector!");
5100*9880d681SAndroid Build Coastguard Worker     assert((!VT.isVector() ||
5101*9880d681SAndroid Build Coastguard Worker             VT.getVectorNumElements() == MemVT.getVectorNumElements()) &&
5102*9880d681SAndroid Build Coastguard Worker            "Cannot use an ext load to change the number of vector elements!");
5103*9880d681SAndroid Build Coastguard Worker   }
5104*9880d681SAndroid Build Coastguard Worker 
5105*9880d681SAndroid Build Coastguard Worker   bool Indexed = AM != ISD::UNINDEXED;
5106*9880d681SAndroid Build Coastguard Worker   assert((Indexed || Offset.isUndef()) && "Unindexed load with an offset!");
5107*9880d681SAndroid Build Coastguard Worker 
5108*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = Indexed ?
5109*9880d681SAndroid Build Coastguard Worker     getVTList(VT, Ptr.getValueType(), MVT::Other) : getVTList(VT, MVT::Other);
5110*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Chain, Ptr, Offset };
5111*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5112*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::LOAD, VTs, Ops);
5113*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MemVT.getRawBits());
5114*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, MMO->isVolatile(),
5115*9880d681SAndroid Build Coastguard Worker                                      MMO->isNonTemporal(),
5116*9880d681SAndroid Build Coastguard Worker                                      MMO->isInvariant()));
5117*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
5118*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5119*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
5120*9880d681SAndroid Build Coastguard Worker     cast<LoadSDNode>(E)->refineAlignment(MMO);
5121*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5122*9880d681SAndroid Build Coastguard Worker   }
5123*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<LoadSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs, AM,
5124*9880d681SAndroid Build Coastguard Worker                                   ExtType, MemVT, MMO);
5125*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5126*9880d681SAndroid Build Coastguard Worker 
5127*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5128*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5129*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5130*9880d681SAndroid Build Coastguard Worker }
5131*9880d681SAndroid Build Coastguard Worker 
getLoad(EVT VT,const SDLoc & dl,SDValue Chain,SDValue Ptr,MachinePointerInfo PtrInfo,bool isVolatile,bool isNonTemporal,bool isInvariant,unsigned Alignment,const AAMDNodes & AAInfo,const MDNode * Ranges)5132*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getLoad(EVT VT, const SDLoc &dl, SDValue Chain,
5133*9880d681SAndroid Build Coastguard Worker                               SDValue Ptr, MachinePointerInfo PtrInfo,
5134*9880d681SAndroid Build Coastguard Worker                               bool isVolatile, bool isNonTemporal,
5135*9880d681SAndroid Build Coastguard Worker                               bool isInvariant, unsigned Alignment,
5136*9880d681SAndroid Build Coastguard Worker                               const AAMDNodes &AAInfo, const MDNode *Ranges) {
5137*9880d681SAndroid Build Coastguard Worker   SDValue Undef = getUNDEF(Ptr.getValueType());
5138*9880d681SAndroid Build Coastguard Worker   return getLoad(ISD::UNINDEXED, ISD::NON_EXTLOAD, VT, dl, Chain, Ptr, Undef,
5139*9880d681SAndroid Build Coastguard Worker                  PtrInfo, VT, isVolatile, isNonTemporal, isInvariant, Alignment,
5140*9880d681SAndroid Build Coastguard Worker                  AAInfo, Ranges);
5141*9880d681SAndroid Build Coastguard Worker }
5142*9880d681SAndroid Build Coastguard Worker 
getLoad(EVT VT,const SDLoc & dl,SDValue Chain,SDValue Ptr,MachineMemOperand * MMO)5143*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getLoad(EVT VT, const SDLoc &dl, SDValue Chain,
5144*9880d681SAndroid Build Coastguard Worker                               SDValue Ptr, MachineMemOperand *MMO) {
5145*9880d681SAndroid Build Coastguard Worker   SDValue Undef = getUNDEF(Ptr.getValueType());
5146*9880d681SAndroid Build Coastguard Worker   return getLoad(ISD::UNINDEXED, ISD::NON_EXTLOAD, VT, dl, Chain, Ptr, Undef,
5147*9880d681SAndroid Build Coastguard Worker                  VT, MMO);
5148*9880d681SAndroid Build Coastguard Worker }
5149*9880d681SAndroid Build Coastguard Worker 
getExtLoad(ISD::LoadExtType ExtType,const SDLoc & dl,EVT VT,SDValue Chain,SDValue Ptr,MachinePointerInfo PtrInfo,EVT MemVT,bool isVolatile,bool isNonTemporal,bool isInvariant,unsigned Alignment,const AAMDNodes & AAInfo)5150*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl,
5151*9880d681SAndroid Build Coastguard Worker                                  EVT VT, SDValue Chain, SDValue Ptr,
5152*9880d681SAndroid Build Coastguard Worker                                  MachinePointerInfo PtrInfo, EVT MemVT,
5153*9880d681SAndroid Build Coastguard Worker                                  bool isVolatile, bool isNonTemporal,
5154*9880d681SAndroid Build Coastguard Worker                                  bool isInvariant, unsigned Alignment,
5155*9880d681SAndroid Build Coastguard Worker                                  const AAMDNodes &AAInfo) {
5156*9880d681SAndroid Build Coastguard Worker   SDValue Undef = getUNDEF(Ptr.getValueType());
5157*9880d681SAndroid Build Coastguard Worker   return getLoad(ISD::UNINDEXED, ExtType, VT, dl, Chain, Ptr, Undef,
5158*9880d681SAndroid Build Coastguard Worker                  PtrInfo, MemVT, isVolatile, isNonTemporal, isInvariant,
5159*9880d681SAndroid Build Coastguard Worker                  Alignment, AAInfo);
5160*9880d681SAndroid Build Coastguard Worker }
5161*9880d681SAndroid Build Coastguard Worker 
getExtLoad(ISD::LoadExtType ExtType,const SDLoc & dl,EVT VT,SDValue Chain,SDValue Ptr,EVT MemVT,MachineMemOperand * MMO)5162*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl,
5163*9880d681SAndroid Build Coastguard Worker                                  EVT VT, SDValue Chain, SDValue Ptr, EVT MemVT,
5164*9880d681SAndroid Build Coastguard Worker                                  MachineMemOperand *MMO) {
5165*9880d681SAndroid Build Coastguard Worker   SDValue Undef = getUNDEF(Ptr.getValueType());
5166*9880d681SAndroid Build Coastguard Worker   return getLoad(ISD::UNINDEXED, ExtType, VT, dl, Chain, Ptr, Undef,
5167*9880d681SAndroid Build Coastguard Worker                  MemVT, MMO);
5168*9880d681SAndroid Build Coastguard Worker }
5169*9880d681SAndroid Build Coastguard Worker 
getIndexedLoad(SDValue OrigLoad,const SDLoc & dl,SDValue Base,SDValue Offset,ISD::MemIndexedMode AM)5170*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getIndexedLoad(SDValue OrigLoad, const SDLoc &dl,
5171*9880d681SAndroid Build Coastguard Worker                                      SDValue Base, SDValue Offset,
5172*9880d681SAndroid Build Coastguard Worker                                      ISD::MemIndexedMode AM) {
5173*9880d681SAndroid Build Coastguard Worker   LoadSDNode *LD = cast<LoadSDNode>(OrigLoad);
5174*9880d681SAndroid Build Coastguard Worker   assert(LD->getOffset().isUndef() && "Load is already a indexed load!");
5175*9880d681SAndroid Build Coastguard Worker   return getLoad(AM, LD->getExtensionType(), OrigLoad.getValueType(), dl,
5176*9880d681SAndroid Build Coastguard Worker                  LD->getChain(), Base, Offset, LD->getPointerInfo(),
5177*9880d681SAndroid Build Coastguard Worker                  LD->getMemoryVT(), LD->isVolatile(), LD->isNonTemporal(),
5178*9880d681SAndroid Build Coastguard Worker                  false, LD->getAlignment());
5179*9880d681SAndroid Build Coastguard Worker }
5180*9880d681SAndroid Build Coastguard Worker 
getStore(SDValue Chain,const SDLoc & dl,SDValue Val,SDValue Ptr,MachinePointerInfo PtrInfo,bool isVolatile,bool isNonTemporal,unsigned Alignment,const AAMDNodes & AAInfo)5181*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getStore(SDValue Chain, const SDLoc &dl, SDValue Val,
5182*9880d681SAndroid Build Coastguard Worker                                SDValue Ptr, MachinePointerInfo PtrInfo,
5183*9880d681SAndroid Build Coastguard Worker                                bool isVolatile, bool isNonTemporal,
5184*9880d681SAndroid Build Coastguard Worker                                unsigned Alignment, const AAMDNodes &AAInfo) {
5185*9880d681SAndroid Build Coastguard Worker   assert(Chain.getValueType() == MVT::Other && "Invalid chain type");
5186*9880d681SAndroid Build Coastguard Worker   if (Alignment == 0)  // Ensure that codegen never sees alignment 0
5187*9880d681SAndroid Build Coastguard Worker     Alignment = getEVTAlignment(Val.getValueType());
5188*9880d681SAndroid Build Coastguard Worker 
5189*9880d681SAndroid Build Coastguard Worker   unsigned Flags = MachineMemOperand::MOStore;
5190*9880d681SAndroid Build Coastguard Worker   if (isVolatile)
5191*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOVolatile;
5192*9880d681SAndroid Build Coastguard Worker   if (isNonTemporal)
5193*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MONonTemporal;
5194*9880d681SAndroid Build Coastguard Worker 
5195*9880d681SAndroid Build Coastguard Worker   if (PtrInfo.V.isNull())
5196*9880d681SAndroid Build Coastguard Worker     PtrInfo = InferPointerInfo(*this, Ptr);
5197*9880d681SAndroid Build Coastguard Worker 
5198*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = getMachineFunction();
5199*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO =
5200*9880d681SAndroid Build Coastguard Worker     MF.getMachineMemOperand(PtrInfo, Flags,
5201*9880d681SAndroid Build Coastguard Worker                             Val.getValueType().getStoreSize(), Alignment,
5202*9880d681SAndroid Build Coastguard Worker                             AAInfo);
5203*9880d681SAndroid Build Coastguard Worker 
5204*9880d681SAndroid Build Coastguard Worker   return getStore(Chain, dl, Val, Ptr, MMO);
5205*9880d681SAndroid Build Coastguard Worker }
5206*9880d681SAndroid Build Coastguard Worker 
getStore(SDValue Chain,const SDLoc & dl,SDValue Val,SDValue Ptr,MachineMemOperand * MMO)5207*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getStore(SDValue Chain, const SDLoc &dl, SDValue Val,
5208*9880d681SAndroid Build Coastguard Worker                                SDValue Ptr, MachineMemOperand *MMO) {
5209*9880d681SAndroid Build Coastguard Worker   assert(Chain.getValueType() == MVT::Other &&
5210*9880d681SAndroid Build Coastguard Worker         "Invalid chain type");
5211*9880d681SAndroid Build Coastguard Worker   EVT VT = Val.getValueType();
5212*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(MVT::Other);
5213*9880d681SAndroid Build Coastguard Worker   SDValue Undef = getUNDEF(Ptr.getValueType());
5214*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Chain, Val, Ptr, Undef };
5215*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5216*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::STORE, VTs, Ops);
5217*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT.getRawBits());
5218*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, MMO->isVolatile(),
5219*9880d681SAndroid Build Coastguard Worker                                      MMO->isNonTemporal(), MMO->isInvariant()));
5220*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
5221*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5222*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
5223*9880d681SAndroid Build Coastguard Worker     cast<StoreSDNode>(E)->refineAlignment(MMO);
5224*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5225*9880d681SAndroid Build Coastguard Worker   }
5226*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<StoreSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs,
5227*9880d681SAndroid Build Coastguard Worker                                    ISD::UNINDEXED, false, VT, MMO);
5228*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5229*9880d681SAndroid Build Coastguard Worker 
5230*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5231*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5232*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5233*9880d681SAndroid Build Coastguard Worker }
5234*9880d681SAndroid Build Coastguard Worker 
getTruncStore(SDValue Chain,const SDLoc & dl,SDValue Val,SDValue Ptr,MachinePointerInfo PtrInfo,EVT SVT,bool isVolatile,bool isNonTemporal,unsigned Alignment,const AAMDNodes & AAInfo)5235*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val,
5236*9880d681SAndroid Build Coastguard Worker                                     SDValue Ptr, MachinePointerInfo PtrInfo,
5237*9880d681SAndroid Build Coastguard Worker                                     EVT SVT, bool isVolatile,
5238*9880d681SAndroid Build Coastguard Worker                                     bool isNonTemporal, unsigned Alignment,
5239*9880d681SAndroid Build Coastguard Worker                                     const AAMDNodes &AAInfo) {
5240*9880d681SAndroid Build Coastguard Worker   assert(Chain.getValueType() == MVT::Other &&
5241*9880d681SAndroid Build Coastguard Worker         "Invalid chain type");
5242*9880d681SAndroid Build Coastguard Worker   if (Alignment == 0)  // Ensure that codegen never sees alignment 0
5243*9880d681SAndroid Build Coastguard Worker     Alignment = getEVTAlignment(SVT);
5244*9880d681SAndroid Build Coastguard Worker 
5245*9880d681SAndroid Build Coastguard Worker   unsigned Flags = MachineMemOperand::MOStore;
5246*9880d681SAndroid Build Coastguard Worker   if (isVolatile)
5247*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MOVolatile;
5248*9880d681SAndroid Build Coastguard Worker   if (isNonTemporal)
5249*9880d681SAndroid Build Coastguard Worker     Flags |= MachineMemOperand::MONonTemporal;
5250*9880d681SAndroid Build Coastguard Worker 
5251*9880d681SAndroid Build Coastguard Worker   if (PtrInfo.V.isNull())
5252*9880d681SAndroid Build Coastguard Worker     PtrInfo = InferPointerInfo(*this, Ptr);
5253*9880d681SAndroid Build Coastguard Worker 
5254*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = getMachineFunction();
5255*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO =
5256*9880d681SAndroid Build Coastguard Worker     MF.getMachineMemOperand(PtrInfo, Flags, SVT.getStoreSize(), Alignment,
5257*9880d681SAndroid Build Coastguard Worker                             AAInfo);
5258*9880d681SAndroid Build Coastguard Worker 
5259*9880d681SAndroid Build Coastguard Worker   return getTruncStore(Chain, dl, Val, Ptr, SVT, MMO);
5260*9880d681SAndroid Build Coastguard Worker }
5261*9880d681SAndroid Build Coastguard Worker 
getTruncStore(SDValue Chain,const SDLoc & dl,SDValue Val,SDValue Ptr,EVT SVT,MachineMemOperand * MMO)5262*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val,
5263*9880d681SAndroid Build Coastguard Worker                                     SDValue Ptr, EVT SVT,
5264*9880d681SAndroid Build Coastguard Worker                                     MachineMemOperand *MMO) {
5265*9880d681SAndroid Build Coastguard Worker   EVT VT = Val.getValueType();
5266*9880d681SAndroid Build Coastguard Worker 
5267*9880d681SAndroid Build Coastguard Worker   assert(Chain.getValueType() == MVT::Other &&
5268*9880d681SAndroid Build Coastguard Worker         "Invalid chain type");
5269*9880d681SAndroid Build Coastguard Worker   if (VT == SVT)
5270*9880d681SAndroid Build Coastguard Worker     return getStore(Chain, dl, Val, Ptr, MMO);
5271*9880d681SAndroid Build Coastguard Worker 
5272*9880d681SAndroid Build Coastguard Worker   assert(SVT.getScalarType().bitsLT(VT.getScalarType()) &&
5273*9880d681SAndroid Build Coastguard Worker          "Should only be a truncating store, not extending!");
5274*9880d681SAndroid Build Coastguard Worker   assert(VT.isInteger() == SVT.isInteger() &&
5275*9880d681SAndroid Build Coastguard Worker          "Can't do FP-INT conversion!");
5276*9880d681SAndroid Build Coastguard Worker   assert(VT.isVector() == SVT.isVector() &&
5277*9880d681SAndroid Build Coastguard Worker          "Cannot use trunc store to convert to or from a vector!");
5278*9880d681SAndroid Build Coastguard Worker   assert((!VT.isVector() ||
5279*9880d681SAndroid Build Coastguard Worker           VT.getVectorNumElements() == SVT.getVectorNumElements()) &&
5280*9880d681SAndroid Build Coastguard Worker          "Cannot use trunc store to change the number of vector elements!");
5281*9880d681SAndroid Build Coastguard Worker 
5282*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(MVT::Other);
5283*9880d681SAndroid Build Coastguard Worker   SDValue Undef = getUNDEF(Ptr.getValueType());
5284*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Chain, Val, Ptr, Undef };
5285*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5286*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::STORE, VTs, Ops);
5287*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(SVT.getRawBits());
5288*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED, MMO->isVolatile(),
5289*9880d681SAndroid Build Coastguard Worker                                      MMO->isNonTemporal(), MMO->isInvariant()));
5290*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
5291*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5292*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
5293*9880d681SAndroid Build Coastguard Worker     cast<StoreSDNode>(E)->refineAlignment(MMO);
5294*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5295*9880d681SAndroid Build Coastguard Worker   }
5296*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<StoreSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs,
5297*9880d681SAndroid Build Coastguard Worker                                    ISD::UNINDEXED, true, SVT, MMO);
5298*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5299*9880d681SAndroid Build Coastguard Worker 
5300*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5301*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5302*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5303*9880d681SAndroid Build Coastguard Worker }
5304*9880d681SAndroid Build Coastguard Worker 
getIndexedStore(SDValue OrigStore,const SDLoc & dl,SDValue Base,SDValue Offset,ISD::MemIndexedMode AM)5305*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getIndexedStore(SDValue OrigStore, const SDLoc &dl,
5306*9880d681SAndroid Build Coastguard Worker                                       SDValue Base, SDValue Offset,
5307*9880d681SAndroid Build Coastguard Worker                                       ISD::MemIndexedMode AM) {
5308*9880d681SAndroid Build Coastguard Worker   StoreSDNode *ST = cast<StoreSDNode>(OrigStore);
5309*9880d681SAndroid Build Coastguard Worker   assert(ST->getOffset().isUndef() && "Store is already a indexed store!");
5310*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(Base.getValueType(), MVT::Other);
5311*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
5312*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5313*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::STORE, VTs, Ops);
5314*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(ST->getMemoryVT().getRawBits());
5315*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(ST->getRawSubclassData());
5316*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(ST->getPointerInfo().getAddrSpace());
5317*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5318*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP))
5319*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5320*9880d681SAndroid Build Coastguard Worker 
5321*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<StoreSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs, AM,
5322*9880d681SAndroid Build Coastguard Worker                                    ST->isTruncatingStore(), ST->getMemoryVT(),
5323*9880d681SAndroid Build Coastguard Worker                                    ST->getMemOperand());
5324*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5325*9880d681SAndroid Build Coastguard Worker 
5326*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5327*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5328*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5329*9880d681SAndroid Build Coastguard Worker }
5330*9880d681SAndroid Build Coastguard Worker 
getMaskedLoad(EVT VT,const SDLoc & dl,SDValue Chain,SDValue Ptr,SDValue Mask,SDValue Src0,EVT MemVT,MachineMemOperand * MMO,ISD::LoadExtType ExtTy)5331*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain,
5332*9880d681SAndroid Build Coastguard Worker                                     SDValue Ptr, SDValue Mask, SDValue Src0,
5333*9880d681SAndroid Build Coastguard Worker                                     EVT MemVT, MachineMemOperand *MMO,
5334*9880d681SAndroid Build Coastguard Worker                                     ISD::LoadExtType ExtTy) {
5335*9880d681SAndroid Build Coastguard Worker 
5336*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT, MVT::Other);
5337*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Chain, Ptr, Mask, Src0 };
5338*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5339*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::MLOAD, VTs, Ops);
5340*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT.getRawBits());
5341*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(encodeMemSDNodeFlags(ExtTy, ISD::UNINDEXED,
5342*9880d681SAndroid Build Coastguard Worker                                      MMO->isVolatile(),
5343*9880d681SAndroid Build Coastguard Worker                                      MMO->isNonTemporal(),
5344*9880d681SAndroid Build Coastguard Worker                                      MMO->isInvariant()));
5345*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
5346*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5347*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
5348*9880d681SAndroid Build Coastguard Worker     cast<MaskedLoadSDNode>(E)->refineAlignment(MMO);
5349*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5350*9880d681SAndroid Build Coastguard Worker   }
5351*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<MaskedLoadSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs,
5352*9880d681SAndroid Build Coastguard Worker                                         ExtTy, MemVT, MMO);
5353*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5354*9880d681SAndroid Build Coastguard Worker 
5355*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5356*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5357*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5358*9880d681SAndroid Build Coastguard Worker }
5359*9880d681SAndroid Build Coastguard Worker 
getMaskedStore(SDValue Chain,const SDLoc & dl,SDValue Val,SDValue Ptr,SDValue Mask,EVT MemVT,MachineMemOperand * MMO,bool isTrunc)5360*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMaskedStore(SDValue Chain, const SDLoc &dl,
5361*9880d681SAndroid Build Coastguard Worker                                      SDValue Val, SDValue Ptr, SDValue Mask,
5362*9880d681SAndroid Build Coastguard Worker                                      EVT MemVT, MachineMemOperand *MMO,
5363*9880d681SAndroid Build Coastguard Worker                                      bool isTrunc) {
5364*9880d681SAndroid Build Coastguard Worker   assert(Chain.getValueType() == MVT::Other &&
5365*9880d681SAndroid Build Coastguard Worker         "Invalid chain type");
5366*9880d681SAndroid Build Coastguard Worker   EVT VT = Val.getValueType();
5367*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(MVT::Other);
5368*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Chain, Ptr, Mask, Val };
5369*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5370*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::MSTORE, VTs, Ops);
5371*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT.getRawBits());
5372*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, MMO->isVolatile(),
5373*9880d681SAndroid Build Coastguard Worker                                      MMO->isNonTemporal(), MMO->isInvariant()));
5374*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
5375*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5376*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
5377*9880d681SAndroid Build Coastguard Worker     cast<MaskedStoreSDNode>(E)->refineAlignment(MMO);
5378*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5379*9880d681SAndroid Build Coastguard Worker   }
5380*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<MaskedStoreSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs,
5381*9880d681SAndroid Build Coastguard Worker                                          isTrunc, MemVT, MMO);
5382*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5383*9880d681SAndroid Build Coastguard Worker 
5384*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5385*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5386*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5387*9880d681SAndroid Build Coastguard Worker }
5388*9880d681SAndroid Build Coastguard Worker 
getMaskedGather(SDVTList VTs,EVT VT,const SDLoc & dl,ArrayRef<SDValue> Ops,MachineMemOperand * MMO)5389*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl,
5390*9880d681SAndroid Build Coastguard Worker                                       ArrayRef<SDValue> Ops,
5391*9880d681SAndroid Build Coastguard Worker                                       MachineMemOperand *MMO) {
5392*9880d681SAndroid Build Coastguard Worker   assert(Ops.size() == 5 && "Incompatible number of operands");
5393*9880d681SAndroid Build Coastguard Worker 
5394*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5395*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::MGATHER, VTs, Ops);
5396*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT.getRawBits());
5397*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(encodeMemSDNodeFlags(ISD::NON_EXTLOAD, ISD::UNINDEXED,
5398*9880d681SAndroid Build Coastguard Worker                                      MMO->isVolatile(),
5399*9880d681SAndroid Build Coastguard Worker                                      MMO->isNonTemporal(),
5400*9880d681SAndroid Build Coastguard Worker                                      MMO->isInvariant()));
5401*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
5402*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5403*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
5404*9880d681SAndroid Build Coastguard Worker     cast<MaskedGatherSDNode>(E)->refineAlignment(MMO);
5405*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5406*9880d681SAndroid Build Coastguard Worker   }
5407*9880d681SAndroid Build Coastguard Worker 
5408*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<MaskedGatherSDNode>(dl.getIROrder(), dl.getDebugLoc(),
5409*9880d681SAndroid Build Coastguard Worker                                           VTs, VT, MMO);
5410*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5411*9880d681SAndroid Build Coastguard Worker 
5412*9880d681SAndroid Build Coastguard Worker   assert(N->getValue().getValueType() == N->getValueType(0) &&
5413*9880d681SAndroid Build Coastguard Worker          "Incompatible type of the PassThru value in MaskedGatherSDNode");
5414*9880d681SAndroid Build Coastguard Worker   assert(N->getMask().getValueType().getVectorNumElements() ==
5415*9880d681SAndroid Build Coastguard Worker              N->getValueType(0).getVectorNumElements() &&
5416*9880d681SAndroid Build Coastguard Worker          "Vector width mismatch between mask and data");
5417*9880d681SAndroid Build Coastguard Worker   assert(N->getIndex().getValueType().getVectorNumElements() ==
5418*9880d681SAndroid Build Coastguard Worker              N->getValueType(0).getVectorNumElements() &&
5419*9880d681SAndroid Build Coastguard Worker          "Vector width mismatch between index and data");
5420*9880d681SAndroid Build Coastguard Worker 
5421*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5422*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5423*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5424*9880d681SAndroid Build Coastguard Worker }
5425*9880d681SAndroid Build Coastguard Worker 
getMaskedScatter(SDVTList VTs,EVT VT,const SDLoc & dl,ArrayRef<SDValue> Ops,MachineMemOperand * MMO)5426*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getMaskedScatter(SDVTList VTs, EVT VT, const SDLoc &dl,
5427*9880d681SAndroid Build Coastguard Worker                                        ArrayRef<SDValue> Ops,
5428*9880d681SAndroid Build Coastguard Worker                                        MachineMemOperand *MMO) {
5429*9880d681SAndroid Build Coastguard Worker   assert(Ops.size() == 5 && "Incompatible number of operands");
5430*9880d681SAndroid Build Coastguard Worker 
5431*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5432*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, ISD::MSCATTER, VTs, Ops);
5433*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT.getRawBits());
5434*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, MMO->isVolatile(),
5435*9880d681SAndroid Build Coastguard Worker                                      MMO->isNonTemporal(),
5436*9880d681SAndroid Build Coastguard Worker                                      MMO->isInvariant()));
5437*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
5438*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5439*9880d681SAndroid Build Coastguard Worker   if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
5440*9880d681SAndroid Build Coastguard Worker     cast<MaskedScatterSDNode>(E)->refineAlignment(MMO);
5441*9880d681SAndroid Build Coastguard Worker     return SDValue(E, 0);
5442*9880d681SAndroid Build Coastguard Worker   }
5443*9880d681SAndroid Build Coastguard Worker   auto *N = newSDNode<MaskedScatterSDNode>(dl.getIROrder(), dl.getDebugLoc(),
5444*9880d681SAndroid Build Coastguard Worker                                            VTs, VT, MMO);
5445*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
5446*9880d681SAndroid Build Coastguard Worker 
5447*9880d681SAndroid Build Coastguard Worker   assert(N->getMask().getValueType().getVectorNumElements() ==
5448*9880d681SAndroid Build Coastguard Worker              N->getValue().getValueType().getVectorNumElements() &&
5449*9880d681SAndroid Build Coastguard Worker          "Vector width mismatch between mask and data");
5450*9880d681SAndroid Build Coastguard Worker   assert(N->getIndex().getValueType().getVectorNumElements() ==
5451*9880d681SAndroid Build Coastguard Worker              N->getValue().getValueType().getVectorNumElements() &&
5452*9880d681SAndroid Build Coastguard Worker          "Vector width mismatch between index and data");
5453*9880d681SAndroid Build Coastguard Worker 
5454*9880d681SAndroid Build Coastguard Worker   CSEMap.InsertNode(N, IP);
5455*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5456*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5457*9880d681SAndroid Build Coastguard Worker }
5458*9880d681SAndroid Build Coastguard Worker 
getVAArg(EVT VT,const SDLoc & dl,SDValue Chain,SDValue Ptr,SDValue SV,unsigned Align)5459*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getVAArg(EVT VT, const SDLoc &dl, SDValue Chain,
5460*9880d681SAndroid Build Coastguard Worker                                SDValue Ptr, SDValue SV, unsigned Align) {
5461*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Chain, Ptr, SV, getTargetConstant(Align, dl, MVT::i32) };
5462*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::VAARG, dl, getVTList(VT, MVT::Other), Ops);
5463*9880d681SAndroid Build Coastguard Worker }
5464*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,EVT VT,ArrayRef<SDUse> Ops)5465*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
5466*9880d681SAndroid Build Coastguard Worker                               ArrayRef<SDUse> Ops) {
5467*9880d681SAndroid Build Coastguard Worker   switch (Ops.size()) {
5468*9880d681SAndroid Build Coastguard Worker   case 0: return getNode(Opcode, DL, VT);
5469*9880d681SAndroid Build Coastguard Worker   case 1: return getNode(Opcode, DL, VT, static_cast<const SDValue>(Ops[0]));
5470*9880d681SAndroid Build Coastguard Worker   case 2: return getNode(Opcode, DL, VT, Ops[0], Ops[1]);
5471*9880d681SAndroid Build Coastguard Worker   case 3: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Ops[2]);
5472*9880d681SAndroid Build Coastguard Worker   default: break;
5473*9880d681SAndroid Build Coastguard Worker   }
5474*9880d681SAndroid Build Coastguard Worker 
5475*9880d681SAndroid Build Coastguard Worker   // Copy from an SDUse array into an SDValue array for use with
5476*9880d681SAndroid Build Coastguard Worker   // the regular getNode logic.
5477*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> NewOps(Ops.begin(), Ops.end());
5478*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VT, NewOps);
5479*9880d681SAndroid Build Coastguard Worker }
5480*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,EVT VT,ArrayRef<SDValue> Ops,const SDNodeFlags * Flags)5481*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
5482*9880d681SAndroid Build Coastguard Worker                               ArrayRef<SDValue> Ops, const SDNodeFlags *Flags) {
5483*9880d681SAndroid Build Coastguard Worker   unsigned NumOps = Ops.size();
5484*9880d681SAndroid Build Coastguard Worker   switch (NumOps) {
5485*9880d681SAndroid Build Coastguard Worker   case 0: return getNode(Opcode, DL, VT);
5486*9880d681SAndroid Build Coastguard Worker   case 1: return getNode(Opcode, DL, VT, Ops[0]);
5487*9880d681SAndroid Build Coastguard Worker   case 2: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Flags);
5488*9880d681SAndroid Build Coastguard Worker   case 3: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Ops[2]);
5489*9880d681SAndroid Build Coastguard Worker   default: break;
5490*9880d681SAndroid Build Coastguard Worker   }
5491*9880d681SAndroid Build Coastguard Worker 
5492*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
5493*9880d681SAndroid Build Coastguard Worker   default: break;
5494*9880d681SAndroid Build Coastguard Worker   case ISD::CONCAT_VECTORS: {
5495*9880d681SAndroid Build Coastguard Worker     // Attempt to fold CONCAT_VECTORS into BUILD_VECTOR or UNDEF.
5496*9880d681SAndroid Build Coastguard Worker     if (SDValue V = FoldCONCAT_VECTORS(DL, VT, Ops, *this))
5497*9880d681SAndroid Build Coastguard Worker       return V;
5498*9880d681SAndroid Build Coastguard Worker     break;
5499*9880d681SAndroid Build Coastguard Worker   }
5500*9880d681SAndroid Build Coastguard Worker   case ISD::SELECT_CC: {
5501*9880d681SAndroid Build Coastguard Worker     assert(NumOps == 5 && "SELECT_CC takes 5 operands!");
5502*9880d681SAndroid Build Coastguard Worker     assert(Ops[0].getValueType() == Ops[1].getValueType() &&
5503*9880d681SAndroid Build Coastguard Worker            "LHS and RHS of condition must have same type!");
5504*9880d681SAndroid Build Coastguard Worker     assert(Ops[2].getValueType() == Ops[3].getValueType() &&
5505*9880d681SAndroid Build Coastguard Worker            "True and False arms of SelectCC must have same type!");
5506*9880d681SAndroid Build Coastguard Worker     assert(Ops[2].getValueType() == VT &&
5507*9880d681SAndroid Build Coastguard Worker            "select_cc node must be of same type as true and false value!");
5508*9880d681SAndroid Build Coastguard Worker     break;
5509*9880d681SAndroid Build Coastguard Worker   }
5510*9880d681SAndroid Build Coastguard Worker   case ISD::BR_CC: {
5511*9880d681SAndroid Build Coastguard Worker     assert(NumOps == 5 && "BR_CC takes 5 operands!");
5512*9880d681SAndroid Build Coastguard Worker     assert(Ops[2].getValueType() == Ops[3].getValueType() &&
5513*9880d681SAndroid Build Coastguard Worker            "LHS/RHS of comparison should match types!");
5514*9880d681SAndroid Build Coastguard Worker     break;
5515*9880d681SAndroid Build Coastguard Worker   }
5516*9880d681SAndroid Build Coastguard Worker   }
5517*9880d681SAndroid Build Coastguard Worker 
5518*9880d681SAndroid Build Coastguard Worker   // Memoize nodes.
5519*9880d681SAndroid Build Coastguard Worker   SDNode *N;
5520*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
5521*9880d681SAndroid Build Coastguard Worker 
5522*9880d681SAndroid Build Coastguard Worker   if (VT != MVT::Glue) {
5523*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
5524*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opcode, VTs, Ops);
5525*9880d681SAndroid Build Coastguard Worker     void *IP = nullptr;
5526*9880d681SAndroid Build Coastguard Worker 
5527*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
5528*9880d681SAndroid Build Coastguard Worker       return SDValue(E, 0);
5529*9880d681SAndroid Build Coastguard Worker 
5530*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
5531*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
5532*9880d681SAndroid Build Coastguard Worker 
5533*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
5534*9880d681SAndroid Build Coastguard Worker   } else {
5535*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
5536*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
5537*9880d681SAndroid Build Coastguard Worker   }
5538*9880d681SAndroid Build Coastguard Worker 
5539*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5540*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5541*9880d681SAndroid Build Coastguard Worker }
5542*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,ArrayRef<EVT> ResultTys,ArrayRef<SDValue> Ops)5543*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL,
5544*9880d681SAndroid Build Coastguard Worker                               ArrayRef<EVT> ResultTys, ArrayRef<SDValue> Ops) {
5545*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, getVTList(ResultTys), Ops);
5546*9880d681SAndroid Build Coastguard Worker }
5547*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,SDVTList VTList,ArrayRef<SDValue> Ops)5548*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
5549*9880d681SAndroid Build Coastguard Worker                               ArrayRef<SDValue> Ops) {
5550*9880d681SAndroid Build Coastguard Worker   if (VTList.NumVTs == 1)
5551*9880d681SAndroid Build Coastguard Worker     return getNode(Opcode, DL, VTList.VTs[0], Ops);
5552*9880d681SAndroid Build Coastguard Worker 
5553*9880d681SAndroid Build Coastguard Worker #if 0
5554*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
5555*9880d681SAndroid Build Coastguard Worker   // FIXME: figure out how to safely handle things like
5556*9880d681SAndroid Build Coastguard Worker   // int foo(int x) { return 1 << (x & 255); }
5557*9880d681SAndroid Build Coastguard Worker   // int bar() { return foo(256); }
5558*9880d681SAndroid Build Coastguard Worker   case ISD::SRA_PARTS:
5559*9880d681SAndroid Build Coastguard Worker   case ISD::SRL_PARTS:
5560*9880d681SAndroid Build Coastguard Worker   case ISD::SHL_PARTS:
5561*9880d681SAndroid Build Coastguard Worker     if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG &&
5562*9880d681SAndroid Build Coastguard Worker         cast<VTSDNode>(N3.getOperand(1))->getVT() != MVT::i1)
5563*9880d681SAndroid Build Coastguard Worker       return getNode(Opcode, DL, VT, N1, N2, N3.getOperand(0));
5564*9880d681SAndroid Build Coastguard Worker     else if (N3.getOpcode() == ISD::AND)
5565*9880d681SAndroid Build Coastguard Worker       if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N3.getOperand(1))) {
5566*9880d681SAndroid Build Coastguard Worker         // If the and is only masking out bits that cannot effect the shift,
5567*9880d681SAndroid Build Coastguard Worker         // eliminate the and.
5568*9880d681SAndroid Build Coastguard Worker         unsigned NumBits = VT.getScalarType().getSizeInBits()*2;
5569*9880d681SAndroid Build Coastguard Worker         if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1)
5570*9880d681SAndroid Build Coastguard Worker           return getNode(Opcode, DL, VT, N1, N2, N3.getOperand(0));
5571*9880d681SAndroid Build Coastguard Worker       }
5572*9880d681SAndroid Build Coastguard Worker     break;
5573*9880d681SAndroid Build Coastguard Worker   }
5574*9880d681SAndroid Build Coastguard Worker #endif
5575*9880d681SAndroid Build Coastguard Worker 
5576*9880d681SAndroid Build Coastguard Worker   // Memoize the node unless it returns a flag.
5577*9880d681SAndroid Build Coastguard Worker   SDNode *N;
5578*9880d681SAndroid Build Coastguard Worker   if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) {
5579*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
5580*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opcode, VTList, Ops);
5581*9880d681SAndroid Build Coastguard Worker     void *IP = nullptr;
5582*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
5583*9880d681SAndroid Build Coastguard Worker       return SDValue(E, 0);
5584*9880d681SAndroid Build Coastguard Worker 
5585*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList);
5586*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
5587*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
5588*9880d681SAndroid Build Coastguard Worker   } else {
5589*9880d681SAndroid Build Coastguard Worker     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList);
5590*9880d681SAndroid Build Coastguard Worker     createOperands(N, Ops);
5591*9880d681SAndroid Build Coastguard Worker   }
5592*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
5593*9880d681SAndroid Build Coastguard Worker   return SDValue(N, 0);
5594*9880d681SAndroid Build Coastguard Worker }
5595*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,SDVTList VTList)5596*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL,
5597*9880d681SAndroid Build Coastguard Worker                               SDVTList VTList) {
5598*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VTList, None);
5599*9880d681SAndroid Build Coastguard Worker }
5600*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,SDVTList VTList,SDValue N1)5601*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
5602*9880d681SAndroid Build Coastguard Worker                               SDValue N1) {
5603*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { N1 };
5604*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VTList, Ops);
5605*9880d681SAndroid Build Coastguard Worker }
5606*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,SDVTList VTList,SDValue N1,SDValue N2)5607*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
5608*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2) {
5609*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { N1, N2 };
5610*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VTList, Ops);
5611*9880d681SAndroid Build Coastguard Worker }
5612*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,SDVTList VTList,SDValue N1,SDValue N2,SDValue N3)5613*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
5614*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2, SDValue N3) {
5615*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { N1, N2, N3 };
5616*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VTList, Ops);
5617*9880d681SAndroid Build Coastguard Worker }
5618*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,SDVTList VTList,SDValue N1,SDValue N2,SDValue N3,SDValue N4)5619*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
5620*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2, SDValue N3, SDValue N4) {
5621*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { N1, N2, N3, N4 };
5622*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VTList, Ops);
5623*9880d681SAndroid Build Coastguard Worker }
5624*9880d681SAndroid Build Coastguard Worker 
getNode(unsigned Opcode,const SDLoc & DL,SDVTList VTList,SDValue N1,SDValue N2,SDValue N3,SDValue N4,SDValue N5)5625*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
5626*9880d681SAndroid Build Coastguard Worker                               SDValue N1, SDValue N2, SDValue N3, SDValue N4,
5627*9880d681SAndroid Build Coastguard Worker                               SDValue N5) {
5628*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { N1, N2, N3, N4, N5 };
5629*9880d681SAndroid Build Coastguard Worker   return getNode(Opcode, DL, VTList, Ops);
5630*9880d681SAndroid Build Coastguard Worker }
5631*9880d681SAndroid Build Coastguard Worker 
getVTList(EVT VT)5632*9880d681SAndroid Build Coastguard Worker SDVTList SelectionDAG::getVTList(EVT VT) {
5633*9880d681SAndroid Build Coastguard Worker   return makeVTList(SDNode::getValueTypeList(VT), 1);
5634*9880d681SAndroid Build Coastguard Worker }
5635*9880d681SAndroid Build Coastguard Worker 
getVTList(EVT VT1,EVT VT2)5636*9880d681SAndroid Build Coastguard Worker SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2) {
5637*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5638*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(2U);
5639*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT1.getRawBits());
5640*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT2.getRawBits());
5641*9880d681SAndroid Build Coastguard Worker 
5642*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5643*9880d681SAndroid Build Coastguard Worker   SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
5644*9880d681SAndroid Build Coastguard Worker   if (!Result) {
5645*9880d681SAndroid Build Coastguard Worker     EVT *Array = Allocator.Allocate<EVT>(2);
5646*9880d681SAndroid Build Coastguard Worker     Array[0] = VT1;
5647*9880d681SAndroid Build Coastguard Worker     Array[1] = VT2;
5648*9880d681SAndroid Build Coastguard Worker     Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, 2);
5649*9880d681SAndroid Build Coastguard Worker     VTListMap.InsertNode(Result, IP);
5650*9880d681SAndroid Build Coastguard Worker   }
5651*9880d681SAndroid Build Coastguard Worker   return Result->getSDVTList();
5652*9880d681SAndroid Build Coastguard Worker }
5653*9880d681SAndroid Build Coastguard Worker 
getVTList(EVT VT1,EVT VT2,EVT VT3)5654*9880d681SAndroid Build Coastguard Worker SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3) {
5655*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5656*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(3U);
5657*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT1.getRawBits());
5658*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT2.getRawBits());
5659*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT3.getRawBits());
5660*9880d681SAndroid Build Coastguard Worker 
5661*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5662*9880d681SAndroid Build Coastguard Worker   SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
5663*9880d681SAndroid Build Coastguard Worker   if (!Result) {
5664*9880d681SAndroid Build Coastguard Worker     EVT *Array = Allocator.Allocate<EVT>(3);
5665*9880d681SAndroid Build Coastguard Worker     Array[0] = VT1;
5666*9880d681SAndroid Build Coastguard Worker     Array[1] = VT2;
5667*9880d681SAndroid Build Coastguard Worker     Array[2] = VT3;
5668*9880d681SAndroid Build Coastguard Worker     Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, 3);
5669*9880d681SAndroid Build Coastguard Worker     VTListMap.InsertNode(Result, IP);
5670*9880d681SAndroid Build Coastguard Worker   }
5671*9880d681SAndroid Build Coastguard Worker   return Result->getSDVTList();
5672*9880d681SAndroid Build Coastguard Worker }
5673*9880d681SAndroid Build Coastguard Worker 
getVTList(EVT VT1,EVT VT2,EVT VT3,EVT VT4)5674*9880d681SAndroid Build Coastguard Worker SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4) {
5675*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5676*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(4U);
5677*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT1.getRawBits());
5678*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT2.getRawBits());
5679*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT3.getRawBits());
5680*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(VT4.getRawBits());
5681*9880d681SAndroid Build Coastguard Worker 
5682*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5683*9880d681SAndroid Build Coastguard Worker   SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
5684*9880d681SAndroid Build Coastguard Worker   if (!Result) {
5685*9880d681SAndroid Build Coastguard Worker     EVT *Array = Allocator.Allocate<EVT>(4);
5686*9880d681SAndroid Build Coastguard Worker     Array[0] = VT1;
5687*9880d681SAndroid Build Coastguard Worker     Array[1] = VT2;
5688*9880d681SAndroid Build Coastguard Worker     Array[2] = VT3;
5689*9880d681SAndroid Build Coastguard Worker     Array[3] = VT4;
5690*9880d681SAndroid Build Coastguard Worker     Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, 4);
5691*9880d681SAndroid Build Coastguard Worker     VTListMap.InsertNode(Result, IP);
5692*9880d681SAndroid Build Coastguard Worker   }
5693*9880d681SAndroid Build Coastguard Worker   return Result->getSDVTList();
5694*9880d681SAndroid Build Coastguard Worker }
5695*9880d681SAndroid Build Coastguard Worker 
getVTList(ArrayRef<EVT> VTs)5696*9880d681SAndroid Build Coastguard Worker SDVTList SelectionDAG::getVTList(ArrayRef<EVT> VTs) {
5697*9880d681SAndroid Build Coastguard Worker   unsigned NumVTs = VTs.size();
5698*9880d681SAndroid Build Coastguard Worker   FoldingSetNodeID ID;
5699*9880d681SAndroid Build Coastguard Worker   ID.AddInteger(NumVTs);
5700*9880d681SAndroid Build Coastguard Worker   for (unsigned index = 0; index < NumVTs; index++) {
5701*9880d681SAndroid Build Coastguard Worker     ID.AddInteger(VTs[index].getRawBits());
5702*9880d681SAndroid Build Coastguard Worker   }
5703*9880d681SAndroid Build Coastguard Worker 
5704*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5705*9880d681SAndroid Build Coastguard Worker   SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
5706*9880d681SAndroid Build Coastguard Worker   if (!Result) {
5707*9880d681SAndroid Build Coastguard Worker     EVT *Array = Allocator.Allocate<EVT>(NumVTs);
5708*9880d681SAndroid Build Coastguard Worker     std::copy(VTs.begin(), VTs.end(), Array);
5709*9880d681SAndroid Build Coastguard Worker     Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, NumVTs);
5710*9880d681SAndroid Build Coastguard Worker     VTListMap.InsertNode(Result, IP);
5711*9880d681SAndroid Build Coastguard Worker   }
5712*9880d681SAndroid Build Coastguard Worker   return Result->getSDVTList();
5713*9880d681SAndroid Build Coastguard Worker }
5714*9880d681SAndroid Build Coastguard Worker 
5715*9880d681SAndroid Build Coastguard Worker 
5716*9880d681SAndroid Build Coastguard Worker /// UpdateNodeOperands - *Mutate* the specified node in-place to have the
5717*9880d681SAndroid Build Coastguard Worker /// specified operands.  If the resultant node already exists in the DAG,
5718*9880d681SAndroid Build Coastguard Worker /// this does not modify the specified node, instead it returns the node that
5719*9880d681SAndroid Build Coastguard Worker /// already exists.  If the resultant node does not exist in the DAG, the
5720*9880d681SAndroid Build Coastguard Worker /// input node is returned.  As a degenerate case, if you specify the same
5721*9880d681SAndroid Build Coastguard Worker /// input operands as the node already has, the input node is returned.
UpdateNodeOperands(SDNode * N,SDValue Op)5722*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::UpdateNodeOperands(SDNode *N, SDValue Op) {
5723*9880d681SAndroid Build Coastguard Worker   assert(N->getNumOperands() == 1 && "Update with wrong number of operands");
5724*9880d681SAndroid Build Coastguard Worker 
5725*9880d681SAndroid Build Coastguard Worker   // Check to see if there is no change.
5726*9880d681SAndroid Build Coastguard Worker   if (Op == N->getOperand(0)) return N;
5727*9880d681SAndroid Build Coastguard Worker 
5728*9880d681SAndroid Build Coastguard Worker   // See if the modified node already exists.
5729*9880d681SAndroid Build Coastguard Worker   void *InsertPos = nullptr;
5730*9880d681SAndroid Build Coastguard Worker   if (SDNode *Existing = FindModifiedNodeSlot(N, Op, InsertPos))
5731*9880d681SAndroid Build Coastguard Worker     return Existing;
5732*9880d681SAndroid Build Coastguard Worker 
5733*9880d681SAndroid Build Coastguard Worker   // Nope it doesn't.  Remove the node from its current place in the maps.
5734*9880d681SAndroid Build Coastguard Worker   if (InsertPos)
5735*9880d681SAndroid Build Coastguard Worker     if (!RemoveNodeFromCSEMaps(N))
5736*9880d681SAndroid Build Coastguard Worker       InsertPos = nullptr;
5737*9880d681SAndroid Build Coastguard Worker 
5738*9880d681SAndroid Build Coastguard Worker   // Now we update the operands.
5739*9880d681SAndroid Build Coastguard Worker   N->OperandList[0].set(Op);
5740*9880d681SAndroid Build Coastguard Worker 
5741*9880d681SAndroid Build Coastguard Worker   // If this gets put into a CSE map, add it.
5742*9880d681SAndroid Build Coastguard Worker   if (InsertPos) CSEMap.InsertNode(N, InsertPos);
5743*9880d681SAndroid Build Coastguard Worker   return N;
5744*9880d681SAndroid Build Coastguard Worker }
5745*9880d681SAndroid Build Coastguard Worker 
UpdateNodeOperands(SDNode * N,SDValue Op1,SDValue Op2)5746*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2) {
5747*9880d681SAndroid Build Coastguard Worker   assert(N->getNumOperands() == 2 && "Update with wrong number of operands");
5748*9880d681SAndroid Build Coastguard Worker 
5749*9880d681SAndroid Build Coastguard Worker   // Check to see if there is no change.
5750*9880d681SAndroid Build Coastguard Worker   if (Op1 == N->getOperand(0) && Op2 == N->getOperand(1))
5751*9880d681SAndroid Build Coastguard Worker     return N;   // No operands changed, just return the input node.
5752*9880d681SAndroid Build Coastguard Worker 
5753*9880d681SAndroid Build Coastguard Worker   // See if the modified node already exists.
5754*9880d681SAndroid Build Coastguard Worker   void *InsertPos = nullptr;
5755*9880d681SAndroid Build Coastguard Worker   if (SDNode *Existing = FindModifiedNodeSlot(N, Op1, Op2, InsertPos))
5756*9880d681SAndroid Build Coastguard Worker     return Existing;
5757*9880d681SAndroid Build Coastguard Worker 
5758*9880d681SAndroid Build Coastguard Worker   // Nope it doesn't.  Remove the node from its current place in the maps.
5759*9880d681SAndroid Build Coastguard Worker   if (InsertPos)
5760*9880d681SAndroid Build Coastguard Worker     if (!RemoveNodeFromCSEMaps(N))
5761*9880d681SAndroid Build Coastguard Worker       InsertPos = nullptr;
5762*9880d681SAndroid Build Coastguard Worker 
5763*9880d681SAndroid Build Coastguard Worker   // Now we update the operands.
5764*9880d681SAndroid Build Coastguard Worker   if (N->OperandList[0] != Op1)
5765*9880d681SAndroid Build Coastguard Worker     N->OperandList[0].set(Op1);
5766*9880d681SAndroid Build Coastguard Worker   if (N->OperandList[1] != Op2)
5767*9880d681SAndroid Build Coastguard Worker     N->OperandList[1].set(Op2);
5768*9880d681SAndroid Build Coastguard Worker 
5769*9880d681SAndroid Build Coastguard Worker   // If this gets put into a CSE map, add it.
5770*9880d681SAndroid Build Coastguard Worker   if (InsertPos) CSEMap.InsertNode(N, InsertPos);
5771*9880d681SAndroid Build Coastguard Worker   return N;
5772*9880d681SAndroid Build Coastguard Worker }
5773*9880d681SAndroid Build Coastguard Worker 
5774*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::
UpdateNodeOperands(SDNode * N,SDValue Op1,SDValue Op2,SDValue Op3)5775*9880d681SAndroid Build Coastguard Worker UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2, SDValue Op3) {
5776*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3 };
5777*9880d681SAndroid Build Coastguard Worker   return UpdateNodeOperands(N, Ops);
5778*9880d681SAndroid Build Coastguard Worker }
5779*9880d681SAndroid Build Coastguard Worker 
5780*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::
UpdateNodeOperands(SDNode * N,SDValue Op1,SDValue Op2,SDValue Op3,SDValue Op4)5781*9880d681SAndroid Build Coastguard Worker UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
5782*9880d681SAndroid Build Coastguard Worker                    SDValue Op3, SDValue Op4) {
5783*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3, Op4 };
5784*9880d681SAndroid Build Coastguard Worker   return UpdateNodeOperands(N, Ops);
5785*9880d681SAndroid Build Coastguard Worker }
5786*9880d681SAndroid Build Coastguard Worker 
5787*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::
UpdateNodeOperands(SDNode * N,SDValue Op1,SDValue Op2,SDValue Op3,SDValue Op4,SDValue Op5)5788*9880d681SAndroid Build Coastguard Worker UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
5789*9880d681SAndroid Build Coastguard Worker                    SDValue Op3, SDValue Op4, SDValue Op5) {
5790*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3, Op4, Op5 };
5791*9880d681SAndroid Build Coastguard Worker   return UpdateNodeOperands(N, Ops);
5792*9880d681SAndroid Build Coastguard Worker }
5793*9880d681SAndroid Build Coastguard Worker 
5794*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::
UpdateNodeOperands(SDNode * N,ArrayRef<SDValue> Ops)5795*9880d681SAndroid Build Coastguard Worker UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops) {
5796*9880d681SAndroid Build Coastguard Worker   unsigned NumOps = Ops.size();
5797*9880d681SAndroid Build Coastguard Worker   assert(N->getNumOperands() == NumOps &&
5798*9880d681SAndroid Build Coastguard Worker          "Update with wrong number of operands");
5799*9880d681SAndroid Build Coastguard Worker 
5800*9880d681SAndroid Build Coastguard Worker   // If no operands changed just return the input node.
5801*9880d681SAndroid Build Coastguard Worker   if (std::equal(Ops.begin(), Ops.end(), N->op_begin()))
5802*9880d681SAndroid Build Coastguard Worker     return N;
5803*9880d681SAndroid Build Coastguard Worker 
5804*9880d681SAndroid Build Coastguard Worker   // See if the modified node already exists.
5805*9880d681SAndroid Build Coastguard Worker   void *InsertPos = nullptr;
5806*9880d681SAndroid Build Coastguard Worker   if (SDNode *Existing = FindModifiedNodeSlot(N, Ops, InsertPos))
5807*9880d681SAndroid Build Coastguard Worker     return Existing;
5808*9880d681SAndroid Build Coastguard Worker 
5809*9880d681SAndroid Build Coastguard Worker   // Nope it doesn't.  Remove the node from its current place in the maps.
5810*9880d681SAndroid Build Coastguard Worker   if (InsertPos)
5811*9880d681SAndroid Build Coastguard Worker     if (!RemoveNodeFromCSEMaps(N))
5812*9880d681SAndroid Build Coastguard Worker       InsertPos = nullptr;
5813*9880d681SAndroid Build Coastguard Worker 
5814*9880d681SAndroid Build Coastguard Worker   // Now we update the operands.
5815*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i != NumOps; ++i)
5816*9880d681SAndroid Build Coastguard Worker     if (N->OperandList[i] != Ops[i])
5817*9880d681SAndroid Build Coastguard Worker       N->OperandList[i].set(Ops[i]);
5818*9880d681SAndroid Build Coastguard Worker 
5819*9880d681SAndroid Build Coastguard Worker   // If this gets put into a CSE map, add it.
5820*9880d681SAndroid Build Coastguard Worker   if (InsertPos) CSEMap.InsertNode(N, InsertPos);
5821*9880d681SAndroid Build Coastguard Worker   return N;
5822*9880d681SAndroid Build Coastguard Worker }
5823*9880d681SAndroid Build Coastguard Worker 
5824*9880d681SAndroid Build Coastguard Worker /// DropOperands - Release the operands and set this node to have
5825*9880d681SAndroid Build Coastguard Worker /// zero operands.
DropOperands()5826*9880d681SAndroid Build Coastguard Worker void SDNode::DropOperands() {
5827*9880d681SAndroid Build Coastguard Worker   // Unlike the code in MorphNodeTo that does this, we don't need to
5828*9880d681SAndroid Build Coastguard Worker   // watch for dead nodes here.
5829*9880d681SAndroid Build Coastguard Worker   for (op_iterator I = op_begin(), E = op_end(); I != E; ) {
5830*9880d681SAndroid Build Coastguard Worker     SDUse &Use = *I++;
5831*9880d681SAndroid Build Coastguard Worker     Use.set(SDValue());
5832*9880d681SAndroid Build Coastguard Worker   }
5833*9880d681SAndroid Build Coastguard Worker }
5834*9880d681SAndroid Build Coastguard Worker 
5835*9880d681SAndroid Build Coastguard Worker /// SelectNodeTo - These are wrappers around MorphNodeTo that accept a
5836*9880d681SAndroid Build Coastguard Worker /// machine opcode.
5837*9880d681SAndroid Build Coastguard Worker ///
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT)5838*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5839*9880d681SAndroid Build Coastguard Worker                                    EVT VT) {
5840*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
5841*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, None);
5842*9880d681SAndroid Build Coastguard Worker }
5843*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT,SDValue Op1)5844*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5845*9880d681SAndroid Build Coastguard Worker                                    EVT VT, SDValue Op1) {
5846*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
5847*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1 };
5848*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5849*9880d681SAndroid Build Coastguard Worker }
5850*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT,SDValue Op1,SDValue Op2)5851*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5852*9880d681SAndroid Build Coastguard Worker                                    EVT VT, SDValue Op1,
5853*9880d681SAndroid Build Coastguard Worker                                    SDValue Op2) {
5854*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
5855*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2 };
5856*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5857*9880d681SAndroid Build Coastguard Worker }
5858*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT,SDValue Op1,SDValue Op2,SDValue Op3)5859*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5860*9880d681SAndroid Build Coastguard Worker                                    EVT VT, SDValue Op1,
5861*9880d681SAndroid Build Coastguard Worker                                    SDValue Op2, SDValue Op3) {
5862*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
5863*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3 };
5864*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5865*9880d681SAndroid Build Coastguard Worker }
5866*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT,ArrayRef<SDValue> Ops)5867*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5868*9880d681SAndroid Build Coastguard Worker                                    EVT VT, ArrayRef<SDValue> Ops) {
5869*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
5870*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5871*9880d681SAndroid Build Coastguard Worker }
5872*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2,ArrayRef<SDValue> Ops)5873*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5874*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2, ArrayRef<SDValue> Ops) {
5875*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
5876*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5877*9880d681SAndroid Build Coastguard Worker }
5878*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2)5879*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5880*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2) {
5881*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
5882*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, None);
5883*9880d681SAndroid Build Coastguard Worker }
5884*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2,EVT VT3,ArrayRef<SDValue> Ops)5885*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5886*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2, EVT VT3,
5887*9880d681SAndroid Build Coastguard Worker                                    ArrayRef<SDValue> Ops) {
5888*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2, VT3);
5889*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5890*9880d681SAndroid Build Coastguard Worker }
5891*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2,EVT VT3,EVT VT4,ArrayRef<SDValue> Ops)5892*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5893*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2, EVT VT3, EVT VT4,
5894*9880d681SAndroid Build Coastguard Worker                                    ArrayRef<SDValue> Ops) {
5895*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2, VT3, VT4);
5896*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5897*9880d681SAndroid Build Coastguard Worker }
5898*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2,SDValue Op1)5899*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5900*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2,
5901*9880d681SAndroid Build Coastguard Worker                                    SDValue Op1) {
5902*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
5903*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1 };
5904*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5905*9880d681SAndroid Build Coastguard Worker }
5906*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2,SDValue Op1,SDValue Op2)5907*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5908*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2,
5909*9880d681SAndroid Build Coastguard Worker                                    SDValue Op1, SDValue Op2) {
5910*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
5911*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2 };
5912*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5913*9880d681SAndroid Build Coastguard Worker }
5914*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2,SDValue Op1,SDValue Op2,SDValue Op3)5915*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5916*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2,
5917*9880d681SAndroid Build Coastguard Worker                                    SDValue Op1, SDValue Op2,
5918*9880d681SAndroid Build Coastguard Worker                                    SDValue Op3) {
5919*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
5920*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3 };
5921*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5922*9880d681SAndroid Build Coastguard Worker }
5923*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,EVT VT1,EVT VT2,EVT VT3,SDValue Op1,SDValue Op2,SDValue Op3)5924*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5925*9880d681SAndroid Build Coastguard Worker                                    EVT VT1, EVT VT2, EVT VT3,
5926*9880d681SAndroid Build Coastguard Worker                                    SDValue Op1, SDValue Op2,
5927*9880d681SAndroid Build Coastguard Worker                                    SDValue Op3) {
5928*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2, VT3);
5929*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3 };
5930*9880d681SAndroid Build Coastguard Worker   return SelectNodeTo(N, MachineOpc, VTs, Ops);
5931*9880d681SAndroid Build Coastguard Worker }
5932*9880d681SAndroid Build Coastguard Worker 
SelectNodeTo(SDNode * N,unsigned MachineOpc,SDVTList VTs,ArrayRef<SDValue> Ops)5933*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
5934*9880d681SAndroid Build Coastguard Worker                                    SDVTList VTs,ArrayRef<SDValue> Ops) {
5935*9880d681SAndroid Build Coastguard Worker   SDNode *New = MorphNodeTo(N, ~MachineOpc, VTs, Ops);
5936*9880d681SAndroid Build Coastguard Worker   // Reset the NodeID to -1.
5937*9880d681SAndroid Build Coastguard Worker   New->setNodeId(-1);
5938*9880d681SAndroid Build Coastguard Worker   if (New != N) {
5939*9880d681SAndroid Build Coastguard Worker     ReplaceAllUsesWith(N, New);
5940*9880d681SAndroid Build Coastguard Worker     RemoveDeadNode(N);
5941*9880d681SAndroid Build Coastguard Worker   }
5942*9880d681SAndroid Build Coastguard Worker   return New;
5943*9880d681SAndroid Build Coastguard Worker }
5944*9880d681SAndroid Build Coastguard Worker 
5945*9880d681SAndroid Build Coastguard Worker /// UpdadeSDLocOnMergedSDNode - If the opt level is -O0 then it throws away
5946*9880d681SAndroid Build Coastguard Worker /// the line number information on the merged node since it is not possible to
5947*9880d681SAndroid Build Coastguard Worker /// preserve the information that operation is associated with multiple lines.
5948*9880d681SAndroid Build Coastguard Worker /// This will make the debugger working better at -O0, were there is a higher
5949*9880d681SAndroid Build Coastguard Worker /// probability having other instructions associated with that line.
5950*9880d681SAndroid Build Coastguard Worker ///
5951*9880d681SAndroid Build Coastguard Worker /// For IROrder, we keep the smaller of the two
UpdadeSDLocOnMergedSDNode(SDNode * N,const SDLoc & OLoc)5952*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::UpdadeSDLocOnMergedSDNode(SDNode *N, const SDLoc &OLoc) {
5953*9880d681SAndroid Build Coastguard Worker   DebugLoc NLoc = N->getDebugLoc();
5954*9880d681SAndroid Build Coastguard Worker   if (NLoc && OptLevel == CodeGenOpt::None && OLoc.getDebugLoc() != NLoc) {
5955*9880d681SAndroid Build Coastguard Worker     N->setDebugLoc(DebugLoc());
5956*9880d681SAndroid Build Coastguard Worker   }
5957*9880d681SAndroid Build Coastguard Worker   unsigned Order = std::min(N->getIROrder(), OLoc.getIROrder());
5958*9880d681SAndroid Build Coastguard Worker   N->setIROrder(Order);
5959*9880d681SAndroid Build Coastguard Worker   return N;
5960*9880d681SAndroid Build Coastguard Worker }
5961*9880d681SAndroid Build Coastguard Worker 
5962*9880d681SAndroid Build Coastguard Worker /// MorphNodeTo - This *mutates* the specified node to have the specified
5963*9880d681SAndroid Build Coastguard Worker /// return type, opcode, and operands.
5964*9880d681SAndroid Build Coastguard Worker ///
5965*9880d681SAndroid Build Coastguard Worker /// Note that MorphNodeTo returns the resultant node.  If there is already a
5966*9880d681SAndroid Build Coastguard Worker /// node of the specified opcode and operands, it returns that node instead of
5967*9880d681SAndroid Build Coastguard Worker /// the current one.  Note that the SDLoc need not be the same.
5968*9880d681SAndroid Build Coastguard Worker ///
5969*9880d681SAndroid Build Coastguard Worker /// Using MorphNodeTo is faster than creating a new node and swapping it in
5970*9880d681SAndroid Build Coastguard Worker /// with ReplaceAllUsesWith both because it often avoids allocating a new
5971*9880d681SAndroid Build Coastguard Worker /// node, and because it doesn't require CSE recalculation for any of
5972*9880d681SAndroid Build Coastguard Worker /// the node's users.
5973*9880d681SAndroid Build Coastguard Worker ///
5974*9880d681SAndroid Build Coastguard Worker /// However, note that MorphNodeTo recursively deletes dead nodes from the DAG.
5975*9880d681SAndroid Build Coastguard Worker /// As a consequence it isn't appropriate to use from within the DAG combiner or
5976*9880d681SAndroid Build Coastguard Worker /// the legalizer which maintain worklists that would need to be updated when
5977*9880d681SAndroid Build Coastguard Worker /// deleting things.
MorphNodeTo(SDNode * N,unsigned Opc,SDVTList VTs,ArrayRef<SDValue> Ops)5978*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
5979*9880d681SAndroid Build Coastguard Worker                                   SDVTList VTs, ArrayRef<SDValue> Ops) {
5980*9880d681SAndroid Build Coastguard Worker   // If an identical node already exists, use it.
5981*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
5982*9880d681SAndroid Build Coastguard Worker   if (VTs.VTs[VTs.NumVTs-1] != MVT::Glue) {
5983*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
5984*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opc, VTs, Ops);
5985*9880d681SAndroid Build Coastguard Worker     if (SDNode *ON = FindNodeOrInsertPos(ID, SDLoc(N), IP))
5986*9880d681SAndroid Build Coastguard Worker       return UpdadeSDLocOnMergedSDNode(ON, SDLoc(N));
5987*9880d681SAndroid Build Coastguard Worker   }
5988*9880d681SAndroid Build Coastguard Worker 
5989*9880d681SAndroid Build Coastguard Worker   if (!RemoveNodeFromCSEMaps(N))
5990*9880d681SAndroid Build Coastguard Worker     IP = nullptr;
5991*9880d681SAndroid Build Coastguard Worker 
5992*9880d681SAndroid Build Coastguard Worker   // Start the morphing.
5993*9880d681SAndroid Build Coastguard Worker   N->NodeType = Opc;
5994*9880d681SAndroid Build Coastguard Worker   N->ValueList = VTs.VTs;
5995*9880d681SAndroid Build Coastguard Worker   N->NumValues = VTs.NumVTs;
5996*9880d681SAndroid Build Coastguard Worker 
5997*9880d681SAndroid Build Coastguard Worker   // Clear the operands list, updating used nodes to remove this from their
5998*9880d681SAndroid Build Coastguard Worker   // use list.  Keep track of any operands that become dead as a result.
5999*9880d681SAndroid Build Coastguard Worker   SmallPtrSet<SDNode*, 16> DeadNodeSet;
6000*9880d681SAndroid Build Coastguard Worker   for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) {
6001*9880d681SAndroid Build Coastguard Worker     SDUse &Use = *I++;
6002*9880d681SAndroid Build Coastguard Worker     SDNode *Used = Use.getNode();
6003*9880d681SAndroid Build Coastguard Worker     Use.set(SDValue());
6004*9880d681SAndroid Build Coastguard Worker     if (Used->use_empty())
6005*9880d681SAndroid Build Coastguard Worker       DeadNodeSet.insert(Used);
6006*9880d681SAndroid Build Coastguard Worker   }
6007*9880d681SAndroid Build Coastguard Worker 
6008*9880d681SAndroid Build Coastguard Worker   // For MachineNode, initialize the memory references information.
6009*9880d681SAndroid Build Coastguard Worker   if (MachineSDNode *MN = dyn_cast<MachineSDNode>(N))
6010*9880d681SAndroid Build Coastguard Worker     MN->setMemRefs(nullptr, nullptr);
6011*9880d681SAndroid Build Coastguard Worker 
6012*9880d681SAndroid Build Coastguard Worker   // Swap for an appropriately sized array from the recycler.
6013*9880d681SAndroid Build Coastguard Worker   removeOperands(N);
6014*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
6015*9880d681SAndroid Build Coastguard Worker 
6016*9880d681SAndroid Build Coastguard Worker   // Delete any nodes that are still dead after adding the uses for the
6017*9880d681SAndroid Build Coastguard Worker   // new operands.
6018*9880d681SAndroid Build Coastguard Worker   if (!DeadNodeSet.empty()) {
6019*9880d681SAndroid Build Coastguard Worker     SmallVector<SDNode *, 16> DeadNodes;
6020*9880d681SAndroid Build Coastguard Worker     for (SDNode *N : DeadNodeSet)
6021*9880d681SAndroid Build Coastguard Worker       if (N->use_empty())
6022*9880d681SAndroid Build Coastguard Worker         DeadNodes.push_back(N);
6023*9880d681SAndroid Build Coastguard Worker     RemoveDeadNodes(DeadNodes);
6024*9880d681SAndroid Build Coastguard Worker   }
6025*9880d681SAndroid Build Coastguard Worker 
6026*9880d681SAndroid Build Coastguard Worker   if (IP)
6027*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);   // Memoize the new node.
6028*9880d681SAndroid Build Coastguard Worker   return N;
6029*9880d681SAndroid Build Coastguard Worker }
6030*9880d681SAndroid Build Coastguard Worker 
6031*9880d681SAndroid Build Coastguard Worker 
6032*9880d681SAndroid Build Coastguard Worker /// getMachineNode - These are used for target selectors to create a new node
6033*9880d681SAndroid Build Coastguard Worker /// with specified return type(s), MachineInstr opcode, and operands.
6034*9880d681SAndroid Build Coastguard Worker ///
6035*9880d681SAndroid Build Coastguard Worker /// Note that getMachineNode returns the resultant node.  If there is already a
6036*9880d681SAndroid Build Coastguard Worker /// node of the specified opcode and operands, it returns that node instead of
6037*9880d681SAndroid Build Coastguard Worker /// the current one.
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT)6038*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6039*9880d681SAndroid Build Coastguard Worker                                             EVT VT) {
6040*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
6041*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, None);
6042*9880d681SAndroid Build Coastguard Worker }
6043*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT,SDValue Op1)6044*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6045*9880d681SAndroid Build Coastguard Worker                                             EVT VT, SDValue Op1) {
6046*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
6047*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1 };
6048*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6049*9880d681SAndroid Build Coastguard Worker }
6050*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT,SDValue Op1,SDValue Op2)6051*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6052*9880d681SAndroid Build Coastguard Worker                                             EVT VT, SDValue Op1, SDValue Op2) {
6053*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
6054*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2 };
6055*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6056*9880d681SAndroid Build Coastguard Worker }
6057*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT,SDValue Op1,SDValue Op2,SDValue Op3)6058*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6059*9880d681SAndroid Build Coastguard Worker                                             EVT VT, SDValue Op1, SDValue Op2,
6060*9880d681SAndroid Build Coastguard Worker                                             SDValue Op3) {
6061*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
6062*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3 };
6063*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6064*9880d681SAndroid Build Coastguard Worker }
6065*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT,ArrayRef<SDValue> Ops)6066*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6067*9880d681SAndroid Build Coastguard Worker                                             EVT VT, ArrayRef<SDValue> Ops) {
6068*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT);
6069*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6070*9880d681SAndroid Build Coastguard Worker }
6071*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2)6072*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6073*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2) {
6074*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
6075*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, None);
6076*9880d681SAndroid Build Coastguard Worker }
6077*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,SDValue Op1)6078*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6079*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2, SDValue Op1) {
6080*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
6081*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1 };
6082*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6083*9880d681SAndroid Build Coastguard Worker }
6084*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,SDValue Op1,SDValue Op2)6085*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6086*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2, SDValue Op1,
6087*9880d681SAndroid Build Coastguard Worker                                             SDValue Op2) {
6088*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
6089*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2 };
6090*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6091*9880d681SAndroid Build Coastguard Worker }
6092*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,SDValue Op1,SDValue Op2,SDValue Op3)6093*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6094*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2, SDValue Op1,
6095*9880d681SAndroid Build Coastguard Worker                                             SDValue Op2, SDValue Op3) {
6096*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
6097*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3 };
6098*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6099*9880d681SAndroid Build Coastguard Worker }
6100*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,ArrayRef<SDValue> Ops)6101*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6102*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2,
6103*9880d681SAndroid Build Coastguard Worker                                             ArrayRef<SDValue> Ops) {
6104*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2);
6105*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6106*9880d681SAndroid Build Coastguard Worker }
6107*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,EVT VT3,SDValue Op1,SDValue Op2)6108*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6109*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2, EVT VT3,
6110*9880d681SAndroid Build Coastguard Worker                                             SDValue Op1, SDValue Op2) {
6111*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2, VT3);
6112*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2 };
6113*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6114*9880d681SAndroid Build Coastguard Worker }
6115*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,EVT VT3,SDValue Op1,SDValue Op2,SDValue Op3)6116*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6117*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2, EVT VT3,
6118*9880d681SAndroid Build Coastguard Worker                                             SDValue Op1, SDValue Op2,
6119*9880d681SAndroid Build Coastguard Worker                                             SDValue Op3) {
6120*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2, VT3);
6121*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op1, Op2, Op3 };
6122*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6123*9880d681SAndroid Build Coastguard Worker }
6124*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,EVT VT3,ArrayRef<SDValue> Ops)6125*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6126*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2, EVT VT3,
6127*9880d681SAndroid Build Coastguard Worker                                             ArrayRef<SDValue> Ops) {
6128*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2, VT3);
6129*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6130*9880d681SAndroid Build Coastguard Worker }
6131*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,EVT VT1,EVT VT2,EVT VT3,EVT VT4,ArrayRef<SDValue> Ops)6132*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6133*9880d681SAndroid Build Coastguard Worker                                             EVT VT1, EVT VT2, EVT VT3, EVT VT4,
6134*9880d681SAndroid Build Coastguard Worker                                             ArrayRef<SDValue> Ops) {
6135*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(VT1, VT2, VT3, VT4);
6136*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6137*9880d681SAndroid Build Coastguard Worker }
6138*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & dl,ArrayRef<EVT> ResultTys,ArrayRef<SDValue> Ops)6139*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &dl,
6140*9880d681SAndroid Build Coastguard Worker                                             ArrayRef<EVT> ResultTys,
6141*9880d681SAndroid Build Coastguard Worker                                             ArrayRef<SDValue> Ops) {
6142*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = getVTList(ResultTys);
6143*9880d681SAndroid Build Coastguard Worker   return getMachineNode(Opcode, dl, VTs, Ops);
6144*9880d681SAndroid Build Coastguard Worker }
6145*9880d681SAndroid Build Coastguard Worker 
getMachineNode(unsigned Opcode,const SDLoc & DL,SDVTList VTs,ArrayRef<SDValue> Ops)6146*9880d681SAndroid Build Coastguard Worker MachineSDNode *SelectionDAG::getMachineNode(unsigned Opcode, const SDLoc &DL,
6147*9880d681SAndroid Build Coastguard Worker                                             SDVTList VTs,
6148*9880d681SAndroid Build Coastguard Worker                                             ArrayRef<SDValue> Ops) {
6149*9880d681SAndroid Build Coastguard Worker   bool DoCSE = VTs.VTs[VTs.NumVTs-1] != MVT::Glue;
6150*9880d681SAndroid Build Coastguard Worker   MachineSDNode *N;
6151*9880d681SAndroid Build Coastguard Worker   void *IP = nullptr;
6152*9880d681SAndroid Build Coastguard Worker 
6153*9880d681SAndroid Build Coastguard Worker   if (DoCSE) {
6154*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
6155*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, ~Opcode, VTs, Ops);
6156*9880d681SAndroid Build Coastguard Worker     IP = nullptr;
6157*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
6158*9880d681SAndroid Build Coastguard Worker       return cast<MachineSDNode>(UpdadeSDLocOnMergedSDNode(E, DL));
6159*9880d681SAndroid Build Coastguard Worker     }
6160*9880d681SAndroid Build Coastguard Worker   }
6161*9880d681SAndroid Build Coastguard Worker 
6162*9880d681SAndroid Build Coastguard Worker   // Allocate a new MachineSDNode.
6163*9880d681SAndroid Build Coastguard Worker   N = newSDNode<MachineSDNode>(~Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6164*9880d681SAndroid Build Coastguard Worker   createOperands(N, Ops);
6165*9880d681SAndroid Build Coastguard Worker 
6166*9880d681SAndroid Build Coastguard Worker   if (DoCSE)
6167*9880d681SAndroid Build Coastguard Worker     CSEMap.InsertNode(N, IP);
6168*9880d681SAndroid Build Coastguard Worker 
6169*9880d681SAndroid Build Coastguard Worker   InsertNode(N);
6170*9880d681SAndroid Build Coastguard Worker   return N;
6171*9880d681SAndroid Build Coastguard Worker }
6172*9880d681SAndroid Build Coastguard Worker 
6173*9880d681SAndroid Build Coastguard Worker /// getTargetExtractSubreg - A convenience function for creating
6174*9880d681SAndroid Build Coastguard Worker /// TargetOpcode::EXTRACT_SUBREG nodes.
getTargetExtractSubreg(int SRIdx,const SDLoc & DL,EVT VT,SDValue Operand)6175*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT,
6176*9880d681SAndroid Build Coastguard Worker                                              SDValue Operand) {
6177*9880d681SAndroid Build Coastguard Worker   SDValue SRIdxVal = getTargetConstant(SRIdx, DL, MVT::i32);
6178*9880d681SAndroid Build Coastguard Worker   SDNode *Subreg = getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
6179*9880d681SAndroid Build Coastguard Worker                                   VT, Operand, SRIdxVal);
6180*9880d681SAndroid Build Coastguard Worker   return SDValue(Subreg, 0);
6181*9880d681SAndroid Build Coastguard Worker }
6182*9880d681SAndroid Build Coastguard Worker 
6183*9880d681SAndroid Build Coastguard Worker /// getTargetInsertSubreg - A convenience function for creating
6184*9880d681SAndroid Build Coastguard Worker /// TargetOpcode::INSERT_SUBREG nodes.
getTargetInsertSubreg(int SRIdx,const SDLoc & DL,EVT VT,SDValue Operand,SDValue Subreg)6185*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT,
6186*9880d681SAndroid Build Coastguard Worker                                             SDValue Operand, SDValue Subreg) {
6187*9880d681SAndroid Build Coastguard Worker   SDValue SRIdxVal = getTargetConstant(SRIdx, DL, MVT::i32);
6188*9880d681SAndroid Build Coastguard Worker   SDNode *Result = getMachineNode(TargetOpcode::INSERT_SUBREG, DL,
6189*9880d681SAndroid Build Coastguard Worker                                   VT, Operand, Subreg, SRIdxVal);
6190*9880d681SAndroid Build Coastguard Worker   return SDValue(Result, 0);
6191*9880d681SAndroid Build Coastguard Worker }
6192*9880d681SAndroid Build Coastguard Worker 
6193*9880d681SAndroid Build Coastguard Worker /// getNodeIfExists - Get the specified node if it's already available, or
6194*9880d681SAndroid Build Coastguard Worker /// else return NULL.
getNodeIfExists(unsigned Opcode,SDVTList VTList,ArrayRef<SDValue> Ops,const SDNodeFlags * Flags)6195*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
6196*9880d681SAndroid Build Coastguard Worker                                       ArrayRef<SDValue> Ops,
6197*9880d681SAndroid Build Coastguard Worker                                       const SDNodeFlags *Flags) {
6198*9880d681SAndroid Build Coastguard Worker   if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) {
6199*9880d681SAndroid Build Coastguard Worker     FoldingSetNodeID ID;
6200*9880d681SAndroid Build Coastguard Worker     AddNodeIDNode(ID, Opcode, VTList, Ops);
6201*9880d681SAndroid Build Coastguard Worker     void *IP = nullptr;
6202*9880d681SAndroid Build Coastguard Worker     if (SDNode *E = FindNodeOrInsertPos(ID, SDLoc(), IP)) {
6203*9880d681SAndroid Build Coastguard Worker       if (Flags)
6204*9880d681SAndroid Build Coastguard Worker         E->intersectFlagsWith(Flags);
6205*9880d681SAndroid Build Coastguard Worker       return E;
6206*9880d681SAndroid Build Coastguard Worker     }
6207*9880d681SAndroid Build Coastguard Worker   }
6208*9880d681SAndroid Build Coastguard Worker   return nullptr;
6209*9880d681SAndroid Build Coastguard Worker }
6210*9880d681SAndroid Build Coastguard Worker 
6211*9880d681SAndroid Build Coastguard Worker /// getDbgValue - Creates a SDDbgValue node.
6212*9880d681SAndroid Build Coastguard Worker ///
6213*9880d681SAndroid Build Coastguard Worker /// SDNode
getDbgValue(MDNode * Var,MDNode * Expr,SDNode * N,unsigned R,bool IsIndirect,uint64_t Off,const DebugLoc & DL,unsigned O)6214*9880d681SAndroid Build Coastguard Worker SDDbgValue *SelectionDAG::getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N,
6215*9880d681SAndroid Build Coastguard Worker                                       unsigned R, bool IsIndirect, uint64_t Off,
6216*9880d681SAndroid Build Coastguard Worker                                       const DebugLoc &DL, unsigned O) {
6217*9880d681SAndroid Build Coastguard Worker   assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
6218*9880d681SAndroid Build Coastguard Worker          "Expected inlined-at fields to agree");
6219*9880d681SAndroid Build Coastguard Worker   return new (DbgInfo->getAlloc())
6220*9880d681SAndroid Build Coastguard Worker       SDDbgValue(Var, Expr, N, R, IsIndirect, Off, DL, O);
6221*9880d681SAndroid Build Coastguard Worker }
6222*9880d681SAndroid Build Coastguard Worker 
6223*9880d681SAndroid Build Coastguard Worker /// Constant
getConstantDbgValue(MDNode * Var,MDNode * Expr,const Value * C,uint64_t Off,const DebugLoc & DL,unsigned O)6224*9880d681SAndroid Build Coastguard Worker SDDbgValue *SelectionDAG::getConstantDbgValue(MDNode *Var, MDNode *Expr,
6225*9880d681SAndroid Build Coastguard Worker                                               const Value *C, uint64_t Off,
6226*9880d681SAndroid Build Coastguard Worker                                               const DebugLoc &DL, unsigned O) {
6227*9880d681SAndroid Build Coastguard Worker   assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
6228*9880d681SAndroid Build Coastguard Worker          "Expected inlined-at fields to agree");
6229*9880d681SAndroid Build Coastguard Worker   return new (DbgInfo->getAlloc()) SDDbgValue(Var, Expr, C, Off, DL, O);
6230*9880d681SAndroid Build Coastguard Worker }
6231*9880d681SAndroid Build Coastguard Worker 
6232*9880d681SAndroid Build Coastguard Worker /// FrameIndex
getFrameIndexDbgValue(MDNode * Var,MDNode * Expr,unsigned FI,uint64_t Off,const DebugLoc & DL,unsigned O)6233*9880d681SAndroid Build Coastguard Worker SDDbgValue *SelectionDAG::getFrameIndexDbgValue(MDNode *Var, MDNode *Expr,
6234*9880d681SAndroid Build Coastguard Worker                                                 unsigned FI, uint64_t Off,
6235*9880d681SAndroid Build Coastguard Worker                                                 const DebugLoc &DL,
6236*9880d681SAndroid Build Coastguard Worker                                                 unsigned O) {
6237*9880d681SAndroid Build Coastguard Worker   assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
6238*9880d681SAndroid Build Coastguard Worker          "Expected inlined-at fields to agree");
6239*9880d681SAndroid Build Coastguard Worker   return new (DbgInfo->getAlloc()) SDDbgValue(Var, Expr, FI, Off, DL, O);
6240*9880d681SAndroid Build Coastguard Worker }
6241*9880d681SAndroid Build Coastguard Worker 
6242*9880d681SAndroid Build Coastguard Worker namespace {
6243*9880d681SAndroid Build Coastguard Worker 
6244*9880d681SAndroid Build Coastguard Worker /// RAUWUpdateListener - Helper for ReplaceAllUsesWith - When the node
6245*9880d681SAndroid Build Coastguard Worker /// pointed to by a use iterator is deleted, increment the use iterator
6246*9880d681SAndroid Build Coastguard Worker /// so that it doesn't dangle.
6247*9880d681SAndroid Build Coastguard Worker ///
6248*9880d681SAndroid Build Coastguard Worker class RAUWUpdateListener : public SelectionDAG::DAGUpdateListener {
6249*9880d681SAndroid Build Coastguard Worker   SDNode::use_iterator &UI;
6250*9880d681SAndroid Build Coastguard Worker   SDNode::use_iterator &UE;
6251*9880d681SAndroid Build Coastguard Worker 
NodeDeleted(SDNode * N,SDNode * E)6252*9880d681SAndroid Build Coastguard Worker   void NodeDeleted(SDNode *N, SDNode *E) override {
6253*9880d681SAndroid Build Coastguard Worker     // Increment the iterator as needed.
6254*9880d681SAndroid Build Coastguard Worker     while (UI != UE && N == *UI)
6255*9880d681SAndroid Build Coastguard Worker       ++UI;
6256*9880d681SAndroid Build Coastguard Worker   }
6257*9880d681SAndroid Build Coastguard Worker 
6258*9880d681SAndroid Build Coastguard Worker public:
RAUWUpdateListener(SelectionDAG & d,SDNode::use_iterator & ui,SDNode::use_iterator & ue)6259*9880d681SAndroid Build Coastguard Worker   RAUWUpdateListener(SelectionDAG &d,
6260*9880d681SAndroid Build Coastguard Worker                      SDNode::use_iterator &ui,
6261*9880d681SAndroid Build Coastguard Worker                      SDNode::use_iterator &ue)
6262*9880d681SAndroid Build Coastguard Worker     : SelectionDAG::DAGUpdateListener(d), UI(ui), UE(ue) {}
6263*9880d681SAndroid Build Coastguard Worker };
6264*9880d681SAndroid Build Coastguard Worker 
6265*9880d681SAndroid Build Coastguard Worker }
6266*9880d681SAndroid Build Coastguard Worker 
6267*9880d681SAndroid Build Coastguard Worker /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
6268*9880d681SAndroid Build Coastguard Worker /// This can cause recursive merging of nodes in the DAG.
6269*9880d681SAndroid Build Coastguard Worker ///
6270*9880d681SAndroid Build Coastguard Worker /// This version assumes From has a single result value.
6271*9880d681SAndroid Build Coastguard Worker ///
ReplaceAllUsesWith(SDValue FromN,SDValue To)6272*9880d681SAndroid Build Coastguard Worker void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To) {
6273*9880d681SAndroid Build Coastguard Worker   SDNode *From = FromN.getNode();
6274*9880d681SAndroid Build Coastguard Worker   assert(From->getNumValues() == 1 && FromN.getResNo() == 0 &&
6275*9880d681SAndroid Build Coastguard Worker          "Cannot replace with this method!");
6276*9880d681SAndroid Build Coastguard Worker   assert(From != To.getNode() && "Cannot replace uses of with self");
6277*9880d681SAndroid Build Coastguard Worker 
6278*9880d681SAndroid Build Coastguard Worker   // Iterate over all the existing uses of From. New uses will be added
6279*9880d681SAndroid Build Coastguard Worker   // to the beginning of the use list, which we avoid visiting.
6280*9880d681SAndroid Build Coastguard Worker   // This specifically avoids visiting uses of From that arise while the
6281*9880d681SAndroid Build Coastguard Worker   // replacement is happening, because any such uses would be the result
6282*9880d681SAndroid Build Coastguard Worker   // of CSE: If an existing node looks like From after one of its operands
6283*9880d681SAndroid Build Coastguard Worker   // is replaced by To, we don't want to replace of all its users with To
6284*9880d681SAndroid Build Coastguard Worker   // too. See PR3018 for more info.
6285*9880d681SAndroid Build Coastguard Worker   SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
6286*9880d681SAndroid Build Coastguard Worker   RAUWUpdateListener Listener(*this, UI, UE);
6287*9880d681SAndroid Build Coastguard Worker   while (UI != UE) {
6288*9880d681SAndroid Build Coastguard Worker     SDNode *User = *UI;
6289*9880d681SAndroid Build Coastguard Worker 
6290*9880d681SAndroid Build Coastguard Worker     // This node is about to morph, remove its old self from the CSE maps.
6291*9880d681SAndroid Build Coastguard Worker     RemoveNodeFromCSEMaps(User);
6292*9880d681SAndroid Build Coastguard Worker 
6293*9880d681SAndroid Build Coastguard Worker     // A user can appear in a use list multiple times, and when this
6294*9880d681SAndroid Build Coastguard Worker     // happens the uses are usually next to each other in the list.
6295*9880d681SAndroid Build Coastguard Worker     // To help reduce the number of CSE recomputations, process all
6296*9880d681SAndroid Build Coastguard Worker     // the uses of this user that we can find this way.
6297*9880d681SAndroid Build Coastguard Worker     do {
6298*9880d681SAndroid Build Coastguard Worker       SDUse &Use = UI.getUse();
6299*9880d681SAndroid Build Coastguard Worker       ++UI;
6300*9880d681SAndroid Build Coastguard Worker       Use.set(To);
6301*9880d681SAndroid Build Coastguard Worker     } while (UI != UE && *UI == User);
6302*9880d681SAndroid Build Coastguard Worker 
6303*9880d681SAndroid Build Coastguard Worker     // Now that we have modified User, add it back to the CSE maps.  If it
6304*9880d681SAndroid Build Coastguard Worker     // already exists there, recursively merge the results together.
6305*9880d681SAndroid Build Coastguard Worker     AddModifiedNodeToCSEMaps(User);
6306*9880d681SAndroid Build Coastguard Worker   }
6307*9880d681SAndroid Build Coastguard Worker 
6308*9880d681SAndroid Build Coastguard Worker   // Preserve Debug Values
6309*9880d681SAndroid Build Coastguard Worker   TransferDbgValues(FromN, To);
6310*9880d681SAndroid Build Coastguard Worker 
6311*9880d681SAndroid Build Coastguard Worker   // If we just RAUW'd the root, take note.
6312*9880d681SAndroid Build Coastguard Worker   if (FromN == getRoot())
6313*9880d681SAndroid Build Coastguard Worker     setRoot(To);
6314*9880d681SAndroid Build Coastguard Worker }
6315*9880d681SAndroid Build Coastguard Worker 
6316*9880d681SAndroid Build Coastguard Worker /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
6317*9880d681SAndroid Build Coastguard Worker /// This can cause recursive merging of nodes in the DAG.
6318*9880d681SAndroid Build Coastguard Worker ///
6319*9880d681SAndroid Build Coastguard Worker /// This version assumes that for each value of From, there is a
6320*9880d681SAndroid Build Coastguard Worker /// corresponding value in To in the same position with the same type.
6321*9880d681SAndroid Build Coastguard Worker ///
ReplaceAllUsesWith(SDNode * From,SDNode * To)6322*9880d681SAndroid Build Coastguard Worker void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) {
6323*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
6324*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = From->getNumValues(); i != e; ++i)
6325*9880d681SAndroid Build Coastguard Worker     assert((!From->hasAnyUseOfValue(i) ||
6326*9880d681SAndroid Build Coastguard Worker             From->getValueType(i) == To->getValueType(i)) &&
6327*9880d681SAndroid Build Coastguard Worker            "Cannot use this version of ReplaceAllUsesWith!");
6328*9880d681SAndroid Build Coastguard Worker #endif
6329*9880d681SAndroid Build Coastguard Worker 
6330*9880d681SAndroid Build Coastguard Worker   // Handle the trivial case.
6331*9880d681SAndroid Build Coastguard Worker   if (From == To)
6332*9880d681SAndroid Build Coastguard Worker     return;
6333*9880d681SAndroid Build Coastguard Worker 
6334*9880d681SAndroid Build Coastguard Worker   // Preserve Debug Info. Only do this if there's a use.
6335*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = From->getNumValues(); i != e; ++i)
6336*9880d681SAndroid Build Coastguard Worker     if (From->hasAnyUseOfValue(i)) {
6337*9880d681SAndroid Build Coastguard Worker       assert((i < To->getNumValues()) && "Invalid To location");
6338*9880d681SAndroid Build Coastguard Worker       TransferDbgValues(SDValue(From, i), SDValue(To, i));
6339*9880d681SAndroid Build Coastguard Worker     }
6340*9880d681SAndroid Build Coastguard Worker 
6341*9880d681SAndroid Build Coastguard Worker   // Iterate over just the existing users of From. See the comments in
6342*9880d681SAndroid Build Coastguard Worker   // the ReplaceAllUsesWith above.
6343*9880d681SAndroid Build Coastguard Worker   SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
6344*9880d681SAndroid Build Coastguard Worker   RAUWUpdateListener Listener(*this, UI, UE);
6345*9880d681SAndroid Build Coastguard Worker   while (UI != UE) {
6346*9880d681SAndroid Build Coastguard Worker     SDNode *User = *UI;
6347*9880d681SAndroid Build Coastguard Worker 
6348*9880d681SAndroid Build Coastguard Worker     // This node is about to morph, remove its old self from the CSE maps.
6349*9880d681SAndroid Build Coastguard Worker     RemoveNodeFromCSEMaps(User);
6350*9880d681SAndroid Build Coastguard Worker 
6351*9880d681SAndroid Build Coastguard Worker     // A user can appear in a use list multiple times, and when this
6352*9880d681SAndroid Build Coastguard Worker     // happens the uses are usually next to each other in the list.
6353*9880d681SAndroid Build Coastguard Worker     // To help reduce the number of CSE recomputations, process all
6354*9880d681SAndroid Build Coastguard Worker     // the uses of this user that we can find this way.
6355*9880d681SAndroid Build Coastguard Worker     do {
6356*9880d681SAndroid Build Coastguard Worker       SDUse &Use = UI.getUse();
6357*9880d681SAndroid Build Coastguard Worker       ++UI;
6358*9880d681SAndroid Build Coastguard Worker       Use.setNode(To);
6359*9880d681SAndroid Build Coastguard Worker     } while (UI != UE && *UI == User);
6360*9880d681SAndroid Build Coastguard Worker 
6361*9880d681SAndroid Build Coastguard Worker     // Now that we have modified User, add it back to the CSE maps.  If it
6362*9880d681SAndroid Build Coastguard Worker     // already exists there, recursively merge the results together.
6363*9880d681SAndroid Build Coastguard Worker     AddModifiedNodeToCSEMaps(User);
6364*9880d681SAndroid Build Coastguard Worker   }
6365*9880d681SAndroid Build Coastguard Worker 
6366*9880d681SAndroid Build Coastguard Worker   // If we just RAUW'd the root, take note.
6367*9880d681SAndroid Build Coastguard Worker   if (From == getRoot().getNode())
6368*9880d681SAndroid Build Coastguard Worker     setRoot(SDValue(To, getRoot().getResNo()));
6369*9880d681SAndroid Build Coastguard Worker }
6370*9880d681SAndroid Build Coastguard Worker 
6371*9880d681SAndroid Build Coastguard Worker /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
6372*9880d681SAndroid Build Coastguard Worker /// This can cause recursive merging of nodes in the DAG.
6373*9880d681SAndroid Build Coastguard Worker ///
6374*9880d681SAndroid Build Coastguard Worker /// This version can replace From with any result values.  To must match the
6375*9880d681SAndroid Build Coastguard Worker /// number and types of values returned by From.
ReplaceAllUsesWith(SDNode * From,const SDValue * To)6376*9880d681SAndroid Build Coastguard Worker void SelectionDAG::ReplaceAllUsesWith(SDNode *From, const SDValue *To) {
6377*9880d681SAndroid Build Coastguard Worker   if (From->getNumValues() == 1)  // Handle the simple case efficiently.
6378*9880d681SAndroid Build Coastguard Worker     return ReplaceAllUsesWith(SDValue(From, 0), To[0]);
6379*9880d681SAndroid Build Coastguard Worker 
6380*9880d681SAndroid Build Coastguard Worker   // Preserve Debug Info.
6381*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = From->getNumValues(); i != e; ++i)
6382*9880d681SAndroid Build Coastguard Worker     TransferDbgValues(SDValue(From, i), *To);
6383*9880d681SAndroid Build Coastguard Worker 
6384*9880d681SAndroid Build Coastguard Worker   // Iterate over just the existing users of From. See the comments in
6385*9880d681SAndroid Build Coastguard Worker   // the ReplaceAllUsesWith above.
6386*9880d681SAndroid Build Coastguard Worker   SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
6387*9880d681SAndroid Build Coastguard Worker   RAUWUpdateListener Listener(*this, UI, UE);
6388*9880d681SAndroid Build Coastguard Worker   while (UI != UE) {
6389*9880d681SAndroid Build Coastguard Worker     SDNode *User = *UI;
6390*9880d681SAndroid Build Coastguard Worker 
6391*9880d681SAndroid Build Coastguard Worker     // This node is about to morph, remove its old self from the CSE maps.
6392*9880d681SAndroid Build Coastguard Worker     RemoveNodeFromCSEMaps(User);
6393*9880d681SAndroid Build Coastguard Worker 
6394*9880d681SAndroid Build Coastguard Worker     // A user can appear in a use list multiple times, and when this
6395*9880d681SAndroid Build Coastguard Worker     // happens the uses are usually next to each other in the list.
6396*9880d681SAndroid Build Coastguard Worker     // To help reduce the number of CSE recomputations, process all
6397*9880d681SAndroid Build Coastguard Worker     // the uses of this user that we can find this way.
6398*9880d681SAndroid Build Coastguard Worker     do {
6399*9880d681SAndroid Build Coastguard Worker       SDUse &Use = UI.getUse();
6400*9880d681SAndroid Build Coastguard Worker       const SDValue &ToOp = To[Use.getResNo()];
6401*9880d681SAndroid Build Coastguard Worker       ++UI;
6402*9880d681SAndroid Build Coastguard Worker       Use.set(ToOp);
6403*9880d681SAndroid Build Coastguard Worker     } while (UI != UE && *UI == User);
6404*9880d681SAndroid Build Coastguard Worker 
6405*9880d681SAndroid Build Coastguard Worker     // Now that we have modified User, add it back to the CSE maps.  If it
6406*9880d681SAndroid Build Coastguard Worker     // already exists there, recursively merge the results together.
6407*9880d681SAndroid Build Coastguard Worker     AddModifiedNodeToCSEMaps(User);
6408*9880d681SAndroid Build Coastguard Worker   }
6409*9880d681SAndroid Build Coastguard Worker 
6410*9880d681SAndroid Build Coastguard Worker   // If we just RAUW'd the root, take note.
6411*9880d681SAndroid Build Coastguard Worker   if (From == getRoot().getNode())
6412*9880d681SAndroid Build Coastguard Worker     setRoot(SDValue(To[getRoot().getResNo()]));
6413*9880d681SAndroid Build Coastguard Worker }
6414*9880d681SAndroid Build Coastguard Worker 
6415*9880d681SAndroid Build Coastguard Worker /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
6416*9880d681SAndroid Build Coastguard Worker /// uses of other values produced by From.getNode() alone.  The Deleted
6417*9880d681SAndroid Build Coastguard Worker /// vector is handled the same way as for ReplaceAllUsesWith.
ReplaceAllUsesOfValueWith(SDValue From,SDValue To)6418*9880d681SAndroid Build Coastguard Worker void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To){
6419*9880d681SAndroid Build Coastguard Worker   // Handle the really simple, really trivial case efficiently.
6420*9880d681SAndroid Build Coastguard Worker   if (From == To) return;
6421*9880d681SAndroid Build Coastguard Worker 
6422*9880d681SAndroid Build Coastguard Worker   // Handle the simple, trivial, case efficiently.
6423*9880d681SAndroid Build Coastguard Worker   if (From.getNode()->getNumValues() == 1) {
6424*9880d681SAndroid Build Coastguard Worker     ReplaceAllUsesWith(From, To);
6425*9880d681SAndroid Build Coastguard Worker     return;
6426*9880d681SAndroid Build Coastguard Worker   }
6427*9880d681SAndroid Build Coastguard Worker 
6428*9880d681SAndroid Build Coastguard Worker   // Preserve Debug Info.
6429*9880d681SAndroid Build Coastguard Worker   TransferDbgValues(From, To);
6430*9880d681SAndroid Build Coastguard Worker 
6431*9880d681SAndroid Build Coastguard Worker   // Iterate over just the existing users of From. See the comments in
6432*9880d681SAndroid Build Coastguard Worker   // the ReplaceAllUsesWith above.
6433*9880d681SAndroid Build Coastguard Worker   SDNode::use_iterator UI = From.getNode()->use_begin(),
6434*9880d681SAndroid Build Coastguard Worker                        UE = From.getNode()->use_end();
6435*9880d681SAndroid Build Coastguard Worker   RAUWUpdateListener Listener(*this, UI, UE);
6436*9880d681SAndroid Build Coastguard Worker   while (UI != UE) {
6437*9880d681SAndroid Build Coastguard Worker     SDNode *User = *UI;
6438*9880d681SAndroid Build Coastguard Worker     bool UserRemovedFromCSEMaps = false;
6439*9880d681SAndroid Build Coastguard Worker 
6440*9880d681SAndroid Build Coastguard Worker     // A user can appear in a use list multiple times, and when this
6441*9880d681SAndroid Build Coastguard Worker     // happens the uses are usually next to each other in the list.
6442*9880d681SAndroid Build Coastguard Worker     // To help reduce the number of CSE recomputations, process all
6443*9880d681SAndroid Build Coastguard Worker     // the uses of this user that we can find this way.
6444*9880d681SAndroid Build Coastguard Worker     do {
6445*9880d681SAndroid Build Coastguard Worker       SDUse &Use = UI.getUse();
6446*9880d681SAndroid Build Coastguard Worker 
6447*9880d681SAndroid Build Coastguard Worker       // Skip uses of different values from the same node.
6448*9880d681SAndroid Build Coastguard Worker       if (Use.getResNo() != From.getResNo()) {
6449*9880d681SAndroid Build Coastguard Worker         ++UI;
6450*9880d681SAndroid Build Coastguard Worker         continue;
6451*9880d681SAndroid Build Coastguard Worker       }
6452*9880d681SAndroid Build Coastguard Worker 
6453*9880d681SAndroid Build Coastguard Worker       // If this node hasn't been modified yet, it's still in the CSE maps,
6454*9880d681SAndroid Build Coastguard Worker       // so remove its old self from the CSE maps.
6455*9880d681SAndroid Build Coastguard Worker       if (!UserRemovedFromCSEMaps) {
6456*9880d681SAndroid Build Coastguard Worker         RemoveNodeFromCSEMaps(User);
6457*9880d681SAndroid Build Coastguard Worker         UserRemovedFromCSEMaps = true;
6458*9880d681SAndroid Build Coastguard Worker       }
6459*9880d681SAndroid Build Coastguard Worker 
6460*9880d681SAndroid Build Coastguard Worker       ++UI;
6461*9880d681SAndroid Build Coastguard Worker       Use.set(To);
6462*9880d681SAndroid Build Coastguard Worker     } while (UI != UE && *UI == User);
6463*9880d681SAndroid Build Coastguard Worker 
6464*9880d681SAndroid Build Coastguard Worker     // We are iterating over all uses of the From node, so if a use
6465*9880d681SAndroid Build Coastguard Worker     // doesn't use the specific value, no changes are made.
6466*9880d681SAndroid Build Coastguard Worker     if (!UserRemovedFromCSEMaps)
6467*9880d681SAndroid Build Coastguard Worker       continue;
6468*9880d681SAndroid Build Coastguard Worker 
6469*9880d681SAndroid Build Coastguard Worker     // Now that we have modified User, add it back to the CSE maps.  If it
6470*9880d681SAndroid Build Coastguard Worker     // already exists there, recursively merge the results together.
6471*9880d681SAndroid Build Coastguard Worker     AddModifiedNodeToCSEMaps(User);
6472*9880d681SAndroid Build Coastguard Worker   }
6473*9880d681SAndroid Build Coastguard Worker 
6474*9880d681SAndroid Build Coastguard Worker   // If we just RAUW'd the root, take note.
6475*9880d681SAndroid Build Coastguard Worker   if (From == getRoot())
6476*9880d681SAndroid Build Coastguard Worker     setRoot(To);
6477*9880d681SAndroid Build Coastguard Worker }
6478*9880d681SAndroid Build Coastguard Worker 
6479*9880d681SAndroid Build Coastguard Worker namespace {
6480*9880d681SAndroid Build Coastguard Worker   /// UseMemo - This class is used by SelectionDAG::ReplaceAllUsesOfValuesWith
6481*9880d681SAndroid Build Coastguard Worker   /// to record information about a use.
6482*9880d681SAndroid Build Coastguard Worker   struct UseMemo {
6483*9880d681SAndroid Build Coastguard Worker     SDNode *User;
6484*9880d681SAndroid Build Coastguard Worker     unsigned Index;
6485*9880d681SAndroid Build Coastguard Worker     SDUse *Use;
6486*9880d681SAndroid Build Coastguard Worker   };
6487*9880d681SAndroid Build Coastguard Worker 
6488*9880d681SAndroid Build Coastguard Worker   /// operator< - Sort Memos by User.
operator <(const UseMemo & L,const UseMemo & R)6489*9880d681SAndroid Build Coastguard Worker   bool operator<(const UseMemo &L, const UseMemo &R) {
6490*9880d681SAndroid Build Coastguard Worker     return (intptr_t)L.User < (intptr_t)R.User;
6491*9880d681SAndroid Build Coastguard Worker   }
6492*9880d681SAndroid Build Coastguard Worker }
6493*9880d681SAndroid Build Coastguard Worker 
6494*9880d681SAndroid Build Coastguard Worker /// ReplaceAllUsesOfValuesWith - Replace any uses of From with To, leaving
6495*9880d681SAndroid Build Coastguard Worker /// uses of other values produced by From.getNode() alone.  The same value
6496*9880d681SAndroid Build Coastguard Worker /// may appear in both the From and To list.  The Deleted vector is
6497*9880d681SAndroid Build Coastguard Worker /// handled the same way as for ReplaceAllUsesWith.
ReplaceAllUsesOfValuesWith(const SDValue * From,const SDValue * To,unsigned Num)6498*9880d681SAndroid Build Coastguard Worker void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,
6499*9880d681SAndroid Build Coastguard Worker                                               const SDValue *To,
6500*9880d681SAndroid Build Coastguard Worker                                               unsigned Num){
6501*9880d681SAndroid Build Coastguard Worker   // Handle the simple, trivial case efficiently.
6502*9880d681SAndroid Build Coastguard Worker   if (Num == 1)
6503*9880d681SAndroid Build Coastguard Worker     return ReplaceAllUsesOfValueWith(*From, *To);
6504*9880d681SAndroid Build Coastguard Worker 
6505*9880d681SAndroid Build Coastguard Worker   TransferDbgValues(*From, *To);
6506*9880d681SAndroid Build Coastguard Worker 
6507*9880d681SAndroid Build Coastguard Worker   // Read up all the uses and make records of them. This helps
6508*9880d681SAndroid Build Coastguard Worker   // processing new uses that are introduced during the
6509*9880d681SAndroid Build Coastguard Worker   // replacement process.
6510*9880d681SAndroid Build Coastguard Worker   SmallVector<UseMemo, 4> Uses;
6511*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i != Num; ++i) {
6512*9880d681SAndroid Build Coastguard Worker     unsigned FromResNo = From[i].getResNo();
6513*9880d681SAndroid Build Coastguard Worker     SDNode *FromNode = From[i].getNode();
6514*9880d681SAndroid Build Coastguard Worker     for (SDNode::use_iterator UI = FromNode->use_begin(),
6515*9880d681SAndroid Build Coastguard Worker          E = FromNode->use_end(); UI != E; ++UI) {
6516*9880d681SAndroid Build Coastguard Worker       SDUse &Use = UI.getUse();
6517*9880d681SAndroid Build Coastguard Worker       if (Use.getResNo() == FromResNo) {
6518*9880d681SAndroid Build Coastguard Worker         UseMemo Memo = { *UI, i, &Use };
6519*9880d681SAndroid Build Coastguard Worker         Uses.push_back(Memo);
6520*9880d681SAndroid Build Coastguard Worker       }
6521*9880d681SAndroid Build Coastguard Worker     }
6522*9880d681SAndroid Build Coastguard Worker   }
6523*9880d681SAndroid Build Coastguard Worker 
6524*9880d681SAndroid Build Coastguard Worker   // Sort the uses, so that all the uses from a given User are together.
6525*9880d681SAndroid Build Coastguard Worker   std::sort(Uses.begin(), Uses.end());
6526*9880d681SAndroid Build Coastguard Worker 
6527*9880d681SAndroid Build Coastguard Worker   for (unsigned UseIndex = 0, UseIndexEnd = Uses.size();
6528*9880d681SAndroid Build Coastguard Worker        UseIndex != UseIndexEnd; ) {
6529*9880d681SAndroid Build Coastguard Worker     // We know that this user uses some value of From.  If it is the right
6530*9880d681SAndroid Build Coastguard Worker     // value, update it.
6531*9880d681SAndroid Build Coastguard Worker     SDNode *User = Uses[UseIndex].User;
6532*9880d681SAndroid Build Coastguard Worker 
6533*9880d681SAndroid Build Coastguard Worker     // This node is about to morph, remove its old self from the CSE maps.
6534*9880d681SAndroid Build Coastguard Worker     RemoveNodeFromCSEMaps(User);
6535*9880d681SAndroid Build Coastguard Worker 
6536*9880d681SAndroid Build Coastguard Worker     // The Uses array is sorted, so all the uses for a given User
6537*9880d681SAndroid Build Coastguard Worker     // are next to each other in the list.
6538*9880d681SAndroid Build Coastguard Worker     // To help reduce the number of CSE recomputations, process all
6539*9880d681SAndroid Build Coastguard Worker     // the uses of this user that we can find this way.
6540*9880d681SAndroid Build Coastguard Worker     do {
6541*9880d681SAndroid Build Coastguard Worker       unsigned i = Uses[UseIndex].Index;
6542*9880d681SAndroid Build Coastguard Worker       SDUse &Use = *Uses[UseIndex].Use;
6543*9880d681SAndroid Build Coastguard Worker       ++UseIndex;
6544*9880d681SAndroid Build Coastguard Worker 
6545*9880d681SAndroid Build Coastguard Worker       Use.set(To[i]);
6546*9880d681SAndroid Build Coastguard Worker     } while (UseIndex != UseIndexEnd && Uses[UseIndex].User == User);
6547*9880d681SAndroid Build Coastguard Worker 
6548*9880d681SAndroid Build Coastguard Worker     // Now that we have modified User, add it back to the CSE maps.  If it
6549*9880d681SAndroid Build Coastguard Worker     // already exists there, recursively merge the results together.
6550*9880d681SAndroid Build Coastguard Worker     AddModifiedNodeToCSEMaps(User);
6551*9880d681SAndroid Build Coastguard Worker   }
6552*9880d681SAndroid Build Coastguard Worker }
6553*9880d681SAndroid Build Coastguard Worker 
6554*9880d681SAndroid Build Coastguard Worker /// AssignTopologicalOrder - Assign a unique node id for each node in the DAG
6555*9880d681SAndroid Build Coastguard Worker /// based on their topological order. It returns the maximum id and a vector
6556*9880d681SAndroid Build Coastguard Worker /// of the SDNodes* in assigned order by reference.
AssignTopologicalOrder()6557*9880d681SAndroid Build Coastguard Worker unsigned SelectionDAG::AssignTopologicalOrder() {
6558*9880d681SAndroid Build Coastguard Worker 
6559*9880d681SAndroid Build Coastguard Worker   unsigned DAGSize = 0;
6560*9880d681SAndroid Build Coastguard Worker 
6561*9880d681SAndroid Build Coastguard Worker   // SortedPos tracks the progress of the algorithm. Nodes before it are
6562*9880d681SAndroid Build Coastguard Worker   // sorted, nodes after it are unsorted. When the algorithm completes
6563*9880d681SAndroid Build Coastguard Worker   // it is at the end of the list.
6564*9880d681SAndroid Build Coastguard Worker   allnodes_iterator SortedPos = allnodes_begin();
6565*9880d681SAndroid Build Coastguard Worker 
6566*9880d681SAndroid Build Coastguard Worker   // Visit all the nodes. Move nodes with no operands to the front of
6567*9880d681SAndroid Build Coastguard Worker   // the list immediately. Annotate nodes that do have operands with their
6568*9880d681SAndroid Build Coastguard Worker   // operand count. Before we do this, the Node Id fields of the nodes
6569*9880d681SAndroid Build Coastguard Worker   // may contain arbitrary values. After, the Node Id fields for nodes
6570*9880d681SAndroid Build Coastguard Worker   // before SortedPos will contain the topological sort index, and the
6571*9880d681SAndroid Build Coastguard Worker   // Node Id fields for nodes At SortedPos and after will contain the
6572*9880d681SAndroid Build Coastguard Worker   // count of outstanding operands.
6573*9880d681SAndroid Build Coastguard Worker   for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ) {
6574*9880d681SAndroid Build Coastguard Worker     SDNode *N = &*I++;
6575*9880d681SAndroid Build Coastguard Worker     checkForCycles(N, this);
6576*9880d681SAndroid Build Coastguard Worker     unsigned Degree = N->getNumOperands();
6577*9880d681SAndroid Build Coastguard Worker     if (Degree == 0) {
6578*9880d681SAndroid Build Coastguard Worker       // A node with no uses, add it to the result array immediately.
6579*9880d681SAndroid Build Coastguard Worker       N->setNodeId(DAGSize++);
6580*9880d681SAndroid Build Coastguard Worker       allnodes_iterator Q(N);
6581*9880d681SAndroid Build Coastguard Worker       if (Q != SortedPos)
6582*9880d681SAndroid Build Coastguard Worker         SortedPos = AllNodes.insert(SortedPos, AllNodes.remove(Q));
6583*9880d681SAndroid Build Coastguard Worker       assert(SortedPos != AllNodes.end() && "Overran node list");
6584*9880d681SAndroid Build Coastguard Worker       ++SortedPos;
6585*9880d681SAndroid Build Coastguard Worker     } else {
6586*9880d681SAndroid Build Coastguard Worker       // Temporarily use the Node Id as scratch space for the degree count.
6587*9880d681SAndroid Build Coastguard Worker       N->setNodeId(Degree);
6588*9880d681SAndroid Build Coastguard Worker     }
6589*9880d681SAndroid Build Coastguard Worker   }
6590*9880d681SAndroid Build Coastguard Worker 
6591*9880d681SAndroid Build Coastguard Worker   // Visit all the nodes. As we iterate, move nodes into sorted order,
6592*9880d681SAndroid Build Coastguard Worker   // such that by the time the end is reached all nodes will be sorted.
6593*9880d681SAndroid Build Coastguard Worker   for (SDNode &Node : allnodes()) {
6594*9880d681SAndroid Build Coastguard Worker     SDNode *N = &Node;
6595*9880d681SAndroid Build Coastguard Worker     checkForCycles(N, this);
6596*9880d681SAndroid Build Coastguard Worker     // N is in sorted position, so all its uses have one less operand
6597*9880d681SAndroid Build Coastguard Worker     // that needs to be sorted.
6598*9880d681SAndroid Build Coastguard Worker     for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
6599*9880d681SAndroid Build Coastguard Worker          UI != UE; ++UI) {
6600*9880d681SAndroid Build Coastguard Worker       SDNode *P = *UI;
6601*9880d681SAndroid Build Coastguard Worker       unsigned Degree = P->getNodeId();
6602*9880d681SAndroid Build Coastguard Worker       assert(Degree != 0 && "Invalid node degree");
6603*9880d681SAndroid Build Coastguard Worker       --Degree;
6604*9880d681SAndroid Build Coastguard Worker       if (Degree == 0) {
6605*9880d681SAndroid Build Coastguard Worker         // All of P's operands are sorted, so P may sorted now.
6606*9880d681SAndroid Build Coastguard Worker         P->setNodeId(DAGSize++);
6607*9880d681SAndroid Build Coastguard Worker         if (P->getIterator() != SortedPos)
6608*9880d681SAndroid Build Coastguard Worker           SortedPos = AllNodes.insert(SortedPos, AllNodes.remove(P));
6609*9880d681SAndroid Build Coastguard Worker         assert(SortedPos != AllNodes.end() && "Overran node list");
6610*9880d681SAndroid Build Coastguard Worker         ++SortedPos;
6611*9880d681SAndroid Build Coastguard Worker       } else {
6612*9880d681SAndroid Build Coastguard Worker         // Update P's outstanding operand count.
6613*9880d681SAndroid Build Coastguard Worker         P->setNodeId(Degree);
6614*9880d681SAndroid Build Coastguard Worker       }
6615*9880d681SAndroid Build Coastguard Worker     }
6616*9880d681SAndroid Build Coastguard Worker     if (Node.getIterator() == SortedPos) {
6617*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
6618*9880d681SAndroid Build Coastguard Worker       allnodes_iterator I(N);
6619*9880d681SAndroid Build Coastguard Worker       SDNode *S = &*++I;
6620*9880d681SAndroid Build Coastguard Worker       dbgs() << "Overran sorted position:\n";
6621*9880d681SAndroid Build Coastguard Worker       S->dumprFull(this); dbgs() << "\n";
6622*9880d681SAndroid Build Coastguard Worker       dbgs() << "Checking if this is due to cycles\n";
6623*9880d681SAndroid Build Coastguard Worker       checkForCycles(this, true);
6624*9880d681SAndroid Build Coastguard Worker #endif
6625*9880d681SAndroid Build Coastguard Worker       llvm_unreachable(nullptr);
6626*9880d681SAndroid Build Coastguard Worker     }
6627*9880d681SAndroid Build Coastguard Worker   }
6628*9880d681SAndroid Build Coastguard Worker 
6629*9880d681SAndroid Build Coastguard Worker   assert(SortedPos == AllNodes.end() &&
6630*9880d681SAndroid Build Coastguard Worker          "Topological sort incomplete!");
6631*9880d681SAndroid Build Coastguard Worker   assert(AllNodes.front().getOpcode() == ISD::EntryToken &&
6632*9880d681SAndroid Build Coastguard Worker          "First node in topological sort is not the entry token!");
6633*9880d681SAndroid Build Coastguard Worker   assert(AllNodes.front().getNodeId() == 0 &&
6634*9880d681SAndroid Build Coastguard Worker          "First node in topological sort has non-zero id!");
6635*9880d681SAndroid Build Coastguard Worker   assert(AllNodes.front().getNumOperands() == 0 &&
6636*9880d681SAndroid Build Coastguard Worker          "First node in topological sort has operands!");
6637*9880d681SAndroid Build Coastguard Worker   assert(AllNodes.back().getNodeId() == (int)DAGSize-1 &&
6638*9880d681SAndroid Build Coastguard Worker          "Last node in topologic sort has unexpected id!");
6639*9880d681SAndroid Build Coastguard Worker   assert(AllNodes.back().use_empty() &&
6640*9880d681SAndroid Build Coastguard Worker          "Last node in topologic sort has users!");
6641*9880d681SAndroid Build Coastguard Worker   assert(DAGSize == allnodes_size() && "Node count mismatch!");
6642*9880d681SAndroid Build Coastguard Worker   return DAGSize;
6643*9880d681SAndroid Build Coastguard Worker }
6644*9880d681SAndroid Build Coastguard Worker 
6645*9880d681SAndroid Build Coastguard Worker /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
6646*9880d681SAndroid Build Coastguard Worker /// value is produced by SD.
AddDbgValue(SDDbgValue * DB,SDNode * SD,bool isParameter)6647*9880d681SAndroid Build Coastguard Worker void SelectionDAG::AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter) {
6648*9880d681SAndroid Build Coastguard Worker   if (SD) {
6649*9880d681SAndroid Build Coastguard Worker     assert(DbgInfo->getSDDbgValues(SD).empty() || SD->getHasDebugValue());
6650*9880d681SAndroid Build Coastguard Worker     SD->setHasDebugValue(true);
6651*9880d681SAndroid Build Coastguard Worker   }
6652*9880d681SAndroid Build Coastguard Worker   DbgInfo->add(DB, SD, isParameter);
6653*9880d681SAndroid Build Coastguard Worker }
6654*9880d681SAndroid Build Coastguard Worker 
6655*9880d681SAndroid Build Coastguard Worker /// TransferDbgValues - Transfer SDDbgValues. Called in replace nodes.
TransferDbgValues(SDValue From,SDValue To)6656*9880d681SAndroid Build Coastguard Worker void SelectionDAG::TransferDbgValues(SDValue From, SDValue To) {
6657*9880d681SAndroid Build Coastguard Worker   if (From == To || !From.getNode()->getHasDebugValue())
6658*9880d681SAndroid Build Coastguard Worker     return;
6659*9880d681SAndroid Build Coastguard Worker   SDNode *FromNode = From.getNode();
6660*9880d681SAndroid Build Coastguard Worker   SDNode *ToNode = To.getNode();
6661*9880d681SAndroid Build Coastguard Worker   ArrayRef<SDDbgValue *> DVs = GetDbgValues(FromNode);
6662*9880d681SAndroid Build Coastguard Worker   for (ArrayRef<SDDbgValue *>::iterator I = DVs.begin(), E = DVs.end();
6663*9880d681SAndroid Build Coastguard Worker        I != E; ++I) {
6664*9880d681SAndroid Build Coastguard Worker     SDDbgValue *Dbg = *I;
6665*9880d681SAndroid Build Coastguard Worker     // Only add Dbgvalues attached to same ResNo.
6666*9880d681SAndroid Build Coastguard Worker     if (Dbg->getKind() == SDDbgValue::SDNODE &&
6667*9880d681SAndroid Build Coastguard Worker         Dbg->getResNo() == From.getResNo()) {
6668*9880d681SAndroid Build Coastguard Worker       SDDbgValue *Clone =
6669*9880d681SAndroid Build Coastguard Worker           getDbgValue(Dbg->getVariable(), Dbg->getExpression(), ToNode,
6670*9880d681SAndroid Build Coastguard Worker                       To.getResNo(), Dbg->isIndirect(), Dbg->getOffset(),
6671*9880d681SAndroid Build Coastguard Worker                       Dbg->getDebugLoc(), Dbg->getOrder());
6672*9880d681SAndroid Build Coastguard Worker       AddDbgValue(Clone, ToNode, false);
6673*9880d681SAndroid Build Coastguard Worker     }
6674*9880d681SAndroid Build Coastguard Worker   }
6675*9880d681SAndroid Build Coastguard Worker }
6676*9880d681SAndroid Build Coastguard Worker 
6677*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
6678*9880d681SAndroid Build Coastguard Worker //                              SDNode Class
6679*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
6680*9880d681SAndroid Build Coastguard Worker 
isNullConstant(SDValue V)6681*9880d681SAndroid Build Coastguard Worker bool llvm::isNullConstant(SDValue V) {
6682*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *Const = dyn_cast<ConstantSDNode>(V);
6683*9880d681SAndroid Build Coastguard Worker   return Const != nullptr && Const->isNullValue();
6684*9880d681SAndroid Build Coastguard Worker }
6685*9880d681SAndroid Build Coastguard Worker 
isNullFPConstant(SDValue V)6686*9880d681SAndroid Build Coastguard Worker bool llvm::isNullFPConstant(SDValue V) {
6687*9880d681SAndroid Build Coastguard Worker   ConstantFPSDNode *Const = dyn_cast<ConstantFPSDNode>(V);
6688*9880d681SAndroid Build Coastguard Worker   return Const != nullptr && Const->isZero() && !Const->isNegative();
6689*9880d681SAndroid Build Coastguard Worker }
6690*9880d681SAndroid Build Coastguard Worker 
isAllOnesConstant(SDValue V)6691*9880d681SAndroid Build Coastguard Worker bool llvm::isAllOnesConstant(SDValue V) {
6692*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *Const = dyn_cast<ConstantSDNode>(V);
6693*9880d681SAndroid Build Coastguard Worker   return Const != nullptr && Const->isAllOnesValue();
6694*9880d681SAndroid Build Coastguard Worker }
6695*9880d681SAndroid Build Coastguard Worker 
isOneConstant(SDValue V)6696*9880d681SAndroid Build Coastguard Worker bool llvm::isOneConstant(SDValue V) {
6697*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *Const = dyn_cast<ConstantSDNode>(V);
6698*9880d681SAndroid Build Coastguard Worker   return Const != nullptr && Const->isOne();
6699*9880d681SAndroid Build Coastguard Worker }
6700*9880d681SAndroid Build Coastguard Worker 
isBitwiseNot(SDValue V)6701*9880d681SAndroid Build Coastguard Worker bool llvm::isBitwiseNot(SDValue V) {
6702*9880d681SAndroid Build Coastguard Worker   return V.getOpcode() == ISD::XOR && isAllOnesConstant(V.getOperand(1));
6703*9880d681SAndroid Build Coastguard Worker }
6704*9880d681SAndroid Build Coastguard Worker 
~HandleSDNode()6705*9880d681SAndroid Build Coastguard Worker HandleSDNode::~HandleSDNode() {
6706*9880d681SAndroid Build Coastguard Worker   DropOperands();
6707*9880d681SAndroid Build Coastguard Worker }
6708*9880d681SAndroid Build Coastguard Worker 
GlobalAddressSDNode(unsigned Opc,unsigned Order,const DebugLoc & DL,const GlobalValue * GA,EVT VT,int64_t o,unsigned char TF)6709*9880d681SAndroid Build Coastguard Worker GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, unsigned Order,
6710*9880d681SAndroid Build Coastguard Worker                                          const DebugLoc &DL,
6711*9880d681SAndroid Build Coastguard Worker                                          const GlobalValue *GA, EVT VT,
6712*9880d681SAndroid Build Coastguard Worker                                          int64_t o, unsigned char TF)
6713*9880d681SAndroid Build Coastguard Worker     : SDNode(Opc, Order, DL, getSDVTList(VT)), Offset(o), TargetFlags(TF) {
6714*9880d681SAndroid Build Coastguard Worker   TheGlobal = GA;
6715*9880d681SAndroid Build Coastguard Worker }
6716*9880d681SAndroid Build Coastguard Worker 
AddrSpaceCastSDNode(unsigned Order,const DebugLoc & dl,EVT VT,unsigned SrcAS,unsigned DestAS)6717*9880d681SAndroid Build Coastguard Worker AddrSpaceCastSDNode::AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl,
6718*9880d681SAndroid Build Coastguard Worker                                          EVT VT, unsigned SrcAS,
6719*9880d681SAndroid Build Coastguard Worker                                          unsigned DestAS)
6720*9880d681SAndroid Build Coastguard Worker     : SDNode(ISD::ADDRSPACECAST, Order, dl, getSDVTList(VT)),
6721*9880d681SAndroid Build Coastguard Worker       SrcAddrSpace(SrcAS), DestAddrSpace(DestAS) {}
6722*9880d681SAndroid Build Coastguard Worker 
MemSDNode(unsigned Opc,unsigned Order,const DebugLoc & dl,SDVTList VTs,EVT memvt,MachineMemOperand * mmo)6723*9880d681SAndroid Build Coastguard Worker MemSDNode::MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
6724*9880d681SAndroid Build Coastguard Worker                      SDVTList VTs, EVT memvt, MachineMemOperand *mmo)
6725*9880d681SAndroid Build Coastguard Worker     : SDNode(Opc, Order, dl, VTs), MemoryVT(memvt), MMO(mmo) {
6726*9880d681SAndroid Build Coastguard Worker   SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile(),
6727*9880d681SAndroid Build Coastguard Worker                                       MMO->isNonTemporal(), MMO->isInvariant());
6728*9880d681SAndroid Build Coastguard Worker   assert(isVolatile() == MMO->isVolatile() && "Volatile encoding error!");
6729*9880d681SAndroid Build Coastguard Worker   assert(isNonTemporal() == MMO->isNonTemporal() &&
6730*9880d681SAndroid Build Coastguard Worker          "Non-temporal encoding error!");
6731*9880d681SAndroid Build Coastguard Worker   // We check here that the size of the memory operand fits within the size of
6732*9880d681SAndroid Build Coastguard Worker   // the MMO. This is because the MMO might indicate only a possible address
6733*9880d681SAndroid Build Coastguard Worker   // range instead of specifying the affected memory addresses precisely.
6734*9880d681SAndroid Build Coastguard Worker   assert(memvt.getStoreSize() <= MMO->getSize() && "Size mismatch!");
6735*9880d681SAndroid Build Coastguard Worker }
6736*9880d681SAndroid Build Coastguard Worker 
6737*9880d681SAndroid Build Coastguard Worker /// Profile - Gather unique data for the node.
6738*9880d681SAndroid Build Coastguard Worker ///
Profile(FoldingSetNodeID & ID) const6739*9880d681SAndroid Build Coastguard Worker void SDNode::Profile(FoldingSetNodeID &ID) const {
6740*9880d681SAndroid Build Coastguard Worker   AddNodeIDNode(ID, this);
6741*9880d681SAndroid Build Coastguard Worker }
6742*9880d681SAndroid Build Coastguard Worker 
6743*9880d681SAndroid Build Coastguard Worker namespace {
6744*9880d681SAndroid Build Coastguard Worker   struct EVTArray {
6745*9880d681SAndroid Build Coastguard Worker     std::vector<EVT> VTs;
6746*9880d681SAndroid Build Coastguard Worker 
EVTArray__anoncc18617f0911::EVTArray6747*9880d681SAndroid Build Coastguard Worker     EVTArray() {
6748*9880d681SAndroid Build Coastguard Worker       VTs.reserve(MVT::LAST_VALUETYPE);
6749*9880d681SAndroid Build Coastguard Worker       for (unsigned i = 0; i < MVT::LAST_VALUETYPE; ++i)
6750*9880d681SAndroid Build Coastguard Worker         VTs.push_back(MVT((MVT::SimpleValueType)i));
6751*9880d681SAndroid Build Coastguard Worker     }
6752*9880d681SAndroid Build Coastguard Worker   };
6753*9880d681SAndroid Build Coastguard Worker }
6754*9880d681SAndroid Build Coastguard Worker 
6755*9880d681SAndroid Build Coastguard Worker static ManagedStatic<std::set<EVT, EVT::compareRawBits> > EVTs;
6756*9880d681SAndroid Build Coastguard Worker static ManagedStatic<EVTArray> SimpleVTArray;
6757*9880d681SAndroid Build Coastguard Worker static ManagedStatic<sys::SmartMutex<true> > VTMutex;
6758*9880d681SAndroid Build Coastguard Worker 
6759*9880d681SAndroid Build Coastguard Worker /// getValueTypeList - Return a pointer to the specified value type.
6760*9880d681SAndroid Build Coastguard Worker ///
getValueTypeList(EVT VT)6761*9880d681SAndroid Build Coastguard Worker const EVT *SDNode::getValueTypeList(EVT VT) {
6762*9880d681SAndroid Build Coastguard Worker   if (VT.isExtended()) {
6763*9880d681SAndroid Build Coastguard Worker     sys::SmartScopedLock<true> Lock(*VTMutex);
6764*9880d681SAndroid Build Coastguard Worker     return &(*EVTs->insert(VT).first);
6765*9880d681SAndroid Build Coastguard Worker   } else {
6766*9880d681SAndroid Build Coastguard Worker     assert(VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
6767*9880d681SAndroid Build Coastguard Worker            "Value type out of range!");
6768*9880d681SAndroid Build Coastguard Worker     return &SimpleVTArray->VTs[VT.getSimpleVT().SimpleTy];
6769*9880d681SAndroid Build Coastguard Worker   }
6770*9880d681SAndroid Build Coastguard Worker }
6771*9880d681SAndroid Build Coastguard Worker 
6772*9880d681SAndroid Build Coastguard Worker /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
6773*9880d681SAndroid Build Coastguard Worker /// indicated value.  This method ignores uses of other values defined by this
6774*9880d681SAndroid Build Coastguard Worker /// operation.
hasNUsesOfValue(unsigned NUses,unsigned Value) const6775*9880d681SAndroid Build Coastguard Worker bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const {
6776*9880d681SAndroid Build Coastguard Worker   assert(Value < getNumValues() && "Bad value!");
6777*9880d681SAndroid Build Coastguard Worker 
6778*9880d681SAndroid Build Coastguard Worker   // TODO: Only iterate over uses of a given value of the node
6779*9880d681SAndroid Build Coastguard Worker   for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
6780*9880d681SAndroid Build Coastguard Worker     if (UI.getUse().getResNo() == Value) {
6781*9880d681SAndroid Build Coastguard Worker       if (NUses == 0)
6782*9880d681SAndroid Build Coastguard Worker         return false;
6783*9880d681SAndroid Build Coastguard Worker       --NUses;
6784*9880d681SAndroid Build Coastguard Worker     }
6785*9880d681SAndroid Build Coastguard Worker   }
6786*9880d681SAndroid Build Coastguard Worker 
6787*9880d681SAndroid Build Coastguard Worker   // Found exactly the right number of uses?
6788*9880d681SAndroid Build Coastguard Worker   return NUses == 0;
6789*9880d681SAndroid Build Coastguard Worker }
6790*9880d681SAndroid Build Coastguard Worker 
6791*9880d681SAndroid Build Coastguard Worker 
6792*9880d681SAndroid Build Coastguard Worker /// hasAnyUseOfValue - Return true if there are any use of the indicated
6793*9880d681SAndroid Build Coastguard Worker /// value. This method ignores uses of other values defined by this operation.
hasAnyUseOfValue(unsigned Value) const6794*9880d681SAndroid Build Coastguard Worker bool SDNode::hasAnyUseOfValue(unsigned Value) const {
6795*9880d681SAndroid Build Coastguard Worker   assert(Value < getNumValues() && "Bad value!");
6796*9880d681SAndroid Build Coastguard Worker 
6797*9880d681SAndroid Build Coastguard Worker   for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI)
6798*9880d681SAndroid Build Coastguard Worker     if (UI.getUse().getResNo() == Value)
6799*9880d681SAndroid Build Coastguard Worker       return true;
6800*9880d681SAndroid Build Coastguard Worker 
6801*9880d681SAndroid Build Coastguard Worker   return false;
6802*9880d681SAndroid Build Coastguard Worker }
6803*9880d681SAndroid Build Coastguard Worker 
6804*9880d681SAndroid Build Coastguard Worker 
6805*9880d681SAndroid Build Coastguard Worker /// isOnlyUserOf - Return true if this node is the only use of N.
6806*9880d681SAndroid Build Coastguard Worker ///
isOnlyUserOf(const SDNode * N) const6807*9880d681SAndroid Build Coastguard Worker bool SDNode::isOnlyUserOf(const SDNode *N) const {
6808*9880d681SAndroid Build Coastguard Worker   bool Seen = false;
6809*9880d681SAndroid Build Coastguard Worker   for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
6810*9880d681SAndroid Build Coastguard Worker     SDNode *User = *I;
6811*9880d681SAndroid Build Coastguard Worker     if (User == this)
6812*9880d681SAndroid Build Coastguard Worker       Seen = true;
6813*9880d681SAndroid Build Coastguard Worker     else
6814*9880d681SAndroid Build Coastguard Worker       return false;
6815*9880d681SAndroid Build Coastguard Worker   }
6816*9880d681SAndroid Build Coastguard Worker 
6817*9880d681SAndroid Build Coastguard Worker   return Seen;
6818*9880d681SAndroid Build Coastguard Worker }
6819*9880d681SAndroid Build Coastguard Worker 
6820*9880d681SAndroid Build Coastguard Worker /// isOperand - Return true if this node is an operand of N.
6821*9880d681SAndroid Build Coastguard Worker ///
isOperandOf(const SDNode * N) const6822*9880d681SAndroid Build Coastguard Worker bool SDValue::isOperandOf(const SDNode *N) const {
6823*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : N->op_values())
6824*9880d681SAndroid Build Coastguard Worker     if (*this == Op)
6825*9880d681SAndroid Build Coastguard Worker       return true;
6826*9880d681SAndroid Build Coastguard Worker   return false;
6827*9880d681SAndroid Build Coastguard Worker }
6828*9880d681SAndroid Build Coastguard Worker 
isOperandOf(const SDNode * N) const6829*9880d681SAndroid Build Coastguard Worker bool SDNode::isOperandOf(const SDNode *N) const {
6830*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : N->op_values())
6831*9880d681SAndroid Build Coastguard Worker     if (this == Op.getNode())
6832*9880d681SAndroid Build Coastguard Worker       return true;
6833*9880d681SAndroid Build Coastguard Worker   return false;
6834*9880d681SAndroid Build Coastguard Worker }
6835*9880d681SAndroid Build Coastguard Worker 
6836*9880d681SAndroid Build Coastguard Worker /// reachesChainWithoutSideEffects - Return true if this operand (which must
6837*9880d681SAndroid Build Coastguard Worker /// be a chain) reaches the specified operand without crossing any
6838*9880d681SAndroid Build Coastguard Worker /// side-effecting instructions on any chain path.  In practice, this looks
6839*9880d681SAndroid Build Coastguard Worker /// through token factors and non-volatile loads.  In order to remain efficient,
6840*9880d681SAndroid Build Coastguard Worker /// this only looks a couple of nodes in, it does not do an exhaustive search.
reachesChainWithoutSideEffects(SDValue Dest,unsigned Depth) const6841*9880d681SAndroid Build Coastguard Worker bool SDValue::reachesChainWithoutSideEffects(SDValue Dest,
6842*9880d681SAndroid Build Coastguard Worker                                                unsigned Depth) const {
6843*9880d681SAndroid Build Coastguard Worker   if (*this == Dest) return true;
6844*9880d681SAndroid Build Coastguard Worker 
6845*9880d681SAndroid Build Coastguard Worker   // Don't search too deeply, we just want to be able to see through
6846*9880d681SAndroid Build Coastguard Worker   // TokenFactor's etc.
6847*9880d681SAndroid Build Coastguard Worker   if (Depth == 0) return false;
6848*9880d681SAndroid Build Coastguard Worker 
6849*9880d681SAndroid Build Coastguard Worker   // If this is a token factor, all inputs to the TF happen in parallel.  If any
6850*9880d681SAndroid Build Coastguard Worker   // of the operands of the TF does not reach dest, then we cannot do the xform.
6851*9880d681SAndroid Build Coastguard Worker   if (getOpcode() == ISD::TokenFactor) {
6852*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
6853*9880d681SAndroid Build Coastguard Worker       if (!getOperand(i).reachesChainWithoutSideEffects(Dest, Depth-1))
6854*9880d681SAndroid Build Coastguard Worker         return false;
6855*9880d681SAndroid Build Coastguard Worker     return true;
6856*9880d681SAndroid Build Coastguard Worker   }
6857*9880d681SAndroid Build Coastguard Worker 
6858*9880d681SAndroid Build Coastguard Worker   // Loads don't have side effects, look through them.
6859*9880d681SAndroid Build Coastguard Worker   if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(*this)) {
6860*9880d681SAndroid Build Coastguard Worker     if (!Ld->isVolatile())
6861*9880d681SAndroid Build Coastguard Worker       return Ld->getChain().reachesChainWithoutSideEffects(Dest, Depth-1);
6862*9880d681SAndroid Build Coastguard Worker   }
6863*9880d681SAndroid Build Coastguard Worker   return false;
6864*9880d681SAndroid Build Coastguard Worker }
6865*9880d681SAndroid Build Coastguard Worker 
hasPredecessor(const SDNode * N) const6866*9880d681SAndroid Build Coastguard Worker bool SDNode::hasPredecessor(const SDNode *N) const {
6867*9880d681SAndroid Build Coastguard Worker   SmallPtrSet<const SDNode *, 32> Visited;
6868*9880d681SAndroid Build Coastguard Worker   SmallVector<const SDNode *, 16> Worklist;
6869*9880d681SAndroid Build Coastguard Worker   Worklist.push_back(this);
6870*9880d681SAndroid Build Coastguard Worker   return hasPredecessorHelper(N, Visited, Worklist);
6871*9880d681SAndroid Build Coastguard Worker }
6872*9880d681SAndroid Build Coastguard Worker 
getConstantOperandVal(unsigned Num) const6873*9880d681SAndroid Build Coastguard Worker uint64_t SDNode::getConstantOperandVal(unsigned Num) const {
6874*9880d681SAndroid Build Coastguard Worker   assert(Num < NumOperands && "Invalid child # of SDNode!");
6875*9880d681SAndroid Build Coastguard Worker   return cast<ConstantSDNode>(OperandList[Num])->getZExtValue();
6876*9880d681SAndroid Build Coastguard Worker }
6877*9880d681SAndroid Build Coastguard Worker 
getFlags() const6878*9880d681SAndroid Build Coastguard Worker const SDNodeFlags *SDNode::getFlags() const {
6879*9880d681SAndroid Build Coastguard Worker   if (auto *FlagsNode = dyn_cast<BinaryWithFlagsSDNode>(this))
6880*9880d681SAndroid Build Coastguard Worker     return &FlagsNode->Flags;
6881*9880d681SAndroid Build Coastguard Worker   return nullptr;
6882*9880d681SAndroid Build Coastguard Worker }
6883*9880d681SAndroid Build Coastguard Worker 
intersectFlagsWith(const SDNodeFlags * Flags)6884*9880d681SAndroid Build Coastguard Worker void SDNode::intersectFlagsWith(const SDNodeFlags *Flags) {
6885*9880d681SAndroid Build Coastguard Worker   if (auto *FlagsNode = dyn_cast<BinaryWithFlagsSDNode>(this))
6886*9880d681SAndroid Build Coastguard Worker     FlagsNode->Flags.intersectWith(Flags);
6887*9880d681SAndroid Build Coastguard Worker }
6888*9880d681SAndroid Build Coastguard Worker 
UnrollVectorOp(SDNode * N,unsigned ResNE)6889*9880d681SAndroid Build Coastguard Worker SDValue SelectionDAG::UnrollVectorOp(SDNode *N, unsigned ResNE) {
6890*9880d681SAndroid Build Coastguard Worker   assert(N->getNumValues() == 1 &&
6891*9880d681SAndroid Build Coastguard Worker          "Can't unroll a vector with multiple results!");
6892*9880d681SAndroid Build Coastguard Worker 
6893*9880d681SAndroid Build Coastguard Worker   EVT VT = N->getValueType(0);
6894*9880d681SAndroid Build Coastguard Worker   unsigned NE = VT.getVectorNumElements();
6895*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getVectorElementType();
6896*9880d681SAndroid Build Coastguard Worker   SDLoc dl(N);
6897*9880d681SAndroid Build Coastguard Worker 
6898*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> Scalars;
6899*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 4> Operands(N->getNumOperands());
6900*9880d681SAndroid Build Coastguard Worker 
6901*9880d681SAndroid Build Coastguard Worker   // If ResNE is 0, fully unroll the vector op.
6902*9880d681SAndroid Build Coastguard Worker   if (ResNE == 0)
6903*9880d681SAndroid Build Coastguard Worker     ResNE = NE;
6904*9880d681SAndroid Build Coastguard Worker   else if (NE > ResNE)
6905*9880d681SAndroid Build Coastguard Worker     NE = ResNE;
6906*9880d681SAndroid Build Coastguard Worker 
6907*9880d681SAndroid Build Coastguard Worker   unsigned i;
6908*9880d681SAndroid Build Coastguard Worker   for (i= 0; i != NE; ++i) {
6909*9880d681SAndroid Build Coastguard Worker     for (unsigned j = 0, e = N->getNumOperands(); j != e; ++j) {
6910*9880d681SAndroid Build Coastguard Worker       SDValue Operand = N->getOperand(j);
6911*9880d681SAndroid Build Coastguard Worker       EVT OperandVT = Operand.getValueType();
6912*9880d681SAndroid Build Coastguard Worker       if (OperandVT.isVector()) {
6913*9880d681SAndroid Build Coastguard Worker         // A vector operand; extract a single element.
6914*9880d681SAndroid Build Coastguard Worker         EVT OperandEltVT = OperandVT.getVectorElementType();
6915*9880d681SAndroid Build Coastguard Worker         Operands[j] =
6916*9880d681SAndroid Build Coastguard Worker             getNode(ISD::EXTRACT_VECTOR_ELT, dl, OperandEltVT, Operand,
6917*9880d681SAndroid Build Coastguard Worker                     getConstant(i, dl, TLI->getVectorIdxTy(getDataLayout())));
6918*9880d681SAndroid Build Coastguard Worker       } else {
6919*9880d681SAndroid Build Coastguard Worker         // A scalar operand; just use it as is.
6920*9880d681SAndroid Build Coastguard Worker         Operands[j] = Operand;
6921*9880d681SAndroid Build Coastguard Worker       }
6922*9880d681SAndroid Build Coastguard Worker     }
6923*9880d681SAndroid Build Coastguard Worker 
6924*9880d681SAndroid Build Coastguard Worker     switch (N->getOpcode()) {
6925*9880d681SAndroid Build Coastguard Worker     default: {
6926*9880d681SAndroid Build Coastguard Worker       Scalars.push_back(getNode(N->getOpcode(), dl, EltVT, Operands,
6927*9880d681SAndroid Build Coastguard Worker                                 N->getFlags()));
6928*9880d681SAndroid Build Coastguard Worker       break;
6929*9880d681SAndroid Build Coastguard Worker     }
6930*9880d681SAndroid Build Coastguard Worker     case ISD::VSELECT:
6931*9880d681SAndroid Build Coastguard Worker       Scalars.push_back(getNode(ISD::SELECT, dl, EltVT, Operands));
6932*9880d681SAndroid Build Coastguard Worker       break;
6933*9880d681SAndroid Build Coastguard Worker     case ISD::SHL:
6934*9880d681SAndroid Build Coastguard Worker     case ISD::SRA:
6935*9880d681SAndroid Build Coastguard Worker     case ISD::SRL:
6936*9880d681SAndroid Build Coastguard Worker     case ISD::ROTL:
6937*9880d681SAndroid Build Coastguard Worker     case ISD::ROTR:
6938*9880d681SAndroid Build Coastguard Worker       Scalars.push_back(getNode(N->getOpcode(), dl, EltVT, Operands[0],
6939*9880d681SAndroid Build Coastguard Worker                                getShiftAmountOperand(Operands[0].getValueType(),
6940*9880d681SAndroid Build Coastguard Worker                                                      Operands[1])));
6941*9880d681SAndroid Build Coastguard Worker       break;
6942*9880d681SAndroid Build Coastguard Worker     case ISD::SIGN_EXTEND_INREG:
6943*9880d681SAndroid Build Coastguard Worker     case ISD::FP_ROUND_INREG: {
6944*9880d681SAndroid Build Coastguard Worker       EVT ExtVT = cast<VTSDNode>(Operands[1])->getVT().getVectorElementType();
6945*9880d681SAndroid Build Coastguard Worker       Scalars.push_back(getNode(N->getOpcode(), dl, EltVT,
6946*9880d681SAndroid Build Coastguard Worker                                 Operands[0],
6947*9880d681SAndroid Build Coastguard Worker                                 getValueType(ExtVT)));
6948*9880d681SAndroid Build Coastguard Worker     }
6949*9880d681SAndroid Build Coastguard Worker     }
6950*9880d681SAndroid Build Coastguard Worker   }
6951*9880d681SAndroid Build Coastguard Worker 
6952*9880d681SAndroid Build Coastguard Worker   for (; i < ResNE; ++i)
6953*9880d681SAndroid Build Coastguard Worker     Scalars.push_back(getUNDEF(EltVT));
6954*9880d681SAndroid Build Coastguard Worker 
6955*9880d681SAndroid Build Coastguard Worker   return getNode(ISD::BUILD_VECTOR, dl,
6956*9880d681SAndroid Build Coastguard Worker                  EVT::getVectorVT(*getContext(), EltVT, ResNE), Scalars);
6957*9880d681SAndroid Build Coastguard Worker }
6958*9880d681SAndroid Build Coastguard Worker 
areNonVolatileConsecutiveLoads(LoadSDNode * LD,LoadSDNode * Base,unsigned Bytes,int Dist) const6959*9880d681SAndroid Build Coastguard Worker bool SelectionDAG::areNonVolatileConsecutiveLoads(LoadSDNode *LD,
6960*9880d681SAndroid Build Coastguard Worker                                                   LoadSDNode *Base,
6961*9880d681SAndroid Build Coastguard Worker                                                   unsigned Bytes,
6962*9880d681SAndroid Build Coastguard Worker                                                   int Dist) const {
6963*9880d681SAndroid Build Coastguard Worker   if (LD->isVolatile() || Base->isVolatile())
6964*9880d681SAndroid Build Coastguard Worker     return false;
6965*9880d681SAndroid Build Coastguard Worker   if (LD->isIndexed() || Base->isIndexed())
6966*9880d681SAndroid Build Coastguard Worker     return false;
6967*9880d681SAndroid Build Coastguard Worker   if (LD->getChain() != Base->getChain())
6968*9880d681SAndroid Build Coastguard Worker     return false;
6969*9880d681SAndroid Build Coastguard Worker   EVT VT = LD->getValueType(0);
6970*9880d681SAndroid Build Coastguard Worker   if (VT.getSizeInBits() / 8 != Bytes)
6971*9880d681SAndroid Build Coastguard Worker     return false;
6972*9880d681SAndroid Build Coastguard Worker 
6973*9880d681SAndroid Build Coastguard Worker   SDValue Loc = LD->getOperand(1);
6974*9880d681SAndroid Build Coastguard Worker   SDValue BaseLoc = Base->getOperand(1);
6975*9880d681SAndroid Build Coastguard Worker   if (Loc.getOpcode() == ISD::FrameIndex) {
6976*9880d681SAndroid Build Coastguard Worker     if (BaseLoc.getOpcode() != ISD::FrameIndex)
6977*9880d681SAndroid Build Coastguard Worker       return false;
6978*9880d681SAndroid Build Coastguard Worker     const MachineFrameInfo *MFI = getMachineFunction().getFrameInfo();
6979*9880d681SAndroid Build Coastguard Worker     int FI  = cast<FrameIndexSDNode>(Loc)->getIndex();
6980*9880d681SAndroid Build Coastguard Worker     int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
6981*9880d681SAndroid Build Coastguard Worker     int FS  = MFI->getObjectSize(FI);
6982*9880d681SAndroid Build Coastguard Worker     int BFS = MFI->getObjectSize(BFI);
6983*9880d681SAndroid Build Coastguard Worker     if (FS != BFS || FS != (int)Bytes) return false;
6984*9880d681SAndroid Build Coastguard Worker     return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Bytes);
6985*9880d681SAndroid Build Coastguard Worker   }
6986*9880d681SAndroid Build Coastguard Worker 
6987*9880d681SAndroid Build Coastguard Worker   // Handle X + C.
6988*9880d681SAndroid Build Coastguard Worker   if (isBaseWithConstantOffset(Loc)) {
6989*9880d681SAndroid Build Coastguard Worker     int64_t LocOffset = cast<ConstantSDNode>(Loc.getOperand(1))->getSExtValue();
6990*9880d681SAndroid Build Coastguard Worker     if (Loc.getOperand(0) == BaseLoc) {
6991*9880d681SAndroid Build Coastguard Worker       // If the base location is a simple address with no offset itself, then
6992*9880d681SAndroid Build Coastguard Worker       // the second load's first add operand should be the base address.
6993*9880d681SAndroid Build Coastguard Worker       if (LocOffset == Dist * (int)Bytes)
6994*9880d681SAndroid Build Coastguard Worker         return true;
6995*9880d681SAndroid Build Coastguard Worker     } else if (isBaseWithConstantOffset(BaseLoc)) {
6996*9880d681SAndroid Build Coastguard Worker       // The base location itself has an offset, so subtract that value from the
6997*9880d681SAndroid Build Coastguard Worker       // second load's offset before comparing to distance * size.
6998*9880d681SAndroid Build Coastguard Worker       int64_t BOffset =
6999*9880d681SAndroid Build Coastguard Worker         cast<ConstantSDNode>(BaseLoc.getOperand(1))->getSExtValue();
7000*9880d681SAndroid Build Coastguard Worker       if (Loc.getOperand(0) == BaseLoc.getOperand(0)) {
7001*9880d681SAndroid Build Coastguard Worker         if ((LocOffset - BOffset) == Dist * (int)Bytes)
7002*9880d681SAndroid Build Coastguard Worker           return true;
7003*9880d681SAndroid Build Coastguard Worker       }
7004*9880d681SAndroid Build Coastguard Worker     }
7005*9880d681SAndroid Build Coastguard Worker   }
7006*9880d681SAndroid Build Coastguard Worker   const GlobalValue *GV1 = nullptr;
7007*9880d681SAndroid Build Coastguard Worker   const GlobalValue *GV2 = nullptr;
7008*9880d681SAndroid Build Coastguard Worker   int64_t Offset1 = 0;
7009*9880d681SAndroid Build Coastguard Worker   int64_t Offset2 = 0;
7010*9880d681SAndroid Build Coastguard Worker   bool isGA1 = TLI->isGAPlusOffset(Loc.getNode(), GV1, Offset1);
7011*9880d681SAndroid Build Coastguard Worker   bool isGA2 = TLI->isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2);
7012*9880d681SAndroid Build Coastguard Worker   if (isGA1 && isGA2 && GV1 == GV2)
7013*9880d681SAndroid Build Coastguard Worker     return Offset1 == (Offset2 + Dist*Bytes);
7014*9880d681SAndroid Build Coastguard Worker   return false;
7015*9880d681SAndroid Build Coastguard Worker }
7016*9880d681SAndroid Build Coastguard Worker 
7017*9880d681SAndroid Build Coastguard Worker 
7018*9880d681SAndroid Build Coastguard Worker /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if
7019*9880d681SAndroid Build Coastguard Worker /// it cannot be inferred.
InferPtrAlignment(SDValue Ptr) const7020*9880d681SAndroid Build Coastguard Worker unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const {
7021*9880d681SAndroid Build Coastguard Worker   // If this is a GlobalAddress + cst, return the alignment.
7022*9880d681SAndroid Build Coastguard Worker   const GlobalValue *GV;
7023*9880d681SAndroid Build Coastguard Worker   int64_t GVOffset = 0;
7024*9880d681SAndroid Build Coastguard Worker   if (TLI->isGAPlusOffset(Ptr.getNode(), GV, GVOffset)) {
7025*9880d681SAndroid Build Coastguard Worker     unsigned PtrWidth = getDataLayout().getPointerTypeSizeInBits(GV->getType());
7026*9880d681SAndroid Build Coastguard Worker     APInt KnownZero(PtrWidth, 0), KnownOne(PtrWidth, 0);
7027*9880d681SAndroid Build Coastguard Worker     llvm::computeKnownBits(const_cast<GlobalValue *>(GV), KnownZero, KnownOne,
7028*9880d681SAndroid Build Coastguard Worker                            getDataLayout());
7029*9880d681SAndroid Build Coastguard Worker     unsigned AlignBits = KnownZero.countTrailingOnes();
7030*9880d681SAndroid Build Coastguard Worker     unsigned Align = AlignBits ? 1 << std::min(31U, AlignBits) : 0;
7031*9880d681SAndroid Build Coastguard Worker     if (Align)
7032*9880d681SAndroid Build Coastguard Worker       return MinAlign(Align, GVOffset);
7033*9880d681SAndroid Build Coastguard Worker   }
7034*9880d681SAndroid Build Coastguard Worker 
7035*9880d681SAndroid Build Coastguard Worker   // If this is a direct reference to a stack slot, use information about the
7036*9880d681SAndroid Build Coastguard Worker   // stack slot's alignment.
7037*9880d681SAndroid Build Coastguard Worker   int FrameIdx = 1 << 31;
7038*9880d681SAndroid Build Coastguard Worker   int64_t FrameOffset = 0;
7039*9880d681SAndroid Build Coastguard Worker   if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Ptr)) {
7040*9880d681SAndroid Build Coastguard Worker     FrameIdx = FI->getIndex();
7041*9880d681SAndroid Build Coastguard Worker   } else if (isBaseWithConstantOffset(Ptr) &&
7042*9880d681SAndroid Build Coastguard Worker              isa<FrameIndexSDNode>(Ptr.getOperand(0))) {
7043*9880d681SAndroid Build Coastguard Worker     // Handle FI+Cst
7044*9880d681SAndroid Build Coastguard Worker     FrameIdx = cast<FrameIndexSDNode>(Ptr.getOperand(0))->getIndex();
7045*9880d681SAndroid Build Coastguard Worker     FrameOffset = Ptr.getConstantOperandVal(1);
7046*9880d681SAndroid Build Coastguard Worker   }
7047*9880d681SAndroid Build Coastguard Worker 
7048*9880d681SAndroid Build Coastguard Worker   if (FrameIdx != (1 << 31)) {
7049*9880d681SAndroid Build Coastguard Worker     const MachineFrameInfo &MFI = *getMachineFunction().getFrameInfo();
7050*9880d681SAndroid Build Coastguard Worker     unsigned FIInfoAlign = MinAlign(MFI.getObjectAlignment(FrameIdx),
7051*9880d681SAndroid Build Coastguard Worker                                     FrameOffset);
7052*9880d681SAndroid Build Coastguard Worker     return FIInfoAlign;
7053*9880d681SAndroid Build Coastguard Worker   }
7054*9880d681SAndroid Build Coastguard Worker 
7055*9880d681SAndroid Build Coastguard Worker   return 0;
7056*9880d681SAndroid Build Coastguard Worker }
7057*9880d681SAndroid Build Coastguard Worker 
7058*9880d681SAndroid Build Coastguard Worker /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
7059*9880d681SAndroid Build Coastguard Worker /// which is split (or expanded) into two not necessarily identical pieces.
GetSplitDestVTs(const EVT & VT) const7060*9880d681SAndroid Build Coastguard Worker std::pair<EVT, EVT> SelectionDAG::GetSplitDestVTs(const EVT &VT) const {
7061*9880d681SAndroid Build Coastguard Worker   // Currently all types are split in half.
7062*9880d681SAndroid Build Coastguard Worker   EVT LoVT, HiVT;
7063*9880d681SAndroid Build Coastguard Worker   if (!VT.isVector()) {
7064*9880d681SAndroid Build Coastguard Worker     LoVT = HiVT = TLI->getTypeToTransformTo(*getContext(), VT);
7065*9880d681SAndroid Build Coastguard Worker   } else {
7066*9880d681SAndroid Build Coastguard Worker     unsigned NumElements = VT.getVectorNumElements();
7067*9880d681SAndroid Build Coastguard Worker     assert(!(NumElements & 1) && "Splitting vector, but not in half!");
7068*9880d681SAndroid Build Coastguard Worker     LoVT = HiVT = EVT::getVectorVT(*getContext(), VT.getVectorElementType(),
7069*9880d681SAndroid Build Coastguard Worker                                    NumElements/2);
7070*9880d681SAndroid Build Coastguard Worker   }
7071*9880d681SAndroid Build Coastguard Worker   return std::make_pair(LoVT, HiVT);
7072*9880d681SAndroid Build Coastguard Worker }
7073*9880d681SAndroid Build Coastguard Worker 
7074*9880d681SAndroid Build Coastguard Worker /// SplitVector - Split the vector with EXTRACT_SUBVECTOR and return the
7075*9880d681SAndroid Build Coastguard Worker /// low/high part.
7076*9880d681SAndroid Build Coastguard Worker std::pair<SDValue, SDValue>
SplitVector(const SDValue & N,const SDLoc & DL,const EVT & LoVT,const EVT & HiVT)7077*9880d681SAndroid Build Coastguard Worker SelectionDAG::SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT,
7078*9880d681SAndroid Build Coastguard Worker                           const EVT &HiVT) {
7079*9880d681SAndroid Build Coastguard Worker   assert(LoVT.getVectorNumElements() + HiVT.getVectorNumElements() <=
7080*9880d681SAndroid Build Coastguard Worker          N.getValueType().getVectorNumElements() &&
7081*9880d681SAndroid Build Coastguard Worker          "More vector elements requested than available!");
7082*9880d681SAndroid Build Coastguard Worker   SDValue Lo, Hi;
7083*9880d681SAndroid Build Coastguard Worker   Lo = getNode(ISD::EXTRACT_SUBVECTOR, DL, LoVT, N,
7084*9880d681SAndroid Build Coastguard Worker                getConstant(0, DL, TLI->getVectorIdxTy(getDataLayout())));
7085*9880d681SAndroid Build Coastguard Worker   Hi = getNode(ISD::EXTRACT_SUBVECTOR, DL, HiVT, N,
7086*9880d681SAndroid Build Coastguard Worker                getConstant(LoVT.getVectorNumElements(), DL,
7087*9880d681SAndroid Build Coastguard Worker                            TLI->getVectorIdxTy(getDataLayout())));
7088*9880d681SAndroid Build Coastguard Worker   return std::make_pair(Lo, Hi);
7089*9880d681SAndroid Build Coastguard Worker }
7090*9880d681SAndroid Build Coastguard Worker 
ExtractVectorElements(SDValue Op,SmallVectorImpl<SDValue> & Args,unsigned Start,unsigned Count)7091*9880d681SAndroid Build Coastguard Worker void SelectionDAG::ExtractVectorElements(SDValue Op,
7092*9880d681SAndroid Build Coastguard Worker                                          SmallVectorImpl<SDValue> &Args,
7093*9880d681SAndroid Build Coastguard Worker                                          unsigned Start, unsigned Count) {
7094*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
7095*9880d681SAndroid Build Coastguard Worker   if (Count == 0)
7096*9880d681SAndroid Build Coastguard Worker     Count = VT.getVectorNumElements();
7097*9880d681SAndroid Build Coastguard Worker 
7098*9880d681SAndroid Build Coastguard Worker   EVT EltVT = VT.getVectorElementType();
7099*9880d681SAndroid Build Coastguard Worker   EVT IdxTy = TLI->getVectorIdxTy(getDataLayout());
7100*9880d681SAndroid Build Coastguard Worker   SDLoc SL(Op);
7101*9880d681SAndroid Build Coastguard Worker   for (unsigned i = Start, e = Start + Count; i != e; ++i) {
7102*9880d681SAndroid Build Coastguard Worker     Args.push_back(getNode(ISD::EXTRACT_VECTOR_ELT, SL, EltVT,
7103*9880d681SAndroid Build Coastguard Worker                            Op, getConstant(i, SL, IdxTy)));
7104*9880d681SAndroid Build Coastguard Worker   }
7105*9880d681SAndroid Build Coastguard Worker }
7106*9880d681SAndroid Build Coastguard Worker 
7107*9880d681SAndroid Build Coastguard Worker // getAddressSpace - Return the address space this GlobalAddress belongs to.
getAddressSpace() const7108*9880d681SAndroid Build Coastguard Worker unsigned GlobalAddressSDNode::getAddressSpace() const {
7109*9880d681SAndroid Build Coastguard Worker   return getGlobal()->getType()->getAddressSpace();
7110*9880d681SAndroid Build Coastguard Worker }
7111*9880d681SAndroid Build Coastguard Worker 
7112*9880d681SAndroid Build Coastguard Worker 
getType() const7113*9880d681SAndroid Build Coastguard Worker Type *ConstantPoolSDNode::getType() const {
7114*9880d681SAndroid Build Coastguard Worker   if (isMachineConstantPoolEntry())
7115*9880d681SAndroid Build Coastguard Worker     return Val.MachineCPVal->getType();
7116*9880d681SAndroid Build Coastguard Worker   return Val.ConstVal->getType();
7117*9880d681SAndroid Build Coastguard Worker }
7118*9880d681SAndroid Build Coastguard Worker 
isConstantSplat(APInt & SplatValue,APInt & SplatUndef,unsigned & SplatBitSize,bool & HasAnyUndefs,unsigned MinSplatBits,bool isBigEndian) const7119*9880d681SAndroid Build Coastguard Worker bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
7120*9880d681SAndroid Build Coastguard Worker                                         APInt &SplatUndef,
7121*9880d681SAndroid Build Coastguard Worker                                         unsigned &SplatBitSize,
7122*9880d681SAndroid Build Coastguard Worker                                         bool &HasAnyUndefs,
7123*9880d681SAndroid Build Coastguard Worker                                         unsigned MinSplatBits,
7124*9880d681SAndroid Build Coastguard Worker                                         bool isBigEndian) const {
7125*9880d681SAndroid Build Coastguard Worker   EVT VT = getValueType(0);
7126*9880d681SAndroid Build Coastguard Worker   assert(VT.isVector() && "Expected a vector type");
7127*9880d681SAndroid Build Coastguard Worker   unsigned sz = VT.getSizeInBits();
7128*9880d681SAndroid Build Coastguard Worker   if (MinSplatBits > sz)
7129*9880d681SAndroid Build Coastguard Worker     return false;
7130*9880d681SAndroid Build Coastguard Worker 
7131*9880d681SAndroid Build Coastguard Worker   SplatValue = APInt(sz, 0);
7132*9880d681SAndroid Build Coastguard Worker   SplatUndef = APInt(sz, 0);
7133*9880d681SAndroid Build Coastguard Worker 
7134*9880d681SAndroid Build Coastguard Worker   // Get the bits.  Bits with undefined values (when the corresponding element
7135*9880d681SAndroid Build Coastguard Worker   // of the vector is an ISD::UNDEF value) are set in SplatUndef and cleared
7136*9880d681SAndroid Build Coastguard Worker   // in SplatValue.  If any of the values are not constant, give up and return
7137*9880d681SAndroid Build Coastguard Worker   // false.
7138*9880d681SAndroid Build Coastguard Worker   unsigned int nOps = getNumOperands();
7139*9880d681SAndroid Build Coastguard Worker   assert(nOps > 0 && "isConstantSplat has 0-size build vector");
7140*9880d681SAndroid Build Coastguard Worker   unsigned EltBitSize = VT.getVectorElementType().getSizeInBits();
7141*9880d681SAndroid Build Coastguard Worker 
7142*9880d681SAndroid Build Coastguard Worker   for (unsigned j = 0; j < nOps; ++j) {
7143*9880d681SAndroid Build Coastguard Worker     unsigned i = isBigEndian ? nOps-1-j : j;
7144*9880d681SAndroid Build Coastguard Worker     SDValue OpVal = getOperand(i);
7145*9880d681SAndroid Build Coastguard Worker     unsigned BitPos = j * EltBitSize;
7146*9880d681SAndroid Build Coastguard Worker 
7147*9880d681SAndroid Build Coastguard Worker     if (OpVal.isUndef())
7148*9880d681SAndroid Build Coastguard Worker       SplatUndef |= APInt::getBitsSet(sz, BitPos, BitPos + EltBitSize);
7149*9880d681SAndroid Build Coastguard Worker     else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal))
7150*9880d681SAndroid Build Coastguard Worker       SplatValue |= CN->getAPIntValue().zextOrTrunc(EltBitSize).
7151*9880d681SAndroid Build Coastguard Worker                     zextOrTrunc(sz) << BitPos;
7152*9880d681SAndroid Build Coastguard Worker     else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal))
7153*9880d681SAndroid Build Coastguard Worker       SplatValue |= CN->getValueAPF().bitcastToAPInt().zextOrTrunc(sz) <<BitPos;
7154*9880d681SAndroid Build Coastguard Worker      else
7155*9880d681SAndroid Build Coastguard Worker       return false;
7156*9880d681SAndroid Build Coastguard Worker   }
7157*9880d681SAndroid Build Coastguard Worker 
7158*9880d681SAndroid Build Coastguard Worker   // The build_vector is all constants or undefs.  Find the smallest element
7159*9880d681SAndroid Build Coastguard Worker   // size that splats the vector.
7160*9880d681SAndroid Build Coastguard Worker 
7161*9880d681SAndroid Build Coastguard Worker   HasAnyUndefs = (SplatUndef != 0);
7162*9880d681SAndroid Build Coastguard Worker   while (sz > 8) {
7163*9880d681SAndroid Build Coastguard Worker 
7164*9880d681SAndroid Build Coastguard Worker     unsigned HalfSize = sz / 2;
7165*9880d681SAndroid Build Coastguard Worker     APInt HighValue = SplatValue.lshr(HalfSize).trunc(HalfSize);
7166*9880d681SAndroid Build Coastguard Worker     APInt LowValue = SplatValue.trunc(HalfSize);
7167*9880d681SAndroid Build Coastguard Worker     APInt HighUndef = SplatUndef.lshr(HalfSize).trunc(HalfSize);
7168*9880d681SAndroid Build Coastguard Worker     APInt LowUndef = SplatUndef.trunc(HalfSize);
7169*9880d681SAndroid Build Coastguard Worker 
7170*9880d681SAndroid Build Coastguard Worker     // If the two halves do not match (ignoring undef bits), stop here.
7171*9880d681SAndroid Build Coastguard Worker     if ((HighValue & ~LowUndef) != (LowValue & ~HighUndef) ||
7172*9880d681SAndroid Build Coastguard Worker         MinSplatBits > HalfSize)
7173*9880d681SAndroid Build Coastguard Worker       break;
7174*9880d681SAndroid Build Coastguard Worker 
7175*9880d681SAndroid Build Coastguard Worker     SplatValue = HighValue | LowValue;
7176*9880d681SAndroid Build Coastguard Worker     SplatUndef = HighUndef & LowUndef;
7177*9880d681SAndroid Build Coastguard Worker 
7178*9880d681SAndroid Build Coastguard Worker     sz = HalfSize;
7179*9880d681SAndroid Build Coastguard Worker   }
7180*9880d681SAndroid Build Coastguard Worker 
7181*9880d681SAndroid Build Coastguard Worker   SplatBitSize = sz;
7182*9880d681SAndroid Build Coastguard Worker   return true;
7183*9880d681SAndroid Build Coastguard Worker }
7184*9880d681SAndroid Build Coastguard Worker 
getSplatValue(BitVector * UndefElements) const7185*9880d681SAndroid Build Coastguard Worker SDValue BuildVectorSDNode::getSplatValue(BitVector *UndefElements) const {
7186*9880d681SAndroid Build Coastguard Worker   if (UndefElements) {
7187*9880d681SAndroid Build Coastguard Worker     UndefElements->clear();
7188*9880d681SAndroid Build Coastguard Worker     UndefElements->resize(getNumOperands());
7189*9880d681SAndroid Build Coastguard Worker   }
7190*9880d681SAndroid Build Coastguard Worker   SDValue Splatted;
7191*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
7192*9880d681SAndroid Build Coastguard Worker     SDValue Op = getOperand(i);
7193*9880d681SAndroid Build Coastguard Worker     if (Op.isUndef()) {
7194*9880d681SAndroid Build Coastguard Worker       if (UndefElements)
7195*9880d681SAndroid Build Coastguard Worker         (*UndefElements)[i] = true;
7196*9880d681SAndroid Build Coastguard Worker     } else if (!Splatted) {
7197*9880d681SAndroid Build Coastguard Worker       Splatted = Op;
7198*9880d681SAndroid Build Coastguard Worker     } else if (Splatted != Op) {
7199*9880d681SAndroid Build Coastguard Worker       return SDValue();
7200*9880d681SAndroid Build Coastguard Worker     }
7201*9880d681SAndroid Build Coastguard Worker   }
7202*9880d681SAndroid Build Coastguard Worker 
7203*9880d681SAndroid Build Coastguard Worker   if (!Splatted) {
7204*9880d681SAndroid Build Coastguard Worker     assert(getOperand(0).isUndef() &&
7205*9880d681SAndroid Build Coastguard Worker            "Can only have a splat without a constant for all undefs.");
7206*9880d681SAndroid Build Coastguard Worker     return getOperand(0);
7207*9880d681SAndroid Build Coastguard Worker   }
7208*9880d681SAndroid Build Coastguard Worker 
7209*9880d681SAndroid Build Coastguard Worker   return Splatted;
7210*9880d681SAndroid Build Coastguard Worker }
7211*9880d681SAndroid Build Coastguard Worker 
7212*9880d681SAndroid Build Coastguard Worker ConstantSDNode *
getConstantSplatNode(BitVector * UndefElements) const7213*9880d681SAndroid Build Coastguard Worker BuildVectorSDNode::getConstantSplatNode(BitVector *UndefElements) const {
7214*9880d681SAndroid Build Coastguard Worker   return dyn_cast_or_null<ConstantSDNode>(getSplatValue(UndefElements));
7215*9880d681SAndroid Build Coastguard Worker }
7216*9880d681SAndroid Build Coastguard Worker 
7217*9880d681SAndroid Build Coastguard Worker ConstantFPSDNode *
getConstantFPSplatNode(BitVector * UndefElements) const7218*9880d681SAndroid Build Coastguard Worker BuildVectorSDNode::getConstantFPSplatNode(BitVector *UndefElements) const {
7219*9880d681SAndroid Build Coastguard Worker   return dyn_cast_or_null<ConstantFPSDNode>(getSplatValue(UndefElements));
7220*9880d681SAndroid Build Coastguard Worker }
7221*9880d681SAndroid Build Coastguard Worker 
7222*9880d681SAndroid Build Coastguard Worker int32_t
getConstantFPSplatPow2ToLog2Int(BitVector * UndefElements,uint32_t BitWidth) const7223*9880d681SAndroid Build Coastguard Worker BuildVectorSDNode::getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements,
7224*9880d681SAndroid Build Coastguard Worker                                                    uint32_t BitWidth) const {
7225*9880d681SAndroid Build Coastguard Worker   if (ConstantFPSDNode *CN =
7226*9880d681SAndroid Build Coastguard Worker           dyn_cast_or_null<ConstantFPSDNode>(getSplatValue(UndefElements))) {
7227*9880d681SAndroid Build Coastguard Worker     bool IsExact;
7228*9880d681SAndroid Build Coastguard Worker     APSInt IntVal(BitWidth);
7229*9880d681SAndroid Build Coastguard Worker     const APFloat &APF = CN->getValueAPF();
7230*9880d681SAndroid Build Coastguard Worker     if (APF.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact) !=
7231*9880d681SAndroid Build Coastguard Worker             APFloat::opOK ||
7232*9880d681SAndroid Build Coastguard Worker         !IsExact)
7233*9880d681SAndroid Build Coastguard Worker       return -1;
7234*9880d681SAndroid Build Coastguard Worker 
7235*9880d681SAndroid Build Coastguard Worker     return IntVal.exactLogBase2();
7236*9880d681SAndroid Build Coastguard Worker   }
7237*9880d681SAndroid Build Coastguard Worker   return -1;
7238*9880d681SAndroid Build Coastguard Worker }
7239*9880d681SAndroid Build Coastguard Worker 
isConstant() const7240*9880d681SAndroid Build Coastguard Worker bool BuildVectorSDNode::isConstant() const {
7241*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : op_values()) {
7242*9880d681SAndroid Build Coastguard Worker     unsigned Opc = Op.getOpcode();
7243*9880d681SAndroid Build Coastguard Worker     if (Opc != ISD::UNDEF && Opc != ISD::Constant && Opc != ISD::ConstantFP)
7244*9880d681SAndroid Build Coastguard Worker       return false;
7245*9880d681SAndroid Build Coastguard Worker   }
7246*9880d681SAndroid Build Coastguard Worker   return true;
7247*9880d681SAndroid Build Coastguard Worker }
7248*9880d681SAndroid Build Coastguard Worker 
isSplatMask(const int * Mask,EVT VT)7249*9880d681SAndroid Build Coastguard Worker bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {
7250*9880d681SAndroid Build Coastguard Worker   // Find the first non-undef value in the shuffle mask.
7251*9880d681SAndroid Build Coastguard Worker   unsigned i, e;
7252*9880d681SAndroid Build Coastguard Worker   for (i = 0, e = VT.getVectorNumElements(); i != e && Mask[i] < 0; ++i)
7253*9880d681SAndroid Build Coastguard Worker     /* search */;
7254*9880d681SAndroid Build Coastguard Worker 
7255*9880d681SAndroid Build Coastguard Worker   assert(i != e && "VECTOR_SHUFFLE node with all undef indices!");
7256*9880d681SAndroid Build Coastguard Worker 
7257*9880d681SAndroid Build Coastguard Worker   // Make sure all remaining elements are either undef or the same as the first
7258*9880d681SAndroid Build Coastguard Worker   // non-undef value.
7259*9880d681SAndroid Build Coastguard Worker   for (int Idx = Mask[i]; i != e; ++i)
7260*9880d681SAndroid Build Coastguard Worker     if (Mask[i] >= 0 && Mask[i] != Idx)
7261*9880d681SAndroid Build Coastguard Worker       return false;
7262*9880d681SAndroid Build Coastguard Worker   return true;
7263*9880d681SAndroid Build Coastguard Worker }
7264*9880d681SAndroid Build Coastguard Worker 
7265*9880d681SAndroid Build Coastguard Worker // \brief Returns the SDNode if it is a constant integer BuildVector
7266*9880d681SAndroid Build Coastguard Worker // or constant integer.
isConstantIntBuildVectorOrConstantInt(SDValue N)7267*9880d681SAndroid Build Coastguard Worker SDNode *SelectionDAG::isConstantIntBuildVectorOrConstantInt(SDValue N) {
7268*9880d681SAndroid Build Coastguard Worker   if (isa<ConstantSDNode>(N))
7269*9880d681SAndroid Build Coastguard Worker     return N.getNode();
7270*9880d681SAndroid Build Coastguard Worker   if (ISD::isBuildVectorOfConstantSDNodes(N.getNode()))
7271*9880d681SAndroid Build Coastguard Worker     return N.getNode();
7272*9880d681SAndroid Build Coastguard Worker   // Treat a GlobalAddress supporting constant offset folding as a
7273*9880d681SAndroid Build Coastguard Worker   // constant integer.
7274*9880d681SAndroid Build Coastguard Worker   if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N))
7275*9880d681SAndroid Build Coastguard Worker     if (GA->getOpcode() == ISD::GlobalAddress &&
7276*9880d681SAndroid Build Coastguard Worker         TLI->isOffsetFoldingLegal(GA))
7277*9880d681SAndroid Build Coastguard Worker       return GA;
7278*9880d681SAndroid Build Coastguard Worker   return nullptr;
7279*9880d681SAndroid Build Coastguard Worker }
7280*9880d681SAndroid Build Coastguard Worker 
7281*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
checkForCyclesHelper(const SDNode * N,SmallPtrSetImpl<const SDNode * > & Visited,SmallPtrSetImpl<const SDNode * > & Checked,const llvm::SelectionDAG * DAG)7282*9880d681SAndroid Build Coastguard Worker static void checkForCyclesHelper(const SDNode *N,
7283*9880d681SAndroid Build Coastguard Worker                                  SmallPtrSetImpl<const SDNode*> &Visited,
7284*9880d681SAndroid Build Coastguard Worker                                  SmallPtrSetImpl<const SDNode*> &Checked,
7285*9880d681SAndroid Build Coastguard Worker                                  const llvm::SelectionDAG *DAG) {
7286*9880d681SAndroid Build Coastguard Worker   // If this node has already been checked, don't check it again.
7287*9880d681SAndroid Build Coastguard Worker   if (Checked.count(N))
7288*9880d681SAndroid Build Coastguard Worker     return;
7289*9880d681SAndroid Build Coastguard Worker 
7290*9880d681SAndroid Build Coastguard Worker   // If a node has already been visited on this depth-first walk, reject it as
7291*9880d681SAndroid Build Coastguard Worker   // a cycle.
7292*9880d681SAndroid Build Coastguard Worker   if (!Visited.insert(N).second) {
7293*9880d681SAndroid Build Coastguard Worker     errs() << "Detected cycle in SelectionDAG\n";
7294*9880d681SAndroid Build Coastguard Worker     dbgs() << "Offending node:\n";
7295*9880d681SAndroid Build Coastguard Worker     N->dumprFull(DAG); dbgs() << "\n";
7296*9880d681SAndroid Build Coastguard Worker     abort();
7297*9880d681SAndroid Build Coastguard Worker   }
7298*9880d681SAndroid Build Coastguard Worker 
7299*9880d681SAndroid Build Coastguard Worker   for (const SDValue &Op : N->op_values())
7300*9880d681SAndroid Build Coastguard Worker     checkForCyclesHelper(Op.getNode(), Visited, Checked, DAG);
7301*9880d681SAndroid Build Coastguard Worker 
7302*9880d681SAndroid Build Coastguard Worker   Checked.insert(N);
7303*9880d681SAndroid Build Coastguard Worker   Visited.erase(N);
7304*9880d681SAndroid Build Coastguard Worker }
7305*9880d681SAndroid Build Coastguard Worker #endif
7306*9880d681SAndroid Build Coastguard Worker 
checkForCycles(const llvm::SDNode * N,const llvm::SelectionDAG * DAG,bool force)7307*9880d681SAndroid Build Coastguard Worker void llvm::checkForCycles(const llvm::SDNode *N,
7308*9880d681SAndroid Build Coastguard Worker                           const llvm::SelectionDAG *DAG,
7309*9880d681SAndroid Build Coastguard Worker                           bool force) {
7310*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
7311*9880d681SAndroid Build Coastguard Worker   bool check = force;
7312*9880d681SAndroid Build Coastguard Worker #ifdef EXPENSIVE_CHECKS
7313*9880d681SAndroid Build Coastguard Worker   check = true;
7314*9880d681SAndroid Build Coastguard Worker #endif  // EXPENSIVE_CHECKS
7315*9880d681SAndroid Build Coastguard Worker   if (check) {
7316*9880d681SAndroid Build Coastguard Worker     assert(N && "Checking nonexistent SDNode");
7317*9880d681SAndroid Build Coastguard Worker     SmallPtrSet<const SDNode*, 32> visited;
7318*9880d681SAndroid Build Coastguard Worker     SmallPtrSet<const SDNode*, 32> checked;
7319*9880d681SAndroid Build Coastguard Worker     checkForCyclesHelper(N, visited, checked, DAG);
7320*9880d681SAndroid Build Coastguard Worker   }
7321*9880d681SAndroid Build Coastguard Worker #endif  // !NDEBUG
7322*9880d681SAndroid Build Coastguard Worker }
7323*9880d681SAndroid Build Coastguard Worker 
checkForCycles(const llvm::SelectionDAG * DAG,bool force)7324*9880d681SAndroid Build Coastguard Worker void llvm::checkForCycles(const llvm::SelectionDAG *DAG, bool force) {
7325*9880d681SAndroid Build Coastguard Worker   checkForCycles(DAG->getRoot().getNode(), DAG, force);
7326*9880d681SAndroid Build Coastguard Worker }
7327