Re: [PATCH] match.pd: fold extract-bitfield-and-shift expressions
Artemiy Volkov <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
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)