From: Neal Patalay Date: Fri, 17 Jul 2026 11:02:39 +0000 (-0700) Subject: match: Simplify sign tests for MIN and BIT_IOR [PR126087] X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f8eb22d8408b25f337fad514aa8f47fe24f051d9;p=thirdparty%2Fgcc.git match: Simplify sign tests for MIN and BIT_IOR [PR126087] 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 --- diff --git a/gcc/match.pd b/gcc/match.pd index cb8c68bd915..a5870dae46b 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4840,6 +4840,17 @@ 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. + 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 op (min bit_ior) + (for cmp (ge lt) + (simplify + (cmp (op: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. */ 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" } } */