diff options
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 4d69dd7..1cb7113 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -717,9 +717,9 @@ private: return getFnValueByID(ValNo, Ty); } - /// Upgrades old-style typeless byval attributes by adding the corresponding - /// argument's pointee type. - void propagateByValTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys); + /// Upgrades old-style typeless byval or sret attributes by adding the + /// corresponding argument's pointee type. + void propagateByValSRetTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys); /// Converts alignment exponent (i.e. power of two (or zero)) to the /// corresponding alignment to use. If alignment is too large, returns @@ -1611,6 +1611,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { // this AttributeList with a function. if (Kind == Attribute::ByVal) B.addByValAttr(nullptr); + else if (Kind == Attribute::StructRet) + B.addStructRetAttr(nullptr); B.addAttribute(Kind); } else if (Record[i] == 1) { // Integer attribute @@ -1654,6 +1656,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { return Err; if (Kind == Attribute::ByVal) { B.addByValAttr(HasType ? getTypeByID(Record[++i]) : nullptr); + } else if (Kind == Attribute::StructRet) { + B.addStructRetAttr(HasType ? getTypeByID(Record[++i]) : nullptr); } else if (Kind == Attribute::ByRef) { B.addByRefAttr(getTypeByID(Record[++i])); } else if (Kind == Attribute::Preallocated) { @@ -3288,17 +3292,24 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { Func->setLinkage(getDecodedLinkage(RawLinkage)); Func->setAttributes(getAttributes(Record[4])); - // Upgrade any old-style byval without a type by propagating the argument's - // pointee type. There should be no opaque pointers where the byval type is - // implicit. + // Upgrade any old-style byval or sret without a type by propagating the + // argument's pointee type. There should be no opaque pointers where the byval + // type is implicit. for (unsigned i = 0; i != Func->arg_size(); ++i) { - if (!Func->hasParamAttribute(i, Attribute::ByVal)) - continue; + for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) { + if (!Func->hasParamAttribute(i, Kind)) + continue; - Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i); - Func->removeParamAttr(i, Attribute::ByVal); - Func->addParamAttr(i, Attribute::getWithByValType( - Context, getPointerElementFlatType(PTy))); + Func->removeParamAttr(i, Kind); + + Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i); + Type *PtrEltTy = getPointerElementFlatType(PTy); + Attribute NewAttr = + Kind == Attribute::ByVal + ? Attribute::getWithByValType(Context, PtrEltTy) + : Attribute::getWithStructRetType(Context, PtrEltTy); + Func->addParamAttr(i, NewAttr); + } } MaybeAlign Alignment; @@ -3759,16 +3770,22 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) { return Error::success(); } -void BitcodeReader::propagateByValTypes(CallBase *CB, - ArrayRef<Type *> ArgsFullTys) { +void BitcodeReader::propagateByValSRetTypes(CallBase *CB, + ArrayRef<Type *> ArgsFullTys) { for (unsigned i = 0; i != CB->arg_size(); ++i) { - if (!CB->paramHasAttr(i, Attribute::ByVal)) - continue; + for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) { + if (!CB->paramHasAttr(i, Kind)) + continue; - CB->removeParamAttr(i, Attribute::ByVal); - CB->addParamAttr( - i, Attribute::getWithByValType( - Context, getPointerElementFlatType(ArgsFullTys[i]))); + CB->removeParamAttr(i, Kind); + + Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]); + Attribute NewAttr = + Kind == Attribute::ByVal + ? Attribute::getWithByValType(Context, PtrEltTy) + : Attribute::getWithStructRetType(Context, PtrEltTy); + CB->addParamAttr(i, NewAttr); + } } } @@ -4620,7 +4637,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { cast<InvokeInst>(I)->setCallingConv( static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo)); cast<InvokeInst>(I)->setAttributes(PAL); - propagateByValTypes(cast<CallBase>(I), ArgsFullTys); + propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys); break; } @@ -5227,7 +5244,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { TCK = CallInst::TCK_NoTail; cast<CallInst>(I)->setTailCallKind(TCK); cast<CallInst>(I)->setAttributes(PAL); - propagateByValTypes(cast<CallBase>(I), ArgsFullTys); + propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys); if (FMF.any()) { if (!isa<FPMathOperator>(I)) return error("Fast-math-flags specified for call without " |