Commit c0b24017 by Eric Botcazou

re PR middle-end/82062 (simple conditional expressions no longer folded)

	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.

From-SVN: r254089
parent a2af967e
2017-10-23 Jan Hubicka <hubicka@ucw.cz> 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 Jan Hubicka <hubicka@ucw.cz>
* i386.c (ix86_builtin_vectorization_cost): Compute scatter/gather * i386.c (ix86_builtin_vectorization_cost): Compute scatter/gather
cost correctly. cost correctly.
...@@ -3366,7 +3366,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) ...@@ -3366,7 +3366,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
#undef OP_SAME_WITH_NULL #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 static bool
operand_equal_for_comparison_p (tree arg0, tree arg1) operand_equal_for_comparison_p (tree arg0, tree arg1)
...@@ -3381,9 +3382,20 @@ operand_equal_for_comparison_p (tree arg0, tree arg1) ...@@ -3381,9 +3382,20 @@ operand_equal_for_comparison_p (tree arg0, tree arg1)
/* Discard any conversions that don't change the modes of ARG0 and ARG1 /* 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 and see if the inner values are the same. This removes any
signedness comparison, which doesn't matter here. */ signedness comparison, which doesn't matter here. */
STRIP_NOPS (arg0); tree op0 = arg0;
STRIP_NOPS (arg1); tree op1 = arg1;
if (operand_equal_p (arg0, arg1, 0)) 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 true;
return false; return false;
...@@ -11169,8 +11181,8 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -11169,8 +11181,8 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
Also try swapping the arguments and inverting the conditional. */ Also try swapping the arguments and inverting the conditional. */
if (COMPARISON_CLASS_P (arg0) if (COMPARISON_CLASS_P (arg0)
&& operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), arg1) && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op1)
&& !HONOR_SIGNED_ZEROS (element_mode (arg1))) && !HONOR_SIGNED_ZEROS (element_mode (op1)))
{ {
tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2); tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2);
if (tem) if (tem)
......
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.
2017-10-25 Richard Biener <rguenther@suse.de> 2017-10-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/82436 PR tree-optimization/82436
......
/* { 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"} } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment