Skip to content

[AArch64] Fix stp kill when merging forward. #152994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2025

Conversation

rj-jesus
Copy link
Contributor

As an alternative to #149177, iterate through all instructions in AArch64LoadStoreOptimizer.

@llvmbot
Copy link
Member

llvmbot commented Aug 11, 2025

@llvm/pr-subscribers-backend-aarch64

Author: Ricardo Jesus (rj-jesus)

Changes

As an alternative to #149177, iterate through all instructions in AArch64LoadStoreOptimizer.


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

2 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp (+2-1)
  • (modified) llvm/test/CodeGen/AArch64/sve-vls-ldst-opt.mir (+18)
diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index 782d62a7e5e13..e69fa32967a79 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -1193,7 +1193,8 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
       //   USE kill %w1   ; need to clear kill flag when moving STRWui downwards
       //   STRW %w0
       Register Reg = getLdStRegOp(*I).getReg();
-      for (MachineInstr &MI : make_range(std::next(I), Paired))
+      for (MachineInstr &MI :
+           make_range(std::next(I->getIterator()), Paired->getIterator()))
         MI.clearRegisterKills(Reg, TRI);
     }
   }
diff --git a/llvm/test/CodeGen/AArch64/sve-vls-ldst-opt.mir b/llvm/test/CodeGen/AArch64/sve-vls-ldst-opt.mir
index 49453bc178914..a3e6cc10c1d0b 100644
--- a/llvm/test/CodeGen/AArch64/sve-vls-ldst-opt.mir
+++ b/llvm/test/CodeGen/AArch64/sve-vls-ldst-opt.mir
@@ -72,3 +72,21 @@ body: |
 # CHECK: STURQi killed renamable $q1, renamable $x1, 16 :: (store (s128))
 # CHECK: STURQi killed renamable $q2, renamable $x1, 48 :: (store (s128))
 # CHECK: STR_ZXI killed renamable $z3, renamable $x1, 4 :: (store (<vscale x 1 x s128>))
+---
+name: clear-kill-in-bundle-forward
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $x0, $z0
+    STR_ZXI $z0, $x0, 0 :: (store (<vscale x 1 x s128>))
+    BUNDLE implicit-def $z1, implicit killed $z0 {
+      $z1 = ADD_ZZZ_D killed $z0, $z0
+    }
+    STR_ZXI renamable $z1, $x0, 1 :: (store (<vscale x 1 x s128>))
+    RET_ReallyLR
+...
+# CHECK-LABEL: name: clear-kill-in-bundle-forward
+# CHECK: BUNDLE implicit-def $z1, implicit $z0 {
+# CHECK:   $z1 = ADD_ZZZ_D $z0, $z0
+# CHECK: }
+# CHECK: STPQi $q0, $q1, $x0, 0 :: (store (<vscale x 1 x s128>))

