Always combine comparisons or conversions from booleans.

2014-11-16  Patrick Palka  <ppalka@gcc.gnu.org>

gcc/
	PR middle-end/63790
	* tree-ssa-forwprop.c (forward_propagate_into_comparison_1):
	Always combine comparisons or conversions from booleans.

gcc/testsuite/
	PR middle-end/63790
	* gcc.dg/tree-ssa/pr21031.c: Drop XFAIL.
	* gcc.dg/tree-ssa/forwprop-29.c: New test.

From-SVN: r217638
This commit is contained in:
Patrick Palka 2014-11-17 02:01:36 +00:00
parent 6e2826178d
commit c1c7f1fc21
5 changed files with 57 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2014-11-16 Patrick Palka <ppalka@gcc.gnu.org>
PR middle-end/63790
* tree-ssa-forwprop.c (forward_propagate_into_comparison_1):
Always combine comparisons or conversions from booleans.
2014-11-16 Jan Hubicka <hubicka@ucw.cz>
* ipa-polymorphic-call.c

View File

@ -1,3 +1,9 @@
2014-11-16 Patrick Palka <ppalka@gcc.gnu.org>
PR middle-end/63790
* gcc.dg/tree-ssa/pr21031.c: Drop XFAIL.
* gcc.dg/tree-ssa/forwprop-29.c: New test.
2014-11-16 Andrew Pinski <apinski@cavium.com>
* gcc.c-torture/execute/memset-4.c: New test.

View File

@ -0,0 +1,31 @@
/* { dg-options "-O2" } */
void runtime_error (void) __attribute__ ((noreturn));
void compiletime_error (void) __attribute__ ((noreturn, error ("")));
static void
compiletime_check_equals_1 (int *x, int y)
{
int __p = *x != y;
if (__builtin_constant_p (__p) && __p)
compiletime_error ();
if (__p)
runtime_error ();
}
static void
compiletime_check_equals_2 (int *x, int y)
{
int __p = *x != y;
if (__builtin_constant_p (__p) && __p)
compiletime_error (); /* { dg-error "call to" } */
if (__p)
runtime_error ();
}
void
foo (int *x)
{
compiletime_check_equals_1 (x, 5);
compiletime_check_equals_2 (x, 10);
}

View File

@ -16,5 +16,5 @@ foo (int a)
return 0;
}
/* { dg-final { scan-tree-dump-times "Replaced" 2 "forwprop1" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "Replaced" 2 "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */

View File

@ -442,9 +442,21 @@ forward_propagate_into_comparison_1 (gimple stmt,
gimple def_stmt = get_prop_source_stmt (op0, false, &single_use0_p);
if (def_stmt && can_propagate_from (def_stmt))
{
enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
bool invariant_only_p = !single_use0_p;
rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
/* Always combine comparisons or conversions from booleans. */
if (TREE_CODE (op1) == INTEGER_CST
&& ((CONVERT_EXPR_CODE_P (def_code)
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs0, 0)))
== BOOLEAN_TYPE)
|| TREE_CODE_CLASS (def_code) == tcc_comparison))
invariant_only_p = false;
tmp = combine_cond_expr_cond (stmt, code, type,
rhs0, op1, !single_use0_p);
rhs0, op1, invariant_only_p);
if (tmp)
return tmp;
}