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