On Fri, Aug 14, 2026 at 08:39:35AM +0200, Richard Biener wrote:
> 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.
> 

Hi Jeff, Richard,

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

To this I just want to quickly add that canonicalizing to BFRs for bitwise
operations would lead to loss of generality, since in the new simplify
pattern, as well as a few existing ones, the mask operand does not have to
be strictly equal to 2^N - 1.

Thanks,
Artemiy

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