summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/gcse.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr90020.c27
-rw-r--r--gcc/tree-ssa-pre.c7
-rw-r--r--gcc/tree-ssa-sccvn.c51
-rw-r--r--gcc/tree-ssa-sccvn.h1
7 files changed, 105 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f1ed98e6f66..d59e43f4f3b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,17 @@
2019-04-11 Richard Biener <rguenther@suse.de>
+ 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 <rguenther@suse.de>
+
PR tree-optimization/90018
* tree-vect-data-refs.c (vect_preserves_scalar_order_p):
Test both SLP and interleaving variants.
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,5 +1,10 @@
2019-04-11 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/90020
+ * gcc.dg/torture/pr90020.c: New testcase.
+
+2019-04-11 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/90018
* gcc.dg/vect/pr90018.c: New testcase.
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);