re PR target/47148 (likely wrong code bug)
authorJakub Jelinek <jakub@redhat.com>
Mon, 3 Jan 2011 21:10:31 +0000 (22:10 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 3 Jan 2011 21:10:31 +0000 (22:10 +0100)
PR tree-optimization/47148
* ipa-split.c (split_function): Convert arguments to
DECL_ARG_TYPE if possible.

* gcc.c-torture/execute/pr47148.c: New test.

From-SVN: r168441

gcc/ChangeLog
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr47148.c [new file with mode: 0644]

index 20e8a8e..bd9b46d 100644 (file)
@@ -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.
index 1a55352..fabd6d1 100644 (file)
@@ -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));
 
index 40223f8..b54a3bf 100644 (file)
@@ -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 (file)
index 0000000..8363631
--- /dev/null
@@ -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;
+}