From 3bab738598b67b501fd1411ef43f9c9f36f13297 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 11 Apr 2019 07:34:20 +0000 Subject: [PATCH] re PR tree-optimization/90020 (-O2 -Os x86-64 wrong code generated for GNU Emacs) 2019-04-11 Richard Biener PR tree-optimization/90020 * tree-ssa-sccvn.c (vn_reference_may_trap): New function. * tree-ssa-sccvn.h (vn_reference_may_trap): Declare. * tree-ssa-pre.c (compute_avail): Use it to not put possibly trapping references after a call that might not return into EXP_GEN. * gcse.c (compute_hash_table_work): Do not elide marking a block containing a call if the call might not return. * gcc.dg/torture/pr90020.c: New testcase. From-SVN: r270275 --- gcc/ChangeLog | 12 ++++++ gcc/gcse.c | 3 +- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/torture/pr90020.c | 27 ++++++++++++++ gcc/tree-ssa-pre.c | 7 ++++ gcc/tree-ssa-sccvn.c | 51 ++++++++++++++++++++++++++ gcc/tree-ssa-sccvn.h | 1 + 7 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr90020.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f1ed98e6f66..d59e43f4f3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-04-11 Richard Biener + + PR tree-optimization/90020 + * tree-ssa-sccvn.c (vn_reference_may_trap): New function. + * tree-ssa-sccvn.h (vn_reference_may_trap): Declare. + * tree-ssa-pre.c (compute_avail): Use it to not put + possibly trapping references after a call that might not + return into EXP_GEN. + * gcse.c (compute_hash_table_work): Do not elide + marking a block containing a call if the call might not + return. + 2019-04-11 Richard Biener PR tree-optimization/90018 diff --git a/gcc/gcse.c b/gcc/gcse.c index 6c77671fe31..7fbdd675005 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -1532,7 +1532,8 @@ compute_hash_table_work (struct gcse_hash_table_d *table) 0, regno, hrsi) record_last_reg_set_info (insn, regno); - if (! RTL_CONST_OR_PURE_CALL_P (insn)) + if (! RTL_CONST_OR_PURE_CALL_P (insn) + || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)) record_last_mem_set_info (insn); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2443e443215..b5094769dd8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-11 Richard Biener + + PR tree-optimization/90020 + * gcc.dg/torture/pr90020.c: New testcase. + 2019-04-11 Richard Biener PR tree-optimization/90018 diff --git a/gcc/testsuite/gcc.dg/torture/pr90020.c b/gcc/testsuite/gcc.dg/torture/pr90020.c new file mode 100644 index 00000000000..2aa8aa0e4a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr90020.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-require-weak "" } */ + +void __attribute__((noinline,noclone)) +check (int i) +{ + if (i == 0) + __builtin_exit (0); +} + +int i; +extern int x __attribute__((weak)); + +int main(int argc, char **argv) +{ + if (argc) + { + check (i); + return x; + } + else + { + check (i); + return x-1; + } + return 0; +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 3f38371cb21..7bb2cf1e220 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3931,6 +3931,13 @@ compute_avail (void) continue; } + /* If the REFERENCE traps and there was a preceding + point in the block that might not return avoid + adding the reference to EXP_GEN. */ + if (BB_MAY_NOTRETURN (block) + && vn_reference_may_trap (ref)) + continue; + /* If the value of the reference is not invalidated in this block until it is computed, add the expression to EXP_GEN. */ diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 872f904ccc5..a174f18f72a 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -4766,6 +4766,57 @@ vn_nary_may_trap (vn_nary_op_t nary) return false; } +/* Return true if the reference operation REF may trap. */ + +bool +vn_reference_may_trap (vn_reference_t ref) +{ + switch (ref->operands[0].opcode) + { + case MODIFY_EXPR: + case CALL_EXPR: + /* We do not handle calls. */ + case ADDR_EXPR: + /* And toplevel address computations never trap. */ + return false; + default:; + } + + vn_reference_op_t op; + unsigned i; + FOR_EACH_VEC_ELT (ref->operands, i, op) + { + switch (op->opcode) + { + case WITH_SIZE_EXPR: + case TARGET_MEM_REF: + /* Always variable. */ + return true; + case COMPONENT_REF: + if (op->op1 && TREE_CODE (op->op1) == SSA_NAME) + return true; + break; + case ARRAY_RANGE_REF: + case ARRAY_REF: + if (TREE_CODE (op->op0) == SSA_NAME) + return true; + break; + case MEM_REF: + /* Nothing interesting in itself, the base is separate. */ + break; + /* The following are the address bases. */ + case SSA_NAME: + return true; + case ADDR_EXPR: + if (op->op0) + return tree_could_trap_p (TREE_OPERAND (op->op0, 0)); + return false; + default:; + } + } + return false; +} + eliminate_dom_walker::eliminate_dom_walker (cdi_direction direction, bitmap inserted_exprs_) : dom_walker (direction), do_pre (inserted_exprs_ != NULL), diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 5413059baec..bd661bc651c 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -243,6 +243,7 @@ vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree, bool vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2); bool vn_nary_may_trap (vn_nary_op_t); +bool vn_reference_may_trap (vn_reference_t); bool vn_reference_eq (const_vn_reference_t const, const_vn_reference_t const); unsigned int get_max_value_id (void); unsigned int get_next_value_id (void); -- 2.30.2