29 return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI();
44 if (ST.isThumb1Only()) {
46 LegacyInfo.computeTables();
47 verify(*ST.getInstrInfo());
52 .legalForCartesianProduct({s8, s16, s32}, {s1, s8, s16});
58 .clampScalar(0, s32, s32);
70 .legalFor({{s32, s32}})
74 bool HasHWDivide = (!ST.isThumb() && ST.hasDivideInARMMode()) ||
75 (ST.isThumb() && ST.hasDivideInThumbMode());
79 .clampScalar(0, s32, s32);
83 .clampScalar(0, s32, s32);
88 REMBuilder.lowerFor({s32});
90 REMBuilder.customFor({s32});
92 REMBuilder.libcallFor({s32});
103 .clampScalar(0, s32, s32);
118 .legalForTypesWithMemDesc({{s8, p0, s8, 8},
122 .unsupportedIfMemSizeNotPow2();
138 if (!ST.useSoftFloat() && ST.hasVFP2Base()) {
140 {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FCONSTANT, G_FNEG})
141 .legalFor({s32, s64});
158 .legalForCartesianProduct({s32}, {s32, s64});
160 .legalForCartesianProduct({s32, s64}, {s32});
169 .libcallFor({s32, s64});
181 setFCmpLibcallsAEABI();
183 setFCmpLibcallsGNU();
189 .libcallForCartesianProduct({s32}, {s32, s64});
191 .libcallForCartesianProduct({s32, s64}, {s32});
200 LoadStoreBuilder.
lower();
202 if (!ST.useSoftFloat() && ST.hasVFP4Base())
209 if (ST.hasV5TOps() && !ST.isThumb1Only()) {
212 .clampScalar(1, s32, s32)
216 .clampScalar(1, s32, s32)
221 .clampScalar(1, s32, s32)
225 .clampScalar(1, s32, s32)
229 LegacyInfo.computeTables();
230 verify(*ST.getInstrInfo());
233void ARMLegalizerInfo::setFCmpLibcallsAEABI() {
289void ARMLegalizerInfo::setFCmpLibcallsGNU() {
329ARMLegalizerInfo::FCmpLibcallsList
331 unsigned Size)
const {
348 switch (
MI.getOpcode()) {
353 Register OriginalResult =
MI.getOperand(0).getReg();
359 MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
369 {{
MI.getOperand(1).getReg(), ArgTy, 0},
370 {
MI.getOperand(2).getReg(), ArgTy, 0}},
378 MRI.
getType(
MI.getOperand(3).getReg()) &&
379 "Mismatched operands for G_FCMP");
382 auto OriginalResult =
MI.getOperand(0).getReg();
385 auto Libcalls = getFCmpLibcalls(Predicate, OpSize);
387 if (Libcalls.empty()) {
390 "Predicate needs libcalls, but none specified");
393 MI.eraseFromParent();
397 assert((OpSize == 32 || OpSize == 64) &&
"Unsupported operand size");
402 for (
auto Libcall : Libcalls) {
406 {{MI.getOperand(2).getReg(), ArgTy, 0},
407 {MI.getOperand(3).getReg(), ArgTy, 0}},
413 auto ProcessedResult =
425 MIRBuilder.
buildTrunc(ProcessedResult, LibcallResult);
430 MIRBuilder.
buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero);
432 Results.push_back(ProcessedResult);
436 assert(
Results.size() == 2 &&
"Unexpected number of results");
451 MI.getOperand(1).getFPImm()->getValueAPF().bitcastToAPInt();
453 *ConstantInt::get(Ctx, AsInteger));
463 auto StatusBits = MIRBuilder.
buildAnd(FPEnvTy, FPEnv, StatusBitMask);
464 auto NotStatusBitMask =
466 auto FPModeBits = MIRBuilder.
buildAnd(FPEnvTy, Modes, NotStatusBitMask);
467 auto NewFPSCR = MIRBuilder.
buildOr(FPEnvTy, StatusBits, FPModeBits);
471 case G_RESET_FPMODE: {
478 auto NewFPSCR = MIRBuilder.
buildAnd(FPEnvTy, FPEnv, NotModeBitMask);
484 MI.eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file describes how to lower LLVM calls to machine code calls.
static bool AEABI(const ARMSubtarget &ST)
This file declares the targeting of the Machinelegalizer class for ARM.
Function Alias Analysis Results
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
ARMLegalizerInfo(const ARMSubtarget &ST)
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const override
Called for instructions with the Custom LegalizationAction.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
bool isFPPredicate() const
static bool isIntPredicate(Predicate P)
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
void resize(typename StorageT::size_type S)
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
This is an important class for using LLVM in a threaded context.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & custom()
Unconditionally custom lower.
LegalizeRuleSet & alwaysLegal()
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
LegalizeRuleSet & legalForTypesWithMemDesc(std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
The instruction is legal when type indexes 0 and 1 along with the memory size and minimum alignment i...
LegalizeRuleSet & customFor(std::initializer_list< LLT > Types)
@ Legalized
Instruction has been legalized and the MachineFunction changed.
LLVM_ABI LegalizeResult createLibcall(const char *Name, const CallLowering::ArgInfo &Result, ArrayRef< CallLowering::ArgInfo > Args, CallingConv::ID CC, LostDebugLocObserver &LocObserver, MachineInstr *MI=nullptr) const
Helper function that creates a libcall to the given Name using the given calling convention CC.
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
LLVM_ABI LegalizeResult lowerConstant(MachineInstr &MI)
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Helper class to build MachineInstr.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineFunction & getMF()
Getter for the function we currently build.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
MachineInstrBuilder buildGetFPEnv(const DstOp &Dst)
Build and insert Dst = G_GET_FPENV.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_OR Op0, Op1.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildSetFPEnv(const SrcOp &Src)
Build and insert G_SET_FPENV Src.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Wrapper class representing virtual and physical registers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const unsigned FPStatusBits
const unsigned FPReservedBits
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Invariant opcodes: All instruction sets have these as their low opcodes.
This is an optimization pass for GlobalISel generic memory operations.
unsigned ConstantMaterializationCost(unsigned Val, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns the number of instructions required to materialize the given constant in a register,...