diff options
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/ipa-split.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr47148.c | 32 |
4 files changed, 61 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20e8a8e8633..bd9b46d1816 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2011-01-03 Jakub Jelinek <jakub@redhat.com> + PR tree-optimization/47148 + * ipa-split.c (split_function): Convert arguments to + DECL_ARG_TYPE if possible. + PR tree-optimization/47155 * tree-ssa-ccp.c (bit_value_binop_1): Use r1type instead of type when computing uns. diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 1a553522153..fabd6d11bd9 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1,5 +1,5 @@ /* Function splitting pass - Copyright (C) 2010 + Copyright (C) 2010, 2011 Free Software Foundation, Inc. Contributed by Jan Hubicka <jh@suse.cz> @@ -943,6 +943,9 @@ split_function (struct split_point *split_point) tree retval = NULL, real_retval = NULL; bool split_part_return_p = false; gimple last_stmt = NULL; + bool conv_needed = false; + unsigned int i; + tree arg; if (dump_file) { @@ -959,7 +962,16 @@ split_function (struct split_point *split_point) SSA_NAME_VERSION (gimple_default_def (cfun, parm)))) bitmap_set_bit (args_to_skip, num); else - VEC_safe_push (tree, heap, args_to_pass, gimple_default_def (cfun, parm)); + { + arg = gimple_default_def (cfun, parm); + if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)) + != TYPE_MAIN_VARIANT (TREE_TYPE (arg))) + { + conv_needed = true; + arg = fold_convert (DECL_ARG_TYPE (parm), arg); + } + VEC_safe_push (tree, heap, args_to_pass, arg); + } /* See if the split function will return. */ FOR_EACH_EDGE (e, ei, return_bb->preds) @@ -1056,6 +1068,14 @@ split_function (struct split_point *split_point) /* Produce the call statement. */ gsi = gsi_last_bb (call_bb); + if (conv_needed) + FOR_EACH_VEC_ELT (tree, args_to_pass, i, arg) + if (!is_gimple_val (arg)) + { + arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE, + false, GSI_NEW_STMT); + VEC_replace (tree, args_to_pass, i, arg); + } call = gimple_build_call_vec (node->decl, args_to_pass); gimple_set_block (call, DECL_INITIAL (current_function_decl)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 40223f88b0f..b54a3bfbe71 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2011-01-03 Jakub Jelinek <jakub@redhat.com> + PR tree-optimization/47148 + * gcc.c-torture/execute/pr47148.c: New test. + PR tree-optimization/47155 * gcc.c-torture/execute/pr47155.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr47148.c b/gcc/testsuite/gcc.c-torture/execute/pr47148.c new file mode 100644 index 00000000000..8363631a9fa --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr47148.c @@ -0,0 +1,32 @@ +/* PR tree-optimization/47148 */ + +static inline unsigned +bar (unsigned x, unsigned y) +{ + if (y >= 32) + return x; + else + return x >> y; +} + +static unsigned a = 1, b = 1; + +static inline void +foo (unsigned char x, unsigned y) +{ + if (!y) + return; + unsigned c = (0x7000U / (x - 2)) ^ a; + unsigned d = bar (a, a); + b &= ((a - d) && (a - 1)) + c; +} + +int +main (void) +{ + foo (1, 1); + foo (-1, 1); + if (b && ((unsigned char) -1) == 255) + __builtin_abort (); + return 0; +} |