@@ -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 ();
@@ -491,9 +493,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
491
493
}
492
494
493
495
static Type *getTypeForLLT (LLT Ty, LLVMContext &C) {
494
- if (Ty.isVector ())
496
+ if (Ty.isFixedVector ())
495
497
return FixedVectorType::get (IntegerType::get (C, Ty.getScalarSizeInBits ()),
496
498
Ty.getNumElements ());
499
+ if (Ty.isScalableVector ())
500
+ return ScalableVectorType::get (
501
+ IntegerType::get (C, Ty.getScalarSizeInBits ()),
502
+ Ty.getElementCount ().getKnownMinValue ());
503
+
497
504
return IntegerType::get (C, Ty.getSizeInBits ());
498
505
}
499
506
@@ -676,6 +683,51 @@ bool RISCVLegalizerInfo::legalizeExt(MachineInstr &MI,
676
683
return true ;
677
684
}
678
685
686
+ bool RISCVLegalizerInfo::legalizeLoadStore (MachineInstr &MI,
687
+ MachineIRBuilder &MIB) const {
688
+ MachineRegisterInfo &MRI = *MIB.getMRI ();
689
+ MachineFunction *MF = MI.getParent ()->getParent ();
690
+ const DataLayout &DL = MIB.getDataLayout ();
691
+ LLVMContext &Ctx = MF->getFunction ().getContext ();
692
+
693
+ Register DstReg = MI.getOperand (0 ).getReg ();
694
+ Register PtrReg = MI.getOperand (1 ).getReg ();
695
+ LLT LoadTy = MRI.getType (DstReg);
696
+
697
+ assert (MI.hasOneMemOperand () &&
698
+ " Load instructions only have one MemOperand." );
699
+ Align Alignment = (*MI.memoperands_begin ())->getAlign ();
700
+ MachineMemOperand *LoadMMO = MF->getMachineMemOperand (
701
+ MachinePointerInfo (), MachineMemOperand::MOLoad, LoadTy, Alignment);
702
+
703
+ const auto *TLI = STI.getTargetLowering ();
704
+ EVT VT = EVT::getEVT (getTypeForLLT (LoadTy, Ctx));
705
+
706
+ if (TLI->allowsMemoryAccessForAlignment (Ctx, DL, VT, *LoadMMO))
707
+ return true ;
708
+
709
+ unsigned EltSizeBits = LoadTy.getScalarSizeInBits ();
710
+ assert ((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64 ) &&
711
+ " Unexpected unaligned RVV load type" );
712
+
713
+ // Calculate the new vector type with i8 elements
714
+ unsigned NumElements =
715
+ LoadTy.getElementCount ().getKnownMinValue () * (EltSizeBits / 8 );
716
+ LLT NewLoadTy = LLT::scalable_vector (NumElements, 8 );
717
+
718
+ DstOp NewDstReg (NewLoadTy);
719
+ MachineMemOperand *NewLoadMMO = MF->getMachineMemOperand (
720
+ MachinePointerInfo (), MachineMemOperand::MOLoad, NewLoadTy, Alignment);
721
+
722
+ auto NewLoad = MIB.buildLoad (NewDstReg, PtrReg, *NewLoadMMO);
723
+
724
+ MIB.buildBitcast (DstReg, NewLoad.getReg (0 ));
725
+
726
+ MI.eraseFromParent ();
727
+
728
+ return true ;
729
+ }
730
+
679
731
// / Return the type of the mask type suitable for masking the provided
680
732
// / vector type. This is simply an i1 element type vector of the same
681
733
// / (possibly scalable) length.
@@ -853,6 +905,9 @@ bool RISCVLegalizerInfo::legalizeCustom(
853
905
return legalizeExt (MI, MIRBuilder);
854
906
case TargetOpcode::G_SPLAT_VECTOR:
855
907
return legalizeSplatVector (MI, MIRBuilder);
908
+ case TargetOpcode::G_LOAD:
909
+ case TargetOpcode::G_STORE:
910
+ return legalizeLoadStore (MI, MIRBuilder);
856
911
}
857
912
858
913
llvm_unreachable (" expected switch to return" );
0 commit comments