[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