[llvm-branch-commits] [llvm] [LSR] Preserve LCSSA in critical edge splitting (PR #192371)

Aiden Grossman via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Apr 18 22:28:12 PDT 2026


https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/192371

>From 400fb1ed1b98ea84d8eea36193619d6b36b34e38 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Sun, 19 Apr 2026 05:28:02 +0000
Subject: [PATCH] fix

Created using spr 1.3.7
---
 .../Transforms/Scalar/LoopStrengthReduce.cpp  |   2 +-
 .../X86/lcssa-preservation-regression.ll      | 143 ++++++++++++------
 2 files changed, 99 insertions(+), 46 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index ad0e746567b2e..d329fa476a2f2 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -5936,7 +5936,7 @@ void LSRInstance::RewriteForPHI(PHINode *PN, const LSRUse &LU,
               for (const Use &U : cast<PHINode>(I).incoming_values()) {
                 if (!isa<Instruction>(U.get()))
                   continue;
-                if (L->contains(cast<Instruction>(U.get())->getParent())) {
+                if (LI.getLoopFor(cast<Instruction>(U.get())->getParent())) {
                   // This phi node references a value inside the loop. We will need
                   // to update LCSSA maybe.
                   InsertedNonLCSSAInsts.insert(cast<Instruction>(U.get()));
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/lcssa-preservation-regression.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/lcssa-preservation-regression.ll
index 344eb896b7c58..a21d8fe3c7ee7 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/lcssa-preservation-regression.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/lcssa-preservation-regression.ll
@@ -48,59 +48,112 @@ exit:                                              ; preds = %loop2
   br label %loop1.header
 }
 
-define void @barney() {
-; CHECK-LABEL: define void @barney() {
-; CHECK-NEXT:  [[BB:.*:]]
-; CHECK-NEXT:    br label %[[BB1:.*]]
-; CHECK:       [[BB1]]:
-; CHECK-NEXT:    switch i8 0, label %[[BB1_BACKEDGE:.*]] [
-; CHECK-NEXT:      i8 63, label %[[BB2_PREHEADER:.*]]
-; CHECK-NEXT:      i8 43, label %[[BB2_PREHEADER]]
-; CHECK-NEXT:      i8 42, label %[[BB2_PREHEADER]]
+define void @regression2() {
+; CHECK-LABEL: define void @regression2() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[LOOP1_HEADER:.*]]
+; CHECK:       [[LOOP1_HEADER]]:
+; CHECK-NEXT:    switch i8 0, label %[[LOOP1_HEADER_BACKEDGE:.*]] [
+; CHECK-NEXT:      i8 63, label %[[LOOP1_LATCH1_PREHEADER:.*]]
+; CHECK-NEXT:      i8 43, label %[[LOOP1_LATCH1_PREHEADER]]
+; CHECK-NEXT:      i8 42, label %[[LOOP1_LATCH1_PREHEADER]]
 ; CHECK-NEXT:    ]
-; CHECK:       [[BB1_BACKEDGE]]:
-; CHECK-NEXT:    br label %[[BB1]]
-; CHECK:       [[BB2_PREHEADER]]:
-; CHECK-NEXT:    br label %[[BB2:.*]]
-; CHECK:       [[BB2]]:
-; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[ADD4:%.*]], %[[BB3:.*]] ], [ 0, %[[BB2_PREHEADER]] ]
-; CHECK-NEXT:    br i1 false, label %[[BB3]], label %[[BB2_BB5_CRIT_EDGE:.*]]
-; CHECK:       [[BB3]]:
+; CHECK:       [[LOOP1_HEADER_BACKEDGE]]:
+; CHECK-NEXT:    br label %[[LOOP1_HEADER]]
+; CHECK:       [[LOOP1_LATCH1_PREHEADER]]:
+; CHECK-NEXT:    br label %[[LOOP1_LATCH1:.*]]
+; CHECK:       [[LOOP1_LATCH1]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[ADD4:%.*]], %[[LOOP1_LATCH2:.*]] ], [ 0, %[[LOOP1_LATCH1_PREHEADER]] ]
+; CHECK-NEXT:    br i1 false, label %[[LOOP1_LATCH2]], label %[[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE:.*]]
+; CHECK:       [[LOOP1_LATCH2]]:
 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 0, 0
 ; CHECK-NEXT:    [[ADD4]] = add i32 [[PHI]], 1
-; CHECK-NEXT:    br i1 false, label %[[BB2]], label %[[BB5SPLIT:.*]]
-; CHECK:       [[BB5SPLIT]]:
-; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], %[[BB3]] ]
-; CHECK-NEXT:    br label %[[BB5:.*]]
-; CHECK:       [[BB2_BB5_CRIT_EDGE]]:
-; CHECK-NEXT:    [[PHI_LCSSA:%.*]] = phi i32 [ [[PHI]], %[[BB2]] ]
-; CHECK-NEXT:    br label %[[BB5]]
-; CHECK:       [[BB5]]:
-; CHECK-NEXT:    [[PHI6:%.*]] = phi i32 [ 0, %[[BB2_BB5_CRIT_EDGE]] ], [ [[ADD_LCSSA]], %[[BB5SPLIT]] ]
-; CHECK-NEXT:    [[PHI7:%.*]] = phi i32 [ [[PHI_LCSSA]], %[[BB2_BB5_CRIT_EDGE]] ], [ 0, %[[BB5SPLIT]] ]
-; CHECK-NEXT:    br label %[[BB1_BACKEDGE]]
+; CHECK-NEXT:    br i1 false, label %[[LOOP1_LATCH1]], label %[[LOOP1_LATCH3SPLIT:.*]]
+; CHECK:       [[LOOP1_LATCH3SPLIT]]:
+; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], %[[LOOP1_LATCH2]] ]
+; CHECK-NEXT:    br label %[[LOOP1_LATCH3:.*]]
+; CHECK:       [[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE]]:
+; CHECK-NEXT:    [[PHI_LCSSA:%.*]] = phi i32 [ [[PHI]], %[[LOOP1_LATCH1]] ]
+; CHECK-NEXT:    br label %[[LOOP1_LATCH3]]
+; CHECK:       [[LOOP1_LATCH3]]:
+; CHECK-NEXT:    [[PHI6:%.*]] = phi i32 [ 0, %[[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE]] ], [ [[ADD_LCSSA]], %[[LOOP1_LATCH3SPLIT]] ]
+; CHECK-NEXT:    [[PHI7:%.*]] = phi i32 [ [[PHI_LCSSA]], %[[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE]] ], [ 0, %[[LOOP1_LATCH3SPLIT]] ]
+; CHECK-NEXT:    br label %[[LOOP1_HEADER_BACKEDGE]]
 ;
