[llvm] [DebugInfo][SimplifyCFG] Specialize cloned PHI debug values per predecessor (PR #221905)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 02:03:17 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: MrEven132
<details>
<summary>Changes</summary>
SimplifyCFG can fold a block containing a PHI node into predecessor branches. The transformed IR specializes the PHI uses correctly, but cloned debug values could describe the same incoming value in both branches. This patch keeps the debug record operand remapping consistent with the predecessor-specific PHI incoming value and adds a regression test.
Fixes #<!-- -->219931.
---
Full diff: https://github.com/llvm/llvm-project/pull/221905.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Utils/SimplifyCFG.cpp (+16-6)
- (added) llvm/test/Transforms/SimplifyCFG/phi-debug-value.ll (+60)
``````````diff
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 2a3a88713920b..8cc8a77555c69 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3763,11 +3763,16 @@ static std::optional<bool> foldCondBranchOnValueKnownInPredecessorImpl(
// Copy all debug-info attached to instructions from the last we
// successfully clone, up to this instruction (they might have been
// folded away).
- for (; SrcDbgCursor != BBI; ++SrcDbgCursor)
- N->cloneDebugInfoFrom(&*SrcDbgCursor);
+ for (; SrcDbgCursor != BBI; ++SrcDbgCursor) {
+ auto Range = N->cloneDebugInfoFrom(&*SrcDbgCursor);
+ RemapDbgRecordRange(N->getModule(), Range, TranslateMap,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+ }
SrcDbgCursor = std::next(BBI);
// Clone debug-info on this instruction too.
- N->cloneDebugInfoFrom(&*BBI);
+ auto Range = N->cloneDebugInfoFrom(&*BBI);
+ RemapDbgRecordRange(N->getModule(), Range, TranslateMap,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
// Register the new instruction with the assumption cache if necessary.
if (auto *Assume = dyn_cast<AssumeInst>(N))
@@ -3776,9 +3781,14 @@ static std::optional<bool> foldCondBranchOnValueKnownInPredecessorImpl(
}
}
- for (; &*SrcDbgCursor != BI; ++SrcDbgCursor)
- InsertPt->cloneDebugInfoFrom(&*SrcDbgCursor);
- InsertPt->cloneDebugInfoFrom(BI);
+ for (; &*SrcDbgCursor != BI; ++SrcDbgCursor) {
+ auto Range = InsertPt->cloneDebugInfoFrom(&*SrcDbgCursor);
+ RemapDbgRecordRange(InsertPt->getModule(), Range, TranslateMap,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+ }
+ auto Range = InsertPt->cloneDebugInfoFrom(BI);
+ RemapDbgRecordRange(InsertPt->getModule(), Range, TranslateMap,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
BB->removePredecessor(EdgeBB);
UncondBrInst *EdgeBI = cast<UncondBrInst>(EdgeBB->getTerminator());
diff --git a/llvm/test/Transforms/SimplifyCFG/phi-debug-value.ll b/llvm/test/Transforms/SimplifyCFG/phi-debug-value.ll
new file mode 100644
index 0000000000000..f6fa45eda57f0
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/phi-debug-value.ll
@@ -0,0 +1,60 @@
+; RUN: opt -passes=simplifycfg -S < %s | FileCheck %s
+
+; The PHI value is specialized independently in each predecessor when the PHI
+; block is duplicated. Its debug value must be specialized in the same way.
+
+; CHECK-LABEL: define void @phi_extra_use(
+; CHECK: cond.true:
+; CHECK-NEXT: call void @foo()
+; CHECK-NEXT: #dbg_value(i1 true, ![[VAR:[0-9]+]], !DIExpression(), ![[LOC:[0-9]+]])
+; CHECK-NEXT: call void @use_bool(i1 true)
+; CHECK: cond.false:
+; CHECK-NEXT: call void @bar()
+; CHECK-NEXT: #dbg_value(i1 false, ![[VAR]], !DIExpression(), ![[LOC]])
+; CHECK-NEXT: call void @use_bool(i1 false)
+
+declare void @foo()
+declare void @bar()
+declare void @use_bool(i1)
+
+define void @phi_extra_use(i1 %c1) !dbg !5 {
+entry:
+ br i1 %c1, label %cond.true, label %cond.false
+
+cond.true:
+ call void @foo()
+ br label %cond.end
+
+cond.false:
+ call void @bar()
+ br label %cond.end
+
+cond.end:
+ %cond = phi i1 [ true, %cond.true ], [ false, %cond.false ]
+ #dbg_value(i1 %cond, !7, !DIExpression(), !6)
+ call void @use_bool(i1 %cond)
+ br i1 %cond, label %if.then, label %if.else
+
+if.then:
+ call void @foo()
+ br label %if.end
+
+if.else:
+ call void @bar()
+ br label %if.end
+
+if.end:
+ ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!1, !2}
+!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "llvm", emissionKind: FullDebug)
+!1 = !{i32 2, !"Debug Info Version", i32 3}
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !DIFile(filename: "phi-debug-value.c", directory: "/tmp")
+!4 = !DISubroutineType(types: !{})
+!5 = distinct !DISubprogram(name: "phi_extra_use", scope: !3, file: !3, line: 1, type: !4, unit: !0, spFlags: DISPFlagDefinition)
+!6 = !DILocation(line: 2, scope: !5)
+!7 = !DILocalVariable(name: "c2", scope: !5, file: !3, line: 2, type: !8)
+!8 = !DIBasicType(name: "bool", size: 1, encoding: DW_ATE_boolean)
``````````
</details>
https://github.com/llvm/llvm-project/pull/221905
More information about the llvm-commits
mailing list