[llvm] [LVI] Skip self loops in `solveBlockValueNonLocal` (PR #127763)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 19 00:09:59 PST 2025
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/127763
We cannot infer more information from backedges in `solveBlockValueNonLocal`. However, since DT is unavailable in LVI, there is not a precise way to check whether a BB edge is a backedge. This patch only skips self loops to unblock the range analysis.
The motivating case is extracted from https://github.com/llvm/llvm-project/pull/127663.
Compile-time impact is high: https://llvm-compile-time-tracker.com/compare.php?from=84ddda58c870681dd12ed765e9d59d5e00567f94&to=af032f1351358f2f5b5d9f4e87c5601c23b9bd37&stat=instructions:u
>From 84ddda58c870681dd12ed765e9d59d5e00567f94 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 19 Feb 2025 14:24:46 +0800
Subject: [PATCH 1/2] [LVI] Add pre-commit tests. NFC.
---
.../CorrelatedValuePropagation/loop.ll | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 llvm/test/Transforms/CorrelatedValuePropagation/loop.ll
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll b/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll
new file mode 100644
index 0000000000000..a2be5e1a40f8a
--- /dev/null
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
+
+define i64 @test_self_loop(i64 %x, i1 %cond) {
+; CHECK-LABEL: define range(i64 0, -9223372036854775808) i64 @test_self_loop(
+; CHECK-SAME: i64 [[X:%.*]], i1 [[COND:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[COND1:%.*]] = icmp ugt i64 [[X]], 576460752303423487
+; CHECK-NEXT: br i1 [[COND1]], label %[[COMMON_RET:.*]], label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: br i1 [[COND]], label %[[INDIRECT:.*]], label %[[LOOP]]
+; CHECK: [[INDIRECT]]:
+; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT: br i1 [[COND2]], label %[[COMMON_RET]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[SMAX:%.*]] = tail call i64 @llvm.smax.i64(i64 [[X]], i64 1)
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[COMMON_RET]]:
+; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[SMAX]], %[[EXIT]] ], [ 0, %[[INDIRECT]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ %cond1 = icmp ugt i64 %x, 576460752303423487
+ br i1 %cond1, label %common.ret, label %loop
+
+loop:
+ br i1 %cond, label %indirect, label %loop
+
+indirect:
+ %cond2 = icmp eq i64 %x, 0
+ br i1 %cond2, label %common.ret, label %exit
+
+exit:
+ %smax = tail call i64 @llvm.smax.i64(i64 %x, i64 1)
+ br label %common.ret
+
+common.ret:
+ %res = phi i64 [ %smax, %exit ], [ 0, %indirect ], [ 0, %entry ]
+ ret i64 %res
+}
>From af032f1351358f2f5b5d9f4e87c5601c23b9bd37 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 19 Feb 2025 14:40:33 +0800
Subject: [PATCH 2/2] [LVI] Skip self loops in `solveBlockValueNonLocal`
---
llvm/lib/Analysis/LazyValueInfo.cpp | 3 +++
.../CorrelatedValuePropagation/loop.ll | 5 ++---
.../test/Transforms/JumpThreading/ddt-crash.ll | 18 +++++++-----------
3 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 5cd179df436de..581358a645780 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -694,6 +694,9 @@ LazyValueInfoImpl::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) {
// canonicalizing to make this true rather than relying on this happy
// accident.
for (BasicBlock *Pred : predecessors(BB)) {
+ // Skip self loops.
+ if (Pred == BB)
+ continue;
std::optional<ValueLatticeElement> EdgeResult = getEdgeValue(Val, Pred, BB);
if (!EdgeResult)
// Explore that input, then return here
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll b/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll
index a2be5e1a40f8a..41e5be78ace8a 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll
@@ -2,7 +2,7 @@
; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
define i64 @test_self_loop(i64 %x, i1 %cond) {
-; CHECK-LABEL: define range(i64 0, -9223372036854775808) i64 @test_self_loop(
+; CHECK-LABEL: define range(i64 0, 576460752303423488) i64 @test_self_loop(
; CHECK-SAME: i64 [[X:%.*]], i1 [[COND:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[COND1:%.*]] = icmp ugt i64 [[X]], 576460752303423487
@@ -13,10 +13,9 @@ define i64 @test_self_loop(i64 %x, i1 %cond) {
; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[X]], 0
; CHECK-NEXT: br i1 [[COND2]], label %[[COMMON_RET]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
-; CHECK-NEXT: [[SMAX:%.*]] = tail call i64 @llvm.smax.i64(i64 [[X]], i64 1)
; CHECK-NEXT: br label %[[COMMON_RET]]
; CHECK: [[COMMON_RET]]:
-; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[SMAX]], %[[EXIT]] ], [ 0, %[[INDIRECT]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[X]], %[[EXIT]] ], [ 0, %[[INDIRECT]] ], [ 0, %[[ENTRY]] ]
; CHECK-NEXT: ret i64 [[RES]]
;
entry:
diff --git a/llvm/test/Transforms/JumpThreading/ddt-crash.ll b/llvm/test/Transforms/JumpThreading/ddt-crash.ll
index b0bba1a2dd0c4..94ab4791f1664 100644
--- a/llvm/test/Transforms/JumpThreading/ddt-crash.ll
+++ b/llvm/test/Transforms/JumpThreading/ddt-crash.ll
@@ -131,20 +131,16 @@ define void @spam(ptr %arg, i1 %arg2) {
; CHECK: bb31:
; CHECK-NEXT: [[TMP32:%.*]] = phi i8 [ [[TMP32]], [[BB31]] ], [ [[TMP32_PR]], [[BB30]] ]
; CHECK-NEXT: [[TMP33:%.*]] = icmp eq i8 [[TMP32]], 0
-; CHECK-NEXT: br i1 [[TMP33]], label [[BB31]], label [[BB37]]
+; CHECK-NEXT: br i1 [[TMP33]], label [[BB31]], label [[BB41_THREAD]]
; CHECK: bb37:
-; CHECK-NEXT: [[TMP36:%.*]] = phi i1 [ false, [[BB23]] ], [ true, [[BB31]] ]
+; CHECK-NEXT: [[TMP36:%.*]] = phi i1 [ false, [[BB23]] ]
; CHECK-NEXT: [[TMP38:%.*]] = icmp eq ptr [[TMP15]], null
-; CHECK-NEXT: br i1 [[TMP38]], label [[BB39:%.*]], label [[BB41:%.*]]
-; CHECK: bb39:
-; CHECK-NEXT: [[TMP364:%.*]] = phi i1 [ [[TMP36]], [[BB37]] ]
-; CHECK-NEXT: [[TMP40:%.*]] = load ptr, ptr @global, align 8
-; CHECK-NEXT: br i1 [[TMP364]], label [[BB41_THREAD]], label [[BB41_THREAD]]
+; CHECK-NEXT: br i1 [[TMP38]], label [[BB41:%.*]], label [[BB41_THREAD]]
; CHECK: bb41:
-; CHECK-NEXT: [[TMP363:%.*]] = phi i1 [ [[TMP36]], [[BB37]] ]
-; CHECK-NEXT: br i1 [[TMP363]], label [[BB41_THREAD]], label [[BB41_THREAD]]
-; CHECK: bb41.thread:
-; CHECK-NEXT: [[TMP0:%.*]] = phi ptr [ undef, [[BB41]] ], [ undef, [[BB39]] ], [ undef, [[BB39]] ], [ undef, [[BB41]] ], [ undef, [[BB27]] ], [ undef, [[BB25]] ]
+; CHECK-NEXT: [[TMP40:%.*]] = load ptr, ptr @global, align 8
+; CHECK-NEXT: br label [[BB41_THREAD]]
+; CHECK: bb41.thread11:
+; CHECK-NEXT: [[TMP0:%.*]] = phi ptr [ undef, [[BB41]] ], [ undef, [[BB25]] ], [ undef, [[BB31]] ], [ undef, [[BB27]] ], [ undef, [[BB37]] ]
; CHECK-NEXT: ret void
;
bb:
More information about the llvm-commits
mailing list