Skip to content

Conversation

@s-barannikov
Copy link
Contributor

@s-barannikov s-barannikov commented Nov 20, 2025

ARM relies on deprecated TableGen behavior of guessing instruction properties from patterns (def ARM : Target doesn't have guessInstructionProperties set to false).

Before #168209, TableGen conservatively guessed that t2WhileLoopSetup has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the added pattern uses only arm_wlssetup node, which has no side effects.

Add SDNPSideEffect to the node so that TableGen guesses the property right, and also hasSideEffects = 1 to the instruction in case ARM ever sets guessInstructionProperties to false.

@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2025

@llvm/pr-subscribers-backend-arm

Author: Sergei Barannikov (s-barannikov)

Changes

ARM relies on deprecated TableGen behavior of guessing instruction properties from patterns (def ARM : Target doesn't have guessInstructionProperties set to false).

Before #168209, TableGen conservatively guessed that t2WhileLoopSetup has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the added pattern uses only arm_wlssetup node, which has no side effects.

Add SDNPSideEffect to the node so that TableGen guesses the property right, and also hasSideEffects = 1 to the instruction in case ARM ever sets guessInstructionProperties to false.


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

2 Files Affected:

  • (modified) llvm/lib/Target/ARM/ARMInstrThumb2.td (+2-1)
  • (added) llvm/test/CodeGen/Thumb2/LowOverheadLoops/pr168209.ll (+45)
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 317959c0342f7..19c179be5b987 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -5584,7 +5584,8 @@ class t2LOL<dag oops, dag iops, string asm, string ops>
 // Setup for the iteration count of a WLS. See t2WhileLoopSetup.
 def arm_wlssetup
     : SDNode<"ARMISD::WLSSETUP",
-             SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisSameAs<1, 0>]>>;
+             SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisSameAs<1, 0>]>,
+             [SDNPSideEffect]>;
 
 // Low-overhead loops, While Loop Start branch. See t2WhileLoopStart
 def arm_wls : SDNode<"ARMISD::WLS",
diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/pr168209.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/pr168209.ll
new file mode 100644
index 0000000000000..a6dded12c064b
--- /dev/null
+++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/pr168209.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=thumbv8.1m.main %s -o - | FileCheck %s
+
+; Checks that t2WhileLoopSetup is not CSEd.
+
+define i32 @test(i16 %arg) {
+; CHECK-LABEL: test:
+; CHECK:       @ %bb.0: @ %bb
+; CHECK-NEXT:    push {r7, lr}
+; CHECK-NEXT:    uxth r0, r0
+; CHECK-NEXT:    wls lr, r0, .LBB0_4
+; CHECK-NEXT:  .LBB0_1: @ %bb3
+; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    le lr, .LBB0_1
+; CHECK-NEXT:  @ %bb.2: @ %bb2
+; CHECK-NEXT:    wls lr, r0, .LBB0_4
+; CHECK-NEXT:  .LBB0_3: @ %bb7
+; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    le lr, .LBB0_3
+; CHECK-NEXT:  .LBB0_4: @ %.critedge
+; CHECK-NEXT:    movs r0, #0
+; CHECK-NEXT:    pop {r7, pc}
+bb:
+  %i = zext i16 %arg to i32
+  %i1 = icmp eq i16 %arg, 0
+  br i1 %i1, label %.critedge, label %bb3
+
+bb2:                                              ; preds = %bb3
+  br i1 %i1, label %.critedge, label %bb7
+
+bb3:                                              ; preds = %bb3, %bb
+  %i4 = phi i32 [ %i5, %bb3 ], [ 0, %bb ]
+  %i5 = add i32 %i4, 1
+  %i6 = icmp eq i32 %i5, %i
+  br i1 %i6, label %bb2, label %bb3
+
+bb7:                                              ; preds = %bb7, %bb2
+  %i8 = phi i32 [ %i9, %bb7 ], [ 0, %bb2 ]
+  %i9 = add i32 %i8, 1
+  %i10 = icmp eq i32 %i9, %i
+  br i1 %i10, label %.critedge, label %bb7
+
+.critedge:                                        ; preds = %bb7, %bb2, %bb
+  ret i32 0
+}

ARM relies on deprecated TableGen behavior of guessing instruction
properties from patterns (`def ARM : Target` doesn't have
`guessInstructionProperties` set to false).

Before llvm#168209, TableGen conservatively guessed that t2WhileLoopSetup
has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the
added pattern uses only `arm_wlssetup` node, which has no side effects.

