https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111849

            Bug ID: 111849
           Summary: GCC replaces volatile struct assignments with memcpy
                    calls
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bugdal at aerifal dot cx
  Target Milestone: ---

On at least some targets where GCC compiles struct assignments to memcpy calls,
this pattern is also used when the struct objects involved are
volatile-qualified. This is invalid; the memcpy function has no contract to
work on volatile objects, and making it compatible with volatile objects would
impose extreme implementation constraints that would limit its performance. For
example, memcpy may copy the same byte more than once to avoid branches, may
use special store instructions with particular cache semantics or data transfer
sizes that aren't compatible with various volatile objects like memory-mapped
registers, etc.

I don't think the C standard is very clear on what is supposed to happen for
volatile struct assignments, but they should at least be done in a way that's
known to be compatible with any memory-mapped interfaces supported on the
target architecture, and the safe behavior is probably implementing them as
member-by-member assignment with some fixup for padding.

I found this while looking at ways to suppress generation of external calls to
memcpy when compiling very restrictive TUs that aren't allowed to make any
external calls, and being surprised that "just add volatile" was not one of the
ways.

I'm filing this as target component because I think the transformation is
taking place at the target backend layer on affected targets rather than
earlier, but I'm not certain. This should be reviewed and possibly reclassified
if that's wrong.

Reply via email to