diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-24 15:03:44 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-24 15:03:44 +0000 |
| commit | 4b4fe385e49bd883fd183b5f21c1ea486c722e61 (patch) | |
| tree | c3d8fdb355c9c73e57723718c22103aaf7d15aa6 /llvm/lib/Bitcode/Reader | |
| parent | 1f917f69ff07f09b6dbb670971f57f8efe718b84 (diff) | |
Diffstat (limited to 'llvm/lib/Bitcode/Reader')
| -rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 55 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Reader/ValueList.h | 1 |
3 files changed, 72 insertions, 11 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 8d5a2555f9af..1d6c21bd66d1 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5510,6 +5510,61 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (!OperandBundles.empty()) UpgradeOperandBundles(OperandBundles); + if (auto *IA = dyn_cast<InlineAsm>(Callee)) { + InlineAsm::ConstraintInfoVector ConstraintInfo = IA->ParseConstraints(); + auto IsLabelConstraint = [](const InlineAsm::ConstraintInfo &CI) { + return CI.Type == InlineAsm::isLabel; + }; + if (none_of(ConstraintInfo, IsLabelConstraint)) { + // Upgrade explicit blockaddress arguments to label constraints. + // Verify that the last arguments are blockaddress arguments that + // match the indirect destinations. Clang always generates callbr + // in this form. We could support reordering with more effort. + unsigned FirstBlockArg = Args.size() - IndirectDests.size(); + for (unsigned ArgNo = FirstBlockArg; ArgNo < Args.size(); ++ArgNo) { + unsigned LabelNo = ArgNo - FirstBlockArg; + auto *BA = dyn_cast<BlockAddress>(Args[ArgNo]); + if (!BA || BA->getFunction() != F || + LabelNo > IndirectDests.size() || + BA->getBasicBlock() != IndirectDests[LabelNo]) + return error("callbr argument does not match indirect dest"); + } + + // Remove blockaddress arguments. + Args.erase(Args.begin() + FirstBlockArg, Args.end()); + ArgTyIDs.erase(ArgTyIDs.begin() + FirstBlockArg, ArgTyIDs.end()); + + // Recreate the function type with less arguments. + SmallVector<Type *> ArgTys; + for (Value *Arg : Args) + ArgTys.push_back(Arg->getType()); + FTy = + FunctionType::get(FTy->getReturnType(), ArgTys, FTy->isVarArg()); + + // Update constraint string to use label constraints. + std::string Constraints = IA->getConstraintString(); + unsigned ArgNo = 0; + size_t Pos = 0; + for (const auto &CI : ConstraintInfo) { + if (CI.hasArg()) { + if (ArgNo >= FirstBlockArg) + Constraints.insert(Pos, "!"); + ++ArgNo; + } + + // Go to next constraint in string. + Pos = Constraints.find(',', Pos); + if (Pos == std::string::npos) + break; + ++Pos; + } + + Callee = InlineAsm::get(FTy, IA->getAsmString(), Constraints, + IA->hasSideEffects(), IA->isAlignStack(), + IA->getDialect(), IA->canThrow()); + } + } + I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args, OperandBundles); ResTypeID = getContainedTypeID(FTyID); diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 0d57ae4ef9df..13d53a35084d 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1226,10 +1226,12 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } - MetadataList.assignValue( - LocalAsMetadata::get(ValueList.getValueFwdRef( - Record[1], Ty, TyID, /*ConstExprInsertBB*/ nullptr)), - NextMetadataNo); + Value *V = ValueList.getValueFwdRef(Record[1], Ty, TyID, + /*ConstExprInsertBB*/ nullptr); + if (!V) + return error("Invalid value reference from old fn metadata"); + + MetadataList.assignValue(LocalAsMetadata::get(V), NextMetadataNo); NextMetadataNo++; break; } @@ -1248,8 +1250,11 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Ty->isMetadataTy()) Elts.push_back(getMD(Record[i + 1])); else if (!Ty->isVoidTy()) { - auto *MD = ValueAsMetadata::get(ValueList.getValueFwdRef( - Record[i + 1], Ty, TyID, /*ConstExprInsertBB*/ nullptr)); + Value *V = ValueList.getValueFwdRef(Record[i + 1], Ty, TyID, + /*ConstExprInsertBB*/ nullptr); + if (!V) + return error("Invalid value reference from old metadata"); + auto *MD = ValueAsMetadata::get(V); assert(isa<ConstantAsMetadata>(MD) && "Expected non-function-local metadata"); Elts.push_back(MD); @@ -1269,10 +1274,12 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Ty->isMetadataTy() || Ty->isVoidTy()) return error("Invalid record"); - MetadataList.assignValue( - ValueAsMetadata::get(ValueList.getValueFwdRef( - Record[1], Ty, TyID, /*ConstExprInsertBB*/ nullptr)), - NextMetadataNo); + Value *V = ValueList.getValueFwdRef(Record[1], Ty, TyID, + /*ConstExprInsertBB*/ nullptr); + if (!V) + return error("Invalid value reference from metadata"); + + MetadataList.assignValue(ValueAsMetadata::get(V), NextMetadataNo); NextMetadataNo++; break; } diff --git a/llvm/lib/Bitcode/Reader/ValueList.h b/llvm/lib/Bitcode/Reader/ValueList.h index 995d46f01f75..a5b3f6e20707 100644 --- a/llvm/lib/Bitcode/Reader/ValueList.h +++ b/llvm/lib/Bitcode/Reader/ValueList.h @@ -21,7 +21,6 @@ namespace llvm { -class Constant; class Error; class Type; class Value; |
