aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2012-11-28 09:27:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-11-28 09:27:10 +0000
commitcc3c4f62f32c2945e5bbd85c084dae1f7046280b (patch)
tree708df4dc743c4f6d7778396707a8a1254049b1dd /gcc/gimplify.c
parentb1c2b51b6662adebbc37c6590d697e9fe3439076 (diff)
downloadgcc-cc3c4f62f32c2945e5bbd85c084dae1f7046280b.zip
gcc-cc3c4f62f32c2945e5bbd85c084dae1f7046280b.tar.gz
gcc-cc3c4f62f32c2945e5bbd85c084dae1f7046280b.tar.bz2
re PR c/35634 (operand of pre-/postin-/decrement not promoted)
2012-11-28 Richard Biener <rguenther@suse.de> PR c/35634 * gimple.h (gimplify_self_mod_expr): Declare. * gimplify.c (gimplify_self_mod_expr): Export. Take a different type for performing the arithmetic in. (gimplify_expr): Adjust. * tree-vect-loop-manip.c (vect_can_advance_ivs_p): Strip sign conversions we can re-apply after adjusting the IV. c-family/ * c-gimplify.c (c_gimplify_expr): Gimplify self-modify expressions here and use a type with proper overflow behavior for types that would need to be promoted for the arithmetic. * gcc.dg/torture/pr35634.c: New testcase. * g++.dg/torture/pr35634.C: Likewise. * gcc.dg/vect/pr18536.c: Mark worker function noinline. From-SVN: r193882
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 8d555f8..384adb2 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2317,11 +2317,13 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
*EXPR_P should be stored.
WANT_VALUE is nonzero iff we want to use the value of this expression
- in another expression. */
+ in another expression.
-static enum gimplify_status
+ ARITH_TYPE is the type the computation should be performed in. */
+
+enum gimplify_status
gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
- bool want_value)
+ bool want_value, tree arith_type)
{
enum tree_code code;
tree lhs, lvalue, rhs, t1;
@@ -2382,27 +2384,32 @@ gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
return ret;
}
+ if (postfix)
+ lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
+
/* For POINTERs increment, use POINTER_PLUS_EXPR. */
if (POINTER_TYPE_P (TREE_TYPE (lhs)))
{
rhs = convert_to_ptrofftype_loc (loc, rhs);
if (arith_code == MINUS_EXPR)
rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
- arith_code = POINTER_PLUS_EXPR;
+ t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
}
+ else
+ t1 = fold_convert (TREE_TYPE (*expr_p),
+ fold_build2 (arith_code, arith_type,
+ fold_convert (arith_type, lhs),
+ fold_convert (arith_type, rhs)));
if (postfix)
{
- tree t2 = get_initialized_tmp_var (lhs, pre_p, NULL);
- t1 = build2 (arith_code, TREE_TYPE (*expr_p), t2, rhs);
gimplify_assign (lvalue, t1, pre_p);
gimplify_seq_add_seq (orig_post_p, post);
- *expr_p = t2;
+ *expr_p = lhs;
return GS_ALL_DONE;
}
else
{
- t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
*expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
return GS_OK;
}
@@ -7111,7 +7118,8 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
- fallback != fb_none);
+ fallback != fb_none,
+ TREE_TYPE (*expr_p));
break;
case ARRAY_REF: