[llvm] [AMDGPU] Fix set_inactive known bits to intersect both operands (PR #201817)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 5 07:52:01 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/201817
>From cc8d205e82655453848aea251409379af6ba0a91 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 5 Jun 2026 13:47:51 +0200
Subject: [PATCH 1/2] [AMDGPU] Fix set_inactive known bits to intersect both
operands
SimplifyDemandedBitsForTargetNode grouped amdgcn_set_inactive with the single-source readfirstlane/readlane/wwm, taking known bits from operand 1 only
Handle the data from the operand 2 inactive lanes as well
---
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 17 +++++++++++-
.../AMDGPU/llvm.amdgcn.set.inactive.ll | 27 +++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 78fcd0fd24b6f..675bc06253526 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -5848,13 +5848,28 @@ bool AMDGPUTargetLowering::SimplifyDemandedBitsForTargetNode(
switch (Op.getConstantOperandVal(0)) {
case Intrinsic::amdgcn_readfirstlane:
case Intrinsic::amdgcn_readlane:
- case Intrinsic::amdgcn_set_inactive:
case Intrinsic::amdgcn_wwm: {
if (SimplifyDemandedBits(Op.getOperand(1), OriginalDemandedBits,
OriginalDemandedElts, Known, TLO, Depth + 1))
return true;
break;
}
+ case Intrinsic::amdgcn_set_inactive:
+ case Intrinsic::amdgcn_set_inactive_chain_arg: {
+ // The result is operand 1 in active lanes and operand 2 in inactive
+ // lanes, so the known bits are the intersection of both operands.
+ KnownBits KnownValue, KnownInactive;
+ if (SimplifyDemandedBits(Op.getOperand(1), OriginalDemandedBits,
+ OriginalDemandedElts, KnownValue, TLO,
+ Depth + 1))
+ return true;
+ if (SimplifyDemandedBits(Op.getOperand(2), OriginalDemandedBits,
+ OriginalDemandedElts, KnownInactive, TLO,
+ Depth + 1))
+ return true;
+ Known = KnownValue.intersectWith(KnownInactive);
+ break;
+ }
default:
break;
}
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll
index ce03681f2eca8..965903b3c3d57 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll
@@ -504,6 +504,33 @@ define amdgpu_kernel void @set_inactive_p6(ptr addrspace(1) %out, ptr addrspace(
ret void
}
+; The result of set_inactive with a constant value operand must not be
+; constant-folded away: SimplifyDemandedBits must intersect the known bits of
+; both operands, so the inactive value (0x55555555) is preserved through the
+; demanded-bits mask.
+define amdgpu_kernel void @set_inactive_const_value_demanded(ptr addrspace(1) %out) {
+; GCN-LABEL: set_inactive_const_value_demanded:
+; GCN: ; %bb.0:
+; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
+; GCN-NEXT: s_mov_b32 s3, 0xf000
+; GCN-NEXT: s_mov_b32 s2, -1
+; GCN-NEXT: v_mov_b32_e32 v1, 0xaaaaaaaa
+; GCN-NEXT: s_or_saveexec_b64 s[4:5], -1
+; GCN-NEXT: v_mov_b32_e32 v0, 0x55555555
+; GCN-NEXT: v_cndmask_b32_e64 v0, v0, v1, s[4:5]
+; GCN-NEXT: v_and_b32_e32 v0, 0xffff, v0
+; GCN-NEXT: s_mov_b64 exec, s[4:5]
+; GCN-NEXT: v_mov_b32_e32 v1, v0
+; GCN-NEXT: s_waitcnt lgkmcnt(0)
+; GCN-NEXT: buffer_store_dword v1, off, s[0:3], 0
+; GCN-NEXT: s_endpgm
+ %tmp.0 = call i32 @llvm.amdgcn.set.inactive.i32(i32 -1431655766, i32 1431655765) #0
+ %and = and i32 %tmp.0, 65535
+ %tmp = call i32 @llvm.amdgcn.strict.wwm.i32(i32 %and)
+ store i32 %tmp, ptr addrspace(1) %out
+ ret void
+}
+
declare i32 @llvm.amdgcn.set.inactive.i32(i32, i32) #0
declare i64 @llvm.amdgcn.set.inactive.i64(i64, i64) #0
declare i32 @llvm.amdgcn.strict.wwm.i32(i32) #1
>From 123b085fcd03a1f628aeb3f88912250a45f36eeb Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 5 Jun 2026 16:51:50 +0200
Subject: [PATCH 2/2] test
---
llvm/test/CodeGen/AMDGPU/fix-wwm-vgpr-copy.ll | 50 +++++++++++--------
1 file changed, 28 insertions(+), 22 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/fix-wwm-vgpr-copy.ll b/llvm/test/CodeGen/AMDGPU/fix-wwm-vgpr-copy.ll
index 3339b85c1bf75..c1b9e51ac8438 100644
--- a/llvm/test/CodeGen/AMDGPU/fix-wwm-vgpr-copy.ll
+++ b/llvm/test/CodeGen/AMDGPU/fix-wwm-vgpr-copy.ll
@@ -6,24 +6,27 @@
define amdgpu_hs void @wwm(i32 inreg %arg, ptr addrspace(8) inreg %buffer) {
; GCN-LABEL: wwm:
; GCN: ; %bb.0: ; %entry
-; GCN-NEXT: s_mov_b32 s7, s4
-; GCN-NEXT: s_mov_b32 s4, s1
-; GCN-NEXT: s_mov_b32 s1, 16
; GCN-NEXT: s_mov_b32 s6, s3
; GCN-NEXT: s_mov_b32 s5, s2
-; GCN-NEXT: v_mov_b32_e32 v0, s1
+; GCN-NEXT: s_or_saveexec_b64 s[2:3], -1
+; GCN-NEXT: s_mov_b32 s7, s4
+; GCN-NEXT: s_mov_b32 s4, s1
+; GCN-NEXT: s_mov_b32 s1, 1
+; GCN-NEXT: v_cndmask_b32_e64 v0, 1, 4, s[2:3]
+; GCN-NEXT: v_lshlrev_b32_e32 v0, 2, v0
+; GCN-NEXT: s_mov_b64 exec, s[2:3]
; GCN-NEXT: s_cmp_lg_u32 s0, 0
-; GCN-NEXT: s_mov_b32 s0, 0
-; GCN-NEXT: s_cbranch_scc1 .LBB0_2
-; GCN-NEXT: ; %bb.1:
-; GCN-NEXT: s_mov_b32 s0, 1
+; GCN-NEXT: v_mov_b32_e32 v1, v0
+; GCN-NEXT: s_cbranch_scc0 .LBB0_2
+; GCN-NEXT: ; %bb.1: ; %bb42
+; GCN-NEXT: s_mov_b32 s1, 0
; GCN-NEXT: .LBB0_2: ; %bb602
-; GCN-NEXT: v_cmp_eq_u32_e32 vcc, s0, v0
+; GCN-NEXT: v_cmp_eq_u32_e32 vcc, s1, v1
; GCN-NEXT: s_and_saveexec_b64 s[0:1], vcc
; GCN-NEXT: s_cbranch_execz .LBB0_4
; GCN-NEXT: ; %bb.3: ; %bb49
-; GCN-NEXT: v_mov_b32_e32 v0, 1.0
-; GCN-NEXT: tbuffer_store_format_x v0, off, s[4:7], 1 format:[BUF_DATA_FORMAT_32,BUF_NUM_FORMAT_FLOAT] offset:4 glc
+; GCN-NEXT: v_mov_b32_e32 v1, 1.0
+; GCN-NEXT: tbuffer_store_format_x v1, off, s[4:7], 1 format:[BUF_DATA_FORMAT_32,BUF_NUM_FORMAT_FLOAT] offset:4 glc
; GCN-NEXT: .LBB0_4: ; %UnifiedReturnBlock
; GCN-NEXT: s_endpgm
entry:
@@ -58,24 +61,27 @@ work:
define amdgpu_hs void @strict_wwm(i32 inreg %arg, ptr addrspace(8) inreg %buffer) {
; GCN-LABEL: strict_wwm:
; GCN: ; %bb.0: ; %entry
-; GCN-NEXT: s_mov_b32 s7, s4
-; GCN-NEXT: s_mov_b32 s4, s1
-; GCN-NEXT: s_mov_b32 s1, 16
; GCN-NEXT: s_mov_b32 s6, s3
; GCN-NEXT: s_mov_b32 s5, s2
-; GCN-NEXT: v_mov_b32_e32 v0, s1
+; GCN-NEXT: s_or_saveexec_b64 s[2:3], -1
+; GCN-NEXT: s_mov_b32 s7, s4
+; GCN-NEXT: s_mov_b32 s4, s1
+; GCN-NEXT: s_mov_b32 s1, 1
+; GCN-NEXT: v_cndmask_b32_e64 v0, 1, 4, s[2:3]
+; GCN-NEXT: v_lshlrev_b32_e32 v0, 2, v0
+; GCN-NEXT: s_mov_b64 exec, s[2:3]
; GCN-NEXT: s_cmp_lg_u32 s0, 0
-; GCN-NEXT: s_mov_b32 s0, 0
-; GCN-NEXT: s_cbranch_scc1 .LBB1_2
-; GCN-NEXT: ; %bb.1:
-; GCN-NEXT: s_mov_b32 s0, 1
+; GCN-NEXT: v_mov_b32_e32 v1, v0
+; GCN-NEXT: s_cbranch_scc0 .LBB1_2
+; GCN-NEXT: ; %bb.1: ; %bb42
+; GCN-NEXT: s_mov_b32 s1, 0
; GCN-NEXT: .LBB1_2: ; %bb602
-; GCN-NEXT: v_cmp_eq_u32_e32 vcc, s0, v0
+; GCN-NEXT: v_cmp_eq_u32_e32 vcc, s1, v1
; GCN-NEXT: s_and_saveexec_b64 s[0:1], vcc
; GCN-NEXT: s_cbranch_execz .LBB1_4
; GCN-NEXT: ; %bb.3: ; %bb49
-; GCN-NEXT: v_mov_b32_e32 v0, 1.0
-; GCN-NEXT: tbuffer_store_format_x v0, off, s[4:7], 1 format:[BUF_DATA_FORMAT_32,BUF_NUM_FORMAT_FLOAT] offset:4 glc
+; GCN-NEXT: v_mov_b32_e32 v1, 1.0
+; GCN-NEXT: tbuffer_store_format_x v1, off, s[4:7], 1 format:[BUF_DATA_FORMAT_32,BUF_NUM_FORMAT_FLOAT] offset:4 glc
; GCN-NEXT: .LBB1_4: ; %UnifiedReturnBlock
; GCN-NEXT: s_endpgm
entry:
More information about the llvm-commits
mailing list