[gcc r17-2854] match: Fix min/max patterns for `((signed)a) < 0` [PR126458]

Andrea Pinski via Gcc-cvs <[email protected]> Fri, 31 Jul 2026 16:30:30 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:667c1b70ac3955c9ac7ccab60cc10b32d4bed5ff

commit r17-2854-g667c1b70ac3955c9ac7ccab60cc10b32d4bed5ff
Author: Andrea Pinski <[email protected]>
Date:   Thu Jul 30 21:06:31 2026 -0700

    match: Fix min/max patterns for `((signed)a) < 0` [PR126458]
    
    In r16-4585-ga4e033fb51d566, I accidently used the wrong type
    to form SIGNED_TYPE_MIN. This was ok most of the time except
    if the two types differ only by one precision. When they diff
    by one precision, we would incorrectly detect the wrong thing
    and think it should be a min/max.  This fixes the problem
    by using the precision of the constant (0) rather then the final
    type.
    
    Pushed as obvious after a bootstrap/test on x86_64-linux-gnu.
    
            PR tree-optimization/126458
    
    gcc/ChangeLog:
    
            * match.pd (min/max detection): Fix precision of
            the signed type min.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr126458-1.c: New test.
    
    Signed-off-by: Andrea Pinski <[email protected]>

Diff:
---
 gcc/match.pd                              |  2 +-
 gcc/testsuite/gcc.dg/torture/pr126458-1.c | 36 +++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index dd223dc45539..2541b898d2e6 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6609,7 +6609,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 		     || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type)))))
 	{
 	  tree_code ncmp = cmp == GE_EXPR ? LE_EXPR : GT_EXPR;
-	  widest_int c1 = wi::mask<widest_int>(TYPE_PRECISION (type) - 1, 0);
+	  widest_int c1 = wi::mask<widest_int>(TYPE_PRECISION (c1_type) - 1, 0);
 	  code = minmax_from_comparison (ncmp, @1, c1, wi::to_widest (@2));
 	}
 
diff --git a/gcc/testsuite/gcc.dg/torture/pr126458-1.c b/gcc/testsuite/gcc.dg/torture/pr126458-1.c
new file mode 100644
index 000000000000..f57410c6573e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr126458-1.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target bitint } } */
+/* PR tree-optimization/126458 */
+
+typedef unsigned _BitInt(17) u17;
+typedef unsigned _BitInt(16) u16;
+typedef unsigned _BitInt(15) u15;
+typedef signed _BitInt(16) s16;
+
+__attribute__((noipa)) int
+neg (u16 a)
+{
+  return ((s16) a) < 0;
+}
+
+__attribute__((noipa)) u17
+fref (u16 a)
+{
+  return neg (a) ? (u17) a : (u17)(u16) -1u;
+}
+
+__attribute__((noipa)) u17
+f (u16 a)
+{
+  return ((s16) a) < 0 ? (u17) a : (u17)(u16) -1u;
+}
+
+int
+main (void)
+{
+  static const u16 v[] = { ((u16)1u)<<15 , (u16)-2u, (u16)-1u, (u16)(u15)-1u, 0u };
+
+  for (unsigned i = 0; i < sizeof v / sizeof v[0]; i++)
+    if (f (v[i]) != fref (v[i]))
+      __builtin_abort ();
+  return 0;
+}