[llvm-bugs] [Bug 32507] New: [Win64] XMM registers saved in funclet prologues clobber register saves in parent function
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Apr 3 09:55:20 PDT 2017
https://bugs.llvm.org/show_bug.cgi?id=32507
Bug ID: 32507
Summary: [Win64] XMM registers saved in funclet prologues
clobber register saves in parent function
Product: libraries
Version: trunk
Hardware: PC
OS: Windows NT
Status: NEW
Severity: enhancement
Priority: P
Component: Backend: X86
Assignee: unassignedbugs at nondot.org
Reporter: rnk at google.com
CC: llvm-bugs at lists.llvm.org
This C++ program illustrates the bug:
$ cat a.cpp
double get_xmm(double);
void throw_internally();
void use_xmm(double d);
int main() {
double xmm = get_xmm(1.0);
use_xmm(xmm);
throw_internally();
use_xmm(xmm);
}
$ cat b.cpp
extern "C" int printf(const char *, ...);
void use_xmm(double d) { printf("%f\n", d); }
double __declspec(noinline) get_xmm(double d) {
asm volatile("" : "=m"(d) : "0"(d));
return d;
}
void throw_internally() {
double r1 = get_xmm(2.0);
use_xmm(r1);
use_xmm(r1);
try {
throw 42;
} catch (...) {
double r2 = get_xmm(3.0);
use_xmm(r2);
}
use_xmm(r1);
}
$ clang-cl -Z7 -EHsc -O0 a.cpp b.cpp -Fet.exe && ./t.exe
1.000000
2.000000
2.000000
3.000000
2.000000
1.000000
$ clang-cl -Z7 -EHsc -O2 a.cpp b.cpp -Fet.exe && ./t.exe
1.000000
2.000000
2.000000
3.000000
2.000000
2.000000 # BUG: should be 1.0
The buggy code is in the catch funclet prologue. It does this:
"?catch$2@?0??throw_internally@@YAXXZ at 4HA":
.seh_proc "?catch$2@?0??throw_internally@@YAXXZ at 4HA"
.seh_handler __CxxFrameHandler3, @unwind, @except
movq %rdx, 16(%rsp)
pushq %rbp
.seh_pushreg 5
pushq %rsi
.seh_pushreg 6
subq $40, %rsp
.seh_stackalloc 40
leaq 80(%rdx), %rbp
movdqa %xmm6, -16(%rbp) # 16-byte Spill
.seh_savexmm 6, 64
.seh_endprologue
We set up RBP to point back to the parent stack frame, and then do XMM spills
through RBP. This is no good, because when we eventually return from
throw_internally, we will now restore XMM6 to the value it contained before
running the catch handler (2.0 in the example), and not the value it contained
before calling throw_internally (1.0 in the example).
Funclets should allocate their own stack memory to spill XMM registers.
This bug could probably also be observed by re-throwing the exception out of
the catch handler, since the .seh_savexmm directives we emit for the catch
handler are definitely wrong.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170403/30a5b8a5/attachment.html>
More information about the llvm-bugs
mailing list