From 2ac47fdf846dae9bfa0598a9efe3f007fc2d9a6c Mon Sep 17 00:00:00 2001 From: rguenth Date: Sun, 18 Jan 2009 15:51:12 +0000 Subject: [PATCH] 2009-01-18 Richard Guenther PR tree-optimization/38819 * tree-flow.h (operation_could_trap_helper_p): Declare. * tree-eh.c (operation_could_trap_helper_p): Export. * tree-ssa-sccvn.h (vn_nary_may_trap): Declare. * tree-ssa-sccvn.c (vn_nary_may_trap): New function. * tree-ssa-pre.c (insert_into_preds_of_block): Check if we are about to insert a possibly trapping instruction and fail in this case. * gcc.c-torture/execute/pr38819.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@143485 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/execute/pr38819.c | 29 +++++++++++++++++ gcc/tree-eh.c | 2 +- gcc/tree-flow.h | 2 ++ gcc/tree-ssa-pre.c | 9 +++++ gcc/tree-ssa-sccvn.c | 47 +++++++++++++++++++++++++++ gcc/tree-ssa-sccvn.h | 1 + 8 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr38819.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 602694cfb5f..1448c0db3a8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-01-18 Richard Guenther + + PR tree-optimization/38819 + * tree-flow.h (operation_could_trap_helper_p): Declare. + * tree-eh.c (operation_could_trap_helper_p): Export. + * tree-ssa-sccvn.h (vn_nary_may_trap): Declare. + * tree-ssa-sccvn.c (vn_nary_may_trap): New function. + * tree-ssa-pre.c (insert_into_preds_of_block): Check if we + are about to insert a possibly trapping instruction and fail + in this case. + 2009-01-18 Andreas Schwab * doc/install.texi (Configuration): Remove obsolete paragraph diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 74d88f1128e..43fe9a9396b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-01-18 Richard Guenther + + PR tree-optimization/38819 + * gcc.c-torture/execute/pr38819.c: New testcase. + 2009-01-17 Paul Thomas PR fortran/38657 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr38819.c b/gcc/testsuite/gcc.c-torture/execute/pr38819.c new file mode 100644 index 00000000000..91ae7d82b7c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr38819.c @@ -0,0 +1,29 @@ +extern void exit (int); +extern void abort (void); + +volatile int a = 1; +volatile int b = 0; +volatile int x = 2; +volatile signed int r = 8; + +void __attribute__((noinline)) +foo (void) +{ + exit (0); +} + +int +main (void) +{ + int si1 = a; + int si2 = b; + int i; + + for (i = 0; i < 100; ++i) { + foo (); + if (x == 8) + i++; + r += i + si1 % si2; + } + abort (); +} diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 5fe8f24ed27..4e95cf3d66d 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2067,7 +2067,7 @@ verify_eh_edges (gimple stmt) /* Helper function for operation_could_trap_p and stmt_could_throw_p. */ -static bool +bool operation_could_trap_helper_p (enum tree_code op, bool fp_operation, bool honor_trapv, diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 46578629673..96c098ec376 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -1071,6 +1071,8 @@ static inline bool unmodifiable_var_p (const_tree); /* In tree-eh.c */ extern void make_eh_edges (gimple); extern bool tree_could_trap_p (tree); +extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool, + bool, tree, bool *); extern bool operation_could_trap_p (enum tree_code, bool, bool, tree); extern bool stmt_could_throw_p (gimple); extern bool tree_could_throw_p (tree); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 0a4fb6ddc10..0717a366bf3 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3004,6 +3004,15 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, } } + /* Make sure we are not inserting trapping expressions. */ + FOR_EACH_EDGE (pred, ei, block->preds) + { + bprime = pred->src; + eprime = avail[bprime->index]; + if (eprime->kind == NARY + && vn_nary_may_trap (PRE_EXPR_NARY (eprime))) + return false; + } /* Make the necessary insertions. */ FOR_EACH_EDGE (pred, ei, block->preds) diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index e40681f9355..78af47ed5eb 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3072,3 +3072,50 @@ sort_vuses_heap (VEC (tree,heap) *vuses) sizeof (tree), operand_build_cmp); } + + +/* Return true if the nary operation NARY may trap. This is a copy + of stmt_could_throw_1_p adjusted to the SCCVN IL. */ + +bool +vn_nary_may_trap (vn_nary_op_t nary) +{ + tree type; + tree rhs2; + bool honor_nans = false; + bool honor_snans = false; + bool fp_operation = false; + bool honor_trapv = false; + bool handled, ret; + unsigned i; + + if (TREE_CODE_CLASS (nary->opcode) == tcc_comparison + || TREE_CODE_CLASS (nary->opcode) == tcc_unary + || TREE_CODE_CLASS (nary->opcode) == tcc_binary) + { + type = nary->type; + fp_operation = FLOAT_TYPE_P (type); + if (fp_operation) + { + honor_nans = flag_trapping_math && !flag_finite_math_only; + honor_snans = flag_signaling_nans != 0; + } + else if (INTEGRAL_TYPE_P (type) + && TYPE_OVERFLOW_TRAPS (type)) + honor_trapv = true; + } + rhs2 = nary->op[1]; + ret = operation_could_trap_helper_p (nary->opcode, fp_operation, + honor_trapv, + honor_nans, honor_snans, rhs2, + &handled); + if (handled + && ret) + return true; + + for (i = 0; i < nary->length; ++i) + if (tree_could_trap_p (nary->op[i])) + return true; + + return false; +} diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index cc74acce10d..74f43c3df2e 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -188,6 +188,7 @@ tree vn_phi_lookup (gimple); hashval_t vn_nary_op_compute_hash (const vn_nary_op_t); int vn_nary_op_eq (const void *, const void *); +bool vn_nary_may_trap (vn_nary_op_t); hashval_t vn_reference_compute_hash (const vn_reference_t); int vn_reference_eq (const void *, const void *); unsigned int get_max_value_id (void); -- 2.11.4.GIT