re PR tree-optimization/38819 (trapping expression wrongly hoisted out of loop)

2009-01-18  Richard Guenther  <rguenther@suse.de>

	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.

From-SVN: r143485
This commit is contained in:
Richard Guenther 2009-01-18 15:51:12 +00:00 committed by Richard Biener
parent a729d731c8
commit 890065bfe4
8 changed files with 105 additions and 1 deletions

View File

@ -1,3 +1,14 @@
2009-01-18 Richard Guenther <rguenther@suse.de>
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 <schwab@suse.de>
* doc/install.texi (Configuration): Remove obsolete paragraph

View File

@ -1,3 +1,8 @@
2009-01-18 Richard Guenther <rguenther@suse.de>
PR tree-optimization/38819
* gcc.c-torture/execute/pr38819.c: New testcase.
2009-01-17 Paul Thomas <pault@gcc.gnu.org>
PR fortran/38657

View File

@ -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 ();
}

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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);