Bug ID: 41136
           Summary: Windows on Arm: Clang doesn't follow the ABI for
                    Indirect Arguments
           Product: tools
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: llc

The Windows on ARM64 ABI specifies the following (under Return Values):

"For return-by-value that cannot be passed via registers, the caller shall
reserve a block of memory of sufficient size and alignment to hold the result.
The address of the memory block shall be passed as an additional argument to
the function in x8 for POD type, or in x0 (or x1 if $this is passed in x0) for
non-POD type. The callee may modify the result memory block at any point during
the execution of the subroutine (there is no requirement for the callee to
preserve the value stored in x8, but for non-POD, the address of this buffer
must also be returned in x0 by callee)."

This means (AFAICT) that when it's impossible to return a value in the native
registers, it instead allocates an indirect location on the stack, and passes
it into the callee function via x0, x1 or x8. MSVC and Clang disagree on when
this is required.

Main file:


template <class T>
class Maybe {
        bool hasValue = false;
        T value = false;
Maybe<bool> f(int x, int y);
int main(void) {
        bool v = f(5, 6).value;
        bool hv = f(5, 6).hasValue;
        printf("main(): value = %d, hasValue = %d\n", v, hv);


Callee file:


Maybe<bool> f(int x, int y) {
        printf("f(): x = %d, y = %d\n", x, y);
        Maybe<bool> m;
        m.hasValue = x < 7;
        m.value = y < 7;
        return m;


Clang passes x and y in w1, w2, indirect buffer passed in x0. Called MSVC
function expects arguments in w0, w1 and therefore receives wrong argument
values. We think this is incorrect behaviour.

You are receiving this mail because:
You are on the CC list for the bug.
llvm-bugs mailing list

Reply via email to