On Tue, Oct 21, 2025 at 5:19 AM Andrew Pinski <[email protected]> wrote: > > This copies the optimization which was done to fix PR 95699 to match > detection of MIN/MAX > from minmax_replacement to match. > This is another step in getting rid of minmax_replacement in phiopt. There > are still a few > more min/max detections that needs to be handled before the removal. > pr101024-1.c adds one > example of that but since the testcase currently passes I didn't xfail it. > > pr110068-1.c adds a testcase which was not detected beforehand either. > > Changes since v1: > * v2: Fix comment about how it is transformed. > Use SIGNED_TYPE_MIN everywhere instead of mxing in SIGNED_TYPE_MAX too.
OK. > Bootstrapped and tested on x86_64-linux-gnu. > > PR tree-optimization/95699 > PR tree-optimization/101024 > PR tree-optimization/110068 > > gcc/ChangeLog: > > * match.pd (`(type1)x CMP CST1 ? (type2)x : CST2`): Treat > `(signed)x </>= 0` as `x >=/< SIGNED_TYPE_MIN` > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/pr101024-1.c: New test. > * gcc.dg/tree-ssa/pr110068-1.c: New test. > > Signed-off-by: Andrew Pinski <[email protected]> > --- > gcc/match.pd | 21 ++++++++++-- > gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c | 39 ++++++++++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c | 22 ++++++++++++ > 3 files changed, 80 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index bfc51e6579a..a4248a521cf 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -6571,6 +6571,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > tree from_type = TREE_TYPE (@1); > tree c1_type = TREE_TYPE (@3), c2_type = TREE_TYPE (@2); > enum tree_code code = ERROR_MARK; > + enum tree_code ncmp = cmp; > + tree c1 = @3; > + > + /* `((signed)a) < 0` should be converted back into > + `a >= (unsigned)SIGNED_TYPE_MIN`. > + `((signed)a) >= 0` should be converted back into > + `a < (unsigned)SIGNED_TYPE_MIN`. */ > + if (integer_zerop (c1) > + && (cmp == GE_EXPR || cmp == LT_EXPR) > + && TYPE_UNSIGNED (from_type) > + && !TYPE_UNSIGNED (c1_type) > + && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type)) > + { > + ncmp = cmp == GE_EXPR ? LT_EXPR : GE_EXPR; > + c1 = fold_convert (from_type, TYPE_MIN_VALUE (c1_type)); > + c1_type = from_type; > + } > > if (INTEGRAL_TYPE_P (from_type) > && int_fits_type_p (@2, from_type) > @@ -6583,8 +6600,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > && (TYPE_UNSIGNED (from_type) > || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) > { > - if (cmp != EQ_EXPR) > - code = minmax_from_comparison (cmp, @1, @3, @1, @2); > + if (ncmp != EQ_EXPR) > + code = minmax_from_comparison (ncmp, @1, c1, @1, @2); > /* Can do A == C1 ? A : C2 -> A == C1 ? C1 : C2? */ > else if (int_fits_type_p (@3, from_type)) > code = EQ_EXPR; > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c > new file mode 100644 > index 00000000000..14379bf3b6a > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c > @@ -0,0 +1,39 @@ > +/* PR tree-optimization/95699 */ > +/* PR tree-optimization/101024 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-phiopt1" } */ > +unsigned long long > +f2 (unsigned long long x) > +{ > + if (x < 0x8000000000000000ULL) > + x = 0x8000000000000000ULL; > + else > + { > + if (x >= 0x8000000000000023ULL) > + x = 0x8000000000000023ULL; > + } > + return x; > +} > +unsigned long long > +f1 (unsigned long long x) > +{ > + if (x >= 100) > + { > + if (x >= 0x8000000000000000ULL) > + x = 0x8000000000000000ULL; > + } > + else > + x = 100; > + return x; > +} > +/* f2: */ > +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775843>" > "optimized" } } */ > +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*9223372036854775808>" > "optimized" } } */ > +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775843>" > "phiopt1" } } */ > +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*9223372036854775808>" > "phiopt1" } } */ > + > +/* f1: */ > +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775808>" > "optimized" } } */ > +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*100>" "optimized" } } */ > +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775808>" > "phiopt1" } } */ > +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*100>" "phiopt1" } } */ > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c > new file mode 100644 > index 00000000000..df88553474c > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c > @@ -0,0 +1,22 @@ > +/* PR tree-optimization/95699 */ > +/* PR tree-optimization/110068 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-phiopt1" } */ > +/* { dg-final { scan-tree-dump-times "MIN_EXPR " 2 "phiopt1" } } */ > + > +#define min1(x,y) ((x) < (y) ? (x) : (y)) > +unsigned > +f1 (unsigned x) > +{ > + return min1(x, 1U<<(sizeof(x)*8-1)); > +} > +unsigned > +f5 (unsigned x) > +{ > + bool t = x >= 1U<<(sizeof(x)*8-1); > + if (!t) > + ; > + else > + x = 1U<<(sizeof(x)*8-1); > + return x; > +} > -- > 2.43.0 >
