https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124667
--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Daniel Barboza <[email protected]>: https://gcc.gnu.org/g:656bb1d9e9637028f917310e6c7688a0f1e99758 commit r17-3334-g656bb1d9e9637028f917310e6c7688a0f1e99758 Author: Daniel Barboza <[email protected]> Date: Tue Aug 11 08:20:40 2026 -0300 match.pd: turn more conditional bit_iors unconditional [PR124667] Add patterns to handle the case where we're checking if a bit is set and setting it in case it's not. Similar to the work done in PR64567 but in this case the bit is a result of a 1 << val lshift: (A & BIT) EQ 0 ? A | BIT : A , BIT = 1 << val => A | BIT (A & BIT) NE 0 ? A : A | BIT , BIT = 1 << val => A | BIT Following Andrea's suggestion we're also handling the variants that results in just 'A' if we switch the conditionals: (A & BIT) EQ 0 ? A | BIT : A , BIT = 1 << val => A | BIT (A & BIT) NE 0 ? A | BIT : A , BIT = 1 << val => A (A & BIT) NE 0 ? A : A | BIT , BIT = 1 << val => A | BIT (A & BIT) EQ 0 ? A : A | BIT , BIT = 1 << val => A We're also adding cases where a full bitmask is tested, i.e.: (A & MASK) EQ MASK ? A : A | MASK => A | MASK (A & MASK) NE MASK ? A : A | MASK => A (A & MASK) NE MASK ? A | MASK : A => A | MASK (A & MASK) EQ MASK ? A | MASK : A => A Note that for these simplifications we're not limited to a bit/pow2 value like the zero comparisons, which don't work with multiple bits because there's no guarantees to preserve the 'non-zero' cases. E.g.: "(A & 0xF) == 0 ? A | 0xF : A" can't be simplified to just "A | 0xF" because there's a whole range of A lower bits (1,2...E) that would be turned to 0xF in the simplification - bits that would be preserved in the original pattern. This is the same scenario discussed before in PR64567. Bootstrapped and regression tested in x86_64, aarch64 and riscv64. PR tree-optimization/124667 gcc/ChangeLog: * match.pd(`(A & BIT) EQ|NE 0 ? A | BIT : A`): New pattern. (`(A & BIT) EQ|NE 0 ? A : A | BIT`): New pattern. (`(A & MASK) EQ|NE MASK ? A : A | MASK`): New pattern. (`(A & MASK) EQ|NE MASK ? A | MASK : A`): New pattern. (`A | (((A >> N) & 1) << N)`): New pattern. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr124667-2.c: New test. * gcc.dg/tree-ssa/pr124667.c: New test.
