On 9/6/26 3:37 AM, Artemiy Volkov wrote:
On Thu, Aug 13, 2026 at 07:36:36AM +0000, 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.Hi Jeff, Richard, Considering the discussion in the main thread seems to have settled on recognizing BFRs at the RTL level, could the original patch please be considered for review/inclusion?
Agreed. Let's get this moving again.
This looks sound to me. I'll set aside my desire to consider special casing 2^n-1 cases for C2 (particularly for n=1).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.
OK for the trunk. jeff
