<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - Windows on Arm: X0 corrupted when returning values indirectly"
href="https://bugs.llvm.org/show_bug.cgi?id=41135">41135</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Windows on Arm: X0 corrupted when returning values indirectly
</td>
</tr>
<tr>
<th>Product</th>
<td>tools
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>llc
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>sjoerd.meijer@arm.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>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.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>