Note that the strided load from concat_vector combine was using the wrong legality test. It happened to work out as the alignment requirement is based on the scalar type either way, but unless I'm missing something allowsMisalignedAccess is expecting a contiguous memory access.
Differential Revision: https://reviews.llvm.org/D149369
}
private:
- bool isLegalTypeAndAlignment(Type *DataType, Value *AlignOp);
-
bool tryCreateStridedLoadStore(IntrinsicInst *II, Type *DataType, Value *Ptr,
Value *AlignOp);
return new RISCVGatherScatterLowering();
}
-bool RISCVGatherScatterLowering::isLegalTypeAndAlignment(Type *DataType,
- Value *AlignOp) {
- Type *ScalarType = DataType->getScalarType();
- if (!TLI->isLegalElementTypeForRVV(ScalarType))
- return false;
-
- MaybeAlign MA = cast<ConstantInt>(AlignOp)->getMaybeAlignValue();
- if (MA && MA->value() < DL->getTypeStoreSize(ScalarType).getFixedValue())
- return false;
-
- // FIXME: Let the backend type legalize by splitting/widening?
- EVT DataVT = TLI->getValueType(*DL, DataType);
- if (!TLI->isTypeLegal(DataVT))
- return false;
-
- return true;
-}
-
// TODO: Should we consider the mask when looking for a stride?
static std::pair<Value *, Value *> matchStridedConstant(Constant *StartC) {
if (!isa<FixedVectorType>(StartC->getType()))
Value *Ptr,
Value *AlignOp) {
// Make sure the operation will be supported by the backend.
- if (!isLegalTypeAndAlignment(DataType, AlignOp))
+ MaybeAlign MA = cast<ConstantInt>(AlignOp)->getMaybeAlignValue();
+ if (!MA || !TLI->isLegalStridedLoadStore(*DL, DataType, *MA))
+ return false;
+
+ // FIXME: Let the backend type legalize by splitting/widening?
+ if (!TLI->isTypeLegal(TLI->getValueType(*DL, DataType)))
return false;
// Pointer should be a GEP.
if (!TLI.isTypeLegal(WideVecVT))
return SDValue();
+ // Check that the operation is legal
+ Type *WideVecTy = EVT(WideVecVT).getTypeForEVT(*DAG.getContext());
+ if (!TLI.isLegalStridedLoadStore(DAG.getDataLayout(), WideVecTy, Align))
+ return SDValue();
+
MVT ContainerVT = TLI.getContainerForFixedLengthVector(WideVecVT);
SDValue VL =
getDefaultVLOps(WideVecVT, ContainerVT, DL, DAG, Subtarget).second;
BaseLd->getPointerInfo(), BaseLd->getMemOperand()->getFlags(), MemSize,
Align);
- // Can't do the combine if the common alignment isn't naturally aligned with
- // the new element type
- if (!TLI.allowsMemoryAccessForAlignment(*DAG.getContext(),
- DAG.getDataLayout(), WideVecVT, *MMO))
- return SDValue();
-
SDValue StridedLoad = DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, DL, VTs,
Ops, WideVecVT, MMO);
for (SDValue Ld : N->ops())
return Factor * LMUL <= 8;
}
+bool RISCVTargetLowering::isLegalStridedLoadStore(const DataLayout &DL,
+ Type *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())
+ return false;
+
+ Type *ScalarType = DataType->getScalarType();
+ if (!isLegalElementTypeForRVV(ScalarType))
+ return false;
+
+ if (Alignment < DL.getTypeStoreSize(ScalarType).getFixedValue())
+ return false;
+
+ return true;
+}
+
/// Lower an interleaved load into a vlsegN intrinsic.
///
/// E.g. Lower an interleaved load (Factor = 2):
bool isLegalInterleavedAccessType(FixedVectorType *, unsigned Factor,
const DataLayout &) const;
+ /// 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;
+
unsigned getMaxSupportedInterleaveFactor() const override { return 8; }
bool lowerInterleavedLoad(LoadInst *LI,