Skip to content

Commit af4944f

Browse files
committed
Fix #135736: salvage debug values with replaced constants
1 parent 6db447f commit af4944f

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/Analysis/ValueTracking.h"
2626
#include "llvm/IR/DataLayout.h"
2727
#include "llvm/IR/Dominators.h"
28+
#include "llvm/IR/DebugInfo.h"
2829
#include "llvm/IR/Function.h"
2930
#include "llvm/IR/IRBuilder.h"
3031
#include "llvm/IR/InstrTypes.h"
@@ -1454,8 +1455,20 @@ static bool checkAndReplaceCondition(
14541455
return ShouldReplace;
14551456
});
14561457
NumCondsRemoved++;
1457-
if (Cmp->use_empty())
1458+
if (Cmp->use_empty()) {
1459+
SmallVector<DbgVariableIntrinsic *> DbgUsers;
1460+
SmallVector<DbgVariableRecord *> DVRUsers;
1461+
findDbgUsers(DbgUsers, Cmp, &DVRUsers);
1462+
1463+
for (auto *DVR: DVRUsers) {
1464+
auto *DTN = DT.getNode(DVR->getParent());
1465+
if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1466+
continue;
1467+
DVR->replaceVariableLocationOp(Cmp, ConstantC);
1468+
}
1469+
14581470
ToRemove.push_back(Cmp);
1471+
}
14591472
return Changed;
14601473
};
14611474

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=constraint-elimination -S | FileCheck %s
3+
4+
; Check that checkAndReplaceCondition() salvages the debug value information after replacing
5+
; the conditions (%t.1 in this test) with the speculated constants (GitHub Issue #135736).
6+
7+
define i1 @test_and_ule(i4 %x, i4 %y, i4 %z) !dbg !5 {
8+
; CHECK-LABEL: define i1 @test_and_ule(
9+
; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) !dbg [[DBG5:![0-9]+]] {
10+
; CHECK-NEXT: [[ENTRY:.*:]]
11+
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i4 [[X]], [[Y]], !dbg [[DBG11:![0-9]+]]
12+
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z]], !dbg [[DBG12:![0-9]+]]
13+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]], !dbg [[DBG13:![0-9]+]]
14+
; CHECK-NEXT: br i1 [[AND]], label %[[THEN:.*]], label %[[EXIT:.*]], !dbg [[DBG14:![0-9]+]]
15+
; CHECK: [[THEN]]:
16+
; CHECK-NEXT: #dbg_value(i1 true, [[META9:![0-9]+]], !DIExpression(), [[META15:![0-9]+]])
17+
; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, true, !dbg [[DBG16:![0-9]+]]
18+
; CHECK-NEXT: br label %[[EXIT]]
19+
; CHECK: [[EXIT]]:
20+
; CHECK-NEXT: #dbg_value(i1 poison, [[META17:![0-9]+]], !DIExpression(), [[META15]])
21+
; CHECK-NEXT: ret i1 true, !dbg [[DBG18:![0-9]+]]
22+
;
23+
entry:
24+
%c.1 = icmp ule i4 %x, %y, !dbg !11
25+
%c.2 = icmp ule i4 %y, %z, !dbg !12
26+
%t.1 = icmp ule i4 %x, %z, !dbg !13
27+
%and = and i1 %c.1, %c.2, !dbg !14
28+
br i1 %and, label %then, label %exit, !dbg !15
29+
30+
then: ; preds = %entry
31+
#dbg_value(i1 %t.1, !9, !DIExpression(), !13)
32+
%r.1 = xor i1 %t.1, %t.1, !dbg !16
33+
br label %exit
34+
35+
exit: ; preds = %bb1, %entry
36+
#dbg_value(i1 %t.1, !17, !DIExpression(), !13)
37+
ret i1 true, !dbg !18
38+
}
39+
40+
!llvm.dbg.cu = !{!0}
41+
!llvm.debugify = !{!2, !3}
42+
!llvm.module.flags = !{!4}
43+
44+
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
45+
!1 = !DIFile(filename: "temp.ll", directory: "/")
46+
!2 = !{i32 20}
47+
!3 = !{i32 17}
48+
!4 = !{i32 2, !"Debug Info Version", i32 3}
49+
!5 = distinct !DISubprogram(name: "test_and_ule", linkageName: "test_and_ule", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
50+
!6 = !DISubroutineType(types: !7)
51+
!7 = !{}
52+
!8 = !{!9}
53+
!9 = !DILocalVariable(name: "4", scope: !5, file: !1, line: 5, type: !10)
54+
!10 = !DIBasicType(name: "ty8", size: 8, encoding: DW_ATE_unsigned)
55+
!11 = !DILocation(line: 1, column: 1, scope: !5)
56+
!12 = !DILocation(line: 2, column: 1, scope: !5)
57+
!13 = !DILocation(line: 5, column: 1, scope: !5)
58+
!14 = !DILocation(line: 3, column: 1, scope: !5)
59+
!15 = !DILocation(line: 4, column: 1, scope: !5)
60+
!16 = !DILocation(line: 7, column: 1, scope: !5)
61+
!17 = !DILocalVariable(name: "6", scope: !5, file: !1, line: 7, type: !10)
62+
!18 = !DILocation(line: 20, column: 1, scope: !5)
63+
;.
64+
; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
65+
; CHECK: [[META1]] = !DIFile(filename: "temp.ll", directory: {{.*}})
66+
; CHECK: [[DBG5]] = distinct !DISubprogram(name: "test_and_ule", linkageName: "test_and_ule", scope: null, file: [[META1]], line: 1, type: [[META6:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META8:![0-9]+]])
67+
; CHECK: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
68+
; CHECK: [[META7]] = !{}
69+
; CHECK: [[META8]] = !{[[META9]]}
70+
; CHECK: [[META9]] = !DILocalVariable(name: "4", scope: [[DBG5]], file: [[META1]], line: 5, type: [[META10:![0-9]+]])
71+
; CHECK: [[META10]] = !DIBasicType(name: "ty8", size: 8, encoding: DW_ATE_unsigned)
72+
; CHECK: [[DBG11]] = !DILocation(line: 1, column: 1, scope: [[DBG5]])
73+
; CHECK: [[DBG12]] = !DILocation(line: 2, column: 1, scope: [[DBG5]])
74+
; CHECK: [[DBG13]] = !DILocation(line: 3, column: 1, scope: [[DBG5]])
75+
; CHECK: [[DBG14]] = !DILocation(line: 4, column: 1, scope: [[DBG5]])
76+
; CHECK: [[META15]] = !DILocation(line: 5, column: 1, scope: [[DBG5]])
77+
; CHECK: [[DBG16]] = !DILocation(line: 7, column: 1, scope: [[DBG5]])
78+
; CHECK: [[META17]] = !DILocalVariable(name: "6", scope: [[DBG5]], file: [[META1]], line: 7, type: [[META10]])
79+
; CHECK: [[DBG18]] = !DILocation(line: 20, column: 1, scope: [[DBG5]])
80+
;.

0 commit comments

Comments
 (0)