re PR tree-optimization/58209 (ICE in extract_range_from_binary_expr, at tree-vrp...
authorJakub Jelinek <jakub@redhat.com>
Fri, 23 Aug 2013 07:30:40 +0000 (09:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 23 Aug 2013 07:30:40 +0000 (09:30 +0200)
PR tree-optimization/58209
* tree-tailcall.c (process_assignment): Handle POINTER_PLUS_EXPR.
(find_tail_calls): Give up for pointer result types if m is non-NULL.
(adjust_return_value_with_ops): For PLUS_EXPR and pointer result type
emit POINTER_PLUS_EXPR.
(create_tailcall_accumulator): For pointer result type accumulate in
sizetype type.

* gcc.c-torture/execute/pr58209.c: New test.

From-SVN: r201935

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr58209.c [new file with mode: 0644]
gcc/tree-tailcall.c

index 039dbe299abc1b0708b2a1cbc512aa684b9b0a5e..9647b90831fa6cefb176136f637fd833849891bd 100644 (file)
@@ -1,3 +1,13 @@
+2013-08-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/58209
+       * tree-tailcall.c (process_assignment): Handle POINTER_PLUS_EXPR.
+       (find_tail_calls): Give up for pointer result types if m is non-NULL.
+       (adjust_return_value_with_ops): For PLUS_EXPR and pointer result type
+       emit POINTER_PLUS_EXPR.
+       (create_tailcall_accumulator): For pointer result type accumulate in
+       sizetype type.
+
 2013-08-22  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * configure.ac: Add backslashes missing from the last change.
index a3346abddcd4bab3ab1cea9d22bd832a06214390..c6e0653ca9efbb9ac1a65abb59bb3b4f4ecde810 100644 (file)
@@ -1,3 +1,8 @@
+2013-08-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/58209
+       * gcc.c-torture/execute/pr58209.c: New test.
+
 2013-08-22  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/pr57744.c: Declare abort.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58209.c b/gcc/testsuite/gcc.c-torture/execute/pr58209.c
new file mode 100644 (file)
index 0000000..78743bf
--- /dev/null
@@ -0,0 +1,32 @@
+/* PR tree-optimization/58209 */
+
+extern void abort (void);
+typedef __INTPTR_TYPE__ T;
+T buf[1024];
+
+T *
+foo (T n)
+{
+  if (n == 0)
+    return (T *) buf;
+  T s = (T) foo (n - 1);
+  return (T *) (s + sizeof (T));
+}
+
+T *
+bar (T n)
+{
+  if (n == 0)
+    return buf;
+  return foo (n - 1) + 1;
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 27; i++)
+    if (foo (i) != buf + i || bar (i) != buf + i)
+      abort ();
+  return 0;
+}
index c9716e708c00cecba970f3d62bd27d33764436d5..96940467181992a8228366f79810755c78def0f3 100644 (file)
@@ -305,7 +305,7 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
   if (rhs_class == GIMPLE_UNARY_RHS)
     ;
   else if (op0 == *ass_var
-      && (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
+          && (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
     ;
   else if (op1 == *ass_var
           && (non_ass_var = independent_of_stmt_p (op0, stmt, call)))
@@ -320,6 +320,13 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
       *ass_var = dest;
       return true;
 
+    case POINTER_PLUS_EXPR:
+      if (op0 != *ass_var)
+       return false;
+      *a = non_ass_var;
+      *ass_var = dest;
+      return true;
+
     case MULT_EXPR:
       *m = non_ass_var;
       *ass_var = dest;
@@ -562,6 +569,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
   if (!tail_recursion && (m || a))
     return;
 
+  /* For pointers only allow additions.  */
+  if (m && POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
+    return;
+
   nw = XNEW (struct tailcall);
 
   nw->call_gsi = gsi;
@@ -604,15 +615,23 @@ adjust_return_value_with_ops (enum tree_code code, const char *label,
   tree result = make_temp_ssa_name (ret_type, NULL, label);
   gimple stmt;
 
-  if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1)))
+  if (POINTER_TYPE_P (ret_type))
+    {
+      gcc_assert (code == PLUS_EXPR && TREE_TYPE (acc) == sizetype);
+      code = POINTER_PLUS_EXPR;
+    }
+  if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1))
+      && code != POINTER_PLUS_EXPR)
     stmt = gimple_build_assign_with_ops (code, result, acc, op1);
   else
     {
-      tree rhs = fold_convert (TREE_TYPE (acc),
-                              fold_build2 (code,
-                                           TREE_TYPE (op1),
-                                           fold_convert (TREE_TYPE (op1), acc),
-                                           op1));
+      tree tem;
+      if (code == POINTER_PLUS_EXPR)
+       tem = fold_build2 (code, TREE_TYPE (op1), op1, acc);
+      else
+       tem = fold_build2 (code, TREE_TYPE (op1),
+                          fold_convert (TREE_TYPE (op1), acc), op1);
+      tree rhs = fold_convert (ret_type, tem);
       rhs = force_gimple_operand_gsi (&gsi, rhs,
                                      false, NULL, true, GSI_SAME_STMT);
       stmt = gimple_build_assign (result, rhs);
@@ -892,6 +911,9 @@ static tree
 create_tailcall_accumulator (const char *label, basic_block bb, tree init)
 {
   tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+  if (POINTER_TYPE_P (ret_type))
+    ret_type = sizetype;
+
   tree tmp = make_temp_ssa_name (ret_type, NULL, label);
   gimple phi;