@@ -2747,20 +2747,72 @@ bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
2747
2747
Intrinsic::ID IID = Inst->getIntrinsicID ();
2748
2748
LLVMContext &C = Inst->getContext ();
2749
2749
bool HasMask = false ;
2750
+
2751
+ auto getSegNum = [](const IntrinsicInst *II, unsigned PtrOperandNo,
2752
+ bool IsWrite) -> int64_t {
2753
+ if (auto *TarExtTy =
2754
+ dyn_cast<TargetExtType>(II->getArgOperand (0 )->getType ()))
2755
+ return TarExtTy->getIntParameter (0 );
2756
+
2757
+ return 1 ;
2758
+ };
2759
+
2750
2760
switch (IID) {
2751
2761
case Intrinsic::riscv_vle_mask:
2752
2762
case Intrinsic::riscv_vse_mask:
2763
+ case Intrinsic::riscv_vlseg2_mask:
2764
+ case Intrinsic::riscv_vlseg3_mask:
2765
+ case Intrinsic::riscv_vlseg4_mask:
2766
+ case Intrinsic::riscv_vlseg5_mask:
2767
+ case Intrinsic::riscv_vlseg6_mask:
2768
+ case Intrinsic::riscv_vlseg7_mask:
2769
+ case Intrinsic::riscv_vlseg8_mask:
2770
+ case Intrinsic::riscv_vsseg2_mask:
2771
+ case Intrinsic::riscv_vsseg3_mask:
2772
+ case Intrinsic::riscv_vsseg4_mask:
2773
+ case Intrinsic::riscv_vsseg5_mask:
2774
+ case Intrinsic::riscv_vsseg6_mask:
2775
+ case Intrinsic::riscv_vsseg7_mask:
2776
+ case Intrinsic::riscv_vsseg8_mask:
2753
2777
HasMask = true ;
2754
2778
[[fallthrough]];
2755
2779
case Intrinsic::riscv_vle:
2756
- case Intrinsic::riscv_vse: {
2780
+ case Intrinsic::riscv_vse:
2781
+ case Intrinsic::riscv_vlseg2:
2782
+ case Intrinsic::riscv_vlseg3:
2783
+ case Intrinsic::riscv_vlseg4:
2784
+ case Intrinsic::riscv_vlseg5:
2785
+ case Intrinsic::riscv_vlseg6:
2786
+ case Intrinsic::riscv_vlseg7:
2787
+ case Intrinsic::riscv_vlseg8:
2788
+ case Intrinsic::riscv_vsseg2:
2789
+ case Intrinsic::riscv_vsseg3:
2790
+ case Intrinsic::riscv_vsseg4:
2791
+ case Intrinsic::riscv_vsseg5:
2792
+ case Intrinsic::riscv_vsseg6:
2793
+ case Intrinsic::riscv_vsseg7:
2794
+ case Intrinsic::riscv_vsseg8: {
2757
2795
// Intrinsic interface:
2758
2796
// riscv_vle(merge, ptr, vl)
2759
2797
// riscv_vle_mask(merge, ptr, mask, vl, policy)
2760
2798
// riscv_vse(val, ptr, vl)
2761
2799
// riscv_vse_mask(val, ptr, mask, vl, policy)
2800
+ // riscv_vlseg#(merge, ptr, vl, sew)
2801
+ // riscv_vlseg#_mask(merge, ptr, mask, vl, policy, sew)
2802
+ // riscv_vsseg#(val, ptr, vl, sew)
2803
+ // riscv_vsseg#_mask(val, ptr, mask, vl, sew)
2762
2804
bool IsWrite = Inst->getType ()->isVoidTy ();
2763
2805
Type *Ty = IsWrite ? Inst->getArgOperand (0 )->getType () : Inst->getType ();
2806
+ // The results of segment loads are TargetExtType.
2807
+ if (auto *TarExtTy = dyn_cast<TargetExtType>(Ty)) {
2808
+ unsigned SEW =
2809
+ 1 << cast<ConstantInt>(Inst->getArgOperand (Inst->arg_size () - 1 ))
2810
+ ->getZExtValue ();
2811
+ Ty = TarExtTy->getTypeParameter (0U );
2812
+ Ty = ScalableVectorType::get (
2813
+ IntegerType::get (C, SEW),
2814
+ cast<ScalableVectorType>(Ty)->getMinNumElements () * 8 / SEW);
2815
+ }
2764
2816
const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo (IID);
2765
2817
unsigned VLIndex = RVVIInfo->VLOperand ;
2766
2818
unsigned PtrOperandNo = VLIndex - 1 - HasMask;
@@ -2771,23 +2823,72 @@ bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
2771
2823
if (HasMask)
2772
2824
Mask = Inst->getArgOperand (VLIndex - 1 );
2773
2825
Value *EVL = Inst->getArgOperand (VLIndex);
2826
+ unsigned SegNum = getSegNum (Inst, PtrOperandNo, IsWrite);
2827
+ // RVV uses contiguous elements as a segment.
2828
+ if (SegNum > 1 ) {
2829
+ unsigned ElemSize = Ty->getScalarSizeInBits ();
2830
+ auto *SegTy = IntegerType::get (C, ElemSize * SegNum);
2831
+ Ty = VectorType::get (SegTy, cast<VectorType>(Ty));
2832
+ }
2774
2833
Info.InterestingOperands .emplace_back (Inst, PtrOperandNo, IsWrite, Ty,
2775
2834
Alignment, Mask, EVL);
2776
2835
return true ;
2777
2836
}
2778
2837
case Intrinsic::riscv_vlse_mask:
2779
2838
case Intrinsic::riscv_vsse_mask:
2839
+ case Intrinsic::riscv_vlsseg2_mask:
2840
+ case Intrinsic::riscv_vlsseg3_mask:
2841
+ case Intrinsic::riscv_vlsseg4_mask:
2842
+ case Intrinsic::riscv_vlsseg5_mask:
2843
+ case Intrinsic::riscv_vlsseg6_mask:
2844
+ case Intrinsic::riscv_vlsseg7_mask:
2845
+ case Intrinsic::riscv_vlsseg8_mask:
2846
+ case Intrinsic::riscv_vssseg2_mask:
2847
+ case Intrinsic::riscv_vssseg3_mask:
2848
+ case Intrinsic::riscv_vssseg4_mask:
2849
+ case Intrinsic::riscv_vssseg5_mask:
2850
+ case Intrinsic::riscv_vssseg6_mask:
2851
+ case Intrinsic::riscv_vssseg7_mask:
2852
+ case Intrinsic::riscv_vssseg8_mask:
2780
2853
HasMask = true ;
2781
2854
[[fallthrough]];
2782
2855
case Intrinsic::riscv_vlse:
2783
- case Intrinsic::riscv_vsse: {
2856
+ case Intrinsic::riscv_vsse:
2857
+ case Intrinsic::riscv_vlsseg2:
2858
+ case Intrinsic::riscv_vlsseg3:
2859
+ case Intrinsic::riscv_vlsseg4:
2860
+ case Intrinsic::riscv_vlsseg5:
2861
+ case Intrinsic::riscv_vlsseg6:
2862
+ case Intrinsic::riscv_vlsseg7:
2863
+ case Intrinsic::riscv_vlsseg8:
2864
+ case Intrinsic::riscv_vssseg2:
2865
+ case Intrinsic::riscv_vssseg3:
2866
+ case Intrinsic::riscv_vssseg4:
2867
+ case Intrinsic::riscv_vssseg5:
2868
+ case Intrinsic::riscv_vssseg6:
2869
+ case Intrinsic::riscv_vssseg7:
2870
+ case Intrinsic::riscv_vssseg8: {
2784
2871
// Intrinsic interface:
2785
2872
// riscv_vlse(merge, ptr, stride, vl)
2786
2873
// riscv_vlse_mask(merge, ptr, stride, mask, vl, policy)
2787
2874
// riscv_vsse(val, ptr, stride, vl)
2788
2875
// riscv_vsse_mask(val, ptr, stride, mask, vl, policy)
2876
+ // riscv_vlsseg#(merge, ptr, offset, vl, sew)
2877
+ // riscv_vlsseg#_mask(merge, ptr, offset, mask, vl, policy, sew)
2878
+ // riscv_vssseg#(val, ptr, offset, vl, sew)
2879
+ // riscv_vssseg#_mask(val, ptr, offset, mask, vl, sew)
2789
2880
bool IsWrite = Inst->getType ()->isVoidTy ();
2790
2881
Type *Ty = IsWrite ? Inst->getArgOperand (0 )->getType () : Inst->getType ();
2882
+ // The results of segment loads are TargetExtType.
2883
+ if (auto *TarExtTy = dyn_cast<TargetExtType>(Ty)) {
2884
+ unsigned SEW =
2885
+ 1 << cast<ConstantInt>(Inst->getArgOperand (Inst->arg_size () - 1 ))
2886
+ ->getZExtValue ();
2887
+ Ty = TarExtTy->getTypeParameter (0U );
2888
+ Ty = ScalableVectorType::get (
2889
+ IntegerType::get (C, SEW),
2890
+ cast<ScalableVectorType>(Ty)->getMinNumElements () * 8 / SEW);
2891
+ }
2791
2892
const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo (IID);
2792
2893
unsigned VLIndex = RVVIInfo->VLOperand ;
2793
2894
unsigned PtrOperandNo = VLIndex - 2 - HasMask;
@@ -2809,6 +2910,13 @@ bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
2809
2910
if (HasMask)
2810
2911
Mask = Inst->getArgOperand (VLIndex - 1 );
2811
2912
Value *EVL = Inst->getArgOperand (VLIndex);
2913
+ unsigned SegNum = getSegNum (Inst, PtrOperandNo, IsWrite);
2914
+ // RVV uses contiguous elements as a segment.
2915
+ if (SegNum > 1 ) {
2916
+ unsigned ElemSize = Ty->getScalarSizeInBits ();
2917
+ auto *SegTy = IntegerType::get (C, ElemSize * SegNum);
2918
+ Ty = VectorType::get (SegTy, cast<VectorType>(Ty));
2919
+ }
2812
2920
Info.InterestingOperands .emplace_back (Inst, PtrOperandNo, IsWrite, Ty,
2813
2921
Alignment, Mask, EVL, Stride);
2814
2922
return true ;
@@ -2817,19 +2925,89 @@ bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
2817
2925
case Intrinsic::riscv_vluxei_mask:
2818
2926
case Intrinsic::riscv_vsoxei_mask:
2819
2927
case Intrinsic::riscv_vsuxei_mask:
2928
+ case Intrinsic::riscv_vloxseg2_mask:
2929
+ case Intrinsic::riscv_vloxseg3_mask:
2930
+ case Intrinsic::riscv_vloxseg4_mask:
2931
+ case Intrinsic::riscv_vloxseg5_mask:
2932
+ case Intrinsic::riscv_vloxseg6_mask:
2933
+ case Intrinsic::riscv_vloxseg7_mask:
2934
+ case Intrinsic::riscv_vloxseg8_mask:
2935
+ case Intrinsic::riscv_vluxseg2_mask:
2936
+ case Intrinsic::riscv_vluxseg3_mask:
2937
+ case Intrinsic::riscv_vluxseg4_mask:
2938
+ case Intrinsic::riscv_vluxseg5_mask:
2939
+ case Intrinsic::riscv_vluxseg6_mask:
2940
+ case Intrinsic::riscv_vluxseg7_mask:
2941
+ case Intrinsic::riscv_vluxseg8_mask:
2942
+ case Intrinsic::riscv_vsoxseg2_mask:
2943
+ case Intrinsic::riscv_vsoxseg3_mask:
2944
+ case Intrinsic::riscv_vsoxseg4_mask:
2945
+ case Intrinsic::riscv_vsoxseg5_mask:
2946
+ case Intrinsic::riscv_vsoxseg6_mask:
2947
+ case Intrinsic::riscv_vsoxseg7_mask:
2948
+ case Intrinsic::riscv_vsoxseg8_mask:
2949
+ case Intrinsic::riscv_vsuxseg2_mask:
2950
+ case Intrinsic::riscv_vsuxseg3_mask:
2951
+ case Intrinsic::riscv_vsuxseg4_mask:
2952
+ case Intrinsic::riscv_vsuxseg5_mask:
2953
+ case Intrinsic::riscv_vsuxseg6_mask:
2954
+ case Intrinsic::riscv_vsuxseg7_mask:
2955
+ case Intrinsic::riscv_vsuxseg8_mask:
2820
2956
HasMask = true ;
2821
2957
[[fallthrough]];
2822
2958
case Intrinsic::riscv_vloxei:
2823
2959
case Intrinsic::riscv_vluxei:
2824
2960
case Intrinsic::riscv_vsoxei:
2825
- case Intrinsic::riscv_vsuxei: {
2961
+ case Intrinsic::riscv_vsuxei:
2962
+ case Intrinsic::riscv_vloxseg2:
2963
+ case Intrinsic::riscv_vloxseg3:
2964
+ case Intrinsic::riscv_vloxseg4:
2965
+ case Intrinsic::riscv_vloxseg5:
2966
+ case Intrinsic::riscv_vloxseg6:
2967
+ case Intrinsic::riscv_vloxseg7:
2968
+ case Intrinsic::riscv_vloxseg8:
2969
+ case Intrinsic::riscv_vluxseg2:
2970
+ case Intrinsic::riscv_vluxseg3:
2971
+ case Intrinsic::riscv_vluxseg4:
2972
+ case Intrinsic::riscv_vluxseg5:
2973
+ case Intrinsic::riscv_vluxseg6:
2974
+ case Intrinsic::riscv_vluxseg7:
2975
+ case Intrinsic::riscv_vluxseg8:
2976
+ case Intrinsic::riscv_vsoxseg2:
2977
+ case Intrinsic::riscv_vsoxseg3:
2978
+ case Intrinsic::riscv_vsoxseg4:
2979
+ case Intrinsic::riscv_vsoxseg5:
2980
+ case Intrinsic::riscv_vsoxseg6:
2981
+ case Intrinsic::riscv_vsoxseg7:
2982
+ case Intrinsic::riscv_vsoxseg8:
2983
+ case Intrinsic::riscv_vsuxseg2:
2984
+ case Intrinsic::riscv_vsuxseg3:
2985
+ case Intrinsic::riscv_vsuxseg4:
2986
+ case Intrinsic::riscv_vsuxseg5:
2987
+ case Intrinsic::riscv_vsuxseg6:
2988
+ case Intrinsic::riscv_vsuxseg7:
2989
+ case Intrinsic::riscv_vsuxseg8: {
2826
2990
// Intrinsic interface (only listed ordered version):
2827
2991
// riscv_vloxei(merge, ptr, index, vl)
2828
2992
// riscv_vloxei_mask(merge, ptr, index, mask, vl, policy)
2829
2993
// riscv_vsoxei(val, ptr, index, vl)
2830
2994
// riscv_vsoxei_mask(val, ptr, index, mask, vl, policy)
2995
+ // riscv_vloxseg#(merge, ptr, index, vl, sew)
2996
+ // riscv_vloxseg#_mask(merge, ptr, index, mask, vl, policy, sew)
2997
+ // riscv_vsoxseg#(val, ptr, index, vl, sew)
2998
+ // riscv_vsoxseg#_mask(val, ptr, index, mask, vl, sew)
2831
2999
bool IsWrite = Inst->getType ()->isVoidTy ();
2832
3000
Type *Ty = IsWrite ? Inst->getArgOperand (0 )->getType () : Inst->getType ();
3001
+ // The results of segment loads are TargetExtType.
3002
+ if (auto *TarExtTy = dyn_cast<TargetExtType>(Ty)) {
3003
+ unsigned SEW =
3004
+ 1 << cast<ConstantInt>(Inst->getArgOperand (Inst->arg_size () - 1 ))
3005
+ ->getZExtValue ();
3006
+ Ty = TarExtTy->getTypeParameter (0U );
3007
+ Ty = ScalableVectorType::get (
3008
+ IntegerType::get (C, SEW),
3009
+ cast<ScalableVectorType>(Ty)->getMinNumElements () * 8 / SEW);
3010
+ }
2833
3011
const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo (IID);
2834
3012
unsigned VLIndex = RVVIInfo->VLOperand ;
2835
3013
unsigned PtrOperandNo = VLIndex - 2 - HasMask;
@@ -2845,6 +3023,13 @@ bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
2845
3023
Mask = ConstantInt::getTrue (MaskType);
2846
3024
}
2847
3025
Value *EVL = Inst->getArgOperand (VLIndex);
3026
+ unsigned SegNum = getSegNum (Inst, PtrOperandNo, IsWrite);
3027
+ // RVV uses contiguous elements as a segment.
3028
+ if (SegNum > 1 ) {
3029
+ unsigned ElemSize = Ty->getScalarSizeInBits ();
3030
+ auto *SegTy = IntegerType::get (C, ElemSize * SegNum);
3031
+ Ty = VectorType::get (SegTy, cast<VectorType>(Ty));
3032
+ }
2848
3033
Value *OffsetOp = Inst->getArgOperand (PtrOperandNo + 1 );
2849
3034
Info.InterestingOperands .emplace_back (Inst, PtrOperandNo, IsWrite, Ty,
2850
3035
Align (1 ), Mask, EVL,
0 commit comments