On 8/13/2026 1:36 AM, Artemiy Volkov wrote:
This patch adds a simplification rule for expressions of the form
((X >> C1) & C2) << C3, which extract some bits from X at position C1,
perform an "and" with a mask which is normally just 2^N - 1, then shift
the result left by C3.  The transformation is limited to cases where X
is unsigned, has its precision equal to its width and where C1 and C3
are smaller than the precision of X (the last condition could probably
be just assumed but I wasn't sure so decided to play it safe).

When all of the above conditions hold, the expression is folded into
either: (a) (X >> (C1 - C3)) & (C2 << C3) when C1 >= C3, or (b)
(X << (C3 - C1)) & (C2 << C3) when C1 < C3.  Additional care is required
to preserve the leading zeros formed by the X >> C1 operation in the
original expression; to handle this, we clear the leading bits of the
mask operand as a preliminary step.

The corner case where C1 is one less the precision of X is handled
elsewhere (and is folded to just (X >> C1) << C3 as long as the LSB of
C2 isn't 0.)

On aarch64, this results in:

         lsr     x0, x0, 16
         and     w0, w0, 130816

being emitted instead of:

         lsr     x1, x0, 32
         lsr     x0, x0, 24
         ubfiz   w1, w1, 16, 1
         ubfiz   w0, w0, 8, 8
         orr     w0, w1, w0

for the expression "((x >> 32) & 1) << 16) | (x >> 24) & 0xff) << 8)".

A couple of new testcases added, with some focus on the case where X is
shifted too far to the right as described above.

Survives bootstrap and regtest on aarch64-linux-gnu and x86_64-linux-gnu.

gcc/ChangeLog:

         * match.pd: New rule to fold ((X >> C1) & C2) << C3.

gcc/testsuite/ChangeLog:

         * gcc.dg/tree-ssa/match-bit-extract-shift.c: New test.
Interesting you should start looking at this.  I just pointed Daniel at a closely related problem.

In particular should we recognize the (x >> C) & 2^n-1 as a BIT_FIELD_REF.  Doing so for the single bit case would help pr32648 on targets that have single bit extraction/manipulation like RISC-V.

I vaguely recall concerns that we didn't want to recognize or canonicalize to BIT_FIELD_REF in the past, but the details escape me.  Might as well get that discussion started since if we target BIT_FIELD_REF it's going to mean this patch would need further adjustment.  I seem to think it was Richi or Andrea that held this position, but far from 100% certain on that.

jeff

Reply via email to