Skip to content

Commit e83543f

Browse files
committed
Don't replace Undef with null value for Constants Differential Revision:https://reviews.llvm.org/D124098
1 parent 8e4cd72 commit e83543f

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

llvm/include/llvm/IR/Metadata.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ class ReplaceableMetadataImpl {
302302
///
303303
/// Replace all uses of this with \c MD, which is allowed to be null.
304304
void replaceAllUsesWith(Metadata *MD);
305-
305+
/// Replace all uses of the constant with Undef in debug info metadata
306+
static void SalvageDebugInfo(const Constant &C);
306307
/// Returns the list of all DIArgList users of this.
307308
SmallVector<Metadata *> getAllArgListUsers();
308309

llvm/lib/IR/Constants.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -741,9 +741,13 @@ static bool constantIsDead(const Constant *C, bool RemoveDeadUsers) {
741741
++I;
742742
}
743743

744-
if (RemoveDeadUsers)
744+
if (RemoveDeadUsers) {
745+
// If C is only used by metadata, it should not be preserved but should
746+
// have its uses replaced.
747+
ReplaceableMetadataImpl::SalvageDebugInfo(*C);
745748
const_cast<Constant *>(C)->destroyConstant();
746-
749+
}
750+
747751
return true;
748752
}
749753

llvm/lib/IR/Metadata.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,36 @@ void ReplaceableMetadataImpl::moveRef(void *Ref, void *New,
245245
"Reference without owner must be direct");
246246
}
247247

248+
void ReplaceableMetadataImpl::SalvageDebugInfo(const Constant &C) {
249+
if (!C.isUsedByMetadata()) {
250+
return;
251+
}
252+
253+
LLVMContext &Context = C.getType()->getContext();
254+
auto &Store = Context.pImpl->ValuesAsMetadata;
255+
auto I = Store.find(&C);
256+
ValueAsMetadata *MD = I->second;
257+
using UseTy =
258+
std::pair<void *, std::pair<MetadataTracking::OwnerTy, uint64_t>>;
259+
// Copy out uses and update value of Constant used by debug info metadata with undef below
260+
SmallVector<UseTy, 8> Uses(MD->UseMap.begin(), MD->UseMap.end());
261+
262+
for (const auto &Pair : Uses) {
263+
MetadataTracking::OwnerTy Owner = Pair.second.first;
264+
if (!Owner)
265+
continue;
266+
if (!Owner.is<Metadata *>())
267+
continue;
268+
auto *OwnerMD = dyn_cast<MDNode>(Owner.get<Metadata *>());
269+
if (!OwnerMD)
270+
continue;
271+
if (isa<DINode>(OwnerMD)) {
272+
OwnerMD->handleChangedOperand(
273+
Pair.first, ValueAsMetadata::get(UndefValue::get(C.getType())));
274+
}
275+
}
276+
}
277+
248278
void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
249279
if (UseMap.empty())
250280
return;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: opt -S -ipsccp %S/undef-type-md.ll | FileCheck %s
2+
; CHECK: llvm.nondebug.metadata = !{[[NONDEBUG_METADATA:![0-9]+]]}
3+
; CHECK: [[NONDEBUG_METADATA]] = distinct !{null}
4+
; CHECK: !DITemplateValueParameter({{.*}} value: %class.1 addrspace(1)* undef)
5+
6+
; ModuleID = '<stdin>'
7+
source_filename = "test.cpp"
8+
9+
%"struct.1" = type <{ float, i32, i8, [3 x i8] }>
10+
%"class.1" = type { %"struct.1" }
11+
12+
@extern_const = external addrspace(1) constant { { float, i32, i8 } }
13+
14+
; Function Attrs: convergent mustprogress norecurse
15+
define linkonce_odr spir_func void @foo() align 2 !dbg !5 {
16+
entry:
17+
%0 = alloca %"class.1", align 8
18+
ret void
19+
}
20+
21+
!llvm.dbg.cu = !{!0}
22+
!llvm.module.flags = !{!3, !4}
23+
!llvm.nondebug.metadata= !{!11}
24+
25+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, emissionKind: FullDebug)
26+
!1 = !DIFile(filename: "test.cpp", directory: "/path/to")
27+
!2 = !{}
28+
!3 = !{i32 7, !"Dwarf Version", i32 4}
29+
!4 = !{i32 2, !"Debug Info Version", i32 3}
30+
!5 = distinct !DISubprogram(name: "foo<param>", scope: !1, file: !1, line: 27, type: !6, scopeLine: 27, spFlags: DISPFlagDefinition, unit: !0, templateParams: !8)
31+
!6 = !DISubroutineType(types: !7)
32+
!7 = !{null}
33+
!8 = !{!9}
34+
!9 = !DITemplateValueParameter(name: "S", type: !10, value: %"class.1" addrspace(1)* bitcast ({ { float, i32, i8 } } addrspace(1)* @extern_const to %"class.1" addrspace(1)*))
35+
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
36+
!11 = !{%"class.1" addrspace(1)* bitcast ({ { float, i32, i8 } } addrspace(1)* @extern_const to %"class.1" addrspace(1)*)}

0 commit comments

Comments
 (0)