public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/94703] New: Small-sized  memcpy leading to unnecessary register spillage unless done through a dummy union
@ 2020-04-21 21:07 pskocik at gmail dot com
  2020-04-22  7:28 ` [Bug middle-end/94703] " rguenth at gcc dot gnu.org
                   ` (14 more replies)
  0 siblings, 15 replies; 16+ messages in thread
From: pskocik at gmail dot com @ 2020-04-21 21:07 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 94703
           Summary: Small-sized  memcpy leading to unnecessary register
                    spillage unless done through a dummy union
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pskocik at gmail dot com
  Target Milestone: ---

The problem, demonstrated in code examples below, can be suppressed by
memcpying into a union (possibly just a one-member union), but that seems like
a silly workaround that shouldn't be required.

Examples:

#include <stdint.h>
#include <string.h>

uint64_t get4_1(void const *X)
{
        //spills
        uint64_t r = 0; memcpy(&r,X,4); return r;
}

uint64_t get4_nospill(void const *X)
{
        //doesn't spill
        union { uint64_t u64; } u = {0};
        memcpy(&u.u64,X,sizeof(uint32_t));
        return u.u64;
}

uint64_t get2_1(void const *X)
{
        //spills
        uint64_t r = 0; memcpy(&r,X,2); return r;
}


uint64_t get2_nospill(void const *X)
{
        //doesn't spill
        union { uint64_t u64; } u = {0};
        memcpy(&u.u64,X,sizeof(uint16_t));
        return u.u64;
}

        void backend(void const*Src, size_t Sz);
        static inline void valInPtrInl(void *Src, size_t Sz)
        {
                if(Sz<=sizeof(void const*)){
                        #if 1 //spills
                                void const*inlSrc; 
                                memcpy(&inlSrc,Src,Sz);
                                backend(inlSrc,Sz); return;
                        #else
                                //doesn't spill
                                union{ void const*inlSrc; } u;
                                memcpy(&u.inlSrc,Src,Sz);
                                backend(u.inlSrc,Sz); return;
                        #endif
                }

                backend(Src,Sz);
                return;

        }
void valInPtr(int X) { valInPtrInl(&X,sizeof(X)); }

GCC 9.3 output on x86_64:

get4_1:
        mov     QWORD PTR [rsp-8], 0
        mov     eax, DWORD PTR [rdi]
        mov     DWORD PTR [rsp-8], eax
        mov     rax, QWORD PTR [rsp-8]
        ret
get4_nospill:
        mov     eax, DWORD PTR [rdi]
        ret
get2_1:
        mov     QWORD PTR [rsp-8], 0
        movzx   eax, WORD PTR [rdi]
        mov     WORD PTR [rsp-8], ax
        mov     rax, QWORD PTR [rsp-8]
        ret
get2_nospill:
        xor     eax, eax
        mov     ax, WORD PTR [rdi]
        ret
valInPtr:
        mov     DWORD PTR [rsp-16], edi
        mov     rdi, QWORD PTR [rsp-16]
        mov     esi, 4
        jmp     backend

Clang 3.1 output on x86_64:

get4_1:                                 # @get4_1
        mov     EAX, DWORD PTR [RDI]
        ret

get4_nospill:                           # @get4_nospill
        mov     EAX, DWORD PTR [RDI]
        ret

get2_1:                                 # @get2_1
        movzx   EAX, WORD PTR [RDI]
        ret

get2_nospill:                           # @get2_nospill
        movzx   EAX, WORD PTR [RDI]
        ret

valInPtr:                               # @valInPtr
        mov     EDI, EDI
        mov     ESI, 4
        jmp     backend                 # TAILCALL


https://gcc.godbolt.org/z/rwq2UY

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-05-14  9:55 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-21 21:07 [Bug c/94703] New: Small-sized memcpy leading to unnecessary register spillage unless done through a dummy union pskocik at gmail dot com
2020-04-22  7:28 ` [Bug middle-end/94703] " rguenth at gcc dot gnu.org
2020-04-22  7:34 ` rguenth at gcc dot gnu.org
2020-04-22  7:59 ` rguenth at gcc dot gnu.org
2020-04-22  8:46 ` rguenth at gcc dot gnu.org
2020-05-07 13:39 ` cvs-commit at gcc dot gnu.org
2020-05-07 13:41 ` rguenth at gcc dot gnu.org
2020-05-08 11:03 ` ro at gcc dot gnu.org
2020-05-08 11:03 ` ro at gcc dot gnu.org
2020-05-08 11:19 ` rguenth at gcc dot gnu.org
2020-05-13 14:43 ` ro at CeBiTec dot Uni-Bielefeld.DE
2020-05-13 16:00 ` pskocik at gmail dot com
2020-05-14  9:10 ` rguenth at gcc dot gnu.org
2020-05-14  9:49 ` rguenth at gcc dot gnu.org
2020-05-14  9:54 ` cvs-commit at gcc dot gnu.org
2020-05-14  9:55 ` rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).