@@ -6853,6 +6853,97 @@ SDValue RISCVTargetLowering::expandUnalignedRVVStore(SDValue Op,
68536853 Store->getMemOperand()->getFlags());
68546854}
68556855
6856+ // While RVV has alignment restrictions, we should always be able to load as a
6857+ // legal equivalently-sized byte-typed vector instead. This method is
6858+ // responsible for re-expressing a ISD::VP_LOAD via a correctly-aligned type. If
6859+ // the load is already correctly-aligned, it returns SDValue().
6860+ SDValue RISCVTargetLowering::expandUnalignedVPLoad(SDValue Op,
6861+ SelectionDAG &DAG) const {
6862+ auto *Load = cast<VPLoadSDNode>(Op);
6863+ assert(Load && Load->getMemoryVT().isVector() && "Expected vector load");
6864+
6865+ if (allowsMemoryAccessForAlignment(*DAG.getContext(), DAG.getDataLayout(),
6866+ Load->getMemoryVT(),
6867+ *Load->getMemOperand()))
6868+ return SDValue();
6869+
6870+ SDValue Mask = Load->getMask();
6871+
6872+ // FIXME: Handled masked loads somehow.
6873+ if (!ISD::isConstantSplatVectorAllOnes(Mask.getNode()))
6874+ return SDValue();
6875+
6876+ SDLoc DL(Op);
6877+ MVT VT = Op.getSimpleValueType();
6878+ unsigned EltSizeBits = VT.getScalarSizeInBits();
6879+ assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6880+ "Unexpected unaligned RVV load type");
6881+ MVT NewVT =
6882+ MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
6883+ assert(NewVT.isValid() &&
6884+ "Expecting equally-sized RVV vector types to be legal");
6885+
6886+ SDValue VL = Load->getVectorLength();
6887+ VL = DAG.getNode(ISD::MUL, DL, VL.getValueType(), VL,
6888+ DAG.getConstant((EltSizeBits / 8), DL, VL.getValueType()));
6889+
6890+ SDValue L = DAG.getLoadVP(NewVT, DL, Load->getChain(), Load->getBasePtr(),
6891+ DAG.getAllOnesConstant(DL, Mask.getValueType()), VL,
6892+ Load->getPointerInfo(), Load->getBaseAlign(),
6893+ Load->getMemOperand()->getFlags(), AAMDNodes());
6894+ return DAG.getMergeValues({DAG.getBitcast(VT, L), L.getValue(1)}, DL);
6895+ }
6896+
6897+ // While RVV has alignment restrictions, we should always be able to store as a
6898+ // legal equivalently-sized byte-typed vector instead. This method is
6899+ // responsible for re-expressing a ISD::VP STORE via a correctly-aligned type.
6900+ // It returns SDValue() if the store is already correctly aligned.
6901+ SDValue RISCVTargetLowering::expandUnalignedVPStore(SDValue Op,
6902+ SelectionDAG &DAG) const {
6903+ auto *Store = cast<VPStoreSDNode>(Op);
6904+ assert(Store && Store->getValue().getValueType().isVector() &&
6905+ "Expected vector store");
6906+
6907+ if (allowsMemoryAccessForAlignment(*DAG.getContext(), DAG.getDataLayout(),
6908+ Store->getMemoryVT(),
6909+ *Store->getMemOperand()))
6910+ return SDValue();
6911+
6912+ SDValue Mask = Store->getMask();
6913+
6914+ // FIXME: Handled masked stores somehow.
6915+ if (!ISD::isConstantSplatVectorAllOnes(Mask.getNode()))
6916+ return SDValue();
6917+
6918+ SDLoc DL(Op);
6919+ SDValue StoredVal = Store->getValue();
6920+ MVT VT = StoredVal.getSimpleValueType();
6921+ unsigned EltSizeBits = VT.getScalarSizeInBits();
6922+ assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6923+ "Unexpected unaligned RVV store type");
6924+ MVT NewVT =
6925+ MVT::getVectorVT(MVT::i8, VT.getVectorElementCount() * (EltSizeBits / 8));
6926+ assert(NewVT.isValid() &&
6927+ "Expecting equally-sized RVV vector types to be legal");
6928+
6929+ SDValue VL = Store->getVectorLength();
6930+ VL = DAG.getNode(ISD::MUL, DL, VL.getValueType(), VL,
6931+ DAG.getConstant((EltSizeBits / 8), DL, VL.getValueType()));
6932+
6933+ StoredVal = DAG.getBitcast(NewVT, StoredVal);
6934+
6935+ LocationSize Size = LocationSize::precise(NewVT.getStoreSize());
6936+ MachineFunction &MF = DAG.getMachineFunction();
6937+ MachineMemOperand *MMO = MF.getMachineMemOperand(
6938+ Store->getPointerInfo(), Store->getMemOperand()->getFlags(), Size,
6939+ Store->getBaseAlign());
6940+
6941+ return DAG.getStoreVP(Store->getChain(), DL, StoredVal, Store->getBasePtr(),
6942+ DAG.getUNDEF(Store->getBasePtr().getValueType()),
6943+ DAG.getAllOnesConstant(DL, Mask.getValueType()), VL,
6944+ NewVT, MMO, ISD::UNINDEXED);
6945+ }
6946+
68566947static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG,
68576948 const RISCVSubtarget &Subtarget) {
68586949 assert(Op.getValueType() == MVT::i64 && "Unexpected VT");
@@ -8408,13 +8499,19 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
84088499 return lowerFixedLengthVectorStoreToRVV(Op, DAG);
84098500 return Op;
84108501 }
8411- case ISD::MLOAD:
84128502 case ISD::VP_LOAD:
8503+ if (SDValue V = expandUnalignedVPLoad(Op, DAG))
8504+ return V;
8505+ [[fallthrough]];
8506+ case ISD::MLOAD:
84138507 return lowerMaskedLoad(Op, DAG);
84148508 case ISD::VP_LOAD_FF:
84158509 return lowerLoadFF(Op, DAG);
8416- case ISD::MSTORE:
84178510 case ISD::VP_STORE:
8511+ if (SDValue V = expandUnalignedVPStore(Op, DAG))
8512+ return V;
8513+ [[fallthrough]];
8514+ case ISD::MSTORE:
84188515 return lowerMaskedStore(Op, DAG);
84198516 case ISD::VECTOR_COMPRESS:
84208517 return lowerVectorCompress(Op, DAG);
0 commit comments