https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92644

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
For pointers, it boils down whether say
void *
foo (void *p)
{
  return p ? p : (void *) 1;
}
optimization into MAX_EXPR <1B, p> is valid or not.  The original code doesn't
involve any non-equality comparisons, while MAX_EXPR is a non-equality
comparison which ought to be valid only as long as the two pointers are
pointing into the same object.  Another possibility would be for pointers to do
this optimization, but perform the MIN_EXPR/MAX_EXPR in pointer sized ints
instead.

So, the fix can be either NULLPTR_TYPE specific, like:
--- gcc/tree-ssa-phiopt.c       2019-11-20 09:25:42.552157763 +0100
+++ gcc/tree-ssa-phiopt.c       2019-11-24 18:56:50.657172109 +0100
@@ -1381,7 +1381,8 @@ minmax_replacement (basic_block cond_bb,

   /* Turn EQ/NE of extreme values to order comparisons.  */
   if ((cmp == NE_EXPR || cmp == EQ_EXPR)
-      && TREE_CODE (rhs) == INTEGER_CST)
+      && TREE_CODE (rhs) == INTEGER_CST
+      && TREE_CODE (TREE_TYPE (rhs)) != NULLPTR_TYPE)
     {
       if (wi::eq_p (wi::to_wide (rhs), wi::min_value (TREE_TYPE (rhs))))
        {
@@ -1407,7 +1408,8 @@ minmax_replacement (basic_block cond_bb,
       larger = rhs;
       /* If we have smaller < CST it is equivalent to smaller <= CST-1.
         Likewise smaller <= CST is equivalent to smaller < CST+1.  */
-      if (TREE_CODE (larger) == INTEGER_CST)
+      if (TREE_CODE (larger) == INTEGER_CST
+         && TREE_CODE (TREE_TYPE (larger)) != NULLPTR_TYPE)
        {
          if (cmp == LT_EXPR)
            {
@@ -1435,7 +1437,8 @@ minmax_replacement (basic_block cond_bb,
       larger = gimple_cond_lhs (cond);
       /* If we have larger > CST it is equivalent to larger >= CST+1.
         Likewise larger >= CST is equivalent to larger > CST-1.  */
-      if (TREE_CODE (smaller) == INTEGER_CST)
+      if (TREE_CODE (smaller) == INTEGER_CST
+         && TREE_CODE (TREE_TYPE (larger)) != NULLPTR_TYPE)
        {
          wi::overflow_type overflow;
          if (cmp == GT_EXPR)
or instead of it say && (INTEGRAL_TYPE_P (TREE_TYPE (rhs)) || POINTER_TYPE_P
(TREE_TYPE (rhs))), or just && INTEGRAL_TYPE_P (TREE_TYPE (rhs)), and if
allowing POINTER_TYPE_P, we can also special case
new_stmt = gimple_build_assign (result, minmax, arg0, arg1);
for pointers by casting to integers and back.
Thoughts?

Reply via email to