On Tue, Oct 13 2026, "Rasmus Villemoes" <[email protected]> wrote:

> The only other difference I can see is the U-Boot version doing a tail
> call
>
>       return memcpy(dst, src, len);
>
> which relies on memcpy() being defined to return the dst argument. Now,
> usually nobody uses memcpy's return value, but it can make code slightly
> more compact, and any custom memcpy() implementation (e.g. in asm) _must_
> honour this, as the compiler might transform
>
>   memcpy(a, b, c);
>   return a;
>
> into
>
>   return memcpy(a, b, c);
>
> [I know this because I played around with this in godbolt a few years
> ago, and I think found that gcc did this but clang did not, or something
> like that].

Just for my own future reference: I misremembered slightly regarding the
gcc/clang behaviour, but I did file an llvm bug report back then. That
was just very hard to re-discover because my name was not included when
llvm migrated their issue tracker to github, but it's this one:
https://github.com/llvm/llvm-project/issues/46610 .

> So my best bet is that your platform uses a custom memcpy() which does
> not have to right return value. Can you try changing that last
>
>       return memcpy(dst, src, len);
>
> into
>
>       memcpy(dst, src, len);
>       return dst;
>
> and verify in the disassembly that the compiler hasn't changed it back,
> and then see if your board boots?

As for this hypothesis, I did quickly look at riscv's asm memcpy(), and
I don't see anything obviously wrong (it does have a "save for return
value"). But the arithmetic and comparisons are somewhat risky and
not-obviously-correct, I think. For example, doing

        /* Unrolled wordwise copy */
        addi    t0, t0, -(16*SZREG-1)
        bgeu    a0, t0, 2f

to see if the end of the destination buffer is at least 16 words ahead
of the a0 doesn't work if we happen to work with addresses very close to
0, i.e. something like

  memcpy(32, from_somewhere, 256)

would certainly fail. But I know nothing about riscv, so I can't really
read the asm properly, and the "close to 0" thing is unlikely to be the
real problem.

Nevertheless, another thing to try is disable CONFIG_SPL_ARCH_MEMPCY
(and CONFIG_ARCH_MEMCPY for good measure) and see if that makes a
difference.

Rasmus

Reply via email to