This was briefly mentioned as a possibility in review discussion on D149369.
One slightly surprising bit to call out - these interfaces can get invoked with non-vector typed arguments. LoopVectorizer likes to call the costing interfaces with scalar types when unrolling, but not vectorizing. I found that surprising, not sure if others do.
Differential Revision: https://reviews.llvm.org/D149462
Value *AlignOp) {
// Make sure the operation will be supported by the backend.
MaybeAlign MA = cast<ConstantInt>(AlignOp)->getMaybeAlignValue();
- if (!MA || !TLI->isLegalStridedLoadStore(*DL, DataType, *MA))
+ EVT DataTypeVT = TLI->getValueType(*DL, DataType);
+ if (!MA || !TLI->isLegalStridedLoadStore(DataTypeVT, *MA))
return false;
// FIXME: Let the backend type legalize by splitting/widening?
- if (!TLI->isTypeLegal(TLI->getValueType(*DL, DataType)))
+ if (!TLI->isTypeLegal(DataTypeVT))
return false;
// Pointer should be a GEP.
(VT.isFixedLengthVector() && VT.getVectorElementType() == MVT::i1);
}
-bool RISCVTargetLowering::isLegalElementTypeForRVV(Type *ScalarTy) const {
- if (ScalarTy->isPointerTy())
+bool RISCVTargetLowering::isLegalElementTypeForRVV(EVT ScalarTy) const {
+ if (!ScalarTy.isSimple())
+ return false;
+ switch (ScalarTy.getSimpleVT().SimpleTy) {
+ case MVT::iPTR:
return Subtarget.is64Bit() ? Subtarget.hasVInstructionsI64() : true;
-
- if (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) ||
- ScalarTy->isIntegerTy(32))
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
return true;
-
- if (ScalarTy->isIntegerTy(64))
+ case MVT::i64:
return Subtarget.hasVInstructionsI64();
-
- if (ScalarTy->isHalfTy())
+ case MVT::f16:
return Subtarget.hasVInstructionsF16();
- if (ScalarTy->isFloatTy())
+ case MVT::f32:
return Subtarget.hasVInstructionsF32();
- if (ScalarTy->isDoubleTy())
+ case MVT::f64:
return Subtarget.hasVInstructionsF64();
-
- return false;
+ default:
+ return false;
+ }
}
+
unsigned RISCVTargetLowering::combineRepeatedFPDivisors() const {
return NumRepeatedDivisors;
}
return SDValue();
// Check that the operation is legal
- Type *WideVecTy = EVT(WideVecVT).getTypeForEVT(*DAG.getContext());
- if (!TLI.isLegalStridedLoadStore(DAG.getDataLayout(), WideVecTy, Align))
+ if (!TLI.isLegalStridedLoadStore(WideVecVT, Align))
return SDValue();
MVT ContainerVT = TLI.getContainerForFixedLengthVector(WideVecVT);
FixedVectorType *VTy, unsigned Factor, const DataLayout &DL) const {
if (!Subtarget.useRVVForFixedLengthVectors())
return false;
- if (!isLegalElementTypeForRVV(VTy->getElementType()))
- return false;
EVT VT = getValueType(DL, VTy);
// Don't lower vlseg/vsseg for fixed length vector types that can't be split.
if (!isTypeLegal(VT))
return false;
+
+ if (!isLegalElementTypeForRVV(VT.getScalarType()))
+ return false;
+
// Sometimes the interleaved access pass picks up splats as interleaves of one
// element. Don't lower these.
if (VTy->getNumElements() < 2)
return Factor * LMUL <= 8;
}
-bool RISCVTargetLowering::isLegalStridedLoadStore(const DataLayout &DL,
- Type *DataType,
+bool RISCVTargetLowering::isLegalStridedLoadStore(EVT DataType,
Align Alignment) const {
if (!Subtarget.hasVInstructions())
return false;
// Only support fixed vectors if we know the minimum vector size.
- if (isa<FixedVectorType>(DataType) && !Subtarget.useRVVForFixedLengthVectors())
+ if (DataType.isFixedLengthVector() && !Subtarget.useRVVForFixedLengthVectors())
return false;
- Type *ScalarType = DataType->getScalarType();
+ EVT ScalarType = DataType.getScalarType();
if (!isLegalElementTypeForRVV(ScalarType))
return false;
if (!Subtarget.enableUnalignedVectorMem() &&
- Alignment < DL.getTypeStoreSize(ScalarType).getFixedValue())
+ Alignment < ScalarType.getStoreSize())
return false;
return true;
bool shouldRemoveExtendFromGSIndex(EVT IndexVT, EVT DataVT) const override;
- bool isLegalElementTypeForRVV(Type *ScalarTy) const;
+ bool isLegalElementTypeForRVV(EVT ScalarTy) const;
bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override;
/// Return true if a stride load store of the given result type and
/// alignment is legal.
- bool isLegalStridedLoadStore(const DataLayout &DL, Type *DataType, Align Alignment) const;
+ bool isLegalStridedLoadStore(EVT DataType, Align Alignment) const;
unsigned getMaxSupportedInterleaveFactor() const override { return 8; }
const Instruction *CxtI = nullptr);
bool isElementTypeLegalForScalableVector(Type *Ty) const {
- return TLI->isLegalElementTypeForRVV(Ty);
+ return TLI->isLegalElementTypeForRVV(TLI->getValueType(DL, Ty));
}
bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) {
if (!ST->hasVInstructions())
return false;
+ EVT DataTypeVT = TLI->getValueType(DL, DataType);
+
// Only support fixed vectors if we know the minimum vector size.
- if (isa<FixedVectorType>(DataType) && !ST->useRVVForFixedLengthVectors())
+ if (DataTypeVT.isFixedLengthVector() && !ST->useRVVForFixedLengthVectors())
return false;
- auto *ElemType = DataType->getScalarType();
- if (!ST->enableUnalignedVectorMem() &&
- Alignment < DL.getTypeStoreSize(ElemType).getFixedValue())
+ EVT ElemType = DataTypeVT.getScalarType();
+ if (!ST->enableUnalignedVectorMem() && Alignment < ElemType.getStoreSize())
return false;
return TLI->isLegalElementTypeForRVV(ElemType);
+
}
bool isLegalMaskedLoad(Type *DataType, Align Alignment) {
if (!ST->hasVInstructions())
return false;
+ EVT DataTypeVT = TLI->getValueType(DL, DataType);
+
// Only support fixed vectors if we know the minimum vector size.
- if (isa<FixedVectorType>(DataType) && !ST->useRVVForFixedLengthVectors())
+ if (DataTypeVT.isFixedLengthVector() && !ST->useRVVForFixedLengthVectors())
return false;
- auto *ElemType = DataType->getScalarType();
- if (!ST->enableUnalignedVectorMem() &&
- Alignment < DL.getTypeStoreSize(ElemType).getFixedValue())
+ EVT ElemType = DataTypeVT.getScalarType();
+ if (!ST->enableUnalignedVectorMem() && Alignment < ElemType.getStoreSize())
return false;
return TLI->isLegalElementTypeForRVV(ElemType);
return true;
Type *Ty = RdxDesc.getRecurrenceType();
- if (!TLI->isLegalElementTypeForRVV(Ty))
+ if (!TLI->isLegalElementTypeForRVV(TLI->getValueType(DL, Ty)))
return false;
switch (RdxDesc.getRecurrenceKind()) {