diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 036a4030308..fae7ece376a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,8 @@ 2020-05-04 Jakub Jelinek + PR tree-optimization/94718 + * match.pd ((X < 0) != (Y < 0) into (X ^ Y) < 0): New simplification. + PR tree-optimization/94718 * match.pd (bitop (convert @0) (convert? @1)): For GIMPLE, if we can, replace two nop conversions on bit_{and,ior,xor} argument diff --git a/gcc/match.pd b/gcc/match.pd index 929be14e8b7..9c1e23984d6 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4358,6 +4358,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cmp (bit_and:cs @0 @2) (bit_and:cs @1 @2)) (cmp (bit_and (bit_xor @0 @1) @2) { build_zero_cst (TREE_TYPE (@2)); }))) +/* (X < 0) != (Y < 0) into (X ^ Y) < 0. + (X >= 0) != (Y >= 0) into (X ^ Y) < 0. + (X < 0) == (Y < 0) into (X ^ Y) >= 0. + (X >= 0) == (Y >= 0) into (X ^ Y) >= 0. */ +(for cmp (eq ne) + ncmp (ge lt) + (for sgncmp (ge lt) + (simplify + (cmp (sgncmp @0 integer_zerop@2) (sgncmp @1 integer_zerop)) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && types_match (@0, @1)) + (ncmp (bit_xor @0 @1) @2))))) +/* (X < 0) == (Y >= 0) into (X ^ Y) < 0. + (X < 0) != (Y >= 0) into (X ^ Y) >= 0. */ +(for cmp (eq ne) + ncmp (lt ge) + (simplify + (cmp:c (lt @0 integer_zerop@2) (ge @1 integer_zerop)) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && types_match (@0, @1)) + (ncmp (bit_xor @0 @1) @2)))) + /* If we have (A & C) == C where C is a power of 2, convert this into (A & C) != 0. Similarly for NE_EXPR. */ (for cmp (eq ne) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 09979b5749c..2fedff399fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2020-05-04 Jakub Jelinek + PR tree-optimization/94718 + * gcc.dg/tree-ssa/pr94718-4.c: New test. + * gcc.dg/tree-ssa/pr94718-5.c: New test. + PR tree-optimization/94718 * gcc.dg/tree-ssa/pr94718-3.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c new file mode 100644 index 00000000000..8b9c109a0e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c @@ -0,0 +1,61 @@ +/* PR tree-optimization/94718 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[0-9]+ < 0;" 8 "optimized" } } */ + +int +f1 (int x, int y) +{ + return (x < 0) != (y < 0); +} + +int +f2 (int x, int y) +{ + return (x >= 0) != (y >= 0); +} + +int +f3 (int x, int y) +{ + return (x < 0) == (y >= 0); +} + +int +f4 (int x, int y) +{ + return (x >= 0) == (y < 0); +} + +int +f5 (int x, int y) +{ + int s = (x < 0); + int t = (y < 0); + return s != t; +} + +int +f6 (int x, int y) +{ + int s = (x >= 0); + int t = (y >= 0); + return s != t; +} + +int +f7 (int x, int y) +{ + int s = (x < 0); + int t = (y >= 0); + return s == t; +} + +int +f8 (int x, int y) +{ + int s = (x >= 0); + int t = (y < 0); + return s == t; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c new file mode 100644 index 00000000000..4bd37327499 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c @@ -0,0 +1,61 @@ +/* PR tree-optimization/94718 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[0-9]+ >= 0;" 8 "optimized" } } */ + +int +f1 (int x, int y) +{ + return (x < 0) == (y < 0); +} + +int +f2 (int x, int y) +{ + return (x >= 0) == (y >= 0); +} + +int +f3 (int x, int y) +{ + return (x < 0) != (y >= 0); +} + +int +f4 (int x, int y) +{ + return (x >= 0) != (y < 0); +} + +int +f5 (int x, int y) +{ + int s = (x < 0); + int t = (y < 0); + return s == t; +} + +int +f6 (int x, int y) +{ + int s = (x >= 0); + int t = (y >= 0); + return s == t; +} + +int +f7 (int x, int y) +{ + int s = (x < 0); + int t = (y >= 0); + return s != t; +} + +int +f8 (int x, int y) +{ + int s = (x >= 0); + int t = (y < 0); + return s != t; +}