[llvm] [AMDGPU] Use a single SubtargetPredicate for fp8/bf8 -> f32 conversions (PR #212888)
Dmitry Sidorov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 30 03:05:47 PDT 2026
https://github.com/MrSidims updated https://github.com/llvm/llvm-project/pull/212888
>From bb9fbe56aaa3a7b0eb5d8532fca2b5e17177ce0a Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Wed, 29 Jul 2026 23:41:03 +0200
Subject: [PATCH 1/2] [AMDGPU] Use a single SubtargetPredicate for fp8/bf8 ->
f32 conversions
The fp8/bf8 to f32 conversions have three mutually exclusive encodings. gfx942
and gfx950 use VOP1 and take the source byte from the SDWA src0_sel field,
gfx11+ use VOP3 and take it from op_sel or byte_sel, and gfx125x add a clamp
bit to the VOP3 form to select the e5m3 interpretation of the source.
Each of them was gated on an ad hoc mix of SubtargetPredicate and
OtherPredicates. The gfx9 definitions were gated on HasFP8ConversionInsts
alone, which is also true on gfx11+ where they have no encoding at all, and
HasSDWA was used as a stand-in for "not gfx11+" with a FIXME saying as much.
Replace all of that with HasFP8ConversionInstsGFX9,
HasFP8ConversionInstsGFX9NoVOP1Bug, HasFP8ConversionInstsGFX11Plus,
HasFP8ConversionInstsE5M3 and HasFP8ConversionInstsGFX11PlusNoE5M3, each
covering the availability of the instructions together with the encoding, so
that every definition and pattern needs one SubtargetPredicate and no
OtherPredicates. NotHasCvtFP8VOP1Bug loses its last user and is removed.
The f32 -> fp8 direction in VOP3Instructions.td splits its predicates the same
way and is left for a follow-up.
Assisted-By: Claude Opus 5 <noreply at anthropic.com>
---
llvm/lib/Target/AMDGPU/AMDGPU.td | 37 ++++++++++++++++-
llvm/lib/Target/AMDGPU/VOP1Instructions.td | 46 +++++++++++-----------
2 files changed, 57 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index b2e0c0df00dc8..c0d78bdef46de 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -2895,6 +2895,41 @@ def NotHasMAIInsts : Predicate<"!Subtarget->hasMAIInsts()">,
def NotHasFP8E5M3Insts : Predicate<"!Subtarget->hasFP8E5M3Insts()">,
AssemblerPredicate<(all_of (not FeatureFP8E5M3Insts))>;
+// The fp8/bf8 to f32 conversions have three mutually exclusive encodings, so
+// each predicate below covers the instructions and the encoding together.
+def HasFP8ConversionInstsGFX9 :
+ Predicate<"Subtarget->hasFP8ConversionInsts() &&"
+ " Subtarget->getGeneration() == AMDGPUSubtarget::GFX9">,
+ AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGCN3Encoding,
+ FeatureGFX9Insts)>;
+
+def HasFP8ConversionInstsGFX9NoVOP1Bug :
+ Predicate<"Subtarget->hasFP8ConversionInsts() &&"
+ " Subtarget->getGeneration() == AMDGPUSubtarget::GFX9 &&"
+ " !Subtarget->hasCvtFP8VOP1Bug()">,
+ AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGCN3Encoding,
+ FeatureGFX9Insts, (not FeatureCvtFP8VOP1Bug))>;
+
+def HasFP8ConversionInstsGFX11Plus :
+ Predicate<"Subtarget->hasFP8ConversionInsts() &&"
+ " Subtarget->getGeneration() >= AMDGPUSubtarget::GFX11">,
+ AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGFX11Insts)>;
+
+def HasFP8ConversionInstsE5M3 :
+ Predicate<"Subtarget->hasFP8ConversionInsts() &&"
+ " Subtarget->hasFP8E5M3Insts() &&"
+ " Subtarget->getGeneration() == AMDGPUSubtarget::GFX12 &&"
+ " Subtarget->hasGFX1250Insts()">,
+ AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureFP8E5M3Insts,
+ FeatureGFX1250Insts, (not FeatureGFX13Insts))>;
+
+def HasFP8ConversionInstsGFX11PlusNoE5M3 :
+ Predicate<"Subtarget->hasFP8ConversionInsts() &&"
+ " Subtarget->getGeneration() >= AMDGPUSubtarget::GFX11 &&"
+ " !Subtarget->hasFP8E5M3Insts()">,
+ AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGFX11Insts,
+ (not FeatureFP8E5M3Insts))>;
+
def HasFmacLegacy32 : Predicate<"Subtarget->hasFmaLegacy32Insts() && Subtarget->getGeneration() < AMDGPUSubtarget::GFX12">,
AssemblerPredicate<(all_of FeatureFmaLegacy32Insts, (not FeatureGFX12Insts))>;
@@ -2923,8 +2958,6 @@ def HasSignedDotInsts : Predicate<"Subtarget->hasDot1Insts() || Subtarget->hasDo
def NotHasIEEEMinimumMaximumInsts : Predicate<"!Subtarget->hasIEEEMinimumMaximumInsts()">;
-def NotHasCvtFP8VOP1Bug : Predicate<"!Subtarget->hasCvtFP8VOP1Bug()">;
-
def NeedsAlignedVGPRs : Predicate<"Subtarget->needsAlignedVGPRs()">,
AssemblerPredicate<(all_of FeatureRequiresAlignedVGPRs)>;
diff --git a/llvm/lib/Target/AMDGPU/VOP1Instructions.td b/llvm/lib/Target/AMDGPU/VOP1Instructions.td
index bc00f071bc197..7220edfa1e67b 100644
--- a/llvm/lib/Target/AMDGPU/VOP1Instructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP1Instructions.td
@@ -680,7 +680,7 @@ class VOPProfile_Base_CVT_F32_F8<ValueType vt> : VOPProfileI2F <vt, i32> {
def VOPProfileCVT_F32_F8 : VOPProfile_Base_CVT_F32_F8 <f32>;
def VOPProfileCVT_PK_F32_F8 : VOPProfile_Base_CVT_F32_F8 <v2f32>;
-let OtherPredicates = [HasFP8ConversionInsts], mayRaiseFPException = 0,
+let SubtargetPredicate = HasFP8ConversionInstsGFX9, mayRaiseFPException = 0,
SchedRW = [WriteFloatCvt] in {
defm V_CVT_F32_FP8 : VOP1Inst<"v_cvt_f32_fp8", VOPProfileCVT_F32_F8>;
defm V_CVT_F32_BF8 : VOP1Inst<"v_cvt_f32_bf8", VOPProfileCVT_F32_F8>;
@@ -694,29 +694,27 @@ class Cvt_F32_F8_Pat<SDPatternOperator node, int index,
(inst_sdwa 0, $src, 0, 0, index)
>;
-let SubtargetPredicate = HasFP8ConversionInsts in {
-let OtherPredicates = [HasCvtFP8VOP1Bug] in {
+// FeatureCvtFP8VOP1Bug implies FeatureFP8ConversionInsts and is gfx9 only.
+let SubtargetPredicate = HasCvtFP8VOP1Bug in {
def : GCNPat<(f32 (int_amdgcn_cvt_f32_fp8 i32:$src, 0)),
(V_CVT_F32_FP8_sdwa 0, $src, 0, 0, 0)>;
def : GCNPat<(f32 (int_amdgcn_cvt_f32_bf8 i32:$src, 0)),
(V_CVT_F32_BF8_sdwa 0, $src, 0, 0, 0)>;
}
-let OtherPredicates = [NotHasCvtFP8VOP1Bug, HasSDWA] in { // FIXME: HasSDWA is a substitute for !gfx12
+let SubtargetPredicate = HasFP8ConversionInstsGFX9NoVOP1Bug in {
def : GCNPat<(f32 (int_amdgcn_cvt_f32_fp8 i32:$src, 0)),
(V_CVT_F32_FP8_e32 $src)>;
def : GCNPat<(f32 (int_amdgcn_cvt_f32_bf8 i32:$src, 0)),
(V_CVT_F32_BF8_e32 $src)>;
}
-let OtherPredicates = [HasSDWA] in {
+let SubtargetPredicate = HasFP8ConversionInstsGFX9 in {
foreach Index = [1, 2, 3] in {
def : Cvt_F32_F8_Pat<int_amdgcn_cvt_f32_fp8, Index, V_CVT_F32_FP8_sdwa>;
def : Cvt_F32_F8_Pat<int_amdgcn_cvt_f32_bf8, Index, V_CVT_F32_BF8_sdwa>;
}
-} // End OtherPredicates = [HasSDWA]
-
-} // End SubtargetPredicate = HasFP8ConversionInsts
+} // End SubtargetPredicate = HasFP8ConversionInstsGFX9
class Cvt_PK_F32_F8_Pat<SDPatternOperator node, int index,
VOP1_Pseudo inst_e32, VOP1_SDWA_Pseudo inst_sdwa> : GCNPat<
@@ -726,7 +724,7 @@ class Cvt_PK_F32_F8_Pat<SDPatternOperator node, int index,
(inst_e32 $src))
>;
-let SubtargetPredicate = HasFP8ConversionInsts, OtherPredicates = [HasSDWA] in {
+let SubtargetPredicate = HasFP8ConversionInstsGFX9 in {
foreach Index = [0, -1] in {
def : Cvt_PK_F32_F8_Pat<int_amdgcn_cvt_pk_f32_fp8, Index,
V_CVT_PK_F32_FP8_e32, V_CVT_PK_F32_FP8_sdwa>;
@@ -765,11 +763,11 @@ def V_CVT_F16_F8_True16_Profile : VOP3_Profile_True16<V_CVT_F16_F8_Profile>;
def V_CVT_F16_F8_Fake16_Profile : VOP3_Profile_Fake16<V_CVT_F16_F8_Profile>;
}
-let SubtargetPredicate = isGFX11Plus, OtherPredicates = [HasFP8ConversionInsts],
+let SubtargetPredicate = HasFP8ConversionInstsGFX11Plus,
mayRaiseFPException = 0, SchedRW = [WriteFloatCvt] in {
- let SubtargetPredicate = isGFX11PlusNot12_50 in
+ let SubtargetPredicate = HasFP8ConversionInstsGFX11PlusNoE5M3 in
defm V_CVT_F32_FP8_OP_SEL : VOP1Inst<"v_cvt_f32_fp8_op_sel", VOPProfile_Base_CVT_F_F8_ByteSel<f32>>;
- let SubtargetPredicate = isGFX125xOnly in
+ let SubtargetPredicate = HasFP8ConversionInstsE5M3 in
defm V_CVT_F32_FP8_gfx1250 : VOP1Inst<"v_cvt_f32_fp8_gfx1250", VOPProfile_Base_CVT_F_F8_ByteSel<f32, 1>>;
defm V_CVT_F32_BF8_OP_SEL : VOP1Inst<"v_cvt_f32_bf8_op_sel", VOPProfile_Base_CVT_F_F8_ByteSel<f32>>;
@@ -790,19 +788,19 @@ class Cvt_F_F8_Pat_ByteSel<SDPatternOperator node, VOP3_Pseudo inst, bit HasOpSe
(inst $src0, (as_i32timm $byte_sel)))
>;
-let OtherPredicates = [HasFP8ConversionInsts] in {
- let SubtargetPredicate = isGFX11PlusNot12_50 in
- def : Cvt_F_F8_Pat_ByteSel<int_amdgcn_cvt_f32_fp8, V_CVT_F32_FP8_OP_SEL_e64>;
- let SubtargetPredicate = isGFX125xOnly in {
- def : GCNPat<(int_amdgcn_cvt_f32_fp8 i32:$src0, timm:$byte_sel),
- (V_CVT_F32_FP8_gfx1250_e64 $src0, DSTCLAMP.NONE, (as_i32timm $byte_sel))>;
- def : GCNPat<(int_amdgcn_cvt_f32_fp8_e5m3 i32:$src0, timm:$byte_sel),
- (V_CVT_F32_FP8_gfx1250_e64 $src0, DSTCLAMP.ENABLE, (as_i32timm $byte_sel))>;
- }
- let SubtargetPredicate = isGFX11Plus in
- def : Cvt_F_F8_Pat_ByteSel<int_amdgcn_cvt_f32_bf8, V_CVT_F32_BF8_OP_SEL_e64>;
+let SubtargetPredicate = HasFP8ConversionInstsGFX11PlusNoE5M3 in
+ def : Cvt_F_F8_Pat_ByteSel<int_amdgcn_cvt_f32_fp8, V_CVT_F32_FP8_OP_SEL_e64>;
+
+let SubtargetPredicate = HasFP8ConversionInstsE5M3 in {
+ def : GCNPat<(int_amdgcn_cvt_f32_fp8 i32:$src0, timm:$byte_sel),
+ (V_CVT_F32_FP8_gfx1250_e64 $src0, DSTCLAMP.NONE, (as_i32timm $byte_sel))>;
+ def : GCNPat<(int_amdgcn_cvt_f32_fp8_e5m3 i32:$src0, timm:$byte_sel),
+ (V_CVT_F32_FP8_gfx1250_e64 $src0, DSTCLAMP.ENABLE, (as_i32timm $byte_sel))>;
}
+let SubtargetPredicate = HasFP8ConversionInstsGFX11Plus in
+ def : Cvt_F_F8_Pat_ByteSel<int_amdgcn_cvt_f32_bf8, V_CVT_F32_BF8_OP_SEL_e64>;
+
class Cvt_PK_F32_F8_Pat_OpSel<SDPatternOperator node, int index,
VOP1_Pseudo inst_e32, VOP3_Pseudo inst_e64> : GCNPat<
(v2f32 (node i32:$src, index)),
@@ -811,7 +809,7 @@ class Cvt_PK_F32_F8_Pat_OpSel<SDPatternOperator node, int index,
(inst_e32 $src))
>;
-let SubtargetPredicate = isGFX11Plus, OtherPredicates = [HasFP8ConversionInsts] in {
+let SubtargetPredicate = HasFP8ConversionInstsGFX11Plus in {
foreach Index = [0, -1] in {
def : Cvt_PK_F32_F8_Pat_OpSel<int_amdgcn_cvt_pk_f32_fp8, Index,
V_CVT_PK_F32_FP8_fake16_e32, V_CVT_PK_F32_FP8_fake16_e64>;
>From 78b9048974021b0b19d0632bade910fa8600395d Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Thu, 30 Jul 2026 11:44:37 +0200
Subject: [PATCH 2/2] avoid hm specs
---
llvm/lib/Target/AMDGPU/AMDGPU.td | 70 ++++++++++++----------
llvm/lib/Target/AMDGPU/VOP1Instructions.td | 27 +++++----
2 files changed, 53 insertions(+), 44 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index c0d78bdef46de..5ca7d23427f98 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -876,6 +876,22 @@ 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.
+defm CvtFP8SDWASrcSel : AMDGPUSubtargetFeature<"cvt-fp8-sdwa-src-sel",
+ "FP8/BF8 conversions to F32 take the source byte from the SDWA src0_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",
+ /*GenPredicate=*/1,
+ /*GenAssemblerPredicate=*/1,
+ [FeatureFP8ConversionInsts]
+>;
+
defm WMMA256bInsts : AMDGPUSubtargetFeature<"wmma-256b-insts",
"Has WMMA instructions where A and B matrices have duplicated data"
>;
@@ -1910,6 +1926,7 @@ def FeatureISAVersion9_5_Common : FeatureSet<
[FeatureAddressableLocalMemorySize163840,
FeatureFP8Insts,
FeatureFP8ConversionInsts,
+ FeatureCvtFP8SDWASrcSel,
FeatureGFX950Insts,
FeaturePrngInst,
FeatureBF16ConversionInsts,
@@ -1929,6 +1946,7 @@ def FeatureISAVersion9_4_2 : FeatureSet<
FeatureAddressableLocalMemorySize65536,
FeatureFP8Insts,
FeatureFP8ConversionInsts,
+ FeatureCvtFP8SDWASrcSel,
FeatureCvtFP8VOP1Bug,
FeatureXF32Insts
])>;
@@ -2119,6 +2137,7 @@ def FeatureISAVersion11_7_Common : FeatureSet<
FeatureSALUFloatInsts,
FeatureDPPSrc1SGPR,
FeatureFP8ConversionInsts,
+ FeatureCvtFP8ByteSel,
FeatureDot11Insts,
FeatureWMMA128bInsts,
FeatureSWMMACGfx1200Insts,
@@ -2159,6 +2178,7 @@ def FeatureISAVersion12 : FeatureSet<
FeatureImageInsts,
FeatureExtendedImageInsts,
FeatureFP8ConversionInsts,
+ FeatureCvtFP8ByteSel,
FeatureWMMA128bInsts,
FeatureSWMMACGfx1200Insts,
FeatureIEEEMinimumMaximumInsts,
@@ -2221,6 +2241,7 @@ def FeatureISAVersion12_50_Common : FeatureSet<
FeatureAtomicBufferPkAddBF16Inst,
FeatureFlatAtomicFaddF32Inst,
FeatureFP8ConversionInsts,
+ FeatureCvtFP8ByteSel,
FeatureFP8E5M3Insts,
FeaturePackedTID,
FeatureVcmpxPermlaneHazard,
@@ -2375,6 +2396,7 @@ def FeatureISAVersion13 : FeatureSet<
FeatureAtomicBufferPkAddBF16Inst,
FeatureFlatAtomicFaddF32Inst,
FeatureFP8ConversionInsts,
+ FeatureCvtFP8ByteSel,
FeaturePackedTID,
FeatureVcmpxPermlaneHazard,
FeatureSALUFloatInsts,
@@ -2895,39 +2917,25 @@ def NotHasMAIInsts : Predicate<"!Subtarget->hasMAIInsts()">,
def NotHasFP8E5M3Insts : Predicate<"!Subtarget->hasFP8E5M3Insts()">,
AssemblerPredicate<(all_of (not FeatureFP8E5M3Insts))>;
-// The fp8/bf8 to f32 conversions have three mutually exclusive encodings, so
-// each predicate below covers the instructions and the encoding together.
-def HasFP8ConversionInstsGFX9 :
- Predicate<"Subtarget->hasFP8ConversionInsts() &&"
- " Subtarget->getGeneration() == AMDGPUSubtarget::GFX9">,
- AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGCN3Encoding,
- FeatureGFX9Insts)>;
-
-def HasFP8ConversionInstsGFX9NoVOP1Bug :
- Predicate<"Subtarget->hasFP8ConversionInsts() &&"
- " Subtarget->getGeneration() == AMDGPUSubtarget::GFX9 &&"
+// Byte 0 of the SDWA src_sel form is reachable through the plain VOP1 encoding
+// unless that encoding is unreliable.
+def HasCvtFP8SDWASrcSelNotVOP1Bug :
+ Predicate<"Subtarget->hasCvtFP8SDWASrcSel() &&"
" !Subtarget->hasCvtFP8VOP1Bug()">,
- AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGCN3Encoding,
- FeatureGFX9Insts, (not FeatureCvtFP8VOP1Bug))>;
-
-def HasFP8ConversionInstsGFX11Plus :
- Predicate<"Subtarget->hasFP8ConversionInsts() &&"
- " Subtarget->getGeneration() >= AMDGPUSubtarget::GFX11">,
- AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGFX11Insts)>;
-
-def HasFP8ConversionInstsE5M3 :
- Predicate<"Subtarget->hasFP8ConversionInsts() &&"
- " Subtarget->hasFP8E5M3Insts() &&"
- " Subtarget->getGeneration() == AMDGPUSubtarget::GFX12 &&"
- " Subtarget->hasGFX1250Insts()">,
- AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureFP8E5M3Insts,
- FeatureGFX1250Insts, (not FeatureGFX13Insts))>;
-
-def HasFP8ConversionInstsGFX11PlusNoE5M3 :
- Predicate<"Subtarget->hasFP8ConversionInsts() &&"
- " Subtarget->getGeneration() >= AMDGPUSubtarget::GFX11 &&"
+ AssemblerPredicate<(all_of FeatureCvtFP8SDWASrcSel,
+ (not FeatureCvtFP8VOP1Bug))>;
+
+// The byte_sel form of the fp8 to f32 conversion reads the source as e5m3 when
+// the clamp bit is set, replacing the plain op_sel form.
+def HasCvtFP8ByteSelE5M3 :
+ Predicate<"Subtarget->hasCvtFP8ByteSel() &&"
+ " Subtarget->hasFP8E5M3Insts()">,
+ AssemblerPredicate<(all_of FeatureCvtFP8ByteSel, FeatureFP8E5M3Insts)>;
+
+def HasCvtFP8ByteSelNotE5M3 :
+ Predicate<"Subtarget->hasCvtFP8ByteSel() &&"
" !Subtarget->hasFP8E5M3Insts()">,
- AssemblerPredicate<(all_of FeatureFP8ConversionInsts, FeatureGFX11Insts,
+ AssemblerPredicate<(all_of FeatureCvtFP8ByteSel,
(not FeatureFP8E5M3Insts))>;
def HasFmacLegacy32 : Predicate<"Subtarget->hasFmaLegacy32Insts() && Subtarget->getGeneration() < AMDGPUSubtarget::GFX12">,
diff --git a/llvm/lib/Target/AMDGPU/VOP1Instructions.td b/llvm/lib/Target/AMDGPU/VOP1Instructions.td
index 7220edfa1e67b..feb803fb4a69f 100644
--- a/llvm/lib/Target/AMDGPU/VOP1Instructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP1Instructions.td
@@ -680,7 +680,7 @@ class VOPProfile_Base_CVT_F32_F8<ValueType vt> : VOPProfileI2F <vt, i32> {
def VOPProfileCVT_F32_F8 : VOPProfile_Base_CVT_F32_F8 <f32>;
def VOPProfileCVT_PK_F32_F8 : VOPProfile_Base_CVT_F32_F8 <v2f32>;
-let SubtargetPredicate = HasFP8ConversionInstsGFX9, mayRaiseFPException = 0,
+let SubtargetPredicate = HasCvtFP8SDWASrcSel, mayRaiseFPException = 0,
SchedRW = [WriteFloatCvt] in {
defm V_CVT_F32_FP8 : VOP1Inst<"v_cvt_f32_fp8", VOPProfileCVT_F32_F8>;
defm V_CVT_F32_BF8 : VOP1Inst<"v_cvt_f32_bf8", VOPProfileCVT_F32_F8>;
@@ -694,7 +694,8 @@ class Cvt_F32_F8_Pat<SDPatternOperator node, int index,
(inst_sdwa 0, $src, 0, 0, index)
>;
-// FeatureCvtFP8VOP1Bug implies FeatureFP8ConversionInsts and is gfx9 only.
+// Route byte 0 through the SDWA form where the VOP1 encoding is unreliable.
+// FeatureCvtFP8VOP1Bug implies FeatureFP8ConversionInsts.
let SubtargetPredicate = HasCvtFP8VOP1Bug in {
def : GCNPat<(f32 (int_amdgcn_cvt_f32_fp8 i32:$src, 0)),
(V_CVT_F32_FP8_sdwa 0, $src, 0, 0, 0)>;
@@ -702,19 +703,19 @@ let SubtargetPredicate = HasCvtFP8VOP1Bug in {
(V_CVT_F32_BF8_sdwa 0, $src, 0, 0, 0)>;
}
-let SubtargetPredicate = HasFP8ConversionInstsGFX9NoVOP1Bug in {
+let SubtargetPredicate = HasCvtFP8SDWASrcSelNotVOP1Bug in {
def : GCNPat<(f32 (int_amdgcn_cvt_f32_fp8 i32:$src, 0)),
(V_CVT_F32_FP8_e32 $src)>;
def : GCNPat<(f32 (int_amdgcn_cvt_f32_bf8 i32:$src, 0)),
(V_CVT_F32_BF8_e32 $src)>;
}
-let SubtargetPredicate = HasFP8ConversionInstsGFX9 in {
+let SubtargetPredicate = HasCvtFP8SDWASrcSel in {
foreach Index = [1, 2, 3] in {
def : Cvt_F32_F8_Pat<int_amdgcn_cvt_f32_fp8, Index, V_CVT_F32_FP8_sdwa>;
def : Cvt_F32_F8_Pat<int_amdgcn_cvt_f32_bf8, Index, V_CVT_F32_BF8_sdwa>;
}
-} // End SubtargetPredicate = HasFP8ConversionInstsGFX9
+} // End SubtargetPredicate = HasCvtFP8SDWASrcSel
class Cvt_PK_F32_F8_Pat<SDPatternOperator node, int index,
VOP1_Pseudo inst_e32, VOP1_SDWA_Pseudo inst_sdwa> : GCNPat<
@@ -724,7 +725,7 @@ class Cvt_PK_F32_F8_Pat<SDPatternOperator node, int index,
(inst_e32 $src))
>;
-let SubtargetPredicate = HasFP8ConversionInstsGFX9 in {
+let SubtargetPredicate = HasCvtFP8SDWASrcSel in {
foreach Index = [0, -1] in {
def : Cvt_PK_F32_F8_Pat<int_amdgcn_cvt_pk_f32_fp8, Index,
V_CVT_PK_F32_FP8_e32, V_CVT_PK_F32_FP8_sdwa>;
@@ -763,11 +764,11 @@ def V_CVT_F16_F8_True16_Profile : VOP3_Profile_True16<V_CVT_F16_F8_Profile>;
def V_CVT_F16_F8_Fake16_Profile : VOP3_Profile_Fake16<V_CVT_F16_F8_Profile>;
}
-let SubtargetPredicate = HasFP8ConversionInstsGFX11Plus,
+let SubtargetPredicate = HasCvtFP8ByteSel,
mayRaiseFPException = 0, SchedRW = [WriteFloatCvt] in {
- let SubtargetPredicate = HasFP8ConversionInstsGFX11PlusNoE5M3 in
+ let SubtargetPredicate = HasCvtFP8ByteSelNotE5M3 in
defm V_CVT_F32_FP8_OP_SEL : VOP1Inst<"v_cvt_f32_fp8_op_sel", VOPProfile_Base_CVT_F_F8_ByteSel<f32>>;
- let SubtargetPredicate = HasFP8ConversionInstsE5M3 in
+ let SubtargetPredicate = HasCvtFP8ByteSelE5M3 in
defm V_CVT_F32_FP8_gfx1250 : VOP1Inst<"v_cvt_f32_fp8_gfx1250", VOPProfile_Base_CVT_F_F8_ByteSel<f32, 1>>;
defm V_CVT_F32_BF8_OP_SEL : VOP1Inst<"v_cvt_f32_bf8_op_sel", VOPProfile_Base_CVT_F_F8_ByteSel<f32>>;
@@ -788,17 +789,17 @@ class Cvt_F_F8_Pat_ByteSel<SDPatternOperator node, VOP3_Pseudo inst, bit HasOpSe
(inst $src0, (as_i32timm $byte_sel)))
>;
-let SubtargetPredicate = HasFP8ConversionInstsGFX11PlusNoE5M3 in
+let SubtargetPredicate = HasCvtFP8ByteSelNotE5M3 in
def : Cvt_F_F8_Pat_ByteSel<int_amdgcn_cvt_f32_fp8, V_CVT_F32_FP8_OP_SEL_e64>;
-let SubtargetPredicate = HasFP8ConversionInstsE5M3 in {
+let SubtargetPredicate = HasCvtFP8ByteSelE5M3 in {
def : GCNPat<(int_amdgcn_cvt_f32_fp8 i32:$src0, timm:$byte_sel),
(V_CVT_F32_FP8_gfx1250_e64 $src0, DSTCLAMP.NONE, (as_i32timm $byte_sel))>;
def : GCNPat<(int_amdgcn_cvt_f32_fp8_e5m3 i32:$src0, timm:$byte_sel),
(V_CVT_F32_FP8_gfx1250_e64 $src0, DSTCLAMP.ENABLE, (as_i32timm $byte_sel))>;
}
-let SubtargetPredicate = HasFP8ConversionInstsGFX11Plus in
+let SubtargetPredicate = HasCvtFP8ByteSel in
def : Cvt_F_F8_Pat_ByteSel<int_amdgcn_cvt_f32_bf8, V_CVT_F32_BF8_OP_SEL_e64>;
class Cvt_PK_F32_F8_Pat_OpSel<SDPatternOperator node, int index,
@@ -809,7 +810,7 @@ class Cvt_PK_F32_F8_Pat_OpSel<SDPatternOperator node, int index,
(inst_e32 $src))
>;
-let SubtargetPredicate = HasFP8ConversionInstsGFX11Plus in {
+let SubtargetPredicate = HasCvtFP8ByteSel in {
foreach Index = [0, -1] in {
def : Cvt_PK_F32_F8_Pat_OpSel<int_amdgcn_cvt_pk_f32_fp8, Index,
V_CVT_PK_F32_FP8_fake16_e32, V_CVT_PK_F32_FP8_fake16_e64>;
More information about the llvm-commits
mailing list