[llvm] [GVN] Skip debug instructions in findDominatingValue function (PR #65977)

Sergey Kachkov via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 12 05:35:55 PDT 2023


https://github.com/skachkov-sc updated https://github.com/llvm/llvm-project/pull/65977:

>From e152ed60d7348ccfcd0d36c45e80954e1c12137c Mon Sep 17 00:00:00 2001
From: Sergey Kachkov <sergey.kachkov at syntacore.com>
Date: Mon, 11 Sep 2023 19:11:27 +0300
Subject: [PATCH 1/2] [GVN] Add pre-commit test

---
 .../Transforms/GVN/load-through-select-dbg.ll | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 llvm/test/Transforms/GVN/load-through-select-dbg.ll

diff --git a/llvm/test/Transforms/GVN/load-through-select-dbg.ll b/llvm/test/Transforms/GVN/load-through-select-dbg.ll
new file mode 100644
index 000000000000000..9fd9b72cf2d4071
--- /dev/null
+++ b/llvm/test/Transforms/GVN/load-through-select-dbg.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt < %s -passes=gvn -gvn-max-num-visited-insts=4 -S | FileCheck %s
+
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+define i32 @foo(ptr %a, ptr %b) {
+; CHECK-LABEL: define i32 @foo(
+; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A]], align 4
+; CHECK-NEXT:    call void @llvm.dbg.declare(metadata ptr undef, metadata [[META4:![0-9]+]], metadata !DIExpression()), !dbg [[DBG10:![0-9]+]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B]], align 4
+; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[COND]], ptr [[A]], ptr [[B]]
+; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    ret i32 [[RES]]
+;
+entry:
+  %0 = load i32, ptr %a, align 4
+  call void @llvm.dbg.declare(metadata ptr undef, metadata !46, metadata !DIExpression()), !dbg !40
+  %1 = load i32, ptr %b, align 4
+  %cond = icmp slt i32 %0, %1
+  %ptr = select i1 %cond, ptr %a, ptr %b
+  %res = load i32, ptr %ptr, align 4
+  ret i32 %res
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!35, !36}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0.prerel", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "bbi-78272.c", directory: "/tmp")
+!5 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
+
+!35 = !{i32 7, !"Dwarf Version", i32 4}
+!36 = !{i32 2, !"Debug Info Version", i32 3}
+!40 = !DILocation(line: 15, column: 7, scope: !41)
+!41 = distinct !DISubprogram(name: "x", scope: !1, file: !1, line: 14, type: !42, scopeLine: 14, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !45)
+!42 = !DISubroutineType(types: !43)
+!43 = !{!5}
+!45 = !{!46}
+!46 = !DILocalVariable(name: "t", scope: !41, file: !1, line: 15, type: !5)

>From 1cab01e6667cd4cdbcab25eaf8403c524d007f6a Mon Sep 17 00:00:00 2001
From: Sergey Kachkov <sergey.kachkov at syntacore.com>
Date: Mon, 11 Sep 2023 19:05:27 +0300
Subject: [PATCH 2/2] [GVN] Skip debug instructions in findDominatingValue
 function

findDominatingValue has a search limit, and when it is reached, optimization is
not applied. This patch fixes the issue that this limit also takes into account
debug intrinsics, so the result of optimization can depend from the presence of
debug info.
---
 llvm/lib/Transforms/Scalar/GVN.cpp                  | 6 ++----
 llvm/test/Transforms/GVN/load-through-select-dbg.ll | 4 ++--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index aaa757f48d08c4e..041591553499f63 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1147,13 +1147,11 @@ static Value *findDominatingValue(const MemoryLocation &Loc, Type *LoadTy,
   BasicBlock *FromBB = From->getParent();
   BatchAAResults BatchAA(*AA);
   for (BasicBlock *BB = FromBB; BB; BB = BB->getSinglePredecessor())
-    for (auto I = BB == FromBB ? From->getReverseIterator() : BB->rbegin(),
-              E = BB->rend();
-         I != E; ++I) {
+    for (auto *Inst = BB == FromBB ? From : BB->getTerminator();
+         Inst != nullptr; Inst = Inst->getPrevNonDebugInstruction()) {
       // Stop the search if limit is reached.
       if (++NumVisitedInsts > MaxNumVisitedInsts)
         return nullptr;
-      Instruction *Inst = &*I;
       if (isModSet(BatchAA.getModRefInfo(Inst, Loc)))
         return nullptr;
       if (auto *LI = dyn_cast<LoadInst>(Inst))
diff --git a/llvm/test/Transforms/GVN/load-through-select-dbg.ll b/llvm/test/Transforms/GVN/load-through-select-dbg.ll
index 9fd9b72cf2d4071..933e727c09cf73c 100644
--- a/llvm/test/Transforms/GVN/load-through-select-dbg.ll
+++ b/llvm/test/Transforms/GVN/load-through-select-dbg.ll
@@ -11,9 +11,9 @@ define i32 @foo(ptr %a, ptr %b) {
 ; CHECK-NEXT:    call void @llvm.dbg.declare(metadata ptr undef, metadata [[META4:![0-9]+]], metadata !DIExpression()), !dbg [[DBG10:![0-9]+]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B]], align 4
 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND]], i32 [[TMP0]], i32 [[TMP1]]
 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[COND]], ptr [[A]], ptr [[B]]
-; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[PTR]], align 4
-; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
 entry:
   %0 = load i32, ptr %a, align 4



More information about the llvm-commits mailing list