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

--- Comment #3 from Jin Haobo <a1343922569 at outlook dot com> ---
The code in my reproduction is wrong. I will re-show the C++ code.

Reproduction C++ code (64-bit variable):
#include <cstdint>

using U = uint64_t;

struct A { U quo; U rem; };

U myDiv(U const& a, U const& b)
{
        U result, dummyRemainder;

        asm (
                "xor %[remainder], %[remainder]  \n\t"
                "div %[divisor]  \n\t"
                : [quotient] "=a"(result), [remainder] "=d" (dummyRemainder)
                : [dividendLow] "a"(a), [divisor] "rm"(b)
        );


        return result;
}

U myMod(U const& a, U const& b)
{    
        U result, dummyQuotient;

        asm (
                "xor %[remainder], %[remainder]  \n\t"
                "div %[divisor]  \n\t"
                : [quotient] "=a" (dummyQuotient), [remainder] "=d" (result)
                : [dividendLow] "a"(a), [divisor] "rm"(b)
        );

        return result;
}

A myDivMod1(U const& a, U const& b)
{
        A result;
        result.quo = myDiv(a, b);
        result.rem = myMod(a, b);
        return result;
}

A myDivMod2(U const& a, U const& b)
{
        A result;

        asm (
                "xor %[dividendRemainder], %[dividendRemainder]  \n\t"
                "div %[divisor]  \n\t"
                : [quotient] "=a"(result.quo), [dividendRemainder] "=d"
(result.rem)
                : [dividendLow] "a"(a), [divisor] "rm"(b)
        );

        return result;
}


Current generated assembly (64-bit variable):
myDiv(unsigned long const&, unsigned long const&):
        mov     rax, QWORD PTR [rdi]
        xor rdx, rdx  
        div QWORD PTR [rsi]  

        ret
myMod(unsigned long const&, unsigned long const&):
        mov     rax, QWORD PTR [rdi]
        xor rdx, rdx  
        div QWORD PTR [rsi]  

        mov     rax, rdx
        ret
myDivMod1(unsigned long const&, unsigned long const&):
        mov     rax, rsi
        mov     rsi, QWORD PTR [rdi]
        mov     rcx, QWORD PTR [rax]
        mov     rax, rsi
        xor rdx, rdx  
        div rcx  

        mov     rdi, rax
        mov     rax, rsi
        xor rdx, rdx  
        div rcx  

        mov     rax, rdi
        ret
myDivMod2(unsigned long const&, unsigned long const&):
        mov     rax, QWORD PTR [rdi]
        xor rdx, rdx  
        div QWORD PTR [rsi]  

        ret


Godbolt link (GCC, generate suboptimal assembly code for myDivMod1, which is
not the same as myDivMod2)
64-bit variable: https://gcc.godbolt.org/z/7j9MsKsMr
32-bit variable: https://gcc.godbolt.org/z/EEKzWWx14
16-bit variable: https://gcc.godbolt.org/z/5j9zoxrro
8-bit variable: https://gcc.godbolt.org/z/3sWh9K6r5


Godbolt link (Clang, generate optimal assembly code for myDivMod1, which is the
same as myDivMod2)
64-bit variable: https://gcc.godbolt.org/z/cneMq3eYT
32-bit variable: https://gcc.godbolt.org/z/E1e9x65hj
16-bit variable: https://gcc.godbolt.org/z/3aq9dsa3M
8-bit variable: https://gcc.godbolt.org/z/8EG8TEzGq

Reply via email to