ipa-icf-gimple.c (func_checker::compare_bb): Fix comment typo.
authorJakub Jelinek <jakub@redhat.com>
Mon, 10 Nov 2014 23:08:08 +0000 (00:08 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 10 Nov 2014 23:08:08 +0000 (00:08 +0100)
* ipa-icf-gimple.c (func_checker::compare_bb): Fix comment typo.
(func_checker::compare_gimple_call): Compare gimple_call_fn,
gimple_call_chain, gimple_call_fntype and call flags.
testsuite/
* gcc.dg/ubsan/ipa-icf-1.c: New test.
* gcc.dg/ipa/ipa-icf-31.c: New test.

Co-Authored-By: Martin Liska <mliska@suse.cz>
From-SVN: r217323

gcc/ChangeLog
gcc/ipa-icf-gimple.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/ipa-icf-31.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ubsan/ipa-icf-1.c [new file with mode: 0644]

index 63d43b682396c18d1e57be6e86eb752dc8b2c3f2..9d7dc265cb6855e646d3113cd248823585cc5e62 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-11  Jakub Jelinek  <jakub@redhat.com>
+           Martin Liska  <mliska@suse.cz>
+
+       * ipa-icf-gimple.c (func_checker::compare_bb): Fix comment typo.
+       (func_checker::compare_gimple_call): Compare gimple_call_fn,
+       gimple_call_chain, gimple_call_fntype and call flags.
+
 2014-11-10  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR rtl-optimization/63620
index 75b5cfbc202e97d5ea906197e433b21e05c3ce8a..a7e5a9241ab1dbe6ab5e7d127ec05bcc385212c0 100644 (file)
@@ -554,7 +554,7 @@ func_checker::parse_labels (sem_bb *bb)
 
    In general, a collection of equivalence dictionaries is built for types
    like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
-   is utilized by every statement-by-stament comparison function.  */
+   is utilized by every statement-by-statement comparison function.  */
 
 bool
 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
@@ -659,12 +659,39 @@ func_checker::compare_gimple_call (gimple s1, gimple s2)
   if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
     return false;
 
-  t1 = gimple_call_fndecl (s1);
-  t2 = gimple_call_fndecl (s2);
-
-  /* Function pointer variables are not supported yet.  */
+  t1 = gimple_call_fn (s1);
+  t2 = gimple_call_fn (s2);
   if (!compare_operand (t1, t2))
-    return return_false();
+    return return_false ();
+
+  /* Compare flags.  */
+  if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
+      || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
+      || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
+      || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
+      || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
+      || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
+      || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
+      || gimple_call_with_bounds_p (s1) != gimple_call_with_bounds_p (s2))
+    return false;
+
+  if (gimple_call_internal_p (s1)
+      && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
+    return false;
+
+  tree fntype1 = gimple_call_fntype (s1);
+  tree fntype2 = gimple_call_fntype (s2);
+  if ((fntype1 && !fntype2)
+      || (!fntype1 && fntype2)
+      || (fntype1 && !types_compatible_p (fntype1, fntype2)))
+    return return_false_with_msg ("call function types are not compatible");
+
+  tree chain1 = gimple_call_chain (s1);
+  tree chain2 = gimple_call_chain (s2);
+  if ((chain1 && !chain2)
+      || (!chain1 && chain2)
+      || !compare_operand (chain1, chain2))
+    return return_false_with_msg ("static call chains are different");
 
   /* Checking of argument.  */
   for (i = 0; i < gimple_call_num_args (s1); ++i)
index 812696db96111dd2aeef203d0ce0b8b8a3597d6a..a44ae99c20eec811966be6f63c6573d6350ce789 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.dg/ubsan/ipa-icf-1.c: New test.
+       * gcc.dg/ipa/ipa-icf-31.c: New test.
+
 2014-11-10  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR middle-end/63748
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-31.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-31.c
new file mode 100644 (file)
index 0000000..6a5ec2e
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-icf" } */
+
+__attribute__ ((noinline, noclone))
+int f1 (int x, int (*p1) (void), int (*p2) (void))
+{
+  if (x)
+    return p1 ();
+  else
+    return p2 ();
+}
+
+__attribute__ ((noinline, noclone))
+int f2 (int x, int (*p1) (void), int (*p2) (void))
+{
+  if (x)
+    return p2 ();
+  else
+    return p1 ();
+}
+
+__attribute__ ((noinline, noclone))
+int f3 (void)
+{
+  return 1;
+}
+
+__attribute__ ((noinline, noclone))
+int f4 (void)
+{
+  return 2;
+}
+
+int
+main ()
+{
+  if (f1 (0, f3, f4) != 2 || f1 (1, f3, f4) != 1 || f2 (0, f3, f4) != 1
+      || f2 (1, f3, f4) != 2)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ubsan/ipa-icf-1.c b/gcc/testsuite/gcc.dg/ubsan/ipa-icf-1.c
new file mode 100644 (file)
index 0000000..1638ec4
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+/* { dg-options "-fsanitize=undefined -fipa-icf" } */
+
+__attribute__ ((noinline, noclone))
+int f1 (int x, int y)
+{
+  return x + y;
+}
+
+__attribute__ ((noinline, noclone))
+int f2 (int x, int y)
+{
+  return x - y;
+}
+
+int
+main ()
+{
+  if (f1 (5, 6) != 11 || f2 (5, 6) != -1)
+    __builtin_abort ();
+  return 0;
+}