On 7/31/2026 3:47 AM, Ben Shi wrote:
It usually costs 4-5 instructions for 64-bit bitwise AND with a large
immediate. For some immediates the operation can be simplified to two
'BSTRINS.D' instructions if the immediate satisfies:
1. its top bit is not zero.
2. has two sections of consecutive zero bits.
gcc/ChangeLog:
* config/loongarch/loongarch.md: Add a new RTL expression
(define_insn_and_split "bstrins_bstrins_for_and_imm").
* config/loongarch/loongarch.cc: Add a helper function
'loongarch_use_bstrins_bstrins_for_and' for the above RTL expression.
* config/loongarch/loongarch-protos.h: Add prototype of function
'loongarch_use_bstrins_bstrins_for_and'.
* testsuite/gcc.target/loongarch/la64/and-large-immediate-opt-2.c:
Add a new test.
You might want ot look at how RISC-V handles this. There's all kinds of
primitives you can use to clear bits and you're usually better using
those primitives to synthesize the logical operation during initial
expansion without constructing the constant. For example you can use
shifts in pairs or triplets, bit clear style instructions, zero
extensions, and-immediate if you have them, rotates in combination with
and-immediate, and so-on. These are composable.
In general define_insn_and_split is not a great way to solve these
problems because it effectively lies about the cost of the patterns it
matches and it will tend to inhibit further optimizations because of
those lies about the cost (and to be clear, I'm not talking about
rtx_cost or insn cost, but instead the internal costing done by combine
which relies solely on insn counts, particularly with regards to insn
splitting).
I'm not at all familiar with the details of the loongarch port and this
should not be considered a review. Just some advice based on working in
this space on the RISC-V port.
jeff