With r14-2299-g71b68cc559b5d3, the removal of prefering
the unsigned type was removed.  This will cause wrong
code with the boundary condition of the unsigned values
of `INT_MAX` and `INT_MAX+1` in some cases.

This adds back the prefering of unsigned types when
the types precisions are the same.  Fixing the issue as
we do the subtraction now in unsigned type; avoiding the
undefined overflow.

Pushed as obvious after a bootstrap/test on x86_64-linux-gnu.

        PR tree-optimization/127358

gcc/ChangeLog:

        * match.pd (two_value cond): Prefer unsigned types.

gcc/testsuite/ChangeLog:

        * gcc.dg/torture/pr127358-1.c: New test.

Signed-off-by: Andrea Pinski <[email protected]>
---
 gcc/match.pd                              |  6 +++++-
 gcc/testsuite/gcc.dg/torture/pr127358-1.c | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr127358-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 81734b73a7d..093b5cbefa7 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6973,12 +6973,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        tree type1;
        if ((eqne == EQ_EXPR) ^ (wi::to_wide (@1) == min))
          std::swap (arg0, arg1);
-       if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type))
+       if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)
+           // Prefer unsigned type if the two has the same precision.
+           || (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type)
+               && !TYPE_UNSIGNED (type)))
         type1 = TREE_TYPE (@0);
        else
         type1 = type;
        auto prec = TYPE_PRECISION (type1);
        auto unsign = TYPE_UNSIGNED (type1);
+       // For boolean types, use an integer type for the plus/minus.
        if (TREE_CODE (type1) == BOOLEAN_TYPE)
        type1 = build_nonstandard_integer_type (prec, unsign);
        min = wide_int::from (min, prec,
diff --git a/gcc/testsuite/gcc.dg/torture/pr127358-1.c 
b/gcc/testsuite/gcc.dg/torture/pr127358-1.c
new file mode 100644
index 00000000000..0e403e3471d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr127358-1.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* PR tree-optimization/127358 */
+
+__attribute__((noipa))
+int compute(unsigned x){
+  unsigned max = __INT_MAX__;
+  if (x != __INT_MAX__
+      && x != (((unsigned)__INT_MAX__)+1))
+    __builtin_unreachable();
+  int r = (x == max) ? 5 : 6;
+  return r;
+}
+
+int main(void){
+  volatile unsigned a = __INT_MAX__;
+  volatile unsigned b = a+1;
+  if (compute(a) != 5)
+    __builtin_abort ();
+  if (compute(b) != 6)
+    __builtin_abort ();
+  return 0;
+}
+
-- 
2.43.0

Reply via email to