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