On 3/21/25 2:59 PM, Georg-Johann Lay wrote:
There are occasions where knowledge about nonzero bits makes some
optimizations possible.  For example,

    Rd |= Rn << Off

can be implemented as

    SBRC Rn, 0
    ORI  Rd, 1 << Off

when Rn in { 0, 1 }, i.e. nonzero_bits (Rn) == 1.  This patch adds some
patterns that exploit nonzero_bits() in some combiner patterns.
As insn conditions are not supposed to contain nonzero_bits(), the patch
splits such insns right after pass insn combine.

The idea to split the patterns right after combine is from Jeff.

The patch passes without new regressions. Ok for trunk?

Johann

--


AVR: target/119421 Better optimize some bit operations.

There are occasions where knowledge about nonzero bits makes some
optimizations possible.  For example,

    Rd |= Rn << Off

can be implemented as

    SBRC Rn, 0
    ORI  Rd, 1 << Off

when Rn in { 0, 1 }, i.e. nonzero_bits (Rn) == 1.  This patch adds some
patterns that exploit nonzero_bits() in some combiner patterns.
As insn conditions are not supposed to contain nonzero_bits(), the patch
splits such insns right after pass insn combine.

     PR target/119421
gcc/
     * config/avr/avr.opt (-muse-nonzero-bits): New option.
     * config/avr/avr-protos.h (avr_nonzero_bits_lsr_operands_p): New.
     (make_avr_pass_split_nzb): New.
     * config/avr/avr.cc (avr_nonzero_bits_lsr_operands_p): New function.
     (avr_rtx_costs_1): Return costs for the new insns.
     * config/avr/avr.md (nzb): New insn attribute.
     (*nzb=1.<code>...): New insns to better support some bit
     operations for <code> in AND, IOR, XOR.
     * common/config/avr/avr-common.cc (avr_option_optimization_table):
     Enable -muse-nonzero-bits for -O2 and higher.
     * avr-passes.def (avr_pass_split_nzb): Insert pass atfer combine.
     * avr-passes.cc (avr_pass_data_split_nzb). New pass data.
     (avr_pass_split_nzb): New pass.
     (make_avr_pass_split_nzb): New function.
     * doc/invoke.texi (AVR Options): Document -muse-nonzero-bits.
So just an FYI, this is basically one of the approaches I've been pondering to deal with problems in the RISC-V port. Use the pass specific data (nonzero_bits in this case, but there could be others), then rewrite after the pass to use an UNSPEC to prevent the rewritten pattern from ever matching inadvertently.

Specifically on rv64 if we want to use the single bit manipulation insns on an SImode object and the bit position is variable, we have to somehow ensure that it's never bit #31. The cases that come up most often there's some earlier insn that masks the count in a useful way. So for example if the bit position is masked with 0x7 we write the pattern with the bit position masked appropriately.

It's an area we'll be looking at again relatively soon and we may end up investigating additional approaches for viability as we find more cases.

jeff

Reply via email to