1*9880d681SAndroid Build Coastguard Worker //===-- TargetLowering.cpp - Implement the TargetLowering class -----------===//
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 TargetLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/CallingConvLower.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineJumpTableInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SelectionDAG.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLoweringObjectFile.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
35*9880d681SAndroid Build Coastguard Worker #include <cctype>
36*9880d681SAndroid Build Coastguard Worker using namespace llvm;
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker /// NOTE: The TargetMachine owns TLOF.
TargetLowering(const TargetMachine & tm)39*9880d681SAndroid Build Coastguard Worker TargetLowering::TargetLowering(const TargetMachine &tm)
40*9880d681SAndroid Build Coastguard Worker : TargetLoweringBase(tm) {}
41*9880d681SAndroid Build Coastguard Worker
getTargetNodeName(unsigned Opcode) const42*9880d681SAndroid Build Coastguard Worker const char *TargetLowering::getTargetNodeName(unsigned Opcode) const {
43*9880d681SAndroid Build Coastguard Worker return nullptr;
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
isPositionIndependent() const46*9880d681SAndroid Build Coastguard Worker bool TargetLowering::isPositionIndependent() const {
47*9880d681SAndroid Build Coastguard Worker return getTargetMachine().isPositionIndependent();
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker /// Check whether a given call node is in tail position within its function. If
51*9880d681SAndroid Build Coastguard Worker /// so, it sets Chain to the input chain of the tail call.
isInTailCallPosition(SelectionDAG & DAG,SDNode * Node,SDValue & Chain) const52*9880d681SAndroid Build Coastguard Worker bool TargetLowering::isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
53*9880d681SAndroid Build Coastguard Worker SDValue &Chain) const {
54*9880d681SAndroid Build Coastguard Worker const Function *F = DAG.getMachineFunction().getFunction();
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker // Conservatively require the attributes of the call to match those of
57*9880d681SAndroid Build Coastguard Worker // the return. Ignore noalias because it doesn't affect the call sequence.
58*9880d681SAndroid Build Coastguard Worker AttributeSet CallerAttrs = F->getAttributes();
59*9880d681SAndroid Build Coastguard Worker if (AttrBuilder(CallerAttrs, AttributeSet::ReturnIndex)
60*9880d681SAndroid Build Coastguard Worker .removeAttribute(Attribute::NoAlias).hasAttributes())
61*9880d681SAndroid Build Coastguard Worker return false;
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker // It's not safe to eliminate the sign / zero extension of the return value.
64*9880d681SAndroid Build Coastguard Worker if (CallerAttrs.hasAttribute(AttributeSet::ReturnIndex, Attribute::ZExt) ||
65*9880d681SAndroid Build Coastguard Worker CallerAttrs.hasAttribute(AttributeSet::ReturnIndex, Attribute::SExt))
66*9880d681SAndroid Build Coastguard Worker return false;
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker // Check if the only use is a function return node.
69*9880d681SAndroid Build Coastguard Worker return isUsedByReturnOnly(Node, Chain);
70*9880d681SAndroid Build Coastguard Worker }
71*9880d681SAndroid Build Coastguard Worker
parametersInCSRMatch(const MachineRegisterInfo & MRI,const uint32_t * CallerPreservedMask,const SmallVectorImpl<CCValAssign> & ArgLocs,const SmallVectorImpl<SDValue> & OutVals) const72*9880d681SAndroid Build Coastguard Worker bool TargetLowering::parametersInCSRMatch(const MachineRegisterInfo &MRI,
73*9880d681SAndroid Build Coastguard Worker const uint32_t *CallerPreservedMask,
74*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<CCValAssign> &ArgLocs,
75*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<SDValue> &OutVals) const {
76*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
77*9880d681SAndroid Build Coastguard Worker const CCValAssign &ArgLoc = ArgLocs[I];
78*9880d681SAndroid Build Coastguard Worker if (!ArgLoc.isRegLoc())
79*9880d681SAndroid Build Coastguard Worker continue;
80*9880d681SAndroid Build Coastguard Worker unsigned Reg = ArgLoc.getLocReg();
81*9880d681SAndroid Build Coastguard Worker // Only look at callee saved registers.
82*9880d681SAndroid Build Coastguard Worker if (MachineOperand::clobbersPhysReg(CallerPreservedMask, Reg))
83*9880d681SAndroid Build Coastguard Worker continue;
84*9880d681SAndroid Build Coastguard Worker // Check that we pass the value used for the caller.
85*9880d681SAndroid Build Coastguard Worker // (We look for a CopyFromReg reading a virtual register that is used
86*9880d681SAndroid Build Coastguard Worker // for the function live-in value of register Reg)
87*9880d681SAndroid Build Coastguard Worker SDValue Value = OutVals[I];
88*9880d681SAndroid Build Coastguard Worker if (Value->getOpcode() != ISD::CopyFromReg)
89*9880d681SAndroid Build Coastguard Worker return false;
90*9880d681SAndroid Build Coastguard Worker unsigned ArgReg = cast<RegisterSDNode>(Value->getOperand(1))->getReg();
91*9880d681SAndroid Build Coastguard Worker if (MRI.getLiveInPhysReg(ArgReg) != Reg)
92*9880d681SAndroid Build Coastguard Worker return false;
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker return true;
95*9880d681SAndroid Build Coastguard Worker }
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker /// \brief Set CallLoweringInfo attribute flags based on a call instruction
98*9880d681SAndroid Build Coastguard Worker /// and called function attributes.
setAttributes(ImmutableCallSite * CS,unsigned AttrIdx)99*9880d681SAndroid Build Coastguard Worker void TargetLowering::ArgListEntry::setAttributes(ImmutableCallSite *CS,
100*9880d681SAndroid Build Coastguard Worker unsigned AttrIdx) {
101*9880d681SAndroid Build Coastguard Worker isSExt = CS->paramHasAttr(AttrIdx, Attribute::SExt);
102*9880d681SAndroid Build Coastguard Worker isZExt = CS->paramHasAttr(AttrIdx, Attribute::ZExt);
103*9880d681SAndroid Build Coastguard Worker isInReg = CS->paramHasAttr(AttrIdx, Attribute::InReg);
104*9880d681SAndroid Build Coastguard Worker isSRet = CS->paramHasAttr(AttrIdx, Attribute::StructRet);
105*9880d681SAndroid Build Coastguard Worker isNest = CS->paramHasAttr(AttrIdx, Attribute::Nest);
106*9880d681SAndroid Build Coastguard Worker isByVal = CS->paramHasAttr(AttrIdx, Attribute::ByVal);
107*9880d681SAndroid Build Coastguard Worker isInAlloca = CS->paramHasAttr(AttrIdx, Attribute::InAlloca);
108*9880d681SAndroid Build Coastguard Worker isReturned = CS->paramHasAttr(AttrIdx, Attribute::Returned);
109*9880d681SAndroid Build Coastguard Worker isSwiftSelf = CS->paramHasAttr(AttrIdx, Attribute::SwiftSelf);
110*9880d681SAndroid Build Coastguard Worker isSwiftError = CS->paramHasAttr(AttrIdx, Attribute::SwiftError);
111*9880d681SAndroid Build Coastguard Worker Alignment = CS->getParamAlignment(AttrIdx);
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker /// Generate a libcall taking the given operands as arguments and returning a
115*9880d681SAndroid Build Coastguard Worker /// result of type RetVT.
116*9880d681SAndroid Build Coastguard Worker std::pair<SDValue, SDValue>
makeLibCall(SelectionDAG & DAG,RTLIB::Libcall LC,EVT RetVT,ArrayRef<SDValue> Ops,bool isSigned,const SDLoc & dl,bool doesNotReturn,bool isReturnValueUsed) const117*9880d681SAndroid Build Coastguard Worker TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
118*9880d681SAndroid Build Coastguard Worker ArrayRef<SDValue> Ops, bool isSigned,
119*9880d681SAndroid Build Coastguard Worker const SDLoc &dl, bool doesNotReturn,
120*9880d681SAndroid Build Coastguard Worker bool isReturnValueUsed) const {
121*9880d681SAndroid Build Coastguard Worker TargetLowering::ArgListTy Args;
122*9880d681SAndroid Build Coastguard Worker Args.reserve(Ops.size());
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker TargetLowering::ArgListEntry Entry;
125*9880d681SAndroid Build Coastguard Worker for (SDValue Op : Ops) {
126*9880d681SAndroid Build Coastguard Worker Entry.Node = Op;
127*9880d681SAndroid Build Coastguard Worker Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext());
128*9880d681SAndroid Build Coastguard Worker Entry.isSExt = shouldSignExtendTypeInLibCall(Op.getValueType(), isSigned);
129*9880d681SAndroid Build Coastguard Worker Entry.isZExt = !shouldSignExtendTypeInLibCall(Op.getValueType(), isSigned);
130*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker if (LC == RTLIB::UNKNOWN_LIBCALL)
134*9880d681SAndroid Build Coastguard Worker report_fatal_error("Unsupported library call operation!");
135*9880d681SAndroid Build Coastguard Worker SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
136*9880d681SAndroid Build Coastguard Worker getPointerTy(DAG.getDataLayout()));
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
139*9880d681SAndroid Build Coastguard Worker TargetLowering::CallLoweringInfo CLI(DAG);
140*9880d681SAndroid Build Coastguard Worker bool signExtend = shouldSignExtendTypeInLibCall(RetVT, isSigned);
141*9880d681SAndroid Build Coastguard Worker CLI.setDebugLoc(dl).setChain(DAG.getEntryNode())
142*9880d681SAndroid Build Coastguard Worker .setCallee(getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
143*9880d681SAndroid Build Coastguard Worker .setNoReturn(doesNotReturn).setDiscardResult(!isReturnValueUsed)
144*9880d681SAndroid Build Coastguard Worker .setSExtResult(signExtend).setZExtResult(!signExtend);
145*9880d681SAndroid Build Coastguard Worker return LowerCallTo(CLI);
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker /// Soften the operands of a comparison. This code is shared among BR_CC,
149*9880d681SAndroid Build Coastguard Worker /// SELECT_CC, and SETCC handlers.
softenSetCCOperands(SelectionDAG & DAG,EVT VT,SDValue & NewLHS,SDValue & NewRHS,ISD::CondCode & CCCode,const SDLoc & dl) const150*9880d681SAndroid Build Coastguard Worker void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
151*9880d681SAndroid Build Coastguard Worker SDValue &NewLHS, SDValue &NewRHS,
152*9880d681SAndroid Build Coastguard Worker ISD::CondCode &CCCode,
153*9880d681SAndroid Build Coastguard Worker const SDLoc &dl) const {
154*9880d681SAndroid Build Coastguard Worker assert((VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f128 || VT == MVT::ppcf128)
155*9880d681SAndroid Build Coastguard Worker && "Unsupported setcc type!");
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker // Expand into one or more soft-fp libcall(s).
158*9880d681SAndroid Build Coastguard Worker RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL;
159*9880d681SAndroid Build Coastguard Worker bool ShouldInvertCC = false;
160*9880d681SAndroid Build Coastguard Worker switch (CCCode) {
161*9880d681SAndroid Build Coastguard Worker case ISD::SETEQ:
162*9880d681SAndroid Build Coastguard Worker case ISD::SETOEQ:
163*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 :
164*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OEQ_F64 :
165*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OEQ_F128 : RTLIB::OEQ_PPCF128;
166*9880d681SAndroid Build Coastguard Worker break;
167*9880d681SAndroid Build Coastguard Worker case ISD::SETNE:
168*9880d681SAndroid Build Coastguard Worker case ISD::SETUNE:
169*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 :
170*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::UNE_F64 :
171*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::UNE_F128 : RTLIB::UNE_PPCF128;
172*9880d681SAndroid Build Coastguard Worker break;
173*9880d681SAndroid Build Coastguard Worker case ISD::SETGE:
174*9880d681SAndroid Build Coastguard Worker case ISD::SETOGE:
175*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 :
176*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OGE_F64 :
177*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OGE_F128 : RTLIB::OGE_PPCF128;
178*9880d681SAndroid Build Coastguard Worker break;
179*9880d681SAndroid Build Coastguard Worker case ISD::SETLT:
180*9880d681SAndroid Build Coastguard Worker case ISD::SETOLT:
181*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 :
182*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OLT_F64 :
183*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OLT_F128 : RTLIB::OLT_PPCF128;
184*9880d681SAndroid Build Coastguard Worker break;
185*9880d681SAndroid Build Coastguard Worker case ISD::SETLE:
186*9880d681SAndroid Build Coastguard Worker case ISD::SETOLE:
187*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 :
188*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OLE_F64 :
189*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OLE_F128 : RTLIB::OLE_PPCF128;
190*9880d681SAndroid Build Coastguard Worker break;
191*9880d681SAndroid Build Coastguard Worker case ISD::SETGT:
192*9880d681SAndroid Build Coastguard Worker case ISD::SETOGT:
193*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 :
194*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OGT_F64 :
195*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OGT_F128 : RTLIB::OGT_PPCF128;
196*9880d681SAndroid Build Coastguard Worker break;
197*9880d681SAndroid Build Coastguard Worker case ISD::SETUO:
198*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 :
199*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::UO_F64 :
200*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::UO_F128 : RTLIB::UO_PPCF128;
201*9880d681SAndroid Build Coastguard Worker break;
202*9880d681SAndroid Build Coastguard Worker case ISD::SETO:
203*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::O_F32 :
204*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::O_F64 :
205*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::O_F128 : RTLIB::O_PPCF128;
206*9880d681SAndroid Build Coastguard Worker break;
207*9880d681SAndroid Build Coastguard Worker case ISD::SETONE:
208*9880d681SAndroid Build Coastguard Worker // SETONE = SETOLT | SETOGT
209*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 :
210*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OLT_F64 :
211*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OLT_F128 : RTLIB::OLT_PPCF128;
212*9880d681SAndroid Build Coastguard Worker LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 :
213*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OGT_F64 :
214*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OGT_F128 : RTLIB::OGT_PPCF128;
215*9880d681SAndroid Build Coastguard Worker break;
216*9880d681SAndroid Build Coastguard Worker case ISD::SETUEQ:
217*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 :
218*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::UO_F64 :
219*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::UO_F64 : RTLIB::UO_PPCF128;
220*9880d681SAndroid Build Coastguard Worker LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 :
221*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OEQ_F64 :
222*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OEQ_F128 : RTLIB::OEQ_PPCF128;
223*9880d681SAndroid Build Coastguard Worker break;
224*9880d681SAndroid Build Coastguard Worker default:
225*9880d681SAndroid Build Coastguard Worker // Invert CC for unordered comparisons
226*9880d681SAndroid Build Coastguard Worker ShouldInvertCC = true;
227*9880d681SAndroid Build Coastguard Worker switch (CCCode) {
228*9880d681SAndroid Build Coastguard Worker case ISD::SETULT:
229*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 :
230*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OGE_F64 :
231*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OGE_F128 : RTLIB::OGE_PPCF128;
232*9880d681SAndroid Build Coastguard Worker break;
233*9880d681SAndroid Build Coastguard Worker case ISD::SETULE:
234*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 :
235*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OGT_F64 :
236*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OGT_F128 : RTLIB::OGT_PPCF128;
237*9880d681SAndroid Build Coastguard Worker break;
238*9880d681SAndroid Build Coastguard Worker case ISD::SETUGT:
239*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 :
240*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OLE_F64 :
241*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OLE_F128 : RTLIB::OLE_PPCF128;
242*9880d681SAndroid Build Coastguard Worker break;
243*9880d681SAndroid Build Coastguard Worker case ISD::SETUGE:
244*9880d681SAndroid Build Coastguard Worker LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 :
245*9880d681SAndroid Build Coastguard Worker (VT == MVT::f64) ? RTLIB::OLT_F64 :
246*9880d681SAndroid Build Coastguard Worker (VT == MVT::f128) ? RTLIB::OLT_F128 : RTLIB::OLT_PPCF128;
247*9880d681SAndroid Build Coastguard Worker break;
248*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Do not know how to soften this setcc!");
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker // Use the target specific return value for comparions lib calls.
253*9880d681SAndroid Build Coastguard Worker EVT RetVT = getCmpLibcallReturnType();
254*9880d681SAndroid Build Coastguard Worker SDValue Ops[2] = {NewLHS, NewRHS};
255*9880d681SAndroid Build Coastguard Worker NewLHS = makeLibCall(DAG, LC1, RetVT, Ops, false /*sign irrelevant*/,
256*9880d681SAndroid Build Coastguard Worker dl).first;
257*9880d681SAndroid Build Coastguard Worker NewRHS = DAG.getConstant(0, dl, RetVT);
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker CCCode = getCmpLibcallCC(LC1);
260*9880d681SAndroid Build Coastguard Worker if (ShouldInvertCC)
261*9880d681SAndroid Build Coastguard Worker CCCode = getSetCCInverse(CCCode, /*isInteger=*/true);
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
264*9880d681SAndroid Build Coastguard Worker SDValue Tmp = DAG.getNode(
265*9880d681SAndroid Build Coastguard Worker ISD::SETCC, dl,
266*9880d681SAndroid Build Coastguard Worker getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), RetVT),
267*9880d681SAndroid Build Coastguard Worker NewLHS, NewRHS, DAG.getCondCode(CCCode));
268*9880d681SAndroid Build Coastguard Worker NewLHS = makeLibCall(DAG, LC2, RetVT, Ops, false/*sign irrelevant*/,
269*9880d681SAndroid Build Coastguard Worker dl).first;
270*9880d681SAndroid Build Coastguard Worker NewLHS = DAG.getNode(
271*9880d681SAndroid Build Coastguard Worker ISD::SETCC, dl,
272*9880d681SAndroid Build Coastguard Worker getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), RetVT),
273*9880d681SAndroid Build Coastguard Worker NewLHS, NewRHS, DAG.getCondCode(getCmpLibcallCC(LC2)));
274*9880d681SAndroid Build Coastguard Worker NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS);
275*9880d681SAndroid Build Coastguard Worker NewRHS = SDValue();
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker }
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker /// Return the entry encoding for a jump table in the current function. The
280*9880d681SAndroid Build Coastguard Worker /// returned value is a member of the MachineJumpTableInfo::JTEntryKind enum.
getJumpTableEncoding() const281*9880d681SAndroid Build Coastguard Worker unsigned TargetLowering::getJumpTableEncoding() const {
282*9880d681SAndroid Build Coastguard Worker // In non-pic modes, just use the address of a block.
283*9880d681SAndroid Build Coastguard Worker if (!isPositionIndependent())
284*9880d681SAndroid Build Coastguard Worker return MachineJumpTableInfo::EK_BlockAddress;
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker // In PIC mode, if the target supports a GPRel32 directive, use it.
287*9880d681SAndroid Build Coastguard Worker if (getTargetMachine().getMCAsmInfo()->getGPRel32Directive() != nullptr)
288*9880d681SAndroid Build Coastguard Worker return MachineJumpTableInfo::EK_GPRel32BlockAddress;
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker // Otherwise, use a label difference.
291*9880d681SAndroid Build Coastguard Worker return MachineJumpTableInfo::EK_LabelDifference32;
292*9880d681SAndroid Build Coastguard Worker }
293*9880d681SAndroid Build Coastguard Worker
getPICJumpTableRelocBase(SDValue Table,SelectionDAG & DAG) const294*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::getPICJumpTableRelocBase(SDValue Table,
295*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
296*9880d681SAndroid Build Coastguard Worker // If our PIC model is GP relative, use the global offset table as the base.
297*9880d681SAndroid Build Coastguard Worker unsigned JTEncoding = getJumpTableEncoding();
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker if ((JTEncoding == MachineJumpTableInfo::EK_GPRel64BlockAddress) ||
300*9880d681SAndroid Build Coastguard Worker (JTEncoding == MachineJumpTableInfo::EK_GPRel32BlockAddress))
301*9880d681SAndroid Build Coastguard Worker return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy(DAG.getDataLayout()));
302*9880d681SAndroid Build Coastguard Worker
303*9880d681SAndroid Build Coastguard Worker return Table;
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker /// This returns the relocation base for the given PIC jumptable, the same as
307*9880d681SAndroid Build Coastguard Worker /// getPICJumpTableRelocBase, but as an MCExpr.
308*9880d681SAndroid Build Coastguard Worker const MCExpr *
getPICJumpTableRelocBaseExpr(const MachineFunction * MF,unsigned JTI,MCContext & Ctx) const309*9880d681SAndroid Build Coastguard Worker TargetLowering::getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
310*9880d681SAndroid Build Coastguard Worker unsigned JTI,MCContext &Ctx) const{
311*9880d681SAndroid Build Coastguard Worker // The normal PIC reloc base is the label at the start of the jump table.
312*9880d681SAndroid Build Coastguard Worker return MCSymbolRefExpr::create(MF->getJTISymbol(JTI, Ctx), Ctx);
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker bool
isOffsetFoldingLegal(const GlobalAddressSDNode * GA) const316*9880d681SAndroid Build Coastguard Worker TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
317*9880d681SAndroid Build Coastguard Worker const TargetMachine &TM = getTargetMachine();
318*9880d681SAndroid Build Coastguard Worker const GlobalValue *GV = GA->getGlobal();
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker // If the address is not even local to this DSO we will have to load it from
321*9880d681SAndroid Build Coastguard Worker // a got and then add the offset.
322*9880d681SAndroid Build Coastguard Worker if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
323*9880d681SAndroid Build Coastguard Worker return false;
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker // If the code is position independent we will have to add a base register.
326*9880d681SAndroid Build Coastguard Worker if (isPositionIndependent())
327*9880d681SAndroid Build Coastguard Worker return false;
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker // Otherwise we can do it.
330*9880d681SAndroid Build Coastguard Worker return true;
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
334*9880d681SAndroid Build Coastguard Worker // Optimization Methods
335*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker /// Check to see if the specified operand of the specified instruction is a
338*9880d681SAndroid Build Coastguard Worker /// constant integer. If so, check to see if there are any bits set in the
339*9880d681SAndroid Build Coastguard Worker /// constant that are not demanded. If so, shrink the constant and return true.
ShrinkDemandedConstant(SDValue Op,const APInt & Demanded)340*9880d681SAndroid Build Coastguard Worker bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDValue Op,
341*9880d681SAndroid Build Coastguard Worker const APInt &Demanded) {
342*9880d681SAndroid Build Coastguard Worker SDLoc dl(Op);
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker // FIXME: ISD::SELECT, ISD::SELECT_CC
345*9880d681SAndroid Build Coastguard Worker switch (Op.getOpcode()) {
346*9880d681SAndroid Build Coastguard Worker default: break;
347*9880d681SAndroid Build Coastguard Worker case ISD::XOR:
348*9880d681SAndroid Build Coastguard Worker case ISD::AND:
349*9880d681SAndroid Build Coastguard Worker case ISD::OR: {
350*9880d681SAndroid Build Coastguard Worker ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
351*9880d681SAndroid Build Coastguard Worker if (!C) return false;
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker if (Op.getOpcode() == ISD::XOR &&
354*9880d681SAndroid Build Coastguard Worker (C->getAPIntValue() | (~Demanded)).isAllOnesValue())
355*9880d681SAndroid Build Coastguard Worker return false;
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker // if we can expand it to have all bits set, do it
358*9880d681SAndroid Build Coastguard Worker if (C->getAPIntValue().intersects(~Demanded)) {
359*9880d681SAndroid Build Coastguard Worker EVT VT = Op.getValueType();
360*9880d681SAndroid Build Coastguard Worker SDValue New = DAG.getNode(Op.getOpcode(), dl, VT, Op.getOperand(0),
361*9880d681SAndroid Build Coastguard Worker DAG.getConstant(Demanded &
362*9880d681SAndroid Build Coastguard Worker C->getAPIntValue(),
363*9880d681SAndroid Build Coastguard Worker dl, VT));
364*9880d681SAndroid Build Coastguard Worker return CombineTo(Op, New);
365*9880d681SAndroid Build Coastguard Worker }
366*9880d681SAndroid Build Coastguard Worker
367*9880d681SAndroid Build Coastguard Worker break;
368*9880d681SAndroid Build Coastguard Worker }
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker return false;
372*9880d681SAndroid Build Coastguard Worker }
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
375*9880d681SAndroid Build Coastguard Worker /// This uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
376*9880d681SAndroid Build Coastguard Worker /// generalized for targets with other types of implicit widening casts.
ShrinkDemandedOp(SDValue Op,unsigned BitWidth,const APInt & Demanded,const SDLoc & dl)377*9880d681SAndroid Build Coastguard Worker bool TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
378*9880d681SAndroid Build Coastguard Worker unsigned BitWidth,
379*9880d681SAndroid Build Coastguard Worker const APInt &Demanded,
380*9880d681SAndroid Build Coastguard Worker const SDLoc &dl) {
381*9880d681SAndroid Build Coastguard Worker assert(Op.getNumOperands() == 2 &&
382*9880d681SAndroid Build Coastguard Worker "ShrinkDemandedOp only supports binary operators!");
383*9880d681SAndroid Build Coastguard Worker assert(Op.getNode()->getNumValues() == 1 &&
384*9880d681SAndroid Build Coastguard Worker "ShrinkDemandedOp only supports nodes with one result!");
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker // Early return, as this function cannot handle vector types.
387*9880d681SAndroid Build Coastguard Worker if (Op.getValueType().isVector())
388*9880d681SAndroid Build Coastguard Worker return false;
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker // Don't do this if the node has another user, which may require the
391*9880d681SAndroid Build Coastguard Worker // full value.
392*9880d681SAndroid Build Coastguard Worker if (!Op.getNode()->hasOneUse())
393*9880d681SAndroid Build Coastguard Worker return false;
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker // Search for the smallest integer type with free casts to and from
396*9880d681SAndroid Build Coastguard Worker // Op's type. For expedience, just check power-of-2 integer types.
397*9880d681SAndroid Build Coastguard Worker const TargetLowering &TLI = DAG.getTargetLoweringInfo();
398*9880d681SAndroid Build Coastguard Worker unsigned DemandedSize = BitWidth - Demanded.countLeadingZeros();
399*9880d681SAndroid Build Coastguard Worker unsigned SmallVTBits = DemandedSize;
400*9880d681SAndroid Build Coastguard Worker if (!isPowerOf2_32(SmallVTBits))
401*9880d681SAndroid Build Coastguard Worker SmallVTBits = NextPowerOf2(SmallVTBits);
402*9880d681SAndroid Build Coastguard Worker for (; SmallVTBits < BitWidth; SmallVTBits = NextPowerOf2(SmallVTBits)) {
403*9880d681SAndroid Build Coastguard Worker EVT SmallVT = EVT::getIntegerVT(*DAG.getContext(), SmallVTBits);
404*9880d681SAndroid Build Coastguard Worker if (TLI.isTruncateFree(Op.getValueType(), SmallVT) &&
405*9880d681SAndroid Build Coastguard Worker TLI.isZExtFree(SmallVT, Op.getValueType())) {
406*9880d681SAndroid Build Coastguard Worker // We found a type with free casts.
407*9880d681SAndroid Build Coastguard Worker SDValue X = DAG.getNode(Op.getOpcode(), dl, SmallVT,
408*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::TRUNCATE, dl, SmallVT,
409*9880d681SAndroid Build Coastguard Worker Op.getNode()->getOperand(0)),
410*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::TRUNCATE, dl, SmallVT,
411*9880d681SAndroid Build Coastguard Worker Op.getNode()->getOperand(1)));
412*9880d681SAndroid Build Coastguard Worker bool NeedZext = DemandedSize > SmallVTBits;
413*9880d681SAndroid Build Coastguard Worker SDValue Z = DAG.getNode(NeedZext ? ISD::ZERO_EXTEND : ISD::ANY_EXTEND,
414*9880d681SAndroid Build Coastguard Worker dl, Op.getValueType(), X);
415*9880d681SAndroid Build Coastguard Worker return CombineTo(Op, Z);
416*9880d681SAndroid Build Coastguard Worker }
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker return false;
419*9880d681SAndroid Build Coastguard Worker }
420*9880d681SAndroid Build Coastguard Worker
421*9880d681SAndroid Build Coastguard Worker /// Look at Op. At this point, we know that only the DemandedMask bits of the
422*9880d681SAndroid Build Coastguard Worker /// result of Op are ever used downstream. If we can use this information to
423*9880d681SAndroid Build Coastguard Worker /// simplify Op, create a new simplified DAG node and return true, returning the
424*9880d681SAndroid Build Coastguard Worker /// original and new nodes in Old and New. Otherwise, analyze the expression and
425*9880d681SAndroid Build Coastguard Worker /// return a mask of KnownOne and KnownZero bits for the expression (used to
426*9880d681SAndroid Build Coastguard Worker /// simplify the caller). The KnownZero/One bits may only be accurate for those
427*9880d681SAndroid Build Coastguard Worker /// bits in the DemandedMask.
SimplifyDemandedBits(SDValue Op,const APInt & DemandedMask,APInt & KnownZero,APInt & KnownOne,TargetLoweringOpt & TLO,unsigned Depth) const428*9880d681SAndroid Build Coastguard Worker bool TargetLowering::SimplifyDemandedBits(SDValue Op,
429*9880d681SAndroid Build Coastguard Worker const APInt &DemandedMask,
430*9880d681SAndroid Build Coastguard Worker APInt &KnownZero,
431*9880d681SAndroid Build Coastguard Worker APInt &KnownOne,
432*9880d681SAndroid Build Coastguard Worker TargetLoweringOpt &TLO,
433*9880d681SAndroid Build Coastguard Worker unsigned Depth) const {
434*9880d681SAndroid Build Coastguard Worker unsigned BitWidth = DemandedMask.getBitWidth();
435*9880d681SAndroid Build Coastguard Worker assert(Op.getValueType().getScalarType().getSizeInBits() == BitWidth &&
436*9880d681SAndroid Build Coastguard Worker "Mask size mismatches value type size!");
437*9880d681SAndroid Build Coastguard Worker APInt NewMask = DemandedMask;
438*9880d681SAndroid Build Coastguard Worker SDLoc dl(Op);
439*9880d681SAndroid Build Coastguard Worker auto &DL = TLO.DAG.getDataLayout();
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker // Don't know anything.
442*9880d681SAndroid Build Coastguard Worker KnownZero = KnownOne = APInt(BitWidth, 0);
443*9880d681SAndroid Build Coastguard Worker
444*9880d681SAndroid Build Coastguard Worker // Other users may use these bits.
445*9880d681SAndroid Build Coastguard Worker if (!Op.getNode()->hasOneUse()) {
446*9880d681SAndroid Build Coastguard Worker if (Depth != 0) {
447*9880d681SAndroid Build Coastguard Worker // If not at the root, Just compute the KnownZero/KnownOne bits to
448*9880d681SAndroid Build Coastguard Worker // simplify things downstream.
449*9880d681SAndroid Build Coastguard Worker TLO.DAG.computeKnownBits(Op, KnownZero, KnownOne, Depth);
450*9880d681SAndroid Build Coastguard Worker return false;
451*9880d681SAndroid Build Coastguard Worker }
452*9880d681SAndroid Build Coastguard Worker // If this is the root being simplified, allow it to have multiple uses,
453*9880d681SAndroid Build Coastguard Worker // just set the NewMask to all bits.
454*9880d681SAndroid Build Coastguard Worker NewMask = APInt::getAllOnesValue(BitWidth);
455*9880d681SAndroid Build Coastguard Worker } else if (DemandedMask == 0) {
456*9880d681SAndroid Build Coastguard Worker // Not demanding any bits from Op.
457*9880d681SAndroid Build Coastguard Worker if (!Op.isUndef())
458*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getUNDEF(Op.getValueType()));
459*9880d681SAndroid Build Coastguard Worker return false;
460*9880d681SAndroid Build Coastguard Worker } else if (Depth == 6) { // Limit search depth.
461*9880d681SAndroid Build Coastguard Worker return false;
462*9880d681SAndroid Build Coastguard Worker }
463*9880d681SAndroid Build Coastguard Worker
464*9880d681SAndroid Build Coastguard Worker APInt KnownZero2, KnownOne2, KnownZeroOut, KnownOneOut;
465*9880d681SAndroid Build Coastguard Worker switch (Op.getOpcode()) {
466*9880d681SAndroid Build Coastguard Worker case ISD::Constant:
467*9880d681SAndroid Build Coastguard Worker // We know all of the bits for a constant!
468*9880d681SAndroid Build Coastguard Worker KnownOne = cast<ConstantSDNode>(Op)->getAPIntValue();
469*9880d681SAndroid Build Coastguard Worker KnownZero = ~KnownOne;
470*9880d681SAndroid Build Coastguard Worker return false; // Don't fall through, will infinitely loop.
471*9880d681SAndroid Build Coastguard Worker case ISD::AND:
472*9880d681SAndroid Build Coastguard Worker // If the RHS is a constant, check to see if the LHS would be zero without
473*9880d681SAndroid Build Coastguard Worker // using the bits from the RHS. Below, we use knowledge about the RHS to
474*9880d681SAndroid Build Coastguard Worker // simplify the LHS, here we're using information from the LHS to simplify
475*9880d681SAndroid Build Coastguard Worker // the RHS.
476*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
477*9880d681SAndroid Build Coastguard Worker APInt LHSZero, LHSOne;
478*9880d681SAndroid Build Coastguard Worker // Do not increment Depth here; that can cause an infinite loop.
479*9880d681SAndroid Build Coastguard Worker TLO.DAG.computeKnownBits(Op.getOperand(0), LHSZero, LHSOne, Depth);
480*9880d681SAndroid Build Coastguard Worker // If the LHS already has zeros where RHSC does, this and is dead.
481*9880d681SAndroid Build Coastguard Worker if ((LHSZero & NewMask) == (~RHSC->getAPIntValue() & NewMask))
482*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(0));
483*9880d681SAndroid Build Coastguard Worker // If any of the set bits in the RHS are known zero on the LHS, shrink
484*9880d681SAndroid Build Coastguard Worker // the constant.
485*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & NewMask))
486*9880d681SAndroid Build Coastguard Worker return true;
487*9880d681SAndroid Build Coastguard Worker }
488*9880d681SAndroid Build Coastguard Worker
489*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,
490*9880d681SAndroid Build Coastguard Worker KnownOne, TLO, Depth+1))
491*9880d681SAndroid Build Coastguard Worker return true;
492*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
493*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), ~KnownZero & NewMask,
494*9880d681SAndroid Build Coastguard Worker KnownZero2, KnownOne2, TLO, Depth+1))
495*9880d681SAndroid Build Coastguard Worker return true;
496*9880d681SAndroid Build Coastguard Worker assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Worker // If all of the demanded bits are known one on one side, return the other.
499*9880d681SAndroid Build Coastguard Worker // These bits cannot contribute to the result of the 'and'.
500*9880d681SAndroid Build Coastguard Worker if ((NewMask & ~KnownZero2 & KnownOne) == (~KnownZero2 & NewMask))
501*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(0));
502*9880d681SAndroid Build Coastguard Worker if ((NewMask & ~KnownZero & KnownOne2) == (~KnownZero & NewMask))
503*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(1));
504*9880d681SAndroid Build Coastguard Worker // If all of the demanded bits in the inputs are known zeros, return zero.
505*9880d681SAndroid Build Coastguard Worker if ((NewMask & (KnownZero|KnownZero2)) == NewMask)
506*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getConstant(0, dl, Op.getValueType()));
507*9880d681SAndroid Build Coastguard Worker // If the RHS is a constant, see if we can simplify it.
508*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask))
509*9880d681SAndroid Build Coastguard Worker return true;
510*9880d681SAndroid Build Coastguard Worker // If the operation can be done in a smaller type, do so.
511*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
512*9880d681SAndroid Build Coastguard Worker return true;
513*9880d681SAndroid Build Coastguard Worker
514*9880d681SAndroid Build Coastguard Worker // Output known-1 bits are only known if set in both the LHS & RHS.
515*9880d681SAndroid Build Coastguard Worker KnownOne &= KnownOne2;
516*9880d681SAndroid Build Coastguard Worker // Output known-0 are known to be clear if zero in either the LHS | RHS.
517*9880d681SAndroid Build Coastguard Worker KnownZero |= KnownZero2;
518*9880d681SAndroid Build Coastguard Worker break;
519*9880d681SAndroid Build Coastguard Worker case ISD::OR:
520*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,
521*9880d681SAndroid Build Coastguard Worker KnownOne, TLO, Depth+1))
522*9880d681SAndroid Build Coastguard Worker return true;
523*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
524*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), ~KnownOne & NewMask,
525*9880d681SAndroid Build Coastguard Worker KnownZero2, KnownOne2, TLO, Depth+1))
526*9880d681SAndroid Build Coastguard Worker return true;
527*9880d681SAndroid Build Coastguard Worker assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
528*9880d681SAndroid Build Coastguard Worker
529*9880d681SAndroid Build Coastguard Worker // If all of the demanded bits are known zero on one side, return the other.
530*9880d681SAndroid Build Coastguard Worker // These bits cannot contribute to the result of the 'or'.
531*9880d681SAndroid Build Coastguard Worker if ((NewMask & ~KnownOne2 & KnownZero) == (~KnownOne2 & NewMask))
532*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(0));
533*9880d681SAndroid Build Coastguard Worker if ((NewMask & ~KnownOne & KnownZero2) == (~KnownOne & NewMask))
534*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(1));
535*9880d681SAndroid Build Coastguard Worker // If all of the potentially set bits on one side are known to be set on
536*9880d681SAndroid Build Coastguard Worker // the other side, just use the 'other' side.
537*9880d681SAndroid Build Coastguard Worker if ((NewMask & ~KnownZero & KnownOne2) == (~KnownZero & NewMask))
538*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(0));
539*9880d681SAndroid Build Coastguard Worker if ((NewMask & ~KnownZero2 & KnownOne) == (~KnownZero2 & NewMask))
540*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(1));
541*9880d681SAndroid Build Coastguard Worker // If the RHS is a constant, see if we can simplify it.
542*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedConstant(Op, NewMask))
543*9880d681SAndroid Build Coastguard Worker return true;
544*9880d681SAndroid Build Coastguard Worker // If the operation can be done in a smaller type, do so.
545*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
546*9880d681SAndroid Build Coastguard Worker return true;
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker // Output known-0 bits are only known if clear in both the LHS & RHS.
549*9880d681SAndroid Build Coastguard Worker KnownZero &= KnownZero2;
550*9880d681SAndroid Build Coastguard Worker // Output known-1 are known to be set if set in either the LHS | RHS.
551*9880d681SAndroid Build Coastguard Worker KnownOne |= KnownOne2;
552*9880d681SAndroid Build Coastguard Worker break;
553*9880d681SAndroid Build Coastguard Worker case ISD::XOR:
554*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,
555*9880d681SAndroid Build Coastguard Worker KnownOne, TLO, Depth+1))
556*9880d681SAndroid Build Coastguard Worker return true;
557*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
558*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), NewMask, KnownZero2,
559*9880d681SAndroid Build Coastguard Worker KnownOne2, TLO, Depth+1))
560*9880d681SAndroid Build Coastguard Worker return true;
561*9880d681SAndroid Build Coastguard Worker assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
562*9880d681SAndroid Build Coastguard Worker
563*9880d681SAndroid Build Coastguard Worker // If all of the demanded bits are known zero on one side, return the other.
564*9880d681SAndroid Build Coastguard Worker // These bits cannot contribute to the result of the 'xor'.
565*9880d681SAndroid Build Coastguard Worker if ((KnownZero & NewMask) == NewMask)
566*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(0));
567*9880d681SAndroid Build Coastguard Worker if ((KnownZero2 & NewMask) == NewMask)
568*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(1));
569*9880d681SAndroid Build Coastguard Worker // If the operation can be done in a smaller type, do so.
570*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
571*9880d681SAndroid Build Coastguard Worker return true;
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Worker // If all of the unknown bits are known to be zero on one side or the other
574*9880d681SAndroid Build Coastguard Worker // (but not both) turn this into an *inclusive* or.
575*9880d681SAndroid Build Coastguard Worker // e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
576*9880d681SAndroid Build Coastguard Worker if ((NewMask & ~KnownZero & ~KnownZero2) == 0)
577*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, dl, Op.getValueType(),
578*9880d681SAndroid Build Coastguard Worker Op.getOperand(0),
579*9880d681SAndroid Build Coastguard Worker Op.getOperand(1)));
580*9880d681SAndroid Build Coastguard Worker
581*9880d681SAndroid Build Coastguard Worker // Output known-0 bits are known if clear or set in both the LHS & RHS.
582*9880d681SAndroid Build Coastguard Worker KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
583*9880d681SAndroid Build Coastguard Worker // Output known-1 are known to be set if set in only one of the LHS, RHS.
584*9880d681SAndroid Build Coastguard Worker KnownOneOut = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
585*9880d681SAndroid Build Coastguard Worker
586*9880d681SAndroid Build Coastguard Worker // If all of the demanded bits on one side are known, and all of the set
587*9880d681SAndroid Build Coastguard Worker // bits on that side are also known to be set on the other side, turn this
588*9880d681SAndroid Build Coastguard Worker // into an AND, as we know the bits will be cleared.
589*9880d681SAndroid Build Coastguard Worker // e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
590*9880d681SAndroid Build Coastguard Worker // NB: it is okay if more bits are known than are requested
591*9880d681SAndroid Build Coastguard Worker if ((NewMask & (KnownZero|KnownOne)) == NewMask) { // all known on one side
592*9880d681SAndroid Build Coastguard Worker if (KnownOne == KnownOne2) { // set bits are the same on both sides
593*9880d681SAndroid Build Coastguard Worker EVT VT = Op.getValueType();
594*9880d681SAndroid Build Coastguard Worker SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, dl, VT);
595*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT,
596*9880d681SAndroid Build Coastguard Worker Op.getOperand(0), ANDC));
597*9880d681SAndroid Build Coastguard Worker }
598*9880d681SAndroid Build Coastguard Worker }
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker // If the RHS is a constant, see if we can simplify it.
601*9880d681SAndroid Build Coastguard Worker // for XOR, we prefer to force bits to 1 if they will make a -1.
602*9880d681SAndroid Build Coastguard Worker // if we can't force bits, try to shrink constant
603*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
604*9880d681SAndroid Build Coastguard Worker APInt Expanded = C->getAPIntValue() | (~NewMask);
605*9880d681SAndroid Build Coastguard Worker // if we can expand it to have all bits set, do it
606*9880d681SAndroid Build Coastguard Worker if (Expanded.isAllOnesValue()) {
607*9880d681SAndroid Build Coastguard Worker if (Expanded != C->getAPIntValue()) {
608*9880d681SAndroid Build Coastguard Worker EVT VT = Op.getValueType();
609*9880d681SAndroid Build Coastguard Worker SDValue New = TLO.DAG.getNode(Op.getOpcode(), dl,VT, Op.getOperand(0),
610*9880d681SAndroid Build Coastguard Worker TLO.DAG.getConstant(Expanded, dl, VT));
611*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, New);
612*9880d681SAndroid Build Coastguard Worker }
613*9880d681SAndroid Build Coastguard Worker // if it already has all the bits set, nothing to change
614*9880d681SAndroid Build Coastguard Worker // but don't shrink either!
615*9880d681SAndroid Build Coastguard Worker } else if (TLO.ShrinkDemandedConstant(Op, NewMask)) {
616*9880d681SAndroid Build Coastguard Worker return true;
617*9880d681SAndroid Build Coastguard Worker }
618*9880d681SAndroid Build Coastguard Worker }
619*9880d681SAndroid Build Coastguard Worker
620*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZeroOut;
621*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOneOut;
622*9880d681SAndroid Build Coastguard Worker break;
623*9880d681SAndroid Build Coastguard Worker case ISD::SELECT:
624*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(2), NewMask, KnownZero,
625*9880d681SAndroid Build Coastguard Worker KnownOne, TLO, Depth+1))
626*9880d681SAndroid Build Coastguard Worker return true;
627*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero2,
628*9880d681SAndroid Build Coastguard Worker KnownOne2, TLO, Depth+1))
629*9880d681SAndroid Build Coastguard Worker return true;
630*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
631*9880d681SAndroid Build Coastguard Worker assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
632*9880d681SAndroid Build Coastguard Worker
633*9880d681SAndroid Build Coastguard Worker // If the operands are constants, see if we can simplify them.
634*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedConstant(Op, NewMask))
635*9880d681SAndroid Build Coastguard Worker return true;
636*9880d681SAndroid Build Coastguard Worker
637*9880d681SAndroid Build Coastguard Worker // Only known if known in both the LHS and RHS.
638*9880d681SAndroid Build Coastguard Worker KnownOne &= KnownOne2;
639*9880d681SAndroid Build Coastguard Worker KnownZero &= KnownZero2;
640*9880d681SAndroid Build Coastguard Worker break;
641*9880d681SAndroid Build Coastguard Worker case ISD::SELECT_CC:
642*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(3), NewMask, KnownZero,
643*9880d681SAndroid Build Coastguard Worker KnownOne, TLO, Depth+1))
644*9880d681SAndroid Build Coastguard Worker return true;
645*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(2), NewMask, KnownZero2,
646*9880d681SAndroid Build Coastguard Worker KnownOne2, TLO, Depth+1))
647*9880d681SAndroid Build Coastguard Worker return true;
648*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
649*9880d681SAndroid Build Coastguard Worker assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
650*9880d681SAndroid Build Coastguard Worker
651*9880d681SAndroid Build Coastguard Worker // If the operands are constants, see if we can simplify them.
652*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedConstant(Op, NewMask))
653*9880d681SAndroid Build Coastguard Worker return true;
654*9880d681SAndroid Build Coastguard Worker
655*9880d681SAndroid Build Coastguard Worker // Only known if known in both the LHS and RHS.
656*9880d681SAndroid Build Coastguard Worker KnownOne &= KnownOne2;
657*9880d681SAndroid Build Coastguard Worker KnownZero &= KnownZero2;
658*9880d681SAndroid Build Coastguard Worker break;
659*9880d681SAndroid Build Coastguard Worker case ISD::SHL:
660*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
661*9880d681SAndroid Build Coastguard Worker unsigned ShAmt = SA->getZExtValue();
662*9880d681SAndroid Build Coastguard Worker SDValue InOp = Op.getOperand(0);
663*9880d681SAndroid Build Coastguard Worker
664*9880d681SAndroid Build Coastguard Worker // If the shift count is an invalid immediate, don't do anything.
665*9880d681SAndroid Build Coastguard Worker if (ShAmt >= BitWidth)
666*9880d681SAndroid Build Coastguard Worker break;
667*9880d681SAndroid Build Coastguard Worker
668*9880d681SAndroid Build Coastguard Worker // If this is ((X >>u C1) << ShAmt), see if we can simplify this into a
669*9880d681SAndroid Build Coastguard Worker // single shift. We can do this if the bottom bits (which are shifted
670*9880d681SAndroid Build Coastguard Worker // out) are never demanded.
671*9880d681SAndroid Build Coastguard Worker if (InOp.getOpcode() == ISD::SRL &&
672*9880d681SAndroid Build Coastguard Worker isa<ConstantSDNode>(InOp.getOperand(1))) {
673*9880d681SAndroid Build Coastguard Worker if (ShAmt && (NewMask & APInt::getLowBitsSet(BitWidth, ShAmt)) == 0) {
674*9880d681SAndroid Build Coastguard Worker unsigned C1= cast<ConstantSDNode>(InOp.getOperand(1))->getZExtValue();
675*9880d681SAndroid Build Coastguard Worker unsigned Opc = ISD::SHL;
676*9880d681SAndroid Build Coastguard Worker int Diff = ShAmt-C1;
677*9880d681SAndroid Build Coastguard Worker if (Diff < 0) {
678*9880d681SAndroid Build Coastguard Worker Diff = -Diff;
679*9880d681SAndroid Build Coastguard Worker Opc = ISD::SRL;
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Worker SDValue NewSA =
683*9880d681SAndroid Build Coastguard Worker TLO.DAG.getConstant(Diff, dl, Op.getOperand(1).getValueType());
684*9880d681SAndroid Build Coastguard Worker EVT VT = Op.getValueType();
685*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT,
686*9880d681SAndroid Build Coastguard Worker InOp.getOperand(0), NewSA));
687*9880d681SAndroid Build Coastguard Worker }
688*9880d681SAndroid Build Coastguard Worker }
689*9880d681SAndroid Build Coastguard Worker
690*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(InOp, NewMask.lshr(ShAmt),
691*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
692*9880d681SAndroid Build Coastguard Worker return true;
693*9880d681SAndroid Build Coastguard Worker
694*9880d681SAndroid Build Coastguard Worker // Convert (shl (anyext x, c)) to (anyext (shl x, c)) if the high bits
695*9880d681SAndroid Build Coastguard Worker // are not demanded. This will likely allow the anyext to be folded away.
696*9880d681SAndroid Build Coastguard Worker if (InOp.getNode()->getOpcode() == ISD::ANY_EXTEND) {
697*9880d681SAndroid Build Coastguard Worker SDValue InnerOp = InOp.getNode()->getOperand(0);
698*9880d681SAndroid Build Coastguard Worker EVT InnerVT = InnerOp.getValueType();
699*9880d681SAndroid Build Coastguard Worker unsigned InnerBits = InnerVT.getSizeInBits();
700*9880d681SAndroid Build Coastguard Worker if (ShAmt < InnerBits && NewMask.lshr(InnerBits) == 0 &&
701*9880d681SAndroid Build Coastguard Worker isTypeDesirableForOp(ISD::SHL, InnerVT)) {
702*9880d681SAndroid Build Coastguard Worker EVT ShTy = getShiftAmountTy(InnerVT, DL);
703*9880d681SAndroid Build Coastguard Worker if (!APInt(BitWidth, ShAmt).isIntN(ShTy.getSizeInBits()))
704*9880d681SAndroid Build Coastguard Worker ShTy = InnerVT;
705*9880d681SAndroid Build Coastguard Worker SDValue NarrowShl =
706*9880d681SAndroid Build Coastguard Worker TLO.DAG.getNode(ISD::SHL, dl, InnerVT, InnerOp,
707*9880d681SAndroid Build Coastguard Worker TLO.DAG.getConstant(ShAmt, dl, ShTy));
708*9880d681SAndroid Build Coastguard Worker return
709*9880d681SAndroid Build Coastguard Worker TLO.CombineTo(Op,
710*9880d681SAndroid Build Coastguard Worker TLO.DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(),
711*9880d681SAndroid Build Coastguard Worker NarrowShl));
712*9880d681SAndroid Build Coastguard Worker }
713*9880d681SAndroid Build Coastguard Worker // Repeat the SHL optimization above in cases where an extension
714*9880d681SAndroid Build Coastguard Worker // intervenes: (shl (anyext (shr x, c1)), c2) to
715*9880d681SAndroid Build Coastguard Worker // (shl (anyext x), c2-c1). This requires that the bottom c1 bits
716*9880d681SAndroid Build Coastguard Worker // aren't demanded (as above) and that the shifted upper c1 bits of
717*9880d681SAndroid Build Coastguard Worker // x aren't demanded.
718*9880d681SAndroid Build Coastguard Worker if (InOp.hasOneUse() &&
719*9880d681SAndroid Build Coastguard Worker InnerOp.getOpcode() == ISD::SRL &&
720*9880d681SAndroid Build Coastguard Worker InnerOp.hasOneUse() &&
721*9880d681SAndroid Build Coastguard Worker isa<ConstantSDNode>(InnerOp.getOperand(1))) {
722*9880d681SAndroid Build Coastguard Worker uint64_t InnerShAmt = cast<ConstantSDNode>(InnerOp.getOperand(1))
723*9880d681SAndroid Build Coastguard Worker ->getZExtValue();
724*9880d681SAndroid Build Coastguard Worker if (InnerShAmt < ShAmt &&
725*9880d681SAndroid Build Coastguard Worker InnerShAmt < InnerBits &&
726*9880d681SAndroid Build Coastguard Worker NewMask.lshr(InnerBits - InnerShAmt + ShAmt) == 0 &&
727*9880d681SAndroid Build Coastguard Worker NewMask.trunc(ShAmt) == 0) {
728*9880d681SAndroid Build Coastguard Worker SDValue NewSA =
729*9880d681SAndroid Build Coastguard Worker TLO.DAG.getConstant(ShAmt - InnerShAmt, dl,
730*9880d681SAndroid Build Coastguard Worker Op.getOperand(1).getValueType());
731*9880d681SAndroid Build Coastguard Worker EVT VT = Op.getValueType();
732*9880d681SAndroid Build Coastguard Worker SDValue NewExt = TLO.DAG.getNode(ISD::ANY_EXTEND, dl, VT,
733*9880d681SAndroid Build Coastguard Worker InnerOp.getOperand(0));
734*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SHL, dl, VT,
735*9880d681SAndroid Build Coastguard Worker NewExt, NewSA));
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker }
738*9880d681SAndroid Build Coastguard Worker }
739*9880d681SAndroid Build Coastguard Worker
740*9880d681SAndroid Build Coastguard Worker KnownZero <<= SA->getZExtValue();
741*9880d681SAndroid Build Coastguard Worker KnownOne <<= SA->getZExtValue();
742*9880d681SAndroid Build Coastguard Worker // low bits known zero.
743*9880d681SAndroid Build Coastguard Worker KnownZero |= APInt::getLowBitsSet(BitWidth, SA->getZExtValue());
744*9880d681SAndroid Build Coastguard Worker }
745*9880d681SAndroid Build Coastguard Worker break;
746*9880d681SAndroid Build Coastguard Worker case ISD::SRL:
747*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
748*9880d681SAndroid Build Coastguard Worker EVT VT = Op.getValueType();
749*9880d681SAndroid Build Coastguard Worker unsigned ShAmt = SA->getZExtValue();
750*9880d681SAndroid Build Coastguard Worker unsigned VTSize = VT.getSizeInBits();
751*9880d681SAndroid Build Coastguard Worker SDValue InOp = Op.getOperand(0);
752*9880d681SAndroid Build Coastguard Worker
753*9880d681SAndroid Build Coastguard Worker // If the shift count is an invalid immediate, don't do anything.
754*9880d681SAndroid Build Coastguard Worker if (ShAmt >= BitWidth)
755*9880d681SAndroid Build Coastguard Worker break;
756*9880d681SAndroid Build Coastguard Worker
757*9880d681SAndroid Build Coastguard Worker APInt InDemandedMask = (NewMask << ShAmt);
758*9880d681SAndroid Build Coastguard Worker
759*9880d681SAndroid Build Coastguard Worker // If the shift is exact, then it does demand the low bits (and knows that
760*9880d681SAndroid Build Coastguard Worker // they are zero).
761*9880d681SAndroid Build Coastguard Worker if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
762*9880d681SAndroid Build Coastguard Worker InDemandedMask |= APInt::getLowBitsSet(BitWidth, ShAmt);
763*9880d681SAndroid Build Coastguard Worker
764*9880d681SAndroid Build Coastguard Worker // If this is ((X << C1) >>u ShAmt), see if we can simplify this into a
765*9880d681SAndroid Build Coastguard Worker // single shift. We can do this if the top bits (which are shifted out)
766*9880d681SAndroid Build Coastguard Worker // are never demanded.
767*9880d681SAndroid Build Coastguard Worker if (InOp.getOpcode() == ISD::SHL &&
768*9880d681SAndroid Build Coastguard Worker isa<ConstantSDNode>(InOp.getOperand(1))) {
769*9880d681SAndroid Build Coastguard Worker if (ShAmt && (NewMask & APInt::getHighBitsSet(VTSize, ShAmt)) == 0) {
770*9880d681SAndroid Build Coastguard Worker unsigned C1= cast<ConstantSDNode>(InOp.getOperand(1))->getZExtValue();
771*9880d681SAndroid Build Coastguard Worker unsigned Opc = ISD::SRL;
772*9880d681SAndroid Build Coastguard Worker int Diff = ShAmt-C1;
773*9880d681SAndroid Build Coastguard Worker if (Diff < 0) {
774*9880d681SAndroid Build Coastguard Worker Diff = -Diff;
775*9880d681SAndroid Build Coastguard Worker Opc = ISD::SHL;
776*9880d681SAndroid Build Coastguard Worker }
777*9880d681SAndroid Build Coastguard Worker
778*9880d681SAndroid Build Coastguard Worker SDValue NewSA =
779*9880d681SAndroid Build Coastguard Worker TLO.DAG.getConstant(Diff, dl, Op.getOperand(1).getValueType());
780*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT,
781*9880d681SAndroid Build Coastguard Worker InOp.getOperand(0), NewSA));
782*9880d681SAndroid Build Coastguard Worker }
783*9880d681SAndroid Build Coastguard Worker }
784*9880d681SAndroid Build Coastguard Worker
785*9880d681SAndroid Build Coastguard Worker // Compute the new bits that are at the top now.
786*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(InOp, InDemandedMask,
787*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
788*9880d681SAndroid Build Coastguard Worker return true;
789*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
790*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZero.lshr(ShAmt);
791*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOne.lshr(ShAmt);
792*9880d681SAndroid Build Coastguard Worker
793*9880d681SAndroid Build Coastguard Worker APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
794*9880d681SAndroid Build Coastguard Worker KnownZero |= HighBits; // High bits known zero.
795*9880d681SAndroid Build Coastguard Worker }
796*9880d681SAndroid Build Coastguard Worker break;
797*9880d681SAndroid Build Coastguard Worker case ISD::SRA:
798*9880d681SAndroid Build Coastguard Worker // If this is an arithmetic shift right and only the low-bit is set, we can
799*9880d681SAndroid Build Coastguard Worker // always convert this into a logical shr, even if the shift amount is
800*9880d681SAndroid Build Coastguard Worker // variable. The low bit of the shift cannot be an input sign bit unless
801*9880d681SAndroid Build Coastguard Worker // the shift amount is >= the size of the datatype, which is undefined.
802*9880d681SAndroid Build Coastguard Worker if (NewMask == 1)
803*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op,
804*9880d681SAndroid Build Coastguard Worker TLO.DAG.getNode(ISD::SRL, dl, Op.getValueType(),
805*9880d681SAndroid Build Coastguard Worker Op.getOperand(0), Op.getOperand(1)));
806*9880d681SAndroid Build Coastguard Worker
807*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
808*9880d681SAndroid Build Coastguard Worker EVT VT = Op.getValueType();
809*9880d681SAndroid Build Coastguard Worker unsigned ShAmt = SA->getZExtValue();
810*9880d681SAndroid Build Coastguard Worker
811*9880d681SAndroid Build Coastguard Worker // If the shift count is an invalid immediate, don't do anything.
812*9880d681SAndroid Build Coastguard Worker if (ShAmt >= BitWidth)
813*9880d681SAndroid Build Coastguard Worker break;
814*9880d681SAndroid Build Coastguard Worker
815*9880d681SAndroid Build Coastguard Worker APInt InDemandedMask = (NewMask << ShAmt);
816*9880d681SAndroid Build Coastguard Worker
817*9880d681SAndroid Build Coastguard Worker // If the shift is exact, then it does demand the low bits (and knows that
818*9880d681SAndroid Build Coastguard Worker // they are zero).
819*9880d681SAndroid Build Coastguard Worker if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
820*9880d681SAndroid Build Coastguard Worker InDemandedMask |= APInt::getLowBitsSet(BitWidth, ShAmt);
821*9880d681SAndroid Build Coastguard Worker
822*9880d681SAndroid Build Coastguard Worker // If any of the demanded bits are produced by the sign extension, we also
823*9880d681SAndroid Build Coastguard Worker // demand the input sign bit.
824*9880d681SAndroid Build Coastguard Worker APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
825*9880d681SAndroid Build Coastguard Worker if (HighBits.intersects(NewMask))
826*9880d681SAndroid Build Coastguard Worker InDemandedMask |= APInt::getSignBit(VT.getScalarType().getSizeInBits());
827*9880d681SAndroid Build Coastguard Worker
828*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), InDemandedMask,
829*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
830*9880d681SAndroid Build Coastguard Worker return true;
831*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
832*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZero.lshr(ShAmt);
833*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOne.lshr(ShAmt);
834*9880d681SAndroid Build Coastguard Worker
835*9880d681SAndroid Build Coastguard Worker // Handle the sign bit, adjusted to where it is now in the mask.
836*9880d681SAndroid Build Coastguard Worker APInt SignBit = APInt::getSignBit(BitWidth).lshr(ShAmt);
837*9880d681SAndroid Build Coastguard Worker
838*9880d681SAndroid Build Coastguard Worker // If the input sign bit is known to be zero, or if none of the top bits
839*9880d681SAndroid Build Coastguard Worker // are demanded, turn this into an unsigned shift right.
840*9880d681SAndroid Build Coastguard Worker if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) {
841*9880d681SAndroid Build Coastguard Worker SDNodeFlags Flags;
842*9880d681SAndroid Build Coastguard Worker Flags.setExact(cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact());
843*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op,
844*9880d681SAndroid Build Coastguard Worker TLO.DAG.getNode(ISD::SRL, dl, VT, Op.getOperand(0),
845*9880d681SAndroid Build Coastguard Worker Op.getOperand(1), &Flags));
846*9880d681SAndroid Build Coastguard Worker }
847*9880d681SAndroid Build Coastguard Worker
848*9880d681SAndroid Build Coastguard Worker int Log2 = NewMask.exactLogBase2();
849*9880d681SAndroid Build Coastguard Worker if (Log2 >= 0) {
850*9880d681SAndroid Build Coastguard Worker // The bit must come from the sign.
851*9880d681SAndroid Build Coastguard Worker SDValue NewSA =
852*9880d681SAndroid Build Coastguard Worker TLO.DAG.getConstant(BitWidth - 1 - Log2, dl,
853*9880d681SAndroid Build Coastguard Worker Op.getOperand(1).getValueType());
854*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT,
855*9880d681SAndroid Build Coastguard Worker Op.getOperand(0), NewSA));
856*9880d681SAndroid Build Coastguard Worker }
857*9880d681SAndroid Build Coastguard Worker
858*9880d681SAndroid Build Coastguard Worker if (KnownOne.intersects(SignBit))
859*9880d681SAndroid Build Coastguard Worker // New bits are known one.
860*9880d681SAndroid Build Coastguard Worker KnownOne |= HighBits;
861*9880d681SAndroid Build Coastguard Worker }
862*9880d681SAndroid Build Coastguard Worker break;
863*9880d681SAndroid Build Coastguard Worker case ISD::SIGN_EXTEND_INREG: {
864*9880d681SAndroid Build Coastguard Worker EVT ExVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
865*9880d681SAndroid Build Coastguard Worker
866*9880d681SAndroid Build Coastguard Worker APInt MsbMask = APInt::getHighBitsSet(BitWidth, 1);
867*9880d681SAndroid Build Coastguard Worker // If we only care about the highest bit, don't bother shifting right.
868*9880d681SAndroid Build Coastguard Worker if (MsbMask == NewMask) {
869*9880d681SAndroid Build Coastguard Worker unsigned ShAmt = ExVT.getScalarType().getSizeInBits();
870*9880d681SAndroid Build Coastguard Worker SDValue InOp = Op.getOperand(0);
871*9880d681SAndroid Build Coastguard Worker unsigned VTBits = Op->getValueType(0).getScalarType().getSizeInBits();
872*9880d681SAndroid Build Coastguard Worker bool AlreadySignExtended =
873*9880d681SAndroid Build Coastguard Worker TLO.DAG.ComputeNumSignBits(InOp) >= VTBits-ShAmt+1;
874*9880d681SAndroid Build Coastguard Worker // However if the input is already sign extended we expect the sign
875*9880d681SAndroid Build Coastguard Worker // extension to be dropped altogether later and do not simplify.
876*9880d681SAndroid Build Coastguard Worker if (!AlreadySignExtended) {
877*9880d681SAndroid Build Coastguard Worker // Compute the correct shift amount type, which must be getShiftAmountTy
878*9880d681SAndroid Build Coastguard Worker // for scalar types after legalization.
879*9880d681SAndroid Build Coastguard Worker EVT ShiftAmtTy = Op.getValueType();
880*9880d681SAndroid Build Coastguard Worker if (TLO.LegalTypes() && !ShiftAmtTy.isVector())
881*9880d681SAndroid Build Coastguard Worker ShiftAmtTy = getShiftAmountTy(ShiftAmtTy, DL);
882*9880d681SAndroid Build Coastguard Worker
883*9880d681SAndroid Build Coastguard Worker SDValue ShiftAmt = TLO.DAG.getConstant(BitWidth - ShAmt, dl,
884*9880d681SAndroid Build Coastguard Worker ShiftAmtTy);
885*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SHL, dl,
886*9880d681SAndroid Build Coastguard Worker Op.getValueType(), InOp,
887*9880d681SAndroid Build Coastguard Worker ShiftAmt));
888*9880d681SAndroid Build Coastguard Worker }
889*9880d681SAndroid Build Coastguard Worker }
890*9880d681SAndroid Build Coastguard Worker
891*9880d681SAndroid Build Coastguard Worker // Sign extension. Compute the demanded bits in the result that are not
892*9880d681SAndroid Build Coastguard Worker // present in the input.
893*9880d681SAndroid Build Coastguard Worker APInt NewBits =
894*9880d681SAndroid Build Coastguard Worker APInt::getHighBitsSet(BitWidth,
895*9880d681SAndroid Build Coastguard Worker BitWidth - ExVT.getScalarType().getSizeInBits());
896*9880d681SAndroid Build Coastguard Worker
897*9880d681SAndroid Build Coastguard Worker // If none of the extended bits are demanded, eliminate the sextinreg.
898*9880d681SAndroid Build Coastguard Worker if ((NewBits & NewMask) == 0)
899*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, Op.getOperand(0));
900*9880d681SAndroid Build Coastguard Worker
901*9880d681SAndroid Build Coastguard Worker APInt InSignBit =
902*9880d681SAndroid Build Coastguard Worker APInt::getSignBit(ExVT.getScalarType().getSizeInBits()).zext(BitWidth);
903*9880d681SAndroid Build Coastguard Worker APInt InputDemandedBits =
904*9880d681SAndroid Build Coastguard Worker APInt::getLowBitsSet(BitWidth,
905*9880d681SAndroid Build Coastguard Worker ExVT.getScalarType().getSizeInBits()) &
906*9880d681SAndroid Build Coastguard Worker NewMask;
907*9880d681SAndroid Build Coastguard Worker
908*9880d681SAndroid Build Coastguard Worker // Since the sign extended bits are demanded, we know that the sign
909*9880d681SAndroid Build Coastguard Worker // bit is demanded.
910*9880d681SAndroid Build Coastguard Worker InputDemandedBits |= InSignBit;
911*9880d681SAndroid Build Coastguard Worker
912*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), InputDemandedBits,
913*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
914*9880d681SAndroid Build Coastguard Worker return true;
915*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
916*9880d681SAndroid Build Coastguard Worker
917*9880d681SAndroid Build Coastguard Worker // If the sign bit of the input is known set or clear, then we know the
918*9880d681SAndroid Build Coastguard Worker // top bits of the result.
919*9880d681SAndroid Build Coastguard Worker
920*9880d681SAndroid Build Coastguard Worker // If the input sign bit is known zero, convert this into a zero extension.
921*9880d681SAndroid Build Coastguard Worker if (KnownZero.intersects(InSignBit))
922*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op,
923*9880d681SAndroid Build Coastguard Worker TLO.DAG.getZeroExtendInReg(Op.getOperand(0),dl,ExVT));
924*9880d681SAndroid Build Coastguard Worker
925*9880d681SAndroid Build Coastguard Worker if (KnownOne.intersects(InSignBit)) { // Input sign bit known set
926*9880d681SAndroid Build Coastguard Worker KnownOne |= NewBits;
927*9880d681SAndroid Build Coastguard Worker KnownZero &= ~NewBits;
928*9880d681SAndroid Build Coastguard Worker } else { // Input sign bit unknown
929*9880d681SAndroid Build Coastguard Worker KnownZero &= ~NewBits;
930*9880d681SAndroid Build Coastguard Worker KnownOne &= ~NewBits;
931*9880d681SAndroid Build Coastguard Worker }
932*9880d681SAndroid Build Coastguard Worker break;
933*9880d681SAndroid Build Coastguard Worker }
934*9880d681SAndroid Build Coastguard Worker case ISD::BUILD_PAIR: {
935*9880d681SAndroid Build Coastguard Worker EVT HalfVT = Op.getOperand(0).getValueType();
936*9880d681SAndroid Build Coastguard Worker unsigned HalfBitWidth = HalfVT.getScalarSizeInBits();
937*9880d681SAndroid Build Coastguard Worker
938*9880d681SAndroid Build Coastguard Worker APInt MaskLo = NewMask.getLoBits(HalfBitWidth).trunc(HalfBitWidth);
939*9880d681SAndroid Build Coastguard Worker APInt MaskHi = NewMask.getHiBits(HalfBitWidth).trunc(HalfBitWidth);
940*9880d681SAndroid Build Coastguard Worker
941*9880d681SAndroid Build Coastguard Worker APInt KnownZeroLo, KnownOneLo;
942*9880d681SAndroid Build Coastguard Worker APInt KnownZeroHi, KnownOneHi;
943*9880d681SAndroid Build Coastguard Worker
944*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), MaskLo, KnownZeroLo,
945*9880d681SAndroid Build Coastguard Worker KnownOneLo, TLO, Depth + 1))
946*9880d681SAndroid Build Coastguard Worker return true;
947*9880d681SAndroid Build Coastguard Worker
948*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(1), MaskHi, KnownZeroHi,
949*9880d681SAndroid Build Coastguard Worker KnownOneHi, TLO, Depth + 1))
950*9880d681SAndroid Build Coastguard Worker return true;
951*9880d681SAndroid Build Coastguard Worker
952*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZeroLo.zext(BitWidth) |
953*9880d681SAndroid Build Coastguard Worker KnownZeroHi.zext(BitWidth).shl(HalfBitWidth);
954*9880d681SAndroid Build Coastguard Worker
955*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOneLo.zext(BitWidth) |
956*9880d681SAndroid Build Coastguard Worker KnownOneHi.zext(BitWidth).shl(HalfBitWidth);
957*9880d681SAndroid Build Coastguard Worker break;
958*9880d681SAndroid Build Coastguard Worker }
959*9880d681SAndroid Build Coastguard Worker case ISD::ZERO_EXTEND: {
960*9880d681SAndroid Build Coastguard Worker unsigned OperandBitWidth =
961*9880d681SAndroid Build Coastguard Worker Op.getOperand(0).getValueType().getScalarType().getSizeInBits();
962*9880d681SAndroid Build Coastguard Worker APInt InMask = NewMask.trunc(OperandBitWidth);
963*9880d681SAndroid Build Coastguard Worker
964*9880d681SAndroid Build Coastguard Worker // If none of the top bits are demanded, convert this into an any_extend.
965*9880d681SAndroid Build Coastguard Worker APInt NewBits =
966*9880d681SAndroid Build Coastguard Worker APInt::getHighBitsSet(BitWidth, BitWidth - OperandBitWidth) & NewMask;
967*9880d681SAndroid Build Coastguard Worker if (!NewBits.intersects(NewMask))
968*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND, dl,
969*9880d681SAndroid Build Coastguard Worker Op.getValueType(),
970*9880d681SAndroid Build Coastguard Worker Op.getOperand(0)));
971*9880d681SAndroid Build Coastguard Worker
972*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), InMask,
973*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
974*9880d681SAndroid Build Coastguard Worker return true;
975*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
976*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZero.zext(BitWidth);
977*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOne.zext(BitWidth);
978*9880d681SAndroid Build Coastguard Worker KnownZero |= NewBits;
979*9880d681SAndroid Build Coastguard Worker break;
980*9880d681SAndroid Build Coastguard Worker }
981*9880d681SAndroid Build Coastguard Worker case ISD::SIGN_EXTEND: {
982*9880d681SAndroid Build Coastguard Worker EVT InVT = Op.getOperand(0).getValueType();
983*9880d681SAndroid Build Coastguard Worker unsigned InBits = InVT.getScalarType().getSizeInBits();
984*9880d681SAndroid Build Coastguard Worker APInt InMask = APInt::getLowBitsSet(BitWidth, InBits);
985*9880d681SAndroid Build Coastguard Worker APInt InSignBit = APInt::getBitsSet(BitWidth, InBits - 1, InBits);
986*9880d681SAndroid Build Coastguard Worker APInt NewBits = ~InMask & NewMask;
987*9880d681SAndroid Build Coastguard Worker
988*9880d681SAndroid Build Coastguard Worker // If none of the top bits are demanded, convert this into an any_extend.
989*9880d681SAndroid Build Coastguard Worker if (NewBits == 0)
990*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op,TLO.DAG.getNode(ISD::ANY_EXTEND, dl,
991*9880d681SAndroid Build Coastguard Worker Op.getValueType(),
992*9880d681SAndroid Build Coastguard Worker Op.getOperand(0)));
993*9880d681SAndroid Build Coastguard Worker
994*9880d681SAndroid Build Coastguard Worker // Since some of the sign extended bits are demanded, we know that the sign
995*9880d681SAndroid Build Coastguard Worker // bit is demanded.
996*9880d681SAndroid Build Coastguard Worker APInt InDemandedBits = InMask & NewMask;
997*9880d681SAndroid Build Coastguard Worker InDemandedBits |= InSignBit;
998*9880d681SAndroid Build Coastguard Worker InDemandedBits = InDemandedBits.trunc(InBits);
999*9880d681SAndroid Build Coastguard Worker
1000*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), InDemandedBits, KnownZero,
1001*9880d681SAndroid Build Coastguard Worker KnownOne, TLO, Depth+1))
1002*9880d681SAndroid Build Coastguard Worker return true;
1003*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZero.zext(BitWidth);
1004*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOne.zext(BitWidth);
1005*9880d681SAndroid Build Coastguard Worker
1006*9880d681SAndroid Build Coastguard Worker // If the sign bit is known zero, convert this to a zero extend.
1007*9880d681SAndroid Build Coastguard Worker if (KnownZero.intersects(InSignBit))
1008*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, dl,
1009*9880d681SAndroid Build Coastguard Worker Op.getValueType(),
1010*9880d681SAndroid Build Coastguard Worker Op.getOperand(0)));
1011*9880d681SAndroid Build Coastguard Worker
1012*9880d681SAndroid Build Coastguard Worker // If the sign bit is known one, the top bits match.
1013*9880d681SAndroid Build Coastguard Worker if (KnownOne.intersects(InSignBit)) {
1014*9880d681SAndroid Build Coastguard Worker KnownOne |= NewBits;
1015*9880d681SAndroid Build Coastguard Worker assert((KnownZero & NewBits) == 0);
1016*9880d681SAndroid Build Coastguard Worker } else { // Otherwise, top bits aren't known.
1017*9880d681SAndroid Build Coastguard Worker assert((KnownOne & NewBits) == 0);
1018*9880d681SAndroid Build Coastguard Worker assert((KnownZero & NewBits) == 0);
1019*9880d681SAndroid Build Coastguard Worker }
1020*9880d681SAndroid Build Coastguard Worker break;
1021*9880d681SAndroid Build Coastguard Worker }
1022*9880d681SAndroid Build Coastguard Worker case ISD::ANY_EXTEND: {
1023*9880d681SAndroid Build Coastguard Worker unsigned OperandBitWidth =
1024*9880d681SAndroid Build Coastguard Worker Op.getOperand(0).getValueType().getScalarType().getSizeInBits();
1025*9880d681SAndroid Build Coastguard Worker APInt InMask = NewMask.trunc(OperandBitWidth);
1026*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), InMask,
1027*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
1028*9880d681SAndroid Build Coastguard Worker return true;
1029*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
1030*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZero.zext(BitWidth);
1031*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOne.zext(BitWidth);
1032*9880d681SAndroid Build Coastguard Worker break;
1033*9880d681SAndroid Build Coastguard Worker }
1034*9880d681SAndroid Build Coastguard Worker case ISD::TRUNCATE: {
1035*9880d681SAndroid Build Coastguard Worker // Simplify the input, using demanded bit information, and compute the known
1036*9880d681SAndroid Build Coastguard Worker // zero/one bits live out.
1037*9880d681SAndroid Build Coastguard Worker unsigned OperandBitWidth =
1038*9880d681SAndroid Build Coastguard Worker Op.getOperand(0).getValueType().getScalarType().getSizeInBits();
1039*9880d681SAndroid Build Coastguard Worker APInt TruncMask = NewMask.zext(OperandBitWidth);
1040*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), TruncMask,
1041*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
1042*9880d681SAndroid Build Coastguard Worker return true;
1043*9880d681SAndroid Build Coastguard Worker KnownZero = KnownZero.trunc(BitWidth);
1044*9880d681SAndroid Build Coastguard Worker KnownOne = KnownOne.trunc(BitWidth);
1045*9880d681SAndroid Build Coastguard Worker
1046*9880d681SAndroid Build Coastguard Worker // If the input is only used by this truncate, see if we can shrink it based
1047*9880d681SAndroid Build Coastguard Worker // on the known demanded bits.
1048*9880d681SAndroid Build Coastguard Worker if (Op.getOperand(0).getNode()->hasOneUse()) {
1049*9880d681SAndroid Build Coastguard Worker SDValue In = Op.getOperand(0);
1050*9880d681SAndroid Build Coastguard Worker switch (In.getOpcode()) {
1051*9880d681SAndroid Build Coastguard Worker default: break;
1052*9880d681SAndroid Build Coastguard Worker case ISD::SRL:
1053*9880d681SAndroid Build Coastguard Worker // Shrink SRL by a constant if none of the high bits shifted in are
1054*9880d681SAndroid Build Coastguard Worker // demanded.
1055*9880d681SAndroid Build Coastguard Worker if (TLO.LegalTypes() &&
1056*9880d681SAndroid Build Coastguard Worker !isTypeDesirableForOp(ISD::SRL, Op.getValueType()))
1057*9880d681SAndroid Build Coastguard Worker // Do not turn (vt1 truncate (vt2 srl)) into (vt1 srl) if vt1 is
1058*9880d681SAndroid Build Coastguard Worker // undesirable.
1059*9880d681SAndroid Build Coastguard Worker break;
1060*9880d681SAndroid Build Coastguard Worker ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(In.getOperand(1));
1061*9880d681SAndroid Build Coastguard Worker if (!ShAmt)
1062*9880d681SAndroid Build Coastguard Worker break;
1063*9880d681SAndroid Build Coastguard Worker SDValue Shift = In.getOperand(1);
1064*9880d681SAndroid Build Coastguard Worker if (TLO.LegalTypes()) {
1065*9880d681SAndroid Build Coastguard Worker uint64_t ShVal = ShAmt->getZExtValue();
1066*9880d681SAndroid Build Coastguard Worker Shift = TLO.DAG.getConstant(ShVal, dl,
1067*9880d681SAndroid Build Coastguard Worker getShiftAmountTy(Op.getValueType(), DL));
1068*9880d681SAndroid Build Coastguard Worker }
1069*9880d681SAndroid Build Coastguard Worker
1070*9880d681SAndroid Build Coastguard Worker APInt HighBits = APInt::getHighBitsSet(OperandBitWidth,
1071*9880d681SAndroid Build Coastguard Worker OperandBitWidth - BitWidth);
1072*9880d681SAndroid Build Coastguard Worker HighBits = HighBits.lshr(ShAmt->getZExtValue()).trunc(BitWidth);
1073*9880d681SAndroid Build Coastguard Worker
1074*9880d681SAndroid Build Coastguard Worker if (ShAmt->getZExtValue() < BitWidth && !(HighBits & NewMask)) {
1075*9880d681SAndroid Build Coastguard Worker // None of the shifted in bits are needed. Add a truncate of the
1076*9880d681SAndroid Build Coastguard Worker // shift input, then shift it.
1077*9880d681SAndroid Build Coastguard Worker SDValue NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, dl,
1078*9880d681SAndroid Build Coastguard Worker Op.getValueType(),
1079*9880d681SAndroid Build Coastguard Worker In.getOperand(0));
1080*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl,
1081*9880d681SAndroid Build Coastguard Worker Op.getValueType(),
1082*9880d681SAndroid Build Coastguard Worker NewTrunc,
1083*9880d681SAndroid Build Coastguard Worker Shift));
1084*9880d681SAndroid Build Coastguard Worker }
1085*9880d681SAndroid Build Coastguard Worker break;
1086*9880d681SAndroid Build Coastguard Worker }
1087*9880d681SAndroid Build Coastguard Worker }
1088*9880d681SAndroid Build Coastguard Worker
1089*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
1090*9880d681SAndroid Build Coastguard Worker break;
1091*9880d681SAndroid Build Coastguard Worker }
1092*9880d681SAndroid Build Coastguard Worker case ISD::AssertZext: {
1093*9880d681SAndroid Build Coastguard Worker // AssertZext demands all of the high bits, plus any of the low bits
1094*9880d681SAndroid Build Coastguard Worker // demanded by its users.
1095*9880d681SAndroid Build Coastguard Worker EVT VT = cast<VTSDNode>(Op.getOperand(1))->getVT();
1096*9880d681SAndroid Build Coastguard Worker APInt InMask = APInt::getLowBitsSet(BitWidth,
1097*9880d681SAndroid Build Coastguard Worker VT.getSizeInBits());
1098*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), ~InMask | NewMask,
1099*9880d681SAndroid Build Coastguard Worker KnownZero, KnownOne, TLO, Depth+1))
1100*9880d681SAndroid Build Coastguard Worker return true;
1101*9880d681SAndroid Build Coastguard Worker assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
1102*9880d681SAndroid Build Coastguard Worker
1103*9880d681SAndroid Build Coastguard Worker KnownZero |= ~InMask & NewMask;
1104*9880d681SAndroid Build Coastguard Worker break;
1105*9880d681SAndroid Build Coastguard Worker }
1106*9880d681SAndroid Build Coastguard Worker case ISD::BITCAST:
1107*9880d681SAndroid Build Coastguard Worker // If this is an FP->Int bitcast and if the sign bit is the only
1108*9880d681SAndroid Build Coastguard Worker // thing demanded, turn this into a FGETSIGN.
1109*9880d681SAndroid Build Coastguard Worker if (!TLO.LegalOperations() &&
1110*9880d681SAndroid Build Coastguard Worker !Op.getValueType().isVector() &&
1111*9880d681SAndroid Build Coastguard Worker !Op.getOperand(0).getValueType().isVector() &&
1112*9880d681SAndroid Build Coastguard Worker NewMask == APInt::getSignBit(Op.getValueType().getSizeInBits()) &&
1113*9880d681SAndroid Build Coastguard Worker Op.getOperand(0).getValueType().isFloatingPoint()) {
1114*9880d681SAndroid Build Coastguard Worker bool OpVTLegal = isOperationLegalOrCustom(ISD::FGETSIGN, Op.getValueType());
1115*9880d681SAndroid Build Coastguard Worker bool i32Legal = isOperationLegalOrCustom(ISD::FGETSIGN, MVT::i32);
1116*9880d681SAndroid Build Coastguard Worker if ((OpVTLegal || i32Legal) && Op.getValueType().isSimple() &&
1117*9880d681SAndroid Build Coastguard Worker Op.getOperand(0).getValueType() != MVT::f128) {
1118*9880d681SAndroid Build Coastguard Worker // Cannot eliminate/lower SHL for f128 yet.
1119*9880d681SAndroid Build Coastguard Worker EVT Ty = OpVTLegal ? Op.getValueType() : MVT::i32;
1120*9880d681SAndroid Build Coastguard Worker // Make a FGETSIGN + SHL to move the sign bit into the appropriate
1121*9880d681SAndroid Build Coastguard Worker // place. We expect the SHL to be eliminated by other optimizations.
1122*9880d681SAndroid Build Coastguard Worker SDValue Sign = TLO.DAG.getNode(ISD::FGETSIGN, dl, Ty, Op.getOperand(0));
1123*9880d681SAndroid Build Coastguard Worker unsigned OpVTSizeInBits = Op.getValueType().getSizeInBits();
1124*9880d681SAndroid Build Coastguard Worker if (!OpVTLegal && OpVTSizeInBits > 32)
1125*9880d681SAndroid Build Coastguard Worker Sign = TLO.DAG.getNode(ISD::ZERO_EXTEND, dl, Op.getValueType(), Sign);
1126*9880d681SAndroid Build Coastguard Worker unsigned ShVal = Op.getValueType().getSizeInBits()-1;
1127*9880d681SAndroid Build Coastguard Worker SDValue ShAmt = TLO.DAG.getConstant(ShVal, dl, Op.getValueType());
1128*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SHL, dl,
1129*9880d681SAndroid Build Coastguard Worker Op.getValueType(),
1130*9880d681SAndroid Build Coastguard Worker Sign, ShAmt));
1131*9880d681SAndroid Build Coastguard Worker }
1132*9880d681SAndroid Build Coastguard Worker }
1133*9880d681SAndroid Build Coastguard Worker break;
1134*9880d681SAndroid Build Coastguard Worker case ISD::ADD:
1135*9880d681SAndroid Build Coastguard Worker case ISD::MUL:
1136*9880d681SAndroid Build Coastguard Worker case ISD::SUB: {
1137*9880d681SAndroid Build Coastguard Worker // Add, Sub, and Mul don't demand any bits in positions beyond that
1138*9880d681SAndroid Build Coastguard Worker // of the highest bit demanded of them.
1139*9880d681SAndroid Build Coastguard Worker APInt LoMask = APInt::getLowBitsSet(BitWidth,
1140*9880d681SAndroid Build Coastguard Worker BitWidth - NewMask.countLeadingZeros());
1141*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(0), LoMask, KnownZero2,
1142*9880d681SAndroid Build Coastguard Worker KnownOne2, TLO, Depth+1))
1143*9880d681SAndroid Build Coastguard Worker return true;
1144*9880d681SAndroid Build Coastguard Worker if (SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2,
1145*9880d681SAndroid Build Coastguard Worker KnownOne2, TLO, Depth+1))
1146*9880d681SAndroid Build Coastguard Worker return true;
1147*9880d681SAndroid Build Coastguard Worker // See if the operation should be performed at a smaller bit width.
1148*9880d681SAndroid Build Coastguard Worker if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl))
1149*9880d681SAndroid Build Coastguard Worker return true;
1150*9880d681SAndroid Build Coastguard Worker }
1151*9880d681SAndroid Build Coastguard Worker // FALL THROUGH
1152*9880d681SAndroid Build Coastguard Worker default:
1153*9880d681SAndroid Build Coastguard Worker // Just use computeKnownBits to compute output bits.
1154*9880d681SAndroid Build Coastguard Worker TLO.DAG.computeKnownBits(Op, KnownZero, KnownOne, Depth);
1155*9880d681SAndroid Build Coastguard Worker break;
1156*9880d681SAndroid Build Coastguard Worker }
1157*9880d681SAndroid Build Coastguard Worker
1158*9880d681SAndroid Build Coastguard Worker // If we know the value of all of the demanded bits, return this as a
1159*9880d681SAndroid Build Coastguard Worker // constant.
1160*9880d681SAndroid Build Coastguard Worker if ((NewMask & (KnownZero|KnownOne)) == NewMask) {
1161*9880d681SAndroid Build Coastguard Worker // Avoid folding to a constant if any OpaqueConstant is involved.
1162*9880d681SAndroid Build Coastguard Worker const SDNode *N = Op.getNode();
1163*9880d681SAndroid Build Coastguard Worker for (SDNodeIterator I = SDNodeIterator::begin(N),
1164*9880d681SAndroid Build Coastguard Worker E = SDNodeIterator::end(N); I != E; ++I) {
1165*9880d681SAndroid Build Coastguard Worker SDNode *Op = *I;
1166*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op))
1167*9880d681SAndroid Build Coastguard Worker if (C->isOpaque())
1168*9880d681SAndroid Build Coastguard Worker return false;
1169*9880d681SAndroid Build Coastguard Worker }
1170*9880d681SAndroid Build Coastguard Worker return TLO.CombineTo(Op,
1171*9880d681SAndroid Build Coastguard Worker TLO.DAG.getConstant(KnownOne, dl, Op.getValueType()));
1172*9880d681SAndroid Build Coastguard Worker }
1173*9880d681SAndroid Build Coastguard Worker
1174*9880d681SAndroid Build Coastguard Worker return false;
1175*9880d681SAndroid Build Coastguard Worker }
1176*9880d681SAndroid Build Coastguard Worker
1177*9880d681SAndroid Build Coastguard Worker /// Determine which of the bits specified in Mask are known to be either zero or
1178*9880d681SAndroid Build Coastguard Worker /// one and return them in the KnownZero/KnownOne bitsets.
computeKnownBitsForTargetNode(const SDValue Op,APInt & KnownZero,APInt & KnownOne,const SelectionDAG & DAG,unsigned Depth) const1179*9880d681SAndroid Build Coastguard Worker void TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1180*9880d681SAndroid Build Coastguard Worker APInt &KnownZero,
1181*9880d681SAndroid Build Coastguard Worker APInt &KnownOne,
1182*9880d681SAndroid Build Coastguard Worker const SelectionDAG &DAG,
1183*9880d681SAndroid Build Coastguard Worker unsigned Depth) const {
1184*9880d681SAndroid Build Coastguard Worker assert((Op.getOpcode() >= ISD::BUILTIN_OP_END ||
1185*9880d681SAndroid Build Coastguard Worker Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
1186*9880d681SAndroid Build Coastguard Worker Op.getOpcode() == ISD::INTRINSIC_W_CHAIN ||
1187*9880d681SAndroid Build Coastguard Worker Op.getOpcode() == ISD::INTRINSIC_VOID) &&
1188*9880d681SAndroid Build Coastguard Worker "Should use MaskedValueIsZero if you don't know whether Op"
1189*9880d681SAndroid Build Coastguard Worker " is a target node!");
1190*9880d681SAndroid Build Coastguard Worker KnownZero = KnownOne = APInt(KnownOne.getBitWidth(), 0);
1191*9880d681SAndroid Build Coastguard Worker }
1192*9880d681SAndroid Build Coastguard Worker
1193*9880d681SAndroid Build Coastguard Worker /// This method can be implemented by targets that want to expose additional
1194*9880d681SAndroid Build Coastguard Worker /// information about sign bits to the DAG Combiner.
ComputeNumSignBitsForTargetNode(SDValue Op,const SelectionDAG &,unsigned Depth) const1195*9880d681SAndroid Build Coastguard Worker unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
1196*9880d681SAndroid Build Coastguard Worker const SelectionDAG &,
1197*9880d681SAndroid Build Coastguard Worker unsigned Depth) const {
1198*9880d681SAndroid Build Coastguard Worker assert((Op.getOpcode() >= ISD::BUILTIN_OP_END ||
1199*9880d681SAndroid Build Coastguard Worker Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
1200*9880d681SAndroid Build Coastguard Worker Op.getOpcode() == ISD::INTRINSIC_W_CHAIN ||
1201*9880d681SAndroid Build Coastguard Worker Op.getOpcode() == ISD::INTRINSIC_VOID) &&
1202*9880d681SAndroid Build Coastguard Worker "Should use ComputeNumSignBits if you don't know whether Op"
1203*9880d681SAndroid Build Coastguard Worker " is a target node!");
1204*9880d681SAndroid Build Coastguard Worker return 1;
1205*9880d681SAndroid Build Coastguard Worker }
1206*9880d681SAndroid Build Coastguard Worker
isConstTrueVal(const SDNode * N) const1207*9880d681SAndroid Build Coastguard Worker bool TargetLowering::isConstTrueVal(const SDNode *N) const {
1208*9880d681SAndroid Build Coastguard Worker if (!N)
1209*9880d681SAndroid Build Coastguard Worker return false;
1210*9880d681SAndroid Build Coastguard Worker
1211*9880d681SAndroid Build Coastguard Worker const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
1212*9880d681SAndroid Build Coastguard Worker if (!CN) {
1213*9880d681SAndroid Build Coastguard Worker const BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N);
1214*9880d681SAndroid Build Coastguard Worker if (!BV)
1215*9880d681SAndroid Build Coastguard Worker return false;
1216*9880d681SAndroid Build Coastguard Worker
1217*9880d681SAndroid Build Coastguard Worker BitVector UndefElements;
1218*9880d681SAndroid Build Coastguard Worker CN = BV->getConstantSplatNode(&UndefElements);
1219*9880d681SAndroid Build Coastguard Worker // Only interested in constant splats, and we don't try to handle undef
1220*9880d681SAndroid Build Coastguard Worker // elements in identifying boolean constants.
1221*9880d681SAndroid Build Coastguard Worker if (!CN || UndefElements.none())
1222*9880d681SAndroid Build Coastguard Worker return false;
1223*9880d681SAndroid Build Coastguard Worker }
1224*9880d681SAndroid Build Coastguard Worker
1225*9880d681SAndroid Build Coastguard Worker switch (getBooleanContents(N->getValueType(0))) {
1226*9880d681SAndroid Build Coastguard Worker case UndefinedBooleanContent:
1227*9880d681SAndroid Build Coastguard Worker return CN->getAPIntValue()[0];
1228*9880d681SAndroid Build Coastguard Worker case ZeroOrOneBooleanContent:
1229*9880d681SAndroid Build Coastguard Worker return CN->isOne();
1230*9880d681SAndroid Build Coastguard Worker case ZeroOrNegativeOneBooleanContent:
1231*9880d681SAndroid Build Coastguard Worker return CN->isAllOnesValue();
1232*9880d681SAndroid Build Coastguard Worker }
1233*9880d681SAndroid Build Coastguard Worker
1234*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid boolean contents");
1235*9880d681SAndroid Build Coastguard Worker }
1236*9880d681SAndroid Build Coastguard Worker
isConstFalseVal(const SDNode * N) const1237*9880d681SAndroid Build Coastguard Worker bool TargetLowering::isConstFalseVal(const SDNode *N) const {
1238*9880d681SAndroid Build Coastguard Worker if (!N)
1239*9880d681SAndroid Build Coastguard Worker return false;
1240*9880d681SAndroid Build Coastguard Worker
1241*9880d681SAndroid Build Coastguard Worker const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
1242*9880d681SAndroid Build Coastguard Worker if (!CN) {
1243*9880d681SAndroid Build Coastguard Worker const BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N);
1244*9880d681SAndroid Build Coastguard Worker if (!BV)
1245*9880d681SAndroid Build Coastguard Worker return false;
1246*9880d681SAndroid Build Coastguard Worker
1247*9880d681SAndroid Build Coastguard Worker BitVector UndefElements;
1248*9880d681SAndroid Build Coastguard Worker CN = BV->getConstantSplatNode(&UndefElements);
1249*9880d681SAndroid Build Coastguard Worker // Only interested in constant splats, and we don't try to handle undef
1250*9880d681SAndroid Build Coastguard Worker // elements in identifying boolean constants.
1251*9880d681SAndroid Build Coastguard Worker if (!CN || UndefElements.none())
1252*9880d681SAndroid Build Coastguard Worker return false;
1253*9880d681SAndroid Build Coastguard Worker }
1254*9880d681SAndroid Build Coastguard Worker
1255*9880d681SAndroid Build Coastguard Worker if (getBooleanContents(N->getValueType(0)) == UndefinedBooleanContent)
1256*9880d681SAndroid Build Coastguard Worker return !CN->getAPIntValue()[0];
1257*9880d681SAndroid Build Coastguard Worker
1258*9880d681SAndroid Build Coastguard Worker return CN->isNullValue();
1259*9880d681SAndroid Build Coastguard Worker }
1260*9880d681SAndroid Build Coastguard Worker
isExtendedTrueVal(const ConstantSDNode * N,EVT VT,bool SExt) const1261*9880d681SAndroid Build Coastguard Worker bool TargetLowering::isExtendedTrueVal(const ConstantSDNode *N, EVT VT,
1262*9880d681SAndroid Build Coastguard Worker bool SExt) const {
1263*9880d681SAndroid Build Coastguard Worker if (VT == MVT::i1)
1264*9880d681SAndroid Build Coastguard Worker return N->isOne();
1265*9880d681SAndroid Build Coastguard Worker
1266*9880d681SAndroid Build Coastguard Worker TargetLowering::BooleanContent Cnt = getBooleanContents(VT);
1267*9880d681SAndroid Build Coastguard Worker switch (Cnt) {
1268*9880d681SAndroid Build Coastguard Worker case TargetLowering::ZeroOrOneBooleanContent:
1269*9880d681SAndroid Build Coastguard Worker // An extended value of 1 is always true, unless its original type is i1,
1270*9880d681SAndroid Build Coastguard Worker // in which case it will be sign extended to -1.
1271*9880d681SAndroid Build Coastguard Worker return (N->isOne() && !SExt) || (SExt && (N->getValueType(0) != MVT::i1));
1272*9880d681SAndroid Build Coastguard Worker case TargetLowering::UndefinedBooleanContent:
1273*9880d681SAndroid Build Coastguard Worker case TargetLowering::ZeroOrNegativeOneBooleanContent:
1274*9880d681SAndroid Build Coastguard Worker return N->isAllOnesValue() && SExt;
1275*9880d681SAndroid Build Coastguard Worker }
1276*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected enumeration.");
1277*9880d681SAndroid Build Coastguard Worker }
1278*9880d681SAndroid Build Coastguard Worker
1279*9880d681SAndroid Build Coastguard Worker /// This helper function of SimplifySetCC tries to optimize the comparison when
1280*9880d681SAndroid Build Coastguard Worker /// either operand of the SetCC node is a bitwise-and instruction.
simplifySetCCWithAnd(EVT VT,SDValue N0,SDValue N1,ISD::CondCode Cond,DAGCombinerInfo & DCI,const SDLoc & DL) const1281*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::simplifySetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
1282*9880d681SAndroid Build Coastguard Worker ISD::CondCode Cond,
1283*9880d681SAndroid Build Coastguard Worker DAGCombinerInfo &DCI,
1284*9880d681SAndroid Build Coastguard Worker const SDLoc &DL) const {
1285*9880d681SAndroid Build Coastguard Worker // Match these patterns in any of their permutations:
1286*9880d681SAndroid Build Coastguard Worker // (X & Y) == Y
1287*9880d681SAndroid Build Coastguard Worker // (X & Y) != Y
1288*9880d681SAndroid Build Coastguard Worker if (N1.getOpcode() == ISD::AND && N0.getOpcode() != ISD::AND)
1289*9880d681SAndroid Build Coastguard Worker std::swap(N0, N1);
1290*9880d681SAndroid Build Coastguard Worker
1291*9880d681SAndroid Build Coastguard Worker EVT OpVT = N0.getValueType();
1292*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() != ISD::AND || !OpVT.isInteger() ||
1293*9880d681SAndroid Build Coastguard Worker (Cond != ISD::SETEQ && Cond != ISD::SETNE))
1294*9880d681SAndroid Build Coastguard Worker return SDValue();
1295*9880d681SAndroid Build Coastguard Worker
1296*9880d681SAndroid Build Coastguard Worker SDValue X, Y;
1297*9880d681SAndroid Build Coastguard Worker if (N0.getOperand(0) == N1) {
1298*9880d681SAndroid Build Coastguard Worker X = N0.getOperand(1);
1299*9880d681SAndroid Build Coastguard Worker Y = N0.getOperand(0);
1300*9880d681SAndroid Build Coastguard Worker } else if (N0.getOperand(1) == N1) {
1301*9880d681SAndroid Build Coastguard Worker X = N0.getOperand(0);
1302*9880d681SAndroid Build Coastguard Worker Y = N0.getOperand(1);
1303*9880d681SAndroid Build Coastguard Worker } else {
1304*9880d681SAndroid Build Coastguard Worker return SDValue();
1305*9880d681SAndroid Build Coastguard Worker }
1306*9880d681SAndroid Build Coastguard Worker
1307*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG = DCI.DAG;
1308*9880d681SAndroid Build Coastguard Worker SDValue Zero = DAG.getConstant(0, DL, OpVT);
1309*9880d681SAndroid Build Coastguard Worker if (DAG.isKnownToBeAPowerOfTwo(Y)) {
1310*9880d681SAndroid Build Coastguard Worker // Simplify X & Y == Y to X & Y != 0 if Y has exactly one bit set.
1311*9880d681SAndroid Build Coastguard Worker // Note that where Y is variable and is known to have at most one bit set
1312*9880d681SAndroid Build Coastguard Worker // (for example, if it is Z & 1) we cannot do this; the expressions are not
1313*9880d681SAndroid Build Coastguard Worker // equivalent when Y == 0.
1314*9880d681SAndroid Build Coastguard Worker Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
1315*9880d681SAndroid Build Coastguard Worker if (DCI.isBeforeLegalizeOps() ||
1316*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(Cond, N0.getSimpleValueType()))
1317*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(DL, VT, N0, Zero, Cond);
1318*9880d681SAndroid Build Coastguard Worker } else if (N0.hasOneUse() && hasAndNotCompare(Y)) {
1319*9880d681SAndroid Build Coastguard Worker // If the target supports an 'and-not' or 'and-complement' logic operation,
1320*9880d681SAndroid Build Coastguard Worker // try to use that to make a comparison operation more efficient.
1321*9880d681SAndroid Build Coastguard Worker // But don't do this transform if the mask is a single bit because there are
1322*9880d681SAndroid Build Coastguard Worker // more efficient ways to deal with that case (for example, 'bt' on x86 or
1323*9880d681SAndroid Build Coastguard Worker // 'rlwinm' on PPC).
1324*9880d681SAndroid Build Coastguard Worker
1325*9880d681SAndroid Build Coastguard Worker // Bail out if the compare operand that we want to turn into a zero is
1326*9880d681SAndroid Build Coastguard Worker // already a zero (otherwise, infinite loop).
1327*9880d681SAndroid Build Coastguard Worker auto *YConst = dyn_cast<ConstantSDNode>(Y);
1328*9880d681SAndroid Build Coastguard Worker if (YConst && YConst->isNullValue())
1329*9880d681SAndroid Build Coastguard Worker return SDValue();
1330*9880d681SAndroid Build Coastguard Worker
1331*9880d681SAndroid Build Coastguard Worker // Transform this into: ~X & Y == 0.
1332*9880d681SAndroid Build Coastguard Worker SDValue NotX = DAG.getNOT(SDLoc(X), X, OpVT);
1333*9880d681SAndroid Build Coastguard Worker SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, NotX, Y);
1334*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(DL, VT, NewAnd, Zero, Cond);
1335*9880d681SAndroid Build Coastguard Worker }
1336*9880d681SAndroid Build Coastguard Worker
1337*9880d681SAndroid Build Coastguard Worker return SDValue();
1338*9880d681SAndroid Build Coastguard Worker }
1339*9880d681SAndroid Build Coastguard Worker
1340*9880d681SAndroid Build Coastguard Worker /// Try to simplify a setcc built with the specified operands and cc. If it is
1341*9880d681SAndroid Build Coastguard Worker /// unable to simplify it, return a null SDValue.
SimplifySetCC(EVT VT,SDValue N0,SDValue N1,ISD::CondCode Cond,bool foldBooleans,DAGCombinerInfo & DCI,const SDLoc & dl) const1342*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
1343*9880d681SAndroid Build Coastguard Worker ISD::CondCode Cond, bool foldBooleans,
1344*9880d681SAndroid Build Coastguard Worker DAGCombinerInfo &DCI,
1345*9880d681SAndroid Build Coastguard Worker const SDLoc &dl) const {
1346*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG = DCI.DAG;
1347*9880d681SAndroid Build Coastguard Worker
1348*9880d681SAndroid Build Coastguard Worker // These setcc operations always fold.
1349*9880d681SAndroid Build Coastguard Worker switch (Cond) {
1350*9880d681SAndroid Build Coastguard Worker default: break;
1351*9880d681SAndroid Build Coastguard Worker case ISD::SETFALSE:
1352*9880d681SAndroid Build Coastguard Worker case ISD::SETFALSE2: return DAG.getConstant(0, dl, VT);
1353*9880d681SAndroid Build Coastguard Worker case ISD::SETTRUE:
1354*9880d681SAndroid Build Coastguard Worker case ISD::SETTRUE2: {
1355*9880d681SAndroid Build Coastguard Worker TargetLowering::BooleanContent Cnt =
1356*9880d681SAndroid Build Coastguard Worker getBooleanContents(N0->getValueType(0));
1357*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(
1358*9880d681SAndroid Build Coastguard Worker Cnt == TargetLowering::ZeroOrNegativeOneBooleanContent ? -1ULL : 1, dl,
1359*9880d681SAndroid Build Coastguard Worker VT);
1360*9880d681SAndroid Build Coastguard Worker }
1361*9880d681SAndroid Build Coastguard Worker }
1362*9880d681SAndroid Build Coastguard Worker
1363*9880d681SAndroid Build Coastguard Worker // Ensure that the constant occurs on the RHS, and fold constant
1364*9880d681SAndroid Build Coastguard Worker // comparisons.
1365*9880d681SAndroid Build Coastguard Worker ISD::CondCode SwappedCC = ISD::getSetCCSwappedOperands(Cond);
1366*9880d681SAndroid Build Coastguard Worker if (isa<ConstantSDNode>(N0.getNode()) &&
1367*9880d681SAndroid Build Coastguard Worker (DCI.isBeforeLegalizeOps() ||
1368*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(SwappedCC, N0.getSimpleValueType())))
1369*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N1, N0, SwappedCC);
1370*9880d681SAndroid Build Coastguard Worker
1371*9880d681SAndroid Build Coastguard Worker if (auto *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
1372*9880d681SAndroid Build Coastguard Worker const APInt &C1 = N1C->getAPIntValue();
1373*9880d681SAndroid Build Coastguard Worker
1374*9880d681SAndroid Build Coastguard Worker // If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an
1375*9880d681SAndroid Build Coastguard Worker // equality comparison, then we're just comparing whether X itself is
1376*9880d681SAndroid Build Coastguard Worker // zero.
1377*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::SRL && (C1 == 0 || C1 == 1) &&
1378*9880d681SAndroid Build Coastguard Worker N0.getOperand(0).getOpcode() == ISD::CTLZ &&
1379*9880d681SAndroid Build Coastguard Worker N0.getOperand(1).getOpcode() == ISD::Constant) {
1380*9880d681SAndroid Build Coastguard Worker const APInt &ShAmt
1381*9880d681SAndroid Build Coastguard Worker = cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue();
1382*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
1383*9880d681SAndroid Build Coastguard Worker ShAmt == Log2_32(N0.getValueType().getSizeInBits())) {
1384*9880d681SAndroid Build Coastguard Worker if ((C1 == 0) == (Cond == ISD::SETEQ)) {
1385*9880d681SAndroid Build Coastguard Worker // (srl (ctlz x), 5) == 0 -> X != 0
1386*9880d681SAndroid Build Coastguard Worker // (srl (ctlz x), 5) != 1 -> X != 0
1387*9880d681SAndroid Build Coastguard Worker Cond = ISD::SETNE;
1388*9880d681SAndroid Build Coastguard Worker } else {
1389*9880d681SAndroid Build Coastguard Worker // (srl (ctlz x), 5) != 0 -> X == 0
1390*9880d681SAndroid Build Coastguard Worker // (srl (ctlz x), 5) == 1 -> X == 0
1391*9880d681SAndroid Build Coastguard Worker Cond = ISD::SETEQ;
1392*9880d681SAndroid Build Coastguard Worker }
1393*9880d681SAndroid Build Coastguard Worker SDValue Zero = DAG.getConstant(0, dl, N0.getValueType());
1394*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(0).getOperand(0),
1395*9880d681SAndroid Build Coastguard Worker Zero, Cond);
1396*9880d681SAndroid Build Coastguard Worker }
1397*9880d681SAndroid Build Coastguard Worker }
1398*9880d681SAndroid Build Coastguard Worker
1399*9880d681SAndroid Build Coastguard Worker SDValue CTPOP = N0;
1400*9880d681SAndroid Build Coastguard Worker // Look through truncs that don't change the value of a ctpop.
1401*9880d681SAndroid Build Coastguard Worker if (N0.hasOneUse() && N0.getOpcode() == ISD::TRUNCATE)
1402*9880d681SAndroid Build Coastguard Worker CTPOP = N0.getOperand(0);
1403*9880d681SAndroid Build Coastguard Worker
1404*9880d681SAndroid Build Coastguard Worker if (CTPOP.hasOneUse() && CTPOP.getOpcode() == ISD::CTPOP &&
1405*9880d681SAndroid Build Coastguard Worker (N0 == CTPOP || N0.getValueType().getSizeInBits() >
1406*9880d681SAndroid Build Coastguard Worker Log2_32_Ceil(CTPOP.getValueType().getSizeInBits()))) {
1407*9880d681SAndroid Build Coastguard Worker EVT CTVT = CTPOP.getValueType();
1408*9880d681SAndroid Build Coastguard Worker SDValue CTOp = CTPOP.getOperand(0);
1409*9880d681SAndroid Build Coastguard Worker
1410*9880d681SAndroid Build Coastguard Worker // (ctpop x) u< 2 -> (x & x-1) == 0
1411*9880d681SAndroid Build Coastguard Worker // (ctpop x) u> 1 -> (x & x-1) != 0
1412*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETULT && C1 == 2) || (Cond == ISD::SETUGT && C1 == 1)){
1413*9880d681SAndroid Build Coastguard Worker SDValue Sub = DAG.getNode(ISD::SUB, dl, CTVT, CTOp,
1414*9880d681SAndroid Build Coastguard Worker DAG.getConstant(1, dl, CTVT));
1415*9880d681SAndroid Build Coastguard Worker SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Sub);
1416*9880d681SAndroid Build Coastguard Worker ISD::CondCode CC = Cond == ISD::SETULT ? ISD::SETEQ : ISD::SETNE;
1417*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, And, DAG.getConstant(0, dl, CTVT), CC);
1418*9880d681SAndroid Build Coastguard Worker }
1419*9880d681SAndroid Build Coastguard Worker
1420*9880d681SAndroid Build Coastguard Worker // TODO: (ctpop x) == 1 -> x && (x & x-1) == 0 iff ctpop is illegal.
1421*9880d681SAndroid Build Coastguard Worker }
1422*9880d681SAndroid Build Coastguard Worker
1423*9880d681SAndroid Build Coastguard Worker // (zext x) == C --> x == (trunc C)
1424*9880d681SAndroid Build Coastguard Worker // (sext x) == C --> x == (trunc C)
1425*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
1426*9880d681SAndroid Build Coastguard Worker DCI.isBeforeLegalize() && N0->hasOneUse()) {
1427*9880d681SAndroid Build Coastguard Worker unsigned MinBits = N0.getValueSizeInBits();
1428*9880d681SAndroid Build Coastguard Worker SDValue PreExt;
1429*9880d681SAndroid Build Coastguard Worker bool Signed = false;
1430*9880d681SAndroid Build Coastguard Worker if (N0->getOpcode() == ISD::ZERO_EXTEND) {
1431*9880d681SAndroid Build Coastguard Worker // ZExt
1432*9880d681SAndroid Build Coastguard Worker MinBits = N0->getOperand(0).getValueSizeInBits();
1433*9880d681SAndroid Build Coastguard Worker PreExt = N0->getOperand(0);
1434*9880d681SAndroid Build Coastguard Worker } else if (N0->getOpcode() == ISD::AND) {
1435*9880d681SAndroid Build Coastguard Worker // DAGCombine turns costly ZExts into ANDs
1436*9880d681SAndroid Build Coastguard Worker if (auto *C = dyn_cast<ConstantSDNode>(N0->getOperand(1)))
1437*9880d681SAndroid Build Coastguard Worker if ((C->getAPIntValue()+1).isPowerOf2()) {
1438*9880d681SAndroid Build Coastguard Worker MinBits = C->getAPIntValue().countTrailingOnes();
1439*9880d681SAndroid Build Coastguard Worker PreExt = N0->getOperand(0);
1440*9880d681SAndroid Build Coastguard Worker }
1441*9880d681SAndroid Build Coastguard Worker } else if (N0->getOpcode() == ISD::SIGN_EXTEND) {
1442*9880d681SAndroid Build Coastguard Worker // SExt
1443*9880d681SAndroid Build Coastguard Worker MinBits = N0->getOperand(0).getValueSizeInBits();
1444*9880d681SAndroid Build Coastguard Worker PreExt = N0->getOperand(0);
1445*9880d681SAndroid Build Coastguard Worker Signed = true;
1446*9880d681SAndroid Build Coastguard Worker } else if (auto *LN0 = dyn_cast<LoadSDNode>(N0)) {
1447*9880d681SAndroid Build Coastguard Worker // ZEXTLOAD / SEXTLOAD
1448*9880d681SAndroid Build Coastguard Worker if (LN0->getExtensionType() == ISD::ZEXTLOAD) {
1449*9880d681SAndroid Build Coastguard Worker MinBits = LN0->getMemoryVT().getSizeInBits();
1450*9880d681SAndroid Build Coastguard Worker PreExt = N0;
1451*9880d681SAndroid Build Coastguard Worker } else if (LN0->getExtensionType() == ISD::SEXTLOAD) {
1452*9880d681SAndroid Build Coastguard Worker Signed = true;
1453*9880d681SAndroid Build Coastguard Worker MinBits = LN0->getMemoryVT().getSizeInBits();
1454*9880d681SAndroid Build Coastguard Worker PreExt = N0;
1455*9880d681SAndroid Build Coastguard Worker }
1456*9880d681SAndroid Build Coastguard Worker }
1457*9880d681SAndroid Build Coastguard Worker
1458*9880d681SAndroid Build Coastguard Worker // Figure out how many bits we need to preserve this constant.
1459*9880d681SAndroid Build Coastguard Worker unsigned ReqdBits = Signed ?
1460*9880d681SAndroid Build Coastguard Worker C1.getBitWidth() - C1.getNumSignBits() + 1 :
1461*9880d681SAndroid Build Coastguard Worker C1.getActiveBits();
1462*9880d681SAndroid Build Coastguard Worker
1463*9880d681SAndroid Build Coastguard Worker // Make sure we're not losing bits from the constant.
1464*9880d681SAndroid Build Coastguard Worker if (MinBits > 0 &&
1465*9880d681SAndroid Build Coastguard Worker MinBits < C1.getBitWidth() &&
1466*9880d681SAndroid Build Coastguard Worker MinBits >= ReqdBits) {
1467*9880d681SAndroid Build Coastguard Worker EVT MinVT = EVT::getIntegerVT(*DAG.getContext(), MinBits);
1468*9880d681SAndroid Build Coastguard Worker if (isTypeDesirableForOp(ISD::SETCC, MinVT)) {
1469*9880d681SAndroid Build Coastguard Worker // Will get folded away.
1470*9880d681SAndroid Build Coastguard Worker SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MinVT, PreExt);
1471*9880d681SAndroid Build Coastguard Worker SDValue C = DAG.getConstant(C1.trunc(MinBits), dl, MinVT);
1472*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, Trunc, C, Cond);
1473*9880d681SAndroid Build Coastguard Worker }
1474*9880d681SAndroid Build Coastguard Worker
1475*9880d681SAndroid Build Coastguard Worker // If truncating the setcc operands is not desirable, we can still
1476*9880d681SAndroid Build Coastguard Worker // simplify the expression in some cases:
1477*9880d681SAndroid Build Coastguard Worker // setcc ([sz]ext (setcc x, y, cc)), 0, setne) -> setcc (x, y, cc)
1478*9880d681SAndroid Build Coastguard Worker // setcc ([sz]ext (setcc x, y, cc)), 0, seteq) -> setcc (x, y, inv(cc))
1479*9880d681SAndroid Build Coastguard Worker // setcc (zext (setcc x, y, cc)), 1, setne) -> setcc (x, y, inv(cc))
1480*9880d681SAndroid Build Coastguard Worker // setcc (zext (setcc x, y, cc)), 1, seteq) -> setcc (x, y, cc)
1481*9880d681SAndroid Build Coastguard Worker // setcc (sext (setcc x, y, cc)), -1, setne) -> setcc (x, y, inv(cc))
1482*9880d681SAndroid Build Coastguard Worker // setcc (sext (setcc x, y, cc)), -1, seteq) -> setcc (x, y, cc)
1483*9880d681SAndroid Build Coastguard Worker SDValue TopSetCC = N0->getOperand(0);
1484*9880d681SAndroid Build Coastguard Worker unsigned N0Opc = N0->getOpcode();
1485*9880d681SAndroid Build Coastguard Worker bool SExt = (N0Opc == ISD::SIGN_EXTEND);
1486*9880d681SAndroid Build Coastguard Worker if (TopSetCC.getValueType() == MVT::i1 && VT == MVT::i1 &&
1487*9880d681SAndroid Build Coastguard Worker TopSetCC.getOpcode() == ISD::SETCC &&
1488*9880d681SAndroid Build Coastguard Worker (N0Opc == ISD::ZERO_EXTEND || N0Opc == ISD::SIGN_EXTEND) &&
1489*9880d681SAndroid Build Coastguard Worker (isConstFalseVal(N1C) ||
1490*9880d681SAndroid Build Coastguard Worker isExtendedTrueVal(N1C, N0->getValueType(0), SExt))) {
1491*9880d681SAndroid Build Coastguard Worker
1492*9880d681SAndroid Build Coastguard Worker bool Inverse = (N1C->isNullValue() && Cond == ISD::SETEQ) ||
1493*9880d681SAndroid Build Coastguard Worker (!N1C->isNullValue() && Cond == ISD::SETNE);
1494*9880d681SAndroid Build Coastguard Worker
1495*9880d681SAndroid Build Coastguard Worker if (!Inverse)
1496*9880d681SAndroid Build Coastguard Worker return TopSetCC;
1497*9880d681SAndroid Build Coastguard Worker
1498*9880d681SAndroid Build Coastguard Worker ISD::CondCode InvCond = ISD::getSetCCInverse(
1499*9880d681SAndroid Build Coastguard Worker cast<CondCodeSDNode>(TopSetCC.getOperand(2))->get(),
1500*9880d681SAndroid Build Coastguard Worker TopSetCC.getOperand(0).getValueType().isInteger());
1501*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, TopSetCC.getOperand(0),
1502*9880d681SAndroid Build Coastguard Worker TopSetCC.getOperand(1),
1503*9880d681SAndroid Build Coastguard Worker InvCond);
1504*9880d681SAndroid Build Coastguard Worker
1505*9880d681SAndroid Build Coastguard Worker }
1506*9880d681SAndroid Build Coastguard Worker }
1507*9880d681SAndroid Build Coastguard Worker }
1508*9880d681SAndroid Build Coastguard Worker
1509*9880d681SAndroid Build Coastguard Worker // If the LHS is '(and load, const)', the RHS is 0,
1510*9880d681SAndroid Build Coastguard Worker // the test is for equality or unsigned, and all 1 bits of the const are
1511*9880d681SAndroid Build Coastguard Worker // in the same partial word, see if we can shorten the load.
1512*9880d681SAndroid Build Coastguard Worker if (DCI.isBeforeLegalize() &&
1513*9880d681SAndroid Build Coastguard Worker !ISD::isSignedIntSetCC(Cond) &&
1514*9880d681SAndroid Build Coastguard Worker N0.getOpcode() == ISD::AND && C1 == 0 &&
1515*9880d681SAndroid Build Coastguard Worker N0.getNode()->hasOneUse() &&
1516*9880d681SAndroid Build Coastguard Worker isa<LoadSDNode>(N0.getOperand(0)) &&
1517*9880d681SAndroid Build Coastguard Worker N0.getOperand(0).getNode()->hasOneUse() &&
1518*9880d681SAndroid Build Coastguard Worker isa<ConstantSDNode>(N0.getOperand(1))) {
1519*9880d681SAndroid Build Coastguard Worker LoadSDNode *Lod = cast<LoadSDNode>(N0.getOperand(0));
1520*9880d681SAndroid Build Coastguard Worker APInt bestMask;
1521*9880d681SAndroid Build Coastguard Worker unsigned bestWidth = 0, bestOffset = 0;
1522*9880d681SAndroid Build Coastguard Worker if (!Lod->isVolatile() && Lod->isUnindexed()) {
1523*9880d681SAndroid Build Coastguard Worker unsigned origWidth = N0.getValueType().getSizeInBits();
1524*9880d681SAndroid Build Coastguard Worker unsigned maskWidth = origWidth;
1525*9880d681SAndroid Build Coastguard Worker // We can narrow (e.g.) 16-bit extending loads on 32-bit target to
1526*9880d681SAndroid Build Coastguard Worker // 8 bits, but have to be careful...
1527*9880d681SAndroid Build Coastguard Worker if (Lod->getExtensionType() != ISD::NON_EXTLOAD)
1528*9880d681SAndroid Build Coastguard Worker origWidth = Lod->getMemoryVT().getSizeInBits();
1529*9880d681SAndroid Build Coastguard Worker const APInt &Mask =
1530*9880d681SAndroid Build Coastguard Worker cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue();
1531*9880d681SAndroid Build Coastguard Worker for (unsigned width = origWidth / 2; width>=8; width /= 2) {
1532*9880d681SAndroid Build Coastguard Worker APInt newMask = APInt::getLowBitsSet(maskWidth, width);
1533*9880d681SAndroid Build Coastguard Worker for (unsigned offset=0; offset<origWidth/width; offset++) {
1534*9880d681SAndroid Build Coastguard Worker if ((newMask & Mask) == Mask) {
1535*9880d681SAndroid Build Coastguard Worker if (!DAG.getDataLayout().isLittleEndian())
1536*9880d681SAndroid Build Coastguard Worker bestOffset = (origWidth/width - offset - 1) * (width/8);
1537*9880d681SAndroid Build Coastguard Worker else
1538*9880d681SAndroid Build Coastguard Worker bestOffset = (uint64_t)offset * (width/8);
1539*9880d681SAndroid Build Coastguard Worker bestMask = Mask.lshr(offset * (width/8) * 8);
1540*9880d681SAndroid Build Coastguard Worker bestWidth = width;
1541*9880d681SAndroid Build Coastguard Worker break;
1542*9880d681SAndroid Build Coastguard Worker }
1543*9880d681SAndroid Build Coastguard Worker newMask = newMask << width;
1544*9880d681SAndroid Build Coastguard Worker }
1545*9880d681SAndroid Build Coastguard Worker }
1546*9880d681SAndroid Build Coastguard Worker }
1547*9880d681SAndroid Build Coastguard Worker if (bestWidth) {
1548*9880d681SAndroid Build Coastguard Worker EVT newVT = EVT::getIntegerVT(*DAG.getContext(), bestWidth);
1549*9880d681SAndroid Build Coastguard Worker if (newVT.isRound()) {
1550*9880d681SAndroid Build Coastguard Worker EVT PtrType = Lod->getOperand(1).getValueType();
1551*9880d681SAndroid Build Coastguard Worker SDValue Ptr = Lod->getBasePtr();
1552*9880d681SAndroid Build Coastguard Worker if (bestOffset != 0)
1553*9880d681SAndroid Build Coastguard Worker Ptr = DAG.getNode(ISD::ADD, dl, PtrType, Lod->getBasePtr(),
1554*9880d681SAndroid Build Coastguard Worker DAG.getConstant(bestOffset, dl, PtrType));
1555*9880d681SAndroid Build Coastguard Worker unsigned NewAlign = MinAlign(Lod->getAlignment(), bestOffset);
1556*9880d681SAndroid Build Coastguard Worker SDValue NewLoad = DAG.getLoad(newVT, dl, Lod->getChain(), Ptr,
1557*9880d681SAndroid Build Coastguard Worker Lod->getPointerInfo().getWithOffset(bestOffset),
1558*9880d681SAndroid Build Coastguard Worker false, false, false, NewAlign);
1559*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT,
1560*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::AND, dl, newVT, NewLoad,
1561*9880d681SAndroid Build Coastguard Worker DAG.getConstant(bestMask.trunc(bestWidth),
1562*9880d681SAndroid Build Coastguard Worker dl, newVT)),
1563*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0LL, dl, newVT), Cond);
1564*9880d681SAndroid Build Coastguard Worker }
1565*9880d681SAndroid Build Coastguard Worker }
1566*9880d681SAndroid Build Coastguard Worker }
1567*9880d681SAndroid Build Coastguard Worker
1568*9880d681SAndroid Build Coastguard Worker // If the LHS is a ZERO_EXTEND, perform the comparison on the input.
1569*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::ZERO_EXTEND) {
1570*9880d681SAndroid Build Coastguard Worker unsigned InSize = N0.getOperand(0).getValueType().getSizeInBits();
1571*9880d681SAndroid Build Coastguard Worker
1572*9880d681SAndroid Build Coastguard Worker // If the comparison constant has bits in the upper part, the
1573*9880d681SAndroid Build Coastguard Worker // zero-extended value could never match.
1574*9880d681SAndroid Build Coastguard Worker if (C1.intersects(APInt::getHighBitsSet(C1.getBitWidth(),
1575*9880d681SAndroid Build Coastguard Worker C1.getBitWidth() - InSize))) {
1576*9880d681SAndroid Build Coastguard Worker switch (Cond) {
1577*9880d681SAndroid Build Coastguard Worker case ISD::SETUGT:
1578*9880d681SAndroid Build Coastguard Worker case ISD::SETUGE:
1579*9880d681SAndroid Build Coastguard Worker case ISD::SETEQ: return DAG.getConstant(0, dl, VT);
1580*9880d681SAndroid Build Coastguard Worker case ISD::SETULT:
1581*9880d681SAndroid Build Coastguard Worker case ISD::SETULE:
1582*9880d681SAndroid Build Coastguard Worker case ISD::SETNE: return DAG.getConstant(1, dl, VT);
1583*9880d681SAndroid Build Coastguard Worker case ISD::SETGT:
1584*9880d681SAndroid Build Coastguard Worker case ISD::SETGE:
1585*9880d681SAndroid Build Coastguard Worker // True if the sign bit of C1 is set.
1586*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(C1.isNegative(), dl, VT);
1587*9880d681SAndroid Build Coastguard Worker case ISD::SETLT:
1588*9880d681SAndroid Build Coastguard Worker case ISD::SETLE:
1589*9880d681SAndroid Build Coastguard Worker // True if the sign bit of C1 isn't set.
1590*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(C1.isNonNegative(), dl, VT);
1591*9880d681SAndroid Build Coastguard Worker default:
1592*9880d681SAndroid Build Coastguard Worker break;
1593*9880d681SAndroid Build Coastguard Worker }
1594*9880d681SAndroid Build Coastguard Worker }
1595*9880d681SAndroid Build Coastguard Worker
1596*9880d681SAndroid Build Coastguard Worker // Otherwise, we can perform the comparison with the low bits.
1597*9880d681SAndroid Build Coastguard Worker switch (Cond) {
1598*9880d681SAndroid Build Coastguard Worker case ISD::SETEQ:
1599*9880d681SAndroid Build Coastguard Worker case ISD::SETNE:
1600*9880d681SAndroid Build Coastguard Worker case ISD::SETUGT:
1601*9880d681SAndroid Build Coastguard Worker case ISD::SETUGE:
1602*9880d681SAndroid Build Coastguard Worker case ISD::SETULT:
1603*9880d681SAndroid Build Coastguard Worker case ISD::SETULE: {
1604*9880d681SAndroid Build Coastguard Worker EVT newVT = N0.getOperand(0).getValueType();
1605*9880d681SAndroid Build Coastguard Worker if (DCI.isBeforeLegalizeOps() ||
1606*9880d681SAndroid Build Coastguard Worker (isOperationLegal(ISD::SETCC, newVT) &&
1607*9880d681SAndroid Build Coastguard Worker getCondCodeAction(Cond, newVT.getSimpleVT()) == Legal)) {
1608*9880d681SAndroid Build Coastguard Worker EVT NewSetCCVT =
1609*9880d681SAndroid Build Coastguard Worker getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), newVT);
1610*9880d681SAndroid Build Coastguard Worker SDValue NewConst = DAG.getConstant(C1.trunc(InSize), dl, newVT);
1611*9880d681SAndroid Build Coastguard Worker
1612*9880d681SAndroid Build Coastguard Worker SDValue NewSetCC = DAG.getSetCC(dl, NewSetCCVT, N0.getOperand(0),
1613*9880d681SAndroid Build Coastguard Worker NewConst, Cond);
1614*9880d681SAndroid Build Coastguard Worker return DAG.getBoolExtOrTrunc(NewSetCC, dl, VT, N0.getValueType());
1615*9880d681SAndroid Build Coastguard Worker }
1616*9880d681SAndroid Build Coastguard Worker break;
1617*9880d681SAndroid Build Coastguard Worker }
1618*9880d681SAndroid Build Coastguard Worker default:
1619*9880d681SAndroid Build Coastguard Worker break; // todo, be more careful with signed comparisons
1620*9880d681SAndroid Build Coastguard Worker }
1621*9880d681SAndroid Build Coastguard Worker } else if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
1622*9880d681SAndroid Build Coastguard Worker (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
1623*9880d681SAndroid Build Coastguard Worker EVT ExtSrcTy = cast<VTSDNode>(N0.getOperand(1))->getVT();
1624*9880d681SAndroid Build Coastguard Worker unsigned ExtSrcTyBits = ExtSrcTy.getSizeInBits();
1625*9880d681SAndroid Build Coastguard Worker EVT ExtDstTy = N0.getValueType();
1626*9880d681SAndroid Build Coastguard Worker unsigned ExtDstTyBits = ExtDstTy.getSizeInBits();
1627*9880d681SAndroid Build Coastguard Worker
1628*9880d681SAndroid Build Coastguard Worker // If the constant doesn't fit into the number of bits for the source of
1629*9880d681SAndroid Build Coastguard Worker // the sign extension, it is impossible for both sides to be equal.
1630*9880d681SAndroid Build Coastguard Worker if (C1.getMinSignedBits() > ExtSrcTyBits)
1631*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(Cond == ISD::SETNE, dl, VT);
1632*9880d681SAndroid Build Coastguard Worker
1633*9880d681SAndroid Build Coastguard Worker SDValue ZextOp;
1634*9880d681SAndroid Build Coastguard Worker EVT Op0Ty = N0.getOperand(0).getValueType();
1635*9880d681SAndroid Build Coastguard Worker if (Op0Ty == ExtSrcTy) {
1636*9880d681SAndroid Build Coastguard Worker ZextOp = N0.getOperand(0);
1637*9880d681SAndroid Build Coastguard Worker } else {
1638*9880d681SAndroid Build Coastguard Worker APInt Imm = APInt::getLowBitsSet(ExtDstTyBits, ExtSrcTyBits);
1639*9880d681SAndroid Build Coastguard Worker ZextOp = DAG.getNode(ISD::AND, dl, Op0Ty, N0.getOperand(0),
1640*9880d681SAndroid Build Coastguard Worker DAG.getConstant(Imm, dl, Op0Ty));
1641*9880d681SAndroid Build Coastguard Worker }
1642*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
1643*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(ZextOp.getNode());
1644*9880d681SAndroid Build Coastguard Worker // Otherwise, make this a use of a zext.
1645*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, ZextOp,
1646*9880d681SAndroid Build Coastguard Worker DAG.getConstant(C1 & APInt::getLowBitsSet(
1647*9880d681SAndroid Build Coastguard Worker ExtDstTyBits,
1648*9880d681SAndroid Build Coastguard Worker ExtSrcTyBits),
1649*9880d681SAndroid Build Coastguard Worker dl, ExtDstTy),
1650*9880d681SAndroid Build Coastguard Worker Cond);
1651*9880d681SAndroid Build Coastguard Worker } else if ((N1C->isNullValue() || N1C->getAPIntValue() == 1) &&
1652*9880d681SAndroid Build Coastguard Worker (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
1653*9880d681SAndroid Build Coastguard Worker // SETCC (SETCC), [0|1], [EQ|NE] -> SETCC
1654*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::SETCC &&
1655*9880d681SAndroid Build Coastguard Worker isTypeLegal(VT) && VT.bitsLE(N0.getValueType())) {
1656*9880d681SAndroid Build Coastguard Worker bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (N1C->getAPIntValue() != 1);
1657*9880d681SAndroid Build Coastguard Worker if (TrueWhenTrue)
1658*9880d681SAndroid Build Coastguard Worker return DAG.getNode(ISD::TRUNCATE, dl, VT, N0);
1659*9880d681SAndroid Build Coastguard Worker // Invert the condition.
1660*9880d681SAndroid Build Coastguard Worker ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
1661*9880d681SAndroid Build Coastguard Worker CC = ISD::getSetCCInverse(CC,
1662*9880d681SAndroid Build Coastguard Worker N0.getOperand(0).getValueType().isInteger());
1663*9880d681SAndroid Build Coastguard Worker if (DCI.isBeforeLegalizeOps() ||
1664*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(CC, N0.getOperand(0).getSimpleValueType()))
1665*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
1666*9880d681SAndroid Build Coastguard Worker }
1667*9880d681SAndroid Build Coastguard Worker
1668*9880d681SAndroid Build Coastguard Worker if ((N0.getOpcode() == ISD::XOR ||
1669*9880d681SAndroid Build Coastguard Worker (N0.getOpcode() == ISD::AND &&
1670*9880d681SAndroid Build Coastguard Worker N0.getOperand(0).getOpcode() == ISD::XOR &&
1671*9880d681SAndroid Build Coastguard Worker N0.getOperand(1) == N0.getOperand(0).getOperand(1))) &&
1672*9880d681SAndroid Build Coastguard Worker isa<ConstantSDNode>(N0.getOperand(1)) &&
1673*9880d681SAndroid Build Coastguard Worker cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue() == 1) {
1674*9880d681SAndroid Build Coastguard Worker // If this is (X^1) == 0/1, swap the RHS and eliminate the xor. We
1675*9880d681SAndroid Build Coastguard Worker // can only do this if the top bits are known zero.
1676*9880d681SAndroid Build Coastguard Worker unsigned BitWidth = N0.getValueSizeInBits();
1677*9880d681SAndroid Build Coastguard Worker if (DAG.MaskedValueIsZero(N0,
1678*9880d681SAndroid Build Coastguard Worker APInt::getHighBitsSet(BitWidth,
1679*9880d681SAndroid Build Coastguard Worker BitWidth-1))) {
1680*9880d681SAndroid Build Coastguard Worker // Okay, get the un-inverted input value.
1681*9880d681SAndroid Build Coastguard Worker SDValue Val;
1682*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::XOR)
1683*9880d681SAndroid Build Coastguard Worker Val = N0.getOperand(0);
1684*9880d681SAndroid Build Coastguard Worker else {
1685*9880d681SAndroid Build Coastguard Worker assert(N0.getOpcode() == ISD::AND &&
1686*9880d681SAndroid Build Coastguard Worker N0.getOperand(0).getOpcode() == ISD::XOR);
1687*9880d681SAndroid Build Coastguard Worker // ((X^1)&1)^1 -> X & 1
1688*9880d681SAndroid Build Coastguard Worker Val = DAG.getNode(ISD::AND, dl, N0.getValueType(),
1689*9880d681SAndroid Build Coastguard Worker N0.getOperand(0).getOperand(0),
1690*9880d681SAndroid Build Coastguard Worker N0.getOperand(1));
1691*9880d681SAndroid Build Coastguard Worker }
1692*9880d681SAndroid Build Coastguard Worker
1693*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, Val, N1,
1694*9880d681SAndroid Build Coastguard Worker Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
1695*9880d681SAndroid Build Coastguard Worker }
1696*9880d681SAndroid Build Coastguard Worker } else if (N1C->getAPIntValue() == 1 &&
1697*9880d681SAndroid Build Coastguard Worker (VT == MVT::i1 ||
1698*9880d681SAndroid Build Coastguard Worker getBooleanContents(N0->getValueType(0)) ==
1699*9880d681SAndroid Build Coastguard Worker ZeroOrOneBooleanContent)) {
1700*9880d681SAndroid Build Coastguard Worker SDValue Op0 = N0;
1701*9880d681SAndroid Build Coastguard Worker if (Op0.getOpcode() == ISD::TRUNCATE)
1702*9880d681SAndroid Build Coastguard Worker Op0 = Op0.getOperand(0);
1703*9880d681SAndroid Build Coastguard Worker
1704*9880d681SAndroid Build Coastguard Worker if ((Op0.getOpcode() == ISD::XOR) &&
1705*9880d681SAndroid Build Coastguard Worker Op0.getOperand(0).getOpcode() == ISD::SETCC &&
1706*9880d681SAndroid Build Coastguard Worker Op0.getOperand(1).getOpcode() == ISD::SETCC) {
1707*9880d681SAndroid Build Coastguard Worker // (xor (setcc), (setcc)) == / != 1 -> (setcc) != / == (setcc)
1708*9880d681SAndroid Build Coastguard Worker Cond = (Cond == ISD::SETEQ) ? ISD::SETNE : ISD::SETEQ;
1709*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, Op0.getOperand(0), Op0.getOperand(1),
1710*9880d681SAndroid Build Coastguard Worker Cond);
1711*9880d681SAndroid Build Coastguard Worker }
1712*9880d681SAndroid Build Coastguard Worker if (Op0.getOpcode() == ISD::AND &&
1713*9880d681SAndroid Build Coastguard Worker isa<ConstantSDNode>(Op0.getOperand(1)) &&
1714*9880d681SAndroid Build Coastguard Worker cast<ConstantSDNode>(Op0.getOperand(1))->getAPIntValue() == 1) {
1715*9880d681SAndroid Build Coastguard Worker // If this is (X&1) == / != 1, normalize it to (X&1) != / == 0.
1716*9880d681SAndroid Build Coastguard Worker if (Op0.getValueType().bitsGT(VT))
1717*9880d681SAndroid Build Coastguard Worker Op0 = DAG.getNode(ISD::AND, dl, VT,
1718*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::TRUNCATE, dl, VT, Op0.getOperand(0)),
1719*9880d681SAndroid Build Coastguard Worker DAG.getConstant(1, dl, VT));
1720*9880d681SAndroid Build Coastguard Worker else if (Op0.getValueType().bitsLT(VT))
1721*9880d681SAndroid Build Coastguard Worker Op0 = DAG.getNode(ISD::AND, dl, VT,
1722*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::ANY_EXTEND, dl, VT, Op0.getOperand(0)),
1723*9880d681SAndroid Build Coastguard Worker DAG.getConstant(1, dl, VT));
1724*9880d681SAndroid Build Coastguard Worker
1725*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, Op0,
1726*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, Op0.getValueType()),
1727*9880d681SAndroid Build Coastguard Worker Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
1728*9880d681SAndroid Build Coastguard Worker }
1729*9880d681SAndroid Build Coastguard Worker if (Op0.getOpcode() == ISD::AssertZext &&
1730*9880d681SAndroid Build Coastguard Worker cast<VTSDNode>(Op0.getOperand(1))->getVT() == MVT::i1)
1731*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, Op0,
1732*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, Op0.getValueType()),
1733*9880d681SAndroid Build Coastguard Worker Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
1734*9880d681SAndroid Build Coastguard Worker }
1735*9880d681SAndroid Build Coastguard Worker }
1736*9880d681SAndroid Build Coastguard Worker
1737*9880d681SAndroid Build Coastguard Worker APInt MinVal, MaxVal;
1738*9880d681SAndroid Build Coastguard Worker unsigned OperandBitSize = N1C->getValueType(0).getSizeInBits();
1739*9880d681SAndroid Build Coastguard Worker if (ISD::isSignedIntSetCC(Cond)) {
1740*9880d681SAndroid Build Coastguard Worker MinVal = APInt::getSignedMinValue(OperandBitSize);
1741*9880d681SAndroid Build Coastguard Worker MaxVal = APInt::getSignedMaxValue(OperandBitSize);
1742*9880d681SAndroid Build Coastguard Worker } else {
1743*9880d681SAndroid Build Coastguard Worker MinVal = APInt::getMinValue(OperandBitSize);
1744*9880d681SAndroid Build Coastguard Worker MaxVal = APInt::getMaxValue(OperandBitSize);
1745*9880d681SAndroid Build Coastguard Worker }
1746*9880d681SAndroid Build Coastguard Worker
1747*9880d681SAndroid Build Coastguard Worker // Canonicalize GE/LE comparisons to use GT/LT comparisons.
1748*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETGE || Cond == ISD::SETUGE) {
1749*9880d681SAndroid Build Coastguard Worker if (C1 == MinVal) return DAG.getConstant(1, dl, VT); // X >= MIN --> true
1750*9880d681SAndroid Build Coastguard Worker // X >= C0 --> X > (C0 - 1)
1751*9880d681SAndroid Build Coastguard Worker APInt C = C1 - 1;
1752*9880d681SAndroid Build Coastguard Worker ISD::CondCode NewCC = (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT;
1753*9880d681SAndroid Build Coastguard Worker if ((DCI.isBeforeLegalizeOps() ||
1754*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(NewCC, VT.getSimpleVT())) &&
1755*9880d681SAndroid Build Coastguard Worker (!N1C->isOpaque() || (N1C->isOpaque() && C.getBitWidth() <= 64 &&
1756*9880d681SAndroid Build Coastguard Worker isLegalICmpImmediate(C.getSExtValue())))) {
1757*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0,
1758*9880d681SAndroid Build Coastguard Worker DAG.getConstant(C, dl, N1.getValueType()),
1759*9880d681SAndroid Build Coastguard Worker NewCC);
1760*9880d681SAndroid Build Coastguard Worker }
1761*9880d681SAndroid Build Coastguard Worker }
1762*9880d681SAndroid Build Coastguard Worker
1763*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETLE || Cond == ISD::SETULE) {
1764*9880d681SAndroid Build Coastguard Worker if (C1 == MaxVal) return DAG.getConstant(1, dl, VT); // X <= MAX --> true
1765*9880d681SAndroid Build Coastguard Worker // X <= C0 --> X < (C0 + 1)
1766*9880d681SAndroid Build Coastguard Worker APInt C = C1 + 1;
1767*9880d681SAndroid Build Coastguard Worker ISD::CondCode NewCC = (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT;
1768*9880d681SAndroid Build Coastguard Worker if ((DCI.isBeforeLegalizeOps() ||
1769*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(NewCC, VT.getSimpleVT())) &&
1770*9880d681SAndroid Build Coastguard Worker (!N1C->isOpaque() || (N1C->isOpaque() && C.getBitWidth() <= 64 &&
1771*9880d681SAndroid Build Coastguard Worker isLegalICmpImmediate(C.getSExtValue())))) {
1772*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0,
1773*9880d681SAndroid Build Coastguard Worker DAG.getConstant(C, dl, N1.getValueType()),
1774*9880d681SAndroid Build Coastguard Worker NewCC);
1775*9880d681SAndroid Build Coastguard Worker }
1776*9880d681SAndroid Build Coastguard Worker }
1777*9880d681SAndroid Build Coastguard Worker
1778*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal)
1779*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(0, dl, VT); // X < MIN --> false
1780*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETGE || Cond == ISD::SETUGE) && C1 == MinVal)
1781*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(1, dl, VT); // X >= MIN --> true
1782*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MaxVal)
1783*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(0, dl, VT); // X > MAX --> false
1784*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETLE || Cond == ISD::SETULE) && C1 == MaxVal)
1785*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(1, dl, VT); // X <= MAX --> true
1786*9880d681SAndroid Build Coastguard Worker
1787*9880d681SAndroid Build Coastguard Worker // Canonicalize setgt X, Min --> setne X, Min
1788*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MinVal)
1789*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE);
1790*9880d681SAndroid Build Coastguard Worker // Canonicalize setlt X, Max --> setne X, Max
1791*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MaxVal)
1792*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE);
1793*9880d681SAndroid Build Coastguard Worker
1794*9880d681SAndroid Build Coastguard Worker // If we have setult X, 1, turn it into seteq X, 0
1795*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal+1)
1796*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0,
1797*9880d681SAndroid Build Coastguard Worker DAG.getConstant(MinVal, dl, N0.getValueType()),
1798*9880d681SAndroid Build Coastguard Worker ISD::SETEQ);
1799*9880d681SAndroid Build Coastguard Worker // If we have setugt X, Max-1, turn it into seteq X, Max
1800*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MaxVal-1)
1801*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0,
1802*9880d681SAndroid Build Coastguard Worker DAG.getConstant(MaxVal, dl, N0.getValueType()),
1803*9880d681SAndroid Build Coastguard Worker ISD::SETEQ);
1804*9880d681SAndroid Build Coastguard Worker
1805*9880d681SAndroid Build Coastguard Worker // If we have "setcc X, C0", check to see if we can shrink the immediate
1806*9880d681SAndroid Build Coastguard Worker // by changing cc.
1807*9880d681SAndroid Build Coastguard Worker
1808*9880d681SAndroid Build Coastguard Worker // SETUGT X, SINTMAX -> SETLT X, 0
1809*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETUGT &&
1810*9880d681SAndroid Build Coastguard Worker C1 == APInt::getSignedMaxValue(OperandBitSize))
1811*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0,
1812*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, N1.getValueType()),
1813*9880d681SAndroid Build Coastguard Worker ISD::SETLT);
1814*9880d681SAndroid Build Coastguard Worker
1815*9880d681SAndroid Build Coastguard Worker // SETULT X, SINTMIN -> SETGT X, -1
1816*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETULT &&
1817*9880d681SAndroid Build Coastguard Worker C1 == APInt::getSignedMinValue(OperandBitSize)) {
1818*9880d681SAndroid Build Coastguard Worker SDValue ConstMinusOne =
1819*9880d681SAndroid Build Coastguard Worker DAG.getConstant(APInt::getAllOnesValue(OperandBitSize), dl,
1820*9880d681SAndroid Build Coastguard Worker N1.getValueType());
1821*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, ConstMinusOne, ISD::SETGT);
1822*9880d681SAndroid Build Coastguard Worker }
1823*9880d681SAndroid Build Coastguard Worker
1824*9880d681SAndroid Build Coastguard Worker // Fold bit comparisons when we can.
1825*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
1826*9880d681SAndroid Build Coastguard Worker (VT == N0.getValueType() ||
1827*9880d681SAndroid Build Coastguard Worker (isTypeLegal(VT) && VT.bitsLE(N0.getValueType()))) &&
1828*9880d681SAndroid Build Coastguard Worker N0.getOpcode() == ISD::AND) {
1829*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
1830*9880d681SAndroid Build Coastguard Worker if (auto *AndRHS = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
1831*9880d681SAndroid Build Coastguard Worker EVT ShiftTy = DCI.isBeforeLegalize()
1832*9880d681SAndroid Build Coastguard Worker ? getPointerTy(DL)
1833*9880d681SAndroid Build Coastguard Worker : getShiftAmountTy(N0.getValueType(), DL);
1834*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3
1835*9880d681SAndroid Build Coastguard Worker // Perform the xform if the AND RHS is a single bit.
1836*9880d681SAndroid Build Coastguard Worker if (AndRHS->getAPIntValue().isPowerOf2()) {
1837*9880d681SAndroid Build Coastguard Worker return DAG.getNode(ISD::TRUNCATE, dl, VT,
1838*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::SRL, dl, N0.getValueType(), N0,
1839*9880d681SAndroid Build Coastguard Worker DAG.getConstant(AndRHS->getAPIntValue().logBase2(), dl,
1840*9880d681SAndroid Build Coastguard Worker ShiftTy)));
1841*9880d681SAndroid Build Coastguard Worker }
1842*9880d681SAndroid Build Coastguard Worker } else if (Cond == ISD::SETEQ && C1 == AndRHS->getAPIntValue()) {
1843*9880d681SAndroid Build Coastguard Worker // (X & 8) == 8 --> (X & 8) >> 3
1844*9880d681SAndroid Build Coastguard Worker // Perform the xform if C1 is a single bit.
1845*9880d681SAndroid Build Coastguard Worker if (C1.isPowerOf2()) {
1846*9880d681SAndroid Build Coastguard Worker return DAG.getNode(ISD::TRUNCATE, dl, VT,
1847*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::SRL, dl, N0.getValueType(), N0,
1848*9880d681SAndroid Build Coastguard Worker DAG.getConstant(C1.logBase2(), dl,
1849*9880d681SAndroid Build Coastguard Worker ShiftTy)));
1850*9880d681SAndroid Build Coastguard Worker }
1851*9880d681SAndroid Build Coastguard Worker }
1852*9880d681SAndroid Build Coastguard Worker }
1853*9880d681SAndroid Build Coastguard Worker }
1854*9880d681SAndroid Build Coastguard Worker
1855*9880d681SAndroid Build Coastguard Worker if (C1.getMinSignedBits() <= 64 &&
1856*9880d681SAndroid Build Coastguard Worker !isLegalICmpImmediate(C1.getSExtValue())) {
1857*9880d681SAndroid Build Coastguard Worker // (X & -256) == 256 -> (X >> 8) == 1
1858*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
1859*9880d681SAndroid Build Coastguard Worker N0.getOpcode() == ISD::AND && N0.hasOneUse()) {
1860*9880d681SAndroid Build Coastguard Worker if (auto *AndRHS = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
1861*9880d681SAndroid Build Coastguard Worker const APInt &AndRHSC = AndRHS->getAPIntValue();
1862*9880d681SAndroid Build Coastguard Worker if ((-AndRHSC).isPowerOf2() && (AndRHSC & C1) == C1) {
1863*9880d681SAndroid Build Coastguard Worker unsigned ShiftBits = AndRHSC.countTrailingZeros();
1864*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
1865*9880d681SAndroid Build Coastguard Worker EVT ShiftTy = DCI.isBeforeLegalize()
1866*9880d681SAndroid Build Coastguard Worker ? getPointerTy(DL)
1867*9880d681SAndroid Build Coastguard Worker : getShiftAmountTy(N0.getValueType(), DL);
1868*9880d681SAndroid Build Coastguard Worker EVT CmpTy = N0.getValueType();
1869*9880d681SAndroid Build Coastguard Worker SDValue Shift = DAG.getNode(ISD::SRL, dl, CmpTy, N0.getOperand(0),
1870*9880d681SAndroid Build Coastguard Worker DAG.getConstant(ShiftBits, dl,
1871*9880d681SAndroid Build Coastguard Worker ShiftTy));
1872*9880d681SAndroid Build Coastguard Worker SDValue CmpRHS = DAG.getConstant(C1.lshr(ShiftBits), dl, CmpTy);
1873*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, Shift, CmpRHS, Cond);
1874*9880d681SAndroid Build Coastguard Worker }
1875*9880d681SAndroid Build Coastguard Worker }
1876*9880d681SAndroid Build Coastguard Worker } else if (Cond == ISD::SETULT || Cond == ISD::SETUGE ||
1877*9880d681SAndroid Build Coastguard Worker Cond == ISD::SETULE || Cond == ISD::SETUGT) {
1878*9880d681SAndroid Build Coastguard Worker bool AdjOne = (Cond == ISD::SETULE || Cond == ISD::SETUGT);
1879*9880d681SAndroid Build Coastguard Worker // X < 0x100000000 -> (X >> 32) < 1
1880*9880d681SAndroid Build Coastguard Worker // X >= 0x100000000 -> (X >> 32) >= 1
1881*9880d681SAndroid Build Coastguard Worker // X <= 0x0ffffffff -> (X >> 32) < 1
1882*9880d681SAndroid Build Coastguard Worker // X > 0x0ffffffff -> (X >> 32) >= 1
1883*9880d681SAndroid Build Coastguard Worker unsigned ShiftBits;
1884*9880d681SAndroid Build Coastguard Worker APInt NewC = C1;
1885*9880d681SAndroid Build Coastguard Worker ISD::CondCode NewCond = Cond;
1886*9880d681SAndroid Build Coastguard Worker if (AdjOne) {
1887*9880d681SAndroid Build Coastguard Worker ShiftBits = C1.countTrailingOnes();
1888*9880d681SAndroid Build Coastguard Worker NewC = NewC + 1;
1889*9880d681SAndroid Build Coastguard Worker NewCond = (Cond == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
1890*9880d681SAndroid Build Coastguard Worker } else {
1891*9880d681SAndroid Build Coastguard Worker ShiftBits = C1.countTrailingZeros();
1892*9880d681SAndroid Build Coastguard Worker }
1893*9880d681SAndroid Build Coastguard Worker NewC = NewC.lshr(ShiftBits);
1894*9880d681SAndroid Build Coastguard Worker if (ShiftBits && NewC.getMinSignedBits() <= 64 &&
1895*9880d681SAndroid Build Coastguard Worker isLegalICmpImmediate(NewC.getSExtValue())) {
1896*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
1897*9880d681SAndroid Build Coastguard Worker EVT ShiftTy = DCI.isBeforeLegalize()
1898*9880d681SAndroid Build Coastguard Worker ? getPointerTy(DL)
1899*9880d681SAndroid Build Coastguard Worker : getShiftAmountTy(N0.getValueType(), DL);
1900*9880d681SAndroid Build Coastguard Worker EVT CmpTy = N0.getValueType();
1901*9880d681SAndroid Build Coastguard Worker SDValue Shift = DAG.getNode(ISD::SRL, dl, CmpTy, N0,
1902*9880d681SAndroid Build Coastguard Worker DAG.getConstant(ShiftBits, dl, ShiftTy));
1903*9880d681SAndroid Build Coastguard Worker SDValue CmpRHS = DAG.getConstant(NewC, dl, CmpTy);
1904*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, Shift, CmpRHS, NewCond);
1905*9880d681SAndroid Build Coastguard Worker }
1906*9880d681SAndroid Build Coastguard Worker }
1907*9880d681SAndroid Build Coastguard Worker }
1908*9880d681SAndroid Build Coastguard Worker }
1909*9880d681SAndroid Build Coastguard Worker
1910*9880d681SAndroid Build Coastguard Worker if (isa<ConstantFPSDNode>(N0.getNode())) {
1911*9880d681SAndroid Build Coastguard Worker // Constant fold or commute setcc.
1912*9880d681SAndroid Build Coastguard Worker SDValue O = DAG.FoldSetCC(VT, N0, N1, Cond, dl);
1913*9880d681SAndroid Build Coastguard Worker if (O.getNode()) return O;
1914*9880d681SAndroid Build Coastguard Worker } else if (auto *CFP = dyn_cast<ConstantFPSDNode>(N1.getNode())) {
1915*9880d681SAndroid Build Coastguard Worker // If the RHS of an FP comparison is a constant, simplify it away in
1916*9880d681SAndroid Build Coastguard Worker // some cases.
1917*9880d681SAndroid Build Coastguard Worker if (CFP->getValueAPF().isNaN()) {
1918*9880d681SAndroid Build Coastguard Worker // If an operand is known to be a nan, we can fold it.
1919*9880d681SAndroid Build Coastguard Worker switch (ISD::getUnorderedFlavor(Cond)) {
1920*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unknown flavor!");
1921*9880d681SAndroid Build Coastguard Worker case 0: // Known false.
1922*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(0, dl, VT);
1923*9880d681SAndroid Build Coastguard Worker case 1: // Known true.
1924*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(1, dl, VT);
1925*9880d681SAndroid Build Coastguard Worker case 2: // Undefined.
1926*9880d681SAndroid Build Coastguard Worker return DAG.getUNDEF(VT);
1927*9880d681SAndroid Build Coastguard Worker }
1928*9880d681SAndroid Build Coastguard Worker }
1929*9880d681SAndroid Build Coastguard Worker
1930*9880d681SAndroid Build Coastguard Worker // Otherwise, we know the RHS is not a NaN. Simplify the node to drop the
1931*9880d681SAndroid Build Coastguard Worker // constant if knowing that the operand is non-nan is enough. We prefer to
1932*9880d681SAndroid Build Coastguard Worker // have SETO(x,x) instead of SETO(x, 0.0) because this avoids having to
1933*9880d681SAndroid Build Coastguard Worker // materialize 0.0.
1934*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETO || Cond == ISD::SETUO)
1935*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N0, Cond);
1936*9880d681SAndroid Build Coastguard Worker
1937*9880d681SAndroid Build Coastguard Worker // If the condition is not legal, see if we can find an equivalent one
1938*9880d681SAndroid Build Coastguard Worker // which is legal.
1939*9880d681SAndroid Build Coastguard Worker if (!isCondCodeLegal(Cond, N0.getSimpleValueType())) {
1940*9880d681SAndroid Build Coastguard Worker // If the comparison was an awkward floating-point == or != and one of
1941*9880d681SAndroid Build Coastguard Worker // the comparison operands is infinity or negative infinity, convert the
1942*9880d681SAndroid Build Coastguard Worker // condition to a less-awkward <= or >=.
1943*9880d681SAndroid Build Coastguard Worker if (CFP->getValueAPF().isInfinity()) {
1944*9880d681SAndroid Build Coastguard Worker if (CFP->getValueAPF().isNegative()) {
1945*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETOEQ &&
1946*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETOLE, N0.getSimpleValueType()))
1947*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETOLE);
1948*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETUEQ &&
1949*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETOLE, N0.getSimpleValueType()))
1950*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETULE);
1951*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETUNE &&
1952*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETUGT, N0.getSimpleValueType()))
1953*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETUGT);
1954*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETONE &&
1955*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETUGT, N0.getSimpleValueType()))
1956*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETOGT);
1957*9880d681SAndroid Build Coastguard Worker } else {
1958*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETOEQ &&
1959*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETOGE, N0.getSimpleValueType()))
1960*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETOGE);
1961*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETUEQ &&
1962*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETOGE, N0.getSimpleValueType()))
1963*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETUGE);
1964*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETUNE &&
1965*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETULT, N0.getSimpleValueType()))
1966*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETULT);
1967*9880d681SAndroid Build Coastguard Worker if (Cond == ISD::SETONE &&
1968*9880d681SAndroid Build Coastguard Worker isCondCodeLegal(ISD::SETULT, N0.getSimpleValueType()))
1969*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, ISD::SETOLT);
1970*9880d681SAndroid Build Coastguard Worker }
1971*9880d681SAndroid Build Coastguard Worker }
1972*9880d681SAndroid Build Coastguard Worker }
1973*9880d681SAndroid Build Coastguard Worker }
1974*9880d681SAndroid Build Coastguard Worker
1975*9880d681SAndroid Build Coastguard Worker if (N0 == N1) {
1976*9880d681SAndroid Build Coastguard Worker // The sext(setcc()) => setcc() optimization relies on the appropriate
1977*9880d681SAndroid Build Coastguard Worker // constant being emitted.
1978*9880d681SAndroid Build Coastguard Worker uint64_t EqVal = 0;
1979*9880d681SAndroid Build Coastguard Worker switch (getBooleanContents(N0.getValueType())) {
1980*9880d681SAndroid Build Coastguard Worker case UndefinedBooleanContent:
1981*9880d681SAndroid Build Coastguard Worker case ZeroOrOneBooleanContent:
1982*9880d681SAndroid Build Coastguard Worker EqVal = ISD::isTrueWhenEqual(Cond);
1983*9880d681SAndroid Build Coastguard Worker break;
1984*9880d681SAndroid Build Coastguard Worker case ZeroOrNegativeOneBooleanContent:
1985*9880d681SAndroid Build Coastguard Worker EqVal = ISD::isTrueWhenEqual(Cond) ? -1 : 0;
1986*9880d681SAndroid Build Coastguard Worker break;
1987*9880d681SAndroid Build Coastguard Worker }
1988*9880d681SAndroid Build Coastguard Worker
1989*9880d681SAndroid Build Coastguard Worker // We can always fold X == X for integer setcc's.
1990*9880d681SAndroid Build Coastguard Worker if (N0.getValueType().isInteger()) {
1991*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(EqVal, dl, VT);
1992*9880d681SAndroid Build Coastguard Worker }
1993*9880d681SAndroid Build Coastguard Worker unsigned UOF = ISD::getUnorderedFlavor(Cond);
1994*9880d681SAndroid Build Coastguard Worker if (UOF == 2) // FP operators that are undefined on NaNs.
1995*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(EqVal, dl, VT);
1996*9880d681SAndroid Build Coastguard Worker if (UOF == unsigned(ISD::isTrueWhenEqual(Cond)))
1997*9880d681SAndroid Build Coastguard Worker return DAG.getConstant(EqVal, dl, VT);
1998*9880d681SAndroid Build Coastguard Worker // Otherwise, we can't fold it. However, we can simplify it to SETUO/SETO
1999*9880d681SAndroid Build Coastguard Worker // if it is not already.
2000*9880d681SAndroid Build Coastguard Worker ISD::CondCode NewCond = UOF == 0 ? ISD::SETO : ISD::SETUO;
2001*9880d681SAndroid Build Coastguard Worker if (NewCond != Cond && (DCI.isBeforeLegalizeOps() ||
2002*9880d681SAndroid Build Coastguard Worker getCondCodeAction(NewCond, N0.getSimpleValueType()) == Legal))
2003*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0, N1, NewCond);
2004*9880d681SAndroid Build Coastguard Worker }
2005*9880d681SAndroid Build Coastguard Worker
2006*9880d681SAndroid Build Coastguard Worker if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
2007*9880d681SAndroid Build Coastguard Worker N0.getValueType().isInteger()) {
2008*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::ADD || N0.getOpcode() == ISD::SUB ||
2009*9880d681SAndroid Build Coastguard Worker N0.getOpcode() == ISD::XOR) {
2010*9880d681SAndroid Build Coastguard Worker // Simplify (X+Y) == (X+Z) --> Y == Z
2011*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == N1.getOpcode()) {
2012*9880d681SAndroid Build Coastguard Worker if (N0.getOperand(0) == N1.getOperand(0))
2013*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(1), Cond);
2014*9880d681SAndroid Build Coastguard Worker if (N0.getOperand(1) == N1.getOperand(1))
2015*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(0), Cond);
2016*9880d681SAndroid Build Coastguard Worker if (DAG.isCommutativeBinOp(N0.getOpcode())) {
2017*9880d681SAndroid Build Coastguard Worker // If X op Y == Y op X, try other combinations.
2018*9880d681SAndroid Build Coastguard Worker if (N0.getOperand(0) == N1.getOperand(1))
2019*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(0),
2020*9880d681SAndroid Build Coastguard Worker Cond);
2021*9880d681SAndroid Build Coastguard Worker if (N0.getOperand(1) == N1.getOperand(0))
2022*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(1),
2023*9880d681SAndroid Build Coastguard Worker Cond);
2024*9880d681SAndroid Build Coastguard Worker }
2025*9880d681SAndroid Build Coastguard Worker }
2026*9880d681SAndroid Build Coastguard Worker
2027*9880d681SAndroid Build Coastguard Worker // If RHS is a legal immediate value for a compare instruction, we need
2028*9880d681SAndroid Build Coastguard Worker // to be careful about increasing register pressure needlessly.
2029*9880d681SAndroid Build Coastguard Worker bool LegalRHSImm = false;
2030*9880d681SAndroid Build Coastguard Worker
2031*9880d681SAndroid Build Coastguard Worker if (auto *RHSC = dyn_cast<ConstantSDNode>(N1)) {
2032*9880d681SAndroid Build Coastguard Worker if (auto *LHSR = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
2033*9880d681SAndroid Build Coastguard Worker // Turn (X+C1) == C2 --> X == C2-C1
2034*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse()) {
2035*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(0),
2036*9880d681SAndroid Build Coastguard Worker DAG.getConstant(RHSC->getAPIntValue()-
2037*9880d681SAndroid Build Coastguard Worker LHSR->getAPIntValue(),
2038*9880d681SAndroid Build Coastguard Worker dl, N0.getValueType()), Cond);
2039*9880d681SAndroid Build Coastguard Worker }
2040*9880d681SAndroid Build Coastguard Worker
2041*9880d681SAndroid Build Coastguard Worker // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0.
2042*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::XOR)
2043*9880d681SAndroid Build Coastguard Worker // If we know that all of the inverted bits are zero, don't bother
2044*9880d681SAndroid Build Coastguard Worker // performing the inversion.
2045*9880d681SAndroid Build Coastguard Worker if (DAG.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getAPIntValue()))
2046*9880d681SAndroid Build Coastguard Worker return
2047*9880d681SAndroid Build Coastguard Worker DAG.getSetCC(dl, VT, N0.getOperand(0),
2048*9880d681SAndroid Build Coastguard Worker DAG.getConstant(LHSR->getAPIntValue() ^
2049*9880d681SAndroid Build Coastguard Worker RHSC->getAPIntValue(),
2050*9880d681SAndroid Build Coastguard Worker dl, N0.getValueType()),
2051*9880d681SAndroid Build Coastguard Worker Cond);
2052*9880d681SAndroid Build Coastguard Worker }
2053*9880d681SAndroid Build Coastguard Worker
2054*9880d681SAndroid Build Coastguard Worker // Turn (C1-X) == C2 --> X == C1-C2
2055*9880d681SAndroid Build Coastguard Worker if (auto *SUBC = dyn_cast<ConstantSDNode>(N0.getOperand(0))) {
2056*9880d681SAndroid Build Coastguard Worker if (N0.getOpcode() == ISD::SUB && N0.getNode()->hasOneUse()) {
2057*9880d681SAndroid Build Coastguard Worker return
2058*9880d681SAndroid Build Coastguard Worker DAG.getSetCC(dl, VT, N0.getOperand(1),
2059*9880d681SAndroid Build Coastguard Worker DAG.getConstant(SUBC->getAPIntValue() -
2060*9880d681SAndroid Build Coastguard Worker RHSC->getAPIntValue(),
2061*9880d681SAndroid Build Coastguard Worker dl, N0.getValueType()),
2062*9880d681SAndroid Build Coastguard Worker Cond);
2063*9880d681SAndroid Build Coastguard Worker }
2064*9880d681SAndroid Build Coastguard Worker }
2065*9880d681SAndroid Build Coastguard Worker
2066*9880d681SAndroid Build Coastguard Worker // Could RHSC fold directly into a compare?
2067*9880d681SAndroid Build Coastguard Worker if (RHSC->getValueType(0).getSizeInBits() <= 64)
2068*9880d681SAndroid Build Coastguard Worker LegalRHSImm = isLegalICmpImmediate(RHSC->getSExtValue());
2069*9880d681SAndroid Build Coastguard Worker }
2070*9880d681SAndroid Build Coastguard Worker
2071*9880d681SAndroid Build Coastguard Worker // Simplify (X+Z) == X --> Z == 0
2072*9880d681SAndroid Build Coastguard Worker // Don't do this if X is an immediate that can fold into a cmp
2073*9880d681SAndroid Build Coastguard Worker // instruction and X+Z has other uses. It could be an induction variable
2074*9880d681SAndroid Build Coastguard Worker // chain, and the transform would increase register pressure.
2075*9880d681SAndroid Build Coastguard Worker if (!LegalRHSImm || N0.getNode()->hasOneUse()) {
2076*9880d681SAndroid Build Coastguard Worker if (N0.getOperand(0) == N1)
2077*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(1),
2078*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, N0.getValueType()), Cond);
2079*9880d681SAndroid Build Coastguard Worker if (N0.getOperand(1) == N1) {
2080*9880d681SAndroid Build Coastguard Worker if (DAG.isCommutativeBinOp(N0.getOpcode()))
2081*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(0),
2082*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, N0.getValueType()),
2083*9880d681SAndroid Build Coastguard Worker Cond);
2084*9880d681SAndroid Build Coastguard Worker if (N0.getNode()->hasOneUse()) {
2085*9880d681SAndroid Build Coastguard Worker assert(N0.getOpcode() == ISD::SUB && "Unexpected operation!");
2086*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
2087*9880d681SAndroid Build Coastguard Worker // (Z-X) == X --> Z == X<<1
2088*9880d681SAndroid Build Coastguard Worker SDValue SH = DAG.getNode(
2089*9880d681SAndroid Build Coastguard Worker ISD::SHL, dl, N1.getValueType(), N1,
2090*9880d681SAndroid Build Coastguard Worker DAG.getConstant(1, dl,
2091*9880d681SAndroid Build Coastguard Worker getShiftAmountTy(N1.getValueType(), DL)));
2092*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
2093*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(SH.getNode());
2094*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N0.getOperand(0), SH, Cond);
2095*9880d681SAndroid Build Coastguard Worker }
2096*9880d681SAndroid Build Coastguard Worker }
2097*9880d681SAndroid Build Coastguard Worker }
2098*9880d681SAndroid Build Coastguard Worker }
2099*9880d681SAndroid Build Coastguard Worker
2100*9880d681SAndroid Build Coastguard Worker if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB ||
2101*9880d681SAndroid Build Coastguard Worker N1.getOpcode() == ISD::XOR) {
2102*9880d681SAndroid Build Coastguard Worker // Simplify X == (X+Z) --> Z == 0
2103*9880d681SAndroid Build Coastguard Worker if (N1.getOperand(0) == N0)
2104*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N1.getOperand(1),
2105*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, N1.getValueType()), Cond);
2106*9880d681SAndroid Build Coastguard Worker if (N1.getOperand(1) == N0) {
2107*9880d681SAndroid Build Coastguard Worker if (DAG.isCommutativeBinOp(N1.getOpcode()))
2108*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, N1.getOperand(0),
2109*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, N1.getValueType()), Cond);
2110*9880d681SAndroid Build Coastguard Worker if (N1.getNode()->hasOneUse()) {
2111*9880d681SAndroid Build Coastguard Worker assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!");
2112*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
2113*9880d681SAndroid Build Coastguard Worker // X == (Z-X) --> X<<1 == Z
2114*9880d681SAndroid Build Coastguard Worker SDValue SH = DAG.getNode(
2115*9880d681SAndroid Build Coastguard Worker ISD::SHL, dl, N1.getValueType(), N0,
2116*9880d681SAndroid Build Coastguard Worker DAG.getConstant(1, dl, getShiftAmountTy(N0.getValueType(), DL)));
2117*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
2118*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(SH.getNode());
2119*9880d681SAndroid Build Coastguard Worker return DAG.getSetCC(dl, VT, SH, N1.getOperand(0), Cond);
2120*9880d681SAndroid Build Coastguard Worker }
2121*9880d681SAndroid Build Coastguard Worker }
2122*9880d681SAndroid Build Coastguard Worker }
2123*9880d681SAndroid Build Coastguard Worker
2124*9880d681SAndroid Build Coastguard Worker if (SDValue V = simplifySetCCWithAnd(VT, N0, N1, Cond, DCI, dl))
2125*9880d681SAndroid Build Coastguard Worker return V;
2126*9880d681SAndroid Build Coastguard Worker }
2127*9880d681SAndroid Build Coastguard Worker
2128*9880d681SAndroid Build Coastguard Worker // Fold away ALL boolean setcc's.
2129*9880d681SAndroid Build Coastguard Worker SDValue Temp;
2130*9880d681SAndroid Build Coastguard Worker if (N0.getValueType() == MVT::i1 && foldBooleans) {
2131*9880d681SAndroid Build Coastguard Worker switch (Cond) {
2132*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unknown integer setcc!");
2133*9880d681SAndroid Build Coastguard Worker case ISD::SETEQ: // X == Y -> ~(X^Y)
2134*9880d681SAndroid Build Coastguard Worker Temp = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1);
2135*9880d681SAndroid Build Coastguard Worker N0 = DAG.getNOT(dl, Temp, MVT::i1);
2136*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
2137*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(Temp.getNode());
2138*9880d681SAndroid Build Coastguard Worker break;
2139*9880d681SAndroid Build Coastguard Worker case ISD::SETNE: // X != Y --> (X^Y)
2140*9880d681SAndroid Build Coastguard Worker N0 = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1);
2141*9880d681SAndroid Build Coastguard Worker break;
2142*9880d681SAndroid Build Coastguard Worker case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> ~X & Y
2143*9880d681SAndroid Build Coastguard Worker case ISD::SETULT: // X <u Y --> X == 0 & Y == 1 --> ~X & Y
2144*9880d681SAndroid Build Coastguard Worker Temp = DAG.getNOT(dl, N0, MVT::i1);
2145*9880d681SAndroid Build Coastguard Worker N0 = DAG.getNode(ISD::AND, dl, MVT::i1, N1, Temp);
2146*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
2147*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(Temp.getNode());
2148*9880d681SAndroid Build Coastguard Worker break;
2149*9880d681SAndroid Build Coastguard Worker case ISD::SETLT: // X <s Y --> X == 1 & Y == 0 --> ~Y & X
2150*9880d681SAndroid Build Coastguard Worker case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> ~Y & X
2151*9880d681SAndroid Build Coastguard Worker Temp = DAG.getNOT(dl, N1, MVT::i1);
2152*9880d681SAndroid Build Coastguard Worker N0 = DAG.getNode(ISD::AND, dl, MVT::i1, N0, Temp);
2153*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
2154*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(Temp.getNode());
2155*9880d681SAndroid Build Coastguard Worker break;
2156*9880d681SAndroid Build Coastguard Worker case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> ~X | Y
2157*9880d681SAndroid Build Coastguard Worker case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> ~X | Y
2158*9880d681SAndroid Build Coastguard Worker Temp = DAG.getNOT(dl, N0, MVT::i1);
2159*9880d681SAndroid Build Coastguard Worker N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N1, Temp);
2160*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
2161*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(Temp.getNode());
2162*9880d681SAndroid Build Coastguard Worker break;
2163*9880d681SAndroid Build Coastguard Worker case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> ~Y | X
2164*9880d681SAndroid Build Coastguard Worker case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> ~Y | X
2165*9880d681SAndroid Build Coastguard Worker Temp = DAG.getNOT(dl, N1, MVT::i1);
2166*9880d681SAndroid Build Coastguard Worker N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N0, Temp);
2167*9880d681SAndroid Build Coastguard Worker break;
2168*9880d681SAndroid Build Coastguard Worker }
2169*9880d681SAndroid Build Coastguard Worker if (VT != MVT::i1) {
2170*9880d681SAndroid Build Coastguard Worker if (!DCI.isCalledByLegalizer())
2171*9880d681SAndroid Build Coastguard Worker DCI.AddToWorklist(N0.getNode());
2172*9880d681SAndroid Build Coastguard Worker // FIXME: If running after legalize, we probably can't do this.
2173*9880d681SAndroid Build Coastguard Worker N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, N0);
2174*9880d681SAndroid Build Coastguard Worker }
2175*9880d681SAndroid Build Coastguard Worker return N0;
2176*9880d681SAndroid Build Coastguard Worker }
2177*9880d681SAndroid Build Coastguard Worker
2178*9880d681SAndroid Build Coastguard Worker // Could not fold it.
2179*9880d681SAndroid Build Coastguard Worker return SDValue();
2180*9880d681SAndroid Build Coastguard Worker }
2181*9880d681SAndroid Build Coastguard Worker
2182*9880d681SAndroid Build Coastguard Worker /// Returns true (and the GlobalValue and the offset) if the node is a
2183*9880d681SAndroid Build Coastguard Worker /// GlobalAddress + offset.
isGAPlusOffset(SDNode * N,const GlobalValue * & GA,int64_t & Offset) const2184*9880d681SAndroid Build Coastguard Worker bool TargetLowering::isGAPlusOffset(SDNode *N, const GlobalValue *&GA,
2185*9880d681SAndroid Build Coastguard Worker int64_t &Offset) const {
2186*9880d681SAndroid Build Coastguard Worker if (auto *GASD = dyn_cast<GlobalAddressSDNode>(N)) {
2187*9880d681SAndroid Build Coastguard Worker GA = GASD->getGlobal();
2188*9880d681SAndroid Build Coastguard Worker Offset += GASD->getOffset();
2189*9880d681SAndroid Build Coastguard Worker return true;
2190*9880d681SAndroid Build Coastguard Worker }
2191*9880d681SAndroid Build Coastguard Worker
2192*9880d681SAndroid Build Coastguard Worker if (N->getOpcode() == ISD::ADD) {
2193*9880d681SAndroid Build Coastguard Worker SDValue N1 = N->getOperand(0);
2194*9880d681SAndroid Build Coastguard Worker SDValue N2 = N->getOperand(1);
2195*9880d681SAndroid Build Coastguard Worker if (isGAPlusOffset(N1.getNode(), GA, Offset)) {
2196*9880d681SAndroid Build Coastguard Worker if (auto *V = dyn_cast<ConstantSDNode>(N2)) {
2197*9880d681SAndroid Build Coastguard Worker Offset += V->getSExtValue();
2198*9880d681SAndroid Build Coastguard Worker return true;
2199*9880d681SAndroid Build Coastguard Worker }
2200*9880d681SAndroid Build Coastguard Worker } else if (isGAPlusOffset(N2.getNode(), GA, Offset)) {
2201*9880d681SAndroid Build Coastguard Worker if (auto *V = dyn_cast<ConstantSDNode>(N1)) {
2202*9880d681SAndroid Build Coastguard Worker Offset += V->getSExtValue();
2203*9880d681SAndroid Build Coastguard Worker return true;
2204*9880d681SAndroid Build Coastguard Worker }
2205*9880d681SAndroid Build Coastguard Worker }
2206*9880d681SAndroid Build Coastguard Worker }
2207*9880d681SAndroid Build Coastguard Worker
2208*9880d681SAndroid Build Coastguard Worker return false;
2209*9880d681SAndroid Build Coastguard Worker }
2210*9880d681SAndroid Build Coastguard Worker
PerformDAGCombine(SDNode * N,DAGCombinerInfo & DCI) const2211*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::PerformDAGCombine(SDNode *N,
2212*9880d681SAndroid Build Coastguard Worker DAGCombinerInfo &DCI) const {
2213*9880d681SAndroid Build Coastguard Worker // Default implementation: no optimization.
2214*9880d681SAndroid Build Coastguard Worker return SDValue();
2215*9880d681SAndroid Build Coastguard Worker }
2216*9880d681SAndroid Build Coastguard Worker
2217*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2218*9880d681SAndroid Build Coastguard Worker // Inline Assembler Implementation Methods
2219*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2220*9880d681SAndroid Build Coastguard Worker
2221*9880d681SAndroid Build Coastguard Worker TargetLowering::ConstraintType
getConstraintType(StringRef Constraint) const2222*9880d681SAndroid Build Coastguard Worker TargetLowering::getConstraintType(StringRef Constraint) const {
2223*9880d681SAndroid Build Coastguard Worker unsigned S = Constraint.size();
2224*9880d681SAndroid Build Coastguard Worker
2225*9880d681SAndroid Build Coastguard Worker if (S == 1) {
2226*9880d681SAndroid Build Coastguard Worker switch (Constraint[0]) {
2227*9880d681SAndroid Build Coastguard Worker default: break;
2228*9880d681SAndroid Build Coastguard Worker case 'r': return C_RegisterClass;
2229*9880d681SAndroid Build Coastguard Worker case 'm': // memory
2230*9880d681SAndroid Build Coastguard Worker case 'o': // offsetable
2231*9880d681SAndroid Build Coastguard Worker case 'V': // not offsetable
2232*9880d681SAndroid Build Coastguard Worker return C_Memory;
2233*9880d681SAndroid Build Coastguard Worker case 'i': // Simple Integer or Relocatable Constant
2234*9880d681SAndroid Build Coastguard Worker case 'n': // Simple Integer
2235*9880d681SAndroid Build Coastguard Worker case 'E': // Floating Point Constant
2236*9880d681SAndroid Build Coastguard Worker case 'F': // Floating Point Constant
2237*9880d681SAndroid Build Coastguard Worker case 's': // Relocatable Constant
2238*9880d681SAndroid Build Coastguard Worker case 'p': // Address.
2239*9880d681SAndroid Build Coastguard Worker case 'X': // Allow ANY value.
2240*9880d681SAndroid Build Coastguard Worker case 'I': // Target registers.
2241*9880d681SAndroid Build Coastguard Worker case 'J':
2242*9880d681SAndroid Build Coastguard Worker case 'K':
2243*9880d681SAndroid Build Coastguard Worker case 'L':
2244*9880d681SAndroid Build Coastguard Worker case 'M':
2245*9880d681SAndroid Build Coastguard Worker case 'N':
2246*9880d681SAndroid Build Coastguard Worker case 'O':
2247*9880d681SAndroid Build Coastguard Worker case 'P':
2248*9880d681SAndroid Build Coastguard Worker case '<':
2249*9880d681SAndroid Build Coastguard Worker case '>':
2250*9880d681SAndroid Build Coastguard Worker return C_Other;
2251*9880d681SAndroid Build Coastguard Worker }
2252*9880d681SAndroid Build Coastguard Worker }
2253*9880d681SAndroid Build Coastguard Worker
2254*9880d681SAndroid Build Coastguard Worker if (S > 1 && Constraint[0] == '{' && Constraint[S-1] == '}') {
2255*9880d681SAndroid Build Coastguard Worker if (S == 8 && Constraint.substr(1, 6) == "memory") // "{memory}"
2256*9880d681SAndroid Build Coastguard Worker return C_Memory;
2257*9880d681SAndroid Build Coastguard Worker return C_Register;
2258*9880d681SAndroid Build Coastguard Worker }
2259*9880d681SAndroid Build Coastguard Worker return C_Unknown;
2260*9880d681SAndroid Build Coastguard Worker }
2261*9880d681SAndroid Build Coastguard Worker
2262*9880d681SAndroid Build Coastguard Worker /// Try to replace an X constraint, which matches anything, with another that
2263*9880d681SAndroid Build Coastguard Worker /// has more specific requirements based on the type of the corresponding
2264*9880d681SAndroid Build Coastguard Worker /// operand.
LowerXConstraint(EVT ConstraintVT) const2265*9880d681SAndroid Build Coastguard Worker const char *TargetLowering::LowerXConstraint(EVT ConstraintVT) const{
2266*9880d681SAndroid Build Coastguard Worker if (ConstraintVT.isInteger())
2267*9880d681SAndroid Build Coastguard Worker return "r";
2268*9880d681SAndroid Build Coastguard Worker if (ConstraintVT.isFloatingPoint())
2269*9880d681SAndroid Build Coastguard Worker return "f"; // works for many targets
2270*9880d681SAndroid Build Coastguard Worker return nullptr;
2271*9880d681SAndroid Build Coastguard Worker }
2272*9880d681SAndroid Build Coastguard Worker
2273*9880d681SAndroid Build Coastguard Worker /// Lower the specified operand into the Ops vector.
2274*9880d681SAndroid Build Coastguard Worker /// If it is invalid, don't add anything to Ops.
LowerAsmOperandForConstraint(SDValue Op,std::string & Constraint,std::vector<SDValue> & Ops,SelectionDAG & DAG) const2275*9880d681SAndroid Build Coastguard Worker void TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
2276*9880d681SAndroid Build Coastguard Worker std::string &Constraint,
2277*9880d681SAndroid Build Coastguard Worker std::vector<SDValue> &Ops,
2278*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
2279*9880d681SAndroid Build Coastguard Worker
2280*9880d681SAndroid Build Coastguard Worker if (Constraint.length() > 1) return;
2281*9880d681SAndroid Build Coastguard Worker
2282*9880d681SAndroid Build Coastguard Worker char ConstraintLetter = Constraint[0];
2283*9880d681SAndroid Build Coastguard Worker switch (ConstraintLetter) {
2284*9880d681SAndroid Build Coastguard Worker default: break;
2285*9880d681SAndroid Build Coastguard Worker case 'X': // Allows any operand; labels (basic block) use this.
2286*9880d681SAndroid Build Coastguard Worker if (Op.getOpcode() == ISD::BasicBlock) {
2287*9880d681SAndroid Build Coastguard Worker Ops.push_back(Op);
2288*9880d681SAndroid Build Coastguard Worker return;
2289*9880d681SAndroid Build Coastguard Worker }
2290*9880d681SAndroid Build Coastguard Worker // fall through
2291*9880d681SAndroid Build Coastguard Worker case 'i': // Simple Integer or Relocatable Constant
2292*9880d681SAndroid Build Coastguard Worker case 'n': // Simple Integer
2293*9880d681SAndroid Build Coastguard Worker case 's': { // Relocatable Constant
2294*9880d681SAndroid Build Coastguard Worker // These operands are interested in values of the form (GV+C), where C may
2295*9880d681SAndroid Build Coastguard Worker // be folded in as an offset of GV, or it may be explicitly added. Also, it
2296*9880d681SAndroid Build Coastguard Worker // is possible and fine if either GV or C are missing.
2297*9880d681SAndroid Build Coastguard Worker ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
2298*9880d681SAndroid Build Coastguard Worker GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op);
2299*9880d681SAndroid Build Coastguard Worker
2300*9880d681SAndroid Build Coastguard Worker // If we have "(add GV, C)", pull out GV/C
2301*9880d681SAndroid Build Coastguard Worker if (Op.getOpcode() == ISD::ADD) {
2302*9880d681SAndroid Build Coastguard Worker C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
2303*9880d681SAndroid Build Coastguard Worker GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
2304*9880d681SAndroid Build Coastguard Worker if (!C || !GA) {
2305*9880d681SAndroid Build Coastguard Worker C = dyn_cast<ConstantSDNode>(Op.getOperand(0));
2306*9880d681SAndroid Build Coastguard Worker GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(1));
2307*9880d681SAndroid Build Coastguard Worker }
2308*9880d681SAndroid Build Coastguard Worker if (!C || !GA) {
2309*9880d681SAndroid Build Coastguard Worker C = nullptr;
2310*9880d681SAndroid Build Coastguard Worker GA = nullptr;
2311*9880d681SAndroid Build Coastguard Worker }
2312*9880d681SAndroid Build Coastguard Worker }
2313*9880d681SAndroid Build Coastguard Worker
2314*9880d681SAndroid Build Coastguard Worker // If we find a valid operand, map to the TargetXXX version so that the
2315*9880d681SAndroid Build Coastguard Worker // value itself doesn't get selected.
2316*9880d681SAndroid Build Coastguard Worker if (GA) { // Either &GV or &GV+C
2317*9880d681SAndroid Build Coastguard Worker if (ConstraintLetter != 'n') {
2318*9880d681SAndroid Build Coastguard Worker int64_t Offs = GA->getOffset();
2319*9880d681SAndroid Build Coastguard Worker if (C) Offs += C->getZExtValue();
2320*9880d681SAndroid Build Coastguard Worker Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(),
2321*9880d681SAndroid Build Coastguard Worker C ? SDLoc(C) : SDLoc(),
2322*9880d681SAndroid Build Coastguard Worker Op.getValueType(), Offs));
2323*9880d681SAndroid Build Coastguard Worker }
2324*9880d681SAndroid Build Coastguard Worker return;
2325*9880d681SAndroid Build Coastguard Worker }
2326*9880d681SAndroid Build Coastguard Worker if (C) { // just C, no GV.
2327*9880d681SAndroid Build Coastguard Worker // Simple constants are not allowed for 's'.
2328*9880d681SAndroid Build Coastguard Worker if (ConstraintLetter != 's') {
2329*9880d681SAndroid Build Coastguard Worker // gcc prints these as sign extended. Sign extend value to 64 bits
2330*9880d681SAndroid Build Coastguard Worker // now; without this it would get ZExt'd later in
2331*9880d681SAndroid Build Coastguard Worker // ScheduleDAGSDNodes::EmitNode, which is very generic.
2332*9880d681SAndroid Build Coastguard Worker Ops.push_back(DAG.getTargetConstant(C->getAPIntValue().getSExtValue(),
2333*9880d681SAndroid Build Coastguard Worker SDLoc(C), MVT::i64));
2334*9880d681SAndroid Build Coastguard Worker }
2335*9880d681SAndroid Build Coastguard Worker return;
2336*9880d681SAndroid Build Coastguard Worker }
2337*9880d681SAndroid Build Coastguard Worker break;
2338*9880d681SAndroid Build Coastguard Worker }
2339*9880d681SAndroid Build Coastguard Worker }
2340*9880d681SAndroid Build Coastguard Worker }
2341*9880d681SAndroid Build Coastguard Worker
2342*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo * RI,StringRef Constraint,MVT VT) const2343*9880d681SAndroid Build Coastguard Worker TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *RI,
2344*9880d681SAndroid Build Coastguard Worker StringRef Constraint,
2345*9880d681SAndroid Build Coastguard Worker MVT VT) const {
2346*9880d681SAndroid Build Coastguard Worker if (Constraint.empty() || Constraint[0] != '{')
2347*9880d681SAndroid Build Coastguard Worker return std::make_pair(0u, static_cast<TargetRegisterClass*>(nullptr));
2348*9880d681SAndroid Build Coastguard Worker assert(*(Constraint.end()-1) == '}' && "Not a brace enclosed constraint?");
2349*9880d681SAndroid Build Coastguard Worker
2350*9880d681SAndroid Build Coastguard Worker // Remove the braces from around the name.
2351*9880d681SAndroid Build Coastguard Worker StringRef RegName(Constraint.data()+1, Constraint.size()-2);
2352*9880d681SAndroid Build Coastguard Worker
2353*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, const TargetRegisterClass*> R =
2354*9880d681SAndroid Build Coastguard Worker std::make_pair(0u, static_cast<const TargetRegisterClass*>(nullptr));
2355*9880d681SAndroid Build Coastguard Worker
2356*9880d681SAndroid Build Coastguard Worker // Figure out which register class contains this reg.
2357*9880d681SAndroid Build Coastguard Worker for (TargetRegisterInfo::regclass_iterator RCI = RI->regclass_begin(),
2358*9880d681SAndroid Build Coastguard Worker E = RI->regclass_end(); RCI != E; ++RCI) {
2359*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = *RCI;
2360*9880d681SAndroid Build Coastguard Worker
2361*9880d681SAndroid Build Coastguard Worker // If none of the value types for this register class are valid, we
2362*9880d681SAndroid Build Coastguard Worker // can't use it. For example, 64-bit reg classes on 32-bit targets.
2363*9880d681SAndroid Build Coastguard Worker if (!isLegalRC(RC))
2364*9880d681SAndroid Build Coastguard Worker continue;
2365*9880d681SAndroid Build Coastguard Worker
2366*9880d681SAndroid Build Coastguard Worker for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
2367*9880d681SAndroid Build Coastguard Worker I != E; ++I) {
2368*9880d681SAndroid Build Coastguard Worker if (RegName.equals_lower(RI->getRegAsmName(*I))) {
2369*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, const TargetRegisterClass*> S =
2370*9880d681SAndroid Build Coastguard Worker std::make_pair(*I, RC);
2371*9880d681SAndroid Build Coastguard Worker
2372*9880d681SAndroid Build Coastguard Worker // If this register class has the requested value type, return it,
2373*9880d681SAndroid Build Coastguard Worker // otherwise keep searching and return the first class found
2374*9880d681SAndroid Build Coastguard Worker // if no other is found which explicitly has the requested type.
2375*9880d681SAndroid Build Coastguard Worker if (RC->hasType(VT))
2376*9880d681SAndroid Build Coastguard Worker return S;
2377*9880d681SAndroid Build Coastguard Worker else if (!R.second)
2378*9880d681SAndroid Build Coastguard Worker R = S;
2379*9880d681SAndroid Build Coastguard Worker }
2380*9880d681SAndroid Build Coastguard Worker }
2381*9880d681SAndroid Build Coastguard Worker }
2382*9880d681SAndroid Build Coastguard Worker
2383*9880d681SAndroid Build Coastguard Worker return R;
2384*9880d681SAndroid Build Coastguard Worker }
2385*9880d681SAndroid Build Coastguard Worker
2386*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2387*9880d681SAndroid Build Coastguard Worker // Constraint Selection.
2388*9880d681SAndroid Build Coastguard Worker
2389*9880d681SAndroid Build Coastguard Worker /// Return true of this is an input operand that is a matching constraint like
2390*9880d681SAndroid Build Coastguard Worker /// "4".
isMatchingInputConstraint() const2391*9880d681SAndroid Build Coastguard Worker bool TargetLowering::AsmOperandInfo::isMatchingInputConstraint() const {
2392*9880d681SAndroid Build Coastguard Worker assert(!ConstraintCode.empty() && "No known constraint!");
2393*9880d681SAndroid Build Coastguard Worker return isdigit(static_cast<unsigned char>(ConstraintCode[0]));
2394*9880d681SAndroid Build Coastguard Worker }
2395*9880d681SAndroid Build Coastguard Worker
2396*9880d681SAndroid Build Coastguard Worker /// If this is an input matching constraint, this method returns the output
2397*9880d681SAndroid Build Coastguard Worker /// operand it matches.
getMatchedOperand() const2398*9880d681SAndroid Build Coastguard Worker unsigned TargetLowering::AsmOperandInfo::getMatchedOperand() const {
2399*9880d681SAndroid Build Coastguard Worker assert(!ConstraintCode.empty() && "No known constraint!");
2400*9880d681SAndroid Build Coastguard Worker return atoi(ConstraintCode.c_str());
2401*9880d681SAndroid Build Coastguard Worker }
2402*9880d681SAndroid Build Coastguard Worker
2403*9880d681SAndroid Build Coastguard Worker /// Split up the constraint string from the inline assembly value into the
2404*9880d681SAndroid Build Coastguard Worker /// specific constraints and their prefixes, and also tie in the associated
2405*9880d681SAndroid Build Coastguard Worker /// operand values.
2406*9880d681SAndroid Build Coastguard Worker /// If this returns an empty vector, and if the constraint string itself
2407*9880d681SAndroid Build Coastguard Worker /// isn't empty, there was an error parsing.
2408*9880d681SAndroid Build Coastguard Worker TargetLowering::AsmOperandInfoVector
ParseConstraints(const DataLayout & DL,const TargetRegisterInfo * TRI,ImmutableCallSite CS) const2409*9880d681SAndroid Build Coastguard Worker TargetLowering::ParseConstraints(const DataLayout &DL,
2410*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI,
2411*9880d681SAndroid Build Coastguard Worker ImmutableCallSite CS) const {
2412*9880d681SAndroid Build Coastguard Worker /// Information about all of the constraints.
2413*9880d681SAndroid Build Coastguard Worker AsmOperandInfoVector ConstraintOperands;
2414*9880d681SAndroid Build Coastguard Worker const InlineAsm *IA = cast<InlineAsm>(CS.getCalledValue());
2415*9880d681SAndroid Build Coastguard Worker unsigned maCount = 0; // Largest number of multiple alternative constraints.
2416*9880d681SAndroid Build Coastguard Worker
2417*9880d681SAndroid Build Coastguard Worker // Do a prepass over the constraints, canonicalizing them, and building up the
2418*9880d681SAndroid Build Coastguard Worker // ConstraintOperands list.
2419*9880d681SAndroid Build Coastguard Worker unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.
2420*9880d681SAndroid Build Coastguard Worker unsigned ResNo = 0; // ResNo - The result number of the next output.
2421*9880d681SAndroid Build Coastguard Worker
2422*9880d681SAndroid Build Coastguard Worker for (InlineAsm::ConstraintInfo &CI : IA->ParseConstraints()) {
2423*9880d681SAndroid Build Coastguard Worker ConstraintOperands.emplace_back(std::move(CI));
2424*9880d681SAndroid Build Coastguard Worker AsmOperandInfo &OpInfo = ConstraintOperands.back();
2425*9880d681SAndroid Build Coastguard Worker
2426*9880d681SAndroid Build Coastguard Worker // Update multiple alternative constraint count.
2427*9880d681SAndroid Build Coastguard Worker if (OpInfo.multipleAlternatives.size() > maCount)
2428*9880d681SAndroid Build Coastguard Worker maCount = OpInfo.multipleAlternatives.size();
2429*9880d681SAndroid Build Coastguard Worker
2430*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintVT = MVT::Other;
2431*9880d681SAndroid Build Coastguard Worker
2432*9880d681SAndroid Build Coastguard Worker // Compute the value type for each operand.
2433*9880d681SAndroid Build Coastguard Worker switch (OpInfo.Type) {
2434*9880d681SAndroid Build Coastguard Worker case InlineAsm::isOutput:
2435*9880d681SAndroid Build Coastguard Worker // Indirect outputs just consume an argument.
2436*9880d681SAndroid Build Coastguard Worker if (OpInfo.isIndirect) {
2437*9880d681SAndroid Build Coastguard Worker OpInfo.CallOperandVal = const_cast<Value *>(CS.getArgument(ArgNo++));
2438*9880d681SAndroid Build Coastguard Worker break;
2439*9880d681SAndroid Build Coastguard Worker }
2440*9880d681SAndroid Build Coastguard Worker
2441*9880d681SAndroid Build Coastguard Worker // The return value of the call is this value. As such, there is no
2442*9880d681SAndroid Build Coastguard Worker // corresponding argument.
2443*9880d681SAndroid Build Coastguard Worker assert(!CS.getType()->isVoidTy() &&
2444*9880d681SAndroid Build Coastguard Worker "Bad inline asm!");
2445*9880d681SAndroid Build Coastguard Worker if (StructType *STy = dyn_cast<StructType>(CS.getType())) {
2446*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintVT =
2447*9880d681SAndroid Build Coastguard Worker getSimpleValueType(DL, STy->getElementType(ResNo));
2448*9880d681SAndroid Build Coastguard Worker } else {
2449*9880d681SAndroid Build Coastguard Worker assert(ResNo == 0 && "Asm only has one result!");
2450*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintVT = getSimpleValueType(DL, CS.getType());
2451*9880d681SAndroid Build Coastguard Worker }
2452*9880d681SAndroid Build Coastguard Worker ++ResNo;
2453*9880d681SAndroid Build Coastguard Worker break;
2454*9880d681SAndroid Build Coastguard Worker case InlineAsm::isInput:
2455*9880d681SAndroid Build Coastguard Worker OpInfo.CallOperandVal = const_cast<Value *>(CS.getArgument(ArgNo++));
2456*9880d681SAndroid Build Coastguard Worker break;
2457*9880d681SAndroid Build Coastguard Worker case InlineAsm::isClobber:
2458*9880d681SAndroid Build Coastguard Worker // Nothing to do.
2459*9880d681SAndroid Build Coastguard Worker break;
2460*9880d681SAndroid Build Coastguard Worker }
2461*9880d681SAndroid Build Coastguard Worker
2462*9880d681SAndroid Build Coastguard Worker if (OpInfo.CallOperandVal) {
2463*9880d681SAndroid Build Coastguard Worker llvm::Type *OpTy = OpInfo.CallOperandVal->getType();
2464*9880d681SAndroid Build Coastguard Worker if (OpInfo.isIndirect) {
2465*9880d681SAndroid Build Coastguard Worker llvm::PointerType *PtrTy = dyn_cast<PointerType>(OpTy);
2466*9880d681SAndroid Build Coastguard Worker if (!PtrTy)
2467*9880d681SAndroid Build Coastguard Worker report_fatal_error("Indirect operand for inline asm not a pointer!");
2468*9880d681SAndroid Build Coastguard Worker OpTy = PtrTy->getElementType();
2469*9880d681SAndroid Build Coastguard Worker }
2470*9880d681SAndroid Build Coastguard Worker
2471*9880d681SAndroid Build Coastguard Worker // Look for vector wrapped in a struct. e.g. { <16 x i8> }.
2472*9880d681SAndroid Build Coastguard Worker if (StructType *STy = dyn_cast<StructType>(OpTy))
2473*9880d681SAndroid Build Coastguard Worker if (STy->getNumElements() == 1)
2474*9880d681SAndroid Build Coastguard Worker OpTy = STy->getElementType(0);
2475*9880d681SAndroid Build Coastguard Worker
2476*9880d681SAndroid Build Coastguard Worker // If OpTy is not a single value, it may be a struct/union that we
2477*9880d681SAndroid Build Coastguard Worker // can tile with integers.
2478*9880d681SAndroid Build Coastguard Worker if (!OpTy->isSingleValueType() && OpTy->isSized()) {
2479*9880d681SAndroid Build Coastguard Worker unsigned BitSize = DL.getTypeSizeInBits(OpTy);
2480*9880d681SAndroid Build Coastguard Worker switch (BitSize) {
2481*9880d681SAndroid Build Coastguard Worker default: break;
2482*9880d681SAndroid Build Coastguard Worker case 1:
2483*9880d681SAndroid Build Coastguard Worker case 8:
2484*9880d681SAndroid Build Coastguard Worker case 16:
2485*9880d681SAndroid Build Coastguard Worker case 32:
2486*9880d681SAndroid Build Coastguard Worker case 64:
2487*9880d681SAndroid Build Coastguard Worker case 128:
2488*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintVT =
2489*9880d681SAndroid Build Coastguard Worker MVT::getVT(IntegerType::get(OpTy->getContext(), BitSize), true);
2490*9880d681SAndroid Build Coastguard Worker break;
2491*9880d681SAndroid Build Coastguard Worker }
2492*9880d681SAndroid Build Coastguard Worker } else if (PointerType *PT = dyn_cast<PointerType>(OpTy)) {
2493*9880d681SAndroid Build Coastguard Worker unsigned PtrSize = DL.getPointerSizeInBits(PT->getAddressSpace());
2494*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintVT = MVT::getIntegerVT(PtrSize);
2495*9880d681SAndroid Build Coastguard Worker } else {
2496*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintVT = MVT::getVT(OpTy, true);
2497*9880d681SAndroid Build Coastguard Worker }
2498*9880d681SAndroid Build Coastguard Worker }
2499*9880d681SAndroid Build Coastguard Worker }
2500*9880d681SAndroid Build Coastguard Worker
2501*9880d681SAndroid Build Coastguard Worker // If we have multiple alternative constraints, select the best alternative.
2502*9880d681SAndroid Build Coastguard Worker if (!ConstraintOperands.empty()) {
2503*9880d681SAndroid Build Coastguard Worker if (maCount) {
2504*9880d681SAndroid Build Coastguard Worker unsigned bestMAIndex = 0;
2505*9880d681SAndroid Build Coastguard Worker int bestWeight = -1;
2506*9880d681SAndroid Build Coastguard Worker // weight: -1 = invalid match, and 0 = so-so match to 5 = good match.
2507*9880d681SAndroid Build Coastguard Worker int weight = -1;
2508*9880d681SAndroid Build Coastguard Worker unsigned maIndex;
2509*9880d681SAndroid Build Coastguard Worker // Compute the sums of the weights for each alternative, keeping track
2510*9880d681SAndroid Build Coastguard Worker // of the best (highest weight) one so far.
2511*9880d681SAndroid Build Coastguard Worker for (maIndex = 0; maIndex < maCount; ++maIndex) {
2512*9880d681SAndroid Build Coastguard Worker int weightSum = 0;
2513*9880d681SAndroid Build Coastguard Worker for (unsigned cIndex = 0, eIndex = ConstraintOperands.size();
2514*9880d681SAndroid Build Coastguard Worker cIndex != eIndex; ++cIndex) {
2515*9880d681SAndroid Build Coastguard Worker AsmOperandInfo& OpInfo = ConstraintOperands[cIndex];
2516*9880d681SAndroid Build Coastguard Worker if (OpInfo.Type == InlineAsm::isClobber)
2517*9880d681SAndroid Build Coastguard Worker continue;
2518*9880d681SAndroid Build Coastguard Worker
2519*9880d681SAndroid Build Coastguard Worker // If this is an output operand with a matching input operand,
2520*9880d681SAndroid Build Coastguard Worker // look up the matching input. If their types mismatch, e.g. one
2521*9880d681SAndroid Build Coastguard Worker // is an integer, the other is floating point, or their sizes are
2522*9880d681SAndroid Build Coastguard Worker // different, flag it as an maCantMatch.
2523*9880d681SAndroid Build Coastguard Worker if (OpInfo.hasMatchingInput()) {
2524*9880d681SAndroid Build Coastguard Worker AsmOperandInfo &Input = ConstraintOperands[OpInfo.MatchingInput];
2525*9880d681SAndroid Build Coastguard Worker if (OpInfo.ConstraintVT != Input.ConstraintVT) {
2526*9880d681SAndroid Build Coastguard Worker if ((OpInfo.ConstraintVT.isInteger() !=
2527*9880d681SAndroid Build Coastguard Worker Input.ConstraintVT.isInteger()) ||
2528*9880d681SAndroid Build Coastguard Worker (OpInfo.ConstraintVT.getSizeInBits() !=
2529*9880d681SAndroid Build Coastguard Worker Input.ConstraintVT.getSizeInBits())) {
2530*9880d681SAndroid Build Coastguard Worker weightSum = -1; // Can't match.
2531*9880d681SAndroid Build Coastguard Worker break;
2532*9880d681SAndroid Build Coastguard Worker }
2533*9880d681SAndroid Build Coastguard Worker }
2534*9880d681SAndroid Build Coastguard Worker }
2535*9880d681SAndroid Build Coastguard Worker weight = getMultipleConstraintMatchWeight(OpInfo, maIndex);
2536*9880d681SAndroid Build Coastguard Worker if (weight == -1) {
2537*9880d681SAndroid Build Coastguard Worker weightSum = -1;
2538*9880d681SAndroid Build Coastguard Worker break;
2539*9880d681SAndroid Build Coastguard Worker }
2540*9880d681SAndroid Build Coastguard Worker weightSum += weight;
2541*9880d681SAndroid Build Coastguard Worker }
2542*9880d681SAndroid Build Coastguard Worker // Update best.
2543*9880d681SAndroid Build Coastguard Worker if (weightSum > bestWeight) {
2544*9880d681SAndroid Build Coastguard Worker bestWeight = weightSum;
2545*9880d681SAndroid Build Coastguard Worker bestMAIndex = maIndex;
2546*9880d681SAndroid Build Coastguard Worker }
2547*9880d681SAndroid Build Coastguard Worker }
2548*9880d681SAndroid Build Coastguard Worker
2549*9880d681SAndroid Build Coastguard Worker // Now select chosen alternative in each constraint.
2550*9880d681SAndroid Build Coastguard Worker for (unsigned cIndex = 0, eIndex = ConstraintOperands.size();
2551*9880d681SAndroid Build Coastguard Worker cIndex != eIndex; ++cIndex) {
2552*9880d681SAndroid Build Coastguard Worker AsmOperandInfo& cInfo = ConstraintOperands[cIndex];
2553*9880d681SAndroid Build Coastguard Worker if (cInfo.Type == InlineAsm::isClobber)
2554*9880d681SAndroid Build Coastguard Worker continue;
2555*9880d681SAndroid Build Coastguard Worker cInfo.selectAlternative(bestMAIndex);
2556*9880d681SAndroid Build Coastguard Worker }
2557*9880d681SAndroid Build Coastguard Worker }
2558*9880d681SAndroid Build Coastguard Worker }
2559*9880d681SAndroid Build Coastguard Worker
2560*9880d681SAndroid Build Coastguard Worker // Check and hook up tied operands, choose constraint code to use.
2561*9880d681SAndroid Build Coastguard Worker for (unsigned cIndex = 0, eIndex = ConstraintOperands.size();
2562*9880d681SAndroid Build Coastguard Worker cIndex != eIndex; ++cIndex) {
2563*9880d681SAndroid Build Coastguard Worker AsmOperandInfo& OpInfo = ConstraintOperands[cIndex];
2564*9880d681SAndroid Build Coastguard Worker
2565*9880d681SAndroid Build Coastguard Worker // If this is an output operand with a matching input operand, look up the
2566*9880d681SAndroid Build Coastguard Worker // matching input. If their types mismatch, e.g. one is an integer, the
2567*9880d681SAndroid Build Coastguard Worker // other is floating point, or their sizes are different, flag it as an
2568*9880d681SAndroid Build Coastguard Worker // error.
2569*9880d681SAndroid Build Coastguard Worker if (OpInfo.hasMatchingInput()) {
2570*9880d681SAndroid Build Coastguard Worker AsmOperandInfo &Input = ConstraintOperands[OpInfo.MatchingInput];
2571*9880d681SAndroid Build Coastguard Worker
2572*9880d681SAndroid Build Coastguard Worker if (OpInfo.ConstraintVT != Input.ConstraintVT) {
2573*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, const TargetRegisterClass *> MatchRC =
2574*9880d681SAndroid Build Coastguard Worker getRegForInlineAsmConstraint(TRI, OpInfo.ConstraintCode,
2575*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintVT);
2576*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, const TargetRegisterClass *> InputRC =
2577*9880d681SAndroid Build Coastguard Worker getRegForInlineAsmConstraint(TRI, Input.ConstraintCode,
2578*9880d681SAndroid Build Coastguard Worker Input.ConstraintVT);
2579*9880d681SAndroid Build Coastguard Worker if ((OpInfo.ConstraintVT.isInteger() !=
2580*9880d681SAndroid Build Coastguard Worker Input.ConstraintVT.isInteger()) ||
2581*9880d681SAndroid Build Coastguard Worker (MatchRC.second != InputRC.second)) {
2582*9880d681SAndroid Build Coastguard Worker report_fatal_error("Unsupported asm: input constraint"
2583*9880d681SAndroid Build Coastguard Worker " with a matching output constraint of"
2584*9880d681SAndroid Build Coastguard Worker " incompatible type!");
2585*9880d681SAndroid Build Coastguard Worker }
2586*9880d681SAndroid Build Coastguard Worker }
2587*9880d681SAndroid Build Coastguard Worker }
2588*9880d681SAndroid Build Coastguard Worker }
2589*9880d681SAndroid Build Coastguard Worker
2590*9880d681SAndroid Build Coastguard Worker return ConstraintOperands;
2591*9880d681SAndroid Build Coastguard Worker }
2592*9880d681SAndroid Build Coastguard Worker
2593*9880d681SAndroid Build Coastguard Worker /// Return an integer indicating how general CT is.
getConstraintGenerality(TargetLowering::ConstraintType CT)2594*9880d681SAndroid Build Coastguard Worker static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {
2595*9880d681SAndroid Build Coastguard Worker switch (CT) {
2596*9880d681SAndroid Build Coastguard Worker case TargetLowering::C_Other:
2597*9880d681SAndroid Build Coastguard Worker case TargetLowering::C_Unknown:
2598*9880d681SAndroid Build Coastguard Worker return 0;
2599*9880d681SAndroid Build Coastguard Worker case TargetLowering::C_Register:
2600*9880d681SAndroid Build Coastguard Worker return 1;
2601*9880d681SAndroid Build Coastguard Worker case TargetLowering::C_RegisterClass:
2602*9880d681SAndroid Build Coastguard Worker return 2;
2603*9880d681SAndroid Build Coastguard Worker case TargetLowering::C_Memory:
2604*9880d681SAndroid Build Coastguard Worker return 3;
2605*9880d681SAndroid Build Coastguard Worker }
2606*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid constraint type");
2607*9880d681SAndroid Build Coastguard Worker }
2608*9880d681SAndroid Build Coastguard Worker
2609*9880d681SAndroid Build Coastguard Worker /// Examine constraint type and operand type and determine a weight value.
2610*9880d681SAndroid Build Coastguard Worker /// This object must already have been set up with the operand type
2611*9880d681SAndroid Build Coastguard Worker /// and the current alternative constraint selected.
2612*9880d681SAndroid Build Coastguard Worker TargetLowering::ConstraintWeight
getMultipleConstraintMatchWeight(AsmOperandInfo & info,int maIndex) const2613*9880d681SAndroid Build Coastguard Worker TargetLowering::getMultipleConstraintMatchWeight(
2614*9880d681SAndroid Build Coastguard Worker AsmOperandInfo &info, int maIndex) const {
2615*9880d681SAndroid Build Coastguard Worker InlineAsm::ConstraintCodeVector *rCodes;
2616*9880d681SAndroid Build Coastguard Worker if (maIndex >= (int)info.multipleAlternatives.size())
2617*9880d681SAndroid Build Coastguard Worker rCodes = &info.Codes;
2618*9880d681SAndroid Build Coastguard Worker else
2619*9880d681SAndroid Build Coastguard Worker rCodes = &info.multipleAlternatives[maIndex].Codes;
2620*9880d681SAndroid Build Coastguard Worker ConstraintWeight BestWeight = CW_Invalid;
2621*9880d681SAndroid Build Coastguard Worker
2622*9880d681SAndroid Build Coastguard Worker // Loop over the options, keeping track of the most general one.
2623*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = rCodes->size(); i != e; ++i) {
2624*9880d681SAndroid Build Coastguard Worker ConstraintWeight weight =
2625*9880d681SAndroid Build Coastguard Worker getSingleConstraintMatchWeight(info, (*rCodes)[i].c_str());
2626*9880d681SAndroid Build Coastguard Worker if (weight > BestWeight)
2627*9880d681SAndroid Build Coastguard Worker BestWeight = weight;
2628*9880d681SAndroid Build Coastguard Worker }
2629*9880d681SAndroid Build Coastguard Worker
2630*9880d681SAndroid Build Coastguard Worker return BestWeight;
2631*9880d681SAndroid Build Coastguard Worker }
2632*9880d681SAndroid Build Coastguard Worker
2633*9880d681SAndroid Build Coastguard Worker /// Examine constraint type and operand type and determine a weight value.
2634*9880d681SAndroid Build Coastguard Worker /// This object must already have been set up with the operand type
2635*9880d681SAndroid Build Coastguard Worker /// and the current alternative constraint selected.
2636*9880d681SAndroid Build Coastguard Worker TargetLowering::ConstraintWeight
getSingleConstraintMatchWeight(AsmOperandInfo & info,const char * constraint) const2637*9880d681SAndroid Build Coastguard Worker TargetLowering::getSingleConstraintMatchWeight(
2638*9880d681SAndroid Build Coastguard Worker AsmOperandInfo &info, const char *constraint) const {
2639*9880d681SAndroid Build Coastguard Worker ConstraintWeight weight = CW_Invalid;
2640*9880d681SAndroid Build Coastguard Worker Value *CallOperandVal = info.CallOperandVal;
2641*9880d681SAndroid Build Coastguard Worker // If we don't have a value, we can't do a match,
2642*9880d681SAndroid Build Coastguard Worker // but allow it at the lowest weight.
2643*9880d681SAndroid Build Coastguard Worker if (!CallOperandVal)
2644*9880d681SAndroid Build Coastguard Worker return CW_Default;
2645*9880d681SAndroid Build Coastguard Worker // Look at the constraint type.
2646*9880d681SAndroid Build Coastguard Worker switch (*constraint) {
2647*9880d681SAndroid Build Coastguard Worker case 'i': // immediate integer.
2648*9880d681SAndroid Build Coastguard Worker case 'n': // immediate integer with a known value.
2649*9880d681SAndroid Build Coastguard Worker if (isa<ConstantInt>(CallOperandVal))
2650*9880d681SAndroid Build Coastguard Worker weight = CW_Constant;
2651*9880d681SAndroid Build Coastguard Worker break;
2652*9880d681SAndroid Build Coastguard Worker case 's': // non-explicit intregal immediate.
2653*9880d681SAndroid Build Coastguard Worker if (isa<GlobalValue>(CallOperandVal))
2654*9880d681SAndroid Build Coastguard Worker weight = CW_Constant;
2655*9880d681SAndroid Build Coastguard Worker break;
2656*9880d681SAndroid Build Coastguard Worker case 'E': // immediate float if host format.
2657*9880d681SAndroid Build Coastguard Worker case 'F': // immediate float.
2658*9880d681SAndroid Build Coastguard Worker if (isa<ConstantFP>(CallOperandVal))
2659*9880d681SAndroid Build Coastguard Worker weight = CW_Constant;
2660*9880d681SAndroid Build Coastguard Worker break;
2661*9880d681SAndroid Build Coastguard Worker case '<': // memory operand with autodecrement.
2662*9880d681SAndroid Build Coastguard Worker case '>': // memory operand with autoincrement.
2663*9880d681SAndroid Build Coastguard Worker case 'm': // memory operand.
2664*9880d681SAndroid Build Coastguard Worker case 'o': // offsettable memory operand
2665*9880d681SAndroid Build Coastguard Worker case 'V': // non-offsettable memory operand
2666*9880d681SAndroid Build Coastguard Worker weight = CW_Memory;
2667*9880d681SAndroid Build Coastguard Worker break;
2668*9880d681SAndroid Build Coastguard Worker case 'r': // general register.
2669*9880d681SAndroid Build Coastguard Worker case 'g': // general register, memory operand or immediate integer.
2670*9880d681SAndroid Build Coastguard Worker // note: Clang converts "g" to "imr".
2671*9880d681SAndroid Build Coastguard Worker if (CallOperandVal->getType()->isIntegerTy())
2672*9880d681SAndroid Build Coastguard Worker weight = CW_Register;
2673*9880d681SAndroid Build Coastguard Worker break;
2674*9880d681SAndroid Build Coastguard Worker case 'X': // any operand.
2675*9880d681SAndroid Build Coastguard Worker default:
2676*9880d681SAndroid Build Coastguard Worker weight = CW_Default;
2677*9880d681SAndroid Build Coastguard Worker break;
2678*9880d681SAndroid Build Coastguard Worker }
2679*9880d681SAndroid Build Coastguard Worker return weight;
2680*9880d681SAndroid Build Coastguard Worker }
2681*9880d681SAndroid Build Coastguard Worker
2682*9880d681SAndroid Build Coastguard Worker /// If there are multiple different constraints that we could pick for this
2683*9880d681SAndroid Build Coastguard Worker /// operand (e.g. "imr") try to pick the 'best' one.
2684*9880d681SAndroid Build Coastguard Worker /// This is somewhat tricky: constraints fall into four classes:
2685*9880d681SAndroid Build Coastguard Worker /// Other -> immediates and magic values
2686*9880d681SAndroid Build Coastguard Worker /// Register -> one specific register
2687*9880d681SAndroid Build Coastguard Worker /// RegisterClass -> a group of regs
2688*9880d681SAndroid Build Coastguard Worker /// Memory -> memory
2689*9880d681SAndroid Build Coastguard Worker /// Ideally, we would pick the most specific constraint possible: if we have
2690*9880d681SAndroid Build Coastguard Worker /// something that fits into a register, we would pick it. The problem here
2691*9880d681SAndroid Build Coastguard Worker /// is that if we have something that could either be in a register or in
2692*9880d681SAndroid Build Coastguard Worker /// memory that use of the register could cause selection of *other*
2693*9880d681SAndroid Build Coastguard Worker /// operands to fail: they might only succeed if we pick memory. Because of
2694*9880d681SAndroid Build Coastguard Worker /// this the heuristic we use is:
2695*9880d681SAndroid Build Coastguard Worker ///
2696*9880d681SAndroid Build Coastguard Worker /// 1) If there is an 'other' constraint, and if the operand is valid for
2697*9880d681SAndroid Build Coastguard Worker /// that constraint, use it. This makes us take advantage of 'i'
2698*9880d681SAndroid Build Coastguard Worker /// constraints when available.
2699*9880d681SAndroid Build Coastguard Worker /// 2) Otherwise, pick the most general constraint present. This prefers
2700*9880d681SAndroid Build Coastguard Worker /// 'm' over 'r', for example.
2701*9880d681SAndroid Build Coastguard Worker ///
ChooseConstraint(TargetLowering::AsmOperandInfo & OpInfo,const TargetLowering & TLI,SDValue Op,SelectionDAG * DAG)2702*9880d681SAndroid Build Coastguard Worker static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,
2703*9880d681SAndroid Build Coastguard Worker const TargetLowering &TLI,
2704*9880d681SAndroid Build Coastguard Worker SDValue Op, SelectionDAG *DAG) {
2705*9880d681SAndroid Build Coastguard Worker assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options");
2706*9880d681SAndroid Build Coastguard Worker unsigned BestIdx = 0;
2707*9880d681SAndroid Build Coastguard Worker TargetLowering::ConstraintType BestType = TargetLowering::C_Unknown;
2708*9880d681SAndroid Build Coastguard Worker int BestGenerality = -1;
2709*9880d681SAndroid Build Coastguard Worker
2710*9880d681SAndroid Build Coastguard Worker // Loop over the options, keeping track of the most general one.
2711*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = OpInfo.Codes.size(); i != e; ++i) {
2712*9880d681SAndroid Build Coastguard Worker TargetLowering::ConstraintType CType =
2713*9880d681SAndroid Build Coastguard Worker TLI.getConstraintType(OpInfo.Codes[i]);
2714*9880d681SAndroid Build Coastguard Worker
2715*9880d681SAndroid Build Coastguard Worker // If this is an 'other' constraint, see if the operand is valid for it.
2716*9880d681SAndroid Build Coastguard Worker // For example, on X86 we might have an 'rI' constraint. If the operand
2717*9880d681SAndroid Build Coastguard Worker // is an integer in the range [0..31] we want to use I (saving a load
2718*9880d681SAndroid Build Coastguard Worker // of a register), otherwise we must use 'r'.
2719*9880d681SAndroid Build Coastguard Worker if (CType == TargetLowering::C_Other && Op.getNode()) {
2720*9880d681SAndroid Build Coastguard Worker assert(OpInfo.Codes[i].size() == 1 &&
2721*9880d681SAndroid Build Coastguard Worker "Unhandled multi-letter 'other' constraint");
2722*9880d681SAndroid Build Coastguard Worker std::vector<SDValue> ResultOps;
2723*9880d681SAndroid Build Coastguard Worker TLI.LowerAsmOperandForConstraint(Op, OpInfo.Codes[i],
2724*9880d681SAndroid Build Coastguard Worker ResultOps, *DAG);
2725*9880d681SAndroid Build Coastguard Worker if (!ResultOps.empty()) {
2726*9880d681SAndroid Build Coastguard Worker BestType = CType;
2727*9880d681SAndroid Build Coastguard Worker BestIdx = i;
2728*9880d681SAndroid Build Coastguard Worker break;
2729*9880d681SAndroid Build Coastguard Worker }
2730*9880d681SAndroid Build Coastguard Worker }
2731*9880d681SAndroid Build Coastguard Worker
2732*9880d681SAndroid Build Coastguard Worker // Things with matching constraints can only be registers, per gcc
2733*9880d681SAndroid Build Coastguard Worker // documentation. This mainly affects "g" constraints.
2734*9880d681SAndroid Build Coastguard Worker if (CType == TargetLowering::C_Memory && OpInfo.hasMatchingInput())
2735*9880d681SAndroid Build Coastguard Worker continue;
2736*9880d681SAndroid Build Coastguard Worker
2737*9880d681SAndroid Build Coastguard Worker // This constraint letter is more general than the previous one, use it.
2738*9880d681SAndroid Build Coastguard Worker int Generality = getConstraintGenerality(CType);
2739*9880d681SAndroid Build Coastguard Worker if (Generality > BestGenerality) {
2740*9880d681SAndroid Build Coastguard Worker BestType = CType;
2741*9880d681SAndroid Build Coastguard Worker BestIdx = i;
2742*9880d681SAndroid Build Coastguard Worker BestGenerality = Generality;
2743*9880d681SAndroid Build Coastguard Worker }
2744*9880d681SAndroid Build Coastguard Worker }
2745*9880d681SAndroid Build Coastguard Worker
2746*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintCode = OpInfo.Codes[BestIdx];
2747*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintType = BestType;
2748*9880d681SAndroid Build Coastguard Worker }
2749*9880d681SAndroid Build Coastguard Worker
2750*9880d681SAndroid Build Coastguard Worker /// Determines the constraint code and constraint type to use for the specific
2751*9880d681SAndroid Build Coastguard Worker /// AsmOperandInfo, setting OpInfo.ConstraintCode and OpInfo.ConstraintType.
ComputeConstraintToUse(AsmOperandInfo & OpInfo,SDValue Op,SelectionDAG * DAG) const2752*9880d681SAndroid Build Coastguard Worker void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,
2753*9880d681SAndroid Build Coastguard Worker SDValue Op,
2754*9880d681SAndroid Build Coastguard Worker SelectionDAG *DAG) const {
2755*9880d681SAndroid Build Coastguard Worker assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
2756*9880d681SAndroid Build Coastguard Worker
2757*9880d681SAndroid Build Coastguard Worker // Single-letter constraints ('r') are very common.
2758*9880d681SAndroid Build Coastguard Worker if (OpInfo.Codes.size() == 1) {
2759*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintCode = OpInfo.Codes[0];
2760*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode);
2761*9880d681SAndroid Build Coastguard Worker } else {
2762*9880d681SAndroid Build Coastguard Worker ChooseConstraint(OpInfo, *this, Op, DAG);
2763*9880d681SAndroid Build Coastguard Worker }
2764*9880d681SAndroid Build Coastguard Worker
2765*9880d681SAndroid Build Coastguard Worker // 'X' matches anything.
2766*9880d681SAndroid Build Coastguard Worker if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) {
2767*9880d681SAndroid Build Coastguard Worker // Labels and constants are handled elsewhere ('X' is the only thing
2768*9880d681SAndroid Build Coastguard Worker // that matches labels). For Functions, the type here is the type of
2769*9880d681SAndroid Build Coastguard Worker // the result, which is not what we want to look at; leave them alone.
2770*9880d681SAndroid Build Coastguard Worker Value *v = OpInfo.CallOperandVal;
2771*9880d681SAndroid Build Coastguard Worker if (isa<BasicBlock>(v) || isa<ConstantInt>(v) || isa<Function>(v)) {
2772*9880d681SAndroid Build Coastguard Worker OpInfo.CallOperandVal = v;
2773*9880d681SAndroid Build Coastguard Worker return;
2774*9880d681SAndroid Build Coastguard Worker }
2775*9880d681SAndroid Build Coastguard Worker
2776*9880d681SAndroid Build Coastguard Worker // Otherwise, try to resolve it to something we know about by looking at
2777*9880d681SAndroid Build Coastguard Worker // the actual operand type.
2778*9880d681SAndroid Build Coastguard Worker if (const char *Repl = LowerXConstraint(OpInfo.ConstraintVT)) {
2779*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintCode = Repl;
2780*9880d681SAndroid Build Coastguard Worker OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode);
2781*9880d681SAndroid Build Coastguard Worker }
2782*9880d681SAndroid Build Coastguard Worker }
2783*9880d681SAndroid Build Coastguard Worker }
2784*9880d681SAndroid Build Coastguard Worker
2785*9880d681SAndroid Build Coastguard Worker /// \brief Given an exact SDIV by a constant, create a multiplication
2786*9880d681SAndroid Build Coastguard Worker /// with the multiplicative inverse of the constant.
BuildExactSDIV(const TargetLowering & TLI,SDValue Op1,APInt d,const SDLoc & dl,SelectionDAG & DAG,std::vector<SDNode * > & Created)2787*9880d681SAndroid Build Coastguard Worker static SDValue BuildExactSDIV(const TargetLowering &TLI, SDValue Op1, APInt d,
2788*9880d681SAndroid Build Coastguard Worker const SDLoc &dl, SelectionDAG &DAG,
2789*9880d681SAndroid Build Coastguard Worker std::vector<SDNode *> &Created) {
2790*9880d681SAndroid Build Coastguard Worker assert(d != 0 && "Division by zero!");
2791*9880d681SAndroid Build Coastguard Worker
2792*9880d681SAndroid Build Coastguard Worker // Shift the value upfront if it is even, so the LSB is one.
2793*9880d681SAndroid Build Coastguard Worker unsigned ShAmt = d.countTrailingZeros();
2794*9880d681SAndroid Build Coastguard Worker if (ShAmt) {
2795*9880d681SAndroid Build Coastguard Worker // TODO: For UDIV use SRL instead of SRA.
2796*9880d681SAndroid Build Coastguard Worker SDValue Amt =
2797*9880d681SAndroid Build Coastguard Worker DAG.getConstant(ShAmt, dl, TLI.getShiftAmountTy(Op1.getValueType(),
2798*9880d681SAndroid Build Coastguard Worker DAG.getDataLayout()));
2799*9880d681SAndroid Build Coastguard Worker SDNodeFlags Flags;
2800*9880d681SAndroid Build Coastguard Worker Flags.setExact(true);
2801*9880d681SAndroid Build Coastguard Worker Op1 = DAG.getNode(ISD::SRA, dl, Op1.getValueType(), Op1, Amt, &Flags);
2802*9880d681SAndroid Build Coastguard Worker Created.push_back(Op1.getNode());
2803*9880d681SAndroid Build Coastguard Worker d = d.ashr(ShAmt);
2804*9880d681SAndroid Build Coastguard Worker }
2805*9880d681SAndroid Build Coastguard Worker
2806*9880d681SAndroid Build Coastguard Worker // Calculate the multiplicative inverse, using Newton's method.
2807*9880d681SAndroid Build Coastguard Worker APInt t, xn = d;
2808*9880d681SAndroid Build Coastguard Worker while ((t = d*xn) != 1)
2809*9880d681SAndroid Build Coastguard Worker xn *= APInt(d.getBitWidth(), 2) - t;
2810*9880d681SAndroid Build Coastguard Worker
2811*9880d681SAndroid Build Coastguard Worker SDValue Op2 = DAG.getConstant(xn, dl, Op1.getValueType());
2812*9880d681SAndroid Build Coastguard Worker SDValue Mul = DAG.getNode(ISD::MUL, dl, Op1.getValueType(), Op1, Op2);
2813*9880d681SAndroid Build Coastguard Worker Created.push_back(Mul.getNode());
2814*9880d681SAndroid Build Coastguard Worker return Mul;
2815*9880d681SAndroid Build Coastguard Worker }
2816*9880d681SAndroid Build Coastguard Worker
BuildSDIVPow2(SDNode * N,const APInt & Divisor,SelectionDAG & DAG,std::vector<SDNode * > * Created) const2817*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
2818*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG,
2819*9880d681SAndroid Build Coastguard Worker std::vector<SDNode *> *Created) const {
2820*9880d681SAndroid Build Coastguard Worker AttributeSet Attr = DAG.getMachineFunction().getFunction()->getAttributes();
2821*9880d681SAndroid Build Coastguard Worker const TargetLowering &TLI = DAG.getTargetLoweringInfo();
2822*9880d681SAndroid Build Coastguard Worker if (TLI.isIntDivCheap(N->getValueType(0), Attr))
2823*9880d681SAndroid Build Coastguard Worker return SDValue(N,0); // Lower SDIV as SDIV
2824*9880d681SAndroid Build Coastguard Worker return SDValue();
2825*9880d681SAndroid Build Coastguard Worker }
2826*9880d681SAndroid Build Coastguard Worker
2827*9880d681SAndroid Build Coastguard Worker /// \brief Given an ISD::SDIV node expressing a divide by constant,
2828*9880d681SAndroid Build Coastguard Worker /// return a DAG expression to select that will generate the same value by
2829*9880d681SAndroid Build Coastguard Worker /// multiplying by a magic number.
2830*9880d681SAndroid Build Coastguard Worker /// Ref: "Hacker's Delight" or "The PowerPC Compiler Writer's Guide".
BuildSDIV(SDNode * N,const APInt & Divisor,SelectionDAG & DAG,bool IsAfterLegalization,std::vector<SDNode * > * Created) const2831*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::BuildSDIV(SDNode *N, const APInt &Divisor,
2832*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, bool IsAfterLegalization,
2833*9880d681SAndroid Build Coastguard Worker std::vector<SDNode *> *Created) const {
2834*9880d681SAndroid Build Coastguard Worker assert(Created && "No vector to hold sdiv ops.");
2835*9880d681SAndroid Build Coastguard Worker
2836*9880d681SAndroid Build Coastguard Worker EVT VT = N->getValueType(0);
2837*9880d681SAndroid Build Coastguard Worker SDLoc dl(N);
2838*9880d681SAndroid Build Coastguard Worker
2839*9880d681SAndroid Build Coastguard Worker // Check to see if we can do this.
2840*9880d681SAndroid Build Coastguard Worker // FIXME: We should be more aggressive here.
2841*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(VT))
2842*9880d681SAndroid Build Coastguard Worker return SDValue();
2843*9880d681SAndroid Build Coastguard Worker
2844*9880d681SAndroid Build Coastguard Worker // If the sdiv has an 'exact' bit we can use a simpler lowering.
2845*9880d681SAndroid Build Coastguard Worker if (cast<BinaryWithFlagsSDNode>(N)->Flags.hasExact())
2846*9880d681SAndroid Build Coastguard Worker return BuildExactSDIV(*this, N->getOperand(0), Divisor, dl, DAG, *Created);
2847*9880d681SAndroid Build Coastguard Worker
2848*9880d681SAndroid Build Coastguard Worker APInt::ms magics = Divisor.magic();
2849*9880d681SAndroid Build Coastguard Worker
2850*9880d681SAndroid Build Coastguard Worker // Multiply the numerator (operand 0) by the magic value
2851*9880d681SAndroid Build Coastguard Worker // FIXME: We should support doing a MUL in a wider type
2852*9880d681SAndroid Build Coastguard Worker SDValue Q;
2853*9880d681SAndroid Build Coastguard Worker if (IsAfterLegalization ? isOperationLegal(ISD::MULHS, VT) :
2854*9880d681SAndroid Build Coastguard Worker isOperationLegalOrCustom(ISD::MULHS, VT))
2855*9880d681SAndroid Build Coastguard Worker Q = DAG.getNode(ISD::MULHS, dl, VT, N->getOperand(0),
2856*9880d681SAndroid Build Coastguard Worker DAG.getConstant(magics.m, dl, VT));
2857*9880d681SAndroid Build Coastguard Worker else if (IsAfterLegalization ? isOperationLegal(ISD::SMUL_LOHI, VT) :
2858*9880d681SAndroid Build Coastguard Worker isOperationLegalOrCustom(ISD::SMUL_LOHI, VT))
2859*9880d681SAndroid Build Coastguard Worker Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT),
2860*9880d681SAndroid Build Coastguard Worker N->getOperand(0),
2861*9880d681SAndroid Build Coastguard Worker DAG.getConstant(magics.m, dl, VT)).getNode(), 1);
2862*9880d681SAndroid Build Coastguard Worker else
2863*9880d681SAndroid Build Coastguard Worker return SDValue(); // No mulhs or equvialent
2864*9880d681SAndroid Build Coastguard Worker // If d > 0 and m < 0, add the numerator
2865*9880d681SAndroid Build Coastguard Worker if (Divisor.isStrictlyPositive() && magics.m.isNegative()) {
2866*9880d681SAndroid Build Coastguard Worker Q = DAG.getNode(ISD::ADD, dl, VT, Q, N->getOperand(0));
2867*9880d681SAndroid Build Coastguard Worker Created->push_back(Q.getNode());
2868*9880d681SAndroid Build Coastguard Worker }
2869*9880d681SAndroid Build Coastguard Worker // If d < 0 and m > 0, subtract the numerator.
2870*9880d681SAndroid Build Coastguard Worker if (Divisor.isNegative() && magics.m.isStrictlyPositive()) {
2871*9880d681SAndroid Build Coastguard Worker Q = DAG.getNode(ISD::SUB, dl, VT, Q, N->getOperand(0));
2872*9880d681SAndroid Build Coastguard Worker Created->push_back(Q.getNode());
2873*9880d681SAndroid Build Coastguard Worker }
2874*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
2875*9880d681SAndroid Build Coastguard Worker // Shift right algebraic if shift value is nonzero
2876*9880d681SAndroid Build Coastguard Worker if (magics.s > 0) {
2877*9880d681SAndroid Build Coastguard Worker Q = DAG.getNode(
2878*9880d681SAndroid Build Coastguard Worker ISD::SRA, dl, VT, Q,
2879*9880d681SAndroid Build Coastguard Worker DAG.getConstant(magics.s, dl, getShiftAmountTy(Q.getValueType(), DL)));
2880*9880d681SAndroid Build Coastguard Worker Created->push_back(Q.getNode());
2881*9880d681SAndroid Build Coastguard Worker }
2882*9880d681SAndroid Build Coastguard Worker // Extract the sign bit and add it to the quotient
2883*9880d681SAndroid Build Coastguard Worker SDValue T =
2884*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::SRL, dl, VT, Q,
2885*9880d681SAndroid Build Coastguard Worker DAG.getConstant(VT.getScalarSizeInBits() - 1, dl,
2886*9880d681SAndroid Build Coastguard Worker getShiftAmountTy(Q.getValueType(), DL)));
2887*9880d681SAndroid Build Coastguard Worker Created->push_back(T.getNode());
2888*9880d681SAndroid Build Coastguard Worker return DAG.getNode(ISD::ADD, dl, VT, Q, T);
2889*9880d681SAndroid Build Coastguard Worker }
2890*9880d681SAndroid Build Coastguard Worker
2891*9880d681SAndroid Build Coastguard Worker /// \brief Given an ISD::UDIV node expressing a divide by constant,
2892*9880d681SAndroid Build Coastguard Worker /// return a DAG expression to select that will generate the same value by
2893*9880d681SAndroid Build Coastguard Worker /// multiplying by a magic number.
2894*9880d681SAndroid Build Coastguard Worker /// Ref: "Hacker's Delight" or "The PowerPC Compiler Writer's Guide".
BuildUDIV(SDNode * N,const APInt & Divisor,SelectionDAG & DAG,bool IsAfterLegalization,std::vector<SDNode * > * Created) const2895*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::BuildUDIV(SDNode *N, const APInt &Divisor,
2896*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, bool IsAfterLegalization,
2897*9880d681SAndroid Build Coastguard Worker std::vector<SDNode *> *Created) const {
2898*9880d681SAndroid Build Coastguard Worker assert(Created && "No vector to hold udiv ops.");
2899*9880d681SAndroid Build Coastguard Worker
2900*9880d681SAndroid Build Coastguard Worker EVT VT = N->getValueType(0);
2901*9880d681SAndroid Build Coastguard Worker SDLoc dl(N);
2902*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
2903*9880d681SAndroid Build Coastguard Worker
2904*9880d681SAndroid Build Coastguard Worker // Check to see if we can do this.
2905*9880d681SAndroid Build Coastguard Worker // FIXME: We should be more aggressive here.
2906*9880d681SAndroid Build Coastguard Worker if (!isTypeLegal(VT))
2907*9880d681SAndroid Build Coastguard Worker return SDValue();
2908*9880d681SAndroid Build Coastguard Worker
2909*9880d681SAndroid Build Coastguard Worker // FIXME: We should use a narrower constant when the upper
2910*9880d681SAndroid Build Coastguard Worker // bits are known to be zero.
2911*9880d681SAndroid Build Coastguard Worker APInt::mu magics = Divisor.magicu();
2912*9880d681SAndroid Build Coastguard Worker
2913*9880d681SAndroid Build Coastguard Worker SDValue Q = N->getOperand(0);
2914*9880d681SAndroid Build Coastguard Worker
2915*9880d681SAndroid Build Coastguard Worker // If the divisor is even, we can avoid using the expensive fixup by shifting
2916*9880d681SAndroid Build Coastguard Worker // the divided value upfront.
2917*9880d681SAndroid Build Coastguard Worker if (magics.a != 0 && !Divisor[0]) {
2918*9880d681SAndroid Build Coastguard Worker unsigned Shift = Divisor.countTrailingZeros();
2919*9880d681SAndroid Build Coastguard Worker Q = DAG.getNode(
2920*9880d681SAndroid Build Coastguard Worker ISD::SRL, dl, VT, Q,
2921*9880d681SAndroid Build Coastguard Worker DAG.getConstant(Shift, dl, getShiftAmountTy(Q.getValueType(), DL)));
2922*9880d681SAndroid Build Coastguard Worker Created->push_back(Q.getNode());
2923*9880d681SAndroid Build Coastguard Worker
2924*9880d681SAndroid Build Coastguard Worker // Get magic number for the shifted divisor.
2925*9880d681SAndroid Build Coastguard Worker magics = Divisor.lshr(Shift).magicu(Shift);
2926*9880d681SAndroid Build Coastguard Worker assert(magics.a == 0 && "Should use cheap fixup now");
2927*9880d681SAndroid Build Coastguard Worker }
2928*9880d681SAndroid Build Coastguard Worker
2929*9880d681SAndroid Build Coastguard Worker // Multiply the numerator (operand 0) by the magic value
2930*9880d681SAndroid Build Coastguard Worker // FIXME: We should support doing a MUL in a wider type
2931*9880d681SAndroid Build Coastguard Worker if (IsAfterLegalization ? isOperationLegal(ISD::MULHU, VT) :
2932*9880d681SAndroid Build Coastguard Worker isOperationLegalOrCustom(ISD::MULHU, VT))
2933*9880d681SAndroid Build Coastguard Worker Q = DAG.getNode(ISD::MULHU, dl, VT, Q, DAG.getConstant(magics.m, dl, VT));
2934*9880d681SAndroid Build Coastguard Worker else if (IsAfterLegalization ? isOperationLegal(ISD::UMUL_LOHI, VT) :
2935*9880d681SAndroid Build Coastguard Worker isOperationLegalOrCustom(ISD::UMUL_LOHI, VT))
2936*9880d681SAndroid Build Coastguard Worker Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT), Q,
2937*9880d681SAndroid Build Coastguard Worker DAG.getConstant(magics.m, dl, VT)).getNode(), 1);
2938*9880d681SAndroid Build Coastguard Worker else
2939*9880d681SAndroid Build Coastguard Worker return SDValue(); // No mulhu or equvialent
2940*9880d681SAndroid Build Coastguard Worker
2941*9880d681SAndroid Build Coastguard Worker Created->push_back(Q.getNode());
2942*9880d681SAndroid Build Coastguard Worker
2943*9880d681SAndroid Build Coastguard Worker if (magics.a == 0) {
2944*9880d681SAndroid Build Coastguard Worker assert(magics.s < Divisor.getBitWidth() &&
2945*9880d681SAndroid Build Coastguard Worker "We shouldn't generate an undefined shift!");
2946*9880d681SAndroid Build Coastguard Worker return DAG.getNode(
2947*9880d681SAndroid Build Coastguard Worker ISD::SRL, dl, VT, Q,
2948*9880d681SAndroid Build Coastguard Worker DAG.getConstant(magics.s, dl, getShiftAmountTy(Q.getValueType(), DL)));
2949*9880d681SAndroid Build Coastguard Worker } else {
2950*9880d681SAndroid Build Coastguard Worker SDValue NPQ = DAG.getNode(ISD::SUB, dl, VT, N->getOperand(0), Q);
2951*9880d681SAndroid Build Coastguard Worker Created->push_back(NPQ.getNode());
2952*9880d681SAndroid Build Coastguard Worker NPQ = DAG.getNode(
2953*9880d681SAndroid Build Coastguard Worker ISD::SRL, dl, VT, NPQ,
2954*9880d681SAndroid Build Coastguard Worker DAG.getConstant(1, dl, getShiftAmountTy(NPQ.getValueType(), DL)));
2955*9880d681SAndroid Build Coastguard Worker Created->push_back(NPQ.getNode());
2956*9880d681SAndroid Build Coastguard Worker NPQ = DAG.getNode(ISD::ADD, dl, VT, NPQ, Q);
2957*9880d681SAndroid Build Coastguard Worker Created->push_back(NPQ.getNode());
2958*9880d681SAndroid Build Coastguard Worker return DAG.getNode(
2959*9880d681SAndroid Build Coastguard Worker ISD::SRL, dl, VT, NPQ,
2960*9880d681SAndroid Build Coastguard Worker DAG.getConstant(magics.s - 1, dl,
2961*9880d681SAndroid Build Coastguard Worker getShiftAmountTy(NPQ.getValueType(), DL)));
2962*9880d681SAndroid Build Coastguard Worker }
2963*9880d681SAndroid Build Coastguard Worker }
2964*9880d681SAndroid Build Coastguard Worker
2965*9880d681SAndroid Build Coastguard Worker bool TargetLowering::
verifyReturnAddressArgumentIsConstant(SDValue Op,SelectionDAG & DAG) const2966*9880d681SAndroid Build Coastguard Worker verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const {
2967*9880d681SAndroid Build Coastguard Worker if (!isa<ConstantSDNode>(Op.getOperand(0))) {
2968*9880d681SAndroid Build Coastguard Worker DAG.getContext()->emitError("argument to '__builtin_return_address' must "
2969*9880d681SAndroid Build Coastguard Worker "be a constant integer");
2970*9880d681SAndroid Build Coastguard Worker return true;
2971*9880d681SAndroid Build Coastguard Worker }
2972*9880d681SAndroid Build Coastguard Worker
2973*9880d681SAndroid Build Coastguard Worker return false;
2974*9880d681SAndroid Build Coastguard Worker }
2975*9880d681SAndroid Build Coastguard Worker
2976*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2977*9880d681SAndroid Build Coastguard Worker // Legalization Utilities
2978*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2979*9880d681SAndroid Build Coastguard Worker
expandMUL(SDNode * N,SDValue & Lo,SDValue & Hi,EVT HiLoVT,SelectionDAG & DAG,SDValue LL,SDValue LH,SDValue RL,SDValue RH) const2980*9880d681SAndroid Build Coastguard Worker bool TargetLowering::expandMUL(SDNode *N, SDValue &Lo, SDValue &Hi, EVT HiLoVT,
2981*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, SDValue LL, SDValue LH,
2982*9880d681SAndroid Build Coastguard Worker SDValue RL, SDValue RH) const {
2983*9880d681SAndroid Build Coastguard Worker EVT VT = N->getValueType(0);
2984*9880d681SAndroid Build Coastguard Worker SDLoc dl(N);
2985*9880d681SAndroid Build Coastguard Worker
2986*9880d681SAndroid Build Coastguard Worker bool HasMULHS = isOperationLegalOrCustom(ISD::MULHS, HiLoVT);
2987*9880d681SAndroid Build Coastguard Worker bool HasMULHU = isOperationLegalOrCustom(ISD::MULHU, HiLoVT);
2988*9880d681SAndroid Build Coastguard Worker bool HasSMUL_LOHI = isOperationLegalOrCustom(ISD::SMUL_LOHI, HiLoVT);
2989*9880d681SAndroid Build Coastguard Worker bool HasUMUL_LOHI = isOperationLegalOrCustom(ISD::UMUL_LOHI, HiLoVT);
2990*9880d681SAndroid Build Coastguard Worker if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
2991*9880d681SAndroid Build Coastguard Worker unsigned OuterBitSize = VT.getSizeInBits();
2992*9880d681SAndroid Build Coastguard Worker unsigned InnerBitSize = HiLoVT.getSizeInBits();
2993*9880d681SAndroid Build Coastguard Worker unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
2994*9880d681SAndroid Build Coastguard Worker unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
2995*9880d681SAndroid Build Coastguard Worker
2996*9880d681SAndroid Build Coastguard Worker // LL, LH, RL, and RH must be either all NULL or all set to a value.
2997*9880d681SAndroid Build Coastguard Worker assert((LL.getNode() && LH.getNode() && RL.getNode() && RH.getNode()) ||
2998*9880d681SAndroid Build Coastguard Worker (!LL.getNode() && !LH.getNode() && !RL.getNode() && !RH.getNode()));
2999*9880d681SAndroid Build Coastguard Worker
3000*9880d681SAndroid Build Coastguard Worker if (!LL.getNode() && !RL.getNode() &&
3001*9880d681SAndroid Build Coastguard Worker isOperationLegalOrCustom(ISD::TRUNCATE, HiLoVT)) {
3002*9880d681SAndroid Build Coastguard Worker LL = DAG.getNode(ISD::TRUNCATE, dl, HiLoVT, N->getOperand(0));
3003*9880d681SAndroid Build Coastguard Worker RL = DAG.getNode(ISD::TRUNCATE, dl, HiLoVT, N->getOperand(1));
3004*9880d681SAndroid Build Coastguard Worker }
3005*9880d681SAndroid Build Coastguard Worker
3006*9880d681SAndroid Build Coastguard Worker if (!LL.getNode())
3007*9880d681SAndroid Build Coastguard Worker return false;
3008*9880d681SAndroid Build Coastguard Worker
3009*9880d681SAndroid Build Coastguard Worker APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize);
3010*9880d681SAndroid Build Coastguard Worker if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) &&
3011*9880d681SAndroid Build Coastguard Worker DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) {
3012*9880d681SAndroid Build Coastguard Worker // The inputs are both zero-extended.
3013*9880d681SAndroid Build Coastguard Worker if (HasUMUL_LOHI) {
3014*9880d681SAndroid Build Coastguard Worker // We can emit a umul_lohi.
3015*9880d681SAndroid Build Coastguard Worker Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(HiLoVT, HiLoVT), LL,
3016*9880d681SAndroid Build Coastguard Worker RL);
3017*9880d681SAndroid Build Coastguard Worker Hi = SDValue(Lo.getNode(), 1);
3018*9880d681SAndroid Build Coastguard Worker return true;
3019*9880d681SAndroid Build Coastguard Worker }
3020*9880d681SAndroid Build Coastguard Worker if (HasMULHU) {
3021*9880d681SAndroid Build Coastguard Worker // We can emit a mulhu+mul.
3022*9880d681SAndroid Build Coastguard Worker Lo = DAG.getNode(ISD::MUL, dl, HiLoVT, LL, RL);
3023*9880d681SAndroid Build Coastguard Worker Hi = DAG.getNode(ISD::MULHU, dl, HiLoVT, LL, RL);
3024*9880d681SAndroid Build Coastguard Worker return true;
3025*9880d681SAndroid Build Coastguard Worker }
3026*9880d681SAndroid Build Coastguard Worker }
3027*9880d681SAndroid Build Coastguard Worker if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
3028*9880d681SAndroid Build Coastguard Worker // The input values are both sign-extended.
3029*9880d681SAndroid Build Coastguard Worker if (HasSMUL_LOHI) {
3030*9880d681SAndroid Build Coastguard Worker // We can emit a smul_lohi.
3031*9880d681SAndroid Build Coastguard Worker Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(HiLoVT, HiLoVT), LL,
3032*9880d681SAndroid Build Coastguard Worker RL);
3033*9880d681SAndroid Build Coastguard Worker Hi = SDValue(Lo.getNode(), 1);
3034*9880d681SAndroid Build Coastguard Worker return true;
3035*9880d681SAndroid Build Coastguard Worker }
3036*9880d681SAndroid Build Coastguard Worker if (HasMULHS) {
3037*9880d681SAndroid Build Coastguard Worker // We can emit a mulhs+mul.
3038*9880d681SAndroid Build Coastguard Worker Lo = DAG.getNode(ISD::MUL, dl, HiLoVT, LL, RL);
3039*9880d681SAndroid Build Coastguard Worker Hi = DAG.getNode(ISD::MULHS, dl, HiLoVT, LL, RL);
3040*9880d681SAndroid Build Coastguard Worker return true;
3041*9880d681SAndroid Build Coastguard Worker }
3042*9880d681SAndroid Build Coastguard Worker }
3043*9880d681SAndroid Build Coastguard Worker
3044*9880d681SAndroid Build Coastguard Worker if (!LH.getNode() && !RH.getNode() &&
3045*9880d681SAndroid Build Coastguard Worker isOperationLegalOrCustom(ISD::SRL, VT) &&
3046*9880d681SAndroid Build Coastguard Worker isOperationLegalOrCustom(ISD::TRUNCATE, HiLoVT)) {
3047*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
3048*9880d681SAndroid Build Coastguard Worker unsigned ShiftAmt = VT.getSizeInBits() - HiLoVT.getSizeInBits();
3049*9880d681SAndroid Build Coastguard Worker SDValue Shift = DAG.getConstant(ShiftAmt, dl, getShiftAmountTy(VT, DL));
3050*9880d681SAndroid Build Coastguard Worker LH = DAG.getNode(ISD::SRL, dl, VT, N->getOperand(0), Shift);
3051*9880d681SAndroid Build Coastguard Worker LH = DAG.getNode(ISD::TRUNCATE, dl, HiLoVT, LH);
3052*9880d681SAndroid Build Coastguard Worker RH = DAG.getNode(ISD::SRL, dl, VT, N->getOperand(1), Shift);
3053*9880d681SAndroid Build Coastguard Worker RH = DAG.getNode(ISD::TRUNCATE, dl, HiLoVT, RH);
3054*9880d681SAndroid Build Coastguard Worker }
3055*9880d681SAndroid Build Coastguard Worker
3056*9880d681SAndroid Build Coastguard Worker if (!LH.getNode())
3057*9880d681SAndroid Build Coastguard Worker return false;
3058*9880d681SAndroid Build Coastguard Worker
3059*9880d681SAndroid Build Coastguard Worker if (HasUMUL_LOHI) {
3060*9880d681SAndroid Build Coastguard Worker // Lo,Hi = umul LHS, RHS.
3061*9880d681SAndroid Build Coastguard Worker SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl,
3062*9880d681SAndroid Build Coastguard Worker DAG.getVTList(HiLoVT, HiLoVT), LL, RL);
3063*9880d681SAndroid Build Coastguard Worker Lo = UMulLOHI;
3064*9880d681SAndroid Build Coastguard Worker Hi = UMulLOHI.getValue(1);
3065*9880d681SAndroid Build Coastguard Worker RH = DAG.getNode(ISD::MUL, dl, HiLoVT, LL, RH);
3066*9880d681SAndroid Build Coastguard Worker LH = DAG.getNode(ISD::MUL, dl, HiLoVT, LH, RL);
3067*9880d681SAndroid Build Coastguard Worker Hi = DAG.getNode(ISD::ADD, dl, HiLoVT, Hi, RH);
3068*9880d681SAndroid Build Coastguard Worker Hi = DAG.getNode(ISD::ADD, dl, HiLoVT, Hi, LH);
3069*9880d681SAndroid Build Coastguard Worker return true;
3070*9880d681SAndroid Build Coastguard Worker }
3071*9880d681SAndroid Build Coastguard Worker if (HasMULHU) {
3072*9880d681SAndroid Build Coastguard Worker Lo = DAG.getNode(ISD::MUL, dl, HiLoVT, LL, RL);
3073*9880d681SAndroid Build Coastguard Worker Hi = DAG.getNode(ISD::MULHU, dl, HiLoVT, LL, RL);
3074*9880d681SAndroid Build Coastguard Worker RH = DAG.getNode(ISD::MUL, dl, HiLoVT, LL, RH);
3075*9880d681SAndroid Build Coastguard Worker LH = DAG.getNode(ISD::MUL, dl, HiLoVT, LH, RL);
3076*9880d681SAndroid Build Coastguard Worker Hi = DAG.getNode(ISD::ADD, dl, HiLoVT, Hi, RH);
3077*9880d681SAndroid Build Coastguard Worker Hi = DAG.getNode(ISD::ADD, dl, HiLoVT, Hi, LH);
3078*9880d681SAndroid Build Coastguard Worker return true;
3079*9880d681SAndroid Build Coastguard Worker }
3080*9880d681SAndroid Build Coastguard Worker }
3081*9880d681SAndroid Build Coastguard Worker return false;
3082*9880d681SAndroid Build Coastguard Worker }
3083*9880d681SAndroid Build Coastguard Worker
expandFP_TO_SINT(SDNode * Node,SDValue & Result,SelectionDAG & DAG) const3084*9880d681SAndroid Build Coastguard Worker bool TargetLowering::expandFP_TO_SINT(SDNode *Node, SDValue &Result,
3085*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
3086*9880d681SAndroid Build Coastguard Worker EVT VT = Node->getOperand(0).getValueType();
3087*9880d681SAndroid Build Coastguard Worker EVT NVT = Node->getValueType(0);
3088*9880d681SAndroid Build Coastguard Worker SDLoc dl(SDValue(Node, 0));
3089*9880d681SAndroid Build Coastguard Worker
3090*9880d681SAndroid Build Coastguard Worker // FIXME: Only f32 to i64 conversions are supported.
3091*9880d681SAndroid Build Coastguard Worker if (VT != MVT::f32 || NVT != MVT::i64)
3092*9880d681SAndroid Build Coastguard Worker return false;
3093*9880d681SAndroid Build Coastguard Worker
3094*9880d681SAndroid Build Coastguard Worker // Expand f32 -> i64 conversion
3095*9880d681SAndroid Build Coastguard Worker // This algorithm comes from compiler-rt's implementation of fixsfdi:
3096*9880d681SAndroid Build Coastguard Worker // https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/fixsfdi.c
3097*9880d681SAndroid Build Coastguard Worker EVT IntVT = EVT::getIntegerVT(*DAG.getContext(),
3098*9880d681SAndroid Build Coastguard Worker VT.getSizeInBits());
3099*9880d681SAndroid Build Coastguard Worker SDValue ExponentMask = DAG.getConstant(0x7F800000, dl, IntVT);
3100*9880d681SAndroid Build Coastguard Worker SDValue ExponentLoBit = DAG.getConstant(23, dl, IntVT);
3101*9880d681SAndroid Build Coastguard Worker SDValue Bias = DAG.getConstant(127, dl, IntVT);
3102*9880d681SAndroid Build Coastguard Worker SDValue SignMask = DAG.getConstant(APInt::getSignBit(VT.getSizeInBits()), dl,
3103*9880d681SAndroid Build Coastguard Worker IntVT);
3104*9880d681SAndroid Build Coastguard Worker SDValue SignLowBit = DAG.getConstant(VT.getSizeInBits() - 1, dl, IntVT);
3105*9880d681SAndroid Build Coastguard Worker SDValue MantissaMask = DAG.getConstant(0x007FFFFF, dl, IntVT);
3106*9880d681SAndroid Build Coastguard Worker
3107*9880d681SAndroid Build Coastguard Worker SDValue Bits = DAG.getNode(ISD::BITCAST, dl, IntVT, Node->getOperand(0));
3108*9880d681SAndroid Build Coastguard Worker
3109*9880d681SAndroid Build Coastguard Worker auto &DL = DAG.getDataLayout();
3110*9880d681SAndroid Build Coastguard Worker SDValue ExponentBits = DAG.getNode(
3111*9880d681SAndroid Build Coastguard Worker ISD::SRL, dl, IntVT, DAG.getNode(ISD::AND, dl, IntVT, Bits, ExponentMask),
3112*9880d681SAndroid Build Coastguard Worker DAG.getZExtOrTrunc(ExponentLoBit, dl, getShiftAmountTy(IntVT, DL)));
3113*9880d681SAndroid Build Coastguard Worker SDValue Exponent = DAG.getNode(ISD::SUB, dl, IntVT, ExponentBits, Bias);
3114*9880d681SAndroid Build Coastguard Worker
3115*9880d681SAndroid Build Coastguard Worker SDValue Sign = DAG.getNode(
3116*9880d681SAndroid Build Coastguard Worker ISD::SRA, dl, IntVT, DAG.getNode(ISD::AND, dl, IntVT, Bits, SignMask),
3117*9880d681SAndroid Build Coastguard Worker DAG.getZExtOrTrunc(SignLowBit, dl, getShiftAmountTy(IntVT, DL)));
3118*9880d681SAndroid Build Coastguard Worker Sign = DAG.getSExtOrTrunc(Sign, dl, NVT);
3119*9880d681SAndroid Build Coastguard Worker
3120*9880d681SAndroid Build Coastguard Worker SDValue R = DAG.getNode(ISD::OR, dl, IntVT,
3121*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::AND, dl, IntVT, Bits, MantissaMask),
3122*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0x00800000, dl, IntVT));
3123*9880d681SAndroid Build Coastguard Worker
3124*9880d681SAndroid Build Coastguard Worker R = DAG.getZExtOrTrunc(R, dl, NVT);
3125*9880d681SAndroid Build Coastguard Worker
3126*9880d681SAndroid Build Coastguard Worker R = DAG.getSelectCC(
3127*9880d681SAndroid Build Coastguard Worker dl, Exponent, ExponentLoBit,
3128*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::SHL, dl, NVT, R,
3129*9880d681SAndroid Build Coastguard Worker DAG.getZExtOrTrunc(
3130*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::SUB, dl, IntVT, Exponent, ExponentLoBit),
3131*9880d681SAndroid Build Coastguard Worker dl, getShiftAmountTy(IntVT, DL))),
3132*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::SRL, dl, NVT, R,
3133*9880d681SAndroid Build Coastguard Worker DAG.getZExtOrTrunc(
3134*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::SUB, dl, IntVT, ExponentLoBit, Exponent),
3135*9880d681SAndroid Build Coastguard Worker dl, getShiftAmountTy(IntVT, DL))),
3136*9880d681SAndroid Build Coastguard Worker ISD::SETGT);
3137*9880d681SAndroid Build Coastguard Worker
3138*9880d681SAndroid Build Coastguard Worker SDValue Ret = DAG.getNode(ISD::SUB, dl, NVT,
3139*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::XOR, dl, NVT, R, Sign),
3140*9880d681SAndroid Build Coastguard Worker Sign);
3141*9880d681SAndroid Build Coastguard Worker
3142*9880d681SAndroid Build Coastguard Worker Result = DAG.getSelectCC(dl, Exponent, DAG.getConstant(0, dl, IntVT),
3143*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, dl, NVT), Ret, ISD::SETLT);
3144*9880d681SAndroid Build Coastguard Worker return true;
3145*9880d681SAndroid Build Coastguard Worker }
3146*9880d681SAndroid Build Coastguard Worker
scalarizeVectorLoad(LoadSDNode * LD,SelectionDAG & DAG) const3147*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::scalarizeVectorLoad(LoadSDNode *LD,
3148*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
3149*9880d681SAndroid Build Coastguard Worker SDLoc SL(LD);
3150*9880d681SAndroid Build Coastguard Worker SDValue Chain = LD->getChain();
3151*9880d681SAndroid Build Coastguard Worker SDValue BasePTR = LD->getBasePtr();
3152*9880d681SAndroid Build Coastguard Worker EVT SrcVT = LD->getMemoryVT();
3153*9880d681SAndroid Build Coastguard Worker ISD::LoadExtType ExtType = LD->getExtensionType();
3154*9880d681SAndroid Build Coastguard Worker
3155*9880d681SAndroid Build Coastguard Worker unsigned NumElem = SrcVT.getVectorNumElements();
3156*9880d681SAndroid Build Coastguard Worker
3157*9880d681SAndroid Build Coastguard Worker EVT SrcEltVT = SrcVT.getScalarType();
3158*9880d681SAndroid Build Coastguard Worker EVT DstEltVT = LD->getValueType(0).getScalarType();
3159*9880d681SAndroid Build Coastguard Worker
3160*9880d681SAndroid Build Coastguard Worker unsigned Stride = SrcEltVT.getSizeInBits() / 8;
3161*9880d681SAndroid Build Coastguard Worker assert(SrcEltVT.isByteSized());
3162*9880d681SAndroid Build Coastguard Worker
3163*9880d681SAndroid Build Coastguard Worker EVT PtrVT = BasePTR.getValueType();
3164*9880d681SAndroid Build Coastguard Worker
3165*9880d681SAndroid Build Coastguard Worker SmallVector<SDValue, 8> Vals;
3166*9880d681SAndroid Build Coastguard Worker SmallVector<SDValue, 8> LoadChains;
3167*9880d681SAndroid Build Coastguard Worker
3168*9880d681SAndroid Build Coastguard Worker for (unsigned Idx = 0; Idx < NumElem; ++Idx) {
3169*9880d681SAndroid Build Coastguard Worker SDValue ScalarLoad = DAG.getExtLoad(
3170*9880d681SAndroid Build Coastguard Worker ExtType, SL, DstEltVT,
3171*9880d681SAndroid Build Coastguard Worker Chain, BasePTR, LD->getPointerInfo().getWithOffset(Idx * Stride),
3172*9880d681SAndroid Build Coastguard Worker SrcEltVT,
3173*9880d681SAndroid Build Coastguard Worker LD->isVolatile(), LD->isNonTemporal(), LD->isInvariant(),
3174*9880d681SAndroid Build Coastguard Worker MinAlign(LD->getAlignment(), Idx * Stride), LD->getAAInfo());
3175*9880d681SAndroid Build Coastguard Worker
3176*9880d681SAndroid Build Coastguard Worker BasePTR = DAG.getNode(ISD::ADD, SL, PtrVT, BasePTR,
3177*9880d681SAndroid Build Coastguard Worker DAG.getConstant(Stride, SL, PtrVT));
3178*9880d681SAndroid Build Coastguard Worker
3179*9880d681SAndroid Build Coastguard Worker Vals.push_back(ScalarLoad.getValue(0));
3180*9880d681SAndroid Build Coastguard Worker LoadChains.push_back(ScalarLoad.getValue(1));
3181*9880d681SAndroid Build Coastguard Worker }
3182*9880d681SAndroid Build Coastguard Worker
3183*9880d681SAndroid Build Coastguard Worker SDValue NewChain = DAG.getNode(ISD::TokenFactor, SL, MVT::Other, LoadChains);
3184*9880d681SAndroid Build Coastguard Worker SDValue Value = DAG.getNode(ISD::BUILD_VECTOR, SL, LD->getValueType(0), Vals);
3185*9880d681SAndroid Build Coastguard Worker
3186*9880d681SAndroid Build Coastguard Worker return DAG.getMergeValues({ Value, NewChain }, SL);
3187*9880d681SAndroid Build Coastguard Worker }
3188*9880d681SAndroid Build Coastguard Worker
3189*9880d681SAndroid Build Coastguard Worker // FIXME: This relies on each element having a byte size, otherwise the stride
3190*9880d681SAndroid Build Coastguard Worker // is 0 and just overwrites the same location. ExpandStore currently expects
3191*9880d681SAndroid Build Coastguard Worker // this broken behavior.
scalarizeVectorStore(StoreSDNode * ST,SelectionDAG & DAG) const3192*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::scalarizeVectorStore(StoreSDNode *ST,
3193*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
3194*9880d681SAndroid Build Coastguard Worker SDLoc SL(ST);
3195*9880d681SAndroid Build Coastguard Worker
3196*9880d681SAndroid Build Coastguard Worker SDValue Chain = ST->getChain();
3197*9880d681SAndroid Build Coastguard Worker SDValue BasePtr = ST->getBasePtr();
3198*9880d681SAndroid Build Coastguard Worker SDValue Value = ST->getValue();
3199*9880d681SAndroid Build Coastguard Worker EVT StVT = ST->getMemoryVT();
3200*9880d681SAndroid Build Coastguard Worker
3201*9880d681SAndroid Build Coastguard Worker unsigned Alignment = ST->getAlignment();
3202*9880d681SAndroid Build Coastguard Worker bool isVolatile = ST->isVolatile();
3203*9880d681SAndroid Build Coastguard Worker bool isNonTemporal = ST->isNonTemporal();
3204*9880d681SAndroid Build Coastguard Worker AAMDNodes AAInfo = ST->getAAInfo();
3205*9880d681SAndroid Build Coastguard Worker
3206*9880d681SAndroid Build Coastguard Worker // The type of the data we want to save
3207*9880d681SAndroid Build Coastguard Worker EVT RegVT = Value.getValueType();
3208*9880d681SAndroid Build Coastguard Worker EVT RegSclVT = RegVT.getScalarType();
3209*9880d681SAndroid Build Coastguard Worker
3210*9880d681SAndroid Build Coastguard Worker // The type of data as saved in memory.
3211*9880d681SAndroid Build Coastguard Worker EVT MemSclVT = StVT.getScalarType();
3212*9880d681SAndroid Build Coastguard Worker
3213*9880d681SAndroid Build Coastguard Worker EVT PtrVT = BasePtr.getValueType();
3214*9880d681SAndroid Build Coastguard Worker
3215*9880d681SAndroid Build Coastguard Worker // Store Stride in bytes
3216*9880d681SAndroid Build Coastguard Worker unsigned Stride = MemSclVT.getSizeInBits() / 8;
3217*9880d681SAndroid Build Coastguard Worker EVT IdxVT = getVectorIdxTy(DAG.getDataLayout());
3218*9880d681SAndroid Build Coastguard Worker unsigned NumElem = StVT.getVectorNumElements();
3219*9880d681SAndroid Build Coastguard Worker
3220*9880d681SAndroid Build Coastguard Worker // Extract each of the elements from the original vector and save them into
3221*9880d681SAndroid Build Coastguard Worker // memory individually.
3222*9880d681SAndroid Build Coastguard Worker SmallVector<SDValue, 8> Stores;
3223*9880d681SAndroid Build Coastguard Worker for (unsigned Idx = 0; Idx < NumElem; ++Idx) {
3224*9880d681SAndroid Build Coastguard Worker SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, RegSclVT, Value,
3225*9880d681SAndroid Build Coastguard Worker DAG.getConstant(Idx, SL, IdxVT));
3226*9880d681SAndroid Build Coastguard Worker
3227*9880d681SAndroid Build Coastguard Worker SDValue Ptr = DAG.getNode(ISD::ADD, SL, PtrVT, BasePtr,
3228*9880d681SAndroid Build Coastguard Worker DAG.getConstant(Idx * Stride, SL, PtrVT));
3229*9880d681SAndroid Build Coastguard Worker
3230*9880d681SAndroid Build Coastguard Worker // This scalar TruncStore may be illegal, but we legalize it later.
3231*9880d681SAndroid Build Coastguard Worker SDValue Store = DAG.getTruncStore(
3232*9880d681SAndroid Build Coastguard Worker Chain, SL, Elt, Ptr,
3233*9880d681SAndroid Build Coastguard Worker ST->getPointerInfo().getWithOffset(Idx * Stride), MemSclVT,
3234*9880d681SAndroid Build Coastguard Worker isVolatile, isNonTemporal, MinAlign(Alignment, Idx * Stride),
3235*9880d681SAndroid Build Coastguard Worker AAInfo);
3236*9880d681SAndroid Build Coastguard Worker
3237*9880d681SAndroid Build Coastguard Worker Stores.push_back(Store);
3238*9880d681SAndroid Build Coastguard Worker }
3239*9880d681SAndroid Build Coastguard Worker
3240*9880d681SAndroid Build Coastguard Worker return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, Stores);
3241*9880d681SAndroid Build Coastguard Worker }
3242*9880d681SAndroid Build Coastguard Worker
3243*9880d681SAndroid Build Coastguard Worker std::pair<SDValue, SDValue>
expandUnalignedLoad(LoadSDNode * LD,SelectionDAG & DAG) const3244*9880d681SAndroid Build Coastguard Worker TargetLowering::expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const {
3245*9880d681SAndroid Build Coastguard Worker assert(LD->getAddressingMode() == ISD::UNINDEXED &&
3246*9880d681SAndroid Build Coastguard Worker "unaligned indexed loads not implemented!");
3247*9880d681SAndroid Build Coastguard Worker SDValue Chain = LD->getChain();
3248*9880d681SAndroid Build Coastguard Worker SDValue Ptr = LD->getBasePtr();
3249*9880d681SAndroid Build Coastguard Worker EVT VT = LD->getValueType(0);
3250*9880d681SAndroid Build Coastguard Worker EVT LoadedVT = LD->getMemoryVT();
3251*9880d681SAndroid Build Coastguard Worker SDLoc dl(LD);
3252*9880d681SAndroid Build Coastguard Worker if (VT.isFloatingPoint() || VT.isVector()) {
3253*9880d681SAndroid Build Coastguard Worker EVT intVT = EVT::getIntegerVT(*DAG.getContext(), LoadedVT.getSizeInBits());
3254*9880d681SAndroid Build Coastguard Worker if (isTypeLegal(intVT) && isTypeLegal(LoadedVT)) {
3255*9880d681SAndroid Build Coastguard Worker if (!isOperationLegalOrCustom(ISD::LOAD, intVT)) {
3256*9880d681SAndroid Build Coastguard Worker // Scalarize the load and let the individual components be handled.
3257*9880d681SAndroid Build Coastguard Worker SDValue Scalarized = scalarizeVectorLoad(LD, DAG);
3258*9880d681SAndroid Build Coastguard Worker return std::make_pair(Scalarized.getValue(0), Scalarized.getValue(1));
3259*9880d681SAndroid Build Coastguard Worker }
3260*9880d681SAndroid Build Coastguard Worker
3261*9880d681SAndroid Build Coastguard Worker // Expand to a (misaligned) integer load of the same size,
3262*9880d681SAndroid Build Coastguard Worker // then bitconvert to floating point or vector.
3263*9880d681SAndroid Build Coastguard Worker SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr,
3264*9880d681SAndroid Build Coastguard Worker LD->getMemOperand());
3265*9880d681SAndroid Build Coastguard Worker SDValue Result = DAG.getNode(ISD::BITCAST, dl, LoadedVT, newLoad);
3266*9880d681SAndroid Build Coastguard Worker if (LoadedVT != VT)
3267*9880d681SAndroid Build Coastguard Worker Result = DAG.getNode(VT.isFloatingPoint() ? ISD::FP_EXTEND :
3268*9880d681SAndroid Build Coastguard Worker ISD::ANY_EXTEND, dl, VT, Result);
3269*9880d681SAndroid Build Coastguard Worker
3270*9880d681SAndroid Build Coastguard Worker return std::make_pair(Result, newLoad.getValue(1));
3271*9880d681SAndroid Build Coastguard Worker }
3272*9880d681SAndroid Build Coastguard Worker
3273*9880d681SAndroid Build Coastguard Worker // Copy the value to a (aligned) stack slot using (unaligned) integer
3274*9880d681SAndroid Build Coastguard Worker // loads and stores, then do a (aligned) load from the stack slot.
3275*9880d681SAndroid Build Coastguard Worker MVT RegVT = getRegisterType(*DAG.getContext(), intVT);
3276*9880d681SAndroid Build Coastguard Worker unsigned LoadedBytes = LoadedVT.getSizeInBits() / 8;
3277*9880d681SAndroid Build Coastguard Worker unsigned RegBytes = RegVT.getSizeInBits() / 8;
3278*9880d681SAndroid Build Coastguard Worker unsigned NumRegs = (LoadedBytes + RegBytes - 1) / RegBytes;
3279*9880d681SAndroid Build Coastguard Worker
3280*9880d681SAndroid Build Coastguard Worker // Make sure the stack slot is also aligned for the register type.
3281*9880d681SAndroid Build Coastguard Worker SDValue StackBase = DAG.CreateStackTemporary(LoadedVT, RegVT);
3282*9880d681SAndroid Build Coastguard Worker
3283*9880d681SAndroid Build Coastguard Worker SmallVector<SDValue, 8> Stores;
3284*9880d681SAndroid Build Coastguard Worker SDValue StackPtr = StackBase;
3285*9880d681SAndroid Build Coastguard Worker unsigned Offset = 0;
3286*9880d681SAndroid Build Coastguard Worker
3287*9880d681SAndroid Build Coastguard Worker EVT PtrVT = Ptr.getValueType();
3288*9880d681SAndroid Build Coastguard Worker EVT StackPtrVT = StackPtr.getValueType();
3289*9880d681SAndroid Build Coastguard Worker
3290*9880d681SAndroid Build Coastguard Worker SDValue PtrIncrement = DAG.getConstant(RegBytes, dl, PtrVT);
3291*9880d681SAndroid Build Coastguard Worker SDValue StackPtrIncrement = DAG.getConstant(RegBytes, dl, StackPtrVT);
3292*9880d681SAndroid Build Coastguard Worker
3293*9880d681SAndroid Build Coastguard Worker // Do all but one copies using the full register width.
3294*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1; i < NumRegs; i++) {
3295*9880d681SAndroid Build Coastguard Worker // Load one integer register's worth from the original location.
3296*9880d681SAndroid Build Coastguard Worker SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr,
3297*9880d681SAndroid Build Coastguard Worker LD->getPointerInfo().getWithOffset(Offset),
3298*9880d681SAndroid Build Coastguard Worker LD->isVolatile(), LD->isNonTemporal(),
3299*9880d681SAndroid Build Coastguard Worker LD->isInvariant(),
3300*9880d681SAndroid Build Coastguard Worker MinAlign(LD->getAlignment(), Offset),
3301*9880d681SAndroid Build Coastguard Worker LD->getAAInfo());
3302*9880d681SAndroid Build Coastguard Worker // Follow the load with a store to the stack slot. Remember the store.
3303*9880d681SAndroid Build Coastguard Worker Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr,
3304*9880d681SAndroid Build Coastguard Worker MachinePointerInfo(), false, false, 0));
3305*9880d681SAndroid Build Coastguard Worker // Increment the pointers.
3306*9880d681SAndroid Build Coastguard Worker Offset += RegBytes;
3307*9880d681SAndroid Build Coastguard Worker Ptr = DAG.getNode(ISD::ADD, dl, PtrVT, Ptr, PtrIncrement);
3308*9880d681SAndroid Build Coastguard Worker StackPtr = DAG.getNode(ISD::ADD, dl, StackPtrVT, StackPtr,
3309*9880d681SAndroid Build Coastguard Worker StackPtrIncrement);
3310*9880d681SAndroid Build Coastguard Worker }
3311*9880d681SAndroid Build Coastguard Worker
3312*9880d681SAndroid Build Coastguard Worker // The last copy may be partial. Do an extending load.
3313*9880d681SAndroid Build Coastguard Worker EVT MemVT = EVT::getIntegerVT(*DAG.getContext(),
3314*9880d681SAndroid Build Coastguard Worker 8 * (LoadedBytes - Offset));
3315*9880d681SAndroid Build Coastguard Worker SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr,
3316*9880d681SAndroid Build Coastguard Worker LD->getPointerInfo().getWithOffset(Offset),
3317*9880d681SAndroid Build Coastguard Worker MemVT, LD->isVolatile(),
3318*9880d681SAndroid Build Coastguard Worker LD->isNonTemporal(),
3319*9880d681SAndroid Build Coastguard Worker LD->isInvariant(),
3320*9880d681SAndroid Build Coastguard Worker MinAlign(LD->getAlignment(), Offset),
3321*9880d681SAndroid Build Coastguard Worker LD->getAAInfo());
3322*9880d681SAndroid Build Coastguard Worker // Follow the load with a store to the stack slot. Remember the store.
3323*9880d681SAndroid Build Coastguard Worker // On big-endian machines this requires a truncating store to ensure
3324*9880d681SAndroid Build Coastguard Worker // that the bits end up in the right place.
3325*9880d681SAndroid Build Coastguard Worker Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr,
3326*9880d681SAndroid Build Coastguard Worker MachinePointerInfo(), MemVT,
3327*9880d681SAndroid Build Coastguard Worker false, false, 0));
3328*9880d681SAndroid Build Coastguard Worker
3329*9880d681SAndroid Build Coastguard Worker // The order of the stores doesn't matter - say it with a TokenFactor.
3330*9880d681SAndroid Build Coastguard Worker SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Stores);
3331*9880d681SAndroid Build Coastguard Worker
3332*9880d681SAndroid Build Coastguard Worker // Finally, perform the original load only redirected to the stack slot.
3333*9880d681SAndroid Build Coastguard Worker Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase,
3334*9880d681SAndroid Build Coastguard Worker MachinePointerInfo(), LoadedVT, false,false, false,
3335*9880d681SAndroid Build Coastguard Worker 0);
3336*9880d681SAndroid Build Coastguard Worker
3337*9880d681SAndroid Build Coastguard Worker // Callers expect a MERGE_VALUES node.
3338*9880d681SAndroid Build Coastguard Worker return std::make_pair(Load, TF);
3339*9880d681SAndroid Build Coastguard Worker }
3340*9880d681SAndroid Build Coastguard Worker
3341*9880d681SAndroid Build Coastguard Worker assert(LoadedVT.isInteger() && !LoadedVT.isVector() &&
3342*9880d681SAndroid Build Coastguard Worker "Unaligned load of unsupported type.");
3343*9880d681SAndroid Build Coastguard Worker
3344*9880d681SAndroid Build Coastguard Worker // Compute the new VT that is half the size of the old one. This is an
3345*9880d681SAndroid Build Coastguard Worker // integer MVT.
3346*9880d681SAndroid Build Coastguard Worker unsigned NumBits = LoadedVT.getSizeInBits();
3347*9880d681SAndroid Build Coastguard Worker EVT NewLoadedVT;
3348*9880d681SAndroid Build Coastguard Worker NewLoadedVT = EVT::getIntegerVT(*DAG.getContext(), NumBits/2);
3349*9880d681SAndroid Build Coastguard Worker NumBits >>= 1;
3350*9880d681SAndroid Build Coastguard Worker
3351*9880d681SAndroid Build Coastguard Worker unsigned Alignment = LD->getAlignment();
3352*9880d681SAndroid Build Coastguard Worker unsigned IncrementSize = NumBits / 8;
3353*9880d681SAndroid Build Coastguard Worker ISD::LoadExtType HiExtType = LD->getExtensionType();
3354*9880d681SAndroid Build Coastguard Worker
3355*9880d681SAndroid Build Coastguard Worker // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD.
3356*9880d681SAndroid Build Coastguard Worker if (HiExtType == ISD::NON_EXTLOAD)
3357*9880d681SAndroid Build Coastguard Worker HiExtType = ISD::ZEXTLOAD;
3358*9880d681SAndroid Build Coastguard Worker
3359*9880d681SAndroid Build Coastguard Worker // Load the value in two parts
3360*9880d681SAndroid Build Coastguard Worker SDValue Lo, Hi;
3361*9880d681SAndroid Build Coastguard Worker if (DAG.getDataLayout().isLittleEndian()) {
3362*9880d681SAndroid Build Coastguard Worker Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getPointerInfo(),
3363*9880d681SAndroid Build Coastguard Worker NewLoadedVT, LD->isVolatile(),
3364*9880d681SAndroid Build Coastguard Worker LD->isNonTemporal(), LD->isInvariant(), Alignment,
3365*9880d681SAndroid Build Coastguard Worker LD->getAAInfo());
3366*9880d681SAndroid Build Coastguard Worker Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
3367*9880d681SAndroid Build Coastguard Worker DAG.getConstant(IncrementSize, dl, Ptr.getValueType()));
3368*9880d681SAndroid Build Coastguard Worker Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr,
3369*9880d681SAndroid Build Coastguard Worker LD->getPointerInfo().getWithOffset(IncrementSize),
3370*9880d681SAndroid Build Coastguard Worker NewLoadedVT, LD->isVolatile(),
3371*9880d681SAndroid Build Coastguard Worker LD->isNonTemporal(),LD->isInvariant(),
3372*9880d681SAndroid Build Coastguard Worker MinAlign(Alignment, IncrementSize), LD->getAAInfo());
3373*9880d681SAndroid Build Coastguard Worker } else {
3374*9880d681SAndroid Build Coastguard Worker Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getPointerInfo(),
3375*9880d681SAndroid Build Coastguard Worker NewLoadedVT, LD->isVolatile(),
3376*9880d681SAndroid Build Coastguard Worker LD->isNonTemporal(), LD->isInvariant(), Alignment,
3377*9880d681SAndroid Build Coastguard Worker LD->getAAInfo());
3378*9880d681SAndroid Build Coastguard Worker Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
3379*9880d681SAndroid Build Coastguard Worker DAG.getConstant(IncrementSize, dl, Ptr.getValueType()));
3380*9880d681SAndroid Build Coastguard Worker Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr,
3381*9880d681SAndroid Build Coastguard Worker LD->getPointerInfo().getWithOffset(IncrementSize),
3382*9880d681SAndroid Build Coastguard Worker NewLoadedVT, LD->isVolatile(),
3383*9880d681SAndroid Build Coastguard Worker LD->isNonTemporal(), LD->isInvariant(),
3384*9880d681SAndroid Build Coastguard Worker MinAlign(Alignment, IncrementSize), LD->getAAInfo());
3385*9880d681SAndroid Build Coastguard Worker }
3386*9880d681SAndroid Build Coastguard Worker
3387*9880d681SAndroid Build Coastguard Worker // aggregate the two parts
3388*9880d681SAndroid Build Coastguard Worker SDValue ShiftAmount =
3389*9880d681SAndroid Build Coastguard Worker DAG.getConstant(NumBits, dl, getShiftAmountTy(Hi.getValueType(),
3390*9880d681SAndroid Build Coastguard Worker DAG.getDataLayout()));
3391*9880d681SAndroid Build Coastguard Worker SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount);
3392*9880d681SAndroid Build Coastguard Worker Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo);
3393*9880d681SAndroid Build Coastguard Worker
3394*9880d681SAndroid Build Coastguard Worker SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
3395*9880d681SAndroid Build Coastguard Worker Hi.getValue(1));
3396*9880d681SAndroid Build Coastguard Worker
3397*9880d681SAndroid Build Coastguard Worker return std::make_pair(Result, TF);
3398*9880d681SAndroid Build Coastguard Worker }
3399*9880d681SAndroid Build Coastguard Worker
expandUnalignedStore(StoreSDNode * ST,SelectionDAG & DAG) const3400*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
3401*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
3402*9880d681SAndroid Build Coastguard Worker assert(ST->getAddressingMode() == ISD::UNINDEXED &&
3403*9880d681SAndroid Build Coastguard Worker "unaligned indexed stores not implemented!");
3404*9880d681SAndroid Build Coastguard Worker SDValue Chain = ST->getChain();
3405*9880d681SAndroid Build Coastguard Worker SDValue Ptr = ST->getBasePtr();
3406*9880d681SAndroid Build Coastguard Worker SDValue Val = ST->getValue();
3407*9880d681SAndroid Build Coastguard Worker EVT VT = Val.getValueType();
3408*9880d681SAndroid Build Coastguard Worker int Alignment = ST->getAlignment();
3409*9880d681SAndroid Build Coastguard Worker
3410*9880d681SAndroid Build Coastguard Worker SDLoc dl(ST);
3411*9880d681SAndroid Build Coastguard Worker if (ST->getMemoryVT().isFloatingPoint() ||
3412*9880d681SAndroid Build Coastguard Worker ST->getMemoryVT().isVector()) {
3413*9880d681SAndroid Build Coastguard Worker EVT intVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
3414*9880d681SAndroid Build Coastguard Worker if (isTypeLegal(intVT)) {
3415*9880d681SAndroid Build Coastguard Worker if (!isOperationLegalOrCustom(ISD::STORE, intVT)) {
3416*9880d681SAndroid Build Coastguard Worker // Scalarize the store and let the individual components be handled.
3417*9880d681SAndroid Build Coastguard Worker SDValue Result = scalarizeVectorStore(ST, DAG);
3418*9880d681SAndroid Build Coastguard Worker
3419*9880d681SAndroid Build Coastguard Worker return Result;
3420*9880d681SAndroid Build Coastguard Worker }
3421*9880d681SAndroid Build Coastguard Worker // Expand to a bitconvert of the value to the integer type of the
3422*9880d681SAndroid Build Coastguard Worker // same size, then a (misaligned) int store.
3423*9880d681SAndroid Build Coastguard Worker // FIXME: Does not handle truncating floating point stores!
3424*9880d681SAndroid Build Coastguard Worker SDValue Result = DAG.getNode(ISD::BITCAST, dl, intVT, Val);
3425*9880d681SAndroid Build Coastguard Worker Result = DAG.getStore(Chain, dl, Result, Ptr, ST->getPointerInfo(),
3426*9880d681SAndroid Build Coastguard Worker ST->isVolatile(), ST->isNonTemporal(), Alignment);
3427*9880d681SAndroid Build Coastguard Worker return Result;
3428*9880d681SAndroid Build Coastguard Worker }
3429*9880d681SAndroid Build Coastguard Worker // Do a (aligned) store to a stack slot, then copy from the stack slot
3430*9880d681SAndroid Build Coastguard Worker // to the final destination using (unaligned) integer loads and stores.
3431*9880d681SAndroid Build Coastguard Worker EVT StoredVT = ST->getMemoryVT();
3432*9880d681SAndroid Build Coastguard Worker MVT RegVT =
3433*9880d681SAndroid Build Coastguard Worker getRegisterType(*DAG.getContext(),
3434*9880d681SAndroid Build Coastguard Worker EVT::getIntegerVT(*DAG.getContext(),
3435*9880d681SAndroid Build Coastguard Worker StoredVT.getSizeInBits()));
3436*9880d681SAndroid Build Coastguard Worker EVT PtrVT = Ptr.getValueType();
3437*9880d681SAndroid Build Coastguard Worker unsigned StoredBytes = StoredVT.getSizeInBits() / 8;
3438*9880d681SAndroid Build Coastguard Worker unsigned RegBytes = RegVT.getSizeInBits() / 8;
3439*9880d681SAndroid Build Coastguard Worker unsigned NumRegs = (StoredBytes + RegBytes - 1) / RegBytes;
3440*9880d681SAndroid Build Coastguard Worker
3441*9880d681SAndroid Build Coastguard Worker // Make sure the stack slot is also aligned for the register type.
3442*9880d681SAndroid Build Coastguard Worker SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT);
3443*9880d681SAndroid Build Coastguard Worker
3444*9880d681SAndroid Build Coastguard Worker // Perform the original store, only redirected to the stack slot.
3445*9880d681SAndroid Build Coastguard Worker SDValue Store = DAG.getTruncStore(Chain, dl,
3446*9880d681SAndroid Build Coastguard Worker Val, StackPtr, MachinePointerInfo(),
3447*9880d681SAndroid Build Coastguard Worker StoredVT, false, false, 0);
3448*9880d681SAndroid Build Coastguard Worker
3449*9880d681SAndroid Build Coastguard Worker EVT StackPtrVT = StackPtr.getValueType();
3450*9880d681SAndroid Build Coastguard Worker
3451*9880d681SAndroid Build Coastguard Worker SDValue PtrIncrement = DAG.getConstant(RegBytes, dl, PtrVT);
3452*9880d681SAndroid Build Coastguard Worker SDValue StackPtrIncrement = DAG.getConstant(RegBytes, dl, StackPtrVT);
3453*9880d681SAndroid Build Coastguard Worker SmallVector<SDValue, 8> Stores;
3454*9880d681SAndroid Build Coastguard Worker unsigned Offset = 0;
3455*9880d681SAndroid Build Coastguard Worker
3456*9880d681SAndroid Build Coastguard Worker // Do all but one copies using the full register width.
3457*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1; i < NumRegs; i++) {
3458*9880d681SAndroid Build Coastguard Worker // Load one integer register's worth from the stack slot.
3459*9880d681SAndroid Build Coastguard Worker SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr,
3460*9880d681SAndroid Build Coastguard Worker MachinePointerInfo(),
3461*9880d681SAndroid Build Coastguard Worker false, false, false, 0);
3462*9880d681SAndroid Build Coastguard Worker // Store it to the final location. Remember the store.
3463*9880d681SAndroid Build Coastguard Worker Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr,
3464*9880d681SAndroid Build Coastguard Worker ST->getPointerInfo().getWithOffset(Offset),
3465*9880d681SAndroid Build Coastguard Worker ST->isVolatile(), ST->isNonTemporal(),
3466*9880d681SAndroid Build Coastguard Worker MinAlign(ST->getAlignment(), Offset)));
3467*9880d681SAndroid Build Coastguard Worker // Increment the pointers.
3468*9880d681SAndroid Build Coastguard Worker Offset += RegBytes;
3469*9880d681SAndroid Build Coastguard Worker StackPtr = DAG.getNode(ISD::ADD, dl, StackPtrVT,
3470*9880d681SAndroid Build Coastguard Worker StackPtr, StackPtrIncrement);
3471*9880d681SAndroid Build Coastguard Worker Ptr = DAG.getNode(ISD::ADD, dl, PtrVT, Ptr, PtrIncrement);
3472*9880d681SAndroid Build Coastguard Worker }
3473*9880d681SAndroid Build Coastguard Worker
3474*9880d681SAndroid Build Coastguard Worker // The last store may be partial. Do a truncating store. On big-endian
3475*9880d681SAndroid Build Coastguard Worker // machines this requires an extending load from the stack slot to ensure
3476*9880d681SAndroid Build Coastguard Worker // that the bits are in the right place.
3477*9880d681SAndroid Build Coastguard Worker EVT MemVT = EVT::getIntegerVT(*DAG.getContext(),
3478*9880d681SAndroid Build Coastguard Worker 8 * (StoredBytes - Offset));
3479*9880d681SAndroid Build Coastguard Worker
3480*9880d681SAndroid Build Coastguard Worker // Load from the stack slot.
3481*9880d681SAndroid Build Coastguard Worker SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr,
3482*9880d681SAndroid Build Coastguard Worker MachinePointerInfo(),
3483*9880d681SAndroid Build Coastguard Worker MemVT, false, false, false, 0);
3484*9880d681SAndroid Build Coastguard Worker
3485*9880d681SAndroid Build Coastguard Worker Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr,
3486*9880d681SAndroid Build Coastguard Worker ST->getPointerInfo()
3487*9880d681SAndroid Build Coastguard Worker .getWithOffset(Offset),
3488*9880d681SAndroid Build Coastguard Worker MemVT, ST->isVolatile(),
3489*9880d681SAndroid Build Coastguard Worker ST->isNonTemporal(),
3490*9880d681SAndroid Build Coastguard Worker MinAlign(ST->getAlignment(), Offset),
3491*9880d681SAndroid Build Coastguard Worker ST->getAAInfo()));
3492*9880d681SAndroid Build Coastguard Worker // The order of the stores doesn't matter - say it with a TokenFactor.
3493*9880d681SAndroid Build Coastguard Worker SDValue Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Stores);
3494*9880d681SAndroid Build Coastguard Worker return Result;
3495*9880d681SAndroid Build Coastguard Worker }
3496*9880d681SAndroid Build Coastguard Worker
3497*9880d681SAndroid Build Coastguard Worker assert(ST->getMemoryVT().isInteger() &&
3498*9880d681SAndroid Build Coastguard Worker !ST->getMemoryVT().isVector() &&
3499*9880d681SAndroid Build Coastguard Worker "Unaligned store of unknown type.");
3500*9880d681SAndroid Build Coastguard Worker // Get the half-size VT
3501*9880d681SAndroid Build Coastguard Worker EVT NewStoredVT = ST->getMemoryVT().getHalfSizedIntegerVT(*DAG.getContext());
3502*9880d681SAndroid Build Coastguard Worker int NumBits = NewStoredVT.getSizeInBits();
3503*9880d681SAndroid Build Coastguard Worker int IncrementSize = NumBits / 8;
3504*9880d681SAndroid Build Coastguard Worker
3505*9880d681SAndroid Build Coastguard Worker // Divide the stored value in two parts.
3506*9880d681SAndroid Build Coastguard Worker SDValue ShiftAmount =
3507*9880d681SAndroid Build Coastguard Worker DAG.getConstant(NumBits, dl, getShiftAmountTy(Val.getValueType(),
3508*9880d681SAndroid Build Coastguard Worker DAG.getDataLayout()));
3509*9880d681SAndroid Build Coastguard Worker SDValue Lo = Val;
3510*9880d681SAndroid Build Coastguard Worker SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount);
3511*9880d681SAndroid Build Coastguard Worker
3512*9880d681SAndroid Build Coastguard Worker // Store the two parts
3513*9880d681SAndroid Build Coastguard Worker SDValue Store1, Store2;
3514*9880d681SAndroid Build Coastguard Worker Store1 = DAG.getTruncStore(Chain, dl,
3515*9880d681SAndroid Build Coastguard Worker DAG.getDataLayout().isLittleEndian() ? Lo : Hi,
3516*9880d681SAndroid Build Coastguard Worker Ptr, ST->getPointerInfo(), NewStoredVT,
3517*9880d681SAndroid Build Coastguard Worker ST->isVolatile(), ST->isNonTemporal(), Alignment);
3518*9880d681SAndroid Build Coastguard Worker
3519*9880d681SAndroid Build Coastguard Worker EVT PtrVT = Ptr.getValueType();
3520*9880d681SAndroid Build Coastguard Worker Ptr = DAG.getNode(ISD::ADD, dl, PtrVT, Ptr,
3521*9880d681SAndroid Build Coastguard Worker DAG.getConstant(IncrementSize, dl, PtrVT));
3522*9880d681SAndroid Build Coastguard Worker Alignment = MinAlign(Alignment, IncrementSize);
3523*9880d681SAndroid Build Coastguard Worker Store2 = DAG.getTruncStore(
3524*9880d681SAndroid Build Coastguard Worker Chain, dl, DAG.getDataLayout().isLittleEndian() ? Hi : Lo, Ptr,
3525*9880d681SAndroid Build Coastguard Worker ST->getPointerInfo().getWithOffset(IncrementSize), NewStoredVT,
3526*9880d681SAndroid Build Coastguard Worker ST->isVolatile(), ST->isNonTemporal(), Alignment, ST->getAAInfo());
3527*9880d681SAndroid Build Coastguard Worker
3528*9880d681SAndroid Build Coastguard Worker SDValue Result =
3529*9880d681SAndroid Build Coastguard Worker DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
3530*9880d681SAndroid Build Coastguard Worker return Result;
3531*9880d681SAndroid Build Coastguard Worker }
3532*9880d681SAndroid Build Coastguard Worker
3533*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
3534*9880d681SAndroid Build Coastguard Worker // Implementation of Emulated TLS Model
3535*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
3536*9880d681SAndroid Build Coastguard Worker
LowerToTLSEmulatedModel(const GlobalAddressSDNode * GA,SelectionDAG & DAG) const3537*9880d681SAndroid Build Coastguard Worker SDValue TargetLowering::LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,
3538*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
3539*9880d681SAndroid Build Coastguard Worker // Access to address of TLS varialbe xyz is lowered to a function call:
3540*9880d681SAndroid Build Coastguard Worker // __emutls_get_address( address of global variable named "__emutls_v.xyz" )
3541*9880d681SAndroid Build Coastguard Worker EVT PtrVT = getPointerTy(DAG.getDataLayout());
3542*9880d681SAndroid Build Coastguard Worker PointerType *VoidPtrType = Type::getInt8PtrTy(*DAG.getContext());
3543*9880d681SAndroid Build Coastguard Worker SDLoc dl(GA);
3544*9880d681SAndroid Build Coastguard Worker
3545*9880d681SAndroid Build Coastguard Worker ArgListTy Args;
3546*9880d681SAndroid Build Coastguard Worker ArgListEntry Entry;
3547*9880d681SAndroid Build Coastguard Worker std::string NameString = ("__emutls_v." + GA->getGlobal()->getName()).str();
3548*9880d681SAndroid Build Coastguard Worker Module *VariableModule = const_cast<Module*>(GA->getGlobal()->getParent());
3549*9880d681SAndroid Build Coastguard Worker StringRef EmuTlsVarName(NameString);
3550*9880d681SAndroid Build Coastguard Worker GlobalVariable *EmuTlsVar = VariableModule->getNamedGlobal(EmuTlsVarName);
3551*9880d681SAndroid Build Coastguard Worker assert(EmuTlsVar && "Cannot find EmuTlsVar ");
3552*9880d681SAndroid Build Coastguard Worker Entry.Node = DAG.getGlobalAddress(EmuTlsVar, dl, PtrVT);
3553*9880d681SAndroid Build Coastguard Worker Entry.Ty = VoidPtrType;
3554*9880d681SAndroid Build Coastguard Worker Args.push_back(Entry);
3555*9880d681SAndroid Build Coastguard Worker
3556*9880d681SAndroid Build Coastguard Worker SDValue EmuTlsGetAddr = DAG.getExternalSymbol("__emutls_get_address", PtrVT);
3557*9880d681SAndroid Build Coastguard Worker
3558*9880d681SAndroid Build Coastguard Worker TargetLowering::CallLoweringInfo CLI(DAG);
3559*9880d681SAndroid Build Coastguard Worker CLI.setDebugLoc(dl).setChain(DAG.getEntryNode());
3560*9880d681SAndroid Build Coastguard Worker CLI.setCallee(CallingConv::C, VoidPtrType, EmuTlsGetAddr, std::move(Args));
3561*9880d681SAndroid Build Coastguard Worker std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
3562*9880d681SAndroid Build Coastguard Worker
3563*9880d681SAndroid Build Coastguard Worker // TLSADDR will be codegen'ed as call. Inform MFI that function has calls.
3564*9880d681SAndroid Build Coastguard Worker // At last for X86 targets, maybe good for other targets too?
3565*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
3566*9880d681SAndroid Build Coastguard Worker MFI->setAdjustsStack(true); // Is this only for X86 target?
3567*9880d681SAndroid Build Coastguard Worker MFI->setHasCalls(true);
3568*9880d681SAndroid Build Coastguard Worker
3569*9880d681SAndroid Build Coastguard Worker assert((GA->getOffset() == 0) &&
3570*9880d681SAndroid Build Coastguard Worker "Emulated TLS must have zero offset in GlobalAddressSDNode");
3571*9880d681SAndroid Build Coastguard Worker return CallResult.first;
3572*9880d681SAndroid Build Coastguard Worker }
3573