Re: [PATCH] match.pd: fold extract-bitfield-and-shift expressions

Jeffrey Law <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>

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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.