[PATCH] D60719: Demonstrate how to fix freestanding for memcpy

Guillaume Chatelet via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 18 01:46:41 PDT 2019


gchatelet added a comment.

In D60719#1470632 <https://reviews.llvm.org/D60719#1470632>, @t.p.northover wrote:

> > IIUC freestanding environment should not rely on memcpy being present so my take on it was that by "fixing" freestanding I could have my cake and eat it too.
>
> The formal situation is that freestanding implementations are only required to provide language support stuff like `va_list`. They're allowed to give more of the standard library if they want though, as implementation defined behaviour.
>
> In practice, everyone I know provides the basic `string.h` functions and the compiler is pretty explicit about relying on them being present for correctness. They're part of the surrounding environment a user is expected to supply (much like the various exception handling callbacks if you want C++ exceptions, but always required).
>
> For the people actually using freestanding I think they're mostly considered important enough that they're implemented in assembly anyway so this isn't really a burden, but...


Ack. "Fixing" freestanding is not the way to go then : )

>> Ultimately I'm interested in implementing libc's mem function in C++. Let's take memcpy for instance
> 
> Ah, that is an entirely different problem from what I thought you were trying to do. In that case I'm all in favour of some solution, but would start thinking along the lines of `-fno-builtin-memcpy` options (it's possible that already does what you want, but can't get LLVM to form a `memcpy` from quick tests to check).

Thx for taking the time to suggest possible solution, I really appreciate it.

I already tried `-fno-builtin-memcpy`. The semantic of this flag is pretty counter intuitive and I'll explain why it doesn't fit my needs.
LLVM is allowed to replace a piece of code that looks like a `memcpy` with an IR intrinsic that implements the same semantic. You can see this by inspecting the IR here: https://godbolt.org/z/0y1Yqh.
Now if you use `-fno-builtin-memcpy` you're preventing the compiler from understanding that this is a memory copy. Look at the IR here: https://godbolt.org/z/lnCIIh.
The vectorizer kicks in in this case and the generated code is quite good but sometimes the generated code is pretty bad: https://godbolt.org/z/mHpAYe.

Last but not least `-fno-builtin-memcpy`prevents the compiler from understanding code constructs as memcpy but does not prevent the compiler from generating calls to `memcpy`:

- Using `__builtin_memcpy` still lowers to `@llvm.memcpy` IR intrinsics: https://godbolt.org/z/O0sjIl
- Passing big structs by value will lowers to `@llvm.memcpy` IR intrinsics: https://godbolt.org/z/4BUDc0

Another solution is needed for my use case, either a new C++ intrinsics `__builtin_inline_memcpy` or an attribute that disables generated libc calls, compiler could either inline or fail with an error.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D60719





More information about the cfe-commits mailing list