[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 23:11:36 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 1/2] 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
}
>From 85c72a3fddf2b74dbd109df886ac44f2c0aace7d Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Sun, 19 Apr 2026 06:11:25 +0000
Subject: [PATCH 2/2] fix
Created using spr 1.3.7
---
llvm/test/Transforms/LoopStrengthReduce/uglygep.ll | 3 ++-
llvm/test/Transforms/LoopStrengthReduce/wrong-hoisting-iv.ll | 5 +++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/test/Transforms/LoopStrengthReduce/uglygep.ll b/llvm/test/Transforms/LoopStrengthReduce/uglygep.ll
index 2500fb7d8cf7d..444fffe3c4ee4 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/uglygep.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/uglygep.ll
@@ -85,10 +85,11 @@ define fastcc void @TransformLine() nounwind {
; CHECK-NEXT: [[TMP0:%.*]] = add i32 -1, [[I1_NEXT_LCSSA]]
; CHECK-NEXT: br label [[BB6SPLIT:%.*]]
; CHECK: bb6splitsplit:
+; CHECK-NEXT: [[I1_LCSSA3:%.*]] = phi i32 [ [[I1]], [[BB2]] ]
; CHECK-NEXT: br label [[BB6SPLIT]]
; CHECK: bb6split:
; CHECK-NEXT: [[P8_PH:%.*]] = phi i32 [ [[TMP0]], [[BB5_BB6SPLIT_CRIT_EDGE]] ], [ undef, [[BB6SPLITSPLIT]] ]
-; CHECK-NEXT: [[P9_PH:%.*]] = phi i32 [ undef, [[BB5_BB6SPLIT_CRIT_EDGE]] ], [ [[I1]], [[BB6SPLITSPLIT]] ]
+; CHECK-NEXT: [[P9_PH:%.*]] = phi i32 [ undef, [[BB5_BB6SPLIT_CRIT_EDGE]] ], [ [[I1_LCSSA3]], [[BB6SPLITSPLIT]] ]
; CHECK-NEXT: br label [[BB6:%.*]]
; CHECK: loop1.bb6_crit_edge:
; CHECK-NEXT: [[I1_LCSSA:%.*]] = phi i32 [ [[I1]], [[LOOP1]] ]
diff --git a/llvm/test/Transforms/LoopStrengthReduce/wrong-hoisting-iv.ll b/llvm/test/Transforms/LoopStrengthReduce/wrong-hoisting-iv.ll
index 865bb832b37ad..b5d78495ecc28 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/wrong-hoisting-iv.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/wrong-hoisting-iv.ll
@@ -36,13 +36,14 @@ define void @test1() {
; CHECK-NEXT: [[VAL14:%.*]] = icmp slt i32 undef, undef
; CHECK-NEXT: br i1 [[VAL14]], label [[BB17:%.*]], label [[BB12_BB15SPLITSPLITSPLITSPLITSPLIT_CRIT_EDGE:%.*]]
; CHECK: bb15splitsplitsplitsplitsplitsplit:
+; CHECK-NEXT: [[VAL35:%.*]] = phi i32 [ [[VAL36:%.*]], [[BB32]] ]
; CHECK-NEXT: br label [[BB15SPLITSPLITSPLITSPLITSPLIT:%.*]]
; CHECK: bb12.bb15splitsplitsplitsplitsplit_crit_edge:
; CHECK-NEXT: [[LSR_IV1_LCSSA23:%.*]] = phi i32 [ [[LSR_IV1]], [[BB12]] ]
; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[LSR_IV1_LCSSA23]], [[VAL6]]
; CHECK-NEXT: br label [[BB15SPLITSPLITSPLITSPLITSPLIT]]
; CHECK: bb15splitsplitsplitsplitsplit:
-; CHECK-NEXT: [[VAL16_PH_PH_PH_PH_PH:%.*]] = phi i32 [ [[TMP6]], [[BB12_BB15SPLITSPLITSPLITSPLITSPLIT_CRIT_EDGE]] ], [ [[VAL35:%.*]], [[BB15SPLITSPLITSPLITSPLITSPLITSPLIT:%.*]] ]
+; CHECK-NEXT: [[VAL16_PH_PH_PH_PH_PH:%.*]] = phi i32 [ [[TMP6]], [[BB12_BB15SPLITSPLITSPLITSPLITSPLIT_CRIT_EDGE]] ], [ [[VAL35]], [[BB15SPLITSPLITSPLITSPLITSPLITSPLIT:%.*]] ]
; CHECK-NEXT: br label [[BB15SPLITSPLITSPLITSPLIT:%.*]]
; CHECK: bb17.bb15splitsplitsplitsplit_crit_edge:
; CHECK-NEXT: [[LSR_IV1_LCSSA18:%.*]] = phi i32 [ [[LSR_IV1]], [[BB17]] ]
@@ -127,7 +128,7 @@ define void @test1() {
; CHECK-NEXT: br i1 [[VAL31]], label [[BB32]], label [[BB29_BB15_CRIT_EDGE]]
; CHECK: bb32:
; CHECK-NEXT: [[TMP42:%.*]] = add i32 [[TMP4]], [[LSR_IV1]]
-; CHECK-NEXT: [[VAL35]] = add i32 [[TMP42]], [[VAL6]]
+; CHECK-NEXT: [[VAL36]] = add i32 [[TMP42]], [[VAL6]]
; CHECK-NEXT: br i1 false, label [[BB7]], label [[BB15SPLITSPLITSPLITSPLITSPLITSPLIT]]
;
bb:
More information about the llvm-branch-commits
mailing list