@@ -303,8 +303,10 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
303
303
{nxv2s64, p0, nxv2s64, 64 },
304
304
{nxv4s64, p0, nxv4s64, 64 },
305
305
{nxv8s64, p0, nxv8s64, 64 }});
306
+
306
307
LoadStoreActions.widenScalarToNextPow2 (0 , /* MinSize = */ 8 )
307
- .lowerIfMemSizeNotByteSizePow2 ();
308
+ .lowerIfMemSizeNotByteSizePow2 ()
309
+ .custom ();
308
310
309
311
LoadStoreActions.clampScalar (0 , s32, sXLen ).lower ();
310
312
ExtLoadActions.widenScalarToNextPow2 (0 ).clampScalar (0 , s32, sXLen ).lower ();
@@ -677,6 +679,57 @@ bool RISCVLegalizerInfo::legalizeExt(MachineInstr &MI,
677
679
return true ;
678
680
}
679
681
682
+ bool RISCVLegalizerInfo::legalizeLoadStore (MachineInstr &MI,
683
+ MachineIRBuilder &MIB) const {
684
+ MachineRegisterInfo &MRI = *MIB.getMRI ();
685
+ MachineFunction *MF = MI.getParent ()->getParent ();
686
+ const DataLayout &DL = MIB.getDataLayout ();
687
+ LLVMContext &Ctx = MF->getFunction ().getContext ();
688
+
689
+ Register DstReg = MI.getOperand (0 ).getReg ();
690
+ Register PtrReg = MI.getOperand (1 ).getReg ();
691
+ LLT LoadTy = MRI.getType (DstReg);
692
+ assert (LoadTy.isVector () && " Expect vector load." );
693
+ assert (STI.hasVInstructions () &&
694
+ (LoadTy.getScalarSizeInBits () != 64 || STI.hasVInstructionsI64 ()) &&
695
+ (LoadTy.getElementCount ().getKnownMinValue () != 1 ||
696
+ STI.getELen () == 64 ) &&
697
+ " Load type must be legal integer or floating point vector." );
698
+
699
+ assert (MI.hasOneMemOperand () &&
700
+ " Load instructions only have one MemOperand." );
701
+ Align Alignment = (*MI.memoperands_begin ())->getAlign ();
702
+ MachineMemOperand *LoadMMO = MF->getMachineMemOperand (
703
+ MachinePointerInfo (), MachineMemOperand::MOLoad, LoadTy, Alignment);
704
+
705
+ const auto *TLI = STI.getTargetLowering ();
706
+ EVT VT = EVT::getEVT (getTypeForLLT (LoadTy, Ctx));
707
+
708
+ if (TLI->allowsMemoryAccessForAlignment (Ctx, DL, VT, *LoadMMO))
709
+ return true ;
710
+
711
+ unsigned EltSizeBits = LoadTy.getScalarSizeInBits ();
712
+ assert ((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64 ) &&
713
+ " Unexpected unaligned RVV load type" );
714
+
715
+ // Calculate the new vector type with i8 elements
716
+ unsigned NumElements =
717
+ LoadTy.getElementCount ().getKnownMinValue () * (EltSizeBits / 8 );
718
+ LLT NewLoadTy = LLT::scalable_vector (NumElements, 8 );
719
+
720
+ MachinePointerInfo PI = cast<GLoad>(MI).getMMO ().getPointerInfo ();
721
+ MachineMemOperand *NewLoadMMO = MF->getMachineMemOperand (
722
+ PI, MachineMemOperand::MOLoad, NewLoadTy, Alignment);
723
+
724
+ auto NewLoad = MIB.buildLoad (NewLoadTy, PtrReg, *NewLoadMMO);
725
+
726
+ MIB.buildBitcast (DstReg, NewLoad);
727
+
728
+ MI.eraseFromParent ();
729
+
730
+ return true ;
731
+ }
732
+
680
733
// / Return the type of the mask type suitable for masking the provided
681
734
// / vector type. This is simply an i1 element type vector of the same
682
735
// / (possibly scalable) length.
@@ -854,6 +907,9 @@ bool RISCVLegalizerInfo::legalizeCustom(
854
907
return legalizeExt (MI, MIRBuilder);
855
908
case TargetOpcode::G_SPLAT_VECTOR:
856
909
return legalizeSplatVector (MI, MIRBuilder);
910
+ case TargetOpcode::G_LOAD:
911
+ case TargetOpcode::G_STORE:
912
+ return legalizeLoadStore (MI, MIRBuilder);
857
913
}
858
914
859
915
llvm_unreachable (" expected switch to return" );
0 commit comments