[PUSHED] match: Fix min/max patterns for `((signed)a) < 0` [PR126458]

Andrea Pinski <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
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]>
---
 gcc/match.pd                              |  2 +-
 gcc/testsuite/gcc.dg/torture/pr126458-1.c | 36 +++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr126458-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 9669a22ef68..4860d98dcfc 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6610,7 +6610,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 00000000000..f57410c6573
--- /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;
+}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.