[llvm] [AMDGPU] Add VINTERP encoding to gfx13 (PR #182481)

Mariusz Sikora via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 2 00:46:25 PST 2026


https://github.com/mariusz-sikora-at-amd updated https://github.com/llvm/llvm-project/pull/182481

>From 18c0aae62eee791176925914e3b06d9b0246340c Mon Sep 17 00:00:00 2001
From: Mariusz Sikora <mariusz.sikora at amd.com>
Date: Fri, 20 Feb 2026 06:42:44 -0500
Subject: [PATCH] [AMDGPU] Add VINTERP encoding to gfx13

---
 llvm/lib/Target/AMDGPU/AMDGPU.td              |  2 +-
 .../Disassembler/AMDGPUDisassembler.cpp       | 10 +++-
 llvm/lib/Target/AMDGPU/VINTERPInstructions.td | 47 +++++++++----------
 llvm/test/MC/AMDGPU/vinterp-fake16.s          |  1 +
 llvm/test/MC/Disassembler/AMDGPU/vinterp.txt  |  2 +
 5 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index cc175423972b9..eb2d45dbfd814 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -2498,7 +2498,7 @@ def HasExportInsts : Predicate<"Subtarget->hasExportInsts()">,
   AssemblerPredicate<(any_of FeatureGFX13Insts, (all_of (not FeatureGFX90AInsts), (not FeatureGFX1250Insts)))>;
 
 def HasVINTERPEncoding : Predicate<"Subtarget->hasVINTERPEncoding()">,
-  AssemblerPredicate<(all_of FeatureGFX11Insts, (not FeatureGFX1250Insts))>;
+  AssemblerPredicate<(any_of FeatureGFX13Insts, (all_of FeatureGFX11Insts, (not FeatureGFX1250Insts)))>;
 
 def HasDSAddTid : Predicate<"Subtarget->getGeneration() >= AMDGPUSubtarget::GFX9">,
   AssemblerPredicate<(all_of FeatureGFX9Insts)>;
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 2309a56f612f1..ba2f6ead29e2a 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -955,18 +955,26 @@ void AMDGPUDisassembler::convertVINTERPInst(MCInst &MI) const {
       MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_fake16_gfx11 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_t16_gfx12 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_fake16_gfx12 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_t16_gfx13 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P10_F16_F32_inreg_fake16_gfx13 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_t16_gfx11 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_fake16_gfx11 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_t16_gfx12 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_fake16_gfx12 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_t16_gfx13 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P10_RTZ_F16_F32_inreg_fake16_gfx13 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_t16_gfx11 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_fake16_gfx11 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_t16_gfx12 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_fake16_gfx12 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_t16_gfx13 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P2_F16_F32_inreg_fake16_gfx13 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_t16_gfx11 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_fake16_gfx11 ||
       MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_t16_gfx12 ||
-      MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_fake16_gfx12) {
+      MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_fake16_gfx12 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_t16_gfx13 ||
+      MI.getOpcode() == AMDGPU::V_INTERP_P2_RTZ_F16_F32_inreg_fake16_gfx13) {
     // The MCInst has this field that is not directly encoded in the
     // instruction.
     insertNamedMCOperand(MI, MCOperand::createImm(0), AMDGPU::OpName::op_sel);
diff --git a/llvm/lib/Target/AMDGPU/VINTERPInstructions.td b/llvm/lib/Target/AMDGPU/VINTERPInstructions.td
index 75437cf527f0a..2030cf1ee76a7 100644
--- a/llvm/lib/Target/AMDGPU/VINTERPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/VINTERPInstructions.td
@@ -44,7 +44,7 @@ class VINTERPe_gfx11 <bits<7> op> : VINTERPe {
   let Inst{22-16} = op;
 }
 
-class VINTERPe_gfx12 <bits<7> op> : VINTERPe {
+class VINTERPe_gfx12_gfx13 <bits<7> op> : VINTERPe {
   let Inst{20-16} = op{4-0};
 }
 
@@ -237,41 +237,36 @@ defm : VInterpF16Pat<int_amdgcn_interp_p2_rtz_f16,
 // VINTERP Real Instructions
 //===----------------------------------------------------------------------===//
 
-multiclass VINTERP_Real_gfx11 <bits<7> op, string asmName> {
+multiclass VINTERP_Real <GFXGen Gen, bits<7> op, string asmName> {
   defvar ps = !cast<VOP3_Pseudo>(NAME);
-  let AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11" #
+  let AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace #
                            !if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in {
-    def _gfx11 :
-      VINTERP_Real<ps, SIEncodingFamily.GFX11, asmName>,
+    if !eq(Gen.Subtarget, SIEncodingFamily.GFX11) then
+    def Gen.Suffix :
+      VINTERP_Real<ps, Gen.Subtarget, asmName>,
       VINTERPe_gfx11<op>;
+    else // gfx12, gfx13
+    def Gen.Suffix :
+      VINTERP_Real<ps, Gen.Subtarget, asmName>,
+      VINTERPe_gfx12_gfx13<op>;
   }
 }
 
-multiclass VINTERP_Real_gfx12 <bits<7> op, string asmName> {
-  defvar ps = !cast<VOP3_Pseudo>(NAME);
-  let AssemblerPredicate = isGFX12Only, DecoderNamespace = "GFX12" #
-                           !if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in {
-    def _gfx12 :
-      VINTERP_Real<ps, SIEncodingFamily.GFX12, asmName>,
-      VINTERPe_gfx12<op>;
-  }
-}
-
-multiclass VINTERP_Real_gfx11_gfx12 <bits<7> op, string asmName = !cast<VOP3_Pseudo>(NAME).Mnemonic> :
-  VINTERP_Real_gfx11<op, asmName>, VINTERP_Real_gfx12<op, asmName>;
+multiclass VINTERP_Real_gfx11_gfx12_gfx13 <bits<7> op, string asmName = !cast<VOP3_Pseudo>(NAME).Mnemonic> :
+  VINTERP_Real<GFX11Gen, op, asmName>, VINTERP_Real<GFX12Gen, op, asmName>, VINTERP_Real<GFX13Gen, op, asmName>;
 
-multiclass VINTERP_Real_t16_and_fake16_gfx11_gfx12 <bits<7> op, string asmName = !cast<VOP3_Pseudo>(NAME).Mnemonic> {
-  defm _t16:    VINTERP_Real_gfx11_gfx12<op, asmName>;
-  defm _fake16: VINTERP_Real_gfx11_gfx12<op, asmName>;
+multiclass VINTERP_Real_t16_and_fake16_gfx11_gfx12_gfx13 <bits<7> op, string asmName = !cast<VOP3_Pseudo>(NAME).Mnemonic> {
+  defm _t16:    VINTERP_Real_gfx11_gfx12_gfx13<op, asmName>;
+  defm _fake16: VINTERP_Real_gfx11_gfx12_gfx13<op, asmName>;
 }
 
 
-defm V_INTERP_P10_F32_inreg : VINTERP_Real_gfx11_gfx12<0x000>;
-defm V_INTERP_P2_F32_inreg : VINTERP_Real_gfx11_gfx12<0x001>;
-defm V_INTERP_P10_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x002, "v_interp_p10_f16_f32">;
-defm V_INTERP_P2_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x003, "v_interp_p2_f16_f32">;
-defm V_INTERP_P10_RTZ_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x004, "v_interp_p10_rtz_f16_f32">;
-defm V_INTERP_P2_RTZ_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x005, "v_interp_p2_rtz_f16_f32">;
+defm V_INTERP_P10_F32_inreg : VINTERP_Real_gfx11_gfx12_gfx13<0x000>;
+defm V_INTERP_P2_F32_inreg : VINTERP_Real_gfx11_gfx12_gfx13<0x001>;
+defm V_INTERP_P10_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12_gfx13<0x002, "v_interp_p10_f16_f32">;
+defm V_INTERP_P2_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12_gfx13<0x003, "v_interp_p2_f16_f32">;
+defm V_INTERP_P10_RTZ_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12_gfx13<0x004, "v_interp_p10_rtz_f16_f32">;
+defm V_INTERP_P2_RTZ_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12_gfx13<0x005, "v_interp_p2_rtz_f16_f32">;
 
 let AssemblerPredicate = isGFX11Plus in
 def : AMDGPUMnemonicAlias<"v_interp_p2_new_f32", "v_interp_p2_f32">;
diff --git a/llvm/test/MC/AMDGPU/vinterp-fake16.s b/llvm/test/MC/AMDGPU/vinterp-fake16.s
index 33dacdd92c317..1b35948151fd6 100644
--- a/llvm/test/MC/AMDGPU/vinterp-fake16.s
+++ b/llvm/test/MC/AMDGPU/vinterp-fake16.s
@@ -1,5 +1,6 @@
 // RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -mattr=-real-true16 -show-encoding %s | FileCheck -check-prefix=GCN %s
 // RUN: llvm-mc -triple=amdgcn -mcpu=gfx1200 -mattr=-real-true16 -show-encoding %s | FileCheck -check-prefix=GCN %s
+// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1310 -mattr=-real-true16 -show-encoding %s | FileCheck -check-prefix=GCN %s
 
 v_interp_p10_f32 v0, v1, v2, v3
 // GCN: v_interp_p10_f32 v0, v1, v2, v3 wait_exp:0  ; encoding: [0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x04]
diff --git a/llvm/test/MC/Disassembler/AMDGPU/vinterp.txt b/llvm/test/MC/Disassembler/AMDGPU/vinterp.txt
index f0e1d6cda522a..83a090042eae4 100644
--- a/llvm/test/MC/Disassembler/AMDGPU/vinterp.txt
+++ b/llvm/test/MC/Disassembler/AMDGPU/vinterp.txt
@@ -1,8 +1,10 @@
 # NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --unique --version 5
 # RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -disassemble %s | FileCheck -strict-whitespace -check-prefixes=CHECK,CHECK-TRUE16 %s
 # RUN: llvm-mc -triple=amdgcn -mcpu=gfx1200 -mattr=+real-true16 -disassemble %s | FileCheck -strict-whitespace -check-prefixes=CHECK,CHECK-TRUE16 %s
+# RUN: llvm-mc -triple=amdgcn -mcpu=gfx1310 -mattr=+real-true16 -disassemble %s | FileCheck -strict-whitespace -check-prefixes=CHECK,CHECK-TRUE16 %s
 # RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -mattr=-real-true16 -disassemble %s | FileCheck -strict-whitespace -check-prefixes=CHECK,CHECK-FAKE16 %s
 # RUN: llvm-mc -triple=amdgcn -mcpu=gfx1200 -mattr=-real-true16 -disassemble %s | FileCheck -strict-whitespace -check-prefixes=CHECK,CHECK-FAKE16 %s
+# RUN: llvm-mc -triple=amdgcn -mcpu=gfx1310 -mattr=-real-true16 -disassemble %s | FileCheck -strict-whitespace -check-prefixes=CHECK,CHECK-FAKE16 %s
 
 0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x04
 # CHECK: v_interp_p10_f32 v0, v1, v2, v3 wait_exp:0



More information about the llvm-commits mailing list