[llvm-bugs] [Bug 40843] New: Vector ABI does not respect target attribute

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Feb 24 08:45:18 PST 2019


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

            Bug ID: 40843
           Summary: Vector ABI does not respect target attribute
           Product: clang
           Version: 7.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: yyc1992 at gmail.com
                CC: llvm-bugs at lists.llvm.org, neeilans at live.com,
                    richard-llvm at metafoo.co.uk

When compiling code with target attribute that may affect the ABI, clang appear
to not handling it correct.

First the observations. Considering the code below compiled on x64.

```
typedef double vdouble __attribute__((vector_size(32)));

__attribute__((target("avx")))
vdouble f(vdouble x, vdouble y)
{
    return x + y;
}
```

Without the target attribute, GCC produces

```
f:
        movapd  8(%rsp), %xmm1
        movapd  24(%rsp), %xmm2
        movq    %rdi, %rax
        addpd   40(%rsp), %xmm1
        addpd   56(%rsp), %xmm2
        movaps  %xmm1, (%rax)
        movaps  %xmm2, 16(%rax)
        ret
```

which AFAICT, is treating the vector as a struct which is passed in on the
stack and passed out by sret. It also issues a warning by default suggesting
that without AVX enabled the ABI is different. (It also gives another warning
about 32bit aligned argument ABI change in gcc 4.6 but that's not relavant to
this issue).

OTOH, without the attribute, clang produces.

```
f:                                      # @f
# %bb.0:
        pushq   %rbp
        movq    %rsp, %rbp
        andq    $-32, %rsp
        subq    $32, %rsp
        movapd  16(%rbp), %xmm0
        movapd  32(%rbp), %xmm1
        addpd   48(%rbp), %xmm0
        addpd   64(%rbp), %xmm1
        movq    %rbp, %rsp
        popq    %rbp
        retq
```

which uses the same argument passing as GCC but passes the value back in `xmm0`
and `xmm1`. I couldn't find any other use of this ABI in other context and
since the LLVM ir returns `<4 x double>` I assume clang just give up fixing it.
As a side note, the generated code is doing a lot of useless work on the stack
pointer. It aligns the stack but actually never uses it..... (We'll see this
below as well)

Now with the attribute, GCC behaves just as if `-mavx` is passed on the command
line, which is what I expected,

```
f:
        vaddpd  %ymm1, %ymm0, %ymm0
        ret
```

Clang, OTOH does,

```
f:                                      # @f
# %bb.0:
        pushq   %rbp
        movq    %rsp, %rbp
        andq    $-32, %rsp
        subq    $32, %rsp
        vmovapd 16(%rbp), %ymm0
        vaddpd  48(%rbp), %ymm0, %ymm0
        movq    %rbp, %rsp
        popq    %rbp
        retq
```

which still passes the parameter in on the stack but passing the return value
in `ymm0`. The uselsess manipulation of the stack pointer is still there as
well...

If `-mavx` is passed on the command line, both clang and gcc generates the same
code. `vaddpd  %ymm1, %ymm0, %ymm0`

Based on the observations above, I believe at the least the stack pointer
manipulation should be fixed and the clang behavior when the attribute is there
should be fixed to match GCC as well (or at least be made consistent though I
don't see why not matching GCC).

I could see an argument about the target attribute not altering the ABI but
that's not what clang is doing either (the ABI with and without that attribute
**is** different in clang). From the generated code, clang is clearly assuming
that the caller knows about ymm0 (that's where it puts the return value) so I
think it should at least be consistent about that for the input arguments too.
If there's a really good argument for separating the feature available in the
function and the feature used for the ABI, there should at least be an
attribute to make the clang behavior match that of gcc in additional to fixing
the return value passing in this case. IMHO though, that should be handled by
the user... (by passing the argument by reference for example).

I saw this on clang 5.0 and 7.0.

-- 
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/20190224/b8e71b99/attachment.html>


More information about the llvm-bugs mailing list