[llvm] cdd1900 - [IR] Do not inherit ABI attributes from the callee (#207173)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 9 01:02:26 PDT 2026


Author: Nikita Popov
Date: 2026-09-09T10:02:21+02:00
New Revision: cdd1900816f625eb1f38a6e755c49ccadec56209

URL: https://github.com/llvm/llvm-project/commit/cdd1900816f625eb1f38a6e755c49ccadec56209
DIFF: https://github.com/llvm/llvm-project/commit/cdd1900816f625eb1f38a6e755c49ccadec56209.diff

LOG: [IR] Do not inherit ABI attributes from the callee (#207173)

Usually attributes that are missing on the call-site are inherited form
the callee instead. This is fine for optional optimization attributes,
but problematic for ABI-affecting attributes.

ABI attributes generally must be placed at the call-site as well,
because there is no callee to inherit from for indirect calls. Failing
to specify ABI attributes at the call-site generally indicates a bug.

The motivation for being stricter about this (apart from just being the
right thing to do) is to properly support cases where the attributes at
the call-site and the callee actually differ. Two examples I'm aware of
are:

* During cross-language LTO, it's possible to have one side use a `ptr`
argument and the other a `ptr byval(ptr)` argument. Both represent the
same ABI using different IR encodings, but you can't just inherit the
`byval` attribute from one to the other (because the byval case requires
an additional level of indirection in use of the argument).
* To fix our incompatibility with the x86-64 psABI, I believe we'll want
to do something like emit zeroext/signext at function returns and
call-site arguments only, so that we both don't assume incoming values
are zero/sign-extended, but still zero/sign-extend outgoing values. This
makes sure we still remain compatible with old Clang-generated object
files.

We've attempted to make a change like this previously, but ran into
substantial issues with missing call-site attributes on
compiler-inserted calls. The issue was particularly severe on s390x,
which requires zeroext/signext on more values than other architectures.
I believe that the situation here has improved a lot in the meantime,
with libcalls now inferring mandatory ABI attributes, and s390x also
using a noext attribute plus validation logic in the backend to detect
cases where the necessary attributes are missing.

-----

ABI attributes on call-sites must be queried using `hasABIParamAttr()`
and `hasABIRetAttr()` instead of `paramHasAttr()` and `hasRetAttr()`
now. Passing an ABI attribute to the latter two will result in an
assertion failure.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/FastISel.h
    llvm/include/llvm/CodeGen/TargetLowering.h
    llvm/include/llvm/IR/Attributes.h
    llvm/include/llvm/IR/Attributes.td
    llvm/include/llvm/IR/InstrTypes.h
    llvm/lib/Analysis/Lint.cpp
    llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
    llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
    llvm/lib/CodeGen/TypePromotion.cpp
    llvm/lib/IR/Attributes.cpp
    llvm/lib/IR/Instructions.cpp
    llvm/lib/IR/Verifier.cpp
    llvm/lib/IR/VerifierAMDGPU.cpp
    llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
    llvm/lib/Target/ARM/ARMFastISel.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
    llvm/lib/Target/X86/X86FastISel.cpp
    llvm/lib/Target/X86/X86ISelLoweringCall.cpp
    llvm/lib/Transforms/IPO/ExpandVariadics.cpp
    llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
    llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
    llvm/test/Analysis/BasicAA/call-attrs.ll
    llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call-sret.ll
    llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
    llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
    llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
    llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-return-values.ll
    llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
    llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call.ll
    llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll
    llvm/test/CodeGen/AMDGPU/swdev504645-global-fold.ll
    llvm/test/CodeGen/AMDGPU/waterfall-call-inreg-agpr.ll
    llvm/test/CodeGen/ARM/returned-ext.ll
    llvm/test/CodeGen/ARM/struct-byval-loop.ll
    llvm/test/CodeGen/M68k/multiple-return.ll
    llvm/test/CodeGen/NVPTX/forward-ld-param.ll
    llvm/test/CodeGen/RISCV/rvv/shrinkwrap.ll
    llvm/test/CodeGen/RISCV/shrinkwrap.ll
    llvm/test/CodeGen/SPARC/64abi.ll
    llvm/test/CodeGen/SystemZ/args-14.ll
    llvm/test/CodeGen/SystemZ/call-zos-01.ll
    llvm/test/CodeGen/VE/Scalar/call.ll
    llvm/test/CodeGen/VE/Scalar/va_callee.ll
    llvm/test/CodeGen/VE/Vector/fastcc_caller.ll
    llvm/test/CodeGen/WebAssembly/signext-zeroext-callsite.ll
    llvm/test/CodeGen/X86/bool-zext.ll
    llvm/test/CodeGen/X86/return-ext.ll
    llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll
    llvm/test/Transforms/DeadArgElim/deadexternal.ll
    llvm/test/Transforms/Inline/access-attributes-prop.ll
    llvm/test/Transforms/PhaseOrdering/pr64289-tce.ll
    llvm/test/Transforms/SROA/readonlynocapture.ll
    llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
    llvm/unittests/IR/AttributesTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h
index 02d2059d54785..04ad564843116 100644
--- a/llvm/include/llvm/CodeGen/FastISel.h
+++ b/llvm/include/llvm/CodeGen/FastISel.h
@@ -108,12 +108,12 @@ class LLVM_ABI FastISel {
       RetTy = ResultTy;
       Callee = Target;
 
-      IsInReg = Call.hasRetAttr(Attribute::InReg);
+      IsInReg = Call.hasABIRetAttr(Attribute::InReg);
       DoesNotReturn = Call.doesNotReturn();
       IsVarArg = FuncTy->isVarArg();
       IsReturnValueUsed = !Call.use_empty();
-      RetSExt = Call.hasRetAttr(Attribute::SExt);
-      RetZExt = Call.hasRetAttr(Attribute::ZExt);
+      RetSExt = Call.hasABIRetAttr(Attribute::SExt);
+      RetZExt = Call.hasABIRetAttr(Attribute::ZExt);
 
       CallConv = Call.getCallingConv();
       Args = std::move(ArgsList);
@@ -132,12 +132,12 @@ class LLVM_ABI FastISel {
       Callee = Call.getCalledOperand();
       Symbol = Target;
 
-      IsInReg = Call.hasRetAttr(Attribute::InReg);
+      IsInReg = Call.hasABIRetAttr(Attribute::InReg);
       DoesNotReturn = Call.doesNotReturn();
       IsVarArg = FuncTy->isVarArg();
       IsReturnValueUsed = !Call.use_empty();
-      RetSExt = Call.hasRetAttr(Attribute::SExt);
-      RetZExt = Call.hasRetAttr(Attribute::ZExt);
+      RetSExt = Call.hasABIRetAttr(Attribute::SExt);
+      RetZExt = Call.hasABIRetAttr(Attribute::ZExt);
 
       CallConv = Call.getCallingConv();
       Args = std::move(ArgsList);

diff  --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 69f5e0e4e3011..71a8438fd4999 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5060,14 +5060,14 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
                                 const CallBase &Call) {
       RetTy = OrigRetTy = ResultType;
 
-      IsInReg = Call.hasRetAttr(Attribute::InReg);
+      IsInReg = Call.hasABIRetAttr(Attribute::InReg);
       DoesNotReturn =
           Call.doesNotReturn() ||
           (!isa<InvokeInst>(Call) && isa<UnreachableInst>(Call.getNextNode()));
       IsVarArg = FTy->isVarArg();
       IsReturnValueUsed = !Call.use_empty();
-      RetSExt = Call.hasRetAttr(Attribute::SExt);
-      RetZExt = Call.hasRetAttr(Attribute::ZExt);
+      RetSExt = Call.hasABIRetAttr(Attribute::SExt);
+      RetZExt = Call.hasABIRetAttr(Attribute::ZExt);
       NoMerge = Call.hasFnAttr(Attribute::NoMerge);
 
       Callee = Target;

diff  --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index f8185c76dfb5c..d9ab56cdcc1f6 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -162,6 +162,9 @@ class Attribute {
   LLVM_ABI static bool intersectWithMin(AttrKind Kind);
   LLVM_ABI static bool intersectWithCustom(AttrKind Kind);
 
+  /// Whether this is an ABI attribute (for returns or arguments).
+  LLVM_ABI static bool isABIAttr(AttrKind Kind);
+
 private:
   AttributeImpl *pImpl = nullptr;
 

diff  --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index ea523cad69cd5..a649430424b9e 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -22,7 +22,8 @@ def ParamAttr : AttrProperty;
 /// Can be used as return attribute.
 def RetAttr : AttrProperty;
 
-
+/// This is an ABI-affecting attribute.
+def ABIAttr : AttrProperty;
 
 /// Intersection rules. Used for example in sinking/hoisting two
 /// callbases to find a set of attributes that apply to both.
@@ -45,8 +46,6 @@ def IntersectMin : AttrProperty;
 /// When intersecting rely on some specially defined code.
 def IntersectCustom : AttrProperty;
 
-
-
 /// Attribute base class.
 class Attr<string S, AttrProperty I, list<AttrProperty> P> {
   // String representation of this attribute in the IR.
@@ -103,10 +102,10 @@ def AlwaysInline : EnumAttr<"alwaysinline", IntersectPreserve, [FnAttr]>;
 def Builtin : EnumAttr<"builtin", IntersectPreserve, [FnAttr]>;
 
 /// Pass structure by value.
-def ByVal : TypeAttr<"byval", IntersectPreserve, [ParamAttr]>;
+def ByVal : TypeAttr<"byval", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// Mark in-memory ABI type.
-def ByRef : TypeAttr<"byref", IntersectPreserve, [ParamAttr]>;
+def ByRef : TypeAttr<"byref", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// Parameter or return value may not contain uninitialized or poison bits.
 def NoUndef : EnumAttr<"noundef", IntersectAnd, [ParamAttr, RetAttr]>;
@@ -145,7 +144,7 @@ def FnRetThunkExtern : EnumAttr<"fn_ret_thunk_extern", IntersectPreserve, [FnAtt
 def HybridPatchable : EnumAttr<"hybrid_patchable", IntersectPreserve, [FnAttr]>;
 
 /// Pass structure in an alloca.
-def InAlloca : TypeAttr<"inalloca", IntersectPreserve, [ParamAttr]>;
+def InAlloca : TypeAttr<"inalloca", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// Pointer argument memory is initialized.
 def Initializes : ConstantRangeListAttr<"initializes", IntersectPreserve, [ParamAttr]>;
@@ -154,7 +153,7 @@ def Initializes : ConstantRangeListAttr<"initializes", IntersectPreserve, [Param
 def InlineHint : EnumAttr<"inlinehint", IntersectAnd, [FnAttr]>;
 
 /// Force argument to be passed in register.
-def InReg : EnumAttr<"inreg", IntersectPreserve, [ParamAttr, RetAttr]>;
+def InReg : EnumAttr<"inreg", IntersectPreserve, [ParamAttr, RetAttr, ABIAttr]>;
 
 /// Build jump-instruction tables and replace refs.
 def JumpTable : EnumAttr<"jumptable", IntersectPreserve, [FnAttr]>;
@@ -172,7 +171,7 @@ def MinSize : EnumAttr<"minsize", IntersectPreserve, [FnAttr]>;
 def Naked : EnumAttr<"naked", IntersectPreserve, [FnAttr]>;
 
 /// Nested function static chain.
-def Nest : EnumAttr<"nest", IntersectPreserve, [ParamAttr]>;
+def Nest : EnumAttr<"nest", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// Considered to not alias after call.
 def NoAlias : EnumAttr<"noalias", IntersectAnd, [ParamAttr, RetAttr]>;
@@ -198,7 +197,7 @@ def NoDivergenceSource : EnumAttr<"nodivergencesource", IntersectAnd, [FnAttr]>;
 def NoDuplicate : EnumAttr<"noduplicate", IntersectPreserve, [FnAttr]>;
 
 /// No extension needed before/after call (high bits are undefined).
-def NoExt : EnumAttr<"noext", IntersectPreserve, [ParamAttr, RetAttr]>;
+def NoExt : EnumAttr<"noext", IntersectPreserve, [ParamAttr, RetAttr, ABIAttr]>;
 
 /// Function does not deallocate memory.
 /// Argument cannot be freed based on the argument pointer.
@@ -281,7 +280,8 @@ def OptimizeForSize : EnumAttr<"optsize", IntersectPreserve, [FnAttr]>;
 def OptimizeNone : EnumAttr<"optnone", IntersectPreserve, [FnAttr]>;
 
 /// Similar to byval but without a copy.
-def Preallocated : TypeAttr<"preallocated", IntersectPreserve, [FnAttr, ParamAttr]>;
+def Preallocated : TypeAttr<"preallocated", IntersectPreserve,
+                            [FnAttr, ParamAttr, ABIAttr]>;
 
 /// Parameter or return value is within the specified range.
 def Range : ConstantRangeAttr<"range", IntersectCustom, [ParamAttr, RetAttr]>;
@@ -308,11 +308,13 @@ def SafeStack : EnumAttr<"safestack", IntersectPreserve, [FnAttr]>;
 def ShadowCallStack : EnumAttr<"shadowcallstack", IntersectPreserve, [FnAttr]>;
 
 /// Sign extended before/after call.
-def SExt : EnumAttr<"signext", IntersectPreserve, [ParamAttr, RetAttr]>;
+def SExt : EnumAttr<"signext", IntersectPreserve,
+                    [ParamAttr, RetAttr, ABIAttr]>;
 
 /// Alignment of stack for function (3 bits)  stored as log2 of alignment with
 /// +1 bias 0 means unaligned (
diff erent from alignstack=(1)).
-def StackAlignment : IntAttr<"alignstack", IntersectPreserve, [FnAttr, ParamAttr, RetAttr]>;
+def StackAlignment : IntAttr<"alignstack", IntersectPreserve,
+                             [FnAttr, ParamAttr, RetAttr, ABIAttr]>;
 
 /// Function can be speculated.
 def Speculatable : EnumAttr<"speculatable", IntersectAnd, [FnAttr]>;
@@ -330,7 +332,7 @@ def StackProtectStrong : EnumAttr<"sspstrong", IntersectPreserve, [FnAttr]>;
 def StrictFP : EnumAttr<"strictfp", IntersectPreserve, [FnAttr]>;
 
 /// Hidden pointer to structure to return.
-def StructRet : TypeAttr<"sret", IntersectPreserve, [ParamAttr]>;
+def StructRet : TypeAttr<"sret", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// AddressSanitizer is on.
 def SanitizeAddress : EnumAttr<"sanitize_address", IntersectPreserve, [FnAttr]>;
@@ -374,13 +376,13 @@ def SpeculativeLoadHardening : EnumAttr<"speculative_load_hardening",
                                         [FnAttr]>;
 
 /// Argument is swift error.
-def SwiftError : EnumAttr<"swifterror", IntersectPreserve, [ParamAttr]>;
+def SwiftError : EnumAttr<"swifterror", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// Argument is swift self/context.
-def SwiftSelf : EnumAttr<"swiftself", IntersectPreserve, [ParamAttr]>;
+def SwiftSelf : EnumAttr<"swiftself", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// Argument is swift async context.
-def SwiftAsync : EnumAttr<"swiftasync", IntersectPreserve, [ParamAttr]>;
+def SwiftAsync : EnumAttr<"swiftasync", IntersectPreserve, [ParamAttr, ABIAttr]>;
 
 /// Function must be in a unwind table.
 def UWTable : IntAttr<"uwtable", IntersectPreserve, [FnAttr]>;
@@ -398,7 +400,8 @@ def Writable : EnumAttr<"writable", IntersectAnd, [ParamAttr]>;
 def WriteOnly : EnumAttr<"writeonly", IntersectAnd, [ParamAttr]>;
 
 /// Zero extended before/after call.
-def ZExt : EnumAttr<"zeroext", IntersectPreserve, [ParamAttr, RetAttr]>;
+def ZExt : EnumAttr<"zeroext", IntersectPreserve,
+                    [ParamAttr, RetAttr, ABIAttr]>;
 
 /// Function is required to make Forward Progress.
 def MustProgress : EnumAttr<"mustprogress", IntersectAnd, [FnAttr]>;

diff  --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index 5f7df6a4eb6f8..8d3ff9c996daa 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -1658,6 +1658,7 @@ class CallBase : public Instruction {
 
   /// Determine whether the return value has the given attribute.
   bool hasRetAttr(Attribute::AttrKind Kind) const {
+    assert(!Attribute::isABIAttr(Kind) && "Use hasABIRetAttr() instead");
     return hasRetAttrImpl(Kind);
   }
   /// Determine whether the return value has the given attribute.
@@ -1687,6 +1688,22 @@ class CallBase : public Instruction {
   LLVM_ABI bool paramHasNonNullAttr(unsigned ArgNo,
                                     bool AllowUndefOrPoison) const;
 
+  /// Determine whether the argument has the given ABI attribute. As this is
+  /// an ABI attribute, only check the call-site and do not inherit from the
+  /// callee.
+  bool hasABIParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
+    assert(Attribute::isABIAttr(Kind) && "Expected ABI attribute");
+    return Attrs.hasParamAttr(ArgNo, Kind);
+  }
+
+  /// Determine whether the return value has the given ABI attribute. As this
+  /// is an ABI attribute, only check the call-site and do not inherit from the
+  /// callee.
+  bool hasABIRetAttr(Attribute::AttrKind Kind) const {
+    assert(Attribute::isABIAttr(Kind) && "Expected ABI attribute");
+    return Attrs.hasRetAttr(Kind);
+  }
+
   /// Get the attribute of a given kind at a position.
   Attribute getAttributeAtIndex(unsigned i, Attribute::AttrKind Kind) const {
     return getAttributes().getAttributeAtIndex(i, Kind);
@@ -1776,20 +1793,20 @@ class CallBase : public Instruction {
 
   /// Determine whether this argument is passed by value.
   bool isByValArgument(unsigned ArgNo) const {
-    return paramHasAttr(ArgNo, Attribute::ByVal);
+    return hasABIParamAttr(ArgNo, Attribute::ByVal);
   }
 
   /// Determine whether this argument is passed in an alloca.
   bool isInAllocaArgument(unsigned ArgNo) const {
-    return paramHasAttr(ArgNo, Attribute::InAlloca);
+    return hasABIParamAttr(ArgNo, Attribute::InAlloca);
   }
 
   /// Determine whether this argument is passed by value, in an alloca, or is
   /// preallocated.
   bool isPassPointeeByValueArgument(unsigned ArgNo) const {
-    return paramHasAttr(ArgNo, Attribute::ByVal) ||
-           paramHasAttr(ArgNo, Attribute::InAlloca) ||
-           paramHasAttr(ArgNo, Attribute::Preallocated);
+    return hasABIParamAttr(ArgNo, Attribute::ByVal) ||
+           hasABIParamAttr(ArgNo, Attribute::InAlloca) ||
+           hasABIParamAttr(ArgNo, Attribute::Preallocated);
   }
 
   /// Determine whether passing undef to this argument is undefined behavior.
@@ -1806,7 +1823,7 @@ class CallBase : public Instruction {
   /// Determine if there are is an inalloca argument. Only the last argument can
   /// have the inalloca attribute.
   bool hasInAllocaArgument() const {
-    return !arg_empty() && paramHasAttr(arg_size() - 1, Attribute::InAlloca);
+    return !arg_empty() && hasABIParamAttr(arg_size() - 1, Attribute::InAlloca);
   }
 
   // FIXME: Once this API is no longer duplicated in `CallSite`, rename this to
@@ -1852,49 +1869,29 @@ class CallBase : public Instruction {
     return Attrs.getParamStackAlignment(ArgNo);
   }
 
-  /// Extract the byref type for a call or parameter.
+  /// Extract the byref type for a call argument.
   Type *getParamByRefType(unsigned ArgNo) const {
-    if (auto *Ty = Attrs.getParamByRefType(ArgNo))
-      return Ty;
-    if (const Function *F = getCalledFunction())
-      return F->getAttributes().getParamByRefType(ArgNo);
-    return nullptr;
+    return Attrs.getParamByRefType(ArgNo);
   }
 
-  /// Extract the byval type for a call or parameter.
+  /// Extract the byval type for a call argument.
   Type *getParamByValType(unsigned ArgNo) const {
-    if (auto *Ty = Attrs.getParamByValType(ArgNo))
-      return Ty;
-    if (const Function *F = getCalledFunction())
-      return F->getAttributes().getParamByValType(ArgNo);
-    return nullptr;
+    return Attrs.getParamByValType(ArgNo);
   }
 
-  /// Extract the preallocated type for a call or parameter.
+  /// Extract the preallocated type for a call argument.
   Type *getParamPreallocatedType(unsigned ArgNo) const {
-    if (auto *Ty = Attrs.getParamPreallocatedType(ArgNo))
-      return Ty;
-    if (const Function *F = getCalledFunction())
-      return F->getAttributes().getParamPreallocatedType(ArgNo);
-    return nullptr;
+    return Attrs.getParamPreallocatedType(ArgNo);
   }
 
-  /// Extract the inalloca type for a call or parameter.
+  /// Extract the inalloca type for a call argument.
   Type *getParamInAllocaType(unsigned ArgNo) const {
-    if (auto *Ty = Attrs.getParamInAllocaType(ArgNo))
-      return Ty;
-    if (const Function *F = getCalledFunction())
-      return F->getAttributes().getParamInAllocaType(ArgNo);
-    return nullptr;
+    return Attrs.getParamInAllocaType(ArgNo);
   }
 
-  /// Extract the sret type for a call or parameter.
+  /// Extract the sret type for a call argument.
   Type *getParamStructRetType(unsigned ArgNo) const {
-    if (auto *Ty = Attrs.getParamStructRetType(ArgNo))
-      return Ty;
-    if (const Function *F = getCalledFunction())
-      return F->getAttributes().getParamStructRetType(ArgNo);
-    return nullptr;
+    return Attrs.getParamStructRetType(ArgNo);
   }
 
   /// Extract the elementtype type for a parameter.
@@ -2043,8 +2040,7 @@ class CallBase : public Instruction {
     if (arg_empty())
       return false;
 
-    // Be friendly and also check the callee.
-    return paramHasAttr(0, Attribute::StructRet);
+    return hasABIParamAttr(0, Attribute::StructRet);
   }
 
   /// Determine if any call argument is an aggregate passed by value.

diff  --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp
index 26e78826848e7..54df723c69e85 100644
--- a/llvm/lib/Analysis/Lint.cpp
+++ b/llvm/lib/Analysis/Lint.cpp
@@ -264,12 +264,13 @@ void Lint::visitCallBase(CallBase &I) {
 
         // Check that ABI attributes for the function and call-site match.
         unsigned ArgNo = AI->getOperandNo();
-        Attribute::AttrKind ABIAttributes[] = {
-            Attribute::ZExt,         Attribute::SExt,     Attribute::InReg,
-            Attribute::ByVal,        Attribute::ByRef,    Attribute::InAlloca,
-            Attribute::Preallocated, Attribute::StructRet};
         AttributeList CallAttrs = I.getAttributes();
-        for (Attribute::AttrKind Attr : ABIAttributes) {
+        for (Attribute::AttrKind Attr :
+             drop_begin(enum_seq(Attribute::None, Attribute::EndAttrKinds,
+                                 force_iteration_on_noniterable_enum))) {
+          if (!Attribute::isABIAttr(Attr))
+            continue;
+
           Attribute CallAttr = CallAttrs.getParamAttr(ArgNo, Attr);
           Attribute FnAttr = F->getParamAttribute(ArgNo, Attr);
           Check(CallAttr.isValid() == FnAttr.isValid(),

diff  --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index 4d97001eb7420..eedb70b6ac522 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -104,8 +104,11 @@ ISD::ArgFlagsTy CallLowering::getAttributesForArgIdx(const CallBase &Call,
   ISD::ArgFlagsTy Flags;
   const AttributeList &Attrs = Call.getAttributes();
   addFlagsFromAttrSet(Flags, Attrs.getParamAttrs(ArgIdx));
-  if (const Function *F = Call.getCalledFunction())
-    addFlagsFromAttrSet(Flags, F->getAttributes().getParamAttrs(ArgIdx));
+  if (const Function *F = Call.getCalledFunction()) {
+    // "returned" is not an ABI attribute, so we can inherit it from the callee.
+    if (F->hasParamAttribute(ArgIdx, Attribute::Returned))
+      Flags.setReturned();
+  }
   return Flags;
 }
 
@@ -113,8 +116,6 @@ ISD::ArgFlagsTy
 CallLowering::getAttributesForReturn(const CallBase &Call) const {
   ISD::ArgFlagsTy Flags;
   addFlagsFromAttrSet(Flags, Call.getAttributes().getRetAttrs());
-  if (const Function *F = Call.getCalledFunction())
-    addFlagsFromAttrSet(Flags, F->getAttributes().getRetAttrs());
   return Flags;
 }
 

diff  --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index 6ca0592644a08..7f9776fda5c0b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -73,8 +73,8 @@ static ISD::NodeType getPreferredExtendForValue(const Instruction *I) {
       if (!CallI->isArgOperand(&U))
         continue;
       unsigned ArgNo = CallI->getArgOperandNo(&U);
-      NumOfUnsigned += CallI->paramHasAttr(ArgNo, Attribute::ZExt);
-      NumOfSigned += CallI->paramHasAttr(ArgNo, Attribute::SExt);
+      NumOfUnsigned += CallI->hasABIParamAttr(ArgNo, Attribute::ZExt);
+      NumOfSigned += CallI->hasABIParamAttr(ArgNo, Attribute::SExt);
     }
   }
   if (NumOfSigned > NumOfUnsigned)

diff  --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index b5f2cd0e61d06..551abd6f0c87f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -119,19 +119,19 @@ bool TargetLowering::parametersInCSRMatch(const MachineRegisterInfo &MRI,
 /// and called function attributes.
 void TargetLoweringBase::ArgListEntry::setAttributes(const CallBase *Call,
                                                      unsigned ArgIdx) {
-  IsSExt = Call->paramHasAttr(ArgIdx, Attribute::SExt);
-  IsZExt = Call->paramHasAttr(ArgIdx, Attribute::ZExt);
-  IsNoExt = Call->paramHasAttr(ArgIdx, Attribute::NoExt);
-  IsInReg = Call->paramHasAttr(ArgIdx, Attribute::InReg);
-  IsSRet = Call->paramHasAttr(ArgIdx, Attribute::StructRet);
-  IsNest = Call->paramHasAttr(ArgIdx, Attribute::Nest);
-  IsByVal = Call->paramHasAttr(ArgIdx, Attribute::ByVal);
-  IsPreallocated = Call->paramHasAttr(ArgIdx, Attribute::Preallocated);
-  IsInAlloca = Call->paramHasAttr(ArgIdx, Attribute::InAlloca);
+  IsSExt = Call->hasABIParamAttr(ArgIdx, Attribute::SExt);
+  IsZExt = Call->hasABIParamAttr(ArgIdx, Attribute::ZExt);
+  IsNoExt = Call->hasABIParamAttr(ArgIdx, Attribute::NoExt);
+  IsInReg = Call->hasABIParamAttr(ArgIdx, Attribute::InReg);
+  IsSRet = Call->hasABIParamAttr(ArgIdx, Attribute::StructRet);
+  IsNest = Call->hasABIParamAttr(ArgIdx, Attribute::Nest);
+  IsByVal = Call->hasABIParamAttr(ArgIdx, Attribute::ByVal);
+  IsPreallocated = Call->hasABIParamAttr(ArgIdx, Attribute::Preallocated);
+  IsInAlloca = Call->hasABIParamAttr(ArgIdx, Attribute::InAlloca);
   IsReturned = Call->paramHasAttr(ArgIdx, Attribute::Returned);
-  IsSwiftSelf = Call->paramHasAttr(ArgIdx, Attribute::SwiftSelf);
-  IsSwiftAsync = Call->paramHasAttr(ArgIdx, Attribute::SwiftAsync);
-  IsSwiftError = Call->paramHasAttr(ArgIdx, Attribute::SwiftError);
+  IsSwiftSelf = Call->hasABIParamAttr(ArgIdx, Attribute::SwiftSelf);
+  IsSwiftAsync = Call->hasABIParamAttr(ArgIdx, Attribute::SwiftAsync);
+  IsSwiftError = Call->hasABIParamAttr(ArgIdx, Attribute::SwiftError);
   Alignment = Call->getParamStackAlign(ArgIdx);
   IndirectType = nullptr;
   assert(IsByVal + IsPreallocated + IsInAlloca + IsSRet <= 1 &&

diff  --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp
index 59ea4281f6ee4..6df993b4420a4 100644
--- a/llvm/lib/CodeGen/TypePromotion.cpp
+++ b/llvm/lib/CodeGen/TypePromotion.cpp
@@ -243,7 +243,7 @@ bool TypePromotionImpl::isSource(Value *V) {
   else if (isa<LoadInst>(V))
     return true;
   else if (auto *Call = dyn_cast<CallInst>(V))
-    return Call->hasRetAttr(Attribute::AttrKind::ZExt);
+    return Call->hasABIRetAttr(Attribute::AttrKind::ZExt);
   else if (auto *Trunc = dyn_cast<TruncInst>(V))
     return EqualTypeSize(Trunc);
   return false;
@@ -774,7 +774,7 @@ bool TypePromotionImpl::isSupportedValue(Value *V) {
       // can still be sinks.
       auto *Call = cast<CallInst>(I);
       return isSupportedType(Call) &&
-             Call->hasRetAttr(Attribute::AttrKind::ZExt);
+             Call->hasABIRetAttr(Attribute::AttrKind::ZExt);
     }
     }
   } else if (isa<Constant>(V) && !isa<ConstantExpr>(V)) {

diff  --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 727a7bcb6a144..7f5f5f34af389 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -811,6 +811,7 @@ enum AttributeProperty {
   IntersectMin = (2 << 3),
   IntersectCustom = (3 << 3),
   IntersectPropertyMask = (3 << 3),
+  ABIAttr = (1 << 5),
 };
 
 #define GET_ATTR_PROP_TABLE
@@ -839,6 +840,10 @@ bool Attribute::canUseAsRetAttr(AttrKind Kind) {
   return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
 }
 
+bool Attribute::isABIAttr(AttrKind Kind) {
+  return hasAttributeProperty(Kind, AttributeProperty::ABIAttr);
+}
+
 static bool hasIntersectProperty(Attribute::AttrKind Kind,
                                  AttributeProperty Prop) {
   assert((Prop == AttributeProperty::IntersectPreserve ||

diff  --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 325850b0a880d..ec794f28fff71 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -419,6 +419,7 @@ Value *CallBase::getArgOperandWithAttribute(Attribute::AttrKind Kind) const {
 /// Determine whether the argument or parameter has the given attribute.
 bool CallBase::paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
   assert(ArgNo < arg_size() && "Param index out of bounds!");
+  assert(!Attribute::isABIAttr(Kind) && "Use hasABIParamAttr() instead");
 
   if (Attrs.hasParamAttr(ArgNo, Kind))
     return true;

diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 20df60ed61da3..dabb285f850e2 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4038,7 +4038,7 @@ void Verifier::visitCallBase(CallBase &Call) {
   // make sure the underlying alloca/parameter it comes from has a swifterror as
   // well.
   for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
-    if (Call.paramHasAttr(i, Attribute::SwiftError)) {
+    if (Call.hasABIParamAttr(i, Attribute::SwiftError)) {
       Value *SwiftErrorArg = Call.getArgOperand(i);
       if (auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets())) {
         Check(AI->isSwiftError(),
@@ -4087,7 +4087,7 @@ void Verifier::visitCallBase(CallBase &Call) {
               Call);
     }
 
-    if (Call.paramHasAttr(i, Attribute::Preallocated)) {
+    if (Call.hasABIParamAttr(i, Attribute::Preallocated)) {
       Value *ArgVal = Call.getArgOperand(i);
       bool hasOB =
           Call.countOperandBundlesOfType(LLVMContext::OB_preallocated) != 0;
@@ -4798,7 +4798,7 @@ void Verifier::verifySwiftErrorCall(CallBase &Call,
                                     const Value *SwiftErrorVal) {
   for (const auto &I : llvm::enumerate(Call.args())) {
     if (I.value() == SwiftErrorVal) {
-      Check(Call.paramHasAttr(I.index(), Attribute::SwiftError),
+      Check(Call.hasABIParamAttr(I.index(), Attribute::SwiftError),
             "swifterror value when used in a callsite should be marked "
             "with swifterror attribute",
             SwiftErrorVal, Call);
@@ -6462,7 +6462,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
         FoundCall = true;
         size_t NumPreallocatedArgs = 0;
         for (unsigned i = 0; i < UseCall->arg_size(); i++) {
-          if (UseCall->paramHasAttr(i, Attribute::Preallocated)) {
+          if (UseCall->hasABIParamAttr(i, Attribute::Preallocated)) {
             ++NumPreallocatedArgs;
           }
         }

diff  --git a/llvm/lib/IR/VerifierAMDGPU.cpp b/llvm/lib/IR/VerifierAMDGPU.cpp
index 9f2cd159ad60f..6338bcd74f431 100644
--- a/llvm/lib/IR/VerifierAMDGPU.cpp
+++ b/llvm/lib/IR/VerifierAMDGPU.cpp
@@ -192,9 +192,9 @@ void llvm::verifyAMDGPUIntrinsicCall(VerifierSupport &VS, Intrinsic::ID ID,
       break;
     }
 
-    Check(Call.paramHasAttr(2, Attribute::InReg),
+    Check(Call.hasABIParamAttr(2, Attribute::InReg),
           "SGPR arguments must have the `inreg` attribute", &Call);
-    Check(!Call.paramHasAttr(3, Attribute::InReg),
+    Check(!Call.hasABIParamAttr(3, Attribute::InReg),
           "VGPR arguments must not have the `inreg` attribute", &Call);
 
     ConstantInt *FlagsArg = cast<ConstantInt>(Call.getArgOperand(4));
@@ -232,7 +232,7 @@ void llvm::verifyAMDGPUIntrinsicCall(VerifierSupport &VS, Intrinsic::ID ID,
     }
 
     unsigned InactiveIdx = 1;
-    Check(!Call.paramHasAttr(InactiveIdx, Attribute::InReg),
+    Check(!Call.hasABIParamAttr(InactiveIdx, Attribute::InReg),
           "Value for inactive lanes must not have the `inreg` attribute",
           &Call);
     Check(isa<Argument>(Call.getArgOperand(InactiveIdx)),
@@ -262,7 +262,7 @@ void llvm::verifyAMDGPUIntrinsicCall(VerifierSupport &VS, Intrinsic::ID ID,
       Check(CallArg->getType() == FuncArg.getType(),
             "Argument types must match", &Call);
 
-      Check(Call.paramHasAttr(FuncArg.getArgNo(), Attribute::InReg) ==
+      Check(Call.hasABIParamAttr(FuncArg.getArgNo(), Attribute::InReg) ==
                 FuncArg.hasInRegAttr(),
             "Argument inreg attributes must match", &Call);
     }

diff  --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index b6dd07dd26514..a5d96bedf72af 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -3345,10 +3345,10 @@ bool isArgPassedInSGPR(const CallBase *CB, unsigned ArgNo) {
   case CallingConv::AMDGPU_CS_ChainPreserve:
     // For non-compute shaders, SGPR inputs are marked with either inreg or
     // byval. Everything else is in VGPRs.
-    return CB->paramHasAttr(ArgNo, Attribute::InReg) ||
+    return CB->hasABIParamAttr(ArgNo, Attribute::InReg) ||
            CB->isByValArgument(ArgNo);
   default:
-    return CB->paramHasAttr(ArgNo, Attribute::InReg);
+    return CB->hasABIParamAttr(ArgNo, Attribute::InReg);
   }
 }
 

diff  --git a/llvm/lib/Target/ARM/ARMFastISel.cpp b/llvm/lib/Target/ARM/ARMFastISel.cpp
index 88ee3156ee339..043533c719846 100644
--- a/llvm/lib/Target/ARM/ARMFastISel.cpp
+++ b/llvm/lib/Target/ARM/ARMFastISel.cpp
@@ -2424,18 +2424,18 @@ bool ARMFastISel::SelectCall(const Instruction *I,
 
     ISD::ArgFlagsTy Flags;
     unsigned ArgIdx = ArgI - CI->arg_begin();
-    if (CI->paramHasAttr(ArgIdx, Attribute::SExt))
+    if (CI->hasABIParamAttr(ArgIdx, Attribute::SExt))
       Flags.setSExt();
-    if (CI->paramHasAttr(ArgIdx, Attribute::ZExt))
+    if (CI->hasABIParamAttr(ArgIdx, Attribute::ZExt))
       Flags.setZExt();
 
     // FIXME: Only handle *easy* calls for now.
-    if (CI->paramHasAttr(ArgIdx, Attribute::InReg) ||
-        CI->paramHasAttr(ArgIdx, Attribute::StructRet) ||
-        CI->paramHasAttr(ArgIdx, Attribute::SwiftSelf) ||
-        CI->paramHasAttr(ArgIdx, Attribute::SwiftError) ||
-        CI->paramHasAttr(ArgIdx, Attribute::Nest) ||
-        CI->paramHasAttr(ArgIdx, Attribute::ByVal))
+    if (CI->hasABIParamAttr(ArgIdx, Attribute::InReg) ||
+        CI->hasABIParamAttr(ArgIdx, Attribute::StructRet) ||
+        CI->hasABIParamAttr(ArgIdx, Attribute::SwiftSelf) ||
+        CI->hasABIParamAttr(ArgIdx, Attribute::SwiftError) ||
+        CI->hasABIParamAttr(ArgIdx, Attribute::Nest) ||
+        CI->hasABIParamAttr(ArgIdx, Attribute::ByVal))
       return false;
 
     Type *ArgTy = (*ArgI)->getType();

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index db03f5874234c..c9eab64788911 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -921,9 +921,9 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
 
     unsigned Reg;
 
-    if (Call->paramHasAttr(I, Attribute::SExt))
+    if (Call->hasABIParamAttr(I, Attribute::SExt))
       Reg = getRegForSignedValue(V);
-    else if (Call->paramHasAttr(I, Attribute::ZExt))
+    else if (Call->hasABIParamAttr(I, Attribute::ZExt))
       Reg = getRegForUnsignedValue(V);
     else
       Reg = getRegForValue(V);

diff  --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp
index a8f228ea661ce..198988d453a33 100644
--- a/llvm/lib/Target/X86/X86FastISel.cpp
+++ b/llvm/lib/Target/X86/X86FastISel.cpp
@@ -3177,8 +3177,8 @@ static unsigned computeBytesPoppedByCalleeForSRet(const X86Subtarget *Subtarget,
     return 0;
 
   if (CB)
-    if (CB->arg_empty() || !CB->paramHasAttr(0, Attribute::StructRet) ||
-        CB->paramHasAttr(0, Attribute::InReg) || Subtarget->isTargetMCU())
+    if (CB->arg_empty() || !CB->hasStructRetAttr() ||
+        CB->hasABIParamAttr(0, Attribute::InReg) || Subtarget->isTargetMCU())
       return 0;
 
   return 4;

diff  --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 9a03da14ee10e..c10b82b68de07 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2294,7 +2294,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
            "parameter");
     SmallVector<size_t, 4> PreallocatedOffsets;
     for (size_t i = 0; i < CLI.OutVals.size(); ++i) {
-      if (CLI.CB->paramHasAttr(i, Attribute::Preallocated)) {
+      if (CLI.CB->hasABIParamAttr(i, Attribute::Preallocated)) {
         PreallocatedOffsets.push_back(ArgLocs[i].getLocMemOffset());
       }
     }

diff  --git a/llvm/lib/Transforms/IPO/ExpandVariadics.cpp b/llvm/lib/Transforms/IPO/ExpandVariadics.cpp
index 44d944933cc3a..bd76b9ce5b954 100644
--- a/llvm/lib/Transforms/IPO/ExpandVariadics.cpp
+++ b/llvm/lib/Transforms/IPO/ExpandVariadics.cpp
@@ -680,8 +680,8 @@ bool ExpandVariadics::expandCall(Module &M, IRBuilder<> &Builder, CallBase *CB,
 
   for (unsigned I : seq(VarargFunctionType->getNumParams(), CB->arg_size())) {
     Value *ArgVal = CB->getArgOperand(I);
-    const bool IsByVal = CB->paramHasAttr(I, Attribute::ByVal);
-    const bool IsByRef = CB->paramHasAttr(I, Attribute::ByRef);
+    const bool IsByVal = CB->hasABIParamAttr(I, Attribute::ByVal);
+    const bool IsByRef = CB->hasABIParamAttr(I, Attribute::ByRef);
 
     // The type of the value being passed, decoded from byval/byref metadata if
     // required

diff  --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 4084f3d580e57..0b7c452103543 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -9098,8 +9098,8 @@ struct VarArgSystemZHelper : public VarArgHelperBase {
     // 64-bit integer representing the same number, using sign or zero
     // extension". Shadow for an integer argument has the same type as the
     // argument itself, so it can be sign or zero extended as well.
-    bool ZExt = CB.paramHasAttr(ArgNo, Attribute::ZExt);
-    bool SExt = CB.paramHasAttr(ArgNo, Attribute::SExt);
+    bool ZExt = CB.hasABIParamAttr(ArgNo, Attribute::ZExt);
+    bool SExt = CB.hasABIParamAttr(ArgNo, Attribute::SExt);
     if (ZExt) {
       assert(!SExt);
       return ShadowExtension::Zero;

diff  --git a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
index a49f0c73ad3e3..7ae67db5f0002 100644
--- a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -476,7 +476,7 @@ bool llvm::isLegalToPromote(const CallBase &CB, Function *Callee,
   for (; I < NumArgs; I++) {
     // Vararg functions can have more arguments than parameters.
     assert(Callee->isVarArg());
-    if (CB.paramHasAttr(I, Attribute::StructRet)) {
+    if (CB.hasABIParamAttr(I, Attribute::StructRet)) {
       if (FailureReason)
         *FailureReason = "SRet arg to vararg function";
       return false;

diff  --git a/llvm/test/Analysis/BasicAA/call-attrs.ll b/llvm/test/Analysis/BasicAA/call-attrs.ll
index f6e92dd34ff7f..aa5fd471c52ba 100644
--- a/llvm/test/Analysis/BasicAA/call-attrs.ll
+++ b/llvm/test/Analysis/BasicAA/call-attrs.ll
@@ -25,7 +25,7 @@ entry:
   call void @readnone_attr(ptr %p)
   call void @readnone_func(ptr %p)
 
-  call void @byval_attr(ptr %p)
+  call void @byval_attr(ptr byval(i32) %p)
 
   call void @read_write(ptr %p, ptr %p, ptr %p)
 
@@ -41,7 +41,7 @@ entry:
 ; CHECK:  Just Mod:  Ptr: i8* %p	<->  call void @writeonly_func(ptr %p)
 ; CHECK:  NoModRef:  Ptr: i8* %p	<->  call void @readnone_attr(ptr %p)
 ; CHECK:  NoModRef:  Ptr: i8* %p	<->  call void @readnone_func(ptr %p)
-; CHECK:  Just Ref:  Ptr: i8* %p	<->  call void @byval_attr(ptr %p)
+; CHECK:  Just Ref:  Ptr: i8* %p	<->  call void @byval_attr(ptr byval(i32) %p)
 ; CHECK:  Both ModRef:  Ptr: i8* %p	<->  call void @read_write(ptr %p, ptr %p, ptr %p)
 ; CHECK:  Just Ref:  Ptr: i8* %p	<->  call void @func() [ "deopt"(ptr %p) ]
 ; CHECK:  Both ModRef:  Ptr: i8* %p	<->  call void @writeonly_attr(ptr %p) [ "deopt"(ptr %p) ]

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call-sret.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call-sret.ll
index 545d854f047ec..c60b9e5cc840a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call-sret.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call-sret.ll
@@ -13,7 +13,7 @@ define void @can_tail_call_forwarded_explicit_sret_ptr(ptr sret(i64) %arg) {
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x8
   ; CHECK-NEXT:   $x8 = COPY [[COPY]](p0)
   ; CHECK-NEXT:   TCRETURNdi @test_explicit_sret, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $x8
-  tail call void @test_explicit_sret(ptr %arg)
+  tail call void @test_explicit_sret(ptr sret(i64) %arg)
   ret void
 }
 
@@ -29,7 +29,7 @@ define void @test_call_explicit_sret(ptr sret(i64) %arg) {
   ; CHECK-NEXT:   BL @test_explicit_sret, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x8
   ; CHECK-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
   ; CHECK-NEXT:   RET_ReallyLR
-  call void @test_explicit_sret(ptr %arg)
+  call void @test_explicit_sret(ptr sret(i64) %arg)
   ret void
 }
 
@@ -43,7 +43,7 @@ define void @dont_tail_call_explicit_sret_alloca_unused() {
   ; CHECK-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
   ; CHECK-NEXT:   RET_ReallyLR
   %l = alloca i64, align 8
-  tail call void @test_explicit_sret(ptr %l)
+  tail call void @test_explicit_sret(ptr sret(i64) %l)
   ret void
 }
 
@@ -64,7 +64,7 @@ define void @dont_tail_call_explicit_sret_alloca_dummyusers(ptr %ptr) {
   %l = alloca i64, align 8
   %r = load i64, ptr %ptr, align 8
   store i64 %r, ptr %l, align 8
-  tail call void @test_explicit_sret(ptr %l)
+  tail call void @test_explicit_sret(ptr sret(i64) %l)
   ret void
 }
 
@@ -82,7 +82,7 @@ define void @dont_tail_call_tailcall_explicit_sret_gep(ptr %ptr) {
   ; CHECK-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
   ; CHECK-NEXT:   RET_ReallyLR
   %ptr2 = getelementptr i64, ptr %ptr, i32 1
-  tail call void @test_explicit_sret(ptr %ptr2)
+  tail call void @test_explicit_sret(ptr sret(i64) %ptr2)
   ret void
 }
 
@@ -98,7 +98,7 @@ define i64 @dont_tail_call_sret_alloca_returned() {
   ; CHECK-NEXT:   $x0 = COPY [[LOAD]](i64)
   ; CHECK-NEXT:   RET_ReallyLR implicit $x0
   %l = alloca i64, align 8
-  tail call void @test_explicit_sret(ptr %l)
+  tail call void @test_explicit_sret(ptr sret(i64) %l)
   %r = load i64, ptr %l, align 8
   ret i64 %r
 }

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
index 25baf6a295b14..2071f8eed9fa4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
@@ -151,13 +151,14 @@ define void @test_abi_exts_call(ptr %addr) {
   ret void
 }
 
+; zeroext on callee is not inherited.
 ; CHECK-LABEL: name: test_zext_in_callee
 ; CHECK: bb.1 (%ir-block.0):
 ; CHECK:   liveins: $x0
 ; CHECK:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
 ; CHECK:   [[LOAD:%[0-9]+]]:_(i8) = G_LOAD [[COPY]](p0) :: (load (i8) from %ir.addr)
 ; CHECK:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
-; CHECK:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[LOAD]](i8)
+; CHECK:   [[ZEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[LOAD]](i8)
 ; CHECK:   $w0 = COPY [[ZEXT]](i32)
 ; CHECK:   BL @has_zext_param, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0
 ; CHECK:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
@@ -169,13 +170,14 @@ define void @test_zext_in_callee(ptr %addr) {
   ret void
 }
 
+; signext on callee is not inherited.
 ; CHECK-LABEL: name: test_sext_in_callee
 ; CHECK: bb.1 (%ir-block.0):
 ; CHECK:   liveins: $x0
 ; CHECK:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
 ; CHECK:   [[LOAD:%[0-9]+]]:_(i8) = G_LOAD [[COPY]](p0) :: (load (i8) from %ir.addr)
 ; CHECK:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
-; CHECK:   [[SEXT:%[0-9]+]]:_(i32) = G_SEXT [[LOAD]](i8)
+; CHECK:   [[SEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[LOAD]](i8)
 ; CHECK:   $w0 = COPY [[SEXT]](i32)
 ; CHECK:   BL @has_sext_param, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0
 ; CHECK:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
@@ -364,7 +366,7 @@ define void @call_returns_array_size0_struct() {
 
 ; Test extends on return values.
 
-; This should notice that the return value from has_zext_return is zero
+; This should *not* assume that the return value from has_zext_return is zero
 ; extended.
 declare zeroext i16 @has_zext_return()
 define i32 @test_zext_return_from_callee() {
@@ -374,8 +376,7 @@ define i32 @test_zext_return_from_callee() {
   ; CHECK-NEXT:   BL @has_zext_return, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $w0
   ; CHECK-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(i32) = COPY $w0
-  ; CHECK-NEXT:   [[ASSERT_ZEXT:%[0-9]+]]:_(i32) = G_ASSERT_ZEXT [[COPY]], 16
-  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[ASSERT_ZEXT]](i32)
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[COPY]](i32)
   ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[TRUNC]](i16)
   ; CHECK-NEXT:   $w0 = COPY [[ZEXT]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
@@ -403,7 +404,7 @@ define i32 @test_zext_return_from_callee2() {
   ret i32 %ext
 }
 
-; This should notice that the return value from has_sext_return is sign
+; This should *not* assume that the return value from has_sext_return is sign
 ; extended.
 declare signext i16 @has_sext_return()
 define i32 @test_sext_return_from_callee() {
@@ -413,8 +414,7 @@ define i32 @test_sext_return_from_callee() {
   ; CHECK-NEXT:   BL @has_sext_return, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $w0
   ; CHECK-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(i32) = COPY $w0
-  ; CHECK-NEXT:   [[ASSERT_SEXT:%[0-9]+]]:_(i32) = G_ASSERT_SEXT [[COPY]], 16
-  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[ASSERT_SEXT]](i32)
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[COPY]](i32)
   ; CHECK-NEXT:   [[SEXT:%[0-9]+]]:_(i32) = G_SEXT [[TRUNC]](i16)
   ; CHECK-NEXT:   $w0 = COPY [[SEXT]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll b/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
index 78fc6ccc50663..26b042213972c 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
@@ -518,7 +518,7 @@ define float @swifterror_param_not_on_call(ptr %error_ref) {
 entry:
   %error_ptr_ref = alloca swifterror ptr
   store ptr null, ptr %error_ptr_ref
-  %call = call float @foo(ptr %error_ptr_ref)
+  %call = call float @foo(ptr swifterror %error_ptr_ref)
   %error_from_foo = load ptr, ptr %error_ptr_ref
   %had_error_from_foo = icmp ne ptr %error_from_foo, null
   br i1 %had_error_from_foo, label %handler, label %cont
@@ -550,7 +550,7 @@ entry:
   %s = alloca %struct.S, align 8
   %error_ptr_ref = alloca swifterror ptr
   store ptr null, ptr %error_ptr_ref
-  call void @foo_sret(ptr %s, i32 1, ptr %error_ptr_ref)
+  call void @foo_sret(ptr %s, i32 1, ptr swifterror %error_ptr_ref)
   %error_from_foo = load ptr, ptr %error_ptr_ref
   %had_error_from_foo = icmp ne ptr %error_from_foo, null
   br i1 %had_error_from_foo, label %handler, label %cont

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll b/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
index b8c9102af3bb1..68872b18b76c0 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
@@ -61,10 +61,10 @@ entry:
   ret void
 }
 
-; Check that x20 is used to pass a swiftself argument when the parameter is
+; Check that x20 is NOT used to pass a swiftself argument when the attribute is
 ; only in the declaration's arguments.
 ; CHECK-LABEL: _swiftself_not_on_call_params:
-; CHECK: mov x20, x0
+; CHECK-NOT: mov{{.*}}x20
 ; CHECK: bl {{_?}}swiftself_param
 ; CHECK: ret
 define ptr @swiftself_not_on_call_params(ptr %arg) {

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-return-values.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-return-values.ll
index 5160093a4e273..0d52c4e3510ed 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-return-values.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-return-values.ll
@@ -286,7 +286,7 @@ define amdgpu_kernel void @test_call_external_i1_zeroext_func_void() #0 {
   ; GCN-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[TRUNC]](i1)
   ; GCN-NEXT:   G_STORE [[ZEXT]](i32), [[DEF]](p1) :: (volatile store (i32) into `ptr addrspace(1) poison`, addrspace 1)
   ; GCN-NEXT:   S_ENDPGM 0
-  %val = call i1 @external_i1_zeroext_func_void()
+  %val = call zeroext i1 @external_i1_zeroext_func_void()
   %val.ext = zext i1 %val to i32
   store volatile i32 %val.ext, ptr addrspace(1) poison
   ret void
@@ -348,7 +348,7 @@ define amdgpu_kernel void @test_call_external_i1_signext_func_void() #0 {
   ; GCN-NEXT:   [[SEXT:%[0-9]+]]:_(i32) = G_SEXT [[TRUNC]](i1)
   ; GCN-NEXT:   G_STORE [[SEXT]](i32), [[DEF]](p1) :: (volatile store (i32) into `ptr addrspace(1) poison`, addrspace 1)
   ; GCN-NEXT:   S_ENDPGM 0
-  %val = call i1 @external_i1_signext_func_void()
+  %val = call signext i1 @external_i1_signext_func_void()
   %val.ext = sext i1 %val to i32
   store volatile i32 %val.ext, ptr addrspace(1) poison
   ret void
@@ -490,7 +490,7 @@ define amdgpu_kernel void @test_call_external_i8_zeroext_func_void() #0 {
   ; GCN-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[TRUNC]](i8)
   ; GCN-NEXT:   G_STORE [[ZEXT]](i32), [[DEF]](p1) :: (volatile store (i32) into `ptr addrspace(1) poison`, addrspace 1)
   ; GCN-NEXT:   S_ENDPGM 0
-  %val = call i8 @external_i8_zeroext_func_void()
+  %val = call zeroext i8 @external_i8_zeroext_func_void()
   %val.ext = zext i8 %val to i32
   store volatile i32 %val.ext, ptr addrspace(1) poison
   ret void
@@ -552,7 +552,7 @@ define amdgpu_kernel void @test_call_external_i8_signext_func_void() #0 {
   ; GCN-NEXT:   [[SEXT:%[0-9]+]]:_(i32) = G_SEXT [[TRUNC]](i8)
   ; GCN-NEXT:   G_STORE [[SEXT]](i32), [[DEF]](p1) :: (volatile store (i32) into `ptr addrspace(1) poison`, addrspace 1)
   ; GCN-NEXT:   S_ENDPGM 0
-  %val = call i8 @external_i8_signext_func_void()
+  %val = call signext i8 @external_i8_signext_func_void()
   %val.ext = sext i8 %val to i32
   store volatile i32 %val.ext, ptr addrspace(1) poison
   ret void
@@ -673,7 +673,7 @@ define amdgpu_kernel void @test_call_external_i16_zeroext_func_void() #0 {
   ; GCN-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[TRUNC]](i16)
   ; GCN-NEXT:   G_STORE [[ZEXT]](i32), [[DEF]](p1) :: (volatile store (i32) into `ptr addrspace(1) poison`, addrspace 1)
   ; GCN-NEXT:   S_ENDPGM 0
-  %val = call i16 @external_i16_zeroext_func_void()
+  %val = call zeroext i16 @external_i16_zeroext_func_void()
   %val.ext = zext i16 %val to i32
   store volatile i32 %val.ext, ptr addrspace(1) poison
   ret void
@@ -735,7 +735,7 @@ define amdgpu_kernel void @test_call_external_i16_signext_func_void() #0 {
   ; GCN-NEXT:   [[SEXT:%[0-9]+]]:_(i32) = G_SEXT [[TRUNC]](i16)
   ; GCN-NEXT:   G_STORE [[SEXT]](i32), [[DEF]](p1) :: (volatile store (i32) into `ptr addrspace(1) poison`, addrspace 1)
   ; GCN-NEXT:   S_ENDPGM 0
-  %val = call i16 @external_i16_signext_func_void()
+  %val = call signext i16 @external_i16_signext_func_void()
   %val.ext = sext i16 %val to i32
   store volatile i32 %val.ext, ptr addrspace(1) poison
   ret void

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
index 3917b06d28f0e..5eada470428fe 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
@@ -80,7 +80,7 @@ define amdgpu_kernel void @test_call_external_void_func_sret_struct_i8_i32_byval
   %in.gep1 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %in.val, i32 0, i32 1
   store i8 3, ptr addrspace(5) %in.gep0
   store i32 8, ptr addrspace(5) %in.gep1
-  call void @external_void_func_sret_struct_i8_i32_byval_struct_i8_i32(ptr addrspace(5) %out.val, ptr addrspace(5) %in.val)
+  call void @external_void_func_sret_struct_i8_i32_byval_struct_i8_i32(ptr addrspace(5) sret({ i8, i32 }) %out.val, ptr addrspace(5) byval({ i8, i32 }) %in.val)
   %out.gep0 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %out.val, i32 0, i32 0
   %out.gep1 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %out.val, i32 0, i32 1
   %out.val0 = load i8, ptr addrspace(5) %out.gep0

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call.ll
index 465e87d84a824..05bbddf444adb 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call.ll
@@ -4183,7 +4183,7 @@ define void @call_byval_3ai32_byval_i8_align32(ptr addrspace(5) %incoming0, ptr
   ; CHECK-NEXT:   $sgpr30_sgpr31 = noconvergent G_SI_CALL [[GV]](p0), @void_func_byval_a3i32_byval_i8_align32, csr_amdgpu, implicit $vgpr0, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr4_sgpr5, implicit $sgpr6_sgpr7, implicit $sgpr8_sgpr9, implicit $sgpr10_sgpr11, implicit $sgpr12, implicit $sgpr13, implicit $sgpr14, implicit $sgpr15, implicit $vgpr31
   ; CHECK-NEXT:   ADJCALLSTACKDOWN 0, 36, implicit-def $scc
   ; CHECK-NEXT:   SI_RETURN
-  call void @void_func_byval_a3i32_byval_i8_align32(ptr addrspace(5) byval([3 x i32]) %incoming0, ptr addrspace(5) align 32 %incoming1, i32 999)
+  call void @void_func_byval_a3i32_byval_i8_align32(ptr addrspace(5) byval([3 x i32]) %incoming0, ptr addrspace(5) byval(i8) align 32 %incoming1, i32 999)
   ret void
 }
 

diff  --git a/llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll b/llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll
index b43ffee6270fb..654ae91286336 100644
--- a/llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll
+++ b/llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll
@@ -18,7 +18,7 @@ define amdgpu_ps <4 x float> @caller(ptr %ptr) {
 ; CHECK-NEXT:    s_swappc_b64 s[30:31], s[4:5]
 ; CHECK-NEXT:    ; return to shader part epilog
   %L = load i32, ptr %ptr, align 4
-  %R = call <4 x float> @fn(<4 x i32> zeroinitializer, i32 0, i32 %L, i32 0)
+  %R = call <4 x float> @fn(<4 x i32> inreg zeroinitializer, i32 0, i32 %L, i32 0)
   ret <4 x float> %R
 }
 

diff  --git a/llvm/test/CodeGen/AMDGPU/swdev504645-global-fold.ll b/llvm/test/CodeGen/AMDGPU/swdev504645-global-fold.ll
index da963c0ec19c2..4b2cca13e2618 100644
--- a/llvm/test/CodeGen/AMDGPU/swdev504645-global-fold.ll
+++ b/llvm/test/CodeGen/AMDGPU/swdev504645-global-fold.ll
@@ -34,7 +34,7 @@ define void @test_load_zext() #0 {
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
 .entry:
   %reloc = call i32 @llvm.amdgcn.reloc.constant(metadata !0)
-  call void @has_spgr_args(i32 %reloc)
+  call void @has_spgr_args(i32 inreg %reloc)
   ret void
 }
 

diff  --git a/llvm/test/CodeGen/AMDGPU/waterfall-call-inreg-agpr.ll b/llvm/test/CodeGen/AMDGPU/waterfall-call-inreg-agpr.ll
index 6073a337a234c..87185a8f4c668 100644
--- a/llvm/test/CodeGen/AMDGPU/waterfall-call-inreg-agpr.ll
+++ b/llvm/test/CodeGen/AMDGPU/waterfall-call-inreg-agpr.ll
@@ -60,6 +60,6 @@ define amdgpu_cs_chain_preserve void @caller() {
 ; CHECK-NEXT:  ; %bb.2:
 ; CHECK-NEXT:    s_endpgm
   %p = load ptr addrspace(3), ptr @G, align 4
-  call void @callee(ptr addrspace(3) %p, ptr addrspace(3) poison)
+  call void @callee(ptr addrspace(3) inreg %p, ptr addrspace(3) poison)
   ret void
 }

diff  --git a/llvm/test/CodeGen/ARM/returned-ext.ll b/llvm/test/CodeGen/ARM/returned-ext.ll
index b59974f6a3cfa..e3550650058e9 100644
--- a/llvm/test/CodeGen/ARM/returned-ext.ll
+++ b/llvm/test/CodeGen/ARM/returned-ext.ll
@@ -56,7 +56,7 @@ entry:
 ; This shouldn't be required
 ; CHECKT2D: mov r0, [[SAVEX]]
 
-  %call = tail call i16 @retzext16(i16 returned %x)
+  %call = tail call zeroext i16 @retzext16(i16 returned %x)
   %b = zext i16 %call to i32
   %call2 = tail call i32 @identity32(i32 returned %b)
   ret i16 %x
@@ -149,7 +149,7 @@ entry:
 ; FIXME: Tail call should be OK here
 ; CHECKT2D: bl _identity32
 
-  %call = tail call i16 @bothzext16(i16 zeroext returned %x)
+  %call = tail call zeroext i16 @bothzext16(i16 zeroext returned %x)
   %b = zext i16 %x to i32
   %call2 = tail call i32 @identity32(i32 returned %b)
   ret i16 %call

diff  --git a/llvm/test/CodeGen/ARM/struct-byval-loop.ll b/llvm/test/CodeGen/ARM/struct-byval-loop.ll
index 7a38dec2434f7..dd25df3901240 100644
--- a/llvm/test/CodeGen/ARM/struct-byval-loop.ll
+++ b/llvm/test/CodeGen/ARM/struct-byval-loop.ll
@@ -34,7 +34,7 @@ define void @test_80() {
 ; CHECK-NEXT:  .LCPI0_0:
 ; CHECK-NEXT:    .long 68 @ 0x44
   %a = alloca %type_80
-  call void @func_80(ptr null, ptr %a)
+  call void @func_80(ptr null, ptr byval(%type_80) %a)
   ret void
 }
 
@@ -77,6 +77,6 @@ define void @test_4000() {
 ; CHECK-NEXT:  .LCPI1_0:
 ; CHECK-NEXT:    .long 3988 @ 0xf94
   %a = alloca %type_4000
-  call void @func_4000(ptr null, ptr %a)
+  call void @func_4000(ptr null, ptr byval(%type_4000) %a)
   ret void
 }

diff  --git a/llvm/test/CodeGen/M68k/multiple-return.ll b/llvm/test/CodeGen/M68k/multiple-return.ll
index 8e97908324f05..3abc799def295 100644
--- a/llvm/test/CodeGen/M68k/multiple-return.ll
+++ b/llvm/test/CodeGen/M68k/multiple-return.ll
@@ -61,7 +61,7 @@ define void @call_test1() {
 ; CHECK-NEXT:    rts
 start:
   %ret_val = alloca { i32, i32, i32, i32 }
-  call void @test1(ptr %ret_val)
+  call void @test1(ptr sret({ i32, i32, i32, i32 }) %ret_val)
   ret void
 }
 

diff  --git a/llvm/test/CodeGen/NVPTX/forward-ld-param.ll b/llvm/test/CodeGen/NVPTX/forward-ld-param.ll
index 4f1454d3788a4..3de524de4745a 100644
--- a/llvm/test/CodeGen/NVPTX/forward-ld-param.ll
+++ b/llvm/test/CodeGen/NVPTX/forward-ld-param.ll
@@ -69,7 +69,7 @@ define void @test_ld_param_byval(ptr byval(i32) %a) {
 ; CHECK-NEXT:    call.uni byval_user, (param0);
 ; CHECK-NEXT:    } // callseq 1
 ; CHECK-NEXT:    ret;
-  call void @byval_user(ptr %a)
+  call void @byval_user(ptr byval(i32) %a)
   ret void
 }
 

diff  --git a/llvm/test/CodeGen/RISCV/rvv/shrinkwrap.ll b/llvm/test/CodeGen/RISCV/rvv/shrinkwrap.ll
index d12f2c889650f..da0cce53f3ab4 100644
--- a/llvm/test/CodeGen/RISCV/rvv/shrinkwrap.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/shrinkwrap.ll
@@ -71,7 +71,7 @@ define void @vecaddr_straightline(i32 zeroext %a, ptr %p) {
   %cmp0 = icmp eq i32 %a, 57
   br i1 %cmp0, label %exit, label %do_call
 do_call:
-  call i32 @foo()
+  call zeroext i32 @foo()
   br label %exit
 exit:
   %v3 = load <4 x i32>, ptr %gep
@@ -155,7 +155,7 @@ define void @vecaddr_loop(i32 zeroext %a, ptr %p) {
   %cmp0 = icmp eq i32 %a, 57
   br i1 %cmp0, label %exit, label %do_call
 do_call:
-  %b = call i32 @foo()
+  %b = call zeroext i32 @foo()
   %v3 = load <4 x i32>, ptr %gep
   %v4 = add <4 x i32> %v3, splat (i32 1)
   store <4 x i32> %v4, ptr %gep

diff  --git a/llvm/test/CodeGen/RISCV/shrinkwrap.ll b/llvm/test/CodeGen/RISCV/shrinkwrap.ll
index e06673d44ea75..a9c359b6a378c 100644
--- a/llvm/test/CodeGen/RISCV/shrinkwrap.ll
+++ b/llvm/test/CodeGen/RISCV/shrinkwrap.ll
@@ -275,11 +275,11 @@ define void @li_straightline_a(i32 zeroext %a, i32 zeroext %b) {
   %cmp0 = icmp eq i32 %a, 57
   br i1 %cmp0, label %exit, label %do_call
 do_call:
-  call i32 @foo()
+  call zeroext i32 @foo()
   %cmp1 = icmp eq i32 %b, 57
   br i1 %cmp1, label %exit, label %do_call2
 do_call2:
-  call i32 @foo()
+  call zeroext i32 @foo()
   br label %exit
 exit:
   ret void
@@ -392,13 +392,13 @@ define void @li_straightline_b(i32 zeroext %a, i32 zeroext %b) {
   %cmp0 = icmp eq i32 %a, 57
   br i1 %cmp0, label %exit, label %do_call
 do_call:
-  call i32 @foo()
+  call zeroext i32 @foo()
   br label %next
 next:
   %cmp1 = icmp eq i32 %b, 57
   br i1 %cmp1, label %exit, label %do_call2
 do_call2:
-  call i32 @foo()
+  call zeroext i32 @foo()
   br label %exit
 exit:
   ret void
@@ -494,13 +494,13 @@ define void @li_straightline_c(i32 zeroext %a) {
   %cmp0 = icmp eq i32 %a, 57
   br i1 %cmp0, label %exit, label %do_call
 do_call:
-  %b = call i32 @foo()
+  %b = call zeroext i32 @foo()
   br label %next
 next:
   %cmp1 = icmp eq i32 %b, 57
   br i1 %cmp1, label %exit, label %do_call2
 do_call2:
-  call i32 @foo()
+  call zeroext i32 @foo()
   br label %exit
 exit:
   ret void
@@ -619,7 +619,7 @@ define void @li_loop(i32 zeroext %a, i32 zeroext %b) {
   %cmp0 = icmp eq i32 %a, 57
   br i1 %cmp0, label %exit, label %do_call
 do_call:
-  call i32 @foo()
+  call zeroext i32 @foo()
   %cmp1 = icmp eq i32 %b, 57
   br i1 %cmp1, label %exit, label %do_call
 exit:

diff  --git a/llvm/test/CodeGen/SPARC/64abi.ll b/llvm/test/CodeGen/SPARC/64abi.ll
index dc8c9af4a5185..3152bf97e3202 100644
--- a/llvm/test/CodeGen/SPARC/64abi.ll
+++ b/llvm/test/CodeGen/SPARC/64abi.ll
@@ -342,8 +342,8 @@ define inreg { i32, float } @ret_i32_float_packed(i32 %a0, i32 %a1,
 ; HARD: st %f1, [%i1]
 ; SOFT: st %o0, [%i1]
 define void @call_ret_i32_float_packed(ptr %i0, ptr %i1) {
-  %rv = call { i32, float } @ret_i32_float_packed(i32 undef, i32 undef,
-                                                  ptr undef, ptr undef)
+  %rv = call inreg { i32, float } @ret_i32_float_packed(i32 undef, i32 undef,
+                                                        ptr undef, ptr undef)
   %e0 = extractvalue { i32, float } %rv, 0
   store i32 %e0, ptr %i0
   %e1 = extractvalue { i32, float } %rv, 1
@@ -374,8 +374,8 @@ define inreg { i32, i32 } @ret_i32_packed(i32 %a0, i32 %a1,
 ; CHECK: st [[R]], [%i0]
 ; CHECK: st %o0, [%i1]
 define void @call_ret_i32_packed(ptr %i0, ptr %i1) {
-  %rv = call { i32, i32 } @ret_i32_packed(i32 undef, i32 undef,
-                                          ptr undef, ptr undef)
+  %rv = call inreg { i32, i32 } @ret_i32_packed(i32 undef, i32 undef,
+                                                ptr undef, ptr undef)
   %e0 = extractvalue { i32, i32 } %rv, 0
   store i32 %e0, ptr %i0
   %e1 = extractvalue { i32, i32 } %rv, 1

diff  --git a/llvm/test/CodeGen/SystemZ/args-14.ll b/llvm/test/CodeGen/SystemZ/args-14.ll
index 84e7523e788de..f2d836bef9cac 100644
--- a/llvm/test/CodeGen/SystemZ/args-14.ll
+++ b/llvm/test/CodeGen/SystemZ/args-14.ll
@@ -1,11 +1,10 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -argext-abi-check
 
 ; Test that it works to pass structs as outgoing call arguments when the
-; NoExt attribute is given, either in the call instruction or in the
-; prototype of the called function.
+; NoExt attribute is given on the call instruction.
 define void @caller() {
   call void @bar_Struct_32(i32 noext 123)
-  call void @bar_Struct_16(i16 123)
+  call void @bar_Struct_16(i16 noext 123)
   call void @bar_Struct_8(i8 noext 123)
   ret void
 }

diff  --git a/llvm/test/CodeGen/SystemZ/call-zos-01.ll b/llvm/test/CodeGen/SystemZ/call-zos-01.ll
index a6006035dcaa1..f70a01e1a0466 100644
--- a/llvm/test/CodeGen/SystemZ/call-zos-01.ll
+++ b/llvm/test/CodeGen/SystemZ/call-zos-01.ll
@@ -17,7 +17,7 @@ define i8 @call_char(){
 ; CHECK-NEXT:    lg 7,2072(4)
 ; CHECK-NEXT:    aghi 4,192
 ; CHECK-NEXT:    b 2(7)
-  %retval = call i8 (i8) @pass_char(i8 8)
+  %retval = call signext i8 (i8) @pass_char(i8 signext 8)
   ret i8 %retval
 }
 
@@ -37,7 +37,7 @@ define i16 @call_short() {
 ; CHECK-NEXT:    aghi 4,192
 ; CHECK-NEXT:    b 2(7)
 entry:
-  %retval = call i16 (i16) @pass_short(i16 16)
+  %retval = call signext i16 (i16) @pass_short(i16 signext 16)
   ret i16 %retval
 }
 
@@ -58,7 +58,7 @@ define i32 @call_int() {
 ; CHECK-NEXT:    aghi 4,192
 ; CHECK-NEXT:    b 2(7)
 entry:
-  %retval = call i32 (i32, i32) @pass_int(i32 32, i32 33)
+  %retval = call signext i32 (i32, i32) @pass_int(i32 signext 32, i32 signext 33)
   ret i32 %retval
 }
 
@@ -123,7 +123,7 @@ define i64 @call_integrals() {
 ; CHECK-NEXT:    aghi 4,192
 ; CHECK-NEXT:    b 2(7)
 entry:
-  %retval = call i64 (i64, i32, i16, i64) @pass_integrals0(i64 64, i32 32, i16 16, i64 128)
+  %retval = call signext i64 (i64, i32, i16, i64) @pass_integrals0(i64 signext 64, i32 signext 32, i16 signext 16, i64 signext 128)
   ret i64 %retval
 }
 

diff  --git a/llvm/test/CodeGen/VE/Scalar/call.ll b/llvm/test/CodeGen/VE/Scalar/call.ll
index 9d949919dc80a..15491310fb229 100644
--- a/llvm/test/CodeGen/VE/Scalar/call.ll
+++ b/llvm/test/CodeGen/VE/Scalar/call.ll
@@ -64,7 +64,7 @@ define i32 @stack_call_int_szext() {
 ; CHECK-NEXT:    st %s34, 240(, %s11)
 ; CHECK-NEXT:    bsic %s10, (, %s12)
 ; CHECK-NEXT:    or %s11, 0, %s9
-  %r = tail call i32 @stack_callee_int_szext(i1 -1, i8 -1, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i16 -1, i8 -1)
+  %r = tail call i32 @stack_callee_int_szext(i1 signext -1, i8 zeroext -1, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i16 zeroext -1, i8 signext -1)
   ret i32 %r
 }
 

diff  --git a/llvm/test/CodeGen/VE/Scalar/va_callee.ll b/llvm/test/CodeGen/VE/Scalar/va_callee.ll
index 8ed707dac8a71..708d60fecbdbb 100644
--- a/llvm/test/CodeGen/VE/Scalar/va_callee.ll
+++ b/llvm/test/CodeGen/VE/Scalar/va_callee.ll
@@ -27,11 +27,11 @@ define i32 @va_func(i32, ...) {
   %p10 = va_arg ptr %va, double
   call void @llvm.va_end(ptr nonnull %va)
   call void @use_i32(i32 %p1)
-  call void @use_s16(i16 %p2)
-  call void @use_s8(i8 %p3)
+  call void @use_s16(i16 signext %p2)
+  call void @use_s8(i8 signext %p3)
   call void @use_i32(i32 %p4)
-  call void @use_u16(i16 %p5)
-  call void @use_u8(i8 %p6)
+  call void @use_u16(i16 zeroext %p5)
+  call void @use_u8(i8 zeroext %p6)
   call void @use_float(float %p7)
   call void @use_i8p(ptr %p8)
   call void @use_i64(i64 %p9)
@@ -73,11 +73,11 @@ define i32 @va_copy0(i32, ...) {
   call void @llvm.va_end(ptr nonnull %vb)
   call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %vb)
   call void @use_i32(i32 %p1)
-  call void @use_s16(i16 %p2)
-  call void @use_s8(i8 %p3)
+  call void @use_s16(i16 signext %p2)
+  call void @use_s8(i8 signext %p3)
   call void @use_i32(i32 %p4)
-  call void @use_u16(i16 %p5)
-  call void @use_u8(i8 %p6)
+  call void @use_u16(i16 zeroext %p5)
+  call void @use_u8(i8 zeroext %p6)
   call void @use_float(float %p7)
   call void @use_i8p(ptr %p8)
   call void @use_i64(i64 %p9)
@@ -117,11 +117,11 @@ define i32 @va_copy8(i32, ...) {
   %p10 = va_arg ptr %vc, double
   call void @llvm.va_end(ptr nonnull %vc)
   call void @use_i32(i32 %p1)
-  call void @use_s16(i16 %p2)
-  call void @use_s8(i8 %p3)
+  call void @use_s16(i16 signext %p2)
+  call void @use_s8(i8 signext %p3)
   call void @use_i32(i32 %p4)
-  call void @use_u16(i16 %p5)
-  call void @use_u8(i8 %p6)
+  call void @use_u16(i16 zeroext %p5)
+  call void @use_u8(i8 zeroext %p6)
   call void @use_float(float %p7)
   call void @use_i8p(ptr %p8)
   call void @use_i64(i64 %p9)

diff  --git a/llvm/test/CodeGen/VE/Vector/fastcc_caller.ll b/llvm/test/CodeGen/VE/Vector/fastcc_caller.ll
index 72e95091f8534..35cbba2b8e13a 100644
--- a/llvm/test/CodeGen/VE/Vector/fastcc_caller.ll
+++ b/llvm/test/CodeGen/VE/Vector/fastcc_caller.ll
@@ -67,7 +67,7 @@ define fastcc i32 @stack_call_int_szext() {
 ; CHECK-NEXT:    st %s34, 240(, %s11)
 ; CHECK-NEXT:    bsic %s10, (, %s12)
 ; CHECK-NEXT:    or %s11, 0, %s9
-  %r = tail call fastcc i32 @stack_callee_int_szext(i1 -1, i8 -1, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i16 -1, i8 -1)
+  %r = tail call fastcc i32 @stack_callee_int_szext(i1 signext -1, i8 zeroext -1, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i16 zeroext -1, i8 signext -1)
   ret i32 %r
 }
 

diff  --git a/llvm/test/CodeGen/WebAssembly/signext-zeroext-callsite.ll b/llvm/test/CodeGen/WebAssembly/signext-zeroext-callsite.ll
index f7f0b68c1b665..1d7adfb712b68 100644
--- a/llvm/test/CodeGen/WebAssembly/signext-zeroext-callsite.ll
+++ b/llvm/test/CodeGen/WebAssembly/signext-zeroext-callsite.ll
@@ -7,25 +7,15 @@ target triple = "wasm32-unknown-unknown"
 
 declare i32 @foo(i1 signext noundef, i32 noundef)
 
-; callsite_signext and callsite_nosignext must emit equivalent codes
+; callsite_signext and callsite_nosignext should emit 
diff erent code,
+; as the signext is not inherited from the callee.
 
 define i32 @callsite_nosignext() {
 ; CHECK-LABEL: callsite_nosignext:
 ; CHECK:         .functype callsite_nosignext () -> (i32)
-; CHECK-NEXT:    .local i32, i32, i32
 ; CHECK-NEXT:  # %bb.0: # %start
 ; CHECK-NEXT:    i32.const 1
-; CHECK-NEXT:    local.set 0
 ; CHECK-NEXT:    i32.const 0
-; CHECK-NEXT:    local.set 1
-; CHECK-NEXT:    i32.const 31
-; CHECK-NEXT:    local.set 2
-; CHECK-NEXT:    local.get 0
-; CHECK-NEXT:    local.get 2
-; CHECK-NEXT:    i32.shl
-; CHECK-NEXT:    local.get 2
-; CHECK-NEXT:    i32.shr_s
-; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    call foo
 ; CHECK-NEXT:    return
 ;
@@ -35,7 +25,7 @@ define i32 @callsite_nosignext() {
 ; NO-FAST-ISEL-NEXT:  # %bb.0: # %start
 ; NO-FAST-ISEL-NEXT:    i32.const 0
 ; NO-FAST-ISEL-NEXT:    local.set 0
-; NO-FAST-ISEL-NEXT:    i32.const -1
+; NO-FAST-ISEL-NEXT:    i32.const 1
 ; NO-FAST-ISEL-NEXT:    local.get 0
 ; NO-FAST-ISEL-NEXT:    call foo
 ; NO-FAST-ISEL-NEXT:    return
@@ -81,21 +71,15 @@ start:
 
 declare i32 @foo2(i1 zeroext noundef, i32 noundef)
 
-; callsite_zeroext and callsite_nozeroext must emit equivalent codes
+; callsite_zeroext and callsite_nozeroext should emit 
diff erent code,
+; as the zeroext is not inherited from the callee.
 
 define i32 @callsite_nozeroext() {
 ; CHECK-LABEL: callsite_nozeroext:
 ; CHECK:         .functype callsite_nozeroext () -> (i32)
-; CHECK-NEXT:    .local i32, i32
 ; CHECK-NEXT:  # %bb.0: # %start
 ; CHECK-NEXT:    i32.const 1
-; CHECK-NEXT:    local.set 0
 ; CHECK-NEXT:    i32.const 0
-; CHECK-NEXT:    local.set 1
-; CHECK-NEXT:    local.get 0
-; CHECK-NEXT:    i32.const 1
-; CHECK-NEXT:    i32.and
-; CHECK-NEXT:    local.get 1
 ; CHECK-NEXT:    call foo2
 ; CHECK-NEXT:    return
 ;

diff  --git a/llvm/test/CodeGen/X86/bool-zext.ll b/llvm/test/CodeGen/X86/bool-zext.ll
index 539be245eb1d0..2df0a63f151e0 100644
--- a/llvm/test/CodeGen/X86/bool-zext.ll
+++ b/llvm/test/CodeGen/X86/bool-zext.ll
@@ -53,7 +53,7 @@ define zeroext i1 @bar3() nounwind ssp {
 ; X64-NEXT:    callq foo2 at PLT
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
-  %call = call i1 @foo2() nounwind
+  %call = call zeroext i1 @foo2() nounwind
   ret i1 %call
 }
 

diff  --git a/llvm/test/CodeGen/X86/return-ext.ll b/llvm/test/CodeGen/X86/return-ext.ll
index d38284df1f530..69bc67489cb1c 100644
--- a/llvm/test/CodeGen/X86/return-ext.ll
+++ b/llvm/test/CodeGen/X86/return-ext.ll
@@ -97,7 +97,7 @@ entry:
 
 define i32 @use_i1() {
 entry:
-  %0 = call i1 @unsigned_i1();
+  %0 = call zeroext i1 @unsigned_i1();
   %1 = zext i1 %0 to i32
   ret i32 %1
 
@@ -112,7 +112,7 @@ entry:
 
 define i32 @use_i8() {
 entry:
-  %0 = call i8 @unsigned_i8();
+  %0 = call zeroext i8 @unsigned_i8();
   %1 = zext i8 %0 to i32
   ret i32 %1
 
@@ -127,7 +127,7 @@ entry:
 
 define i32 @use_i16() {
 entry:
-  %0 = call i16 @unsigned_i16();
+  %0 = call zeroext i16 @unsigned_i16();
   %1 = zext i16 %0 to i32
   ret i32 %1
 

diff  --git a/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll b/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll
index 5a15cfa6864c4..14020d0a76d97 100644
--- a/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll
+++ b/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll
@@ -94,7 +94,7 @@ define void @SwiftError(ptr swifterror) sanitize_thread {
 define void @SwiftErrorCall(ptr swifterror) sanitize_thread {
   %swifterror_addr = alloca swifterror ptr
   store ptr null, ptr %0
-  call void @SwiftError(ptr %0)
+  call void @SwiftError(ptr swifterror %0)
   ret void
 }
 

diff  --git a/llvm/test/Transforms/DeadArgElim/deadexternal.ll b/llvm/test/Transforms/DeadArgElim/deadexternal.ll
index 5120d1a5f98ee..6839e4ecf5736 100644
--- a/llvm/test/Transforms/DeadArgElim/deadexternal.ll
+++ b/llvm/test/Transforms/DeadArgElim/deadexternal.ll
@@ -62,6 +62,6 @@ define void @unused_swifterror_arg(ptr swifterror %dead_arg) {
 define void @dont_replace_by_poison() {
   %error_ptr_ref = alloca swifterror ptr
   store ptr null, ptr %error_ptr_ref
-  call void @unused_swifterror_arg(ptr %error_ptr_ref)
+  call void @unused_swifterror_arg(ptr swifterror %error_ptr_ref)
   ret void
 }

diff  --git a/llvm/test/Transforms/Inline/access-attributes-prop.ll b/llvm/test/Transforms/Inline/access-attributes-prop.ll
index a5c52ecdfd8c2..efa3cb7d26413 100644
--- a/llvm/test/Transforms/Inline/access-attributes-prop.ll
+++ b/llvm/test/Transforms/Inline/access-attributes-prop.ll
@@ -591,17 +591,17 @@ define ptr @callee_bad_param_prop(ptr readonly %x) {
 define dso_local void @foo_byval_readonly2(ptr readonly %p) {
 ; CHECK-LABEL: define {{[^@]+}}@foo_byval_readonly2
 ; CHECK-SAME: (ptr readonly [[P:%.*]]) {
-; CHECK-NEXT:    call void @bar4(ptr [[P]])
+; CHECK-NEXT:    call void @bar4(ptr byval([4 x i32]) [[P]])
 ; CHECK-NEXT:    ret void
 ;
-  call void @bar4(ptr %p)
+  call void @bar4(ptr byval([4 x i32]) %p)
   ret void
 }
 
 define void @prop_byval_readonly2(ptr %p) {
 ; CHECK-LABEL: define {{[^@]+}}@prop_byval_readonly2
 ; CHECK-SAME: (ptr [[P:%.*]]) {
-; CHECK-NEXT:    call void @bar4(ptr [[P]])
+; CHECK-NEXT:    call void @bar4(ptr byval([4 x i32]) [[P]])
 ; CHECK-NEXT:    ret void
 ;
   call void @foo_byval_readonly2(ptr %p)

diff  --git a/llvm/test/Transforms/PhaseOrdering/pr64289-tce.ll b/llvm/test/Transforms/PhaseOrdering/pr64289-tce.ll
index f56463a0b6107..d420511952539 100644
--- a/llvm/test/Transforms/PhaseOrdering/pr64289-tce.ll
+++ b/llvm/test/Transforms/PhaseOrdering/pr64289-tce.ll
@@ -19,7 +19,7 @@ start:
 
 recurse:
   store i64 0, ptr %new_x, align 8
-  call void @pr64289(ptr %new_x)
+  call void @pr64289(ptr byval(i64) %new_x)
   br label %end
 
 end:

diff  --git a/llvm/test/Transforms/SROA/readonlynocapture.ll b/llvm/test/Transforms/SROA/readonlynocapture.ll
index b6f7b1fd1685e..488efc9930677 100644
--- a/llvm/test/Transforms/SROA/readonlynocapture.ll
+++ b/llvm/test/Transforms/SROA/readonlynocapture.ll
@@ -396,12 +396,12 @@ define i32 @simple_byval() {
 ; CHECK-LABEL: @simple_byval(
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    store i32 0, ptr [[A]], align 4
-; CHECK-NEXT:    call void @callee_byval(ptr [[A]])
+; CHECK-NEXT:    call void @callee_byval(ptr byval(i32) [[A]])
 ; CHECK-NEXT:    ret i32 0
 ;
   %a = alloca i32
   store i32 0, ptr %a
-  call void @callee_byval(ptr %a)
+  call void @callee_byval(ptr byval(i32) %a)
   %l1 = load i32, ptr %a
   ret i32 %l1
 }

diff  --git a/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll b/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
index 382d881caf5c0..aaf1063d3ad86 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll
@@ -227,11 +227,11 @@ define swiftcc void @sink_call(i1 %c) {
 ; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
 ; CHECK:       then:
 ; CHECK-NEXT:    call void @clobber1()
-; CHECK-NEXT:    call swiftcc void @foo(ptr [[TMP2]])
+; CHECK-NEXT:    call swiftcc void @foo(ptr swifterror [[TMP2]])
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       else:
 ; CHECK-NEXT:    call void @clobber2()
-; CHECK-NEXT:    call swiftcc void @foo(ptr [[TMP1]])
+; CHECK-NEXT:    call swiftcc void @foo(ptr swifterror [[TMP1]])
 ; CHECK-NEXT:    br label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
@@ -242,12 +242,12 @@ define swiftcc void @sink_call(i1 %c) {
 
 then:
   call void @clobber1()
-  call swiftcc void @foo(ptr %3)
+  call swiftcc void @foo(ptr swifterror %3)
   br label %exit
 
 else:
   call void @clobber2()
-  call swiftcc void @foo(ptr %2)
+  call swiftcc void @foo(ptr swifterror %2)
   br label %exit
 
 exit:
@@ -270,7 +270,7 @@ define swiftcc void @safe_sink_call(i1 %c) {
 ; CHECK-NEXT:    br label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    [[B_SINK:%.*]] = phi ptr [ [[B]], [[ELSE]] ], [ [[A]], [[THEN]] ]
-; CHECK-NEXT:    call swiftcc void @bar(ptr [[ERR]], ptr [[B_SINK]])
+; CHECK-NEXT:    call swiftcc void @bar(ptr swifterror [[ERR]], ptr [[B_SINK]])
 ; CHECK-NEXT:    ret void
 ;
   %err = alloca swifterror ptr, align 8
@@ -280,12 +280,12 @@ define swiftcc void @safe_sink_call(i1 %c) {
 
 then:
   call void @clobber1()
-  call swiftcc void @bar(ptr %err, ptr %a)
+  call swiftcc void @bar(ptr swifterror %err, ptr %a)
   br label %exit
 
 else:
   call void @clobber2()
-  call swiftcc void @bar(ptr %err, ptr %b)
+  call swiftcc void @bar(ptr swifterror %err, ptr %b)
   br label %exit
 
 exit:

diff  --git a/llvm/unittests/IR/AttributesTest.cpp b/llvm/unittests/IR/AttributesTest.cpp
index 5e795ef771713..1c6fc053f9779 100644
--- a/llvm/unittests/IR/AttributesTest.cpp
+++ b/llvm/unittests/IR/AttributesTest.cpp
@@ -287,17 +287,17 @@ TEST(Attributes, MismatchedABIAttrs) {
 
   {
     auto *I = cast<CallBase>(&M->getFunction("g")->getEntryBlock().front());
-    ASSERT_TRUE(I->isByValArgument(0));
-    ASSERT_TRUE(I->getParamByValType(0));
+    ASSERT_FALSE(I->isByValArgument(0));
+    ASSERT_FALSE(I->getParamByValType(0));
   }
   {
     auto *I = cast<CallBase>(&M->getFunction("h")->getEntryBlock().front());
-    ASSERT_TRUE(I->getParamPreallocatedType(0));
+    ASSERT_FALSE(I->getParamPreallocatedType(0));
   }
   {
     auto *I = cast<CallBase>(&M->getFunction("i")->getEntryBlock().front());
-    ASSERT_TRUE(I->isInAllocaArgument(0));
-    ASSERT_TRUE(I->getParamInAllocaType(0));
+    ASSERT_FALSE(I->isInAllocaArgument(0));
+    ASSERT_FALSE(I->getParamInAllocaType(0));
   }
 }
 


        


More information about the llvm-commits mailing list