[llvm] [LVI] Skip self loops in `solveBlockValueNonLocal` (PR #127763)

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 19 04:59:11 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Yingwei Zheng (dtcxzyw)

<details>
<summary>Changes</summary>

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


---
Full diff: https://github.com/llvm/llvm-project/pull/127763.diff


3 Files Affected:

- (modified) llvm/lib/Analysis/LazyValueInfo.cpp (+3) 
- (added) llvm/test/Transforms/CorrelatedValuePropagation/loop.ll (+39) 
- (modified) llvm/test/Transforms/JumpThreading/ddt-crash.ll (+7-11) 


``````````diff
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
new file mode 100644
index 0000000000000..41e5be78ace8a
--- /dev/null
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/loop.ll
@@ -0,0 +1,39 @@
+; 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, 576460752303423488) 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:    br label %[[COMMON_RET]]
+; CHECK:       [[COMMON_RET]]:
+; CHECK-NEXT:    [[RES:%.*]] = phi i64 [ [[X]], %[[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
+}
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:

``````````

</details>


https://github.com/llvm/llvm-project/pull/127763


More information about the llvm-commits mailing list