MachineVerifier flagging calls to memcpy as part of setting up a call stack

Hi all,

I have a question about how large objects passed as arguments by value are handled .

One way a target may handle a large object being passed by value is to memcpy the object into the stack before the call. This is seen in the LLVM regressions test suite as 2010-11-04-BigByval.ll

%big = type [131072 x i8]

declare void @foo(%big* byval(%big) align 1)

define void @bar(%big* byval(%big) align 1 %x) {

call void @foo(%big* byval(%big) align 1 %x)

ret void

}

On our downstream target, this test fails in the MachineVerifier. Lowering of the call to @foo creates a call to memcpy to copy %x onto the stack so that it’s passed by value. This results in the following code:

ADJCALLSTACKDOWN (For call to @foo)

ADJCALLSTACKDOWN (For call to @memcpy)

call memcpy

ADJCALLSTACKUP (For call to @memcpy)

call @foo

ADJCALLSTACKUP (For call to @foo)

The verifier is specifically checking that each ‘FrameSetup’ (here, ADJCALLSTACKDOWN) is followed by ‘FrameDestroy’ (here, ADJCALLSTACKUP), with no intervening ‘FrameSetup’. I thought this to be an issue with our implementation, but I then ran this example on the AArch64 target available on Compiler Explorer:

https://godbolt.org/z/j1veMhqdY

And saw the same error. My searches through the email list, docs, and bug list couldn’t immediately find a reference to this test or error and how to avoid it or do it correctly. The only thing I can think of is hoisting the call to memcpy above the first FrameSetup instruction, but I don’t think I understand enough about what these instructions are doing or why the MachineVerifier cares about such ordering. Is there a correct way to perform this operation to make the verifier happy?

Regards,

J.B. Nagurne

Code Generation

Texas Instruments