/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
- /// 'IsZeroVal' is true, that means it's safe to return a
+ /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded.
/// target-independent logic.
virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
- bool /*IsZeroVal*/,
+ bool /*ZeroOrLdSrc*/,
bool /*MemcpyStrSrc*/,
MachineFunction &/*MF*/) const {
return MVT::Other;
}
- /// isLegalMemOpType - Returns true if it's legal to use load / store of the
+ /// isSafeMemOpType - Returns true if it's safe to use load / store of the
/// specified type to expand memcpy / memset inline. This is mostly true
- /// for legal types except for some special cases. For example, on X86
+ /// for all types except for some special cases. For example, on X86
/// targets without SSE2 f64 load / store are done with fldl / fstpl which
- /// also does type conversion.
- virtual bool isLegalMemOpType(MVT VT) const {
- return VT.isInteger();
+ /// also does type conversion. Note the specified type doesn't have to be
+ /// legal as the hook is used before type legalization.
+ virtual bool isSafeMemOpType(MVT VT) const {
+ return true;
}
/// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
unsigned Limit, uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool IsZeroVal,
+ bool ZeroOrLdSrc,
bool MemcpyStrSrc,
bool AllowOverlap,
SelectionDAG &DAG,
// 'MemcpyStrSrc' indicates whether the memcpy source is constant so it does
// not need to be loaded.
EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign,
- IsZeroVal, MemcpyStrSrc,
+ ZeroOrLdSrc, MemcpyStrSrc,
DAG.getMachineFunction());
if (VT == MVT::Other) {
if (VT.isVector() || VT.isFloatingPoint()) {
NewVT = (VT.getSizeInBits() > 64) ? MVT::i64 : MVT::i32;
if (TLI.isOperationLegalOrCustom(ISD::STORE, NewVT) &&
- TLI.isLegalMemOpType(NewVT.getSimpleVT()))
+ TLI.isSafeMemOpType(NewVT.getSimpleVT()))
Found = true;
else if (NewVT == MVT::i64 &&
TLI.isOperationLegalOrCustom(ISD::STORE, MVT::f64) &&
- TLI.isLegalMemOpType(MVT::f64)) {
+ TLI.isSafeMemOpType(MVT::f64)) {
// i64 is usually not legal on 32-bit targets, but f64 may be.
NewVT = MVT::f64;
Found = true;
NewVT = (MVT::SimpleValueType)(NewVT.getSimpleVT().SimpleTy - 1);
if (NewVT == MVT::i8)
break;
- } while (!TLI.isLegalMemOpType(NewVT.getSimpleVT()));
+ } while (!TLI.isSafeMemOpType(NewVT.getSimpleVT()));
}
NewVTSize = NewVT.getSizeInBits() / 8;
EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool IsZeroVal,
+ bool ZeroOrLdSrc,
bool MemcpyStrSrc,
MachineFunction &MF) const {
const Function *F = MF.getFunction();
// See if we can use NEON instructions for this...
- if (IsZeroVal &&
+ if (ZeroOrLdSrc &&
Subtarget->hasNEON() &&
!F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) {
bool Fast;
return MVT::Other;
}
-bool ARMTargetLowering::isLegalMemOpType(MVT VT) const {
- return VT.isInteger() || VT == MVT::f64 || VT == MVT::v2f64;
-}
-
bool ARMTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
if (Val.getOpcode() != ISD::LOAD)
return false;
virtual EVT getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool IsZeroVal,
+ bool ZeroOrLdSrc,
bool MemcpyStrSrc,
MachineFunction &MF) const;
- /// isLegalMemOpType - Returns true if it's legal to use load / store of the
- /// specified type to expand memcpy / memset inline. This is mostly true
- /// for legal types except for some special cases. For example, on X86
- /// targets without SSE2 f64 load / store are done with fldl / fstpl which
- /// also does type conversion.
- virtual bool isLegalMemOpType(MVT VT) const;
-
using TargetLowering::isZExtFree;
virtual bool isZExtFree(SDValue Val, EVT VT2) const;
}
EVT MipsTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
- unsigned SrcAlign, bool IsZeroVal,
+ unsigned SrcAlign, bool ZeroOrLdSrc,
bool MemcpyStrSrc,
MachineFunction &MF) const {
if (Subtarget->hasMips64())
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
- unsigned SrcAlign, bool IsZeroVal,
+ unsigned SrcAlign, bool ZeroOrLdSrc,
bool MemcpyStrSrc,
MachineFunction &MF) const;
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
-/// 'IsZeroVal' is true, that means it's safe to return a
+/// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded.
/// target-independent logic.
EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool IsZeroVal,
+ bool ZeroOrLdSrc,
bool MemcpyStrSrc,
MachineFunction &MF) const {
if (this->PPCSubTarget.isPPC64()) {
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
- /// 'IsZeroVal' is true, that means it's safe to return a
+ /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded.
/// target-independent logic.
virtual EVT
getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
- bool IsZeroVal, bool MemcpyStrSrc,
+ bool ZeroOrLdSrc, bool MemcpyStrSrc,
MachineFunction &MF) const;
/// isFMAFasterThanMulAndAdd - Return true if an FMA operation is faster than
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
-/// 'IsZeroVal' is true, that means it's safe to return a
+/// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded.
EVT
X86TargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool IsZeroVal,
+ bool ZeroOrLdSrc,
bool MemcpyStrSrc,
MachineFunction &MF) const {
const Function *F = MF.getFunction();
- if (IsZeroVal &&
+ if (ZeroOrLdSrc &&
!F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) {
if (Size >= 16 &&
(Subtarget->isUnalignedMemAccessFast() ||
return MVT::i32;
}
-bool X86TargetLowering::isLegalMemOpType(MVT VT) const {
+bool X86TargetLowering::isSafeMemOpType(MVT VT) const {
if (VT == MVT::f32)
return X86ScalarSSEf32;
else if (VT == MVT::f64)
return X86ScalarSSEf64;
- return VT.isInteger();
+ return true;
}
bool
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
- /// 'IsZeroVal' is true, that means it's safe to return a
+ /// 'ZeroOrLdSrc' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded.
/// target-independent logic.
virtual EVT
getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
- bool IsZeroVal, bool MemcpyStrSrc,
+ bool ZeroOrLdSrc, bool MemcpyStrSrc,
MachineFunction &MF) const;
- /// isLegalMemOpType - Returns true if it's legal to use load / store of the
+ /// isSafeMemOpType - Returns true if it's safe to use load / store of the
/// specified type to expand memcpy / memset inline. This is mostly true
- /// for legal types except for some special cases. For example, on X86
+ /// for all types except for some special cases. For example, on X86
/// targets without SSE2 f64 load / store are done with fldl / fstpl which
- /// also does type conversion.
- virtual bool isLegalMemOpType(MVT VT) const;
+ /// also does type conversion. Note the specified type doesn't have to be
+ /// legal as the hook is used before type legalization.
+ virtual bool isSafeMemOpType(MVT VT) const;
/// allowsUnalignedMemoryAccesses - Returns true if the target allows
/// unaligned memory accesses. of the specified type. Returns whether it