This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR middle-end/82062


This is the regression in the folding of conditional expressions like

unsigned long f1 (int x)
{
  return x > 0 ? (unsigned long) x : 0;
}

unsigned long f2 (int x, int y)
{
  return x > y ? (unsigned long) x : (unsigned long) y;
}

introduced by the fix for PR middle-end/81814.  These conditional expressions 
are very common in Ada in the size expressions of unconstrained array types.

The attached patch reinstates a limited version of the optimization that was 
disabled by the aforementioned fix.  The long term plan is to move the whole 
thing to match.pd but I'll leave that to specialists.

Bootstrapped/regtested on x86_64-suse-linux, approved by Richard B. in the 
audit trail of the PR, applied on the mainline.


2017-10-25  Eric Botcazou  <ebotcazou@adacore.com>

	PR middle-end/82062
	* fold-const.c (operand_equal_for_comparison_p): Also return true
	if ARG0 is a simple variant of ARG1 with narrower precision.
	(fold_ternary_loc): Always pass unstripped operands to the predicate.


2017-10-25  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.dg/fold-cond_expr-1.c: Rename to...
	* gcc.dg/fold-cond-2.c: ...this.
	* gcc.dg/fold-cond-3.c: New test.

-- 
Eric Botcazou
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 254037)
+++ fold-const.c	(working copy)
@@ -3366,7 +3366,8 @@ operand_equal_p (const_tree arg0, const_
 #undef OP_SAME_WITH_NULL
 }
 
-/* Similar to operand_equal_p, but strip nops first.  */
+/* Similar to operand_equal_p, but see if ARG0 might be a variant of ARG1
+   with a different signedness or a narrower precision.  */
 
 static bool
 operand_equal_for_comparison_p (tree arg0, tree arg1)
@@ -3381,9 +3382,20 @@ operand_equal_for_comparison_p (tree arg
   /* Discard any conversions that don't change the modes of ARG0 and ARG1
      and see if the inner values are the same.  This removes any
      signedness comparison, which doesn't matter here.  */
-  STRIP_NOPS (arg0);
-  STRIP_NOPS (arg1);
-  if (operand_equal_p (arg0, arg1, 0))
+  tree op0 = arg0;
+  tree op1 = arg1;
+  STRIP_NOPS (op0);
+  STRIP_NOPS (op1);
+  if (operand_equal_p (op0, op1, 0))
+    return true;
+
+  /* Discard a single widening conversion from ARG1 and see if the inner
+     value is the same as ARG0.  */
+  if (CONVERT_EXPR_P (arg1)
+      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0)))
+      && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))
+         < TYPE_PRECISION (TREE_TYPE (arg1))
+      && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
     return true;
 
   return false;
@@ -11169,8 +11181,8 @@ fold_ternary_loc (location_t loc, enum t
 
          Also try swapping the arguments and inverting the conditional.  */
       if (COMPARISON_CLASS_P (arg0)
-	  && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), arg1)
-	  && !HONOR_SIGNED_ZEROS (element_mode (arg1)))
+	  && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op1)
+	  && !HONOR_SIGNED_ZEROS (element_mode (op1)))
 	{
 	  tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2);
 	  if (tem)
/* { dg-do compile } */
/* { dg-options "-fdump-tree-original" } */

unsigned long f1 (int x)
{
  return x > 0 ? (unsigned long) x : 0;
}

unsigned long f2 (int x, int y)
{
  return x > y ? (unsigned long) x : (unsigned long) y;
}

unsigned long f3 (int x)
{
  return x < 0 ? (unsigned long) x : 0;
}

unsigned long f4 (int x, int y)
{
  return x < y ? (unsigned long) x : (unsigned long) y;
}

unsigned long f5 (unsigned int x, unsigned int y)
{
  return x > y ? (unsigned long) x : (unsigned long) y;
}

unsigned long f6 (unsigned int x, unsigned int y)
{
  return x < y ? (unsigned long) x : (unsigned long) y;
}

/* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "original"} } */
/* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "original"} } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]