aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-08-23 09:30:40 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2013-08-23 09:30:40 +0200
commit6b00d7dd17673acaf9a34f136345000d473ba6ba (patch)
treee2bf13f7e786fbd6ce69ddedeabcef9c0e3d0876 /gcc
parent6e6bbb604ef6970174f50b710caf03c1d9fcee58 (diff)
downloadgcc-6b00d7dd17673acaf9a34f136345000d473ba6ba.zip
gcc-6b00d7dd17673acaf9a34f136345000d473ba6ba.tar.gz
gcc-6b00d7dd17673acaf9a34f136345000d473ba6ba.tar.bz2
re PR tree-optimization/58209 (ICE in extract_range_from_binary_expr, at tree-vrp.c:2294)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr58209.c32
-rw-r--r--gcc/tree-tailcall.c36
4 files changed, 76 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 039dbe2..9647b90 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a3346ab..c6e0653 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..78743bf
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr58209.c
@@ -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;
+}
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index c9716e70..9694046 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -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;