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

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

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

commit r17-4462-gf95a1c7f4e4b1f4c41e40d2eab8cbde258292962
Author: Milan Tripkovic <[email protected]>
Date:   Sat Sep 19 07:55:27 2026 -0600

    [PATCH] RISC-V: PR target/126074 - Missing cases for constant synthesis on
RISC-V

    This patch implements the shNadd.uw case from the PR.

    The instruction shNadd.uw a0, a0, a0 computes:
      ((a0 & 0xffffffff) << N) + a0

    If a0 holds a value sign extended from bit 31, with u being its low
    32 bits, this formula evaluates to:
      u * (2^N + 1) - 2^32

    This allows us to build certain 64-bit constants using just a lui
    and a single shNadd.uw.

    To find u, riscv_build_integer_1 reverses the formula: it adds
    2^32 to the constant and divide it by 3, 5, or 9. If the quotient
    fits in 32 bits with bit 31 set, and the new sequence is cheaper,
    we emit an FMA entry with use_uw set.

    For 0x180005000, before:

    ââââââli      a0,1572864
    ââââââaddi    t0,a0,5
    ââââââslli    a0,t0,12

    after:

    ââââââliââââa0,-715821056
    ââââââsh1add.uwâââa0,a0,a0

    Finally, in riscv_move_integer, the FMA check is moved above the
    use_uw check. Since our shNadd.uw case sets use_uw = true,
    checking use_uw first would mistakenly treat the operation as a
    plain zero-extended shift instead of shNadd.uw.

            PR target/126074
    gcc/ChangeLog:

            * config/riscv/riscv.cc (riscv_build_integer_1): Add logic to
            synthesize constants using shNadd.uw.
            (riscv_move_integer): Handle FMA with use_uw for RTL emission.

    gcc/testsuite/ChangeLog:

            * gcc.target/riscv/pr126074.c: New test.
  • [Bug target/126074] Missing cas... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to