Take the following three functions: int f(int a, int b) { int c = a != 0; int d = (c!=0|b!=0); return d; } int f1(int a, int b) { int c = a != 0; int e = c!=0; int h = b!=0; int d = e|h; return d; } int f2(int a, int b) { return (a!=0|b!=0); } --- CUT --- Right now only f2 produces good code while the other two are not so good.
I have a fix in mind.
For the trunk, they all come close (at least for aarch64): f: cmp w0, 0 cset w0, ne orr w1, w0, w1 cmp w1, 0 cset w0, ne ret .size f, .-f .align 2 .p2align 3,,7 .global f1 .type f1, %function f1: cmp w0, 0 ccmp w1, 0, 0, eq cset w0, ne ret .size f1, .-f1 .align 2 .p2align 3,,7 .global f2 .type f2, %function f2: orr w0, w0, w1 cmp w0, 0 cset w0, ne ret f1 and f2 are similar enough for aarch64 (at least for ThunderX).
I don't remember what the patch was ... so unassigning.
The generic rule is: original 3 expressions; (((int)b) | i) == 0 -> (b == 0) & (i == 0) -> ~b & (i == 0) (4 expressions; maybe 3 if b is a comparison and single use) (((int)b) | i) != 0 -> (b != 0) | (i != 0) -> b | (i != 0) (still 3 expressions) (((int)b) & i) == 0 -> (b == 0) | ((i&1) == 0) -> ~b | ((i&1) == 0) (4 expressions; maybe 3 if b is a comparison and single use) (((int)b) & i) != 0 -> (b != 0) & ((i&1) != 0) -> b & ((i&1) != 0) (still 3 expressions) Where b is a "boolean" type variable.
// (a | zero_one) != 0 -> a!=0 | zero_one (simplify (ne (bit_ior:c @1 zero_one_value_p@2) integer_zerop@3) (bit_ior (convert @1) (ne @2 @3))) // (a & zero_one) != 0 -> a==0 & (zero_one^1) (simplify (eq (bit_and:c @1 zero_one_value_p@2) integer_zerop@3) (bit_and (convert (bit_xor @1 { build_one_cst (TREE_TYPE (@1)); } )) (ne @2 @3))) Similar to: https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630651.html
(In reply to Andrew Pinski from comment #5) > // (a | zero_one) != 0 -> a!=0 | zero_one > > (simplify > (ne (bit_ior:c @1 zero_one_value_p@2) integer_zerop@3) > (bit_ior (convert @1) (ne @2 @3))) > > > // (a & zero_one) != 0 -> a==0 & (zero_one^1) Should have been: // (a & zero_one) == 0 -> a==0 & (zero_one^1) > (simplify > (eq (bit_and:c @1 zero_one_value_p@2) integer_zerop@3) > (bit_and > (convert (bit_xor @1 { build_one_cst (TREE_TYPE (@1)); } )) > (ne @2 @3))) > > > Similar to: > https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630651.html