Skip to content

Commit 236228f

Browse files
committed
[BitcodeReader] Replace unsupported constexprs in metadata with undef
Metadata (via ValueAsMetadata) can reference constant expressions that may no longer be supported. These references can both be in function-local metadata and module metadata, if the same expression is used in multiple functions. At least in theory, such references could also be in metadata proper, rather than just inside ValueAsMetadata references in calls. Instead of trying to expand these expressions (which we can't reliably do), pretend that the constant has been deleted, which means that ValueAsMetadata references will get replaced with undef metadata. Fixes #68281.
1 parent 2ca30eb commit 236228f

File tree

6 files changed

+41
-31
lines changed

6 files changed

+41
-31
lines changed

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4683,7 +4683,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
46834683
case bitc::METADATA_BLOCK_ID:
46844684
assert(DeferredMetadataInfo.empty() &&
46854685
"Must read all module-level metadata before function-level");
4686-
if (Error Err = MDLoader->parseFunctionMetadata(CurBB))
4686+
if (Error Err = MDLoader->parseFunctionMetadata())
46874687
return Err;
46884688
break;
46894689
case bitc::USELIST_BLOCK_ID:

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,7 @@ class MetadataLoader::MetadataLoaderImpl {
473473

474474
Error parseOneMetadata(SmallVectorImpl<uint64_t> &Record, unsigned Code,
475475
PlaceholderQueue &Placeholders, StringRef Blob,
476-
unsigned &NextMetadataNo,
477-
BasicBlock *ConstExprInsertBB);
476+
unsigned &NextMetadataNo);
478477
Error parseMetadataStrings(ArrayRef<uint64_t> Record, StringRef Blob,
479478
function_ref<void(StringRef)> CallBack);
480479
Error parseGlobalObjectAttachment(GlobalObject &GO,
@@ -723,7 +722,7 @@ class MetadataLoader::MetadataLoaderImpl {
723722
TheModule(TheModule), Callbacks(std::move(Callbacks)),
724723
IsImporting(IsImporting) {}
725724

726-
Error parseMetadata(bool ModuleLevel, BasicBlock *ConstExprInsertBB);
725+
Error parseMetadata(bool ModuleLevel);
727726

728727
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
729728

@@ -1048,8 +1047,7 @@ void MetadataLoader::MetadataLoaderImpl::callMDTypeCallback(Metadata **Val,
10481047

10491048
/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
10501049
/// module level metadata.
1051-
Error MetadataLoader::MetadataLoaderImpl::parseMetadata(
1052-
bool ModuleLevel, BasicBlock *ConstExprInsertBB) {
1050+
Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
10531051
if (!ModuleLevel && MetadataList.hasFwdRefs())
10541052
return error("Invalid metadata: fwd refs into function blocks");
10551053

@@ -1132,7 +1130,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(
11321130
if (Expected<unsigned> MaybeCode =
11331131
Stream.readRecord(Entry.ID, Record, &Blob)) {
11341132
if (Error Err = parseOneMetadata(Record, MaybeCode.get(), Placeholders,
1135-
Blob, NextMetadataNo, ConstExprInsertBB))
1133+
Blob, NextMetadataNo))
11361134
return Err;
11371135
} else
11381136
return MaybeCode.takeError();
@@ -1173,8 +1171,7 @@ void MetadataLoader::MetadataLoaderImpl::lazyLoadOneMetadata(
11731171
if (Expected<unsigned> MaybeCode =
11741172
IndexCursor.readRecord(Entry.ID, Record, &Blob)) {
11751173
if (Error Err =
1176-
parseOneMetadata(Record, MaybeCode.get(), Placeholders, Blob, ID,
1177-
/* ConstExprInsertBB */ nullptr))
1174+
parseOneMetadata(Record, MaybeCode.get(), Placeholders, Blob, ID))
11781175
report_fatal_error("Can't lazyload MD, parseOneMetadata: " +
11791176
Twine(toString(std::move(Err))));
11801177
} else
@@ -1216,10 +1213,29 @@ void MetadataLoader::MetadataLoaderImpl::resolveForwardRefsAndPlaceholders(
12161213
Placeholders.flush(MetadataList);
12171214
}
12181215

1216+
static Value *getValueFwdRef(BitcodeReaderValueList &ValueList, unsigned Idx,
1217+
Type *Ty, unsigned TyID) {
1218+
Value *V = ValueList.getValueFwdRef(Idx, Ty, TyID,
1219+
/*ConstExprInsertBB*/ nullptr);
1220+
if (V)
1221+
return V;
1222+
1223+
// This is a reference to a no longer supported constant expression.
1224+
// Pretend that the constant was deleted, which will replace metadata
1225+
// references with undef.
1226+
// TODO: This is a rather indirect check. It would be more elegant to use
1227+
// a separate ErrorInfo for constant materialization failure and thread
1228+
// the error reporting through getValueFwdRef().
1229+
if (Idx < ValueList.size() && ValueList[Idx] &&
1230+
ValueList[Idx]->getType() == Ty)
1231+
return UndefValue::get(Ty);
1232+
1233+
return nullptr;
1234+
}
1235+
12191236
Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
12201237
SmallVectorImpl<uint64_t> &Record, unsigned Code,
1221-
PlaceholderQueue &Placeholders, StringRef Blob, unsigned &NextMetadataNo,
1222-
BasicBlock *ConstExprInsertBB) {
1238+
PlaceholderQueue &Placeholders, StringRef Blob, unsigned &NextMetadataNo) {
12231239

12241240
bool IsDistinct = false;
12251241
auto getMD = [&](unsigned ID) -> Metadata * {
@@ -1348,8 +1364,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
13481364
if (Ty->isMetadataTy())
13491365
Elts.push_back(getMD(Record[i + 1]));
13501366
else if (!Ty->isVoidTy()) {
1351-
Value *V = ValueList.getValueFwdRef(Record[i + 1], Ty, TyID,
1352-
/*ConstExprInsertBB*/ nullptr);
1367+
Value *V = getValueFwdRef(ValueList, Record[i + 1], Ty, TyID);
13531368
if (!V)
13541369
return error("Invalid value reference from old metadata");
13551370
Metadata *MD = ValueAsMetadata::get(V);
@@ -1373,7 +1388,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
13731388
if (!Ty || Ty->isMetadataTy() || Ty->isVoidTy())
13741389
return error("Invalid record");
13751390

1376-
Value *V = ValueList.getValueFwdRef(Record[1], Ty, TyID, ConstExprInsertBB);
1391+
Value *V = getValueFwdRef(ValueList, Record[1], Ty, TyID);
13771392
if (!V)
13781393
return error("Invalid value reference from metadata");
13791394

@@ -2462,9 +2477,8 @@ MetadataLoader::MetadataLoader(BitstreamCursor &Stream, Module &TheModule,
24622477
: Pimpl(std::make_unique<MetadataLoaderImpl>(
24632478
Stream, TheModule, ValueList, std::move(Callbacks), IsImporting)) {}
24642479

2465-
Error MetadataLoader::parseMetadata(bool ModuleLevel,
2466-
BasicBlock *ConstExprInsertBB) {
2467-
return Pimpl->parseMetadata(ModuleLevel, ConstExprInsertBB);
2480+
Error MetadataLoader::parseMetadata(bool ModuleLevel) {
2481+
return Pimpl->parseMetadata(ModuleLevel);
24682482
}
24692483

24702484
bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }

llvm/lib/Bitcode/Reader/MetadataLoader.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ struct MetadataLoaderCallbacks {
4848
class MetadataLoader {
4949
class MetadataLoaderImpl;
5050
std::unique_ptr<MetadataLoaderImpl> Pimpl;
51-
Error parseMetadata(bool ModuleLevel,
52-
BasicBlock *ConstExprInsertBB = nullptr);
51+
Error parseMetadata(bool ModuleLevel);
5352

5453
public:
5554
~MetadataLoader();
@@ -63,9 +62,7 @@ class MetadataLoader {
6362
Error parseModuleMetadata() { return parseMetadata(true); }
6463

6564
// Parse a function metadata block
66-
Error parseFunctionMetadata(BasicBlock *ConstExprInsertBB) {
67-
return parseMetadata(false, ConstExprInsertBB);
68-
}
65+
Error parseFunctionMetadata() { return parseMetadata(false); }
6966

7067
/// Set the mode to strip TBAA metadata on load.
7168
void setStripTBAA(bool StripTBAA = true);
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
; RUN: llvm-dis -expand-constant-exprs < %S/Inputs/constexpr-to-instr-metadata-2.bc | FileCheck %s
2+
3+
; CHECK-LABEL: define void @_ZN4alsa3pcm3PCM17hw_params_current17hf1c237aece2f69c4E() {
4+
; CHECK: call void @llvm.dbg.value(metadata ptr undef, metadata !4, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg !14
5+
6+
; CHECK-LABEL: define void @_ZN4alsa3pcm8HwParams3any17h02a64cfc85ce8a66E() {
7+
; CHECK: call void @llvm.dbg.value(metadata ptr undef, metadata !23, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg !28
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
; RUN: llvm-dis -expand-constant-exprs < %S/Inputs/constexpr-to-instr-metadata.bc | FileCheck %s
22

33
; CHECK-LABEL: define void @test() {
4-
; CHECK: %constexpr = ptrtoint ptr @g to i32
5-
; CHECK: %constexpr1 = zext i32 %constexpr to i64
6-
; CHECK: %constexpr2 = ptrtoint ptr @g to i64
7-
; CHECK: %constexpr3 = lshr i64 %constexpr2, 32
8-
; CHECK: %constexpr4 = trunc i64 %constexpr3 to i32
9-
; CHECK: %constexpr5 = zext i32 %constexpr4 to i64
10-
; CHECK: %constexpr6 = shl i64 %constexpr5, 32
11-
; CHECK: %constexpr7 = or i64 %constexpr1, %constexpr6
12-
; CHECK: call void @llvm.dbg.value(metadata i64 %constexpr7, metadata !4, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64)), !dbg !13
4+
; CHECK: call void @llvm.dbg.value(metadata i64 undef, metadata !4, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64)), !dbg !13

0 commit comments

Comments
 (0)