[PATCH] D150970: [MemCpyOpt] Use memcpy source directly if dest is known to be immutable from attributes

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 6 12:55:55 PDT 2023


nikic requested changes to this revision.
nikic added a comment.
This revision now requires changes to proceed.

It looks like the alignment checks are inverted.



================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1624
+///     pointer is dereferenceable for the required range
+///     2-2. The src pointer has alignment <= the alloca alignment or can be
+///     enforced so.
----------------
`<=` should be `>=` here?


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1639
+  // 2. Check that arg is alloca
+  // TODO: Even if the arg get back to branches, we can remove memcpy if the all
+  // alloca alignments can be enforced to source alignment.
----------------
"Even if the arg can be based on multiple allocas" or so.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1647
+  // Can't handle unknown size alloca (e.g. VLA)
+  if (!AllocaSize)
+    return false;
----------------
`&& !AllocaSize->isScalable()` (and a test for this)


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1662
+  // If the immut argument isn't fed by a memcpy, ignore it.  If it is fed by
+  // a memcpy, check that the arg equals to memcpy dest.
+  if (!MDep || MDep->isVolatile() || AI != MDep->getDest())
----------------
"equals to" -> "equals the" or "is equal to the"


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1673
+  auto *MDepLen = dyn_cast<ConstantInt>(MDep->getLength());
+  if (!MDepLen || AllocaSize != MDepLen->getValue().getZExtValue())
+    return false;
----------------
Does that work? getZextValue() may assert for wide integers (though probably not really relevant here).


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1676
+
+  // 2-2. the memcpy source align must be smaller than the alloca's align.
+  // If not so, we check to see if we can force the source of the memcpy to the
----------------
smaller -> larger than or equal


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1679
+  // alignment we need. If we fail, we bail out.
+  MaybeAlign MemDepAlign = MDep->getSourceAlign();
+  Align AllocaAlign = AI->getAlign();
----------------
Then you don't need to check `!MemDepAlign`


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1681-1683
+  if ((!MemDepAlign || AllocaAlign < *MemDepAlign) &&
+      AllocaAlign < getOrEnforceKnownAlignment(MDep->getSource(), MemDepAlign,
+                                               DL, &CB, AC, DT))
----------------



================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1704
+
+  // Otherwise we're good!  Update the byval argument.
+  CB.setArgOperand(ArgNo, MDep->getSource());
----------------
stray byval


================
Comment at: llvm/test/Transforms/MemCpyOpt/memcpy.ll:444
 
 ; Can't remove memcpy for VLA because of unknown size and alignment.
 define void @immut_param_vla(ptr align 4 noalias %val) {
----------------
This is not a VLA. You need to do something like `alloca i8, i64 %n`.


================
Comment at: llvm/test/Transforms/MemCpyOpt/memcpy.ll:474
 
 ; Can't remove memcpy if we remove, the alignment assumption would break
 define void @immut_param_bigger_align(ptr align 16 noalias %val) {
----------------
This case is fine, the problematic case is if the `%val` alignment is smaller.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150970/new/

https://reviews.llvm.org/D150970



More information about the llvm-commits mailing list