Builtin memcpy() requirements
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Jan 3 13:37:17 UTC 2020
Hello Jonathan,
On 20/12/2019 20:03, Jonathan Brandmeyer wrote:
> Small improvements inline:
>
> On Fri, Dec 20, 2019 at 1:25 AM Sebastian Huber
> <sebastian.huber at embedded-brains.de
> <mailto:sebastian.huber at embedded-brains.de>> wrote:
>
> Hello,
>
> while working on a test case for
>
> https://devel.rtems.org/ticket/3767
>
> I tried to find the right test suite for it. At first I thought that
> this is a unit test
> (testsuites/unit/compiler/tc-misaligned-builtin-memcpy.c). However, I
> now think that we should have a requirement for this function. The test
> case is more or less clear:
>
> T_TEST_CASE(MisalignedBuiltinMemcpy)
> {
> double a;
> double b;
> char buf[2 * sizeof(double)];
>
>
> buf has the alignment of char. Although it is likely to be aligned to
> sizeof(int), it very well could be less than that. In C11 and newer,
> you can use alignas() to force buf to have the alignment of double.
>
> void *p;
>
> p = &buf[0];
>
> p = (void *)((uintptr_t)p | 1);
>
>
> IMO, this reads a bit clearer if p is just a char*. Then you would
> initialize it to the address of buf[1] to force the misalignment.
This depends on the compiler and the system to provide a char buffer
with the specified alignment. The (uintptr_t)p | 1 does not depend on this.
>
> RTEMS_OBFUSCATE_VARIABLE(p);
> a = 123e4;
> RTEMS_OBFUSCATE_VARIABLE(a);
> a *= a;
> memcpy(p, &a, sizeof(a));
> RTEMS_OBFUSCATE_VARIABLE(p);
> memcpy(&b, p, sizeof(b));
> T_eq(a, b, "%f == %f", a, b);
> }
>
> It is obvious that such a memcpy() operation should work. In
> general, we
> assume in RTEMS that the compiler does the right job. However, on some
> architectures we have to select the right compiler options and this is
> clearly under full control of the RTEMS BSP. I think we should add
> something like this to the RTEMS requirements:
>
> A call of memcpy() in C from a pointer to a double value to a
> misaligned
> destination buffer shall store the double value in the destination
> buffer.
>
> The formulation is quite specific, but I was not able to formulate it
> more generic and keep it testable.
>
>
> I've worked on at least one system where double's were silently
> equivalent to float. Maybe a sized integer type such as int64_t would
> be a better candidate for the test case?
No, I specifically want to test situations in which the compiler
generates floating point load/store operations to a misaligned location. The
a = 123e4;
RTEMS_OBFUSCATE_VARIABLE(a);
a *= a;
is there to make the compiler load "a" into a floating point register
and push the compiler to consider to replace the memcpy(p, &a,
sizeof(a)) with a floating point store operation.
I guess we need the same requirement with double replaced by int64_t.
>
> We have to keep in mind here that we
> are not interested in the memcpy() C library function, but rather the
> compiler optimized code for the memcpy() builtin function.
>
>
> This is going to be difficult to verify without examining the generated
> assembly code.
Yes, if you have to look at the assembly code to be sure. Maybe we need
some sort of a signal in the test plans, e.g. this test case needs a
validation by inspection.
>
> -mstrict-align would be overkill for some systems. At least on ARMv7
> and ARMv8, many instructions do support unaligned accesses, while some
> other instructions don't.
Yes, I also think the -mstrict-align is unnecessary on most systems.
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.huber at embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the devel
mailing list