[PATCH] D150967: [MemCpyOpt] precommit test for memcpy removal for immutable arguments from attributes (NFC)

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 11:44:24 PDT 2023


nikic added a comment.

To write down what I said on the last call: For this transform, we need to be careful because we don't know what kind of accesses the called function will perform. The function may have an unknown assumption on the alignment and may access an unknown number of bytes. As such, we can only perform the transform if we know the alignment/size of the object that is passed to the function.

If we have something like this

  define void @test(i1 %c, ptr noalias %val) {
    %val1 = alloca [4 x i8], align 4
    %val2 = alloca [16 x i8], align 16
    %val3 = select i1 %c, ptr %val1, ptr %val2
    call void @llvm.memcpy.p0.p0.i64(ptr align 4 %val3, ptr align 4 %val, i64 4, i1 false)
    call void @f(ptr nocapture noalias readonly %val3)
    ret void
  }

then it might be that `%c` is always known false, so `@f` assumes it gets the `%val2 = alloca [16 x i8], align 16` pointer. As such, it might assume that the pointer is aligned to 16 bytes and is 16 bytes large. As such, we need to be sure that `%val` satisfies this as well if we do the replacement.

I think in practice, this means we should only do the replacement if a) the pointer passed to the function is an `alloca` (which ensures we know alignment & size) b) the memcpy copies the full size of the alloca (which ensures that the new pointer is dereferencable for the required range) and c) the new pointer has alignment >= the alloca alignment.


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

https://reviews.llvm.org/D150967



More information about the llvm-commits mailing list