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