aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-eh.c
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2019-10-07 14:59:00 +0000
committerIlya Leoshkevich <iii@gcc.gnu.org>2019-10-07 14:59:00 +0000
commit70e2a30ac8f474feefbcc392cbc59cf91271b92b (patch)
tree3302596f71ab0b28e68060f10d0b68451d44590c /gcc/tree-eh.c
parent880dcdaedac453d2c64ebcc6f1bb5f81539c863c (diff)
downloadgcc-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/tree-eh.c')
-rw-r--r--gcc/tree-eh.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 1aba733..7a02873 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2523,6 +2523,10 @@ operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv,
bool honor_snans = fp_operation && flag_signaling_nans != 0;
bool handled;
+ /* This function cannot tell whether or not COND_EXPR and VEC_COND_EXPR could
+ trap, because that depends on the respective condition op. */
+ gcc_assert (op != COND_EXPR && op != VEC_COND_EXPR);
+
if (TREE_CODE_CLASS (op) != tcc_comparison
&& TREE_CODE_CLASS (op) != tcc_unary
&& TREE_CODE_CLASS (op) != tcc_binary)
@@ -2610,6 +2614,10 @@ tree_could_trap_p (tree expr)
if (!expr)
return false;
+ /* For COND_EXPR and VEC_COND_EXPR only the condition may trap. */
+ if (TREE_CODE (expr) == COND_EXPR || TREE_CODE (expr) == VEC_COND_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
code = TREE_CODE (expr);
t = TREE_TYPE (expr);