[llvm] [CodeGen] MachineLICM: Do not consider "loop liveins" as loop defs (PR #121769)

Gaƫtan Bossu via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 7 06:09:28 PST 2025


================
@@ -0,0 +1,217 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass machinelicm -o - %s | FileCheck %s
+
+# A couple of "unit" tests for the post-ra MachineLICM pass.
+
+# Positive test to show MachineLICM can hoist instructions with register operands.
+---
+name:            hoist_invariant_add
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: hoist_invariant_add
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.1(0x40000000)
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   CBZW renamable $w0, %bb.3
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.2(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $w2 = ADDWri killed renamable $w1, 1, 0
+  ; CHECK-NEXT:   B %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT:   liveins: $w0, $w1, $w2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $w0 = SUBWrr killed renamable $w0, $w2
+  ; CHECK-NEXT:   CBZW renamable $w0, %bb.3
+  ; CHECK-NEXT:   B %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   RET_ReallyLR
+  bb.0:
+    successors: %bb.3(0x40000000), %bb.1(0x40000000)
+    liveins: $w0, $w1
+    CBZW renamable $w0, %bb.3
+
+  bb.1:
+    successors: %bb.2(0x80000000)
+    liveins: $w0, $w1
+    B %bb.2
+
+  bb.2:
+    successors: %bb.3(0x40000000), %bb.2(0x40000000)
+    liveins: $w0, $w1
+    renamable $w2 = ADDWri killed renamable $w1, 1, 0
+    renamable $w0 = SUBWrr killed renamable $w0, $w2
+    CBZW renamable $w0, %bb.3
+    B %bb.2
+
+  bb.3:
+    RET_ReallyLR
+...
+
+# The first ADDWri does not have loop-invariant source operands,
+# it cannot be hoisted.
+---
+name:            nohoist_variable_add_operands
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: nohoist_variable_add_operands
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.1(0x40000000)
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   CBZW renamable $w0, %bb.3
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.2(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   B %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $w2 = ADDWri renamable $w1, 1, 0
+  ; CHECK-NEXT:   renamable $w0 = SUBWrr killed renamable $w0, $w2
+  ; CHECK-NEXT:   renamable $w1 = ADDWri killed renamable $w1, 1, 0
+  ; CHECK-NEXT:   CBZW renamable $w0, %bb.3
+  ; CHECK-NEXT:   B %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   RET_ReallyLR
+  bb.0:
+    successors: %bb.3(0x40000000), %bb.1(0x40000000)
+    liveins: $w0, $w1
+    CBZW renamable $w0, %bb.3
+
+  bb.1:
+    successors: %bb.2(0x80000000)
+    liveins: $w0, $w1
+    B %bb.2
+
+  bb.2:
+    successors: %bb.3(0x40000000), %bb.2(0x40000000)
+    liveins: $w0, $w1
+    renamable $w2 = ADDWri renamable $w1, 1, 0
+    renamable $w0 = SUBWrr killed renamable $w0, $w2
+    renamable $w1 = ADDWri killed renamable $w1, 1, 0
+    CBZW renamable $w0, %bb.3
+    B %bb.2
+
+  bb.3:
+    RET_ReallyLR
+...
+
+# w2 is a loop-livein, but it is also redefined in the loop by ADDWri.
+# The latter cannot be hoisted.
+---
+name:            nohoist_redef_livein_reg
----------------
gbossu wrote:

 - In that case, `renamable $w2 = ADDWri killed renamable $w1, 1, 0` has constant source operands, but redefines a register that is loop-livein.
 - In the previous one, the `$w1` input to `renamable $w2 = ADDWri renamable $w1, 1, 0` isn't loop-invariant, so it cannot be hoisted

Those are different reasons IMO, but I agree it's not obvious at first glance. Any suggestion to improve the tests is welcome :)

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


More information about the llvm-commits mailing list