[llvm] [AMDGPU] Don't allow nesting hard clauses. (PR #188460)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 25 04:21:59 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: sstipano

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/188460.diff


2 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/SIInsertHardClauses.cpp (+14-1) 
- (added) llvm/test/CodeGen/AMDGPU/si-insert-hard-clauses-no-nesting.mir (+150) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/SIInsertHardClauses.cpp b/llvm/lib/Target/AMDGPU/SIInsertHardClauses.cpp
index 0a68512668c7d..af2020d4304e9 100644
--- a/llvm/lib/Target/AMDGPU/SIInsertHardClauses.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInsertHardClauses.cpp
@@ -209,8 +209,21 @@ class SIInsertHardClauses {
     bool Changed = false;
     for (auto &MBB : MF) {
       ClauseInfo CI;
+      unsigned ExistingClauseRemaining = 0;
       for (auto &MI : MBB) {
-        HardClauseType Type = getHardClauseType(MI);
+        HardClauseType Type;
+        if (ExistingClauseRemaining) {
+          if (!MI.isMetaInstruction())
+            ExistingClauseRemaining--;
+          Type = HARDCLAUSE_ILLEGAL;
+        } else if (MI.getOpcode() == AMDGPU::S_CLAUSE) {
+          // Respect existing explicit clauses. Re-clausing instructions that
+          // are already covered by an S_CLAUSE can create nested clauses.
+          ExistingClauseRemaining = (MI.getOperand(0).getImm() & 63) + 1;
+          Type = HARDCLAUSE_ILLEGAL;
+        } else {
+          Type = getHardClauseType(MI);
+        }
 
         int64_t Dummy1;
         bool Dummy2;
diff --git a/llvm/test/CodeGen/AMDGPU/si-insert-hard-clauses-no-nesting.mir b/llvm/test/CodeGen/AMDGPU/si-insert-hard-clauses-no-nesting.mir
new file mode 100644
index 0000000000000..e4e314b23dc76
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/si-insert-hard-clauses-no-nesting.mir
@@ -0,0 +1,150 @@
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -run-pass si-insert-hard-clauses %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1200 -verify-machineinstrs -run-pass si-insert-hard-clauses %s -o - | FileCheck %s
+
+---
+name: no_nested_clause_from_existing_clause
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $sgpr0_sgpr1
+    ; CHECK-LABEL: name: no_nested_clause_from_existing_clause
+    ; CHECK: liveins: $sgpr0_sgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit $sgpr0_sgpr1 {
+    ; CHECK-NEXT:   S_CLAUSE 1
+    ; CHECK-NEXT:   $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+    ; CHECK-NEXT:   KILL undef renamable $sgpr0
+    ; CHECK-NEXT:   $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+    ; CHECK-NEXT: }
+    ; CHECK-NOT: S_CLAUSE
+    ; CHECK: S_ENDPGM 0
+    BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit $sgpr0_sgpr1 {
+      S_CLAUSE 1
+      $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+      KILL undef renamable $sgpr0
+      $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+    }
+    S_ENDPGM 0
+...
+
+---
+name: no_nested_clause_longer_existing_clause
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $sgpr0_sgpr1
+    ; CHECK-LABEL: name: no_nested_clause_longer_existing_clause
+    ; CHECK: liveins: $sgpr0_sgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit-def $sgpr4, implicit $sgpr0_sgpr1 {
+    ; CHECK-NEXT:   S_CLAUSE 2
+    ; CHECK-NEXT:   $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+    ; CHECK-NEXT:   KILL undef renamable $sgpr0
+    ; CHECK-NEXT:   $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+    ; CHECK-NEXT:   KILL undef renamable $sgpr0
+    ; CHECK-NEXT:   $sgpr4 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 8, 0
+    ; CHECK-NEXT: }
+    ; CHECK-NOT: S_CLAUSE
+    ; CHECK: S_ENDPGM 0
+    BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit-def $sgpr4, implicit $sgpr0_sgpr1 {
+      S_CLAUSE 2
+      $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+      KILL undef renamable $sgpr0
+      $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+      KILL undef renamable $sgpr0
+      $sgpr4 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 8, 0
+    }
+    S_ENDPGM 0
+...
+
+---
+name: no_nested_clause_existing_flat_clause
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0_vgpr1
+    ; CHECK-LABEL: name: no_nested_clause_existing_flat_clause
+    ; CHECK: liveins: $vgpr0_vgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: BUNDLE implicit-def $vgpr2, implicit-def $vgpr3, implicit-def $vgpr4, implicit $vgpr0_vgpr1, implicit $exec, implicit $flat_scr {
+    ; CHECK-NEXT:   S_CLAUSE 2
+    ; CHECK-NEXT:   $vgpr2 = FLAT_LOAD_DWORD $vgpr0_vgpr1, 0, 0, implicit $exec, implicit $flat_scr
+    ; CHECK-NEXT:   $vgpr3 = FLAT_LOAD_DWORD $vgpr0_vgpr1, 4, 0, implicit $exec, implicit $flat_scr
+    ; CHECK-NEXT:   $vgpr4 = FLAT_LOAD_DWORD $vgpr0_vgpr1, 8, 0, implicit $exec, implicit $flat_scr
+    ; CHECK-NEXT: }
+    ; CHECK-NOT: S_CLAUSE
+    ; CHECK: S_ENDPGM 0
+    BUNDLE implicit-def $vgpr2, implicit-def $vgpr3, implicit-def $vgpr4, implicit $vgpr0_vgpr1, implicit $exec, implicit $flat_scr {
+      S_CLAUSE 2
+      $vgpr2 = FLAT_LOAD_DWORD $vgpr0_vgpr1, 0, 0, implicit $exec, implicit $flat_scr
+      $vgpr3 = FLAT_LOAD_DWORD $vgpr0_vgpr1, 4, 0, implicit $exec, implicit $flat_scr
+      $vgpr4 = FLAT_LOAD_DWORD $vgpr0_vgpr1, 8, 0, implicit $exec, implicit $flat_scr
+    }
+    S_ENDPGM 0
+...
+
+---
+name: no_nested_clause_but_new_clause_afterwards
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $sgpr0_sgpr1
+    ; CHECK-LABEL: name: no_nested_clause_but_new_clause_afterwards
+    ; CHECK: liveins: $sgpr0_sgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit $sgpr0_sgpr1 {
+    ; CHECK-NEXT:   S_CLAUSE 1
+    ; CHECK-NEXT:   $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+    ; CHECK-NEXT:   KILL undef renamable $sgpr0
+    ; CHECK-NEXT:   $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+    ; CHECK-NEXT: }
+    ; CHECK-NEXT: BUNDLE implicit-def $sgpr4, implicit-def $sgpr5, implicit $sgpr0_sgpr1 {
+    ; CHECK-NEXT:   S_CLAUSE 1
+    ; CHECK-NEXT:   $sgpr4 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 8, 0
+    ; CHECK-NEXT:   $sgpr5 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 12, 0
+    ; CHECK-NEXT: }
+    ; CHECK: S_ENDPGM 0
+    BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit $sgpr0_sgpr1 {
+      S_CLAUSE 1
+      $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+      KILL undef renamable $sgpr0
+      $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+    }
+    $sgpr4 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 8, 0
+    $sgpr5 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 12, 0
+    S_ENDPGM 0
+...
+
+---
+name: new_clause_after_existing_clause_with_gap
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $sgpr0_sgpr1
+    ; CHECK-LABEL: name: new_clause_after_existing_clause_with_gap
+    ; CHECK: liveins: $sgpr0_sgpr1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit $sgpr0_sgpr1 {
+    ; CHECK-NEXT:   S_CLAUSE 1
+    ; CHECK-NEXT:   $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+    ; CHECK-NEXT:   KILL undef renamable $sgpr0
+    ; CHECK-NEXT:   $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+    ; CHECK-NEXT: }
+    ; CHECK-NEXT: $sgpr6 = S_MOV_B32 0
+    ; CHECK-NEXT: BUNDLE implicit-def $sgpr4, implicit-def $sgpr5, implicit $sgpr0_sgpr1 {
+    ; CHECK-NEXT:   S_CLAUSE 1
+    ; CHECK-NEXT:   $sgpr4 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 8, 0
+    ; CHECK-NEXT:   $sgpr5 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 12, 0
+    ; CHECK-NEXT: }
+    ; CHECK: S_ENDPGM 0
+    BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit $sgpr0_sgpr1 {
+      S_CLAUSE 1
+      $sgpr2 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 0, 0
+      KILL undef renamable $sgpr0
+      $sgpr3 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 4, 0
+    }
+    $sgpr6 = S_MOV_B32 0
+    $sgpr4 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 8, 0
+    $sgpr5 = S_LOAD_DWORD_IMM $sgpr0_sgpr1, 12, 0
+    S_ENDPGM 0
+...

``````````

</details>


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


More information about the llvm-commits mailing list