[PATCH] D155073: [LSR] Don't consider users of constant outside loop

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 12 05:15:58 PDT 2023


nikic created this revision.
nikic added reviewers: fhahn, dmgreen.
Herald added subscribers: StephenFan, hiraditya, arichardson.
Herald added a project: All.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

In CollectLoopInvariantFixupsAndFormulae(), LSR looks at users outside the loop. E.g. if we have an addrec based on %base, and %base is also used outside the loop, then we have to keep it in a register anyway, which may make it more profitable to use %base + %idx style addressing.

This reasoning doesn't hold up when the base is a constant, because the constant can be rematerialized. The lsr-memcpy.ll regressed when enabling opaque pointer, because `inttoptr (i64 6442450944 to ptr)` now also has a use outside the loop (previously it didn't due to a pointer type difference), and that extra "use" results in worse use of addressing modes in the loop. However, the use outside the loop actually gets rematerialized, so the alleged register saving does not occur.

This patch opts to skip users of constants entirely for this heuristic. I considered a narrower fix for only inttoptr expressions first, but as this doesn't impact any other tests, it seems better to just handle all constants.


https://reviews.llvm.org/D155073

Files:
  llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
  llvm/test/Transforms/LoopStrengthReduce/AArch64/lsr-memcpy.ll


Index: llvm/test/Transforms/LoopStrengthReduce/AArch64/lsr-memcpy.ll
===================================================================
--- llvm/test/Transforms/LoopStrengthReduce/AArch64/lsr-memcpy.ll
+++ llvm/test/Transforms/LoopStrengthReduce/AArch64/lsr-memcpy.ll
@@ -7,21 +7,18 @@
 ; <rdar://problem/12702735> [ARM64][coalescer] need better register
 ; coalescing for simple unit tests.
 
-; FIXME: This regressed after enabling opaque pointers.
 define i32 @testCase() nounwind ssp {
 ; CHECK-LABEL: testCase:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
-; CHECK-NEXT:    mov x8, #0 // =0x0
-; CHECK-NEXT:    mov w9, #1288 // =0x508
-; CHECK-NEXT:    mov x10, #4294967296 // =0x100000000
-; CHECK-NEXT:    mov x11, #6442450944 // =0x180000000
+; CHECK-NEXT:    mov w8, #1288 // =0x508
+; CHECK-NEXT:    mov x9, #4294967296 // =0x100000000
+; CHECK-NEXT:    mov x10, #6442450944 // =0x180000000
 ; CHECK-NEXT:  .LBB0_1: // %while.body
 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldr x12, [x8, x10]
-; CHECK-NEXT:    str x12, [x8, x11]
-; CHECK-NEXT:    add x8, x8, #8
-; CHECK-NEXT:    subs x9, x9, #8
+; CHECK-NEXT:    ldr x11, [x9], #8
+; CHECK-NEXT:    str x11, [x10], #8
+; CHECK-NEXT:    subs x8, x8, #8
 ; CHECK-NEXT:    b.pl .LBB0_1
 ; CHECK-NEXT:  // %bb.2: // %while.end
 ; CHECK-NEXT:    mov x8, #6442450944 // =0x180000000
Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -3507,8 +3507,8 @@
       if (const Instruction *Inst = dyn_cast<Instruction>(V)) {
         // Look for instructions defined outside the loop.
         if (L->contains(Inst)) continue;
-      } else if (isa<UndefValue>(V))
-        // Undef doesn't have a live range, so it doesn't matter.
+      } else if (isa<Constant>(V))
+        // Constants can be re-materialized.
         continue;
       for (const Use &U : V->uses()) {
         const Instruction *UserInst = dyn_cast<Instruction>(U.getUser());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D155073.539509.patch
Type: text/x-patch
Size: 2166 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230712/e62fa4df/attachment-0001.bin>


More information about the llvm-commits mailing list