+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
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);
}
+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
--- /dev/null
+/* { 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;
+}
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. */
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),
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);