When `b` is known to be non-negative, the sign of both `MIN (a, b)`
and `a | b` depends only on the sign of `a`. Add patterns to match.pd
to optimize `MIN (a, b) cmp 0` and `(a | b) cmp 0` into `a cmp 0`,
where `cmp` is `<` or `>=`. Currently, `(a | b) cmp 0` is optimized
at the RTL level for some targets, but simplifying earlier is
preferable.
PR tree-optimization/126087
gcc/ChangeLog:
* match.pd: Simplify MIN and BIT_IOR compared to 0 when
one operand is non-negative.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr126087.c: New test.
Signed-off-by: Neal Patalay <[email protected]>
---
Bootstrapped and regression tested on x86_64-pc-linux-gnu with no
regressions.
If this patch is approved, could someone please commit it and update
PR126087 for me?
gcc/match.pd | 16 +++++++++++
gcc/testsuite/gcc.dg/tree-ssa/pr126087.c | 36 ++++++++++++++++++++++++
2 files changed, 52 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126087.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 9d4ab622fe5..5c8d1cc1b52 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4831,6 +4831,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cmp (bit_ior (convert:utype @0) (convert:utype @1))
{ build_zero_cst (utype); } ))))
+/* Optimize MIN (a, b) >= 0 to a >= 0 if b is non-negative.
+ Optimize MIN (a, b) < 0 to a < 0 if b is non-negative. */
+(for cmp (ge lt)
+ (simplify
+ (cmp (min:c @0 @1) integer_zerop@2)
+ (if (tree_expr_nonnegative_p (@1))
+ (cmp @0 @2))))
+
/* Undo fancy ways of writing max/min or other ?: expressions, like
a - ((a - b) & -(a < b)) and a - (a - b) * (a < b) into (a < b) ? b : a.
People normally use ?: and that is what we actually try to optimize. */
@@ -6900,6 +6908,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
@2))
#endif
+/* Optimize (a | b) >= 0 to a >= 0 if b is non-negative.
+ Optimize (a | b) < 0 to a < 0 if b is non-negative. */
+(for cmp (ge lt)
+ (simplify
+ (cmp (bit_ior:c @0 @1) integer_zerop@2)
+ (if (tree_expr_nonnegative_p (@1))
+ (cmp @0 @2))))
+
/* These was part of minmax phiopt. */
/* Optimize (a CMP b) ? minmax<a, c> : minmax<b, c>
to minmax<min/max<a, b>, c> */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126087.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr126087.c
new file mode 100644
index 00000000000..308a5096c42
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126087.c
@@ -0,0 +1,36 @@
+/* PR tree-optimization/126087 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void use();
+
+void f2(int a, unsigned short bb) {
+ int b = bb;
+ int m = a < b ? a : b;
+ if (m >= 0)
+ use();
+}
+
+void f3(int a, unsigned short bb) {
+ int b = bb;
+ int m = a | b;
+ if (m >= 0)
+ use();
+}
+
+void f4(int a, unsigned short bb) {
+ int b = bb;
+ int m = a < b ? a : b;
+ if (m < 0)
+ use();
+}
+
+void f5(int a, unsigned short bb) {
+ int b = bb;
+ int m = a | b;
+ if (m < 0)
+ use();
+}
+
+/* { dg-final { scan-tree-dump-not "MIN_EXPR" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\| " "optimized" } } */
--
2.55.0