[llvm] [AMDGPU] Avoid width-32 V_BFE in GlobalISel (PR #215457)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 10 22:09:30 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Keshav Vinayak Jha (keshavvinayak01)
<details>
<summary>Changes</summary>
AMDGPU `V_BFE` masks its width operand to 5 bits, so selecting one with a width of 32 extracts zero bits. Reuse the shifted low half directly when legalizing 64-bit signed and unsigned extracts of width 32.
Assisted-by: Codex
---
Full diff: https://github.com/llvm/llvm-project/pull/215457.diff
5 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp (+5-1)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.sbfe.ll (-1)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.ubfe.ll (-1)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-sbfx.mir (+30)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/sbfx.ll (+16)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
index f03edccf9a132..b9be394862ae1 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp
@@ -752,7 +752,11 @@ bool RegBankLegalizeHelper::lowerV_BFE(MachineInstr &MI) {
if (WidthImm <= 32) {
// SHRSrc Hi|Lo: ????????|???syyyl -> ????????|ssssyyyl
- auto Lo = B.buildInstr(BFXOpc, {VgprRB_I32}, {SHRSrcLo, Zero, Width});
+ Register Lo = SHRSrcLo;
+ // V_BFE masks its width to 5 bits, so 32 would extract zero bits.
+ if (WidthImm < 32)
+ Lo =
+ B.buildInstr(BFXOpc, {VgprRB_I32}, {SHRSrcLo, Zero, Width}).getReg(0);
MachineInstrBuilder Hi;
if (Signed) {
// SHRSrc Hi|Lo: ????????|ssssyyyl -> ssssssss|ssssyyyl
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.sbfe.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.sbfe.ll
index 9427f329e5ffc..939633ba9c748 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.sbfe.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.sbfe.ll
@@ -41,7 +41,6 @@ define i64 @v_bfe_i64_arg_arg_imm_width_32(i64 %src0, i32 %src1) #0 {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_ashr_i64 v[0:1], v[0:1], v2
-; GFX6-NEXT: v_bfe_i32 v0, v0, 0, 32
; GFX6-NEXT: v_ashrrev_i32_e32 v1, 31, v0
; GFX6-NEXT: s_setpc_b64 s[30:31]
%bfe_i64 = call i64 @llvm.amdgcn.sbfe.i64(i64 %src0, i32 %src1, i32 32)
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.ubfe.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.ubfe.ll
index 380938ae41726..bec929f60d153 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.ubfe.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.ubfe.ll
@@ -42,7 +42,6 @@ define i64 @v_bfe_i64_arg_arg_imm_width_32(i64 %src0, i32 %src1) #0 {
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_lshr_b64 v[0:1], v[0:1], v2
; GFX6-NEXT: v_mov_b32_e32 v1, 0
-; GFX6-NEXT: v_bfe_u32 v0, v0, 0, 32
; GFX6-NEXT: s_setpc_b64 s[30:31]
%bfe_i64 = call i64 @llvm.amdgcn.ubfe.i64(i64 %src0, i32 %src1, i32 32)
ret i64 %bfe_i64
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-sbfx.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-sbfx.mir
index efa4bb891fefb..c77bdc4cb1b1a 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-sbfx.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-sbfx.mir
@@ -167,6 +167,36 @@ body: |
$vgpr0_vgpr1 = COPY %3(s64)
...
+---
+name: test_sbfx_s64_vii_32
+legalized: true
+
+body: |
+ bb.0.entry:
+ liveins: $vgpr0_vgpr1
+
+ ; CHECK-LABEL: name: test_sbfx_s64_vii_32
+ ; CHECK: liveins: $vgpr0_vgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:sgpr(s32) = G_CONSTANT i32 32
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY [[C]](s32)
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY [[C1]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:vgpr(i64) = G_ASHR [[COPY]], [[COPY1]](s32)
+ ; CHECK-NEXT: [[UV:%[0-9]+]]:vgpr(i32), [[UV1:%[0-9]+]]:vgpr(i32) = G_UNMERGE_VALUES [[ASHR]](i64)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:vgpr(i32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:vgpr(i32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:vgpr(i32) = G_ASHR [[UV]], [[C3]](i32)
+ ; CHECK-NEXT: [[MV:%[0-9]+]]:vgpr(s64) = G_MERGE_VALUES [[UV]](i32), [[ASHR1]](i32)
+ ; CHECK-NEXT: $vgpr0_vgpr1 = COPY [[MV]](s64)
+ %0:_(s64) = COPY $vgpr0_vgpr1
+ %1:_(s32) = G_CONSTANT i32 1
+ %2:_(s32) = G_CONSTANT i32 32
+ %3:_(s64) = G_SBFX %0, %1(s32), %2
+ $vgpr0_vgpr1 = COPY %3(s64)
+...
+
---
name: test_sbfx_s64_vii_big
legalized: true
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/sbfx.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/sbfx.ll
index c11ba7a3dcaea..91fecbce77b7c 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/sbfx.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/sbfx.ll
@@ -129,3 +129,19 @@ define amdgpu_ps i64 @s_ashr_i64(i64 inreg %value) {
%3 = ashr i64 %2, 60
ret i64 %3
}
+
+define i32 @v_lshr_trunc_sext_lshr_i64(i64 %value) {
+; GCN-LABEL: v_lshr_trunc_sext_lshr_i64:
+; GCN: ; %bb.0:
+; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT: v_ashrrev_i64 v[0:1], 1, v[0:1]
+; GCN-NEXT: v_ashrrev_i32_e32 v1, 31, v0
+; GCN-NEXT: v_lshrrev_b64 v[0:1], 1, v[0:1]
+; GCN-NEXT: s_setpc_b64 s[30:31]
+ %shift = lshr i64 %value, 1
+ %trunc = trunc i64 %shift to i32
+ %ext = sext i32 %trunc to i64
+ %result.wide = lshr i64 %ext, 1
+ %result = trunc i64 %result.wide to i32
+ ret i32 %result
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/215457
More information about the llvm-commits
mailing list