[AMDGPU] Use SubtargetPredicates for the f32/f16 -> fp8/bf8 conversions (#213383)
The follow-up #212888 left for the other direction. HasCvtFP8SDWASrcSel and HasCvtFP8ByteSel replace isGFX940Plus and isGFX11Plus on the f32 -> fp8/bf8 conversions, which split by the same encoding characteristic, so the two feature descriptions become direction-neutral. The f16 -> fp8/bf8 conversions had no feature at all, so add FeatureF16FP8ConversionInsts, the mirror of the existing FeatureFP8F16ConversionInsts, and use it in place of isGFX1250Plus. Assisted-By: Claude Opus 5
This commit is contained in:
parent
232e8b5f45
commit
71b120f63e
3 changed files with 28 additions and 19 deletions
|
|
@ -898,6 +898,11 @@ defm FP8F16ConversionInsts : AMDGPUSubtargetFeature<"fp8-f16-conversion-insts",
|
|||
"Has fp8 and bf8 conversion to f16 instructions"
|
||||
>;
|
||||
|
||||
// The opposite direction of FP8F16ConversionInsts above.
|
||||
defm F16FP8ConversionInsts : AMDGPUSubtargetFeature<"f16-fp8-conversion-insts",
|
||||
"Has f16 conversion to fp8 and bf8 instructions"
|
||||
>;
|
||||
|
||||
defm FP8E5M3Insts : AMDGPUSubtargetFeature<"fp8e5m3-insts",
|
||||
"Has fp8 e5m3 format support"
|
||||
>;
|
||||
|
|
@ -909,17 +914,17 @@ defm CvtFP8VOP1Bug : AMDGPUSubtargetFeature<"cvt-fp8-vop1-bug",
|
|||
[FeatureFP8ConversionInsts]
|
||||
>;
|
||||
|
||||
// The fp8/bf8 to f32 conversions select which byte of the source to convert in
|
||||
// one of two ways.
|
||||
// The fp8/bf8 conversions take the byte index in one of two ways, and a
|
||||
// subtarget uses the same one in both directions.
|
||||
defm CvtFP8SDWASrcSel : AMDGPUSubtargetFeature<"cvt-fp8-sdwa-src-sel",
|
||||
"FP8/BF8 conversions to F32 take the source byte from the SDWA src0_sel field",
|
||||
"FP8/BF8 conversions take the byte index from the SDWA src0_sel or op_sel field",
|
||||
/*GenPredicate=*/1,
|
||||
/*GenAssemblerPredicate=*/1,
|
||||
[FeatureFP8ConversionInsts]
|
||||
>;
|
||||
|
||||
defm CvtFP8ByteSel : AMDGPUSubtargetFeature<"cvt-fp8-byte-sel",
|
||||
"FP8/BF8 conversions to F32 take the source byte from a byte_sel operand",
|
||||
"FP8/BF8 conversions take the byte index from a byte_sel operand",
|
||||
/*GenPredicate=*/1,
|
||||
/*GenAssemblerPredicate=*/1,
|
||||
[FeatureFP8ConversionInsts]
|
||||
|
|
@ -2297,6 +2302,7 @@ def FeatureISAVersion12_50_Common : FeatureSet<
|
|||
FeatureCvtFP8ByteSel,
|
||||
FeatureOCPFP8ConversionInsts,
|
||||
FeatureFP8F16ConversionInsts,
|
||||
FeatureF16FP8ConversionInsts,
|
||||
FeatureFP8E5M3Insts,
|
||||
FeaturePackedTID,
|
||||
FeatureVcmpxPermlaneHazard,
|
||||
|
|
@ -2455,6 +2461,7 @@ def FeatureISAVersion13 : FeatureSet<
|
|||
FeatureCvtFP8ByteSel,
|
||||
FeatureOCPFP8ConversionInsts,
|
||||
FeatureFP8F16ConversionInsts,
|
||||
FeatureF16FP8ConversionInsts,
|
||||
FeaturePackedTID,
|
||||
FeatureVcmpxPermlaneHazard,
|
||||
FeatureSALUFloatInsts,
|
||||
|
|
|
|||
|
|
@ -1228,7 +1228,7 @@ class VOP1_CVT_PK_F8_F16_Fake16_Profile<RegisterOperand RC> : VOPProfile_Fake16<
|
|||
}
|
||||
}
|
||||
|
||||
let SubtargetPredicate = isGFX1250Plus in {
|
||||
let SubtargetPredicate = HasF16FP8ConversionInsts in {
|
||||
let ReadsModeReg = 0 in {
|
||||
defm V_CVT_PK_FP8_F16 : VOP1Inst_t16_with_profiles<"v_cvt_pk_fp8_f16",
|
||||
VOP1_CVT_PK_F8_F16_Profile<VSrc_NoInline_v2f16>,
|
||||
|
|
|
|||
|
|
@ -813,19 +813,19 @@ let OtherPredicates = [HasFP8ConversionInsts], mayRaiseFPException = 0,
|
|||
VOP3_CVT_PK_F8_F32_Profile_t16<>,
|
||||
VOP3_CVT_PK_F8_F32_Profile_fake16<>>;
|
||||
|
||||
let SubtargetPredicate = isGFX11Plus in {
|
||||
let SubtargetPredicate = HasCvtFP8ByteSel in {
|
||||
let OtherPredicates = [HasFP8ConversionInsts, NotHasFP8E5M3Insts] in
|
||||
defm V_CVT_SR_FP8_F32_gfx12 : VOP3Inst<"v_cvt_sr_fp8_f32_gfx12", VOP3_CVT_SR_F8_ByteSel_Profile<f32>>;
|
||||
let OtherPredicates = [HasFP8ConversionInsts, HasFP8E5M3Insts] in
|
||||
defm V_CVT_SR_FP8_F32_gfx1250 : VOP3Inst<"v_cvt_sr_fp8_f32_gfx1250", VOP3_CVT_SR_F8_ByteSel_Profile<f32, true>>;
|
||||
defm V_CVT_SR_BF8_F32_gfx12 : VOP3Inst<"v_cvt_sr_bf8_f32_gfx12", VOP3_CVT_SR_F8_ByteSel_Profile<f32>>;
|
||||
} // End SubtargetPredicate = isGFX11Plus
|
||||
} // End SubtargetPredicate = HasCvtFP8ByteSel
|
||||
}
|
||||
|
||||
// These instructions have non-standard use of op_sel. In particular they are
|
||||
// using op_sel bits 2 and 3 while only having two sources. Therefore dummy
|
||||
// src2 is used to hold the op_sel value.
|
||||
let Constraints = "$vdst = $src2", SubtargetPredicate = isGFX940Plus in {
|
||||
let Constraints = "$vdst = $src2", SubtargetPredicate = HasCvtFP8SDWASrcSel in {
|
||||
defm V_CVT_SR_FP8_F32 : VOP3Inst<"v_cvt_sr_fp8_f32", VOP3_CVT_SR_F8_F32_Profile>;
|
||||
defm V_CVT_SR_BF8_F32 : VOP3Inst<"v_cvt_sr_bf8_f32", VOP3_CVT_SR_F8_F32_Profile>;
|
||||
}
|
||||
|
|
@ -920,14 +920,14 @@ defm : Cvt_PK_F8_F32_t16_Pat<int_amdgcn_cvt_pk_bf8_f32, V_CVT_PK_BF8_F32_t16_e64
|
|||
}
|
||||
}
|
||||
|
||||
let SubtargetPredicate = isGFX940Plus in {
|
||||
let SubtargetPredicate = HasCvtFP8SDWASrcSel in {
|
||||
foreach Index = [0, 1, 2, 3] in {
|
||||
def : Cvt_SR_F8_F32_Pat<int_amdgcn_cvt_sr_fp8_f32, Index, V_CVT_SR_FP8_F32_e64>;
|
||||
def : Cvt_SR_F8_F32_Pat<int_amdgcn_cvt_sr_bf8_f32, Index, V_CVT_SR_BF8_F32_e64>;
|
||||
}
|
||||
}
|
||||
|
||||
let SubtargetPredicate = isGFX11Plus in {
|
||||
let SubtargetPredicate = HasCvtFP8ByteSel in {
|
||||
let OtherPredicates = [HasFP8ConversionInsts, NotHasFP8E5M3Insts] in
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_fp8_f32, V_CVT_SR_FP8_F32_gfx12_e64, f32>;
|
||||
let OtherPredicates = [HasFP8ConversionInsts, HasFP8E5M3Insts] in {
|
||||
|
|
@ -935,7 +935,7 @@ let SubtargetPredicate = isGFX11Plus in {
|
|||
def : Cvt_SR_F8_ByteSel_E5M3_Pat<int_amdgcn_cvt_sr_fp8_f32_e5m3, V_CVT_SR_FP8_F32_gfx1250_e64, f32, DSTCLAMP.ENABLE>;
|
||||
}
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_bf8_f32, V_CVT_SR_BF8_F32_gfx12_e64, f32>;
|
||||
} // End SubtargetPredicate = isGFX11Plus
|
||||
} // End SubtargetPredicate = HasCvtFP8ByteSel
|
||||
}
|
||||
|
||||
class ThreeOp_i32_Pats <SDPatternOperator op1, SDPatternOperator op2, Instruction inst> : GCNPat <
|
||||
|
|
@ -1850,7 +1850,7 @@ let SubtargetPredicate = isGFX1250Plus in {
|
|||
|
||||
// These instructions have non-standard use of op_sel. They are using bits 2 and 3 of opsel
|
||||
// to select a byte in the vdst. Bits 0 and 1 are unused.
|
||||
let Constraints = "$vdst = $vdst_in" in {
|
||||
let Constraints = "$vdst = $vdst_in", SubtargetPredicate = HasF16FP8ConversionInsts in {
|
||||
defm V_CVT_SR_FP8_F16 : VOP3Inst_t16_with_profiles<"v_cvt_sr_fp8_f16", VOP3_CVT_SR_F8_F16_Profile,
|
||||
VOP3_CVT_SR_F8_F16_True16_Profile, VOP3_CVT_SR_F8_F16_Fake16_Profile>;
|
||||
defm V_CVT_SR_BF8_F16 : VOP3Inst_t16_with_profiles<"v_cvt_sr_bf8_f16", VOP3_CVT_SR_F8_F16_Profile,
|
||||
|
|
@ -1919,13 +1919,15 @@ let SubtargetPredicate = isGFX1250Plus in {
|
|||
defm V_CVT_SCALEF32_SR_PK16_FP6_F32 : VOP3Inst<"v_cvt_scalef32_sr_pk16_fp6_f32", VOP3_CVT_SCALEF32_PK_F864_Profile<VOP_V3I32_V16F32_I32_F32>, int_amdgcn_cvt_scalef32_sr_pk16_fp6_f32>;
|
||||
} // End Constraints = "@earlyclobber $vdst"
|
||||
|
||||
let True16Predicate = UseRealTrue16Insts in {
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_fp8_f16, V_CVT_SR_FP8_F16_t16_e64, f16>;
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_bf8_f16, V_CVT_SR_BF8_F16_t16_e64, f16>;
|
||||
}
|
||||
let True16Predicate = UseFakeTrue16Insts in {
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_fp8_f16, V_CVT_SR_FP8_F16_fake16_e64, f16>;
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_bf8_f16, V_CVT_SR_BF8_F16_fake16_e64, f16>;
|
||||
let SubtargetPredicate = HasF16FP8ConversionInsts in {
|
||||
let True16Predicate = UseRealTrue16Insts in {
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_fp8_f16, V_CVT_SR_FP8_F16_t16_e64, f16>;
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_bf8_f16, V_CVT_SR_BF8_F16_t16_e64, f16>;
|
||||
}
|
||||
let True16Predicate = UseFakeTrue16Insts in {
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_fp8_f16, V_CVT_SR_FP8_F16_fake16_e64, f16>;
|
||||
def : Cvt_SR_F8_ByteSel_Pat<int_amdgcn_cvt_sr_bf8_f16, V_CVT_SR_BF8_F16_fake16_e64, f16>;
|
||||
}
|
||||
}
|
||||
} // End SubtargetPredicate = isGFX1250Plus
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue