[llvm] [AMDGPU] Post-RA Peephole for Two-Address Instructions (PR #207731)

Carl Ritson via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 15 00:04:43 PDT 2026


================
@@ -0,0 +1,124 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -run-pass=si-pre-emit-peephole -o - %s | FileCheck %s
+
+---
+name: fmac_f64_e32_return_copy
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0, $vgpr1
+
+    ; CHECK-LABEL: name: fmac_f64_e32_return_copy
+    ; CHECK: liveins: $vgpr0, $vgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: renamable $vgpr2_vgpr3 = nofpexcept V_RSQ_F64_e32 $vgpr0_vgpr1, implicit $mode, implicit $exec
+    ; CHECK-NEXT: renamable $vgpr4_vgpr5 = nofpexcept V_MUL_F64_e64 0, $vgpr2_vgpr3, 0, $vgpr0_vgpr1, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: renamable $vgpr0_vgpr1 = nofpexcept V_FMA_F64_e64 0, killed $vgpr0_vgpr1, 0, $vgpr2_vgpr3, 0, 4602678819172646912, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: $vgpr0_vgpr1 = nofpexcept V_FMA_F64_e64 0, killed $vgpr4_vgpr5, 0, killed $vgpr0_vgpr1, 0, killed $vgpr2_vgpr3, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: SI_RETURN implicit killed $vgpr0, implicit killed $vgpr1
+    renamable $vgpr2_vgpr3 = nofpexcept V_RSQ_F64_e32 $vgpr0_vgpr1, implicit $mode, implicit $exec
+    renamable $vgpr4_vgpr5 = nofpexcept V_MUL_F64_e64 0, $vgpr2_vgpr3, 0, $vgpr0_vgpr1, 0, 0, implicit $mode, implicit $exec
+    renamable $vgpr0_vgpr1 = nofpexcept V_FMA_F64_e64 0, killed $vgpr0_vgpr1, 0, $vgpr2_vgpr3, 0, 4602678819172646912, 0, 0, implicit $mode, implicit $exec
+    renamable $vgpr2_vgpr3 = nofpexcept V_FMAC_F64_e32 killed renamable $vgpr4_vgpr5, killed renamable $vgpr0_vgpr1, killed renamable $vgpr2_vgpr3, implicit $mode, implicit $exec
+    $vgpr0 = V_MOV_B32_e32 killed $vgpr2, implicit $exec, implicit $exec
+    $vgpr1 = V_MOV_B32_e32 killed $vgpr3, implicit $exec, implicit $exec
+    SI_RETURN implicit killed $vgpr0, implicit killed $vgpr1
+...
+
+---
+name: fmac_f64_e32_return_full_copy
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0, $vgpr1
+
+    ; CHECK-LABEL: name: fmac_f64_e32_return_full_copy
+    ; CHECK: liveins: $vgpr0, $vgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: renamable $vgpr2_vgpr3 = nofpexcept V_RSQ_F64_e32 $vgpr0_vgpr1, implicit $mode, implicit $exec
+    ; CHECK-NEXT: renamable $vgpr4_vgpr5 = nofpexcept V_MUL_F64_e64 0, $vgpr2_vgpr3, 0, $vgpr0_vgpr1, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: renamable $vgpr0_vgpr1 = nofpexcept V_FMA_F64_e64 0, killed $vgpr0_vgpr1, 0, $vgpr2_vgpr3, 0, 4602678819172646912, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: $vgpr0_vgpr1 = nofpexcept V_FMA_F64_e64 0, killed $vgpr4_vgpr5, 0, killed $vgpr0_vgpr1, 0, killed $vgpr2_vgpr3, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: SI_RETURN implicit killed $vgpr0, implicit killed $vgpr1
+    renamable $vgpr2_vgpr3 = nofpexcept V_RSQ_F64_e32 $vgpr0_vgpr1, implicit $mode, implicit $exec
+    renamable $vgpr4_vgpr5 = nofpexcept V_MUL_F64_e64 0, $vgpr2_vgpr3, 0, $vgpr0_vgpr1, 0, 0, implicit $mode, implicit $exec
+    renamable $vgpr0_vgpr1 = nofpexcept V_FMA_F64_e64 0, killed $vgpr0_vgpr1, 0, $vgpr2_vgpr3, 0, 4602678819172646912, 0, 0, implicit $mode, implicit $exec
+    renamable $vgpr2_vgpr3 = nofpexcept V_FMAC_F64_e32 killed renamable $vgpr4_vgpr5, killed renamable $vgpr0_vgpr1, killed renamable $vgpr2_vgpr3, implicit $mode, implicit $exec
+    $vgpr0_vgpr1 = V_MOV_B64_e32 killed $vgpr2_vgpr3, implicit $exec, implicit $exec
+    SI_RETURN implicit killed $vgpr0, implicit killed $vgpr1
+...
+
+---
+name: fmac_f32_e32_return_copy
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0
+
+    ; CHECK-LABEL: name: fmac_f32_e32_return_copy
+    ; CHECK: liveins: $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: renamable $vgpr2 = nofpexcept V_RSQ_F32_e32 $vgpr0, implicit $exec, implicit $mode
+    ; CHECK-NEXT: renamable $vgpr4 = nofpexcept V_MUL_F32_e64 0, $vgpr2, 0, $vgpr0, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: renamable $vgpr0 = nofpexcept V_FMA_F32_e64 0, killed $vgpr0, 0, $vgpr2, 0, 1056964608, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: $vgpr0 = nofpexcept V_FMA_F32_e64 0, killed $vgpr4, 0, killed $vgpr0, 0, killed $vgpr2, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: SI_RETURN implicit killed $vgpr0
+    renamable $vgpr2 = nofpexcept V_RSQ_F32_e32 $vgpr0, implicit $exec, implicit $mode
+    renamable $vgpr4 = nofpexcept V_MUL_F32_e64 0, $vgpr2, 0, $vgpr0, 0, 0, implicit $mode, implicit $exec
+    renamable $vgpr0 = nofpexcept V_FMA_F32_e64 0, killed $vgpr0, 0, $vgpr2, 0, 1056964608, 0, 0, implicit $mode, implicit $exec
+    renamable $vgpr2 = nofpexcept V_FMAC_F32_e32 killed renamable $vgpr4, killed renamable $vgpr0, killed renamable $vgpr2, implicit $mode, implicit $exec
+    $vgpr0 = V_MOV_B32_e32 killed $vgpr2, implicit $exec, implicit $exec
+    SI_RETURN implicit killed $vgpr0
+...
+
+---
+name: mac_f32_e32_return_copy
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0, $vgpr2, $vgpr4
+
+    ; CHECK-LABEL: name: mac_f32_e32_return_copy
+    ; CHECK: liveins: $vgpr0, $vgpr2, $vgpr4
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $vgpr1 = V_MOV_B32_e32 $vgpr0, implicit $exec
+    ; CHECK-NEXT: $vgpr1 = nofpexcept V_MAD_F32_e64 0, killed $vgpr4, 0, killed $vgpr0, 0, killed $vgpr2, 0, 0, implicit $mode, implicit $exec
+    ; CHECK-NEXT: S_ENDPGM 0, implicit killed $vgpr1
+    $vgpr1 = V_MOV_B32_e32 $vgpr0, implicit $exec
+    $vgpr2 = nofpexcept V_MAC_F32_e32 killed $vgpr4, killed $vgpr0, killed $vgpr2, implicit $mode, implicit $exec
+    $vgpr1 = V_MOV_B32_e32 killed $vgpr2, implicit $exec
+    S_ENDPGM 0, implicit killed $vgpr1
+...
+
+---
+name: fmac_f32_e32_copy_live_out
+tracksRegLiveness: true
+body: |
+  ; CHECK-LABEL: name: fmac_f32_e32_copy_live_out
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0, $vgpr2, $vgpr4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr2 = nofpexcept V_FMAC_F32_e32 killed $vgpr4, killed $vgpr0, killed $vgpr2, implicit $mode, implicit $exec
+  ; CHECK-NEXT:   $vgpr0 = V_MOV_B32_e32 $vgpr2, implicit $exec, implicit $exec
+  ; CHECK-NEXT:   S_BRANCH %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   liveins: $vgpr2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   SI_RETURN implicit killed $vgpr2
+  ; Negative test to check the peephole doesn't apply if the original
+  ; destination register is live out of the block.
+  bb.0:
+    liveins: $vgpr0, $vgpr2, $vgpr4
+    successors: %bb.1
+
+    renamable $vgpr2 = nofpexcept V_FMAC_F32_e32 killed renamable $vgpr4, killed renamable $vgpr0, killed renamable $vgpr2, implicit $mode, implicit $exec
+    $vgpr0 = V_MOV_B32_e32 $vgpr2, implicit $exec, implicit $exec
+    S_BRANCH %bb.1
+
+  bb.1:
+    liveins: $vgpr2
+
+    SI_RETURN implicit killed $vgpr2
+...
----------------
perlfu wrote:

Probably need one or more tests on odd subregister usage?

https://github.com/llvm/llvm-project/pull/207731


More information about the llvm-commits mailing list