Using nonzero_bits() in insn conditions?

Jeff Law jeffreyalaw@gmail.com
Sun Mar 16 13:51:55 GMT 2025



On 3/13/25 5:39 AM, Georg-Johann Lay via Gcc wrote:
> There are situations where knowledge about which bits
> of a value are (not) set can be used for optimization.
> For example in an insn combine pattern like:
> 
> (define_insn_and_split ""
>    [(set (match_operand:QI 0 "register_operand"                       "=d")
>          (ior:QI (ashift:QI (match_operand:QI 1 "register_operand"     "r")
>                             (match_operand:QI 2 "const_0_to_7_operand" 
> "n"))
>                  (match_operand:QI 3 "register_operand" "0")))]
>    "optimize
>     && !reload_completed
>     && nonzero_bits (operands[1], VOIDmode) == 1"
> ...
> 
> This pattern is only correct when operands[1] is 0 or 1.
> 
> While such patterns seem to work, it's all quite wonky,
> in particular since nonzero_bits() may forget about known
> properties in later passes.
While it works most of the time, it's fundamentally wrong to have a 
pattern where the conditional is dependent on state that changes based 
on pass specific data, nearby context, etc.

> 
> For the use case I have in mind, it is in order when the
> pattern works until split1 which would transform it into
> something else (and without nonzero_bits() in the insn
> condition, asserting that the existence of the pattern
> certifies the bit condition).
It's still the wrong thing to do.  You'll get away with it for a while, 
but one day it'll break.

We have similar problems in the RISC-V world where we would like to be 
able to match certain patterns based on known ranges of an operand.  The 
most common case would be bset/bclr/binv on an SImode object on rv64 
where the bit twiddled is variable.  In particular we need to know the 
bit position is not bit 31.

There's no way to really describe that in an insn's condition because 
range information like that isn't available in RTL and something like 
nonzero bits is pass specific.

As a result we're limited in our ability to use the bset/bclr/binv 
instructions.

Jeff


More information about the Gcc mailing list