aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorFelipe de Azevedo Piovezan <fpiovezan@apple.com>2023-01-19 12:02:28 -0300
committerFelipe de Azevedo Piovezan <fpiovezan@apple.com>2023-01-30 11:17:36 -0500
commit055f2f04e658c7dddd1fc261e5e0c0bd136cc2b5 (patch)
tree33c02305b5d89e5da615695e229d1b2324c51bc7 /llvm/lib/Transforms/Utils/Local.cpp
parent8f6c623e874624c1f247f93bf457d5196a84cec6 (diff)
downloadllvm-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.cpp33
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);
}