[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