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