1818#include " llvm/ADT/DenseSet.h"
1919#include " llvm/ADT/MapVector.h"
2020#include " llvm/ADT/STLExtras.h"
21+ #include " llvm/ADT/Sequence.h"
2122#include " llvm/ADT/SetVector.h"
2223#include " llvm/ADT/SmallSet.h"
2324#include " llvm/ADT/SmallVector.h"
@@ -1422,14 +1423,15 @@ static constexpr Attribute::AttrKind FnAttrsToStrip[] =
14221423 {Attribute::Memory, Attribute::NoSync, Attribute::NoFree};
14231424
14241425// Create new attribute set containing only attributes which can be transferred
1425- // from original call to the safepoint.
1426- static AttributeList legalizeCallAttributes (LLVMContext &Ctx,
1427- AttributeList OrigAL,
1426+ // from the original call to the safepoint.
1427+ static AttributeList legalizeCallAttributes (CallBase *Call, bool IsMemIntrinsic,
14281428 AttributeList StatepointAL) {
1429+ AttributeList OrigAL = Call->getAttributes ();
14291430 if (OrigAL.isEmpty ())
14301431 return StatepointAL;
14311432
14321433 // Remove the readonly, readnone, and statepoint function attributes.
1434+ LLVMContext &Ctx = Call->getContext ();
14331435 AttrBuilder FnAttrs (Ctx, OrigAL.getFnAttrs ());
14341436 for (auto Attr : FnAttrsToStrip)
14351437 FnAttrs.removeAttribute (Attr);
@@ -1439,8 +1441,24 @@ static AttributeList legalizeCallAttributes(LLVMContext &Ctx,
14391441 FnAttrs.removeAttribute (A);
14401442 }
14411443
1442- // Just skip parameter and return attributes for now
1443- return StatepointAL.addFnAttributes (Ctx, FnAttrs);
1444+ StatepointAL = StatepointAL.addFnAttributes (Ctx, FnAttrs);
1445+
1446+ // The memory intrinsics do not have a 1:1 correspondence of the original
1447+ // call arguments to the produced statepoint. Do not transfer the argument
1448+ // attributes to avoid putting them on incorrect arguments.
1449+ if (IsMemIntrinsic)
1450+ return StatepointAL;
1451+
1452+ // Attach the argument attributes from the original call at the corresponding
1453+ // arguments in the statepoint. Note that any argument attributes that are
1454+ // invalid after lowering are stripped in stripNonValidDataFromBody.
1455+ for (unsigned I : llvm::seq (Call->arg_size ()))
1456+ StatepointAL = StatepointAL.addParamAttributes (
1457+ Ctx, GCStatepointInst::CallArgsBeginPos + I,
1458+ AttrBuilder (Ctx, OrigAL.getParamAttrs (I)));
1459+
1460+ // Return attributes are later attached to the gc.result intrinsic.
1461+ return StatepointAL;
14441462}
14451463
14461464// / Helper function to place all gc relocates necessary for the given
@@ -1630,6 +1648,7 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
16301648 // with a return value, we lower then as never returning calls to
16311649 // __llvm_deoptimize that are followed by unreachable to get better codegen.
16321650 bool IsDeoptimize = false ;
1651+ bool IsMemIntrinsic = false ;
16331652
16341653 StatepointDirectives SD =
16351654 parseStatepointDirectivesFromAttrs (Call->getAttributes ());
@@ -1670,6 +1689,8 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
16701689 IsDeoptimize = true ;
16711690 } else if (IID == Intrinsic::memcpy_element_unordered_atomic ||
16721691 IID == Intrinsic::memmove_element_unordered_atomic) {
1692+ IsMemIntrinsic = true ;
1693+
16731694 // Unordered atomic memcpy and memmove intrinsics which are not explicitly
16741695 // marked as "gc-leaf-function" should be lowered in a GC parseable way.
16751696 // Specifically, these calls should be lowered to the
@@ -1785,12 +1806,10 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
17851806 SPCall->setTailCallKind (CI->getTailCallKind ());
17861807 SPCall->setCallingConv (CI->getCallingConv ());
17871808
1788- // Currently we will fail on parameter attributes and on certain
1789- // function attributes. In case if we can handle this set of attributes -
1790- // set up function attrs directly on statepoint and return attrs later for
1809+ // Set up function attrs directly on statepoint and return attrs later for
17911810 // gc_result intrinsic.
1792- SPCall->setAttributes (legalizeCallAttributes (
1793- CI-> getContext (), CI-> getAttributes () , SPCall->getAttributes ()));
1811+ SPCall->setAttributes (
1812+ legalizeCallAttributes (CI, IsMemIntrinsic , SPCall->getAttributes ()));
17941813
17951814 Token = cast<GCStatepointInst>(SPCall);
17961815
@@ -1812,12 +1831,10 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
18121831
18131832 SPInvoke->setCallingConv (II->getCallingConv ());
18141833
1815- // Currently we will fail on parameter attributes and on certain
1816- // function attributes. In case if we can handle this set of attributes -
1817- // set up function attrs directly on statepoint and return attrs later for
1834+ // Set up function attrs directly on statepoint and return attrs later for
18181835 // gc_result intrinsic.
1819- SPInvoke->setAttributes (legalizeCallAttributes (
1820- II-> getContext (), II-> getAttributes () , SPInvoke->getAttributes ()));
1836+ SPInvoke->setAttributes (
1837+ legalizeCallAttributes (II, IsMemIntrinsic , SPInvoke->getAttributes ()));
18211838
18221839 Token = cast<GCStatepointInst>(SPInvoke);
18231840
0 commit comments