Hi, This adds the following two simplifcations to match.pd: ((A & N) == CST1) & ((A & M) == CST2) if (N&M)&CST1 == (N&M)&CST2, then (A&(N|M)) == (CST1|CST2) else false And ((A & N) != CST1) | ((A & M) != CST2)
if (N&M)&CST1 == (N&M)&CST2, then (A&(N|M)) != (CST1|CST2) else true NOTE it adds a check to make sure N&~CST1 and M&~CST2 are zero; that is non outside bits are set in CST1/CST2; just to make sure we don't have an ordering issue when doing the simplification. I added a testcase for majority of cases I could think of, so there are a total of 29 testcases include. NOTE It does not solve the original testcase in the bug report though, because we need to handle (A&integer_pow2p) !=/== 0 as ((A & integer_pow2p) ==/!= integer_pow2p) which is not done in this patch. I will implement that in a follow up patch. NOTE this is a step forward to be able to remove the fold_truth_andor_1 and optimize_bit_field_compare from fold-const.c. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Thanks, Andrew Pinski ChangeLog: * match.pd (((A & N) ==/!= CST1) &/| ((A & M) ==/!= CST2)): New pattern. testsuite/ChangeLog: * gcc.c-torture/execute/cmpandor-1.c: New testcase * gcc.c-torture/execute/cmpandor-1.h: New file. * gcc.dg/tree-ssa/eqand-1.c: New testcase. * gcc.dg/tree-ssa/eqand-2.c: New testcase. * gcc.dg/tree-ssa/eqand-3.c: New testcase. * gcc.dg/tree-ssa/eqand-4.c: New testcase. * gcc.dg/tree-ssa/eqand-5.c: New testcase. * gcc.dg/tree-ssa/eqand-6.c: New testcase. * gcc.dg/tree-ssa/eqand-7.c: New testcase. * gcc.dg/tree-ssa/eqor-1.c: New testcase. * gcc.dg/tree-ssa/eqor-2.c: New testcase. * gcc.dg/tree-ssa/eqor-3.c: New testcase. * gcc.dg/tree-ssa/eqor-4.c: New testcase. * gcc.dg/tree-ssa/eqor-5.c: New testcase. * gcc.dg/tree-ssa/eqor-6.c: New testcase. * gcc.dg/tree-ssa/eqor-7.c: New testcase. * gcc.dg/tree-ssa/neand-1.c: New testcase. * gcc.dg/tree-ssa/neand-2.c: New testcase. * gcc.dg/tree-ssa/neand-3.c: New testcase. * gcc.dg/tree-ssa/neand-4.c: New testcase. * gcc.dg/tree-ssa/neand-5.c: New testcase. * gcc.dg/tree-ssa/neand-6.c: New testcase. * gcc.dg/tree-ssa/neand-7.c: New testcase. * gcc.dg/tree-ssa/neor-1.c: New testcase. * gcc.dg/tree-ssa/neor-2.c: New testcase. * gcc.dg/tree-ssa/neor-3.c: New testcase. * gcc.dg/tree-ssa/neor-4.c: New testcase. * gcc.dg/tree-ssa/neor-5.c: New testcase. * gcc.dg/tree-ssa/neor-6.c: New testcase. * gcc.dg/tree-ssa/neor-7.c: New testcase.
Index: match.pd =================================================================== --- match.pd (revision 279865) +++ match.pd (working copy) @@ -807,6 +807,35 @@ (define_operator_list COND_TERNARY && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1))) (cmp (bit_and @0 (convert @1)) @2)))) +/* Transform ((A & N) ==/!= CST1) &/| ((A & M) ==/!= CST2) + if (CST1&~N) == 0 && (CST2&~M) == 0 then + if (N&M)&CST1 != (N&M)&CST2 then + false/true + else + (A&(N|M)) ==/!= (CST1|CST2) */ +(for bitop (bit_and bit_ior) + cmp (eq ne) + (simplify + (bitop + (cmp (bit_and @0 INTEGER_CST@mask1) INTEGER_CST@CST1) + (cmp (bit_and @0 INTEGER_CST@mask2) INTEGER_CST@CST2)) + (with + { + tree type1 = TREE_TYPE (@0); + wide_int mask1 = wi::to_wide (@mask1); + wide_int mask2 = wi::to_wide (@mask2); + wide_int newmask = mask1 | mask2; + wide_int m = mask1 & mask2; + wide_int cst1 = wi::to_wide (@CST1); + wide_int cst2 = wi::to_wide (@CST2); + } + (if (wi::bit_and_not (cst1, mask1) == 0 + && wi::bit_and_not (cst2, mask2) == 0) + (if (wi::eq_p (m & cst1, m & cst2)) + (cmp (bit_and @0 { wide_int_to_tree (type1, newmask); } ) + { wide_int_to_tree (type1, cst1 | cst2); } ) + { constant_boolean_node (cmp == NE_EXPR, type); }))))) + /* Fold (A & ~B) - (A & B) into (A ^ B) - B. */ (simplify (minus (bit_and:cs @0 (bit_not @1)) (bit_and:cs @0 @1)) Index: testsuite/gcc.c-torture/execute/cmpandor-1.c =================================================================== --- testsuite/gcc.c-torture/execute/cmpandor-1.c (nonexistent) +++ testsuite/gcc.c-torture/execute/cmpandor-1.c (working copy) @@ -0,0 +1,91 @@ + +#define NOIPA __attribute__((__noipa__)) + + +#define functiondefine(name, cmp, bitop, v1, v1cmp, v2, v2cmp) \ +int name(int a) NOIPA; \ +int name(int a) \ +{ \ + int b = (a & (v1)) cmp (v1cmp); \ + int c = (a & (v2)) cmp (v2cmp); \ + return b bitop c; \ +} + + +#define func functiondefine +#include "cmpandor-1.h" +#undef func + +struct inputsuse +{ + const char *name; + int (*function)(int); + int input; + int result; +}; + +#define strivify(input) #input + +#define func(name, cmp, bitop, v1, v1cmp, v2, v2cmp) \ +{ \ + "" #name "_" strivify(input), \ + &name, \ + input, \ + ((input) & (v1)) cmp (v1cmp) bitop ((input) & (v2)) cmp (v2cmp) \ +}, + +struct inputsuse values[] = +{ +#define input 0 +#include "cmpandor-1.h" +#undef input + +#define input 1 +#include "cmpandor-1.h" +#undef input + +#define input 2 +#include "cmpandor-1.h" +#undef input + +#define input 3 +#include "cmpandor-1.h" +#undef input + +#define input 4 +#include "cmpandor-1.h" +#undef input + +#define input 5 +#include "cmpandor-1.h" +#undef input + +#define input 7 +#include "cmpandor-1.h" +#undef input + +#define input 12 +#include "cmpandor-1.h" +#undef input + +#define input 15 +#include "cmpandor-1.h" +#undef input + + +}; + +#define SIZEOFARRAY(a) (sizeof(a)/sizeof(a[0])) + +int +main (void) +{ + for(int i = 0; i < SIZEOFARRAY(values); i++) + { + if (values[i].function(values[i].input) != values[i].result) + __builtin_abort (); + + } + +} + Index: testsuite/gcc.c-torture/execute/cmpandor-1.h =================================================================== --- testsuite/gcc.c-torture/execute/cmpandor-1.h (nonexistent) +++ testsuite/gcc.c-torture/execute/cmpandor-1.h (working copy) @@ -0,0 +1,60 @@ + // ((a&3) == 3) & ((a&5) == 5) -> (a&7) == 7 +func(eqand1, ==, &, 3, 3, 5, 5) + // ((a&3) == 3) & ((a&12) == 12) -> (a&15) == 15 +func(eqand2, ==, &, 3, 3, 12, 12) + // ((a&3) == 0) & ((a&5) == 0) -> (a&7) == 0 +func(eqand3, ==, &, 3, 0, 5, 0) + // ((a&3) == 0) & ((a&12) == 0) -> (a&15) == 0 +func(eqand4, ==, &, 3, 0, 12, 0) + // ((a&3) == 3) & ((a&5) == 1) -> (a&7) == 3 +func(eqand5, ==, &, 3, 3, 5, 1) + // ((a&3) == 3) & ((a&5) == 4) -> false // mismatch of bits set +func(eqand6, ==, &, 3, 3, 5, 4) + // ((a&3) == 4) & ((a&5) == 5) -> false // mismatch of bits set in the cmp first +func(eqand7, ==, &, 3, 4, 5, 5) + + // ((a&3) == 3) | ((a&5) == 5) +func(eqor1, ==, |, 3, 3, 5, 5) + // ((a&3) == 3) | ((a&12) == 12) +func(eqor2, ==, |, 3, 3, 12, 12) + // ((a&3) == 3) | ((a&5) == 0) +func(eqor3, ==, |, 3, 0, 5, 0) + // ((a&3) == 0) | ((a&12) == 0) +func(eqor4, ==, |, 3, 0, 12, 0) + // ((a&3) == 3) | ((a&5) == 1) +func(eqor5, ==, |, 3, 3, 5, 1) + // ((a&3) == 3) | ((a&5) == 4) +func(eqor6, ==, |, 3, 3, 5, 4) + // ((a&3) == 4) | ((a&5) == 5) -> ((a&5) == 5) // mismatch of bits set in the cmp first +func(eqor7, ==, |, 3, 4, 5, 5) + + // ((a&3) != 3) | ((a&5) != 5) +func(neand1, !=, &, 3, 3, 5, 5) + // ((a&3) != 3) & ((a&12) != 12) +func(neand2, !=, &, 3, 3, 12, 12) + // ((a&3) != 3) & ((a&5) != 0) +func(neand3, !=, &, 3, 0, 5, 0) + // ((a&3) != 0) & ((a&12) != 0) +func(neand4, !=, &, 3, 0, 12, 0) + // ((a&3) != 3) & ((a&5) != 1) +func(neand5, !=, &, 3, 3, 5, 1) + // ((a&3) != 3) & ((a&5) != 4) +func(neand6, !=, &, 3, 3, 5, 4) + // ((a&3) != 4) & ((a&5) != 5) -> ((a&5) != 5) // mismatch of bits set in the cmp first +func(neand7, !=, &, 3, 4, 5, 5) + + // ((a&3) != 3) | ((a&5) != 5) -> (a&7) != 7 +func(neor1, !=, |, 3, 3, 5, 5) + // ((a&3) != 3) | ((a&12) != 12) -> (a&15) != 15 +func(neor2, !=, |, 3, 3, 12, 12) + // ((a&3) != 0) | ((a&5) != 0) -> (a&7) != 0 +func(neor3, !=, |, 3, 0, 5, 0) + // ((a&3) != 0) | ((a&12) != 0) -> (a&15) != 0 +func(neor4, !=, |, 3, 0, 12, 0) + // ((a&3) != 3) | ((a&5) != 1) -> (a&7) != 3 +func(neor5, !=, |, 3, 3, 5, 1) + // ((a&3) != 3) | ((a&5) != 4) -> true // mismatch of bits set +func(neor6, !=, |, 3, 3, 5, 4) +// ((a&3) != 4) | ((a&5) != 5) -> true // mismatch of bits set in the cmp first +func(neor7, !=, |, 3, 4, 5, 5) + Index: testsuite/gcc.dg/tree-ssa/eqand-1.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqand-1.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqand-1.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) & ((a&5) == 5) -> (a&7) == 7 +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&5) == 5); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 7" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 5" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqand-2.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqand-2.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqand-2.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) & ((a&12) == 12) -> (a&15) == 15 +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&12) == 12); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 15" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 12" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 12" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqand-3.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqand-3.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqand-3.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 0) & ((a&5) == 0) -> (a&7) == 0 +int f(int a) +{ + int b = ((a&3) == 0); + int c = ((a&5) == 0); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 0" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqand-4.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqand-4.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqand-4.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 0) & ((a&12) == 0) -> (a&15) == 0 +int f(int a) +{ + int b = ((a&3) == 0); + int c = ((a&12) == 0); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 0" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 12" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqand-5.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqand-5.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqand-5.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) & ((a&5) == 1) -> (a&7) == 3 +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&5) == 1); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 1" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqand-6.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqand-6.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqand-6.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) & ((a&5) == 4) -> false // mismatch of bits set +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&5) == 4); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 4" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqand-7.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqand-7.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqand-7.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 4) & ((a&5) == 5) -> false // mismatch of bits set in the cmp first +int f(int a) +{ + int b = ((a&3) == 4); + int c = ((a&5) == 5); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 4" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 5" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqor-1.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqor-1.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqor-1.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) | ((a&5) == 5) +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&5) == 5); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 7" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 5" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqor-2.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqor-2.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqor-2.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) | ((a&12) == 12) +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&12) == 12); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 15" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 12" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 12" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqor-3.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqor-3.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqor-3.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) | ((a&5) == 0) +int f(int a) +{ + int b = ((a&3) == 0); + int c = ((a&5) == 0); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 0" 2 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqor-4.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqor-4.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqor-4.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 0) | ((a&12) == 0) +int f(int a) +{ + int b = ((a&3) == 0); + int c = ((a&12) == 0); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 12" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 0" 2 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqor-5.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqor-5.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqor-5.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) | ((a&5) == 1) +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&5) == 1); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 1" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqor-6.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqor-6.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqor-6.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 3) | ((a&5) == 4) +int f(int a) +{ + int b = ((a&3) == 3); + int c = ((a&5) == 4); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "return 0" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 4" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/eqor-7.c =================================================================== --- testsuite/gcc.dg/tree-ssa/eqor-7.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/eqor-7.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) == 4) | ((a&5) == 5) -> ((a&5) == 5) // mismatch of bits set in the cmp first +int f(int a) +{ + int b = ((a&3) == 4); + int c = ((a&5) == 5); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "return 0" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 4" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 5" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neand-1.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neand-1.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neand-1.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) | ((a&5) != 5) +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&5) != 5); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 7" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 5" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neand-2.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neand-2.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neand-2.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) & ((a&12) != 12) +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&12) != 12); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 15" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 12" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 12" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neand-3.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neand-3.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neand-3.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) & ((a&5) != 0) +int f(int a) +{ + int b = ((a&3) != 0); + int c = ((a&5) != 0); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 0" 2 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neand-4.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neand-4.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neand-4.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 0) & ((a&12) != 0) +int f(int a) +{ + int b = ((a&3) != 0); + int c = ((a&12) != 0); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 0" 2 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neand-5.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neand-5.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neand-5.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) & ((a&5) != 1) +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&5) != 1); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 1" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neand-6.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neand-6.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neand-6.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) & ((a&5) != 4) +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&5) != 4); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "return 0" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 3" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 4" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neand-7.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neand-7.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neand-7.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 4) & ((a&5) != 5) -> ((a&5) != 5) // mismatch of bits set in the cmp first +int f(int a) +{ + int b = ((a&3) != 4); + int c = ((a&5) != 5); + return b & c; + +} + +/* { dg-final { scan-tree-dump-times "return 0" 0 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 4" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 5" 1 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neor-1.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neor-1.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neor-1.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) | ((a&5) != 5) -> (a&7) != 7 +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&5) != 5); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 7" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 5" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neor-2.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neor-2.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neor-2.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) | ((a&12) != 12) -> (a&15) != 15 +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&12) != 12); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 15" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 12" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 12" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neor-3.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neor-3.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neor-3.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 0) | ((a&5) != 0) -> (a&7) != 0 +int f(int a) +{ + int b = ((a&3) != 0); + int c = ((a&5) != 0); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 0" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neor-4.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neor-4.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neor-4.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 0) | ((a&12) != 0) -> (a&15) != 0 +int f(int a) +{ + int b = ((a&3) != 0); + int c = ((a&12) != 0); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 15" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 0" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neor-5.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neor-5.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neor-5.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) | ((a&5) != 1) -> (a&7) != 3 +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&5) != 1); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "& 7" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 3" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "!= 1" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neor-6.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neor-6.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neor-6.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + + // ((a&3) != 3) | ((a&5) != 4) -> true // mismatch of bits set +int f(int a) +{ + int b = ((a&3) != 3); + int c = ((a&5) != 4); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "return 1" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 4" 0 "optimized" } } */ Index: testsuite/gcc.dg/tree-ssa/neor-7.c =================================================================== --- testsuite/gcc.dg/tree-ssa/neor-7.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/neor-7.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + +// ((a&3) != 4) | ((a&5) != 5) -> true // mismatch of bits set in the cmp first +int f(int a) +{ + int b = ((a&3) != 4); + int c = ((a&5) != 5); + return b | c; + +} + +/* { dg-final { scan-tree-dump-times "return 1" 1 "optimized" } } */ + +/* { dg-final { scan-tree-dump-times "& 3" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 4" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "& 5" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "== 5" 0 "optimized" } } */