diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h --- a/llvm/include/llvm/IR/Argument.h +++ b/llvm/include/llvm/IR/Argument.h @@ -162,6 +162,8 @@ /// Remove attributes from an argument. void removeAttr(Attribute::AttrKind Kind); + void removeAttrs(const AttrBuilder &B); + /// Check if an argument has a given attribute. bool hasAttribute(Attribute::AttrKind Kind) const; diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1555,6 +1555,13 @@ setAttributes(PAL); } + /// Removes the attributes from the given argument + void removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) { + AttributeList PAL = getAttributes(); + PAL = PAL.removeParamAttributes(getContext(), ArgNo, Attrs); + setAttributes(PAL); + } + /// Removes noundef and other attributes that imply undefined behavior if a /// `undef` or `poison` value is passed from the given argument. void removeParamUndefImplyingAttrs(unsigned ArgNo) { diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5629,10 +5629,15 @@ } } - // Remove align from return attribute on CallInst. - if (auto *CI = dyn_cast(&I)) { - if (CI->getFunctionType()->getReturnType()->isVoidTy()) - CI->removeAttribute(0, Attribute::Alignment); + // Remove incompatible attributes on function calls. + if (auto *CI = dyn_cast(&I)) { + CI->removeAttributes(AttributeList::ReturnIndex, + AttributeFuncs::typeIncompatible( + CI->getFunctionType()->getReturnType())); + + for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ++ArgNo) + CI->removeParamAttrs(ArgNo, AttributeFuncs::typeIncompatible( + CI->getArgOperand(ArgNo)->getType())); } } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -4377,11 +4377,11 @@ F.addParamAttr(0, NewAttr); } - // If function has void return type, check it has align attribute. It has no - // affect on the return type and no longer passes the verifier. - if (F.getReturnType()->isVoidTy() && - F.hasAttribute(AttributeList::ReturnIndex, Attribute::Alignment)) - F.removeAttribute(AttributeList::ReturnIndex, Attribute::Alignment); + // Remove all incompatibile attributes from function. + F.removeAttributes(AttributeList::ReturnIndex, + AttributeFuncs::typeIncompatible(F.getReturnType())); + for (auto &Arg : F.args()) + Arg.removeAttrs(AttributeFuncs::typeIncompatible(Arg.getType())); } static bool isOldLoopArgument(Metadata *MD) { diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -301,6 +301,12 @@ getParent()->removeParamAttr(getArgNo(), Kind); } +void Argument::removeAttrs(const AttrBuilder &B) { + AttributeList AL = getParent()->getAttributes(); + AL = AL.removeParamAttributes(Parent->getContext(), getArgNo(), B); + getParent()->setAttributes(AL); +} + bool Argument::hasAttribute(Attribute::AttrKind Kind) const { return getParent()->hasParamAttribute(getArgNo(), Kind); } diff --git a/llvm/test/Bitcode/upgrade-incompatible-func-attr-11.0.ll b/llvm/test/Bitcode/upgrade-incompatible-func-attr-11.0.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/upgrade-incompatible-func-attr-11.0.ll @@ -0,0 +1,29 @@ +; Check upgrade is removing the incompatible attributes on function types. + +; RUN: llvm-dis < %s.bc | FileCheck %s + +; CHECK: define i8 @f(i8 %0, i8 %1) +define align 8 i8 @f(i8 align 8 %0, i8 align 8 %1) { + ret i8 0 +} + +; CHECK: declare i8 @f2(i8, i8, ...) +declare align 8 i8 @f2(i8 align 8, i8 align 8, ...) + +declare i32* @"personality_function"() + +define void @g() personality i32* ()* @"personality_function" { +; CHECK: call i8 @f(i8 0, i8 1) + %1 = call align 8 i8 @f(i8 align 8 0, i8 align 8 1); +; CHECK: call i8 (i8, i8, ...) @f2(i8 0, i8 1, i8 2) + %2 = call align 8 i8(i8, i8, ...) @f2(i8 align 8 0, i8 align 8 1, i8 align 8 2); +; CHECK: invoke i8 @f(i8 0, i8 1) + %3 = invoke align 8 i8 @f(i8 align 8 0, i8 align 8 1) to label %cont unwind label %cleanup + +cont: + ret void + +cleanup: + %4 = landingpad i8 cleanup + ret void +} diff --git a/llvm/test/Bitcode/upgrade-incompatible-func-attr-11.0.ll.bc b/llvm/test/Bitcode/upgrade-incompatible-func-attr-11.0.ll.bc new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@