Add with Carry



  • Hallo

    Ich möchte zwei 128-bit Zahlen, die je als zwei 64-bit Zahlen gespeichert sind, addieren und das Carry-Flag zurückgeben. Meine aktuelle Implementierung (für GCC und Clang) sieht wie folgt aus:

    // aLo += bLo, aHi += bHi + carryLo, ret carryHi
    bool AddWithCarry( std::uint64_t& aHi, std::uint64_t& aLo, std::uint64_t bHi, std::uint64_t bLo )
    {
        using T = unsigned __int128;
    
        const T a = T{ aHi } << 64 | aLo;
        const T b = T{ bHi } << 64 | bLo;
        const T x = a + b;
        aLo = x;
        aHi = x >> 64;
        return x < a;
    }
    

    Godbolt
    GCC generiert leider sehr schlechten Code für diese Funktion wohingegen Clang scheinbar optimalen Code erzeugt. Meinen Messungen zufolge ist der Clang-Output knapp 4x schneller.

    Hat jemand eine Idee, wieso der GCC hier nicht so gut optimieren kann? 🙂 Hat es mit den Referenzen zu tun? Und wieso generiert er Jumps?

    LG


Anmelden zum Antworten