40 for (
unsigned i = 0; i < v.size(); ++i) {
41 result.push_back(v[i]);
42 if (i + 1 < v[i].
first && i + 1 < v.size() &&
43 v[i + 1].first != v[i].first + 1)
44 result.push_back({v[i].first + 1, Unsupported});
58 auto Largest = result.back().first;
68 using namespace TargetOpcode;
85 getActionDefinitionsBuilder({G_SEXT, G_ZEXT, G_ANYEXT})
86 .legalForCartesianProduct({s32}, {s1, s8, s16});
88 getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})
92 getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s32}});
93 getActionDefinitionsBuilder(G_PTRTOINT).legalFor({{s32, p0}});
95 getActionDefinitionsBuilder(G_CONSTANT)
97 .clampScalar(0, s32, s32);
101 auto &LoadStoreBuilder =
102 getActionDefinitionsBuilder({G_LOAD, G_STORE})
103 .legalForTypesWithMemSize({
117 getActionDefinitionsBuilder(G_GLOBAL_VALUE).legalFor({p0});
118 getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0});
121 getActionDefinitionsBuilder({G_SDIV, G_UDIV})
123 .clampScalar(0, s32, s32);
125 getActionDefinitionsBuilder({G_SDIV, G_UDIV})
127 .clampScalar(0, s32, s32);
129 for (
unsigned Op : {G_SREM, G_UREM}) {
130 setLegalizeScalarToDifferentSizeStrategy(
Op, 0,
widen_8_16);
139 getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL}).legalFor({s32});
142 getActionDefinitionsBuilder(G_CTLZ)
144 .clampScalar(0, s32, s32);
145 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
147 .clampScalar(0, s32, s32);
149 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
151 .clampScalar(0, s32, s32);
152 getActionDefinitionsBuilder(G_CTLZ)
154 .clampScalar(0, s32, s32);
157 getActionDefinitionsBuilder(G_GEP).legalFor({{p0, s32}});
159 getActionDefinitionsBuilder(G_SELECT).legalForCartesianProduct({s32, p0},
162 getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
164 getActionDefinitionsBuilder(G_ICMP)
165 .legalForCartesianProduct({s1}, {s32, p0})
171 getActionDefinitionsBuilder(G_PHI).legalFor({s32, p0}).minScalar(0, s32);
174 getActionDefinitionsBuilder(
175 {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FCONSTANT, G_FNEG})
176 .legalFor({s32, s64});
178 LoadStoreBuilder.legalFor({{s64, p0}});
179 PhiBuilder.legalFor({s64});
181 getActionDefinitionsBuilder(G_FCMP).legalForCartesianProduct({s1},
184 getActionDefinitionsBuilder(G_MERGE_VALUES).legalFor({{s64, s32}});
185 getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}});
187 getActionDefinitionsBuilder(G_FPEXT).legalFor({{s64, s32}});
188 getActionDefinitionsBuilder(G_FPTRUNC).legalFor({{s32, s64}});
190 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
191 .legalForCartesianProduct({s32}, {s32, s64});
192 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
193 .legalForCartesianProduct({s32, s64}, {s32});
195 getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
196 .libcallFor({s32, s64});
198 LoadStoreBuilder.maxScalar(0, s32);
200 for (
auto Ty : {s32, s64})
201 setAction({G_FNEG, Ty},
Lower);
203 getActionDefinitionsBuilder(G_FCONSTANT).customFor({s32, s64});
205 getActionDefinitionsBuilder(G_FCMP).customForCartesianProduct({s1},
209 setFCmpLibcallsAEABI();
211 setFCmpLibcallsGNU();
213 getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s64, s32}});
214 getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s32, s64}});
216 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
217 .libcallForCartesianProduct({s32}, {s32, s64});
218 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
219 .libcallForCartesianProduct({s32, s64}, {s32});
223 getActionDefinitionsBuilder(G_FMA).legalFor({s32, s64});
225 getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64});
227 getActionDefinitionsBuilder({G_FREM, G_FPOW}).libcallFor({s32, s64});
233 void ARMLegalizerInfo::setFCmpLibcallsAEABI() {
240 {RTLIB::OGE_F32, CmpInst::BAD_ICMP_PREDICATE}};
242 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE}};
244 {RTLIB::OLE_F32, CmpInst::BAD_ICMP_PREDICATE}};
246 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
254 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
256 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE},
257 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
259 {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE},
260 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
264 {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE}};
266 {RTLIB::OGE_F64, CmpInst::BAD_ICMP_PREDICATE}};
268 {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE}};
270 {RTLIB::OLE_F64, CmpInst::BAD_ICMP_PREDICATE}};
272 {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}};
280 {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}};
282 {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE},
283 {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}};
285 {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE},
286 {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}};
289 void ARMLegalizerInfo::setFCmpLibcallsGNU() {
306 {RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
308 {RTLIB::UO_F32, CmpInst::ICMP_NE}};
324 {RTLIB::OLT_F64, CmpInst::ICMP_SLT}};
326 {RTLIB::UO_F64, CmpInst::ICMP_NE}};
331 unsigned Size)
const {
344 using namespace TargetOpcode;
360 MI.
getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
386 "Mismatched operands for G_FCMP");
392 auto Libcalls = getFCmpLibcalls(
Predicate, OpSize);
394 if (Libcalls.empty()) {
397 "Predicate needs libcalls, but none specified");
404 assert((OpSize == 32 || OpSize == 64) &&
"Unsupported operand size");
409 for (
auto Libcall : Libcalls) {
413 {{MI.getOperand(2).getReg(), ArgTy},
414 {MI.getOperand(3).getReg(), ArgTy}});
419 auto ProcessedResult =
431 MIRBuilder.
buildTrunc(ProcessedResult, LibcallResult);
437 MIRBuilder.
buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero);
458 MI.eraseFromParent();
bool isFPPredicate() const
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
bool isTargetGNUAEABI() const
static Type * getDoubleTy(LLVMContext &C)
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
This class represents lattice values for constants.
The operation should be implemented in terms of a wider scalar base-type.
void push_back(const T &Elt)
unsigned getReg() const
getReg - Returns the register number.
static bool AEABI(const ARMSubtarget &ST)
std::vector< SizeAndAction > SizeAndActionsVec
0 1 0 0 True if ordered and less than
Function Alias Analysis Results
MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_OR Op0, Op1.
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
1 1 1 0 True if unordered or not equal
bool isThumb1Only() const
bool isTargetMuslAEABI() const
const ARMBaseInstrInfo * getInstrInfo() const override
1 0 0 1 True if unordered or equal
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
static Type * getFloatTy(LLVMContext &C)
const ConstantFP * getFPImm() const
Class to represent struct types.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
0 1 0 1 True if ordered and less than or equal
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
This operation is completely unsupported on the target.
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
LegalizerHelper::LegalizeResult createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result, ArrayRef< CallLowering::ArgInfo > Args)
Helper function that creates the given libcall.
MachineFunction & getMF()
Getter for the function we currently build.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
The operation itself must be expressed in terms of simpler actions on this target.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
static LegalizerInfo::SizeAndActionsVec widen_8_16(const LegalizerInfo::SizeAndActionsVec &v)
bool hasDivideInARMMode() const
Abstract class that contains various methods for clients to notify about changes. ...
unsigned const MachineRegisterInfo * MRI
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This file declares the targeting of the Machinelegalizer class for ARM.
Helper class to build MachineInstr.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
ARMLegalizerInfo(const ARMSubtarget &ST)
0 1 1 1 True if ordered (no nans)
1 1 1 1 Always true (always folded)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
1 1 0 1 True if unordered, less than, or equal
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
const APFloat & getValueAPF() const
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
0 0 1 0 True if ordered and greater than
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
bool useSoftFloat() const
bool isTargetAEABI() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
1 1 0 0 True if unordered or less than
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
The operation should be implemented as a call to some kind of runtime support library.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
The target wants to do something special with this combination of operand and type.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
bool isIntPredicate() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Instruction has been legalized and the MachineFunction changed.
static IntegerType * getInt32Ty(LLVMContext &C)
bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const override
0 1 1 0 True if ordered and operands are unequal
static void addAndInterleaveWithUnsupported(LegalizerInfo::SizeAndActionsVec &result, const LegalizerInfo::SizeAndActionsVec &v)
FIXME: The following static functions are SizeChangeStrategy functions that are meant to temporarily ...
1 0 1 0 True if unordered or greater than
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
0 0 0 1 True if ordered and equal
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
1 0 1 1 True if unordered, greater than, or equal
APInt bitcastToAPInt() const
This file describes how to lower LLVM calls to machine code calls.
const MachineOperand & getOperand(unsigned i) const
0 0 1 1 True if ordered and greater than or equal
0 0 0 0 Always false (always folded)
unsigned getPredicate() const