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

--- Comment #14 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Kyrylo Tkachov <[email protected]>:

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

commit r17-6103-gee2f4aeb3c55f2603e41cf4772275660f987f046
Author: Kyrylo Tkachov <[email protected]>
Date:   Mon Nov 9 10:53:43 2026 +0100

    aarch64: Implement clmul and clmul_widen optabs [PR128111]

    __builtin_clmulg expands through the clmul and clmul_widen optabs, and
    without them it falls back to a multiply-based software sequence.
    AArch64 has carry-less multiplication in PMULL: the 64x64->128 form
    with +aes (FEAT_PMULL) and the 8x8->16 form in base AdvSIMD.

    Add clmuldi3 and clmul_widendi3 for TARGET_AES on top of
    aarch64_crypto_pmulldi.  The middle-end zero-extends narrower operands
    to DImode, so these also cover 16-bit and 32-bit clmul and the 32-bit
    widening form.  The high half is extracted as a lane of the V2DI view
    of the product.  A highpart subreg of the TImode product is spilled
    to the stack when it is the only half used.

    These are not available in streaming mode, so the expanders require
    TARGET_NON_STREAMING.

    Add clmul_widenqi3 for TARGET_SIMD using the 8x8->16 PMULL, so 8-bit
    clmul does not need +aes.

    For example, with +aes the low half of a 64x64->128 carry-less product
    (clmul) and both halves (clmul_widen):

      unsigned long long clmul (unsigned long long a, unsigned long long b)
      {
        return __builtin_clmulg (a, b);
      }

      unsigned long long clmul_widen (unsigned long long a, unsigned long long
b,
                                      unsigned long long *hi)
      {
        return __builtin_clmulg (a, b, hi);
      }

    generate:

      clmul:
            fmov    d31, x0
            fmov    d30, x1
            pmull   v30.1q, v31.1d, v30.1d
            fmov    x0, d30
            ret

      clmul_widen:
            fmov    d31, x0
            fmov    d30, x1
            pmull   v30.1q, v31.1d, v30.1d
            fmov    x0, d30
            st1     {v30.d}[1], [x2]
            ret

    and without +aes the 8-bit clmul_widen generates:

      clmul8_widen:
            dup     v31.8b, w0
            dup     v30.8b, w1
            pmull   v30.8h, v31.8b, v30.8b
            ushr    v31.2s, v30.2s, 8
            umov    w0, v30.b[0]
            str     b31, [x2]
            ret

    The runtime test clmul_4.c needs FEAT_PMULL, so it requires the new
    effective target aarch64_pmull_hw.

    Bootstrapped and tested on aarch64-linux-gnu.

    gcc/ChangeLog:

            PR middle-end/128111
            * config/aarch64/aarch64-simd.md (clmuldi3, clmul_widendi3): New
            expanders, enabled for TARGET_AES in non-streaming mode.
            (clmul_widenqi3): New expander.

    gcc/testsuite/ChangeLog:

            PR middle-end/128111
            * lib/target-supports.exp
(check_effective_target_aarch64_pmull_hw):
            New.
            * gcc.target/aarch64/clmul_1.c: New test.
            * gcc.target/aarch64/clmul_2.c: Likewise.
            * gcc.target/aarch64/clmul_3.c: Likewise.
            * gcc.target/aarch64/clmul_4.c: Likewise.
            * gcc.target/aarch64/clmul_5.c: Likewise.
            * gcc.target/aarch64/clmul_6.c: Likewise.
            * gcc.target/aarch64/sme/clmul_1.c: Likewise.

    Signed-off-by: Kyrylo Tkachov <[email protected]>

Reply via email to