Add SDNPSideEffect to the node so that TableGen guesses the property
right, and also `hasSideEffects = 1` to the instruction in case ARM
ever sets `guessInstructionProperties` to false.
@github-actions
Copy link

🐧 Linux x64 Test Results

  • 186432 tests passed
  • 4864 tests skipped

Copy link
Contributor

@VladiKrapp-Arm VladiKrapp-Arm left a comment

Choose a reason for hiding this comment

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

Checked that this does resolve the crash.
LGTM, but I'd appreciate a review from someone a bit more familiar with the domain.

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.

Sounds good. LGTM

@s-barannikov s-barannikov merged commit f56ddde into llvm:main Nov 21, 2025
10 checks passed
@s-barannikov s-barannikov deleted the arm-lol-fix branch November 21, 2025 16:16
@llvm-ci
Copy link
Collaborator

llvm-ci commented Nov 21, 2025

LLVM Buildbot has detected a new failure on builder llvm-nvptx64-nvidia-win running on as-builder-8 while building llvm at step 7 "test-build-unified-tree-check-llvm".

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

Here is the relevant piece of the build log for the reference
Step 7 (test-build-unified-tree-check-llvm) failure: test (failure)
******************** TEST 'LLVM-Unit :: Support/./SupportTests.exe/79/105' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:C:\buildbot\as-builder-8\llvm-nvptx64-nvidia-win\build\unittests\Support\.\SupportTests.exe-LLVM-Unit-24868-79-105.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=105 GTEST_SHARD_INDEX=79 C:\buildbot\as-builder-8\llvm-nvptx64-nvidia-win\build\unittests\Support\.\SupportTests.exe
--


Note: This is test shard 80 of 105.

[==========] Running 16 tests from 16 test suites.

[----------] Global test environment set-up.

[----------] 1 test from BinaryStreamTest

[ RUN      ] BinaryStreamTest.DropOperations

[       OK ] BinaryStreamTest.DropOperations (0 ms)

[----------] 1 test from BinaryStreamTest (0 ms total)



[----------] 1 test from CommandLineTest

[ RUN      ] CommandLineTest.TokenizeAndMarkEOLs

[       OK ] CommandLineTest.TokenizeAndMarkEOLs (0 ms)

[----------] 1 test from CommandLineTest (0 ms total)



[----------] 1 test from DataExtractorTest

[ RUN      ] DataExtractorTest.LEB128_error

[       OK ] DataExtractorTest.LEB128_error (0 ms)

[----------] 1 test from DataExtractorTest (0 ms total)



[----------] 1 test from Error

[ RUN      ] Error.ForwardToExpected

[       OK ] Error.ForwardToExpected (0 ms)

[----------] 1 test from Error (0 ms total)
...

aadeshps-mcw pushed a commit to aadeshps-mcw/llvm-project that referenced this pull request Nov 26, 2025
ARM relies on deprecated TableGen behavior of guessing instruction
properties from patterns (`def ARM : Target` doesn't have
`guessInstructionProperties` set to false).

Before llvm#168209, TableGen conservatively guessed that `t2WhileLoopSetup`
has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the
added pattern uses only `arm_wlssetup` node, which has no side effects.

Add `SDNPSideEffect` to the node so that TableGen guesses the property
right, and also `hasSideEffects = 1` to the instruction in case ARM ever
sets `guessInstructionProperties` to false.
Priyanshu3820 pushed a commit to Priyanshu3820/llvm-project that referenced this pull request Nov 26, 2025
ARM relies on deprecated TableGen behavior of guessing instruction
properties from patterns (`def ARM : Target` doesn't have
`guessInstructionProperties` set to false).

Before llvm#168209, TableGen conservatively guessed that `t2WhileLoopSetup`
has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the
added pattern uses only `arm_wlssetup` node, which has no side effects.

Add `SDNPSideEffect` to the node so that TableGen guesses the property
right, and also `hasSideEffects = 1` to the instruction in case ARM ever
sets `guessInstructionProperties` to false.
augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Dec 3, 2025
ARM relies on deprecated TableGen behavior of guessing instruction
properties from patterns (`def ARM : Target` doesn't have
`guessInstructionProperties` set to false).

Before llvm#168209, TableGen conservatively guessed that `t2WhileLoopSetup`
has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the
added pattern uses only `arm_wlssetup` node, which has no side effects.

Add `SDNPSideEffect` to the node so that TableGen guesses the property
right, and also `hasSideEffects = 1` to the instruction in case ARM ever
sets `guessInstructionProperties` to false.
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