@@ -1193,7 +1193,8 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
// USE kill %w1 ; need to clear kill flag when moving STRWui downwards
// STRW %w0
Register Reg = getLdStRegOp(*I).getReg();
for (MachineInstr &MI : make_range(std::next(I), Paired))
for (MachineInstr &MI :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can just do MRI.clearKillFlags

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the kill flags of I should be preserved here as they are used to track defined registers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kill flags have been deprecated for over a decade and should not be relied on. We should be be actively purging uses and not bothering to preserve them. Liveness should be tracked by reverse walking from the bottom of the block which avoids the need for them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, what I was trying to say is that the code, as written, currently depends on some kill flags being preserved. If we use MRI.clearKillFlags here without further refactoring the code, we'll have miscompiles.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed kill flags should at worst give missed optimizations, they could never be relied on for correctness

Copy link
Contributor Author

@rj-jesus rj-jesus Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With MRI.clearKillFlags, test12 from 17554b8, which added the bit of code I linked previously, miscompiles due to a register being incorrectly renamed:

Function Live Ins: $x0, $x1, $x8

bb.0:
  liveins: $x0, $x1
  renamable $x10 = LDRXui renamable $x0, 0 :: (load (s64))
  $x10, renamable $x8 = LDPXi renamable $x0, 3 :: (load (s64))
  renamable $x9 = LDRXui renamable $x0, 2 :: (load (s64))
  renamable $x8 = ADDXrr $x8, $x8
  STPXi renamable $x8, killed $x10, renamable $x0, 10 :: (store (s64), align 4)
  STPXi renamable $x10, renamable $x9, renamable $x0, 20 :: (store (s64), align 4)
  RET undef $lr

As you say, this could be done differently, but doing MRI.clearKillFlags doesn't seem correct without first refactoring the code (which I believe would be preferably done separately).

Copy link
Collaborator

@davemgreen davemgreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, In the meantime this sounds fine to me. Thanks for the fix, LGTM.

@rj-jesus rj-jesus merged commit ef5e65d into llvm:main Aug 12, 2025
11 checks passed
@rj-jesus rj-jesus deleted the rjj/aarch64-fix-stp-kill-forward branch August 12, 2025 13:19
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 12, 2025

LLVM Buildbot has detected a new failure on builder lldb-aarch64-ubuntu running on linaro-lldb-aarch64-ubuntu while building llvm at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/22475

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: lang/c/global_variables/TestGlobalVariables.py (754 of 2305)
PASS: lldb-api :: lang/c/local_variables/TestLocalVariables.py (755 of 2305)
XFAIL: lldb-api :: lang/c/modules/TestCModules.py (756 of 2305)
PASS: lldb-api :: lang/c/offsetof/TestOffsetof.py (757 of 2305)
PASS: lldb-api :: lang/c/non-mangled/TestCNonMangled.py (758 of 2305)
PASS: lldb-api :: lang/c/record_decl_in_expr/TestRecordDeclInExpr.py (759 of 2305)
PASS: lldb-api :: lang/c/parray_vrs_char_array/TestParrayVrsCharArrayChild.py (760 of 2305)
PASS: lldb-api :: lang/c/sizeof/TestCSizeof.py (761 of 2305)
PASS: lldb-api :: lang/c/register_variables/TestRegisterVariables.py (762 of 2305)
UNRESOLVED: lldb-api :: functionalities/statusline/TestStatusline.py (763 of 2305)
******************** TEST 'lldb-api :: functionalities/statusline/TestStatusline.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --arch aarch64 --build-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --cmake-build-type Release /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/statusline -p TestStatusline.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project.git revision ef5e65d27b940a2a2ce1d4ff20c38105d52d23b6)
  clang revision ef5e65d27b940a2a2ce1d4ff20c38105d52d23b6
  llvm revision ef5e65d27b940a2a2ce1d4ff20c38105d52d23b6
Skipping the following test categories: ['libc++', 'msvcstl', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test (TestStatusline.TestStatusline)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_deadlock (TestStatusline.TestStatusline)
lldb-server exiting...
FAIL: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_modulelist_deadlock (TestStatusline.TestStatusline)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_no_color (TestStatusline.TestStatusline)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_no_target (TestStatusline.TestStatusline)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_resize (TestStatusline.TestStatusline)
======================================================================
ERROR: test_modulelist_deadlock (TestStatusline.TestStatusline)
   Regression test for a deadlock that occurs when the status line is enabled before connecting
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/statusline/TestStatusline.py", line 199, in test_modulelist_deadlock
    self.expect(
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbpexpect.py", line 95, in expect
    self.expect_prompt()
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbpexpect.py", line 19, in expect_prompt
    self.child.expect_exact(self.PROMPT)
  File "/usr/local/lib/python3.10/dist-packages/pexpect/spawnbase.py", line 432, in expect_exact
    return exp.expect_loop(timeout)
  File "/usr/local/lib/python3.10/dist-packages/pexpect/expect.py", line 179, in expect_loop
    return self.eof(e)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants