On Thu, 13 Aug 2026, Jeffrey Law wrote:

> 
> 
> 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.

I think we want to avoid multiple ways to express the same thing as
that makes writing general simplifiers harder.  ISTR we had patches
to lower BIT_FIELD_REFs to shifts and masking to be able to better
combine with other operations.  This was for lowering of bitfield
component-refs to accessing representatives plus then extracting
the accessed bits.

Towards RTL expansion detecting bitfield extraction if the target
natively support that would be another thing.

Richard.

> jeff
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)

Reply via email to