https://bugs.llvm.org/show_bug.cgi?id=41135

            Bug ID: 41135
           Summary: Windows on Arm: X0 corrupted when returning values
                    indirectly
           Product: tools
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: llc
          Assignee: unassignedb...@nondot.org
          Reporter: sjoerd.mei...@arm.com
                CC: llvm-bugs@lists.llvm.org

We think that we miscompile code targeting aarch64-pc-windows-msvc. It looks
like the problem is in Clang/LLVM not obeying the Windows ARM64 ABI, which says
that:

"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 problem is that we do not preserve x0 when the result value is passed
through X0 and another function call is made.


Here's a reproducer:

------------------------------------

template <class T>
class MaybeLocal {
    public:
        T* ptr = nullptr;
};

extern int FOO(bool);

template <class T>
class Maybe {
  public:
    bool hasValue = false;
    T value = false;

    MaybeLocal<T> Invert() {
        Maybe<T> ret;
        ret.value = ~this->value;
        FOO(hasValue);
        return MaybeLocal<bool>{&this->value};
    }
};

int main(void) {

  Maybe<bool> m;
  m.hasValue = true;
  m.value = 7;
  return (m.Invert().ptr == nullptr);
}

------------------------------------


Compiling this e.g. with:

  clang++ --target=aarch64-pc-windows-msvc -S -Os fno-inline 


Generates this for function Invert:

.globl  "?Invert@?$Maybe@_N@@QEAA?AV?$MaybeLocal@_N@@XZ" ; -- Begin function
?Invert@?$Maybe@_N@@QEAA?AV?$MaybeLocal@_N@@XZ
        .p2align        2
"?Invert@?$Maybe@_N@@QEAA?AV?$MaybeLocal@_N@@XZ": ;
@"?Invert@?$Maybe@_N@@QEAA?AV?$MaybeLocal@_N@@XZ"
.seh_proc "?Invert@?$Maybe@_N@@QEAA?AV?$MaybeLocal@_N@@XZ"
; %bb.0:                                ; %entry
        stp     x19, x20, [sp, #-32]!
        str     x30, [sp, #16]
        mov     x20, x0          <~~~~~~~~~~~ MOV X0 TO X20
        add     x0, sp, #24
        mov     x19, x1
        bl      "??0?$Maybe@_N@@QEAA@XZ"
        orr     w8, wzr, #0x1
        strb    w8, [sp, #25]
        ldrb    w0, [x20], #1    <~~~~~~~~~~~ LOAD W0 HERE
        bl      "?FOO@@YAH_N@Z"
        str     x20, [x19]       <~~~~~~~~~~~ DON'T RELOAD X0 HERE SOMEWHERE 
        ldr     x30, [sp, #16] 
        ldp     x19, x20, [sp], #32
        ret

As annotated in the assembly code above, we move X0 to X20, but don't seem to
reload X0 after the call to FOO.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to