[llvm] [AMDGPU] gfx1251 VOP2 dpp support (PR #159641)
Stanislav Mekhanoshin via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 18 13:42:38 PDT 2025
https://github.com/rampitec updated https://github.com/llvm/llvm-project/pull/159641
>From dfcc9d2bd6957250dfa78260ccb62381bf5f02e0 Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin <Stanislav.Mekhanoshin at amd.com>
Date: Thu, 18 Sep 2025 12:03:33 -0700
Subject: [PATCH 1/2] [AMDGPU] gfx1251 VOP1 dpp support
---
llvm/lib/Target/AMDGPU/VOP1Instructions.td | 65 +++++---
llvm/test/CodeGen/AMDGPU/dpp64_combine.mir | 1 +
.../AMDGPU/llvm.amdgcn.mov.dpp.gfx1251.ll | 25 +++
llvm/test/MC/AMDGPU/gfx1251_asm_vop1_dpp16.s | 98 +++++++++++
llvm/test/MC/AMDGPU/gfx1251_asm_vop1_err.s | 156 ++++++++++++++++++
llvm/test/MC/AMDGPU/gfx1251_err.s | 6 +
llvm/test/MC/AMDGPU/gfx9-asm-err.s | 2 +-
.../AMDGPU/gfx1251_dasm_vop1_dpp16.txt | 49 ++++++
8 files changed, 379 insertions(+), 23 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp.gfx1251.ll
create mode 100644 llvm/test/MC/AMDGPU/gfx1251_asm_vop1_dpp16.s
create mode 100644 llvm/test/MC/AMDGPU/gfx1251_asm_vop1_err.s
create mode 100644 llvm/test/MC/AMDGPU/gfx1251_err.s
create mode 100644 llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop1_dpp16.txt
diff --git a/llvm/lib/Target/AMDGPU/VOP1Instructions.td b/llvm/lib/Target/AMDGPU/VOP1Instructions.td
index f816d7de27ee4..6230c17e20804 100644
--- a/llvm/lib/Target/AMDGPU/VOP1Instructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP1Instructions.td
@@ -212,6 +212,11 @@ def VOP_I16_F16_SPECIAL_OMOD_fake16 : VOPProfile_Fake16<VOP_I16_F16> {
}
+def VOP_F64_F64_NO_DPP : VOPProfile <[f64, f64, untyped, untyped]> {
+ let HasExtVOP3DPP = 0;
+ let HasExt64BitDPP = 0;
+}
+
//===----------------------------------------------------------------------===//
// VOP1 Instructions
//===----------------------------------------------------------------------===//
@@ -344,9 +349,9 @@ defm V_SQRT_F32 : VOP1Inst <"v_sqrt_f32", VOP_F32_F32, int_amdgcn_sqrt>;
} // End TRANS = 1, SchedRW = [WriteTrans32]
let TRANS = 1, SchedRW = [WriteTrans64] in {
-defm V_RCP_F64 : VOP1Inst <"v_rcp_f64", VOP_F64_F64, AMDGPUrcp>;
-defm V_RSQ_F64 : VOP1Inst <"v_rsq_f64", VOP_F64_F64, AMDGPUrsq>;
-defm V_SQRT_F64 : VOP1Inst <"v_sqrt_f64", VOP_F64_F64, int_amdgcn_sqrt>;
+defm V_RCP_F64 : VOP1Inst <"v_rcp_f64", VOP_F64_F64_NO_DPP, AMDGPUrcp>;
+defm V_RSQ_F64 : VOP1Inst <"v_rsq_f64", VOP_F64_F64_NO_DPP, AMDGPUrsq>;
+defm V_SQRT_F64 : VOP1Inst <"v_sqrt_f64", VOP_F64_F64_NO_DPP, int_amdgcn_sqrt>;
} // End TRANS = 1, SchedRW = [WriteTrans64]
let TRANS = 1, SchedRW = [WriteTrans32] in {
@@ -1025,6 +1030,11 @@ multiclass VOP1_Real_FULL_with_name<GFXGen Gen, bits<9> op, string opName,
multiclass VOP1_Real_NO_DPP<GFXGen Gen, bits<9> op> :
VOP1_Real_e32<Gen, op>, VOP1_Real_e64<Gen, op>;
+multiclass VOP1_Real_with_DPP16<GFXGen Gen, bits<9> op> :
+ VOP1_Real_NO_DPP<Gen, op>,
+ VOP1_Real_dpp<Gen, op>,
+ VOP3_Real_dpp_Base<Gen, {0, 1, 1, op{6-0}}>;
+
multiclass VOP1_Real_FULL_t16_gfx11_gfx12<bits<9> op, string asmName,
string opName = NAME> :
VOP1_Real_FULL_with_name<GFX11Gen, op, opName, asmName>,
@@ -1057,6 +1067,11 @@ multiclass VOP1_Real_FULL_t16_and_fake16_gfx1250<
VOP1_Real_FULL_with_name<GFX1250Gen, op, opName#"_fake16", asmName>;
}
+multiclass VOP1_Real_FULL_with_name_gfx11_gfx12_not_gfx1250<bits<9> op, string opName,
+ string asmName> :
+ VOP1_Real_FULL_with_name<GFX11Gen, op, opName, asmName>,
+ VOP1_Real_FULL_with_name<GFX12Not12_50Gen, op, opName, asmName>;
+
multiclass VOP1_Real_OpSelIsDPP_gfx1250<bits<9> op> : VOP1_Real_e32<GFX1250Gen, op> {
defvar ps = !cast<VOP_Pseudo>(NAME#"_e64");
def _e64_gfx1250 :
@@ -1064,10 +1079,10 @@ multiclass VOP1_Real_OpSelIsDPP_gfx1250<bits<9> op> : VOP1_Real_e32<GFX1250Gen,
VOP3OpSelIsDPP_gfx12<{0, 1, 1, op{6-0}}, ps.Pfl>;
}
-defm V_CVT_F32_FP8 : VOP1_Real_FULL_with_name<GFX12Not12_50Gen, 0x06c, "V_CVT_F32_FP8_OP_SEL", "v_cvt_f32_fp8">;
-defm V_CVT_F32_FP8 : VOP1_Real_FULL_with_name<GFX1250Gen, 0x06c, "V_CVT_F32_FP8_gfx1250", "v_cvt_f32_fp8">;
+defm V_CVT_F32_FP8 : VOP1_Real_FULL_with_name_gfx11_gfx12_not_gfx1250<0x06c, "V_CVT_F32_FP8_OP_SEL", "v_cvt_f32_fp8">;
+defm V_CVT_F32_FP8 : VOP1_Real_FULL_with_name<GFX1250Gen, 0x06c, "V_CVT_F32_FP8_gfx1250", "v_cvt_f32_fp8">;
-defm V_CVT_F32_BF8 : VOP1_Real_FULL_with_name<GFX12Gen, 0x06d, "V_CVT_F32_BF8_OP_SEL", "v_cvt_f32_bf8">;
+defm V_CVT_F32_BF8 : VOP1_Real_FULL_with_name<GFX12Gen, 0x06d, "V_CVT_F32_BF8_OP_SEL", "v_cvt_f32_bf8">;
defm V_CVT_PK_F32_FP8_fake16 : VOP1_Real_e32_with_name<GFX12Gen, 0x06e, "V_CVT_PK_F32_FP8_fake16", "v_cvt_pk_f32_fp8">;
defm V_CVT_PK_F32_FP8_t16 : VOP1_Real_e32_with_name<GFX12Gen, 0x06e, "V_CVT_PK_F32_FP8_t16", "v_cvt_pk_f32_fp8">;
@@ -1252,17 +1267,17 @@ let AssemblerPredicate = isGFX7Only, DecoderNamespace = "GFX7" in {
multiclass VOP1_Real_gfx7<bits<9> op> :
VOP1_Real_e32_gfx7<op>, VOP1_Real_e64_gfx7<op>;
-multiclass VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_gfx12<bits<9> op> :
+multiclass VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<bits<9> op> :
VOP1_Real_gfx7<op>, VOP1_Real_gfx10<op>, VOP1_Real_NO_DPP<GFX11Gen, op>,
- VOP1_Real_NO_DPP<GFX12Gen, op>;
+ VOP1_Real_with_DPP16<GFX12Gen, op>;
defm V_LOG_LEGACY_F32 : VOP1_Real_gfx7<0x045>;
defm V_EXP_LEGACY_F32 : VOP1_Real_gfx7<0x046>;
-defm V_TRUNC_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x017>;
-defm V_CEIL_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x018>;
-defm V_RNDNE_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x019>;
-defm V_FLOOR_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x01a>;
+defm V_TRUNC_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x017>;
+defm V_CEIL_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x018>;
+defm V_RNDNE_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x019>;
+defm V_FLOOR_F64 : VOP1_Real_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x01a>;
//===----------------------------------------------------------------------===//
// GFX6, GFX7, GFX10, GFX11, GFX12
@@ -1300,6 +1315,10 @@ multiclass VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<bits<9> op> :
VOP1_Real_gfx6_gfx7_gfx10<op>, VOP1_Real_NO_DPP<GFX11Gen, op>,
VOP1_Real_NO_DPP<GFX12Gen, op>;
+multiclass VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<bits<9> op> :
+ VOP1_Real_gfx6_gfx7_gfx10<op>, VOP1_Real_NO_DPP<GFX11Gen, op>,
+ VOP1_Real_with_DPP16<GFX12Gen, op>;
+
multiclass VOP1Only_Real_gfx6_gfx7_gfx10_gfx11_gfx12<bits<9> op> :
VOP1Only_Real_gfx6_gfx7<op>, VOP1Only_Real_gfx10_gfx11_gfx12<op>;
@@ -1314,8 +1333,8 @@ defm V_RSQ_CLAMP_F64 : VOP1_Real_gfx6_gfx7<0x032>;
defm V_NOP : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x000>;
defm V_MOV_B32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x001>;
defm V_READFIRSTLANE_B32 : VOP1Only_Real_gfx6_gfx7_gfx10_gfx11_gfx12<0x002>;
-defm V_CVT_I32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x003>;
-defm V_CVT_F64_I32 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x004>;
+defm V_CVT_I32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x003>;
+defm V_CVT_F64_I32 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x004>;
defm V_CVT_F32_I32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x005>;
defm V_CVT_F32_U32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x006>;
defm V_CVT_U32_F32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x007>;
@@ -1325,14 +1344,14 @@ defm V_CVT_F32_F16 : VOP1_Real_gfx6_gfx7_gfx10<0x00b>;
defm V_CVT_RPI_I32_F32 : VOP1_Real_gfx6_gfx7_gfx10<0x00c>;
defm V_CVT_FLR_I32_F32 : VOP1_Real_gfx6_gfx7_gfx10<0x00d>;
defm V_CVT_OFF_F32_I4 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x00e>;
-defm V_CVT_F32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x00f>;
-defm V_CVT_F64_F32 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x010>;
+defm V_CVT_F32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x00f>;
+defm V_CVT_F64_F32 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x010>;
defm V_CVT_F32_UBYTE0 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x011>;
defm V_CVT_F32_UBYTE1 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x012>;
defm V_CVT_F32_UBYTE2 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x013>;
defm V_CVT_F32_UBYTE3 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x014>;
-defm V_CVT_U32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x015>;
-defm V_CVT_F64_U32 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x016>;
+defm V_CVT_U32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x015>;
+defm V_CVT_F64_U32 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x016>;
defm V_FRACT_F32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x020>;
defm V_TRUNC_F32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x021>;
defm V_CEIL_F32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x022>;
@@ -1354,9 +1373,9 @@ defm V_BFREV_B32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x038>;
defm V_FFBH_U32 : VOP1_Real_gfx6_gfx7_gfx10<0x039>;
defm V_FFBL_B32 : VOP1_Real_gfx6_gfx7_gfx10<0x03a>;
defm V_FFBH_I32 : VOP1_Real_gfx6_gfx7_gfx10<0x03b>;
-defm V_FREXP_EXP_I32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x03c>;
-defm V_FREXP_MANT_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x03d>;
-defm V_FRACT_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_gfx12<0x03e>;
+defm V_FREXP_EXP_I32_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x03c>;
+defm V_FREXP_MANT_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x03d>;
+defm V_FRACT_F64 : VOP1_Real_gfx6_gfx7_gfx10_NO_DPP_gfx11_with_DPP16_gfx12<0x03e>;
defm V_FREXP_EXP_I32_F32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x03f>;
defm V_FREXP_MANT_F32 : VOP1_Real_gfx6_gfx7_gfx10_FULL_gfx11_gfx12<0x040>;
defm V_CLREXCP : VOP1_Real_gfx6_gfx7_gfx10<0x041>;
@@ -1410,7 +1429,9 @@ multiclass VOP1_Real_vi <bits<10> op> {
if !cast<VOP1_Pseudo>(NAME#"_e32").Pfl.HasExtDPP then
def _dpp_vi :
VOP_DPP_Real<!cast<VOP1_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.VI>,
- VOP1_DPPe<op{7-0}, !cast<VOP1_DPP_Pseudo>(NAME#"_dpp")>;
+ VOP1_DPPe<op{7-0}, !cast<VOP1_DPP_Pseudo>(NAME#"_dpp")> {
+ let AssemblerPredicate = isGFX8GFX9;
+ }
}
defm V_NOP : VOP1_Real_vi <0x0>;
diff --git a/llvm/test/CodeGen/AMDGPU/dpp64_combine.mir b/llvm/test/CodeGen/AMDGPU/dpp64_combine.mir
index 84da231c95a62..8094dbaf418b8 100644
--- a/llvm/test/CodeGen/AMDGPU/dpp64_combine.mir
+++ b/llvm/test/CodeGen/AMDGPU/dpp64_combine.mir
@@ -1,5 +1,6 @@
# RUN: llc -mtriple=amdgcn -mcpu=gfx90a -run-pass=gcn-dpp-combine -verify-machineinstrs -o - %s | FileCheck %s --check-prefix=GCN
# RUN: llc -mtriple=amdgcn -mcpu=gfx942 -run-pass=gcn-dpp-combine -verify-machineinstrs -o - %s | FileCheck %s --check-prefix=GCN
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1251 -run-pass=gcn-dpp-combine -o - %s | FileCheck %s --check-prefix=GCN
---
# GCN-LABEL: name: dpp64_old_impdef
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp.gfx1251.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp.gfx1251.ll
new file mode 100644
index 0000000000000..7a2f8faae9e89
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp.gfx1251.ll
@@ -0,0 +1,25 @@
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck -check-prefixes=GCN,GFX12 %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1250 < %s | FileCheck -check-prefixes=GCN,GFX12 %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1251 < %s | FileCheck -check-prefixes=GCN,GFX1251 %s
+
+; GCN-LABEL: {{^}}mov_dpp64_test:
+; GCN: v_mov_b32_dpp v{{[0-9]+}}, v{{[0-9]+}} quad_perm:[1,0,0,0] row_mask:0x1 bank_mask:0x1
+; GCN: v_mov_b32_dpp v{{[0-9]+}}, v{{[0-9]+}} quad_perm:[1,0,0,0] row_mask:0x1 bank_mask:0x1
+define amdgpu_kernel void @mov_dpp64_test(ptr addrspace(1) %out, i64 %in1) {
+ %tmp0 = call i64 @llvm.amdgcn.mov.dpp.i64(i64 %in1, i32 1, i32 1, i32 1, i1 0) #0
+ store i64 %tmp0, ptr addrspace(1) %out
+ ret void
+}
+
+; GCN-LABEL: {{^}}mov_dpp64_row_share_test:
+; GFX12-COUNT-2: v_mov_b32_dpp v{{[0-9]+}}, v{{[0-9]+}} row_share:1 row_mask:0x1 bank_mask:0x1
+; GFX1251: v_mov_b64_dpp v[{{[0-9:]+}}], v[{{[0-9:]+}}] row_share:1 row_mask:0x1 bank_mask:0x1
+define amdgpu_kernel void @mov_dpp64_row_share_test(ptr addrspace(1) %out, i64 %in1) {
+ %tmp0 = call i64 @llvm.amdgcn.mov.dpp.i64(i64 %in1, i32 337, i32 1, i32 1, i1 0) #0
+ store i64 %tmp0, ptr addrspace(1) %out
+ ret void
+}
+
+declare i64 @llvm.amdgcn.mov.dpp.i64(i64, i32, i32, i32, i1) #0
+
+attributes #0 = { nounwind readnone convergent }
diff --git a/llvm/test/MC/AMDGPU/gfx1251_asm_vop1_dpp16.s b/llvm/test/MC/AMDGPU/gfx1251_asm_vop1_dpp16.s
new file mode 100644
index 0000000000000..bb1ccaf53ce32
--- /dev/null
+++ b/llvm/test/MC/AMDGPU/gfx1251_asm_vop1_dpp16.s
@@ -0,0 +1,98 @@
+// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1251 -show-encoding %s | FileCheck --check-prefixes=GFX1251 %s
+// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1250-ERR --implicit-check-not=error: --strict-whitespace %s
+
+v_mov_b64 v[4:5], v[2:3] row_share:0 row_mask:0xf bank_mask:0xf
+// GFX1251: v_mov_b64_dpp v[4:5], v[2:3] row_share:0 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x3a,0x08,0x7e,0x02,0x50,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_mov_b64 v[4:5], v[2:3] row_share:0 row_mask:0xf bank_mask:0xf
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_mov_b64 v[4:5], v[2:3] row_share:15 row_mask:0x0 bank_mask:0x1
+// GFX1251: v_mov_b64_dpp v[4:5], v[2:3] row_share:15 row_mask:0x0 bank_mask:0x1 ; encoding: [0xfa,0x3a,0x08,0x7e,0x02,0x5f,0x01,0x01]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_mov_b64 v[4:5], v[2:3] row_share:15 row_mask:0x0 bank_mask:0x1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_mov_b64 v[254:255], v[254:255] row_share:3 row_mask:0x3 bank_mask:0x0 bound_ctrl:0 fi:1
+// GFX1251: v_mov_b64_dpp v[254:255], v[254:255] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1 ; encoding: [0xfa,0x3a,0xfc,0x7f,0xfe,0x53,0x05,0x30]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_mov_b64 v[254:255], v[254:255] row_share:3 row_mask:0x3 bank_mask:0x0 bound_ctrl:0 fi:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_cvt_i32_f64 v2, v[4:5] row_share:1
+// GFX1251: v_cvt_i32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x06,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_cvt_i32_f64 v2, v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_i32 v[4:5], v2 row_share:1
+// GFX1251: v_cvt_f64_i32_dpp v[4:5], v2 row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x7e,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_cvt_f64_i32 v[4:5], v2 row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_cvt_f32_f64 v2, v[4:5] row_share:1
+// GFX1251: v_cvt_f32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x1e,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_cvt_f32_f64 v2, v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_f32 v[4:5], v2 row_share:1
+// GFX1251: v_cvt_f64_f32_dpp v[4:5], v2 row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x20,0x08,0x7e,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_cvt_f64_f32 v[4:5], v2 row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_cvt_u32_f64 v2, v[4:5] row_share:1
+// GFX1251: v_cvt_u32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x2a,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_cvt_u32_f64 v2, v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_u32 v[4:5], v2 row_share:1
+// GFX1251: v_cvt_f64_u32_dpp v[4:5], v2 row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x2c,0x08,0x7e,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_cvt_f64_u32 v[4:5], v2 row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_trunc_f64 v[2:3], v[4:5] row_share:1
+// GFX1251: v_trunc_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x2e,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_trunc_f64 v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_ceil_f64 v[2:3], v[4:5] row_share:1
+// GFX1251: v_ceil_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x30,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_ceil_f64 v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_rndne_f64 v[2:3], v[4:5] row_share:1
+// GFX1251: v_rndne_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x32,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_rndne_f64 v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_floor_f64 v[2:3], v[4:5] row_share:1
+// GFX1251: v_floor_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x34,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_floor_f64 v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_frexp_exp_i32_f64 v2, v[4:5] row_share:1
+// GFX1251: v_frexp_exp_i32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x78,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_frexp_exp_i32_f64 v2, v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_frexp_mant_f64 v[2:3], v[4:5] row_share:1
+// GFX1251: v_frexp_mant_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x7a,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_frexp_mant_f64 v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_fract_f64 v[2:3], v[4:5] row_share:1
+// GFX1251: v_fract_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x7c,0x04,0x7e,0x04,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_fract_f64 v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
diff --git a/llvm/test/MC/AMDGPU/gfx1251_asm_vop1_err.s b/llvm/test/MC/AMDGPU/gfx1251_asm_vop1_err.s
new file mode 100644
index 0000000000000..1d88e9cb59c8e
--- /dev/null
+++ b/llvm/test/MC/AMDGPU/gfx1251_asm_vop1_err.s
@@ -0,0 +1,156 @@
+// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1251 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1251-ERR --implicit-check-not=error: --strict-whitespace %s
+
+v_mov_b64 v[4:5], v[2:3] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_mov_b64 v[4:5], v[2:3] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_i32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_cvt_i32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_i32 v[4:5], v2 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f64_i32 v[4:5], v2 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_f32 v[4:5], v2 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f64_f32 v[4:5], v2 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_u32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_cvt_u32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_u32 v[4:5], v2 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f64_u32 v[4:5], v2 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_trunc_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_trunc_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_ceil_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_ceil_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_rndne_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_rndne_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_floor_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_floor_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_frexp_exp_i32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_frexp_exp_i32_f64 v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_frexp_mant_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_frexp_mant_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fract_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_fract_f64 v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_mov_b64 v[4:5], v[2:3] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_mov_b64 v[4:5], v[2:3] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_i32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_cvt_i32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_i32 v[4:5], v2 quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f64_i32 v[4:5], v2 quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_f32 v[4:5], v2 quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f64_f32 v[4:5], v2 quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_u32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_cvt_u32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_cvt_f64_u32 v[4:5], v2 quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_cvt_f64_u32 v[4:5], v2 quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_trunc_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_trunc_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_ceil_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_ceil_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_rndne_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_rndne_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_floor_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_floor_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_frexp_exp_i32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_frexp_exp_i32_f64 v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_frexp_mant_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_frexp_mant_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fract_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_fract_f64 v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_rcp_f64 v[4:5], v[2:3] row_share:1
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_rcp_f64 v[4:5], v[2:3] row_share:1
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_rsq_f64 v[4:5], v[2:3] row_share:1
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_rsq_f64 v[4:5], v[2:3] row_share:1
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_sqrt_f64 v[4:5], v[2:3] row_share:1
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_sqrt_f64 v[4:5], v[2:3] row_share:1
+// GFX1251-ERR-NEXT:{{^}} ^
diff --git a/llvm/test/MC/AMDGPU/gfx1251_err.s b/llvm/test/MC/AMDGPU/gfx1251_err.s
new file mode 100644
index 0000000000000..d4db1bf9bb780
--- /dev/null
+++ b/llvm/test/MC/AMDGPU/gfx1251_err.s
@@ -0,0 +1,6 @@
+// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1251 -show-encoding %s 2>&1 | FileCheck --check-prefixes=GFX1251-ERR --implicit-check-not=error: -strict-whitespace %s
+
+v_mov_b64 v[4:5], v[2:3] quad_perm:[1,1,1,1]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR: v_mov_b64 v[4:5], v[2:3] quad_perm:[1,1,1,1]
+// GFX1251-ERR: ^
diff --git a/llvm/test/MC/AMDGPU/gfx9-asm-err.s b/llvm/test/MC/AMDGPU/gfx9-asm-err.s
index 31e0d953b5bd8..eb1d7b0b90772 100644
--- a/llvm/test/MC/AMDGPU/gfx9-asm-err.s
+++ b/llvm/test/MC/AMDGPU/gfx9-asm-err.s
@@ -31,7 +31,7 @@ v_subrev_u16_e64 v5, v1, -4.2
// GFX9ERR: :[[@LINE-1]]:{{[0-9]+}}: error: literal operands are not supported
v_cvt_u32_f64 v5, v[0:1] quad_perm:[0,2,1,1] row_mask:0xf bank_mask:0xf
-// GFX9ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX9ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
global_load_lds_dword v[2:3], off
// GFX9ERR: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU
diff --git a/llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop1_dpp16.txt b/llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop1_dpp16.txt
new file mode 100644
index 0000000000000..3380b77a27a5d
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop1_dpp16.txt
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple=amdgcn -mcpu=gfx1251 -disassemble -show-encoding < %s | FileCheck -check-prefix=GFX1251 %s
+
+# GFX1251: v_mov_b64_dpp v[254:255], v[254:255] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1 ; encoding: [0xfa,0x3a,0xfc,0x7f,0xfe,0x53,0x05,0x30]
+0xfa,0x3a,0xfc,0x7f,0xfe,0x53,0x05,0x30
+
+# GFX1251: v_mov_b64_dpp v[4:5], v[2:3] row_share:0 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x3a,0x08,0x7e,0x02,0x50,0x01,0xff]
+0xfa,0x3a,0x08,0x7e,0x02,0x50,0x01,0xff
+
+# GFX1251: v_mov_b64_dpp v[4:5], v[2:3] row_share:15 row_mask:0x0 bank_mask:0x1 ; encoding: [0xfa,0x3a,0x08,0x7e,0x02,0x5f,0x01,0x01]
+0xfa,0x3a,0x08,0x7e,0x02,0x5f,0x01,0x01
+
+# GFX1251: v_ceil_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x30,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x30,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_cvt_f32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x1e,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x1e,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_cvt_f64_f32_dpp v[4:5], v2 row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x20,0x08,0x7e,0x02,0x51,0x01,0xff]
+0xfa,0x20,0x08,0x7e,0x02,0x51,0x01,0xff
+
+# GFX1251: v_cvt_f64_i32_dpp v[4:5], v2 row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x7e,0x02,0x51,0x01,0xff]
+0xfa,0x08,0x08,0x7e,0x02,0x51,0x01,0xff
+
+# GFX1251: v_cvt_f64_u32_dpp v[4:5], v2 row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x2c,0x08,0x7e,0x02,0x51,0x01,0xff]
+0xfa,0x2c,0x08,0x7e,0x02,0x51,0x01,0xff
+
+# GFX1251: v_cvt_i32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x06,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x06,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_cvt_u32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x2a,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x2a,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_floor_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x34,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x34,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_fract_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x7c,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x7c,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_frexp_exp_i32_f64_dpp v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x78,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x78,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_frexp_mant_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x7a,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x7a,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_rndne_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x32,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x32,0x04,0x7e,0x04,0x51,0x01,0xff
+
+# GFX1251: v_trunc_f64_dpp v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x2e,0x04,0x7e,0x04,0x51,0x01,0xff]
+0xfa,0x2e,0x04,0x7e,0x04,0x51,0x01,0xff
>From 344bfe15f023e965348da4d92738b48683768887 Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin <Stanislav.Mekhanoshin at amd.com>
Date: Thu, 18 Sep 2025 12:58:41 -0700
Subject: [PATCH 2/2] [AMDGPU] gfx1251 VOP2 dpp support
---
llvm/lib/Target/AMDGPU/VOP2Instructions.td | 79 +++++++------
llvm/test/CodeGen/AMDGPU/dpp_combine.ll | 6 +-
llvm/test/MC/AMDGPU/gfx1251_asm_vop2_dpp16.s | 74 ++++++++++++
llvm/test/MC/AMDGPU/gfx1251_asm_vop2_err.s | 106 ++++++++++++++++++
.../AMDGPU/gfx1251_dasm_vop2_dpp16.txt | 37 ++++++
5 files changed, 267 insertions(+), 35 deletions(-)
create mode 100644 llvm/test/MC/AMDGPU/gfx1251_asm_vop2_dpp16.s
create mode 100644 llvm/test/MC/AMDGPU/gfx1251_asm_vop2_err.s
create mode 100644 llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop2_dpp16.txt
diff --git a/llvm/lib/Target/AMDGPU/VOP2Instructions.td b/llvm/lib/Target/AMDGPU/VOP2Instructions.td
index 46a1a4bf1ab4a..37d92bc5076de 100644
--- a/llvm/lib/Target/AMDGPU/VOP2Instructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP2Instructions.td
@@ -287,10 +287,14 @@ multiclass VOP2bInst <string opName,
def _e64 : VOP3InstBase <opName, P, node, 1>,
Commutable_REV<revOp#"_e64", !eq(revOp, opName)>;
- let SubtargetPredicate = isGFX11Plus in {
- if P.HasExtVOP3DPP then
- def _e64_dpp : VOP3_DPP_Pseudo <opName, P>;
- } // End SubtargetPredicate = isGFX11Plus
+ if P.HasExtVOP3DPP then
+ def _e64_dpp : VOP3_DPP_Pseudo <opName, P> {
+ let SubtargetPredicate = isGFX11Plus;
+ }
+ else if P.HasExt64BitDPP then
+ def _e64_dpp : VOP3_DPP_Pseudo <opName, P> {
+ let OtherPredicates = [HasDPALU_DPP];
+ }
}
}
@@ -345,10 +349,14 @@ multiclass
VOPD_Component<VOPDOp, VOPDName>;
}
- let SubtargetPredicate = isGFX11Plus in {
- if P.HasExtVOP3DPP then
- def _e64_dpp : VOP3_DPP_Pseudo <opName, P>;
- } // End SubtargetPredicate = isGFX11Plus
+ if P.HasExtVOP3DPP then
+ def _e64_dpp : VOP3_DPP_Pseudo <opName, P> {
+ let SubtargetPredicate = isGFX11Plus;
+ }
+ else if P.HasExt64BitDPP then
+ def _e64_dpp : VOP3_DPP_Pseudo <opName, P> {
+ let OtherPredicates = [HasDPALU_DPP];
+ }
}
}
@@ -1607,8 +1615,9 @@ multiclass VOP2_Real_dpp<GFXGen Gen, bits<6> op> {
}
multiclass VOP2_Real_dpp8<GFXGen Gen, bits<6> op> {
- if !cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP then
- def _dpp8#Gen.Suffix : VOP2_DPP8_Gen<op, !cast<VOP2_Pseudo>(NAME#"_e32"), Gen>;
+ defvar ps = !cast<VOP2_Pseudo>(NAME#"_e32");
+ if !and(ps.Pfl.HasExtDPP, !not(ps.Pfl.HasExt64BitDPP)) then
+ def _dpp8#Gen.Suffix : VOP2_DPP8_Gen<op, ps, Gen>;
}
//===------------------------- VOP2 (with name) -------------------------===//
@@ -1643,10 +1652,10 @@ multiclass VOP2_Real_dpp_with_name<GFXGen Gen, bits<6> op, string opName,
multiclass VOP2_Real_dpp8_with_name<GFXGen Gen, bits<6> op, string opName,
string asmName> {
defvar ps = !cast<VOP2_Pseudo>(opName#"_e32");
- if ps.Pfl.HasExtDPP then
- def _dpp8#Gen.Suffix : VOP2_DPP8_Gen<op, ps, Gen> {
- let AsmString = asmName # ps.Pfl.AsmDPP8;
- }
+ if !and(ps.Pfl.HasExtDPP, !not(ps.Pfl.HasExt64BitDPP)) then
+ def _dpp8#Gen.Suffix : VOP2_DPP8_Gen<op, ps, Gen> {
+ let AsmString = asmName # ps.Pfl.AsmDPP8;
+ }
}
//===------------------------------ VOP2be ------------------------------===//
@@ -1687,32 +1696,32 @@ multiclass VOP2be_Real_dpp<GFXGen Gen, bits<6> op, string opName, string asmName
}
}
multiclass VOP2be_Real_dpp8<GFXGen Gen, bits<6> op, string opName, string asmName> {
- if !cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP then
+ defvar ps = !cast<VOP2_Pseudo>(opName#"_e32");
+ if !and(ps.Pfl.HasExtDPP, !not(ps.Pfl.HasExt64BitDPP)) then {
def _dpp8#Gen.Suffix :
- VOP2_DPP8_Gen<op, !cast<VOP2_Pseudo>(opName#"_e32"), Gen> {
- string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
+ VOP2_DPP8_Gen<op, ps, Gen> {
+ string AsmDPP8 = ps.Pfl.AsmDPP8;
let AsmString = asmName # !subst(", vcc", "", AsmDPP8);
}
- if !cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP then
def _dpp8_w32#Gen.Suffix :
- VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
- string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
+ VOP2_DPP8<op, ps> {
+ string AsmDPP8 = ps.Pfl.AsmDPP8;
let AsmString = asmName # !subst("vcc", "vcc_lo", AsmDPP8);
let isAsmParserOnly = 1;
let WaveSizePredicate = isWave32;
let AssemblerPredicate = Gen.AssemblerPredicate;
let DecoderNamespace = Gen.DecoderNamespace;
}
- if !cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP then
def _dpp8_w64#Gen.Suffix :
- VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
- string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
+ VOP2_DPP8<op, ps> {
+ string AsmDPP8 = ps.Pfl.AsmDPP8;
let AsmString = asmName # AsmDPP8;
let isAsmParserOnly = 1;
let WaveSizePredicate = isWave64;
let AssemblerPredicate = Gen.AssemblerPredicate;
let DecoderNamespace = Gen.DecoderNamespace;
}
+ }
}
// We don't want to override separate decoderNamespaces within these
@@ -1777,9 +1786,11 @@ multiclass VOP2_Real_NO_DPP_with_name<GFXGen Gen, bits<6> op, string opName,
}
}
-multiclass VOP2_Real_NO_DPP_with_alias<GFXGen Gen, bits<6> op, string alias> {
+multiclass VOP2_Real_with_DPP16_with_alias<GFXGen Gen, bits<6> op, string alias> {
defm NAME : VOP2_Real_e32<Gen, op>,
- VOP2_Real_e64<Gen, op>;
+ VOP2_Real_dpp<Gen, op>,
+ VOP2_Real_e64<Gen, op>,
+ VOP3_Real_dpp_Base<Gen, {0, 1, 0, 0, op{5-0}}>;
def Gen.Suffix#"_alias" : AMDGPUMnemonicAlias<alias, NAME> {
let AssemblerPredicate = Gen.AssemblerPredicate;
}
@@ -1808,6 +1819,9 @@ multiclass VOP2_Real_FULL_t16_gfx12<bits<6> op, string opName,
}
}
+multiclass VOP2_Real_with_DPP16_with_alias_gfx12<bits<6> op, string alias> :
+ VOP2_Real_with_DPP16_with_alias<GFX12Gen, op, alias>;
+
multiclass VOP2_Real_FULL_t16_and_fake16_gfx12<bits<6> op, string opName,
string asmName, string alias> {
defm _t16: VOP2_Real_FULL_t16_gfx12<op, opName#"_t16", asmName, alias>;
@@ -1818,14 +1832,11 @@ multiclass VOP2_Real_NO_DPP_with_name_gfx12<bits<6> op, string opName,
string asmName> :
VOP2_Real_NO_DPP_with_name<GFX12Gen, op, opName, asmName>;
-multiclass VOP2_Real_NO_DPP_with_alias_gfx12<bits<6> op, string alias> :
- VOP2_Real_NO_DPP_with_alias<GFX12Gen, op, alias>;
-
-defm V_ADD_F64 : VOP2_Real_NO_DPP_with_name_gfx12<0x002, "V_ADD_F64_pseudo", "v_add_f64">;
-defm V_MUL_F64 : VOP2_Real_NO_DPP_with_name_gfx12<0x006, "V_MUL_F64_pseudo", "v_mul_f64">;
-defm V_LSHLREV_B64 : VOP2_Real_NO_DPP_with_name_gfx12<0x01f, "V_LSHLREV_B64_pseudo", "v_lshlrev_b64">;
-defm V_MIN_NUM_F64 : VOP2_Real_NO_DPP_with_alias_gfx12<0x00d, "v_min_f64">;
-defm V_MAX_NUM_F64 : VOP2_Real_NO_DPP_with_alias_gfx12<0x00e, "v_max_f64">;
+defm V_ADD_F64 : VOP2_Real_FULL_with_name_gfx12<0x002, "V_ADD_F64_pseudo", "v_add_f64">;
+defm V_MUL_F64 : VOP2_Real_FULL_with_name_gfx12<0x006, "V_MUL_F64_pseudo", "v_mul_f64">;
+defm V_LSHLREV_B64 : VOP2_Real_FULL_with_name_gfx12<0x01f, "V_LSHLREV_B64_pseudo", "v_lshlrev_b64">;
+defm V_MIN_NUM_F64 : VOP2_Real_with_DPP16_with_alias_gfx12<0x00d, "v_min_f64">;
+defm V_MAX_NUM_F64 : VOP2_Real_with_DPP16_with_alias_gfx12<0x00e, "v_max_f64">;
defm V_CNDMASK_B32 : VOP2e_Real_gfx12<0x001, "V_CNDMASK_B32", "v_cndmask_b32">;
defm V_ADD_CO_CI_U32 :
@@ -2776,7 +2787,7 @@ let DecoderNamespace = "GFX90A" in {
}
} // End AssemblerPredicate = isGFX90APlus, DecoderNamespace = "GFX90A"
-let SubtargetPredicate = HasFmacF64Inst in {
+let SubtargetPredicate = HasFmacF64Inst, OtherPredicates = [isGFX9Only] in {
defm V_FMAC_F64 : VOP2_Real_e32e64_gfx90a <0x4>;
} // End SubtargetPredicate = HasFmacF64Inst
diff --git a/llvm/test/CodeGen/AMDGPU/dpp_combine.ll b/llvm/test/CodeGen/AMDGPU/dpp_combine.ll
index 539485d19a2b9..a3251bdfafebf 100644
--- a/llvm/test/CodeGen/AMDGPU/dpp_combine.ll
+++ b/llvm/test/CodeGen/AMDGPU/dpp_combine.ll
@@ -4,6 +4,8 @@
; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=-real-true16 < %s | FileCheck %s -check-prefixes=GCN,GFX11-FAKE16
; RUN: llc -mtriple=amdgcn -mcpu=gfx1150 -mattr=+real-true16 < %s | FileCheck %s -check-prefixes=GCN,GFX11-TRUE16
; RUN: llc -mtriple=amdgcn -mcpu=gfx1150 -mattr=-real-true16 < %s | FileCheck %s -check-prefixes=GCN,GFX11-FAKE16
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1251 -mattr=+real-true16 < %s | FileCheck %s -check-prefixes=GCN,GFX11-TRUE16
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1251 -mattr=-real-true16 < %s | FileCheck %s -check-prefixes=GCN,GFX11-FAKE16
; GCN-LABEL: {{^}}dpp_add:
; GCN: global_load_{{dword|b32}} [[V:v[0-9]+]],
@@ -49,7 +51,9 @@ define amdgpu_kernel void @dpp_fadd(ptr addrspace(1) %arg) {
ret void
}
-; Fails to combine because v_mul_lo_u32 has no e32 or dpp form.
+; Fails to combine prior to gfx1251 because v_mul_lo_u32 has no e32 or dpp form.
+; Fails to combine on gfx1251 because DPP control value is invalid for DP DPP and v_mul_lo_u32 is
+; classified as DP DPP.
; GCN-LABEL: {{^}}dpp_mul:
; GCN: global_load_{{dword|b32}} [[V:v[0-9]+]],
; GCN: v_mov_b32_e32 [[V2:v[0-9]+]], [[V]]
diff --git a/llvm/test/MC/AMDGPU/gfx1251_asm_vop2_dpp16.s b/llvm/test/MC/AMDGPU/gfx1251_asm_vop2_dpp16.s
new file mode 100644
index 0000000000000..38bbc69fb3a72
--- /dev/null
+++ b/llvm/test/MC/AMDGPU/gfx1251_asm_vop2_dpp16.s
@@ -0,0 +1,74 @@
+// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1251 -show-encoding < %s | FileCheck --check-prefix=GFX1251 %s
+// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1250-ERR --implicit-check-not=error: --strict-whitespace %s
+
+v_add_nc_u64 v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1
+// GFX1251: v_add_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1 ; encoding: [0xfa,0x08,0x08,0x50,0x02,0x53,0x05,0x30]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_add_nc_u64 v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_add_nc_u64 v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf
+// GFX1251: v_add_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x50,0x02,0x50,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_add_nc_u64 v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_add_nc_u64 v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1
+// GFX1251: v_add_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1 ; encoding: [0xfa,0x08,0x08,0x50,0x02,0x5f,0x01,0x01]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_add_nc_u64 v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_sub_nc_u64 v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1
+// GFX1251: v_sub_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1 ; encoding: [0xfa,0x08,0x08,0x52,0x02,0x53,0x05,0x30]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_sub_nc_u64 v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_sub_nc_u64 v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf
+// GFX1251: v_sub_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x52,0x02,0x50,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_sub_nc_u64 v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_sub_nc_u64 v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1
+// GFX1251: v_sub_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1 ; encoding: [0xfa,0x08,0x08,0x52,0x02,0x5f,0x01,0x01]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_sub_nc_u64 v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_fmac_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1251: v_fmac_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x2e,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_fmac_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_add_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1251: v_add_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x04,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_add_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_mul_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1251: v_mul_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x0c,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_mul_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_max_num_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1251: v_max_num_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x1c,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_max_num_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_min_num_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1251: v_min_num_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x1a,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_min_num_f64 v[4:5], v[2:3], v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
+
+v_lshlrev_b64 v[4:5], v2, v[4:5] row_share:1
+// GFX1251: v_lshlrev_b64_dpp v[4:5], v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x3e,0x02,0x51,0x01,0xff]
+// GFX1250-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1250-ERR-NEXT:{{^}}v_lshlrev_b64 v[4:5], v2, v[4:5] row_share:1
+// GFX1250-ERR-NEXT:{{^}} ^
diff --git a/llvm/test/MC/AMDGPU/gfx1251_asm_vop2_err.s b/llvm/test/MC/AMDGPU/gfx1251_asm_vop2_err.s
new file mode 100644
index 0000000000000..99d781d1e0fa1
--- /dev/null
+++ b/llvm/test/MC/AMDGPU/gfx1251_asm_vop2_err.s
@@ -0,0 +1,106 @@
+// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1251 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1251-ERR --implicit-check-not=error: --strict-whitespace %s
+
+v_add_nc_u64 v[2:3], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_add_nc_u64 v[2:3], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_sub_nc_u64 v[2:3], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_sub_nc_u64 v[2:3], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fmac_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_fmac_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_add_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_add_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_mul_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_mul_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_max_num_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_max_num_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_min_num_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_min_num_f64 v[4:5], v[2:3], v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_lshlrev_b64 v[4:5], v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_lshlrev_b64 v[4:5], v2, v[4:5] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fmamk_f64 v[4:5], v[2:3], 123.0, v[6:7] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_fmamk_f64 v[4:5], v[2:3], 123.0, v[6:7] dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fmaak_f64 v[4:5], v[2:3], v[6:7], 123.0 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_fmaak_f64 v[4:5], v[2:3], v[6:7], 123.0 dpp8:[7,6,5,4,3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_add_nc_u64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_add_nc_u64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_sub_nc_u64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_sub_nc_u64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fmac_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_fmac_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_add_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_add_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_mul_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_mul_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_max_num_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_max_num_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_min_num_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_min_num_f64 v[4:5], v[2:3], v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_lshlrev_b64 v[4:5], v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: DP ALU dpp only supports row_share
+// GFX1251-ERR-NEXT:{{^}}v_lshlrev_b64 v[4:5], v2, v[4:5] quad_perm:[3,2,1,0]
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_mul_u64 v[2:3], v[4:5], v[6:7] row_share:1
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_mul_u64 v[2:3], v[4:5], v[6:7] row_share:1
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fmamk_f64 v[4:5], v[2:3], 123.0, v[6:7] row_share:1
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_fmamk_f64 v[4:5], v[2:3], 123.0, v[6:7] row_share:1
+// GFX1251-ERR-NEXT:{{^}} ^
+
+v_fmaak_f64 v[4:5], v[2:3], v[6:7], 123.0 row_share:1
+// GFX1251-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand.
+// GFX1251-ERR-NEXT:{{^}}v_fmaak_f64 v[4:5], v[2:3], v[6:7], 123.0 row_share:1
+// GFX1251-ERR-NEXT:{{^}} ^
diff --git a/llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop2_dpp16.txt b/llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop2_dpp16.txt
new file mode 100644
index 0000000000000..a92b81b9bb486
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop2_dpp16.txt
@@ -0,0 +1,37 @@
+# RUN: llvm-mc -triple=amdgcn -mcpu=gfx1251 -disassemble -show-encoding < %s | FileCheck -check-prefixes=GFX1251 %s
+
+# GFX1251: v_add_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x50,0x02,0x50,0x01,0xff]
+0xfa,0x08,0x08,0x50,0x02,0x50,0x01,0xff
+
+# GFX1251: v_add_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1 ; encoding: [0xfa,0x08,0x08,0x50,0x02,0x5f,0x01,0x01]
+0xfa,0x08,0x08,0x50,0x02,0x5f,0x01,0x01
+
+# GFX1251: v_add_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1 ; encoding: [0xfa,0x08,0x08,0x50,0x02,0x53,0x05,0x30]
+0xfa,0x08,0x08,0x50,0x02,0x53,0x05,0x30
+
+# GFX1251: v_sub_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:0 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x52,0x02,0x50,0x01,0xff]
+0xfa,0x08,0x08,0x52,0x02,0x50,0x01,0xff
+
+# GFX1251: v_sub_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:15 row_mask:0x0 bank_mask:0x1 ; encoding: [0xfa,0x08,0x08,0x52,0x02,0x5f,0x01,0x01]
+0xfa,0x08,0x08,0x52,0x02,0x5f,0x01,0x01
+
+# GFX1251: v_sub_nc_u64_dpp v[4:5], v[2:3], v[4:5] row_share:3 row_mask:0x3 bank_mask:0x0 fi:1 ; encoding: [0xfa,0x08,0x08,0x52,0x02,0x53,0x05,0x30]
+0xfa,0x08,0x08,0x52,0x02,0x53,0x05,0x30
+
+# GFX1251: v_add_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x04,0x02,0x51,0x01,0xff]
+0xfa,0x08,0x08,0x04,0x02,0x51,0x01,0xff
+
+# GFX1251: v_fmac_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x2e,0x02,0x51,0x01,0xff]
+0xfa,0x08,0x08,0x2e,0x02,0x51,0x01,0xff
+
+# GFX1251: v_lshlrev_b64_dpp v[4:5], v2, v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x3e,0x02,0x51,0x01,0xff]
+0xfa,0x08,0x08,0x3e,0x02,0x51,0x01,0xff
+
+# GFX1251: v_max_num_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x1c,0x02,0x51,0x01,0xff]
+0xfa,0x08,0x08,0x1c,0x02,0x51,0x01,0xff
+
+# GFX1251: v_min_num_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x1a,0x02,0x51,0x01,0xff]
+0xfa,0x08,0x08,0x1a,0x02,0x51,0x01,0xff
+
+# GFX1251: v_mul_f64_dpp v[4:5], v[2:3], v[4:5] row_share:1 row_mask:0xf bank_mask:0xf ; encoding: [0xfa,0x08,0x08,0x0c,0x02,0x51,0x01,0xff]
+0xfa,0x08,0x08,0x0c,0x02,0x51,0x01,0xff
More information about the llvm-commits
mailing list