Repository: llvm/llvm-project
Pull request #134487: [AMDGPU] Set hasSideEffects=0 for SALU psuedos
Author: login: amansharma612
Labels: name: backend:AMDGPU
Created: 2025-04-05T08:35:46Z | Merged: 2025-04-11T15:35:01Z

Fixes #128685


Linked issue #128685: AMDGPU SALU pseudos should not have side effects
The following pseudos do not have an explicit `hasSideEffects = 0` in the *.td files, so the MCInstrs are marked as `MCID::UnmodeledSideEffects`:
```
S_ADD_CO_PSEUDO
S_MUL_I64_I32_PSEUDO
S_MUL_U64_U32_PSEUDO
S_SUB_CO_PSEUDO
S_UADDO_PSEUDO
S_USUBO_PSEUDO
```
These are all regular ALU operations without side effects.
Linked issue comments: user: login: llvmbot
created_at: 2025-02-25T09:49:23Z
body: 
@llvm/issue-subscribers-backend-amdgpu

Author: Jay Foad (jayfoad)

<details>
The following pseudos do not have an explicit `hasSideEffects = 0` in the *.td files, so the MCInstrs are marked as `MCID::UnmodeledSideEffects`:
```
S_ADD_CO_PSEUDO
S_MUL_I64_I32_PSEUDO
S_MUL_U64_U32_PSEUDO
S_SUB_CO_PSEUDO
S_UADDO_PSEUDO
S_USUBO_PSEUDO
```
These are all regular ALU operations without side effects.
</details>

author_association: MEMBER
user: login: llvmbot
created_at: 2025-02-26T01:11:52Z
body: 
Hi!

This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:

