https://gcc.gnu.org/g:a4e033fb51d566019f8605d132f81bf66037b811
commit r16-4585-ga4e033fb51d566019f8605d132f81bf66037b811 Author: Andrew Pinski <[email protected]> Date: Wed Oct 22 15:46:03 2025 -0700 match: improve handling of `((signed)x) < 0` to `x >= (unsigned)SIGNED_TYPE_MIN` in `(type1)x CMP CST1 ? (type2)x : CST2` pattern. This is a follow on r16-4534-g07800a565abd20 based on the review of the other pattern (https://gcc.gnu.org/pipermail/gcc-patches/2025-October/698336.html) as the same issue mentioned in that review apply here. This changes to use the new version of minmax_from_comparison so we don't need to create a tree for the constant. and use wi::mask instead of TYPE_MIN_VALUE. gcc/ChangeLog: * match.pd (`(type1)x CMP CST1 ? (type2)x : CST2`): Better handling of `((signed)x) < 0`. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/match.pd | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index d00b925416ae..4c05fe2c1a6d 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6592,25 +6592,30 @@ 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) + if (integer_zerop (@3) + && INTEGRAL_TYPE_P (from_type) && (cmp == GE_EXPR || cmp == LT_EXPR) && TYPE_UNSIGNED (from_type) && !TYPE_UNSIGNED (c1_type) - && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type)) + && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type) + && int_fits_type_p (@2, from_type) + && (types_match (c2_type, from_type) + || (TYPE_PRECISION (c2_type) > TYPE_PRECISION (from_type) + && (TYPE_UNSIGNED (from_type) + || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) { - ncmp = cmp == GE_EXPR ? LT_EXPR : GE_EXPR; - c1 = fold_convert (from_type, TYPE_MIN_VALUE (c1_type)); - c1_type = from_type; + tree_code ncmp = cmp == GE_EXPR ? LE_EXPR : GT_EXPR; + widest_int c1 = wi::mask<widest_int>(TYPE_PRECISION (type) - 1, 0); + code = minmax_from_comparison (ncmp, @1, c1, wi::to_widest (@2)); } - if (INTEGRAL_TYPE_P (from_type) + if (code == ERROR_MARK + && INTEGRAL_TYPE_P (from_type) && int_fits_type_p (@2, from_type) && (types_match (c1_type, from_type) || (TYPE_PRECISION (c1_type) > TYPE_PRECISION (from_type) @@ -6621,8 +6626,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (TYPE_UNSIGNED (from_type) || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) { - if (ncmp != EQ_EXPR) - code = minmax_from_comparison (ncmp, @1, c1, @1, @2); + if (cmp != EQ_EXPR) + code = minmax_from_comparison (cmp, @1, @3, @1, @2); /* Can do A == C1 ? A : C2 -> A == C1 ? C1 : C2? */ else if (int_fits_type_p (@3, from_type)) code = EQ_EXPR;
