diff options
author | Richard Biener <rguenther@suse.de> | 2012-11-28 09:27:10 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-11-28 09:27:10 +0000 |
commit | cc3c4f62f32c2945e5bbd85c084dae1f7046280b (patch) | |
tree | 708df4dc743c4f6d7778396707a8a1254049b1dd /gcc/gimplify.c | |
parent | b1c2b51b6662adebbc37c6590d697e9fe3439076 (diff) | |
download | gcc-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.c | 26 |
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: |