1. Check that no other contributor has already been assigned to this issue. If you believe that no one is actually working on it despite an assignment, ping the person. After one week without a response, the assignee may be changed.
1. In the comments of this issue, request for it to be assigned to you, or just create a [pull request](https://github.com/llvm/llvm-project/pulls) after following the steps below. [Mention](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this issue in the description of the pull request.
1. Fix the issue locally.
1. [Run the test suite](https://llvm.org/docs/TestingGuide.html#unit-and-regression-tests) locally. Remember that the subdirectories under `test/` create fine-grained testing targets, so you can e.g. use `make check-clang-ast` to only run Clang's AST tests.
1. Create a Git commit.
1. Run [`git clang-format HEAD~1`](https://clang.llvm.org/docs/ClangFormat.html#git-integration) to format your changes.
1. Open a [pull request](https://github.com/llvm/llvm-project/pulls) to the [upstream repository](https://github.com/llvm/llvm-project) on GitHub. Detailed instructions can be found [in GitHub's documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). [Mention](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this issue in the description of the pull request.

If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below.


author_association: MEMBER
user: login: llvmbot
created_at: 2025-02-26T01:11:54Z
body: 
@llvm/issue-subscribers-good-first-issue

Author: Jay Foad (jayfoad)

<details>
The following pseudos do not have an explicit `hasSideEffects = 0` in the *.td files, so the MCInstrs are marked as `MCID::UnmodeledSideEffects`:
```
S_ADD_CO_PSEUDO
S_MUL_I64_I32_PSEUDO
S_MUL_U64_U32_PSEUDO
S_SUB_CO_PSEUDO
S_UADDO_PSEUDO
S_USUBO_PSEUDO
```
These are all regular ALU operations without side effects.
</details>

author_association: MEMBER
user: login: average-avancha
created_at: 2025-02-26T01:28:52Z
body: I can take a look at this issue, can it be assigned to me?
author_association: NONE

Diff:
diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td
index 9051db0c01ed1..0e089e76e9722 100644
--- a/llvm/lib/Target/AMDGPU/SIInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SIInstructions.td
@@ -231,7 +231,7 @@ def EXIT_STRICT_WQM : SPseudoInstSI <(outs SReg_1:$sdst), (ins SReg_1:$src0)> {
   let mayStore = 0;
 }
 
-let usesCustomInserter = 1 in {
+let usesCustomInserter = 1, hasSideEffects = 0 in {
 let WaveSizePredicate = isWave32 in
 def S_INVERSE_BALLOT_U32 : SPseudoInstSI<
   (outs SReg_32:$sdst), (ins SSrc_b32:$mask),
@@ -243,7 +243,7 @@ def S_INVERSE_BALLOT_U64 : SPseudoInstSI<
   (outs SReg_64:$sdst), (ins SSrc_b64:$mask),
   [(set i1:$sdst, (int_amdgcn_inverse_ballot i64:$mask))]
 >;
-} // End usesCustomInserter = 1
+} // End usesCustomInserter = 1, hasSideEffects = 0
 
 let WaveSizePredicate = isWave32 in
   def : GCNPat <
@@ -338,21 +338,23 @@ def S_SUB_U64_PSEUDO : SPseudoInstSI <
   [(set SReg_64:$sdst, (UniformBinFrag<sub> i64:$src0, i64:$src1))]
 >;
 
-def S_ADD_CO_PSEUDO : SPseudoInstSI <
-  (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
->;
+let hasSideEffects = 0 in {
+  def S_ADD_CO_PSEUDO : SPseudoInstSI <
+    (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
+  >;
 
-def S_SUB_CO_PSEUDO : SPseudoInstSI <
-  (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
->;
+  def S_SUB_CO_PSEUDO : SPseudoInstSI <
+    (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
+  >;
 
-def S_UADDO_PSEUDO : SPseudoInstSI <
-  (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1)
->;
+  def S_UADDO_PSEUDO : SPseudoInstSI <
+    (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1)
+  >;
 
-def S_USUBO_PSEUDO : SPseudoInstSI <
-  (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1)
->;
+  def S_USUBO_PSEUDO : SPseudoInstSI <
+    (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1)
+  >;
+}
 
 let OtherPredicates = [HasShaderCyclesHiLoRegisters] in
 def GET_SHADERCYCLESHILO : SPseudoInstSI<
diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td
index 73f4655f735a2..3d3f1ba3f5170 100644
--- a/llvm/lib/Target/AMDGPU/SOPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td
@@ -663,14 +663,16 @@ let SubtargetPredicate = isGFX12Plus in {
   }
 
   // The higher 32-bits of the inputs contain the sign extension bits.
-  def S_MUL_I64_I32_PSEUDO : SPseudoInstSI <
-    (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b64:$src1)
-  >;
+  let hasSideEffects = 0 in {
+    def S_MUL_I64_I32_PSEUDO : SPseudoInstSI <
+      (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b64:$src1)
+    >;
 
-  // The higher 32-bits of the inputs are zero.
-  def S_MUL_U64_U32_PSEUDO : SPseudoInstSI <
-    (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b64:$src1)
-  >;
+    // The higher 32-bits of the inputs are zero.
+    def S_MUL_U64_U32_PSEUDO : SPseudoInstSI <
+      (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b64:$src1)
+    >;
+  }
 
 } // End SubtargetPredicate = isGFX12Plus
 
diff --git a/llvm/test/CodeGen/AMDGPU/mul.ll b/llvm/test/CodeGen/AMDGPU/mul.ll
index 7dd45181a8356..896f48a9215b9 100644
--- a/llvm/test/CodeGen/AMDGPU/mul.ll
+++ b/llvm/test/CodeGen/AMDGPU/mul.ll
@@ -2850,17 +2850,17 @@ define amdgpu_kernel void @s_mul_i128(ptr addrspace(1) %out, [8 x i32], i128 %a,
 ; GFX12-NEXT:    s_mov_b32 s5, s3
 ; GFX12-NEXT:    s_mov_b32 s17, s3
 ; GFX12-NEXT:    s_mov_b32 s19, s3
-; GFX12-NEXT:    s_mov_b32 s24, s3
+; GFX12-NEXT:    s_mov_b32 s20, s3
 ; GFX12-NEXT:    s_wait_kmcnt 0x0
 ; GFX12-NEXT:    s_mov_b32 s2, s8
 ; GFX12-NEXT:    s_mov_b32 s6, s12
 ; GFX12-NEXT:    s_mov_b32 s4, s13
 ; GFX12-NEXT:    s_mul_u64 s[22:23], s[6:7], s[2:3]
-; GFX12-NEXT:    s_mul_u64 s[20:21], s[4:5], s[2:3]
+; GFX12-NEXT:    s_mul_u64 s[24:25], s[4:5], s[2:3]
 ; GFX12-NEXT:    s_mov_b32 s2, s23
 ; GFX12-NEXT:    s_mov_b32 s16, s9
 ; GFX12-NEXT:    s_mul_u64 s[10:11], s[10:11], s[12:13]
-; GFX12-NEXT:    s_add_nc_u64 s[12:13], s[20:21], s[2:3]
+; GFX12-NEXT:    s_add_nc_u64 s[12:13], s[24:25], s[2:3]
 ; GFX12-NEXT:    s_mul_u64 s[6:7], s[6:7], s[16:17]
 ; GFX12-NEXT:    s_mov_b32 s2, s13
 ; GFX12-NEXT:    s_mov_b32 s13, s3
@@ -2871,9 +2871,9 @@ define amdgpu_kernel void @s_mul_i128(ptr addrspace(1) %out, [8 x i32], i128 %a,
 ; GFX12-NEXT:    s_mov_b32 s23, s3
 ; GFX12-NEXT:    s_add_nc_u64 s[2:3], s[2:3], s[18:19]
 ; GFX12-NEXT:    s_add_nc_u64 s[8:9], s[10:11], s[8:9]
-; GFX12-NEXT:    s_mov_b32 s25, s6
+; GFX12-NEXT:    s_mov_b32 s21, s6
 ; GFX12-NEXT:    s_add_nc_u64 s[2:3], s[4:5], s[2:3]
-; GFX12-NEXT:    s_or_b64 s[6:7], s[22:23], s[24:25]
+; GFX12-NEXT:    s_or_b64 s[6:7], s[22:23], s[20:21]
 ; GFX12-NEXT:    s_add_nc_u64 s[2:3], s[2:3], s[8:9]
 ; GFX12-NEXT:    v_dual_mov_b32 v0, s6 :: v_dual_mov_b32 v1, s7
 ; GFX12-NEXT:    v_dual_mov_b32 v2, s2 :: v_dual_mov_b32 v3, s3


Reviews:
user: login: kerbowa
body: I'm curious why no side effects is not the default and this needs to be explicit for these pseudos in particular? Is there any motivating test/example where this impacts scheduling or some other optimization?
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-05T21:47:44Z
user: login: arsenm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T03:16:58Z
user: login: Pierre-vh
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T08:24:14Z
user: login: arsenm
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T09:20:46Z
user: login: jayfoad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T10:44:19Z
user: login: jayfoad
body: LGTM, thanks.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T11:09:48Z

Review comments:
diff_hunk: @@ -340,19 +340,27 @@ def S_SUB_U64_PSEUDO : SPseudoInstSI <
 
 def S_ADD_CO_PSEUDO : SPseudoInstSI <
   (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
->;
+>{
path: llvm/lib/Target/AMDGPU/SIInstructions.td
user: login: arsenm
body: Move >{ to previous line 
created_at: 2025-04-07T03:16:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -340,19 +340,27 @@ def S_SUB_U64_PSEUDO : SPseudoInstSI <
 
 def S_ADD_CO_PSEUDO : SPseudoInstSI <
   (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
->;
+>{
path: llvm/lib/Target/AMDGPU/SIInstructions.td
user: login: Pierre-vh
body: nit: use ` let hasSideEffects=0 in { .. }` to avoid repetition?
created_at: 2025-04-07T08:24:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -231,7 +231,7 @@ def EXIT_STRICT_WQM : SPseudoInstSI <(outs SReg_1:$sdst), (ins SReg_1:$src0)> {
   let mayStore = 0;
 }
 
-let usesCustomInserter = 1 in {
+let usesCustomInserter = 1, hasSideEffects = 0 in {
path: llvm/lib/Target/AMDGPU/SIInstructions.td
user: login: jayfoad
body: Update the corresponding `// End` comment below.
created_at: 2025-04-10T10:44:19Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-05T08:36:04Z
body: <!--LLVM NEW CONTRIBUTOR COMMENT-->

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/).
author_association: NONE
user: login: llvmbot
created_at: 2025-04-05T08:36:32Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: None (amansharma612)

<details>
<summary>Changes</summary>

Fixes #<!-- -->128685


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


2 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/SIInstructions.td (+12-4) 
- (modified) llvm/lib/Target/AMDGPU/SOPInstructions.td (+6-2) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td
index 9051db0c01ed1..e78a29e36b358 100644
--- a/llvm/lib/Target/AMDGPU/SIInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SIInstructions.td
@@ -340,19 +340,27 @@ def S_SUB_U64_PSEUDO : SPseudoInstSI <
 
 def S_ADD_CO_PSEUDO : SPseudoInstSI <
   (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
->;
+>{
+    let hasSideEffects = 0;
+}
 
 def S_SUB_CO_PSEUDO : SPseudoInstSI <
   (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1, SSrc_i1:$scc_in)
->;
+>{
+    let hasSideEffects = 0;
+}
 
 def S_UADDO_PSEUDO : SPseudoInstSI <
   (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1)
->;
+>{
+    let hasSideEffects = 0;
+}
 
 def S_USUBO_PSEUDO : SPseudoInstSI <
   (outs SReg_32:$sdst, SSrc_i1:$scc_out), (ins SSrc_b32:$src0, SSrc_b32:$src1)
->;
+>{
+    let hasSideEffects = 0;
+}
 
 let OtherPredicates = [HasShaderCyclesHiLoRegisters] in
 def GET_SHADERCYCLESHILO : SPseudoInstSI<
diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td
index 73f4655f735a2..be63bc4a745eb 100644
--- a/llvm/lib/Target/AMDGPU/SOPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td
@@ -665,12 +665,16 @@ let SubtargetPredicate = isGFX12Plus in {
   // The higher 32-bits of the inputs contain the sign extension bits.
   def S_MUL_I64_I32_PSEUDO : SPseudoInstSI <
     (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b64:$src1)
-  >;
+  >{
+      let hasSideEffects = 0;
+  }
 
   // The higher 32-bits of the inputs are zero.
   def S_MUL_U64_U32_PSEUDO : SPseudoInstSI <
     (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b64:$src1)
-  >;
+  >{
+    let hasSideEffects = 0;
+  }
 
 } // End SubtargetPredicate = isGFX12Plus
 

``````````

</details>

author_association: MEMBER
user: login: arsenm
created_at: 2025-04-07T03:16:21Z
body: > I'm curious why no side effects is not the default 

Wrong by default is a horrible design mistake LLVM has repeated in far too many places. This is the correct default 
author_association: CONTRIBUTOR
user: login: arsenm
created_at: 2025-04-07T03:17:49Z
body: > Is there any motivating test/example where this impacts scheduling or some other optimization?

I doubt it, these are a SelectionDAG hack more than anything and expand immediately. It doesn't hurt to correct this though 


author_association: CONTRIBUTOR
user: login: amansharma612
created_at: 2025-04-07T07:36:10Z
body: Regression test `mul.ll` fails with the intended changes.
author_association: CONTRIBUTOR
user: login: arsenm
created_at: 2025-04-07T07:40:42Z
body: > Regression test `mul.ll` fails with the intended changes.

Probably just need to run update_llc_test_checks 
author_association: CONTRIBUTOR
user: login: jayfoad
created_at: 2025-04-07T09:35:14Z
body: Could also do this for S_INVERSE_BALLOT_U32/64
author_association: CONTRIBUTOR
user: login: arsenm
created_at: 2025-04-10T09:21:01Z
body: LGTM but could also do this for the inverse ballots 
author_association: CONTRIBUTOR
user: login: amansharma612
created_at: 2025-04-10T10:38:00Z
body: > LGTM but could also do this for the inverse ballots

@arsenm I've added the changes for inverse ballots already
author_association: CONTRIBUTOR
user: login: jayfoad
created_at: 2025-04-10T11:11:33Z
body: > mansharma612 force-pushed the salusideeffects branch from 926a934 to baddce9 3 minutes ago

To fix things in your PR it is almost always better to push an extra commit, instead of modifying your commit and force-pushing it. Force-pushing makes it harder for reviewers to see what you have changed.
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-11T15:35:24Z
body: <!--LLVM BUILDBOT INFORMATION COMMENT-->

@amansharma612 Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail [here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr).

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of [LLVM development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy). You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

author_association: NONE