[llvm] [RemoveDIs][DebugInfo] Handle RAUW from dead constants (PR #80837)

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 6 06:29:25 PST 2024


https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/80837

Currently when a constant value dies, all `ValueAsMetadata` uses of that constant will be replaced with `nullptr`. For debug info intrinsics, this `RAUW` operation ends up being passed to `MetadataAsValue`, which canonicalizes the `nullptr` argument, replacing it with an empty `MDNode`, `!{}` (this is one of the only ways that an `MDNode` can be the first argument of a debug intrinsic). Since DPValues don't use `MetadataAsValue`, this is skipped and we end up with just a `nullptr`; currently this doesn't cause any problems because for most operations we use a wrapper that translates nullness, but will cause problems when we start printing DPValues, and should be considered an invalid state.

There are no tests for this change because currently any `nullptr` argument in a DPValue will be replaced with `!{}` when we convert it back to a debug intrinsic before printing, meaning this change is "NFC" for now. Instead, this patch adds an assert before converting back to debug intrinsics, which will cause the following tests to fail without the functional change:
```
llvm/test/Transforms/Inline/delete-function-with-metadata-use.ll
llvm/test/DebugInfo/X86/array2.ll
```

Hopefully this also paves the way to eliminating instances of empty `MDNodes` appearing in DPValues at any time as well, but there may be other cases that introduce them as well (@OCHyams may be familiar?).

>From 77db15e23c549ab0bcbf79fad2e2b2e8427afe7d Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Thu, 18 Jan 2024 21:20:25 +0000
Subject: [PATCH] Handle RAUW from dead constants

---
 llvm/lib/IR/DebugProgramInstruction.cpp | 1 +
 llvm/lib/IR/Metadata.cpp                | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index 03085b3bfd127..5b9382fec88fd 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -286,6 +286,7 @@ DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
   // Create the intrinsic from this DPValue's information, optionally insert
   // into the target location.
   DbgVariableIntrinsic *DVI;
+  assert(getRawLocation() && "DPValue's RawLocation should be non-null.");
   if (isDbgAssign()) {
     Value *AssignArgs[] = {
         MetadataAsValue::get(Context, getRawLocation()),
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 37017a222d485..06db91fe4f8e7 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -158,6 +158,12 @@ void DebugValueUser::handleChangedValue(void *Old, Metadata *New) {
   // getOwner, if needed.
   auto OldMD = static_cast<Metadata **>(Old);
   ptrdiff_t Idx = std::distance(&*DebugValues.begin(), OldMD);
+  // If replacing a ValueAsMetadata with a nullptr, replace it with a
+  // PoisonValue instead.
+  if (OldMD && isa<ValueAsMetadata>(*OldMD) && !New) {
+    auto *OldVAM = cast<ValueAsMetadata>(*OldMD);
+    New = ValueAsMetadata::get(PoisonValue::get(OldVAM->getValue()->getType()));
+  }
   resetDebugValue(Idx, New);
 }
 



More information about the llvm-commits mailing list