public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fix PR middle-end/82062
@ 2017-10-25 21:58 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2017-10-25 21:58 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1185 bytes --]

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

[-- Attachment #2: pr82062.diff --]
[-- Type: text/x-patch, Size: 1916 bytes --]

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
 }
 \f
-/* 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)

[-- Attachment #3: fold-cond-3.c --]
[-- Type: text/x-csrc, Size: 751 bytes --]

/* { 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"} } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-10-25 21:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-25 21:58 Fix PR middle-end/82062 Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).