diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2019-10-07 14:59:00 +0000 |
---|---|---|
committer | Ilya Leoshkevich <iii@gcc.gnu.org> | 2019-10-07 14:59:00 +0000 |
commit | 70e2a30ac8f474feefbcc392cbc59cf91271b92b (patch) | |
tree | 3302596f71ab0b28e68060f10d0b68451d44590c /gcc/gimple-expr.c | |
parent | 880dcdaedac453d2c64ebcc6f1bb5f81539c863c (diff) | |
download | gcc-70e2a30ac8f474feefbcc392cbc59cf91271b92b.zip gcc-70e2a30ac8f474feefbcc392cbc59cf91271b92b.tar.gz gcc-70e2a30ac8f474feefbcc392cbc59cf91271b92b.tar.bz2 |
Allow COND_EXPR and VEC_COND_EXPR condtions to trap
Right now gimplifier does not allow VEC_COND_EXPR's condition to trap
and introduces a temporary if this could happen, for example, generating
_5 = _4 > { 2.0e+0, 2.0e+0, 2.0e+0, 2.0e+0 };
_6 = VEC_COND_EXPR <_5, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>;
from GENERIC
VEC_COND_EXPR < (*b > { 2.0e+0, 2.0e+0, 2.0e+0, 2.0e+0 }) ,
{ -1, -1, -1, -1 } ,
{ 0, 0, 0, 0 } >
This is not necessary and makes the resulting GIMPLE harder to analyze.
Change the gimplifier so as to allow COND_EXPR and VEC_COND_EXPR
conditions to trap.
This patch takes special care to avoid introducing trapping comparisons
in GIMPLE_COND. They are not allowed, because they would require 3
outgoing edges (then, else and EH), which is awkward to say the least.
Therefore, computations of such conditions should live in their own basic
blocks.
gcc/ChangeLog:
2019-10-07 Ilya Leoshkevich <iii@linux.ibm.com>
PR target/77918
* gimple-expr.c (gimple_cond_get_ops_from_tree): Assert that the
caller passes a non-trapping condition.
(is_gimple_condexpr): Allow trapping conditions.
(is_gimple_condexpr_1): New helper function.
(is_gimple_condexpr_for_cond): New function, acts like old
is_gimple_condexpr.
* gimple-expr.h (is_gimple_condexpr_for_cond): New function.
* gimple.c (gimple_could_trap_p_1): Handle COND_EXPR and
VEC_COND_EXPR. Fix an issue with statements like i = (fp < 1.).
* gimplify.c (gimplify_cond_expr): Use
is_gimple_condexpr_for_cond.
(gimplify_expr): Allow is_gimple_condexpr_for_cond.
* tree-eh.c (operation_could_trap_p): Assert on COND_EXPR and
VEC_COND_EXPR.
(tree_could_trap_p): Handle COND_EXPR and VEC_COND_EXPR.
* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond): Use
is_gimple_condexpr_for_cond, remove pointless tmp check
(forward_propagate_into_cond): Remove pointless tmp check.
From-SVN: r276659
Diffstat (limited to 'gcc/gimple-expr.c')
-rw-r--r-- | gcc/gimple-expr.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c index 4082828..1738af1 100644 --- a/gcc/gimple-expr.c +++ b/gcc/gimple-expr.c @@ -574,6 +574,7 @@ gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p, || TREE_CODE (cond) == TRUTH_NOT_EXPR || is_gimple_min_invariant (cond) || SSA_VAR_P (cond)); + gcc_checking_assert (!tree_could_throw_p (cond)); extract_ops_from_tree (cond, code_p, lhs_p, rhs_p); @@ -605,17 +606,33 @@ is_gimple_lvalue (tree t) || TREE_CODE (t) == BIT_FIELD_REF); } -/* Return true if T is a GIMPLE condition. */ +/* Helper for is_gimple_condexpr and is_gimple_condexpr_for_cond. */ -bool -is_gimple_condexpr (tree t) +static bool +is_gimple_condexpr_1 (tree t, bool allow_traps) { return (is_gimple_val (t) || (COMPARISON_CLASS_P (t) - && !tree_could_throw_p (t) + && (allow_traps || !tree_could_throw_p (t)) && is_gimple_val (TREE_OPERAND (t, 0)) && is_gimple_val (TREE_OPERAND (t, 1)))); } +/* Return true if T is a GIMPLE condition. */ + +bool +is_gimple_condexpr (tree t) +{ + return is_gimple_condexpr_1 (t, true); +} + +/* Like is_gimple_condexpr, but does not allow T to trap. */ + +bool +is_gimple_condexpr_for_cond (tree t) +{ + return is_gimple_condexpr_1 (t, false); +} + /* Return true if T is a gimple address. */ bool |