https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65782

--- Comment #10 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-8 branch has been updated by Jakub Jelinek
<ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:baef3efdc4992e4dcb7f4de62ff5bcb13bf05f60

commit r8-10016-gbaef3efdc4992e4dcb7f4de62ff5bcb13bf05f60
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Feb 14 15:47:55 2020 +0100

    i386: Make xmm16-xmm31 call used even in ms ABI [PR65782]

    On Tue, Feb 04, 2020 at 11:16:06AM +0100, Uros Bizjak wrote:
    > I guess that Comment #9 patch form the PR should be trivially correct,
    > but althouhg it looks obvious, I don't want to propose the patch since
    > I have no means of testing it.

    I don't have means of testing it either.
   
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019
    is quite explicit that [xyz]mm16-31 are call clobbered and only xmm6-15
(low
    128-bits only) are call preserved.

    We are talking e.g. about
    /* { dg-options "-O2 -mabi=ms -mavx512vl" } */

    typedef double V __attribute__((vector_size (16)));
    void foo (void);
    V bar (void);
    void baz (V);
    void
    qux (void)
    {
      V c;
      {
        register V a __asm ("xmm18");
        V b = bar ();
        asm ("" : "=x" (a) : "0" (b));
        c = a;
      }
      foo ();
      {
        register V d __asm ("xmm18");
        V e;
        d = c;
        asm ("" : "=x" (e) : "0" (d));
        baz (e);
      }
    }
    where according to the MSDN doc gcc incorrectly holds the c value
    in xmm18 register across the foo call; if foo is compiled by some Microsoft
    compiler (or LLVM), then it could clobber %xmm18.
    If all xmm18 occurrences are changed to say xmm15, then it is valid to hold
    the 128-bit value across the foo call (though, surprisingly, LLVM saves it
    into stack anyway).

    The other parts are I guess mainly about SEH.  Consider e.g.
    void
    foo (void)
    {
      register double x __asm ("xmm14");
      register double y __asm ("xmm18");
      asm ("" : "=x" (x));
      asm ("" : "=v" (y));
      x += y;
      y += x;
      asm ("" : : "x" (x));
      asm ("" : : "v" (y));
    }
    looking at cross-compiler output, with -O2 -mavx512f this emits
        .file   "abcdeq.c"
        .text
        .align 16
        .globl  foo
        .def    foo;    .scl    2;      .type   32;     .endef
        .seh_proc       foo
    foo:
        subq    $40, %rsp
        .seh_stackalloc 40
        vmovaps %xmm14, (%rsp)
        .seh_savexmm    %xmm14, 0
        vmovaps %xmm18, 16(%rsp)
        .seh_savexmm    %xmm18, 16
        .seh_endprologue
        vaddsd  %xmm18, %xmm14, %xmm14
        vaddsd  %xmm18, %xmm14, %xmm18
        vmovaps (%rsp), %xmm14
        vmovaps 16(%rsp), %xmm18
        addq    $40, %rsp
        ret
        .seh_endproc
        .ident  "GCC: (GNU) 10.0.1 20200207 (experimental)"
    Does whatever assembler mingw64 uses even assemble this (I mean the
    .seh_savexmm %xmm16, 16 could be problematic)?
    I can find e.g.
   
https://stackoverflow.com/questions/43152633/invalid-register-for-seh-savexmm-in-cygwin/43210527
    which then links to
    https://gcc.gnu.org/PR65782

    2020-02-08  Uroš Bizjak  <ubiz...@gmail.com>
            Jakub Jelinek  <ja...@redhat.com>

        PR target/65782
        * config/i386/i386.h (CALL_USED_REGISTERS): Make
        xmm16-xmm31 call-used even in 64-bit ms-abi.

        * gcc.target/i386/pr65782.c: New test.

    Co-authored-by: Uroš Bizjak <ubiz...@gmail.com>

Reply via email to