[llvm-bugs] [Bug 45667] New: FoldBranchToCommonDest in SimplifyCFG can invalidate dbg.value operands
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Apr 24 23:39:59 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=45667
Bug ID: 45667
Summary: FoldBranchToCommonDest in SimplifyCFG can invalidate
dbg.value operands
Product: libraries
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: Transformation Utilities
Assignee: unassignedbugs at nondot.org
Reporter: ricky at rzhou.org
CC: llvm-bugs at lists.llvm.org
Reproduction case:
Compiling the following program (https://godbolt.org/z/y2nzqR):
```
int main(int argc, char** argv) {
bool a = false;
bool b = false;
bool c = false;
[&a, &b, &c] { b = true; }();
if (a || b || c) {
__builtin_debugtrap();
}
return 0;
}
```
with
```
clang++ -O1 -g -fno-exceptions -o test test.cc
```
produces incorrect DWARF debugging information for the "b" variable. This can
be seen by running the program in lldb and printing "b" at the breakpoint:
```
$ lldb ~/test
(lldb) target create ".../test"
Current executable set to '.../test' (x86_64).
(lldb) r
Process 90101 launched: '.../test' (x86_64)
Process 90101 stopped
* thread #1, name = 'test', stop reason = signal SIGTRAP
frame #0: 0x000000000040115a test`main(argc=<unavailable>,
argv=<unavailable>) at test.cc:12:1
9 }
10
11 return 0;
-> 12 }
(lldb) p b
(bool) $0 = false
```
The LLVM IR at the goldbolt link shows the issue. When "a", "b", and "c" are
initialized to 0, the original dbg.declare for these variables is replaced with
a dbg.value:
```
...
call void @llvm.dbg.value(metadata i8 0, metadata !18, metadata
!DIExpression()), !dbg !22
store i8 0, i8* %a, align 1, !dbg !24, !tbaa !25
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %b) #3, !dbg !29
call void @llvm.dbg.value(metadata i8 0, metadata !20, metadata
!DIExpression()), !dbg !22
store i8 0, i8* %b, align 1, !dbg !30, !tbaa !25
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %c) #3, !dbg !31
call void @llvm.dbg.value(metadata i8 0, metadata !21, metadata
!DIExpression()), !dbg !22
store i8 0, i8* %c, align 1, !dbg !32, !tbaa !25
... call to lambda ...
%4 = load i8, i8* %a, align 1, !dbg !36, !tbaa !25, !range !38
call void @llvm.dbg.value(metadata i8 %4, metadata !18, metadata
!DIExpression()), !dbg !22
%5 = load i8, i8* %b, align 1, !dbg !39
%6 = or i8 %5, %4, !dbg !40
%7 = load i8, i8* %c, align 1, !dbg !41
%8 = or i8 %6, %7, !dbg !40
...
```
when "a" is loaded after calling the lambda, we emit an updated dbg.value for
it. However, "b" and "c" do not get one.
I into where this breaks by compiling with `-mllvm -print-after-all -mllvm
-print-before-all`, and found that there were valid-looking dbg.value
intrinsics the loads of "b" and "c" a "Simplify the CFG" phase invalidated
them, replacing them with a call like this:
```
!2 = !{}
...
call void @llvm.dbg.value(metadata !2, metadata !20, metadata
!DIExpression()), !dbg !30
```
Then an "Early CSE w/ MemorySSA" phase discards these intrinsics entirely, as
they fail this test:
https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/Utils/Local.cpp#L385
The transformation producing the invalidated dbg.value appears to be
SimplifyCFG rewriting:
```
if (a)
if (b)
if (c) ...
```
to
```
if (a || b || c) ...
```
Looking at the code that does this,
https://github.com/llvm-mirror/llvm/blob/master/lib/Transforms/Utils/SimplifyCFG.cpp#L2731-L2749
appears to clone some instructions into a different basic block.
https://github.com/llvm-mirror/llvm/blob/master/lib/Transforms/Utils/SimplifyCFG.cpp#L2868-L2870
then clones dbg intrinsics over, but does not update their operands to point to
the appropriate cloned values.
The following patch fixes up the dbg.value operands for me and causes
correct-looking debug info to be generated:
```
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index be5a375a2cf..73db4728ef3 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2898,9 +2898,14 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI,
MemorySSAUpdater *MSSAU,
// could replace PBI's branch probabilities with BI's.
// Copy any debug value intrinsics into the end of PredBlock.
- for (Instruction &I : *BB)
- if (isa<DbgInfoIntrinsic>(I))
- I.clone()->insertBefore(PBI);
+ for (Instruction &I : *BB) {
+ if (isa<DbgInfoIntrinsic>(I)) {
+ Instruction *NewI = I.clone();
+ RemapInstruction(NewI, VMap,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+ NewI->insertBefore(PBI);
+ }
+ }
return true;
}
```
Note that even with this patch, the generated DWARF information is not ideal.
"b" becomes "optimized out" at the breakpoint, even though it is on the stack.
It seems that replacing dbg.declare with dbg.value was counterproductive in
this case.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200425/325b3a9c/attachment-0001.html>
More information about the llvm-bugs
mailing list