[llvm] [AMDGPU] SIFoldOperands: Add REQ_SEQUENCE subregister use fold (PR #188451)
Frederik Harwath via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 28 08:01:14 PDT 2026
================
@@ -0,0 +1,114 @@
+# NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -mcpu=gfx900 -start-before si-fold-operands -o - %s | FileCheck --check-prefix=GCN %s
+
+--- |
+ define amdgpu_kernel void @sdwa_reg_sequence_add_shr_i32() {
+ ; GCN-LABEL: sdwa_reg_sequence_add_shr_i32:
+ ; GCN: ; %bb.0:
+ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+ ; GCN-NEXT: flat_load_dword v2, v[2:3] glc
+ ; GCN-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)
+ ; GCN-NEXT: buffer_wbinvl1_vol
+ ; GCN-NEXT: v_mov_b32_e32 v3, 0x7b
+ ; GCN-NEXT: v_add_co_u32_sdwa v2, vcc, v3, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+ ; GCN-NEXT: flat_store_dword v[0:1], v2
+ ; GCN-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)
+ ; GCN-NEXT: s_setpc_b64 s[30:31]
+ ret void
+ }
+
+ define amdgpu_kernel void @sdwa_reg_sequence_and_add_co() {
+ ; GCN-LABEL: sdwa_reg_sequence_and_add_co:
+ ; GCN: ; %bb.0:
+ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+ ; GCN-NEXT: v_add_u32_e32 v1, 10, v0
+ ; GCN-NEXT: v_add_u32_e32 v0, 20, v0
+ ; GCN-NEXT: v_add_co_u32_sdwa v0, vcc, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_0
+ ; GCN-NEXT: v_addc_co_u32_e64 v1, s[0:1], 0, 0, vcc
+ ; GCN-NEXT: global_store_dwordx2 v[0:1], v[0:1], off
+ ; GCN-NEXT: s_endpgm
+ ret void
+ }
+
+ define amdgpu_kernel void @sdwa_reg_sequence_composed_subregs() {
+ ; GCN-LABEL: sdwa_reg_sequence_composed_subregs:
+ ; GCN: ; %bb.0:
+ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+ ; GCN-NEXT: v_add_u32_e32 v0, 20, v2
+ ; GCN-NEXT: v_mov_b32_e32 v1, 0
+ ; GCN-NEXT: v_add_co_u32_sdwa v0, vcc, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_0
+ ; GCN-NEXT: v_addc_co_u32_e64 v1, s[0:1], 0, 0, vcc
+ ; GCN-NEXT: global_store_dwordx2 v[0:1], v[0:1], off
+ ; GCN-NEXT: s_endpgm
+ ret void
+ }
+...
+
+---
+name: sdwa_reg_sequence_add_shr_i32
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $sgpr30_sgpr31
+
+ %0:vreg_64 = COPY $vgpr0_vgpr1
+ %1:vreg_64 = COPY $vgpr2_vgpr3
+ %2:sreg_64 = COPY $sgpr30_sgpr31
+ %3:vgpr_32 = FLAT_LOAD_DWORD %1, 0, 0, implicit $exec, implicit $flat_scr
+ %4:sreg_32_xm0 = S_MOV_B32 123
+ %5:vgpr_32 = V_LSHRREV_B32_e64 16, %3, implicit $exec
+ %6:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
+ %7:vreg_64 = REG_SEQUENCE %5, %subreg.sub0, %6, %subreg.sub1
+ %8:vgpr_32 = V_ADD_CO_U32_e32 %4, killed %7.sub0, implicit-def $vcc, implicit $exec
+ FLAT_STORE_DWORD %0, %8, 0, 0, implicit $exec, implicit $flat_scr
+ $sgpr30_sgpr31 = COPY %2
+ S_SETPC_B64_return $sgpr30_sgpr31
+...
+
+---
+name: sdwa_reg_sequence_and_add_co
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0
+
+ %0:vgpr_32 = COPY $vgpr0
+ %1:vgpr_32 = V_ADD_U32_e64 %0, 10, 0, implicit $exec
+ %2:vgpr_32 = V_ADD_U32_e64 %0, 20, 0, implicit $exec
+ %3:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
+ %4:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, %3, %subreg.sub1
+ %5:sreg_32 = S_MOV_B32 255
+ %6:vgpr_32 = V_AND_B32_e64 killed %2, killed %5, implicit $exec
+ %7:vreg_64 = REG_SEQUENCE %6, %subreg.sub0, %3, %subreg.sub1
+ %8:vgpr_32, %9:sreg_64_xexec = V_ADD_CO_U32_e64 %4.sub0, %7.sub0, 0, implicit $exec
+ %10:vgpr_32, dead %11:sreg_64_xexec = V_ADDC_U32_e64 0, 0, killed %9, 0, implicit $exec
----------------
frederik-h wrote:
> > In any case the correct solution looks like rewrite registers to avoid reg_sequences, not add additional logic in every pass to look at transitive users of reg_sequence
>
> That's a good point, I think. For some reason, there were many seemingly redundant REG_SEQUENCEs in another example I had right after DAG->DAG Isel. I have not looked further into that example.. yet..
I have a patch that adds a similar optimization (not integrated with the existing copy optimizations where it does not seem to fit in, but as an additional step) to the one from this PR to peephole-opt. That's probably desirable then? I noticed that the register pressure issue that we discussed elsewhere is essentially caused by returning subregister sources to the coalescable copy optimization for REG_SEQUENCES; see my draft PR #194628 .
https://github.com/llvm/llvm-project/pull/188451
More information about the llvm-commits
mailing list