[llvm] AMDGPU/GlobalISel: Implement RegBankLegalizeRules for amdgcn_log, amdgcn_rcp, and amdgcn_sqrt (PR #195099)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 07:07:02 PDT 2026
https://github.com/anjenner updated https://github.com/llvm/llvm-project/pull/195099
>From 737a169918a43102662701e48b9117805d475bb8 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Thu, 5 Feb 2026 09:51:47 -0500
Subject: [PATCH 1/8] [AMDGPU] [GlobalISel] Add register bank legalize rules
for amdgcn_log, amdgcn_exp2, amdgcn_rcp, and amdgcn_sqrt.
---
llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp | 11 +++++++++++
.../CodeGen/AMDGPU/pseudo-scalar-transcendental.ll | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 118d75dd6bbe3..e7c75c7fe84f6 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1766,6 +1766,17 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
.Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
+ bool hasPST = ST->hasPseudoScalarTrans();
+ addRulesForIOpcs({amdgcn_log, amdgcn_exp2, amdgcn_rcp, amdgcn_sqrt}, Standard)
+ .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
+ .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
+ .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
+ .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST)
+ .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
+ .Uni(S64, {{Sgpr64}, {IntrId, Sgpr64}}, hasPST)
+ .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}}, !hasPST)
+ .Div(S64, {{Vgpr64}, {IntrId, Vgpr64}});
+
addRulesForIOpcs({amdgcn_frexp_mant, amdgcn_fract}, Standard)
.Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
.Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
diff --git a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
index f001b26030896..ab289ed1d350c 100644
--- a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
+++ b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck -check-prefixes=GFX12,GFX12-SDAG %s
-; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck -check-prefixes=GFX12,GFX12-GISEL %s
+; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 -new-reg-bank-select -global-isel-abort=1 < %s | FileCheck -check-prefixes=GFX12,GFX12-GISEL %s
; TODO: GlobalISel should avoid generating v_ldexp_f32.
define amdgpu_cs float @v_s_exp_f32(float inreg %src) {
>From 47d85424ee4935605a6a6478791d055d82741306 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Thu, 30 Apr 2026 10:10:00 -0400
Subject: [PATCH 2/8] Fix up after merge.
---
llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index e7c75c7fe84f6..f2c802e88f948 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1766,8 +1766,7 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
.Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
- bool hasPST = ST->hasPseudoScalarTrans();
- addRulesForIOpcs({amdgcn_log, amdgcn_exp2, amdgcn_rcp, amdgcn_sqrt}, Standard)
+ addRulesForIOpcs({amdgcn_log, amdgcn_rcp, amdgcn_sqrt}, Standard)
.Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
.Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
.Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
>From 8b87274fc87791bf2fa4ce738926233f96247d02 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Thu, 30 Apr 2026 10:34:12 -0400
Subject: [PATCH 3/8] Fix up pseudo-scalar-transcendental.ll testcase.
---
.../AMDGPU/pseudo-scalar-transcendental.ll | 246 +++++++++++-------
1 file changed, 158 insertions(+), 88 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
index ab289ed1d350c..c12a9ff3121dd 100644
--- a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
+++ b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
@@ -35,13 +35,18 @@ define amdgpu_cs float @v_s_exp_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_exp_f16(half inreg %src) {
-; GFX12-LABEL: v_s_exp_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_exp_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_exp_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_exp_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_exp_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_exp_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.exp2.f16(half %src)
ret half %result
}
@@ -88,29 +93,39 @@ define amdgpu_cs float @v_s_log_f32(float inreg %src) {
; GFX12-GISEL-LABEL: v_s_log_f32:
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: s_cmp_lt_f32 s0, 0x800000
+; GFX12-GISEL-NEXT: s_cselect_b32 s2, 1, 0
; GFX12-GISEL-NEXT: s_cselect_b32 s1, 1, 0
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
-; GFX12-GISEL-NEXT: s_lshl_b32 s2, s1, 5
+; GFX12-GISEL-NEXT: s_lshl_b32 s2, s2, 5
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
; GFX12-GISEL-NEXT: v_ldexp_f32 v0, s0, s2
-; GFX12-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX12-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-GISEL-NEXT: v_s_log_f32 s0, s0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: s_sub_f32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.log2.f32(float %src)
ret float %result
}
define amdgpu_cs half @v_s_log_f16(half inreg %src) {
-; GFX12-LABEL: v_s_log_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_log_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_log_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.log2.f16(half %src)
ret half %result
}
@@ -128,13 +143,18 @@ define amdgpu_cs float @v_s_amdgcn_log_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_amdgcn_log_f16(half inreg %src) {
-; GFX12-LABEL: v_s_amdgcn_log_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_amdgcn_log_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_amdgcn_log_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.log.f16(half %src)
ret half %result
}
@@ -152,13 +172,18 @@ define amdgpu_cs float @v_s_rcp_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_rcp_f16(half inreg %src) {
-; GFX12-LABEL: v_s_rcp_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_rcp_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_rcp_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_rcp_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_rcp_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_rcp_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call fast half @llvm.amdgcn.rcp.f16(half %src)
ret half %result
}
@@ -188,13 +213,18 @@ define amdgpu_cs float @v_s_rsq_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_rsq_f16(half inreg %src) {
-; GFX12-LABEL: v_s_rsq_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_rsq_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_rsq_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_rsq_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_rsq_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_rsq_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%sqrt = call fast half @llvm.sqrt.f16(half %src)
%result = fdiv fast half 1.0, %sqrt
ret half %result
@@ -260,16 +290,17 @@ define amdgpu_cs float @v_s_sqrt_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_fmac_f32 s6, s7, s2
; GFX12-GISEL-NEXT: s_cselect_b32 s2, s3, s2
; GFX12-GISEL-NEXT: s_cmp_gt_f32 s6, 0
+; GFX12-GISEL-NEXT: v_cmp_class_f32_e64 s3, s0, 0x260
; GFX12-GISEL-NEXT: s_cselect_b32 s2, s5, s2
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
-; GFX12-GISEL-NEXT: s_mul_f32 s3, s2, 0x37800000
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_3) | instskip(SKIP_4) | instid1(VALU_DEP_1)
-; GFX12-GISEL-NEXT: s_cselect_b32 s1, s3, s2
+; GFX12-GISEL-NEXT: s_mul_f32 s4, s2, 0x37800000
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_3)
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, s4, s2
+; GFX12-GISEL-NEXT: s_cmp_lg_u32 s3, 0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s1
-; GFX12-GISEL-NEXT: v_cmp_class_f32_e64 s1, s0, 0x260
-; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-GISEL-NEXT: v_cndmask_b32_e64 v0, v0, s0, s1
+; GFX12-GISEL-NEXT: s_cselect_b32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.sqrt.f32(float %src)
ret float %result
@@ -300,13 +331,18 @@ define amdgpu_cs float @v_amdgcn_sqrt_f32(float inreg %src) {
}
define amdgpu_cs half @v_amdgcn_sqrt_f16(half inreg %src) {
-; GFX12-LABEL: v_amdgcn_sqrt_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_sqrt_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_amdgcn_sqrt_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_sqrt_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_amdgcn_sqrt_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_sqrt_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.sqrt.f16(half %src)
ret half %result
}
@@ -331,17 +367,23 @@ define amdgpu_cs float @srcmods_abs_f32(float inreg %src) {
; GFX12-GISEL-LABEL: srcmods_abs_f32:
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: s_and_b32 s1, s0, 0x7fffffff
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX12-GISEL-NEXT: s_cmp_lt_f32 s1, 0x800000
+; GFX12-GISEL-NEXT: s_cselect_b32 s2, 1, 0
; GFX12-GISEL-NEXT: s_cselect_b32 s1, 1, 0
-; GFX12-GISEL-NEXT: s_lshl_b32 s2, s1, 5
+; GFX12-GISEL-NEXT: s_lshl_b32 s2, s2, 5
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
; GFX12-GISEL-NEXT: v_ldexp_f32 v0, |s0|, s2
-; GFX12-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(TRANS32_DEP_1)
-; GFX12-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-GISEL-NEXT: v_s_log_f32 s0, s0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: s_sub_f32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%abs = call float @llvm.fabs.f32(float %src)
%result = call float @llvm.log2.f32(float %abs)
@@ -367,17 +409,23 @@ define amdgpu_cs float @srcmods_neg_f32(float inreg %src) {
; GFX12-GISEL-LABEL: srcmods_neg_f32:
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: s_xor_b32 s1, s0, 0x80000000
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX12-GISEL-NEXT: s_cmp_lt_f32 s1, 0x800000
+; GFX12-GISEL-NEXT: s_cselect_b32 s2, 1, 0
; GFX12-GISEL-NEXT: s_cselect_b32 s1, 1, 0
-; GFX12-GISEL-NEXT: s_lshl_b32 s2, s1, 5
+; GFX12-GISEL-NEXT: s_lshl_b32 s2, s2, 5
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
; GFX12-GISEL-NEXT: v_ldexp_f32 v0, -s0, s2
-; GFX12-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(TRANS32_DEP_1)
-; GFX12-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-GISEL-NEXT: v_s_log_f32 s0, s0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: s_sub_f32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%neg = fneg float %src
%result = call float @llvm.log2.f32(float %neg)
@@ -385,26 +433,36 @@ define amdgpu_cs float @srcmods_neg_f32(float inreg %src) {
}
define amdgpu_cs half @srcmods_abs_f16(half inreg %src) {
-; GFX12-LABEL: srcmods_abs_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, |s0|
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: srcmods_abs_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, |s0|
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: srcmods_abs_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e64 v0.l, |s0|
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%abs = call half @llvm.fabs.f16(half %src)
%result = call half @llvm.log2.f16(half %abs)
ret half %result
}
define amdgpu_cs half @srcmods_neg_f16(half inreg %src) {
-; GFX12-LABEL: srcmods_neg_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, -s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: srcmods_neg_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, -s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: srcmods_neg_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e64 v0.l, -s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%neg = fneg half %src
%result = call half @llvm.log2.f16(half %neg)
ret half %result
@@ -436,13 +494,25 @@ define amdgpu_cs float @fdiv_f32_i32(float inreg %a, i32 inreg %b) {
}
define amdgpu_cs half @fdiv_f16_i16(half inreg %a, i16 inreg %b) {
-; GFX12-LABEL: fdiv_f16_i16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_cvt_f16_u16_e32 v0.l, s1
-; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(TRANS32_DEP_1)
-; GFX12-NEXT: v_rcp_f16_e32 v0.l, v0.l
-; GFX12-NEXT: v_mul_f16_e32 v0.l, s0, v0.l
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: fdiv_f16_i16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_cvt_f16_u16_e32 v0.l, s1
+; GFX12-SDAG-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_rcp_f16_e32 v0.l, v0.l
+; GFX12-SDAG-NEXT: v_mul_f16_e32 v0.l, s0, v0.l
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: fdiv_f16_i16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_cvt_f16_u16_e32 v0.l, s1
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX12-GISEL-NEXT: v_rcp_f16_e32 v0.l, v0.l
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s1, v0
+; GFX12-GISEL-NEXT: s_mul_f16 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%uint = uitofp i16 %b to half
%result = fdiv afn half %a, %uint
ret half %result
>From 75b18a4667459978d4278d9795c442dad541dca9 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Wed, 6 May 2026 09:29:38 -0400
Subject: [PATCH 4/8] Combine amdgcn_log, amdgcn_rcp with existing amdgcn_sqrt.
Remove -global-isel-abort=1 from test and regenerate.
---
.../AMDGPU/AMDGPURegBankLegalizeRules.cpp | 12 +---
.../AMDGPU/pseudo-scalar-transcendental.ll | 66 ++++++++-----------
2 files changed, 27 insertions(+), 51 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index f2c802e88f948..9327935b5f105 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1766,16 +1766,6 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
.Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
- addRulesForIOpcs({amdgcn_log, amdgcn_rcp, amdgcn_sqrt}, Standard)
- .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
- .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
- .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
- .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST)
- .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
- .Uni(S64, {{Sgpr64}, {IntrId, Sgpr64}}, hasPST)
- .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}}, !hasPST)
- .Div(S64, {{Vgpr64}, {IntrId, Vgpr64}});
-
addRulesForIOpcs({amdgcn_frexp_mant, amdgcn_fract}, Standard)
.Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
.Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
@@ -1949,7 +1939,7 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
.Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST);
- addRulesForIOpcs({amdgcn_sqrt}, Standard)
+ addRulesForIOpcs({amdgcn_log, amdgcn_rcp, amdgcn_sqrt}, Standard)
.Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
.Uni(S16, {{Sgpr16}, {IntrId, Sgpr16}}, hasPST)
.Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}}, !hasPST)
diff --git a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
index c12a9ff3121dd..f3b825c5f42c1 100644
--- a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
+++ b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck -check-prefixes=GFX12,GFX12-SDAG %s
-; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 -new-reg-bank-select -global-isel-abort=1 < %s | FileCheck -check-prefixes=GFX12,GFX12-GISEL %s
+; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 -new-reg-bank-select < %s | FileCheck -check-prefixes=GFX12,GFX12-GISEL %s
; TODO: GlobalISel should avoid generating v_ldexp_f32.
define amdgpu_cs float @v_s_exp_f32(float inreg %src) {
@@ -143,18 +143,13 @@ define amdgpu_cs float @v_s_amdgcn_log_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_amdgcn_log_f16(half inreg %src) {
-; GFX12-SDAG-LABEL: v_s_amdgcn_log_f16:
-; GFX12-SDAG: ; %bb.0:
-; GFX12-SDAG-NEXT: v_s_log_f16 s0, s0
-; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-SDAG-NEXT: ; return to shader part epilog
-;
-; GFX12-GISEL-LABEL: v_s_amdgcn_log_f16:
-; GFX12-GISEL: ; %bb.0:
-; GFX12-GISEL-NEXT: v_log_f16_e32 v0.l, s0
-; GFX12-GISEL-NEXT: ; return to shader part epilog
+; GFX12-LABEL: v_s_amdgcn_log_f16:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: v_s_log_f16 s0, s0
+; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.log.f16(half %src)
ret half %result
}
@@ -172,18 +167,13 @@ define amdgpu_cs float @v_s_rcp_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_rcp_f16(half inreg %src) {
-; GFX12-SDAG-LABEL: v_s_rcp_f16:
-; GFX12-SDAG: ; %bb.0:
-; GFX12-SDAG-NEXT: v_s_rcp_f16 s0, s0
-; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-SDAG-NEXT: ; return to shader part epilog
-;
-; GFX12-GISEL-LABEL: v_s_rcp_f16:
-; GFX12-GISEL: ; %bb.0:
-; GFX12-GISEL-NEXT: v_rcp_f16_e32 v0.l, s0
-; GFX12-GISEL-NEXT: ; return to shader part epilog
+; GFX12-LABEL: v_s_rcp_f16:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: v_s_rcp_f16 s0, s0
+; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-NEXT: ; return to shader part epilog
%result = call fast half @llvm.amdgcn.rcp.f16(half %src)
ret half %result
}
@@ -331,18 +321,13 @@ define amdgpu_cs float @v_amdgcn_sqrt_f32(float inreg %src) {
}
define amdgpu_cs half @v_amdgcn_sqrt_f16(half inreg %src) {
-; GFX12-SDAG-LABEL: v_amdgcn_sqrt_f16:
-; GFX12-SDAG: ; %bb.0:
-; GFX12-SDAG-NEXT: v_s_sqrt_f16 s0, s0
-; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-SDAG-NEXT: ; return to shader part epilog
-;
-; GFX12-GISEL-LABEL: v_amdgcn_sqrt_f16:
-; GFX12-GISEL: ; %bb.0:
-; GFX12-GISEL-NEXT: v_sqrt_f16_e32 v0.l, s0
-; GFX12-GISEL-NEXT: ; return to shader part epilog
+; GFX12-LABEL: v_amdgcn_sqrt_f16:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: v_s_sqrt_f16 s0, s0
+; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.sqrt.f16(half %src)
ret half %result
}
@@ -505,12 +490,13 @@ define amdgpu_cs half @fdiv_f16_i16(half inreg %a, i16 inreg %b) {
; GFX12-GISEL-LABEL: fdiv_f16_i16:
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: v_cvt_f16_u16_e32 v0.l, s1
-; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(TRANS32_DEP_1)
-; GFX12-GISEL-NEXT: v_rcp_f16_e32 v0.l, v0.l
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
; GFX12-GISEL-NEXT: v_readfirstlane_b32 s1, v0
+; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-GISEL-NEXT: v_s_rcp_f16 s1, s1
+; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_2)
; GFX12-GISEL-NEXT: s_mul_f16 s0, s0, s1
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_2)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%uint = uitofp i16 %b to half
>From 327384179729b11cab5e5b40927db0f68dba6123 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Thu, 5 Feb 2026 09:51:47 -0500
Subject: [PATCH 5/8] [AMDGPU] [GlobalISel] Add register bank legalize rules
for amdgcn_log, amdgcn_exp2, amdgcn_rcp, and amdgcn_sqrt.
---
llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp | 11 +++++++++++
.../CodeGen/AMDGPU/pseudo-scalar-transcendental.ll | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 118d75dd6bbe3..e7c75c7fe84f6 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1766,6 +1766,17 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
.Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
+ bool hasPST = ST->hasPseudoScalarTrans();
+ addRulesForIOpcs({amdgcn_log, amdgcn_exp2, amdgcn_rcp, amdgcn_sqrt}, Standard)
+ .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
+ .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
+ .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
+ .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST)
+ .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
+ .Uni(S64, {{Sgpr64}, {IntrId, Sgpr64}}, hasPST)
+ .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}}, !hasPST)
+ .Div(S64, {{Vgpr64}, {IntrId, Vgpr64}});
+
addRulesForIOpcs({amdgcn_frexp_mant, amdgcn_fract}, Standard)
.Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
.Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
diff --git a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
index f001b26030896..ab289ed1d350c 100644
--- a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
+++ b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck -check-prefixes=GFX12,GFX12-SDAG %s
-; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck -check-prefixes=GFX12,GFX12-GISEL %s
+; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 -new-reg-bank-select -global-isel-abort=1 < %s | FileCheck -check-prefixes=GFX12,GFX12-GISEL %s
; TODO: GlobalISel should avoid generating v_ldexp_f32.
define amdgpu_cs float @v_s_exp_f32(float inreg %src) {
>From 6c999f4c9fe3419ac4d5e96187f0ca47f303add8 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Thu, 30 Apr 2026 10:10:00 -0400
Subject: [PATCH 6/8] Fix up after merge.
---
llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index e7c75c7fe84f6..f2c802e88f948 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1766,8 +1766,7 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
.Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
- bool hasPST = ST->hasPseudoScalarTrans();
- addRulesForIOpcs({amdgcn_log, amdgcn_exp2, amdgcn_rcp, amdgcn_sqrt}, Standard)
+ addRulesForIOpcs({amdgcn_log, amdgcn_rcp, amdgcn_sqrt}, Standard)
.Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
.Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
.Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
>From fd8fe436d0edf9e8916c276229cb6b4f9c1e8aa6 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Thu, 30 Apr 2026 10:34:12 -0400
Subject: [PATCH 7/8] Fix up pseudo-scalar-transcendental.ll testcase.
---
.../AMDGPU/pseudo-scalar-transcendental.ll | 246 +++++++++++-------
1 file changed, 158 insertions(+), 88 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
index ab289ed1d350c..c12a9ff3121dd 100644
--- a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
+++ b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
@@ -35,13 +35,18 @@ define amdgpu_cs float @v_s_exp_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_exp_f16(half inreg %src) {
-; GFX12-LABEL: v_s_exp_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_exp_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_exp_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_exp_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_exp_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_exp_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.exp2.f16(half %src)
ret half %result
}
@@ -88,29 +93,39 @@ define amdgpu_cs float @v_s_log_f32(float inreg %src) {
; GFX12-GISEL-LABEL: v_s_log_f32:
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: s_cmp_lt_f32 s0, 0x800000
+; GFX12-GISEL-NEXT: s_cselect_b32 s2, 1, 0
; GFX12-GISEL-NEXT: s_cselect_b32 s1, 1, 0
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
-; GFX12-GISEL-NEXT: s_lshl_b32 s2, s1, 5
+; GFX12-GISEL-NEXT: s_lshl_b32 s2, s2, 5
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
; GFX12-GISEL-NEXT: v_ldexp_f32 v0, s0, s2
-; GFX12-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX12-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-GISEL-NEXT: v_s_log_f32 s0, s0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: s_sub_f32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.log2.f32(float %src)
ret float %result
}
define amdgpu_cs half @v_s_log_f16(half inreg %src) {
-; GFX12-LABEL: v_s_log_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_log_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_log_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.log2.f16(half %src)
ret half %result
}
@@ -128,13 +143,18 @@ define amdgpu_cs float @v_s_amdgcn_log_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_amdgcn_log_f16(half inreg %src) {
-; GFX12-LABEL: v_s_amdgcn_log_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_amdgcn_log_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_amdgcn_log_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.log.f16(half %src)
ret half %result
}
@@ -152,13 +172,18 @@ define amdgpu_cs float @v_s_rcp_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_rcp_f16(half inreg %src) {
-; GFX12-LABEL: v_s_rcp_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_rcp_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_rcp_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_rcp_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_rcp_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_rcp_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call fast half @llvm.amdgcn.rcp.f16(half %src)
ret half %result
}
@@ -188,13 +213,18 @@ define amdgpu_cs float @v_s_rsq_f32(float inreg %src) {
}
define amdgpu_cs half @v_s_rsq_f16(half inreg %src) {
-; GFX12-LABEL: v_s_rsq_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_rsq_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_s_rsq_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_rsq_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_s_rsq_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_rsq_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%sqrt = call fast half @llvm.sqrt.f16(half %src)
%result = fdiv fast half 1.0, %sqrt
ret half %result
@@ -260,16 +290,17 @@ define amdgpu_cs float @v_s_sqrt_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_fmac_f32 s6, s7, s2
; GFX12-GISEL-NEXT: s_cselect_b32 s2, s3, s2
; GFX12-GISEL-NEXT: s_cmp_gt_f32 s6, 0
+; GFX12-GISEL-NEXT: v_cmp_class_f32_e64 s3, s0, 0x260
; GFX12-GISEL-NEXT: s_cselect_b32 s2, s5, s2
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
-; GFX12-GISEL-NEXT: s_mul_f32 s3, s2, 0x37800000
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_3) | instskip(SKIP_4) | instid1(VALU_DEP_1)
-; GFX12-GISEL-NEXT: s_cselect_b32 s1, s3, s2
+; GFX12-GISEL-NEXT: s_mul_f32 s4, s2, 0x37800000
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_3)
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, s4, s2
+; GFX12-GISEL-NEXT: s_cmp_lg_u32 s3, 0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s1
-; GFX12-GISEL-NEXT: v_cmp_class_f32_e64 s1, s0, 0x260
-; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-GISEL-NEXT: v_cndmask_b32_e64 v0, v0, s0, s1
+; GFX12-GISEL-NEXT: s_cselect_b32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.sqrt.f32(float %src)
ret float %result
@@ -300,13 +331,18 @@ define amdgpu_cs float @v_amdgcn_sqrt_f32(float inreg %src) {
}
define amdgpu_cs half @v_amdgcn_sqrt_f16(half inreg %src) {
-; GFX12-LABEL: v_amdgcn_sqrt_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_sqrt_f16 s0, s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: v_amdgcn_sqrt_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_sqrt_f16 s0, s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: v_amdgcn_sqrt_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_sqrt_f16_e32 v0.l, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.sqrt.f16(half %src)
ret half %result
}
@@ -331,17 +367,23 @@ define amdgpu_cs float @srcmods_abs_f32(float inreg %src) {
; GFX12-GISEL-LABEL: srcmods_abs_f32:
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: s_and_b32 s1, s0, 0x7fffffff
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX12-GISEL-NEXT: s_cmp_lt_f32 s1, 0x800000
+; GFX12-GISEL-NEXT: s_cselect_b32 s2, 1, 0
; GFX12-GISEL-NEXT: s_cselect_b32 s1, 1, 0
-; GFX12-GISEL-NEXT: s_lshl_b32 s2, s1, 5
+; GFX12-GISEL-NEXT: s_lshl_b32 s2, s2, 5
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
; GFX12-GISEL-NEXT: v_ldexp_f32 v0, |s0|, s2
-; GFX12-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(TRANS32_DEP_1)
-; GFX12-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-GISEL-NEXT: v_s_log_f32 s0, s0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: s_sub_f32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%abs = call float @llvm.fabs.f32(float %src)
%result = call float @llvm.log2.f32(float %abs)
@@ -367,17 +409,23 @@ define amdgpu_cs float @srcmods_neg_f32(float inreg %src) {
; GFX12-GISEL-LABEL: srcmods_neg_f32:
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: s_xor_b32 s1, s0, 0x80000000
-; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX12-GISEL-NEXT: s_cmp_lt_f32 s1, 0x800000
+; GFX12-GISEL-NEXT: s_cselect_b32 s2, 1, 0
; GFX12-GISEL-NEXT: s_cselect_b32 s1, 1, 0
-; GFX12-GISEL-NEXT: s_lshl_b32 s2, s1, 5
+; GFX12-GISEL-NEXT: s_lshl_b32 s2, s2, 5
; GFX12-GISEL-NEXT: s_cmp_lg_u32 s1, 0
; GFX12-GISEL-NEXT: v_ldexp_f32 v0, -s0, s2
-; GFX12-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(TRANS32_DEP_1)
-; GFX12-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GFX12-GISEL-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-GISEL-NEXT: v_s_log_f32 s0, s0
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: s_sub_f32 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
%neg = fneg float %src
%result = call float @llvm.log2.f32(float %neg)
@@ -385,26 +433,36 @@ define amdgpu_cs float @srcmods_neg_f32(float inreg %src) {
}
define amdgpu_cs half @srcmods_abs_f16(half inreg %src) {
-; GFX12-LABEL: srcmods_abs_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, |s0|
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: srcmods_abs_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, |s0|
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: srcmods_abs_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e64 v0.l, |s0|
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%abs = call half @llvm.fabs.f16(half %src)
%result = call half @llvm.log2.f16(half %abs)
ret half %result
}
define amdgpu_cs half @srcmods_neg_f16(half inreg %src) {
-; GFX12-LABEL: srcmods_neg_f16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_s_log_f16 s0, -s0
-; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
-; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
-; GFX12-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: srcmods_neg_f16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_s_log_f16 s0, -s0
+; GFX12-SDAG-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-SDAG-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: srcmods_neg_f16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_log_f16_e64 v0.l, -s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%neg = fneg half %src
%result = call half @llvm.log2.f16(half %neg)
ret half %result
@@ -436,13 +494,25 @@ define amdgpu_cs float @fdiv_f32_i32(float inreg %a, i32 inreg %b) {
}
define amdgpu_cs half @fdiv_f16_i16(half inreg %a, i16 inreg %b) {
-; GFX12-LABEL: fdiv_f16_i16:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: v_cvt_f16_u16_e32 v0.l, s1
-; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(TRANS32_DEP_1)
-; GFX12-NEXT: v_rcp_f16_e32 v0.l, v0.l
-; GFX12-NEXT: v_mul_f16_e32 v0.l, s0, v0.l
-; GFX12-NEXT: ; return to shader part epilog
+; GFX12-SDAG-LABEL: fdiv_f16_i16:
+; GFX12-SDAG: ; %bb.0:
+; GFX12-SDAG-NEXT: v_cvt_f16_u16_e32 v0.l, s1
+; GFX12-SDAG-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX12-SDAG-NEXT: v_rcp_f16_e32 v0.l, v0.l
+; GFX12-SDAG-NEXT: v_mul_f16_e32 v0.l, s0, v0.l
+; GFX12-SDAG-NEXT: ; return to shader part epilog
+;
+; GFX12-GISEL-LABEL: fdiv_f16_i16:
+; GFX12-GISEL: ; %bb.0:
+; GFX12-GISEL-NEXT: v_cvt_f16_u16_e32 v0.l, s1
+; GFX12-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX12-GISEL-NEXT: v_rcp_f16_e32 v0.l, v0.l
+; GFX12-GISEL-NEXT: v_readfirstlane_b32 s1, v0
+; GFX12-GISEL-NEXT: s_mul_f16 s0, s0, s1
+; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_2)
+; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-GISEL-NEXT: ; return to shader part epilog
%uint = uitofp i16 %b to half
%result = fdiv afn half %a, %uint
ret half %result
>From 0f6c34500971459beeee23cfde4c0c35779f4d17 Mon Sep 17 00:00:00 2001
From: Andrew Jenner <Andrew.Jenner at amd.com>
Date: Thu, 7 May 2026 10:14:08 -0400
Subject: [PATCH 8/8] Remove register bank legalization rules for amdgcn_log
S64. Add tests for S64, divergent and !hasPST.
---
.../AMDGPU/AMDGPURegBankLegalizeRules.cpp | 10 +-
.../AMDGPU/pseudo-scalar-transcendental.ll | 328 ++++++++++++++++++
2 files changed, 337 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 9327935b5f105..f410240c4b005 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1939,7 +1939,7 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
.Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST);
- addRulesForIOpcs({amdgcn_log, amdgcn_rcp, amdgcn_sqrt}, Standard)
+ addRulesForIOpcs({amdgcn_rcp, amdgcn_sqrt}, Standard)
.Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
.Uni(S16, {{Sgpr16}, {IntrId, Sgpr16}}, hasPST)
.Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}}, !hasPST)
@@ -1949,6 +1949,14 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Div(S64, {{Vgpr64}, {IntrId, Vgpr64}})
.Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}});
+ addRulesForIOpcs({amdgcn_log}, Standard)
+ .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
+ .Uni(S16, {{Sgpr16}, {IntrId, Sgpr16}}, hasPST)
+ .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}}, !hasPST)
+ .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
+ .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
+ .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST);
+
addRulesForIOpcs({amdgcn_ds_atomic_async_barrier_arrive_b64})
.Any({{}, {{}, {IntrId, VgprP3}}});
diff --git a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
index f3b825c5f42c1..86ecc738d5515 100644
--- a/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
+++ b/llvm/test/CodeGen/AMDGPU/pseudo-scalar-transcendental.ll
@@ -1,6 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 < %s | FileCheck -check-prefixes=GFX12,GFX12-SDAG %s
; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 -new-reg-bank-select < %s | FileCheck -check-prefixes=GFX12,GFX12-GISEL %s
+; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=fiji -new-reg-bank-select < %s | FileCheck -check-prefixes=GCN-GISEL %s
; TODO: GlobalISel should avoid generating v_ldexp_f32.
define amdgpu_cs float @v_s_exp_f32(float inreg %src) {
@@ -30,6 +31,19 @@ define amdgpu_cs float @v_s_exp_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-GISEL-NEXT: v_ldexp_f32 v0, s0, s1
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_exp_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0xc2fc0000
+; GCN-GISEL-NEXT: v_cmp_lt_f32_e32 vcc, s0, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u64 vcc, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s1, 0x42800000, 0
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, s1
+; GCN-GISEL-NEXT: v_add_f32_e32 v0, s0, v0
+; GCN-GISEL-NEXT: v_exp_f32_e32 v0, v0
+; GCN-GISEL-NEXT: s_cselect_b32 s0, 0xffffffc0, 0
+; GCN-GISEL-NEXT: v_ldexp_f32 v0, v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.exp2.f32(float %src)
ret float %result
}
@@ -47,6 +61,11 @@ define amdgpu_cs half @v_s_exp_f16(half inreg %src) {
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: v_exp_f16_e32 v0.l, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_exp_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_exp_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.exp2.f16(half %src)
ret half %result
}
@@ -59,6 +78,11 @@ define amdgpu_cs float @v_s_amdgcn_exp_f32(float inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_amdgcn_exp_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_exp_f32_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.amdgcn.exp2.f32(float %src)
ret float %result
}
@@ -71,6 +95,11 @@ define amdgpu_cs half @v_s_amdgcn_exp_f16(half inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_amdgcn_exp_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_exp_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.exp2.f16(half %src)
ret half %result
}
@@ -109,6 +138,22 @@ define amdgpu_cs float @v_s_log_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_log_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0x800000
+; GCN-GISEL-NEXT: v_cmp_lt_f32_e32 vcc, s0, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u64 vcc, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s2, 1, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s1, 1, 0
+; GCN-GISEL-NEXT: s_lshl_b32 s2, s2, 5
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, s2
+; GCN-GISEL-NEXT: v_ldexp_f32 v0, s0, v0
+; GCN-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u32 s1, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GCN-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.log2.f32(float %src)
ret float %result
}
@@ -126,6 +171,11 @@ define amdgpu_cs half @v_s_log_f16(half inreg %src) {
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: v_log_f16_e32 v0.l, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_log_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_log_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.log2.f16(half %src)
ret half %result
}
@@ -138,6 +188,11 @@ define amdgpu_cs float @v_s_amdgcn_log_f32(float inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_amdgcn_log_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_log_f32_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.amdgcn.log.f32(float %src)
ret float %result
}
@@ -150,10 +205,63 @@ define amdgpu_cs half @v_s_amdgcn_log_f16(half inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_amdgcn_log_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_log_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.log.f16(half %src)
ret half %result
}
+define void @v_amdgcn_log_f16_div(half %src, ptr addrspace(1) %out) {
+; GFX12-LABEL: v_amdgcn_log_f16_div:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_log_f16_e32 v0.l, v0.l
+; GFX12-NEXT: global_store_b16 v[1:2], v0, off
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+;
+; GCN-GISEL-LABEL: v_amdgcn_log_f16_div:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-GISEL-NEXT: v_log_f16_e32 v0, v0
+; GCN-GISEL-NEXT: flat_store_short v[1:2], v0
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0)
+; GCN-GISEL-NEXT: s_setpc_b64 s[30:31]
+ %result = call half @llvm.amdgcn.log.f16(half %src)
+ store half %result, ptr addrspace(1) %out
+ ret void
+}
+
+define void @v_amdgcn_log_f32_div(float %src, ptr addrspace(1) %out) {
+; GFX12-LABEL: v_amdgcn_log_f32_div:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_log_f32_e32 v0, v0
+; GFX12-NEXT: global_store_b32 v[1:2], v0, off
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+;
+; GCN-GISEL-LABEL: v_amdgcn_log_f32_div:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GCN-GISEL-NEXT: flat_store_dword v[1:2], v0
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0)
+; GCN-GISEL-NEXT: s_setpc_b64 s[30:31]
+ %result = call float @llvm.amdgcn.log.f32(float %src)
+ store float %result, ptr addrspace(1) %out
+ ret void
+}
+
define amdgpu_cs float @v_s_rcp_f32(float inreg %src) {
; GFX12-LABEL: v_s_rcp_f32:
; GFX12: ; %bb.0:
@@ -162,6 +270,11 @@ define amdgpu_cs float @v_s_rcp_f32(float inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_rcp_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_rcp_f32_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call fast float @llvm.amdgcn.rcp.f32(float %src)
ret float %result
}
@@ -174,10 +287,107 @@ define amdgpu_cs half @v_s_rcp_f16(half inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_rcp_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_rcp_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call fast half @llvm.amdgcn.rcp.f16(half %src)
ret half %result
}
+define void @v_rcp_f16_div(half %src, ptr addrspace(1) %out) {
+; GFX12-LABEL: v_rcp_f16_div:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_rcp_f16_e32 v0.l, v0.l
+; GFX12-NEXT: global_store_b16 v[1:2], v0, off
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+;
+; GCN-GISEL-LABEL: v_rcp_f16_div:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-GISEL-NEXT: v_rcp_f16_e32 v0, v0
+; GCN-GISEL-NEXT: flat_store_short v[1:2], v0
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0)
+; GCN-GISEL-NEXT: s_setpc_b64 s[30:31]
+ %result = call half @llvm.amdgcn.rcp.f16(half %src)
+ store half %result, ptr addrspace(1) %out
+ ret void
+}
+
+define void @v_rcp_f32_div(float %src, ptr addrspace(1) %out) {
+; GFX12-LABEL: v_rcp_f32_div:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_rcp_f32_e32 v0, v0
+; GFX12-NEXT: global_store_b32 v[1:2], v0, off
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+;
+; GCN-GISEL-LABEL: v_rcp_f32_div:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-GISEL-NEXT: v_rcp_f32_e32 v0, v0
+; GCN-GISEL-NEXT: flat_store_dword v[1:2], v0
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0)
+; GCN-GISEL-NEXT: s_setpc_b64 s[30:31]
+ %result = call float @llvm.amdgcn.rcp.f32(float %src)
+ store float %result, ptr addrspace(1) %out
+ ret void
+}
+
+define void @v_rcp_f64_div(double %src, ptr addrspace(1) %out) {
+; GFX12-LABEL: v_rcp_f64_div:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_rcp_f64_e32 v[0:1], v[0:1]
+; GFX12-NEXT: global_store_b64 v[2:3], v[0:1], off
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+;
+; GCN-GISEL-LABEL: v_rcp_f64_div:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-GISEL-NEXT: v_rcp_f64_e32 v[0:1], v[0:1]
+; GCN-GISEL-NEXT: flat_store_dwordx2 v[2:3], v[0:1]
+; GCN-GISEL-NEXT: s_waitcnt vmcnt(0)
+; GCN-GISEL-NEXT: s_setpc_b64 s[30:31]
+ %result = call double @llvm.amdgcn.rcp.f64(double %src)
+ store double %result, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_cs double @v_s_rcp_f64(double inreg %src) {
+; GFX12-LABEL: v_s_rcp_f64:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: v_rcp_f64_e32 v[0:1], s[0:1]
+; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX12-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-NEXT: v_readfirstlane_b32 s1, v1
+; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)
+; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_rcp_f64:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_rcp_f64_e32 v[0:1], s[0:1]
+; GCN-GISEL-NEXT: v_readfirstlane_b32 s0, v0
+; GCN-GISEL-NEXT: v_readfirstlane_b32 s1, v1
+; GCN-GISEL-NEXT: ; return to shader part epilog
+ %result = call double @llvm.amdgcn.rcp.f64(double %src)
+ ret double %result
+}
+
; TODO: GlobalISel should generate v_s_rsq.
define amdgpu_cs float @v_s_rsq_f32(float inreg %src) {
; GFX12-SDAG-LABEL: v_s_rsq_f32:
@@ -197,6 +407,12 @@ define amdgpu_cs float @v_s_rsq_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_wait_alu depctr_va_sdst(0)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_rsq_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_sqrt_f32_e32 v0, s0
+; GCN-GISEL-NEXT: v_rcp_f32_e32 v0, v0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%sqrt = call fast float @llvm.sqrt.f32(float %src)
%fdiv = fdiv fast float 1.0, %sqrt
ret float %fdiv
@@ -215,6 +431,11 @@ define amdgpu_cs half @v_s_rsq_f16(half inreg %src) {
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: v_rsq_f16_e32 v0.l, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_rsq_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_rsq_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%sqrt = call fast half @llvm.sqrt.f16(half %src)
%result = fdiv fast half 1.0, %sqrt
ret half %result
@@ -292,6 +513,42 @@ define amdgpu_cs float @v_s_sqrt_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_sqrt_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0xf800000
+; GCN-GISEL-NEXT: v_cmp_lt_f32_e32 vcc, s0, v0
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0x4f800000
+; GCN-GISEL-NEXT: v_mul_f32_e32 v0, s0, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u64 vcc, 0
+; GCN-GISEL-NEXT: v_readfirstlane_b32 s2, v0
+; GCN-GISEL-NEXT: s_cselect_b32 s0, s2, s0
+; GCN-GISEL-NEXT: v_sqrt_f32_e32 v0, s0
+; GCN-GISEL-NEXT: s_cselect_b32 s1, 1, 0
+; GCN-GISEL-NEXT: v_readfirstlane_b32 s2, v0
+; GCN-GISEL-NEXT: s_add_i32 s3, s2, -1
+; GCN-GISEL-NEXT: v_mov_b32_e32 v1, s3
+; GCN-GISEL-NEXT: s_add_i32 s4, s2, 1
+; GCN-GISEL-NEXT: v_fma_f32 v1, -v1, v0, s0
+; GCN-GISEL-NEXT: v_mov_b32_e32 v2, s4
+; GCN-GISEL-NEXT: v_fma_f32 v0, -v2, v0, s0
+; GCN-GISEL-NEXT: v_cmp_ge_f32_e32 vcc, 0, v1
+; GCN-GISEL-NEXT: s_cmp_lg_u64 vcc, 0
+; GCN-GISEL-NEXT: v_cmp_lt_f32_e32 vcc, 0, v0
+; GCN-GISEL-NEXT: s_cselect_b32 s2, s3, s2
+; GCN-GISEL-NEXT: s_cmp_lg_u64 vcc, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s2, s4, s2
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0x37800000
+; GCN-GISEL-NEXT: v_mul_f32_e32 v0, s2, v0
+; GCN-GISEL-NEXT: v_readfirstlane_b32 s3, v0
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0x260
+; GCN-GISEL-NEXT: s_cmp_lg_u32 s1, 0
+; GCN-GISEL-NEXT: v_cmp_class_f32_e32 vcc, s0, v0
+; GCN-GISEL-NEXT: s_cselect_b32 s1, s3, s2
+; GCN-GISEL-NEXT: s_cmp_lg_u64 vcc, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s0, s0, s1
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.sqrt.f32(float %src)
ret float %result
}
@@ -304,6 +561,11 @@ define amdgpu_cs half @v_s_sqrt_f16(half inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_s_sqrt_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_sqrt_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.sqrt.f16(half %src)
ret half %result
}
@@ -316,6 +578,11 @@ define amdgpu_cs float @v_amdgcn_sqrt_f32(float inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_amdgcn_sqrt_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_sqrt_f32_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call float @llvm.amdgcn.sqrt.f32(float %src)
ret float %result
}
@@ -328,6 +595,11 @@ define amdgpu_cs half @v_amdgcn_sqrt_f16(half inreg %src) {
; GFX12-NEXT: s_delay_alu instid0(TRANS32_DEP_1)
; GFX12-NEXT: v_mov_b32_e32 v0, s0
; GFX12-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: v_amdgcn_sqrt_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_sqrt_f16_e32 v0, s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%result = call half @llvm.amdgcn.sqrt.f16(half %src)
ret half %result
}
@@ -370,6 +642,22 @@ define amdgpu_cs float @srcmods_abs_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: srcmods_abs_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0x800000
+; GCN-GISEL-NEXT: v_cmp_lt_f32_e64 s[2:3], |s0|, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u64 s[2:3], 0
+; GCN-GISEL-NEXT: s_cselect_b32 s2, 1, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s1, 1, 0
+; GCN-GISEL-NEXT: s_lshl_b32 s2, s2, 5
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, s2
+; GCN-GISEL-NEXT: v_ldexp_f32 v0, |s0|, v0
+; GCN-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u32 s1, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GCN-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%abs = call float @llvm.fabs.f32(float %src)
%result = call float @llvm.log2.f32(float %abs)
ret float %result
@@ -412,6 +700,22 @@ define amdgpu_cs float @srcmods_neg_f32(float inreg %src) {
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: srcmods_neg_f32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, 0x800000
+; GCN-GISEL-NEXT: v_cmp_lt_f32_e64 s[2:3], -s0, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u64 s[2:3], 0
+; GCN-GISEL-NEXT: s_cselect_b32 s2, 1, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s1, 1, 0
+; GCN-GISEL-NEXT: s_lshl_b32 s2, s2, 5
+; GCN-GISEL-NEXT: v_mov_b32_e32 v0, s2
+; GCN-GISEL-NEXT: v_ldexp_f32 v0, -s0, v0
+; GCN-GISEL-NEXT: v_log_f32_e32 v0, v0
+; GCN-GISEL-NEXT: s_cmp_lg_u32 s1, 0
+; GCN-GISEL-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GCN-GISEL-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%neg = fneg float %src
%result = call float @llvm.log2.f32(float %neg)
ret float %result
@@ -430,6 +734,11 @@ define amdgpu_cs half @srcmods_abs_f16(half inreg %src) {
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: v_log_f16_e64 v0.l, |s0|
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: srcmods_abs_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_log_f16_e64 v0, |s0|
+; GCN-GISEL-NEXT: ; return to shader part epilog
%abs = call half @llvm.fabs.f16(half %src)
%result = call half @llvm.log2.f16(half %abs)
ret half %result
@@ -448,6 +757,11 @@ define amdgpu_cs half @srcmods_neg_f16(half inreg %src) {
; GFX12-GISEL: ; %bb.0:
; GFX12-GISEL-NEXT: v_log_f16_e64 v0.l, -s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: srcmods_neg_f16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_log_f16_e64 v0, -s0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%neg = fneg half %src
%result = call half @llvm.log2.f16(half %neg)
ret half %result
@@ -473,6 +787,13 @@ define amdgpu_cs float @fdiv_f32_i32(float inreg %a, i32 inreg %b) {
; GFX12-GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_2)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: fdiv_f32_i32:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_cvt_f32_u32_e32 v0, s1
+; GCN-GISEL-NEXT: v_rcp_f32_e32 v0, v0
+; GCN-GISEL-NEXT: v_mul_f32_e32 v0, s0, v0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%uint = uitofp i32 %b to float
%result = fdiv afn float %a, %uint
ret float %result
@@ -499,6 +820,13 @@ define amdgpu_cs half @fdiv_f16_i16(half inreg %a, i16 inreg %b) {
; GFX12-GISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GISEL-NEXT: v_mov_b32_e32 v0, s0
; GFX12-GISEL-NEXT: ; return to shader part epilog
+;
+; GCN-GISEL-LABEL: fdiv_f16_i16:
+; GCN-GISEL: ; %bb.0:
+; GCN-GISEL-NEXT: v_cvt_f16_u16_e32 v0, s1
+; GCN-GISEL-NEXT: v_rcp_f16_e32 v0, v0
+; GCN-GISEL-NEXT: v_mul_f16_e32 v0, s0, v0
+; GCN-GISEL-NEXT: ; return to shader part epilog
%uint = uitofp i16 %b to half
%result = fdiv afn half %a, %uint
ret half %result
More information about the llvm-commits
mailing list