diff options
author | Felipe de Azevedo Piovezan <fpiovezan@apple.com> | 2023-01-19 12:02:28 -0300 |
---|---|---|
committer | Felipe de Azevedo Piovezan <fpiovezan@apple.com> | 2023-01-30 11:17:36 -0500 |
commit | 055f2f04e658c7dddd1fc261e5e0c0bd136cc2b5 (patch) | |
tree | 33c02305b5d89e5da615695e229d1b2324c51bc7 /llvm/lib/Transforms/Utils/Local.cpp | |
parent | 8f6c623e874624c1f247f93bf457d5196a84cec6 (diff) | |
download | llvm-055f2f04e658c7dddd1fc261e5e0c0bd136cc2b5.zip llvm-055f2f04e658c7dddd1fc261e5e0c0bd136cc2b5.tar.gz llvm-055f2f04e658c7dddd1fc261e5e0c0bd136cc2b5.tar.bz2 |
[mem2reg][debuginfo] Handle op_deref when converting dbg.declare
The conversion of dbg.declare into dbg.values doesn't take into account
the DIExpression attached to the intrinsic. In particular, when
converting:
```
store %val, ptr %alloca
dbg.declare(ptr %alloca, !SomeVar, !DIExpression())
```
Mem2Reg will try to figure out if `%val` has the size of `!SomeVar`. If
it does, then a non-undef dbg.value is inserted:
```
dbg.value(%val, !SomeVar, !DIExpression())
```
This makes sense: the alloca is _the_ address of the variable. So a
store to the alloca is a store to the variable. However, if the
expression in the original intrinsic is a `DW_OP_deref`, this logic is
not applicable:
```
store ptr %val, ptr %alloca
dbg.declare(ptr %alloca, !SomeVar, !DIExpression(DW_OP_deref))
```
Here, the alloca is *not* the address of the variable. A store to the
alloca is *not* a store to the variable. As such, querying whether
`%val` has the same size as `!SomeVar` is meaningless.
This patch addresses the issue by:
1. Allowing the conversion when the expression is _only_ a `DW_OP_deref`
without any other expressions (see code comment).
2. Checking that the expression does not start with a `DW_OP_deref`
before applying the logic that checks whether the value being stored and
the variable have the same length.
Differential Revision: https://reviews.llvm.org/D142160
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 633f0bb..b6c6c5a 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1524,19 +1524,34 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, DebugLoc NewLoc = getDebugValueLoc(DII); - if (!valueCoversEntireFragment(DV->getType(), DII)) { - // FIXME: If storing to a part of the variable described by the dbg.declare, - // then we want to insert a dbg.value for the corresponding fragment. - LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " - << *DII << '\n'); - // For now, when there is a store to parts of the variable (but we do not - // know which part) we insert an dbg.value intrinsic to indicate that we - // know nothing about the variable's content. - DV = UndefValue::get(DV->getType()); + // If the alloca describes the variable itself, i.e. the expression in the + // dbg.declare doesn't start with a dereference, we can perform the + // conversion if the value covers the entire fragment of DII. + // If the alloca describes the *address* of DIVar, i.e. DIExpr is + // *just* a DW_OP_deref, we use DV as is for the dbg.value. + // We conservatively ignore other dereferences, because the following two are + // not equivalent: + // dbg.declare(alloca, ..., !Expr(deref, plus_uconstant, 2)) + // dbg.value(DV, ..., !Expr(deref, plus_uconstant, 2)) + // The former is adding 2 to the address of the variable, whereas the latter + // is adding 2 to the value of the variable. As such, we insist on just a + // deref expression. + bool CanConvert = + DIExpr->isDeref() || (!DIExpr->startsWithDeref() && + valueCoversEntireFragment(DV->getType(), DII)); + if (CanConvert) { Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, SI); return; } + // FIXME: If storing to a part of the variable described by the dbg.declare, + // then we want to insert a dbg.value for the corresponding fragment. + LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " << *DII + << '\n'); + // For now, when there is a store to parts of the variable (but we do not + // know which part) we insert an dbg.value intrinsic to indicate that we + // know nothing about the variable's content. + DV = UndefValue::get(DV->getType()); Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, SI); } |