From: Jakub Jelinek Date: Fri, 23 Aug 2013 07:30:40 +0000 (+0200) Subject: re PR tree-optimization/58209 (ICE in extract_range_from_binary_expr, at tree-vrp... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6b00d7dd17673acaf9a34f136345000d473ba6ba;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 039dbe299ab..9647b90831f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-08-23 Jakub Jelinek + + 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 * configure.ac: Add backslashes missing from the last change. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a3346abddcd..c6e0653ca9e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-08-23 Jakub Jelinek + + PR tree-optimization/58209 + * gcc.c-torture/execute/pr58209.c: New test. + 2013-08-22 Michael Meissner * 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 00000000000..78743bfb959 --- /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 c9716e708c0..96940467181 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;