-bb:
-  br label %bb1
-
-bb1:                                              ; preds = %bb5, %bb1, %bb
-  switch i8 0, label %bb1 [
-  i8 63, label %bb2
-  i8 43, label %bb2
-  i8 42, label %bb2
+entry:
+  br label %loop1.header
+
+loop1.header:                                              ; preds = %loop1.latch3, %loop1.header, %entry
+  switch i8 0, label %loop1.header [
+  i8 63, label %loop1.latch1
+  i8 43, label %loop1.latch1
+  i8 42, label %loop1.latch1
   ]
 
-bb2:                                              ; preds = %bb3, %bb1, %bb1, %bb1
-  %phi = phi i32 [ %add4, %bb3 ], [ 0, %bb1 ], [ 0, %bb1 ], [ 0, %bb1 ]
-  br i1 false, label %bb3, label %bb5
+loop1.latch1:                                              ; preds = %loop1.latch2, %loop1.header, %loop1.header, %loop1.header
+  %phi = phi i32 [ %add4, %loop1.latch2 ], [ 0, %loop1.header ], [ 0, %loop1.header ], [ 0, %loop1.header ]
+  br i1 false, label %loop1.latch2, label %loop1.latch3
 
-bb3:                                              ; preds = %bb2
+loop1.latch2:                                              ; preds = %loop1.latch1
   %add = add i32 0, 0
   %add4 = add i32 %phi, 1
-  br i1 false, label %bb2, label %bb5
+  br i1 false, label %loop1.latch1, label %loop1.latch3
+
+loop1.latch3:                                              ; preds = %loop1.latch2, %loop1.latch1
+  %phi6 = phi i32 [ %add, %loop1.latch2 ], [ 0, %loop1.latch1 ]
+  %phi7 = phi i32 [ 0, %loop1.latch2 ], [ %phi, %loop1.latch1 ]
+  br label %loop1.header
+}
+
+define i64 @regression3() {
+; CHECK-LABEL: define i64 @regression3() {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[ASHR:%.*]] = ashr i64 0, 1
+; CHECK-NEXT:    br label %[[LOOP2_HEADER:.*]]
+; CHECK:       [[FUNCEXITSPLIT:.*]]:
+; CHECK-NEXT:    [[PHI6_LCSSA:%.*]] = phi i64 [ [[PHI6:%.*]], %[[LOOP1_HEADER:.*]] ]
+; CHECK-NEXT:    br label %[[FUNCEXIT:.*]]
+; CHECK:       [[FUNCEXIT]]:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[ASHR]], %[[LOOP1_LATCH_FUNCEXIT_CRIT_EDGE:.*]] ], [ [[PHI6_LCSSA]], %[[FUNCEXITSPLIT]] ]
+; CHECK-NEXT:    ret i64 [[PHI]]
+; CHECK:       [[LOOP2_HEADER]]:
+; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], %[[LOOP2_LATCH:.*]] ], [ [[ASHR]], %[[ENTRY]] ]
+; CHECK-NEXT:    br i1 false, label %[[LOOP2_LATCH]], label %[[LOOP1_HEADER_PREHEADER:.*]]
+; CHECK:       [[LOOP1_HEADER_PREHEADER]]:
+; CHECK-NEXT:    br label %[[LOOP1_HEADER]]
+; CHECK:       [[LOOP2_LATCH]]:
+; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i64 [[LSR_IV]], 0
+; CHECK-NEXT:    [[LSR_IV_NEXT]] = add nuw nsw i64 [[LSR_IV]], -1
+; CHECK-NEXT:    br label %[[LOOP2_HEADER]]
+; CHECK:       [[LOOP1_HEADER]]:
+; CHECK-NEXT:    [[PHI6]] = phi i64 [ 0, %[[LOOP1_LATCH:.*]] ], [ 1, %[[LOOP1_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    br i1 false, label %[[LOOP1_LATCH]], label %[[FUNCEXITSPLIT]]
+; CHECK:       [[LOOP1_LATCH]]:
+; CHECK-NEXT:    br i1 false, label %[[LOOP1_LATCH_FUNCEXIT_CRIT_EDGE]], label %[[LOOP1_HEADER]]
+; CHECK:       [[LOOP1_LATCH_FUNCEXIT_CRIT_EDGE]]:
+; CHECK-NEXT:    br label %[[FUNCEXIT]]
+;
+entry:
+  %ashr = ashr i64 0, 1
+  br label %loop2.header
+
+funcexit:                                              ; preds = %loop1.latch, %loop1.header
+  %phi = phi i64 [ %phi6, %loop1.header ], [ %ashr, %loop1.latch ]
+  ret i64 %phi
+
+loop2.header:                                              ; preds = %loop2.latch, %entry
+  %phi3 = phi i64 [ 0, %entry ], [ %add, %loop2.latch ]
+  br i1 false, label %loop2.latch, label %loop1.header
+
+loop2.latch:                                              ; preds = %loop2.header
+  %add = add i64 %phi3, 1
+  %icmp = icmp eq i64 %phi3, %ashr
+  br label %loop2.header
+
+loop1.header:                                              ; preds = %loop1.latch, %loop2.header
+  %phi6 = phi i64 [ 0, %loop1.latch ], [ 1, %loop2.header ]
+  br i1 false, label %loop1.latch, label %funcexit
 
-bb5:                                              ; preds = %bb3, %bb2
-  %phi6 = phi i32 [ %add, %bb3 ], [ 0, %bb2 ]
-  %phi7 = phi i32 [ 0, %bb3 ], [ %phi, %bb2 ]
-  br label %bb1
+loop1.latch:                                              ; preds = %loop1.header
+  br i1 false, label %funcexit, label %loop1.header
 }



More information about the llvm-branch-commits mailing list