@@ -1525,11 +1525,21 @@ bool MemCpyOptPass::processMemMove(MemMoveInst *M) {
1525
1525
// / This is called on every byval argument in call sites.
1526
1526
bool MemCpyOptPass::processByValArgument (CallBase &CB, unsigned ArgNo) {
1527
1527
const DataLayout &DL = CB.getCaller ()->getParent ()->getDataLayout ();
1528
- // Find out what feeds this byval argument.
1528
+
1529
1529
Value *ByValArg = CB.getArgOperand (ArgNo);
1530
- Type *ByValTy = CB.getParamByValType (ArgNo);
1530
+ Type *ByValTy;
1531
+ if (CB.isByValArgument (ArgNo)) {
1532
+ ByValTy = CB.getParamByValType (ArgNo);
1533
+ } else {
1534
+ if (AllocaInst *Alloca = dyn_cast<AllocaInst>(ByValArg->stripPointerCasts ()))
1535
+ ByValTy = Alloca->getAllocatedType ();
1536
+ else
1537
+ return false ;
1538
+ }
1531
1539
TypeSize ByValSize = DL.getTypeAllocSize (ByValTy);
1532
- MemoryLocation Loc (ByValArg, LocationSize::precise (ByValSize));
1540
+ MemoryLocation Loc = MemoryLocation (ByValArg, LocationSize::precise (ByValSize));
1541
+
1542
+ // Find out what feeds this byval argument.
1533
1543
MemoryUseOrDef *CallAccess = MSSA->getMemoryAccess (&CB);
1534
1544
if (!CallAccess)
1535
1545
return false ;
@@ -1627,9 +1637,14 @@ bool MemCpyOptPass::iterateOnFunction(Function &F) {
1627
1637
else if (auto *M = dyn_cast<MemMoveInst>(I))
1628
1638
RepeatInstruction = processMemMove (M);
1629
1639
else if (auto *CB = dyn_cast<CallBase>(I)) {
1630
- for (unsigned i = 0 , e = CB->arg_size (); i != e; ++i)
1631
- if (CB->isByValArgument (i))
1640
+ for (unsigned i = 0 , e = CB->arg_size (); i != e; ++i) {
1641
+ if (CB->isByValArgument (i) ||
1642
+ (CB->paramHasAttr (i, Attribute::ReadOnly) &&
1643
+ CB->paramHasAttr (i, Attribute::NoCapture) &&
1644
+ CB->paramHasAttr (i, Attribute::NoAlias))) {
1632
1645
MadeChange |= processByValArgument (*CB, i);
1646
+ }
1647
+ }
1633
1648
}
1634
1649
1635
1650
// Reprocess the instruction if desired.
0 commit comments