[llvm] [AMDGPU] Improve SelectionDAG codegen around barrier intrinsics (PR #207688)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 6 02:51:31 PDT 2026


https://github.com/jayfoad updated https://github.com/llvm/llvm-project/pull/207688

>From c1c68d7c560e4de50636f5283085b5f470c6aba1 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.foad at amd.com>
Date: Mon, 6 Jul 2026 10:38:33 +0100
Subject: [PATCH] [AMDGPU] Improve SelectionDAG codegen around barrier
 intrinsics

When lowering some intrinsics use generic AND/OR nodes instead of
specific machine instructions. This allows DAG combines and ISel to
select better instructions like S_BFE_U32.
---
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     | 33 +++++----------
 .../lds-link-time-codegen-named-barrier.ll    |  2 +-
 .../AMDGPU/s-barrier-signal-var-gep.ll        | 30 ++++++-------
 llvm/test/CodeGen/AMDGPU/s-barrier.ll         | 42 ++++++++++++-------
 llvm/test/CodeGen/AMDGPU/s-wakeup-barrier.ll  |  4 +-
 5 files changed, 52 insertions(+), 59 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 8a8a3b97e8e08..9b4b3ada342fe 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -12004,10 +12004,8 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
         SDValue M0Val;
         M0Val = DAG.getNode(ISD::SRL, DL, MVT::i32, Op->getOperand(2),
                             DAG.getShiftAmountConstant(4, MVT::i32, DL));
-        M0Val = SDValue(
-            DAG.getMachineNode(AMDGPU::S_AND_B32, DL, MVT::i32, M0Val,
-                               DAG.getTargetConstant(0x3F, DL, MVT::i32)),
-            0);
+        M0Val = DAG.getNode(ISD::AND, DL, MVT::i32, M0Val,
+                            DAG.getConstant(0x3F, DL, MVT::i32));
         Ops.push_back(copyToM0(DAG, Chain, DL, M0Val).getValue(0));
       } else
         Ops.push_back(copyToM0(DAG, Chain, DL, Op->getOperand(2)).getValue(0));
@@ -12644,22 +12642,17 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
     SDValue BarID;
     BarID = DAG.getNode(ISD::SRL, DL, MVT::i32, BarOp,
                         DAG.getShiftAmountConstant(4, MVT::i32, DL));
-    BarID =
-        SDValue(DAG.getMachineNode(AMDGPU::S_AND_B32, DL, MVT::i32, BarID,
-                                   DAG.getTargetConstant(0x3F, DL, MVT::i32)),
-                0);
+    BarID = DAG.getNode(ISD::AND, DL, MVT::i32, BarID,
+                        DAG.getConstant(0x3F, DL, MVT::i32));
     // Member count should be put into M0[ShAmt:+6]
     // Barrier ID should be put into M0[5:0]
-    M0Val =
-        SDValue(DAG.getMachineNode(AMDGPU::S_AND_B32, DL, MVT::i32, CntOp,
-                                   DAG.getTargetConstant(0x3F, DL, MVT::i32)),
-                0);
+    M0Val = DAG.getNode(ISD::AND, DL, MVT::i32, CntOp,
+                        DAG.getConstant(0x3F, DL, MVT::i32));
     constexpr unsigned ShAmt = 16;
     M0Val = DAG.getNode(ISD::SHL, DL, MVT::i32, CntOp,
                         DAG.getShiftAmountConstant(ShAmt, MVT::i32, DL));
 
-    M0Val = SDValue(
-        DAG.getMachineNode(AMDGPU::S_OR_B32, DL, MVT::i32, M0Val, BarID), 0);
+    M0Val = DAG.getNode(ISD::OR, DL, MVT::i32, M0Val, BarID);
 
     Ops.push_back(copyToM0(DAG, Chain, DL, M0Val).getValue(0));
 
@@ -12710,10 +12703,8 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
       SDValue M0Val;
       M0Val = DAG.getNode(ISD::SRL, DL, MVT::i32, BarOp,
                           DAG.getShiftAmountConstant(4, MVT::i32, DL));
-      M0Val =
-          SDValue(DAG.getMachineNode(AMDGPU::S_AND_B32, DL, MVT::i32, M0Val,
-                                     DAG.getTargetConstant(0x3F, DL, MVT::i32)),
-                  0);
+      M0Val = DAG.getNode(ISD::AND, DL, MVT::i32, M0Val,
+                          DAG.getConstant(0x3F, DL, MVT::i32));
       Ops.push_back(copyToM0(DAG, Chain, DL, M0Val).getValue(0));
     }
 
