[llvm] AMDGPU/GlobalISel: RegBankLegalize rules for amdgcn_exp/exp_row (PR #181956)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 4 09:15:55 PST 2026


https://github.com/vangthao95 updated https://github.com/llvm/llvm-project/pull/181956

>From 379652c572efab3149ea2f4f3815345312e2eb11 Mon Sep 17 00:00:00 2001
From: Vang Thao <vang.thao at amd.com>
Date: Tue, 17 Feb 2026 18:01:41 -0800
Subject: [PATCH 1/3] AMDGPU/GlobalISel: RegBankLegalize rules for
 amdgcn_exp/exp_row

---
 .../AMDGPU/AMDGPURegBankLegalizeHelper.cpp    | 11 ++++
 .../AMDGPU/AMDGPURegBankLegalizeRules.cpp     | 10 ++++
 .../AMDGPU/AMDGPURegBankLegalizeRules.h       |  3 +
 .../GlobalISel/regbankselect-amdgcn-exp.mir   |  3 +-
 llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.ll   | 14 +++--
 .../CodeGen/AMDGPU/llvm.amdgcn.exp.row.ll     | 58 +++++++------------
 6 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
index d262f074679a8..754e77be0e7bd 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
@@ -1142,6 +1142,7 @@ LLT RegBankLegalizeHelper::getBTyFromID(RegBankLLTMappingApplyID ID, LLT Ty) {
   switch (ID) {
   case SgprB32:
   case VgprB32:
+  case ForceSgprB32:
   case UniInVgprB32:
     if (Ty == LLT::scalar(32) || Ty == LLT::fixed_vector(2, 16) ||
         isAnyPtr(Ty, 32))
@@ -1564,6 +1565,16 @@ bool RegBankLegalizeHelper::applyMappingSrc(
         SgprWaterfallOperandRegs.insert(Reg);
       break;
     }
+    case ForceSgprB32: {
+      assert(Ty == getBTyFromID(MethodIDs[i], Ty));
+      if (RB == SgprRB)
+        break;
+      assert(RB == VgprRB);
+      Register NewSGPR32 = MRI.createVirtualRegister({SgprRB, Ty});
+      buildReadAnyLane(B, NewSGPR32, Op.getReg(), RBI);
+      Op.setReg(NewSGPR32);
+      break;
+    }
     // sgpr and vgpr scalars with extend
     case Sgpr32AExt: {
       // Note: this ext allows S1, and it is meant to be combined away.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 73592d52ad04c..1a5ce5f94094c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1359,6 +1359,16 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
       .Uni(S64, {{Sgpr64}, {IntrId, Vcc, Sgpr64}})
       .Uni(S32, {{Sgpr32}, {IntrId, Vcc, Sgpr32}});
 
+  addRulesForIOpcs({amdgcn_exp})
+      .Any({{_, _, _, S32, S32, S32, S32},
+            {{}, {IntrId, Imm, Imm, Vgpr32, Vgpr32, Vgpr32, Vgpr32}}});
+
+  addRulesForIOpcs({amdgcn_exp_row})
+      .Any({{_, _, _, S32, S32, S32, S32, _, S32},
+            {{},
+             {IntrId, Imm, Imm, Vgpr32, Vgpr32, Vgpr32, Vgpr32, Imm,
+              ForceSgprB32}}});
+
   addRulesForIOpcs({amdgcn_mbcnt_lo, amdgcn_mbcnt_hi}, Standard)
       .Div(S32, {{}, {Vgpr32, None, Vgpr32, Vgpr32}});
 
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
index eee4f6276b925..3f94c53a632f2 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
@@ -221,6 +221,9 @@ enum RegBankLLTMappingApplyID {
   Sgpr32_WF,
   SgprV4S32_WF,
 
+  // Src only modifiers: readfirstlane if divergent (not waterfall)
+  ForceSgprB32,
+
   // Src only modifiers: extends
   Sgpr32AExt,
   Sgpr32AExtBoolInReg,
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir
index 313b0c5b6707c..61bcc7482da94 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir
@@ -1,6 +1,5 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=amdgcn -mcpu=fiji -run-pass=regbankselect %s -verify-machineinstrs -o - -regbankselect-fast | FileCheck %s
-# RUN: llc -mtriple=amdgcn -mcpu=fiji -run-pass=regbankselect %s -verify-machineinstrs -o - -regbankselect-greedy | FileCheck %s
+# RUN: llc -mtriple=amdgcn -mcpu=fiji -run-pass='amdgpu-regbankselect,amdgpu-regbanklegalize' %s -o - | FileCheck %s
 
 --- |
   define void @exp_s() {
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.ll
index f921ad30e4977..c08b7b087fa04 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.ll
@@ -1,7 +1,11 @@
-; RUN: llc -mtriple=amdgcn -mcpu=tonga < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX8,PREGFX11 %s
-; RUN: llc -mtriple=amdgcn -mcpu=gfx1010 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX10,PREGFX11 %s
-; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -amdgpu-enable-vopd=0 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX11 %s
-; RUN: llc -mtriple=amdgcn -mcpu=gfx1200 -amdgpu-enable-vopd=0 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX11 %s
+; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=tonga < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX8,PREGFX11 %s
+; RUN: llc -global-isel=1 -new-reg-bank-select -mtriple=amdgcn -mcpu=tonga < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX8,PREGFX11 %s
+; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1010 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX10,PREGFX11 %s
+; RUN: llc -global-isel=1 -new-reg-bank-select -mtriple=amdgcn -mcpu=gfx1010 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX10,PREGFX11 %s
+; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1100 -amdgpu-enable-vopd=0 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX11 %s
+; RUN: llc -global-isel=1 -new-reg-bank-select -mtriple=amdgcn -mcpu=gfx1100 -amdgpu-enable-vopd=0 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX11 %s
+; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 -amdgpu-enable-vopd=0 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX11 %s
+; RUN: llc -global-isel=1 -new-reg-bank-select -mtriple=amdgcn -mcpu=gfx1200 -amdgpu-enable-vopd=0 < %s | FileCheck -strict-whitespace -check-prefixes=GCN,GFX11 %s
 
 declare void @llvm.amdgcn.exp.f32(i32, i32, float, float, float, float, i1, i1) #1
 declare void @llvm.amdgcn.exp.i32(i32, i32, i32, i32, i32, i32, i1, i1) #1
@@ -554,7 +558,7 @@ end:
 ; GFX8-DAG: v_mov_b32_e32 [[X:v[0-9]+]], s1
 ; GFX8-DAG: v_mov_b32_e32 [[Y:v[0-9]+]], s0
 ; GFX8-DAG: v_add_f32_e{{32|64}} [[Z0:v[0-9]+]]
-; GFX8-DAG: v_sub_f32_e{{32|64}} [[Z1:v[0-9]+]]
+; GFX8-DAG: v_{{sub|subrev}}_f32_e{{32|64}} [[Z1:v[0-9]+]]
 ; GFX8: {{exp|export}} param0 [[Y]], [[X]], [[Z0]], [[W0]]{{$}}
 ; GFX8-NEXT: {{exp|export}} param1 [[Y]], [[X]], [[Z1]], [[W1]] done{{$}}
 
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.row.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.row.ll
index af73475e14a89..7693606846484 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.row.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.exp.row.ll
@@ -1,8 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1100 < %s | FileCheck %s -check-prefixes=GFX11
-; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1100 < %s | FileCheck %s -check-prefixes=GFX11
+; RUN: llc -global-isel=1 -new-reg-bank-select -mtriple=amdgcn -mcpu=gfx1100 < %s | FileCheck %s -check-prefixes=GFX11
 ; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck %s -check-prefixes=GFX12
-; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck %s -check-prefixes=GFX12
+; RUN: llc -global-isel=1 -new-reg-bank-select -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck %s -check-prefixes=GFX12
 
 declare void @llvm.amdgcn.exp.row.i32(i32, i32, i32, i32, i32, i32, i1, i32)
 declare void @llvm.amdgcn.exp.row.f32(i32, i32, float, float, float, float, i1, i32)
@@ -132,43 +132,25 @@ define amdgpu_kernel void @id_arg_i32(i32 %row) #0 {
 
 ; Divergent row number just causes a readfirstlane for now.
 define amdgpu_kernel void @id_row_i32() #0 {
-; GFX11-SDAG-LABEL: id_row_i32:
-; GFX11-SDAG:       ; %bb.0:
-; GFX11-SDAG-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; GFX11-SDAG-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-SDAG-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX11-SDAG-NEXT:    v_mov_b32_e32 v0, 0x63
-; GFX11-SDAG-NEXT:    s_mov_b32 m0, s0
-; GFX11-SDAG-NEXT:    exp pos0 v0, off, off, off done row_en
-; GFX11-SDAG-NEXT:    s_endpgm
-;
-; GFX11-GISEL-LABEL: id_row_i32:
-; GFX11-GISEL:       ; %bb.0:
-; GFX11-GISEL-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; GFX11-GISEL-NEXT:    v_mov_b32_e32 v1, 0x63
-; GFX11-GISEL-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; GFX11-GISEL-NEXT:    v_readfirstlane_b32 m0, v0
-; GFX11-GISEL-NEXT:    exp pos0 v1, off, off, off done row_en
-; GFX11-GISEL-NEXT:    s_endpgm
-;
-; GFX12-SDAG-LABEL: id_row_i32:
-; GFX12-SDAG:       ; %bb.0:
-; GFX12-SDAG-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; GFX12-SDAG-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX12-SDAG-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX12-SDAG-NEXT:    v_mov_b32_e32 v0, 0x63
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, s0
-; GFX12-SDAG-NEXT:    export pos0 v0, off, off, off done row_en
-; GFX12-SDAG-NEXT:    s_endpgm
+; GFX11-LABEL: id_row_i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_readfirstlane_b32 s0, v0
+; GFX11-NEXT:    v_mov_b32_e32 v0, 0x63
+; GFX11-NEXT:    s_mov_b32 m0, s0
+; GFX11-NEXT:    exp pos0 v0, off, off, off done row_en
+; GFX11-NEXT:    s_endpgm
 ;
-; GFX12-GISEL-LABEL: id_row_i32:
-; GFX12-GISEL:       ; %bb.0:
-; GFX12-GISEL-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; GFX12-GISEL-NEXT:    v_mov_b32_e32 v1, 0x63
-; GFX12-GISEL-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; GFX12-GISEL-NEXT:    v_readfirstlane_b32 m0, v0
-; GFX12-GISEL-NEXT:    export pos0 v1, off, off, off done row_en
-; GFX12-GISEL-NEXT:    s_endpgm
+; GFX12-LABEL: id_row_i32:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
+; GFX12-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX12-NEXT:    v_readfirstlane_b32 s0, v0
+; GFX12-NEXT:    v_mov_b32_e32 v0, 0x63
+; GFX12-NEXT:    s_mov_b32 m0, s0
+; GFX12-NEXT:    export pos0 v0, off, off, off done row_en
+; GFX12-NEXT:    s_endpgm
   %id = call i32 @llvm.amdgcn.workitem.id.x()
   call void @llvm.amdgcn.exp.row.i32(i32 12, i32 1, i32 99, i32 poison, i32 poison, i32 poison, i1 true, i32 %id)
   ret void

>From 6d9c31fd8627e41f6a486f88dab8b1e8d1a90f38 Mon Sep 17 00:00:00 2001
From: Vang Thao <vang.thao at amd.com>
Date: Wed, 4 Mar 2026 08:23:29 -0800
Subject: [PATCH 2/3] Change ForceSgprB32 name and add readfirstlane

---
 llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp | 6 +++---
 llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp  | 2 +-
 llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h    | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
index 754e77be0e7bd..eedf507b5e532 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
@@ -1142,7 +1142,7 @@ LLT RegBankLegalizeHelper::getBTyFromID(RegBankLLTMappingApplyID ID, LLT Ty) {
   switch (ID) {
   case SgprB32:
   case VgprB32:
-  case ForceSgprB32:
+  case SgprB32_M0:
   case UniInVgprB32:
     if (Ty == LLT::scalar(32) || Ty == LLT::fixed_vector(2, 16) ||
         isAnyPtr(Ty, 32))
@@ -1565,13 +1565,13 @@ bool RegBankLegalizeHelper::applyMappingSrc(
         SgprWaterfallOperandRegs.insert(Reg);
       break;
     }
-    case ForceSgprB32: {
+    case SgprB32_M0: {
       assert(Ty == getBTyFromID(MethodIDs[i], Ty));
       if (RB == SgprRB)
         break;
       assert(RB == VgprRB);
       Register NewSGPR32 = MRI.createVirtualRegister({SgprRB, Ty});
-      buildReadAnyLane(B, NewSGPR32, Op.getReg(), RBI);
+      buildReadFirstLane(B, NewSGPR32, Op.getReg(), RBI);
       Op.setReg(NewSGPR32);
       break;
     }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 1a5ce5f94094c..f029215d7c864 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1367,7 +1367,7 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
       .Any({{_, _, _, S32, S32, S32, S32, _, S32},
             {{},
              {IntrId, Imm, Imm, Vgpr32, Vgpr32, Vgpr32, Vgpr32, Imm,
-              ForceSgprB32}}});
+              SgprB32_M0}}});
 
   addRulesForIOpcs({amdgcn_mbcnt_lo, amdgcn_mbcnt_hi}, Standard)
       .Div(S32, {{}, {Vgpr32, None, Vgpr32, Vgpr32}});
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
index 3f94c53a632f2..e25aa14b58c44 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
@@ -221,8 +221,8 @@ enum RegBankLLTMappingApplyID {
   Sgpr32_WF,
   SgprV4S32_WF,
 
-  // Src only modifiers: readfirstlane if divergent (not waterfall)
-  ForceSgprB32,
+  // Src only modifiers: readfirstlane to M0 if divergent (not waterfall)
+  SgprB32_M0,
 
   // Src only modifiers: extends
   Sgpr32AExt,

>From 82d3dcdd0f45fdadeaa0abf662b4ab8c0f93454c Mon Sep 17 00:00:00 2001
From: Vang Thao <vang.thao at amd.com>
Date: Wed, 4 Mar 2026 09:15:42 -0800
Subject: [PATCH 3/3] Add export row test, update comment

---
 .../AMDGPU/AMDGPURegBankLegalizeRules.h       |  3 +-
 .../GlobalISel/regbankselect-amdgcn-exp.mir   | 66 ++++++++++++++++---
 2 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
index e25aa14b58c44..6c3d54f797019 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
@@ -221,7 +221,8 @@ enum RegBankLLTMappingApplyID {
   Sgpr32_WF,
   SgprV4S32_WF,
 
-  // Src only modifiers: readfirstlane to M0 if divergent (not waterfall)
+  // Src only modifiers: for operands that must end up in M0. If divergent,
+  // readfirstlane to SGPR. The result can then be copied to M0 in ISel.
   SgprB32_M0,
 
   // Src only modifiers: extends
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir
index 61bcc7482da94..7d2a3c1c5f6f9 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-amdgcn-exp.mir
@@ -1,17 +1,26 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=amdgcn -mcpu=fiji -run-pass='amdgpu-regbankselect,amdgpu-regbanklegalize' %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -run-pass='amdgpu-regbankselect,amdgpu-regbanklegalize' %s -o - | FileCheck %s
 
 --- |
-  define void @exp_s() {
-    call void @llvm.amdgcn.exp.f32(i32 0, i32 0, float 1.0, float 1.0, float 1.0, float 1.0, i1 0, i1 0)
+  define amdgpu_ps void @exp_s(float inreg %v0, float inreg %v1, float inreg %v2, float inreg %v3) {
+    call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %v0, float %v1, float %v2, float %v3, i1 false, i1 false)
     ret void
   }
-  define void @exp_v() {
-    call void @llvm.amdgcn.exp.f32(i32 0, i32 0, float 1.0, float 1.0, float 1.0, float 1.0, i1 0, i1 0)
+  define amdgpu_ps void @exp_v(float %v0, float %v1, float %v2, float %v3) {
+    call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %v0, float %v1, float %v2, float %v3, i1 false, i1 false)
+    ret void
+  }
+  define amdgpu_ps void @exp_row_s(i32 inreg %row, float inreg %val) {
+    call void @llvm.amdgcn.exp.row.f32(i32 12, i32 1, float %val, float %val, float %val, float %val, i1 true, i32 %row)
+    ret void
+  }
+  define amdgpu_ps void @exp_row_v(float %val, i32 %row) {
+    call void @llvm.amdgcn.exp.row.f32(i32 12, i32 1, float %val, float %val, float %val, float %val, i1 true, i32 %row)
     ret void
   }
 
   declare void @llvm.amdgcn.exp.f32(i32, i32, float, float, float, float, i1, i1)
+  declare void @llvm.amdgcn.exp.row.f32(i32 immarg, i32 immarg, float, float, float, float, i1 immarg, i32)
 ...
 
 ---
@@ -32,12 +41,12 @@ body: |
     ; CHECK-NEXT: [[COPY5:%[0-9]+]]:vgpr(s32) = COPY [[COPY1]](s32)
     ; CHECK-NEXT: [[COPY6:%[0-9]+]]:vgpr(s32) = COPY [[COPY2]](s32)
     ; CHECK-NEXT: [[COPY7:%[0-9]+]]:vgpr(s32) = COPY [[COPY3]](s32)
-    ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp), 0, 0, [[COPY4]](s32), [[COPY5]](s32), [[COPY6]](s32), [[COPY7]](s32), 0, 0
+    ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp), 0, 15, [[COPY4]](s32), [[COPY5]](s32), [[COPY6]](s32), [[COPY7]](s32), 0, 0
     %0:_(s32) = COPY $sgpr0
     %1:_(s32) = COPY $sgpr1
     %2:_(s32) = COPY $sgpr2
     %3:_(s32) = COPY $sgpr3
-    G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp.f32), 0, 0, %0, %1, %2, %3, 0, 0
+    G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp), 0, 15, %0(s32), %1(s32), %2(s32), %3(s32), 0, 0
 ...
 ---
 name: exp_v
@@ -53,10 +62,49 @@ body: |
     ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1
     ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr2
     ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vgpr(s32) = COPY $vgpr3
-    ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp), 0, 0, [[COPY]](s32), [[COPY1]](s32), [[COPY2]](s32), [[COPY3]](s32), 0, 0
+    ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp), 0, 15, [[COPY]](s32), [[COPY1]](s32), [[COPY2]](s32), [[COPY3]](s32), 0, 0
     %0:_(s32) = COPY $vgpr0
     %1:_(s32) = COPY $vgpr1
     %2:_(s32) = COPY $vgpr2
     %3:_(s32) = COPY $vgpr3
-    G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp.f32), 0, 0, %0, %1, %2, %3, 0, 0
+    G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp), 0, 15, %0(s32), %1(s32), %2(s32), %3(s32), 0, 0
+...
+---
+name: exp_row_s
+legalized: true
+
+body: |
+  bb.0:
+    liveins: $sgpr0, $sgpr1
+    ; CHECK-LABEL: name: exp_row_s
+    ; CHECK: liveins: $sgpr0, $sgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vgpr(s32) = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: [[COPY4:%[0-9]+]]:vgpr(s32) = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: [[COPY5:%[0-9]+]]:vgpr(s32) = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp.row), 12, 1, [[COPY2]](s32), [[COPY3]](s32), [[COPY4]](s32), [[COPY5]](s32), -1, [[COPY]](s32)
+    %0:_(s32) = COPY $sgpr0
+    %1:_(s32) = COPY $sgpr1
+    G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp.row), 12, 1, %1(s32), %1(s32), %1(s32), %1(s32), -1, %0(s32)
+...
+---
+name: exp_row_v
+legalized: true
+
+body: |
+  bb.0:
+    liveins: $vgpr0, $vgpr1
+    ; CHECK-LABEL: name: exp_row_v
+    ; CHECK: liveins: $vgpr0, $vgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1
+    ; CHECK-NEXT: [[INTRINSIC_CONVERGENT:%[0-9]+]]:sgpr(s32) = G_INTRINSIC_CONVERGENT intrinsic(@llvm.amdgcn.readfirstlane), [[COPY1]](s32)
+    ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp.row), 12, 1, [[COPY]](s32), [[COPY]](s32), [[COPY]](s32), [[COPY]](s32), -1, [[INTRINSIC_CONVERGENT]](s32)
+    %0:_(s32) = COPY $vgpr0
+    %1:_(s32) = COPY $vgpr1
+    G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.exp.row), 12, 1, %0(s32), %0(s32), %0(s32), %0(s32), -1, %1(s32)
 ...



More information about the llvm-commits mailing list