On 3/12/2026 12:30 PM, Philipp Tomsich wrote:
> In riscv_expand_conditional_move, detect unsigned comparisons against
> power-of-2 boundaries and convert them to shift-based equality tests.
> This avoids materializing large constants (e.g. 2^56 - 1) that may
> require multiple instructions (bseti + sltu), replacing them with a
> single srli that feeds directly into czero.eqz/czero.nez.
>
> The transformation handles four cases:
>    GTU x, (2^N-1)  ->  NE (x >> N), 0
>    LEU x, (2^N-1)  ->  EQ (x >> N), 0
>    GEU x, 2^N      ->  NE (x >> N), 0
>    LTU x, 2^N      ->  EQ (x >> N), 0
>
> For example, `(a & (0xff << 56)) ? b : 0` previously generated:
>    bseti  a5, zero, 56
>    sltu   a0, a0, a5
>    czero.nez  a0, a1, a0
>
> Now generates:
>    srli      a0, a0, 56
>    czero.eqz a0, a1, a0
>
> Existing define_split patterns in riscv.md (lines 3727-3748) handle
> the same optimization for standalone SCC operations, but they don't
> fire in the conditional move expansion path which goes through
> riscv_expand_int_scc directly.
>
> gcc/ChangeLog:
>
>       * config/riscv/riscv.cc (riscv_expand_conditional_move):
>       Convert unsigned comparisons against power-of-2 boundaries
>       to shift-based equality tests.
>
> gcc/testsuite/ChangeLog:
>
>       * gcc.target/riscv/zicond-shift-cond.c: New test.
OK for gcc-17 once the trunk opens for development.

jeff

Reply via email to