diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d385e334bf7..de6db6dd5e6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-11-16 Patrick Palka + + 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 * ipa-polymorphic-call.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 87cb8d8c191..4ddc713a37e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-11-16 Patrick Palka + + 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 * gcc.c-torture/execute/memset-4.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-29.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-29.c new file mode 100644 index 00000000000..df5334e2d07 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-29.c @@ -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); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c index 251b84e82ef..1ff18205536 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c @@ -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" } } */ diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index d42dcf891a9..5b8c10e8f8e 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -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; }