Skip to content

Commit f42482d

Browse files
authored
[DebugInfo][RemoveDIs] Don't convert debug-intrinsics to Unreachable (#72380)
It might seem obvious, but it's not a good idea to convert a debug-intrinsic instruction into an UnreachableInst, as this means things operate differently with and without the -g option. However this can happen due to the "mutate the next instruction" API calls we make. With RemoveDIs eliminating debug intrinsics, this behaviour is at risk of changing, hence this patch ensures we only ever mutate the next _non_ debuginfo instruction into an Unreachable. The tests instrumented with the --try... flag all exercise this, I've added some metadata to a SCCP test to ensure it's exercised.
1 parent 6352a07 commit f42482d

File tree

9 files changed

+55
-4
lines changed

9 files changed

+55
-4
lines changed

llvm/lib/Transforms/IPO/SCCP.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,11 @@ static bool runIPSCCP(
236236
// nodes in executable blocks we found values for. The function's entry
237237
// block is not part of BlocksToErase, so we have to handle it separately.
238238
for (BasicBlock *BB : BlocksToErase) {
239-
NumInstRemoved += changeToUnreachable(BB->getFirstNonPHI(),
239+
NumInstRemoved += changeToUnreachable(BB->getFirstNonPHIOrDbg(),
240240
/*PreserveLCSSA=*/false, &DTU);
241241
}
242242
if (!Solver.isBlockExecutable(&F.front()))
243-
NumInstRemoved += changeToUnreachable(F.front().getFirstNonPHI(),
243+
NumInstRemoved += changeToUnreachable(F.front().getFirstNonPHIOrDbg(),
244244
/*PreserveLCSSA=*/false, &DTU);
245245

246246
BasicBlock *NewUnreachableBB = nullptr;

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2871,10 +2871,16 @@ void InstCombinerImpl::handleUnreachableFrom(
28712871
}
28722872
if (Inst.isEHPad() || Inst.getType()->isTokenTy())
28732873
continue;
2874+
// RemoveDIs: erase debug-info on this instruction manually.
2875+
Inst.dropDbgValues();
28742876
eraseInstFromFunction(Inst);
28752877
MadeIRChange = true;
28762878
}
28772879

2880+
// RemoveDIs: to match behaviour in dbg.value mode, drop debug-info on
2881+
// terminator too.
2882+
BB->getTerminator()->dropDbgValues();
2883+
28782884
// Handle potentially dead successors.
28792885
for (BasicBlock *Succ : successors(BB))
28802886
addDeadEdge(BB, Succ, Worklist);

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,6 +2750,7 @@ unsigned llvm::changeToUnreachable(Instruction *I, bool PreserveLCSSA,
27502750
Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
27512751
DTU->applyUpdates(Updates);
27522752
}
2753+
BB->flushTerminatorDbgValues();
27532754
return NumInstrsRemoved;
27542755
}
27552756

@@ -2903,9 +2904,9 @@ static bool markAliveBlocks(Function &F,
29032904
// If we found a call to a no-return function, insert an unreachable
29042905
// instruction after it. Make sure there isn't *already* one there
29052906
// though.
2906-
if (!isa<UnreachableInst>(CI->getNextNode())) {
2907+
if (!isa<UnreachableInst>(CI->getNextNonDebugInstruction())) {
29072908
// Don't insert a call to llvm.trap right before the unreachable.
2908-
changeToUnreachable(CI->getNextNode(), false, DTU);
2909+
changeToUnreachable(CI->getNextNonDebugInstruction(), false, DTU);
29092910
Changed = true;
29102911
}
29112912
break;

llvm/test/Transforms/InstCombine/assume.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
; RUN: opt < %s -passes=instcombine -S | FileCheck --check-prefixes=CHECK,DEFAULT %s
33
; RUN: opt < %s -passes=instcombine --enable-knowledge-retention -S | FileCheck --check-prefixes=CHECK,BUNDLES %s
44

5+
; RUN: opt < %s -passes=instcombine -S --try-experimental-debuginfo-iterators | FileCheck --check-prefixes=CHECK,DEFAULT %s
6+
; RUN: opt < %s -passes=instcombine --enable-knowledge-retention -S --try-experimental-debuginfo-iterators | FileCheck --check-prefixes=CHECK,BUNDLES %s
7+
58
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
69
target triple = "x86_64-unknown-linux-gnu"
710

llvm/test/Transforms/InstCombine/unreachable-dbg-info-modified.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
2+
; RUN: opt < %s -passes=instcombine -S --try-experimental-debuginfo-iterators | FileCheck %s
23

34
; When removing the llvm.dbg.value intrinsic in the unreachable block
45
; InstCombine would incorrectly return a false Modified status.

llvm/test/Transforms/SCCP/ipsccp-branch-unresolved-undef.ll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
22
; RUN: opt < %s -S -passes=ipsccp | FileCheck %s
3+
; RUN: opt < %s -S -passes=ipsccp --try-experimental-debuginfo-iterators | FileCheck %s
4+
;; Check that @patatino is optimised to "unreachable" given that it branches on
5+
;; undef. Check too that debug intrinsics have no effect on this.
36

47
define void @main() {
58
; CHECK-LABEL: define {{[^@]+}}@main() {
@@ -17,7 +20,39 @@ define internal i1 @patatino(i1 %a) {
1720
;
1821
br i1 %a, label %ontrue, label %onfalse
1922
ontrue:
23+
call void @llvm.dbg.value(metadata i32 0, metadata !6, metadata !DIExpression()), !dbg !11
24+
call void @llvm.dbg.value(metadata i32 1, metadata !9, metadata !DIExpression()), !dbg !11
2025
ret i1 false
2126
onfalse:
27+
call void @llvm.dbg.value(metadata i32 0, metadata !6, metadata !DIExpression()), !dbg !11
28+
call void @llvm.dbg.value(metadata i32 1, metadata !9, metadata !DIExpression()), !dbg !11
2229
ret i1 false
2330
}
31+
32+
declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone
33+
34+
!llvm.module.flags = !{!21}
35+
!llvm.dbg.cu = !{!2}
36+
37+
!0 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !2, file: !20, scope: !1, type: !3)
38+
!1 = !DIFile(filename: "b.c", directory: "/private/tmp")
39+
!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", isOptimized: true, emissionKind: FullDebug, file: !20)
40+
!3 = !DISubroutineType(types: !4)
41+
!4 = !{!5}
42+
!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
43+
!6 = !DILocalVariable(name: "i", line: 2, arg: 1, scope: !0, file: !1, type: !5)
44+
!7 = !DILocation(line: 2, column: 13, scope: !0)
45+
!9 = !DILocalVariable(name: "k", line: 3, scope: !10, file: !1, type: !5)
46+
!10 = distinct !DILexicalBlock(line: 2, column: 16, file: !20, scope: !0)
47+
!11 = !DILocation(line: 3, column: 12, scope: !10)
48+
!12 = !DILocation(line: 4, column: 3, scope: !10)
49+
!13 = !DILocation(line: 5, column: 5, scope: !14)
50+
!14 = distinct !DILexicalBlock(line: 4, column: 10, file: !20, scope: !10)
51+
!15 = !DILocation(line: 6, column: 3, scope: !14)
52+
!16 = !DILocation(line: 7, column: 5, scope: !17)
53+
!17 = distinct !DILexicalBlock(line: 6, column: 10, file: !20, scope: !10)
54+
!18 = !DILocation(line: 8, column: 3, scope: !17)
55+
!19 = !DILocation(line: 9, column: 3, scope: !10)
56+
!20 = !DIFile(filename: "b.c", directory: "/private/tmp")
57+
!21 = !{i32 1, !"Debug Info Version", i32 3}
58+

llvm/test/Transforms/SimplifyCFG/PR27615-simplify-cond-br.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -strip-debug < %s | FileCheck %s
22
; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
33

4+
; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -strip-debug < %s --try-experimental-debuginfo-iterators | FileCheck %s
5+
; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s --try-experimental-debuginfo-iterators | FileCheck %s
6+
47
; Test case for BUG-27615
58
; Test that simplify cond branch produce same result for debug and non-debug builds
69
; CHECK: select i1 %or.cond, i32 -1, i32 5

llvm/test/Transforms/SimplifyCFG/branch-fold-dbg.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
3+
; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s --try-experimental-debuginfo-iterators | FileCheck %s
34

45
%0 = type { ptr, ptr }
56

llvm/test/Transforms/SimplifyCFG/dbginfo.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3+
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S --try-experimental-debuginfo-iterators | FileCheck %s
34

45
%llvm.dbg.anchor.type = type { i32, i32 }
56
%llvm.dbg.basictype.type = type { i32, ptr, ptr, ptr, i32, i64, i64, i64, i32, i32 }

0 commit comments

Comments
 (0)