@@ -19260,10 +19251,8 @@ MachineSDNode *SITargetLowering::buildRSRC(SelectionDAG &DAG, const SDLoc &DL,
   SDValue PtrLo = DAG.getTargetExtractSubreg(AMDGPU::sub0, DL, MVT::i32, Ptr);
   SDValue PtrHi = DAG.getTargetExtractSubreg(AMDGPU::sub1, DL, MVT::i32, Ptr);
   if (RsrcDword1) {
-    PtrHi =
-        SDValue(DAG.getMachineNode(AMDGPU::S_OR_B32, DL, MVT::i32, PtrHi,
-                                   DAG.getConstant(RsrcDword1, DL, MVT::i32)),
-                0);
+    PtrHi = DAG.getNode(ISD::OR, DL, MVT::i32, PtrHi,
+                        DAG.getConstant(RsrcDword1, DL, MVT::i32));
   }
 
   SDValue DataLo =
diff --git a/llvm/test/CodeGen/AMDGPU/lds-link-time-codegen-named-barrier.ll b/llvm/test/CodeGen/AMDGPU/lds-link-time-codegen-named-barrier.ll
index f573a3180c067..a4acd4a1d646d 100644
--- a/llvm/test/CodeGen/AMDGPU/lds-link-time-codegen-named-barrier.ll
+++ b/llvm/test/CodeGen/AMDGPU/lds-link-time-codegen-named-barrier.ll
@@ -10,7 +10,7 @@
 @bar = internal addrspace(3) global [2 x target("amdgcn.named.barrier", 0)] poison
 
 ; CHECK-LABEL: kernel:
-; CHECK: s_lshr_b32 s{{[0-9]+}}, __amdgpu_named_barrier.bar{{[^ @]*}}@abs32 at lo, 4
+; CHECK: s_mov_b32 s{{[0-9]+}}, __amdgpu_named_barrier.bar{{[^ @]*}}@abs32 at lo
 ; CHECK: s_barrier_join m0
 ; CHECK: s_barrier_signal m0
 ; CHECK: s_barrier_wait 1
diff --git a/llvm/test/CodeGen/AMDGPU/s-barrier-signal-var-gep.ll b/llvm/test/CodeGen/AMDGPU/s-barrier-signal-var-gep.ll
index f5bbefbe8da9f..e8b7f32c5fc89 100644
--- a/llvm/test/CodeGen/AMDGPU/s-barrier-signal-var-gep.ll
+++ b/llvm/test/CodeGen/AMDGPU/s-barrier-signal-var-gep.ll
@@ -25,10 +25,10 @@ define amdgpu_kernel void @signal_var_bar0() {
 ; CHECK-OBJ-SDAG-LABEL: signal_var_bar0:
 ; CHECK-OBJ-SDAG:       ; %bb.0:
 ; CHECK-OBJ-SDAG-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
-; CHECK-OBJ-SDAG-NEXT:    s_lshr_b32 s0, __amdgpu_named_barrier.bars.5a19a560517f8a3a4347b4502da34a70 at abs32@lo, 4
+; CHECK-OBJ-SDAG-NEXT:    s_mov_b32 s0, __amdgpu_named_barrier.bars.5a19a560517f8a3a4347b4502da34a70 at abs32@lo
 ; CHECK-OBJ-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; CHECK-OBJ-SDAG-NEXT:    s_and_b32 s0, s0, 63
-; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, 0x100000, s0
+; CHECK-OBJ-SDAG-NEXT:    s_bfe_u32 s0, s0, 0x60004
+; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, s0, 0x100000
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_init m0
 ; CHECK-OBJ-SDAG-NEXT:    s_mov_b32 m0, s0
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_signal m0
@@ -66,10 +66,10 @@ define amdgpu_kernel void @signal_var_bar1() {
 ; CHECK-OBJ-SDAG-LABEL: signal_var_bar1:
 ; CHECK-OBJ-SDAG:       ; %bb.0:
 ; CHECK-OBJ-SDAG-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
-; CHECK-OBJ-SDAG-NEXT:    s_lshr_b32 s0, __amdgpu_named_barrier.bars.5a19a560517f8a3a4347b4502da34a70 at abs32@lo+16, 4
+; CHECK-OBJ-SDAG-NEXT:    s_mov_b32 s0, __amdgpu_named_barrier.bars.5a19a560517f8a3a4347b4502da34a70 at abs32@lo+16
 ; CHECK-OBJ-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; CHECK-OBJ-SDAG-NEXT:    s_and_b32 s0, s0, 63
-; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, 0x100000, s0
+; CHECK-OBJ-SDAG-NEXT:    s_bfe_u32 s0, s0, 0x60004
+; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, s0, 0x100000
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_init m0
 ; CHECK-OBJ-SDAG-NEXT:    s_mov_b32 m0, s0
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_signal m0
@@ -114,10 +114,10 @@ define amdgpu_kernel void @signal_var_misaligned() {
 ; CHECK-OBJ-SDAG-LABEL: signal_var_misaligned:
 ; CHECK-OBJ-SDAG:       ; %bb.0:
 ; CHECK-OBJ-SDAG-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
-; CHECK-OBJ-SDAG-NEXT:    s_lshr_b32 s0, __amdgpu_named_barrier.bars.5a19a560517f8a3a4347b4502da34a70 at abs32@lo+1, 4
+; CHECK-OBJ-SDAG-NEXT:    s_mov_b32 s0, __amdgpu_named_barrier.bars.5a19a560517f8a3a4347b4502da34a70 at abs32@lo+1
 ; CHECK-OBJ-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; CHECK-OBJ-SDAG-NEXT:    s_and_b32 s0, s0, 63
-; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, 0x100000, s0
+; CHECK-OBJ-SDAG-NEXT:    s_bfe_u32 s0, s0, 0x60004
+; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, s0, 0x100000
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_init m0
 ; CHECK-OBJ-SDAG-NEXT:    s_mov_b32 m0, s0
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_signal m0
@@ -157,10 +157,8 @@ define amdgpu_kernel void @signal_var_dynamic(i32 %idx) {
 ; CHECK-SDAG-NEXT:    s_wait_kmcnt 0x0
 ; CHECK-SDAG-NEXT:    s_lshl4_add_u32 s0, s0, 0x802010
 ; CHECK-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; CHECK-SDAG-NEXT:    s_lshr_b32 s0, s0, 4
-; CHECK-SDAG-NEXT:    s_and_b32 s0, s0, 63
-; CHECK-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
-; CHECK-SDAG-NEXT:    s_or_b32 m0, 0x100000, s0
+; CHECK-SDAG-NEXT:    s_bfe_u32 s0, s0, 0x60004
+; CHECK-SDAG-NEXT:    s_or_b32 m0, s0, 0x100000
 ; CHECK-SDAG-NEXT:    s_barrier_init m0
 ; CHECK-SDAG-NEXT:    s_mov_b32 m0, s0
 ; CHECK-SDAG-NEXT:    s_barrier_signal m0
@@ -192,10 +190,8 @@ define amdgpu_kernel void @signal_var_dynamic(i32 %idx) {
 ; CHECK-OBJ-SDAG-NEXT:    s_wait_kmcnt 0x0
 ; CHECK-OBJ-SDAG-NEXT:    s_lshl4_add_u32 s0, s0, __amdgpu_named_barrier.bars.5a19a560517f8a3a4347b4502da34a70 at abs32@lo
 ; CHECK-OBJ-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; CHECK-OBJ-SDAG-NEXT:    s_lshr_b32 s0, s0, 4
-; CHECK-OBJ-SDAG-NEXT:    s_and_b32 s0, s0, 63
-; CHECK-OBJ-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
-; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, 0x100000, s0
+; CHECK-OBJ-SDAG-NEXT:    s_bfe_u32 s0, s0, 0x60004
+; CHECK-OBJ-SDAG-NEXT:    s_or_b32 m0, s0, 0x100000
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_init m0
 ; CHECK-OBJ-SDAG-NEXT:    s_mov_b32 m0, s0
 ; CHECK-OBJ-SDAG-NEXT:    s_barrier_signal m0
diff --git a/llvm/test/CodeGen/AMDGPU/s-barrier.ll b/llvm/test/CodeGen/AMDGPU/s-barrier.ll
index f9af6dfc870df..a15c31703f814 100644
--- a/llvm/test/CodeGen/AMDGPU/s-barrier.ll
+++ b/llvm/test/CodeGen/AMDGPU/s-barrier.ll
@@ -85,10 +85,9 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-SDAG-NEXT:    s_mov_b64 s[4:5], s[0:1]
 ; GFX12-SDAG-NEXT:    s_mov_b32 s32, 0
 ; GFX12-SDAG-NEXT:    s_wait_kmcnt 0x0
-; GFX12-SDAG-NEXT:    s_lshr_b32 s2, s2, 4
-; GFX12-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; GFX12-SDAG-NEXT:    s_and_b32 s2, s2, 63
-; GFX12-SDAG-NEXT:    s_or_b32 s3, 0x90000, s2
+; GFX12-SDAG-NEXT:    s_bfe_u32 s2, s2, 0x60004
+; GFX12-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX12-SDAG-NEXT:    s_or_b32 s3, s2, 0x90000
 ; GFX12-SDAG-NEXT:    s_cmp_eq_u32 0, 0
 ; GFX12-SDAG-NEXT:    s_mov_b32 m0, s3
 ; GFX12-SDAG-NEXT:    s_barrier_init m0
@@ -273,18 +272,29 @@ define void @signal_var_cnt0_const_bar() {
 }
 
 define void @signal_var_cnt0_dynamic_bar(ptr addrspace(3) inreg %bar) {
-; GFX12-LABEL: signal_var_cnt0_dynamic_bar:
-; 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:    s_lshr_b32 s0, s0, 4
-; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
-; GFX12-NEXT:    s_and_b32 m0, s0, 63
-; GFX12-NEXT:    s_barrier_signal m0
-; GFX12-NEXT:    s_setpc_b64 s[30:31]
+; GFX12-SDAG-LABEL: signal_var_cnt0_dynamic_bar:
+; GFX12-SDAG:       ; %bb.0:
+; GFX12-SDAG-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-SDAG-NEXT:    s_wait_expcnt 0x0
+; GFX12-SDAG-NEXT:    s_wait_samplecnt 0x0
+; GFX12-SDAG-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-SDAG-NEXT:    s_wait_kmcnt 0x0
+; GFX12-SDAG-NEXT:    s_bfe_u32 m0, s0, 0x60004
+; GFX12-SDAG-NEXT:    s_barrier_signal m0
+; GFX12-SDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-GISEL-LABEL: signal_var_cnt0_dynamic_bar:
+; GFX12-GISEL:       ; %bb.0:
+; GFX12-GISEL-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-GISEL-NEXT:    s_wait_expcnt 0x0
+; GFX12-GISEL-NEXT:    s_wait_samplecnt 0x0
+; GFX12-GISEL-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-GISEL-NEXT:    s_wait_kmcnt 0x0
+; GFX12-GISEL-NEXT:    s_lshr_b32 s0, s0, 4
+; GFX12-GISEL-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-GISEL-NEXT:    s_and_b32 m0, s0, 63
+; GFX12-GISEL-NEXT:    s_barrier_signal m0
+; GFX12-GISEL-NEXT:    s_setpc_b64 s[30:31]
     call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) %bar, i32 0)
     ret void
 }
diff --git a/llvm/test/CodeGen/AMDGPU/s-wakeup-barrier.ll b/llvm/test/CodeGen/AMDGPU/s-wakeup-barrier.ll
index bc995f4738af8..0b907ebfc1ed1 100644
--- a/llvm/test/CodeGen/AMDGPU/s-wakeup-barrier.ll
+++ b/llvm/test/CodeGen/AMDGPU/s-wakeup-barrier.ll
@@ -12,9 +12,7 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX1250-SDAG-NEXT:    s_mov_b32 m0, 1
 ; GFX1250-SDAG-NEXT:    s_wakeup_barrier m0
 ; GFX1250-SDAG-NEXT:    s_wait_kmcnt 0x0
-; GFX1250-SDAG-NEXT:    s_lshr_b32 s0, s0, 4
-; GFX1250-SDAG-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
-; GFX1250-SDAG-NEXT:    s_and_b32 m0, s0, 63
+; GFX1250-SDAG-NEXT:    s_bfe_u32 m0, s0, 0x60004
 ; GFX1250-SDAG-NEXT:    s_wakeup_barrier m0
 ; GFX1250-SDAG-NEXT:    s_endpgm
 ;



More information about the llvm-commits mailing list