[Bug tree-optimization/93504] Missed reassociation with constants and not of that constant with IORs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93504
--- Comment #6 from GCC Commits ---
The master branch has been updated by Jeff Law :
https://gcc.gnu.org/g:50adb5bb87d434467cf8d41b561a649db2473543
commit r17-411-g50adb5bb87d434467cf8d41b561a649db2473543
Author: Jeff Law
Date: Fri May 8 11:19:02 2026 -0600
[RISC-V][PR tree-optimization/93504] Handle (X & C) | ((X^Y) & ~C) -> X ^ (
Y & ~C) in simplify-rtx
This is a trivial generalization of existing simplify-rtx code.
Essentially
the code in question was handling IOR, but not XOR. I'm keeping the bz
open as
this probably should have been cleaned up before getting into RTL.
The net is something like this:
> #define N 0x202
> #define OP ^
>
> unsigned f(unsigned a, unsigned b)
> {
>unsigned t = a OP b;
>unsigned t1 = t&N;
>unsigned t2 = a&~N;
>return t1 | t2;
> }
>
Originally compiled into:
xor a1,a0,a1
andia1,a1,514
andia0,a0,-515
or a0,a1,a0
ret
After it compiles into:
andia1,a1,514
xor a0,a1,a0
ret
Bootstrapped and regression tested on x86, aarch64 and various targets in
qemu.
Also tested on the usual embedded targets.
PR tree-optimization/93504
gcc/
* simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
Generalize existing code for (X & C) | ((X|Y) & ~C) to handle
(X & C) | ((X^Y) & ~C) as well.
gcc/testsuite
* gcc.target/riscv/pr93504.c: New test.
[Bug tree-optimization/93504] Missed reassociation with constants and not of that constant with IORs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93504
Andrew Pinski changed:
What|Removed |Added
See Also||https://gcc.gnu.org/bugzill
||a/show_bug.cgi?id=110111
Assignee|unassigned at gcc dot gnu.org |pinskia at gcc dot
gnu.org
Status|NEW |ASSIGNED
--- Comment #5 from Andrew Pinski ---
So it is this pattern:
```
/* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */
(simplify
(bit_ior:c (bit_and:cs @0 (bit_not @2)) (bit_and:cs @1 @2))
(bit_xor (bit_and (bit_xor @0 @1) @2) @0))
```
If we change it to:
```
/* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */
(simplify
(bit_ior:c (bit_and:cs @0 (maybe_bit_not @3)) (bit_and:cs @1 @2))
(with { bool wascmp; }
(if (bitwise_inverted_equal_p (@1, @3, wascmp)
(bit_xor (bit_and (bit_xor @0 @1) @2) @0
```
This should fix it.
[Bug tree-optimization/93504] Missed reassociation with constants and not of that constant with IORs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93504
--- Comment #4 from Marc Glisse ---
/* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */
I guess several transformations like this one which match (unary m) could do
with a second version for the case where m is constant (and thus (unary m) is
already constant folded). That is, unless we come up with a trick to avoid that
duplication, like (untested)
(match (my_not @0)
(bit_not @0))
(match (my_not @0)
INTEGER_CST@0
(with { @0 = fold_unary (BIT_NOT_EXPR, TREE_TYPE(@0), @0); }
(if (true
although that's hackish, the commutative version is redundant, it builds a tree
unnecessarily, the conditions (single_use?) to make the transformation worth it
may be different, etc.
[Bug tree-optimization/93504] Missed reassociation with constants and not of that constant with IORs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93504 Richard Biener changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2020-01-30 Ever confirmed|0 |1 --- Comment #3 from Richard Biener --- We have quite some of these associating patterns in match.pd, guess some are misssing.
[Bug tree-optimization/93504] Missed reassociation with constants and not of that constant with IORs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93504 --- Comment #2 from Andrew Pinski --- I should note this does not block bit-field lowering because store merging did not optimize it this way either.
[Bug tree-optimization/93504] Missed reassociation with constants and not of that constant with IORs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93504 --- Comment #1 from Andrew Pinski --- OP can be ^ too.
