[llvm] [MachineLICM] Only mark live-ins as non-invariant if defined in loop (PR #191755)
Yuyang Zhang via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 23 00:09:40 PDT 2026
================
@@ -36,11 +36,11 @@ define i32 @test(ptr %arg, ptr %arg1, ptr %arg2) #0 !dbg !6 {
; CHECK-NEXT: movne r6, #0
; CHECK-NEXT: Ltmp0:
; CHECK-NEXT: @DEBUG_VALUE: test:this <- [DW_OP_LLVM_arg 0, DW_OP_plus_uconst 135168, DW_OP_LLVM_arg 1, DW_OP_constu 4, DW_OP_mul, DW_OP_plus, DW_OP_plus_uconst 4, DW_OP_stack_value] $r0, $r5
-; CHECK-NEXT: .loc 1 28 24 prologue_end @ test.cpp:28:24
+; CHECK-NEXT: .loc 1 28 24 prologue_end @ test.cpp:28:24 @[ test.cpp:204:23 ]
; CHECK-NEXT: strne.w r6, [r8]
; CHECK-NEXT: moveq r6, #1
; CHECK-NEXT: ldr r4, [r4, #4]
-; CHECK-NEXT: orrs r4, r6
+; CHECK-NEXT: orr.w r4, r4, r6
----------------
yuyzhang512 wrote:
Yes, it did. The hoisted instruction is:
```
t2CMPri lr, 0, implicit-def $cpsr
```
Since `lr` is loop-invariant, the compare becomes hoistable with this change. Hoisting it into the preheader keeps `$cpsr` live throughout the loop, preventing `Thumb2SizeReduce` from using the 16-bit `adds`/`orrs` forms in the loop body because they would clobber the live `$cpsr`. As a result, those instructions remain in their 32-bit forms, leading to the code size increase.
The hoist is correct but unprofitable. This reflects a pre-existing limitation of post-RA `MachineLICM`, which currently has no cost model for hoisting. I also prototyped a guard to avoid hoisting instructions that define registers used by a loop terminator, but it also suppressed existing hoists, so I didn't include it in this patch.
Do you think it's worth pursuing a separate improvement here?
https://github.com/llvm/llvm-project/pull/191755
More information about the llvm-commits
mailing list