@@ -852,9 +852,11 @@ determinePointerAccessAttrs(Argument *A,
852852 continue ;
853853 }
854854
855- // Given we've explictily handled the callee operand above, what's left
855+ // Given we've explicitly handled the callee operand above, what's left
856856 // must be a data operand (e.g. argument or operand bundle)
857857 const unsigned UseIndex = CB.getDataOperandNo (U);
858+ const bool IsByVal =
859+ CB.isArgOperand (U) && CB.isByValArgument (CB.getArgOperandNo (U));
858860
859861 // Some intrinsics (for instance ptrmask) do not capture their results,
860862 // but return results thas alias their pointer argument, and thus should
@@ -864,7 +866,7 @@ determinePointerAccessAttrs(Argument *A,
864866 for (Use &UU : CB.uses ())
865867 if (Visited.insert (&UU).second )
866868 Worklist.push_back (&UU);
867- } else if (!CB.doesNotCapture (UseIndex)) {
869+ } else if (!( CB.doesNotCapture (UseIndex) || IsByVal )) {
868870 if (!CB.onlyReadsMemory ())
869871 // If the callee can save a copy into other memory, then simply
870872 // scanning uses of the call is insufficient. We have no way
@@ -894,7 +896,7 @@ determinePointerAccessAttrs(Argument *A,
894896 // invokes with operand bundles.
895897 if (CB.doesNotAccessMemory (UseIndex)) {
896898 /* nop */
897- } else if (!isModSet (ArgMR) || CB.onlyReadsMemory (UseIndex)) {
899+ } else if (!isModSet (ArgMR) || CB.onlyReadsMemory (UseIndex) || IsByVal ) {
898900 IsRead = true ;
899901 } else if (!isRefSet (ArgMR) ||
900902 CB.dataOperandHasImpliedAttr (UseIndex, Attribute::WriteOnly)) {
0 commit comments