@@ -6846,6 +6846,99 @@ SDValue RISCVTargetLowering::expandUnalignedRVVStore(SDValue Op,
68466846 Store->getMemOperand()->getFlags());
68476847}
68486848
6849+ // While RVV has alignment restrictions, we should always be able to load as a
6850+ // legal equivalently-sized byte-typed vector instead. This method is
6851+ // responsible for re-expressing a ISD::VP_LOAD via a correctly-aligned type. If
6852+ // the load is already correctly-aligned, it returns SDValue().
6853+ SDValue RISCVTargetLowering::expandUnalignedVPLoad(SDValue Op,
6854+ SelectionDAG &DAG) const {
6855+ auto *Load = cast<VPLoadSDNode>(Op);
6856+ assert(Load && Load->getMemoryVT().isVector() && "Expected vector load");
6857+
6858+ if (allowsMemoryAccessForAlignment(*DAG.getContext(), DAG.getDataLayout(),
6859+ Load->getMemoryVT(),
6860+ *Load->getMemOperand()))
6861+ return SDValue();
6862+
6863+ SDValue Mask = Load->getMask();
6864+
6865+ // FIXME: Handled masked loads somehow.
6866+ if (!ISD::isConstantSplatVectorAllOnes(Mask.getNode()))
6867+ return SDValue();
6868+
6869+ SDLoc DL(Op);
6870+ MVT VT = Op.getSimpleValueType();
6871+ unsigned EltSizeBits = VT.getScalarSizeInBits();
6872+ assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6873+ "Unexpected unaligned RVV load type");
6874+ MVT NewVT =
6875+ MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
6876+ assert(NewVT.isValid() &&
6877+ "Expecting equally-sized RVV vector types to be legal");
6878+
6879+ SDValue VL = Load->getVectorLength();
6880+ VL = DAG.getNode(ISD::MUL, DL, VL.getValueType(), VL,
6881+ DAG.getConstant((EltSizeBits / 8), DL, VL.getValueType()));
6882+
6883+ MVT MaskVT = MVT::getVectorVT(MVT::i1, NewVT.getVectorElementCount());
6884+ SDValue L = DAG.getLoadVP(NewVT, DL, Load->getChain(), Load->getBasePtr(),
6885+ DAG.getAllOnesConstant(DL, MaskVT), VL,
6886+ Load->getPointerInfo(), Load->getBaseAlign(),
6887+ Load->getMemOperand()->getFlags(), AAMDNodes());
6888+ return DAG.getMergeValues({DAG.getBitcast(VT, L), L.getValue(1)}, DL);
6889+ }
6890+
6891+ // While RVV has alignment restrictions, we should always be able to store as a
6892+ // legal equivalently-sized byte-typed vector instead. This method is
6893+ // responsible for re-expressing a ISD::VP STORE via a correctly-aligned type.
6894+ // It returns SDValue() if the store is already correctly aligned.
6895+ SDValue RISCVTargetLowering::expandUnalignedVPStore(SDValue Op,
6896+ SelectionDAG &DAG) const {
6897+ auto *Store = cast<VPStoreSDNode>(Op);
6898+ assert(Store && Store->getValue().getValueType().isVector() &&
6899+ "Expected vector store");
6900+
6901+ if (allowsMemoryAccessForAlignment(*DAG.getContext(), DAG.getDataLayout(),
6902+ Store->getMemoryVT(),
6903+ *Store->getMemOperand()))
6904+ return SDValue();
6905+
6906+ SDValue Mask = Store->getMask();
6907+
6908+ // FIXME: Handled masked stores somehow.
6909+ if (!ISD::isConstantSplatVectorAllOnes(Mask.getNode()))
6910+ return SDValue();
6911+
6912+ SDLoc DL(Op);
6913+ SDValue StoredVal = Store->getValue();
6914+ MVT VT = StoredVal.getSimpleValueType();
6915+ unsigned EltSizeBits = VT.getScalarSizeInBits();
6916+ assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6917+ "Unexpected unaligned RVV store type");
6918+ MVT NewVT =
6919+ MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
6920+ assert(NewVT.isValid() &&
6921+ "Expecting equally-sized RVV vector types to be legal");
6922+
6923+ SDValue VL = Store->getVectorLength();
6924+ VL = DAG.getNode(ISD::MUL, DL, VL.getValueType(), VL,
6925+ DAG.getConstant((EltSizeBits / 8), DL, VL.getValueType()));
6926+
6927+ StoredVal = DAG.getBitcast(NewVT, StoredVal);
6928+
6929+ LocationSize Size = LocationSize::precise(NewVT.getStoreSize());
6930+ MachineFunction &MF = DAG.getMachineFunction();
6931+ MachineMemOperand *MMO = MF.getMachineMemOperand(
6932+ Store->getPointerInfo(), Store->getMemOperand()->getFlags(), Size,
6933+ Store->getBaseAlign());
6934+
6935+ MVT MaskVT = MVT::getVectorVT(MVT::i1, NewVT.getVectorElementCount());
6936+ return DAG.getStoreVP(Store->getChain(), DL, StoredVal, Store->getBasePtr(),
6937+ DAG.getUNDEF(Store->getBasePtr().getValueType()),
6938+ DAG.getAllOnesConstant(DL, MaskVT), VL, NewVT, MMO,
6939+ ISD::UNINDEXED);
6940+ }
6941+
68496942static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG,
68506943 const RISCVSubtarget &Subtarget) {
68516944 assert(Op.getValueType() == MVT::i64 && "Unexpected VT");
@@ -8401,13 +8494,19 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
84018494 return lowerFixedLengthVectorStoreToRVV(Op, DAG);
84028495 return Op;
84038496 }
8404- case ISD::MLOAD:
84058497 case ISD::VP_LOAD:
8498+ if (SDValue V = expandUnalignedVPLoad(Op, DAG))
8499+ return V;
8500+ [[fallthrough]];
8501+ case ISD::MLOAD:
84068502 return lowerMaskedLoad(Op, DAG);
84078503 case ISD::VP_LOAD_FF:
84088504 return lowerLoadFF(Op, DAG);
8409- case ISD::MSTORE:
84108505 case ISD::VP_STORE:
8506+ if (SDValue V = expandUnalignedVPStore(Op, DAG))
8507+ return V;
8508+ [[fallthrough]];
8509+ case ISD::MSTORE:
84118510 return lowerMaskedStore(Op, DAG);
84128511 case ISD::VECTOR_COMPRESS:
84138512 return lowerVectorCompress(Op, DAG);
0 commit comments