jfb added a comment. In D79279#2168649 <https://reviews.llvm.org/D79279#2168649>, @rjmccall wrote:
> In D79279#2168533 <https://reviews.llvm.org/D79279#2168533>, @jfb wrote: > > > In D79279#2168479 <https://reviews.llvm.org/D79279#2168479>, @rjmccall > > wrote: > > > > > Is there a need for an atomic memcpy at all? Why is it useful to allow > > > this operation to take on "atomic" semantics — which aren't actually > > > atomic because the loads and stores to elements are torn — with hardcoded > > > memory ordering and somewhat arbitrary rules about what the atomic size > > > is? > > > > > > Hans lays out a rationale for usefulness in his paper, but what I've > > implemented is more useful: it's *unordered* so you can fence as you desire > > around it, yet it guarantees a minimum memory access size based on the > > pointer parameters. For example, copying an atomic `int` will be 4 byte > > operations which are single-copy-atomic, but the accesses from one `int` to > > the next aren't performed in any guaranteed order (or observable in any > > guaranteed order either). I talked about this with him a while ago but IIRC > > he wasn't sure about implementation among other things, so when you asked > > me to widen my original `volatile`-only `memcpy` to also do other > > qualifiers, I realized that it was a neat way to do atomic as well as other > > qualifiers. I've talked to a few SG1 folks about this, and I believe (for > > other reasons too) it's where the design will end up for Hans' paper. > > > I can see the usefulness of this operation, but it seems like a odd semantic > mismatch for what is basically just a memcpy where one of the pointers > happens to have `_Atomic` type, like you're shoe-horning it into this builtin > just to avoid declaring a different one. I'm following the discussion we had here regarding overloading <http://lists.llvm.org/pipermail/cfe-dev/2020-May/065388.html>: >> There are other qualifiers that can meaningfully contribute to the operation >> here besides volatile, such as restrict and (more importantly) address >> spaces. And again, for the copy operations these might differ between the >> two pointer types. >> >> In both cases, I’d say that the logical design is to allow the pointers to >> be to arbitrarily-qualified types. We can then propagate that information >> from the builtin into the LLVM intrinsic call as best as we’re allowed. So I >> think you should make builtins called something like >> __builtin_overloaded_memcpy (name to be decided) and just have their >> semantics be type-directed. > > Ah yes, I’d like to hear what others think of this. I hadn’t thought about it > before you brought it up, and it sounds like a good idea. As you noted earlier, for `memcpy` you probably want to express differences in destination and source qualification, even if today IR can't express e.g. `volatile` source and non-`volatile` destination. You were talking about `volatile`, but this applies to the entire combination of dst+src qualified with zero-to-five `volatile`, `_Atomic`, `__unaligned`, `restrict`, and address space. Pulling the entire combination space out into different functions would create way too many functions. Right now the implementation has a few limitations: it treats both dst and src as `volatile` if either are, it can't do `_Atomic` with `volatile` so we diagnose, and it ignores `restrict`. Otherwise it supports all combinations. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D79279/new/ https://reviews.llvm.org/D79279 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits