re PR tree-optimization/90020 (-O2 -Os x86-64 wrong code generated for GNU Emacs)
authorRichard Biener <rguenther@suse.de>
Thu, 11 Apr 2019 07:34:20 +0000 (07:34 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 11 Apr 2019 07:34:20 +0000 (07:34 +0000)
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.

* gcc.dg/torture/pr90020.c: New testcase.

From-SVN: r270275

gcc/ChangeLog
gcc/gcse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr90020.c [new file with mode: 0644]
gcc/tree-ssa-pre.c
gcc/tree-ssa-sccvn.c
gcc/tree-ssa-sccvn.h

index f1ed98e6f66999313a70279604f3b3aadc90ed02..d59e43f4f3b0a8c511783896f79249112d309d26 100644 (file)
@@ -1,3 +1,15 @@
+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
index 6c77671fe3115a0051173855268ed46f87f79ede..7fbdd675005e866d5d06949993ca3a545fe89e1f 100644 (file)
@@ -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);
            }
 
index 2443e443215a6a6bb1c6b6cc74c1f6f46b3edfc5..b5094769dd8d1bf538dccdb9ef66288b13de4454 100644 (file)
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/gcc.dg/torture/pr90020.c b/gcc/testsuite/gcc.dg/torture/pr90020.c
new file mode 100644 (file)
index 0000000..2aa8aa0
--- /dev/null
@@ -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;
+}
index 3f38371cb21a205ad745972ec69f518f2e8e4ad1..7bb2cf1e2207b83a6b6b05615a709a509cce3cdf 100644 (file)
@@ -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.  */
index 872f904ccc5cf4b90b94a772e5029327ab5993b0..a174f18f72a0198cfe2ed2844b31f1dccc216086 100644 (file)
@@ -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),
index 5413059baec603a3bda40faf6f1211b55baca3d7..bd661bc651c43ce75ed0ca2604f1026a04cf99a5 100644 (file)
@@ -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);