re PR ipa/85960 (-fipa-pta and ifunc are incompatible)
authorRichard Biener <rguenther@suse.de>
Fri, 1 Jun 2018 08:20:08 +0000 (08:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 1 Jun 2018 08:20:08 +0000 (08:20 +0000)
2018-06-01  Richard Biener  <rguenther@suse.de>

PR ipa/85960
* tree-ssa-structalias.c (get_function_part_constraint):
Handle NULL fi->decl.
(find_func_aliases_for_call): Properly handle indirect
fi from direct call.
(find_func_clobbers): Likewise.
(ipa_pta_execute): Likewise.
(create_variable_info_for): For functions that are ifunc_resolver
resolve to a varinfo that contains the result of the resolver
call.
(associate_varinfo_to_alias): Do not treat ifunc resolvers as
aliases.

* gcc.dg/ipa/ipa-pta-19.c: New testcase.

From-SVN: r261056

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/ipa-pta-19.c [new file with mode: 0644]
gcc/tree-ssa-structalias.c

index 956fbde816bbafec58d912cbae66b97eeeb4efd8..7adafede7ec77c82a18f592371595a0390a975a7 100644 (file)
@@ -1,3 +1,18 @@
+2018-06-01  Richard Biener  <rguenther@suse.de>
+
+       PR ipa/85960
+       * tree-ssa-structalias.c (get_function_part_constraint):
+       Handle NULL fi->decl.
+       (find_func_aliases_for_call): Properly handle indirect
+       fi from direct call.
+       (find_func_clobbers): Likewise.
+       (ipa_pta_execute): Likewise.
+       (create_variable_info_for): For functions that are ifunc_resolver
+       resolve to a varinfo that contains the result of the resolver
+       call.
+       (associate_varinfo_to_alias): Do not treat ifunc resolvers as
+       aliases.
+
 2018-05-31  Michael Collison  <michael.collison@arm.com>
 
        * config/aarch64/aarch64.md:
index 677d8e00d18ea8179bb43f371b1911f70e34ad03..cec80a5d238744fb72cc184095151614ec7db422 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-01  Richard Biener  <rguenther@suse.de>
+
+       PR ipa/85960
+       * gcc.dg/ipa/ipa-pta-19.c: New testcase.
+
 2018-05-31  Qing Zhao <qing.zhao@oracle.com>
 
        PR middle-end/78809
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-19.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-19.c
new file mode 100644 (file)
index 0000000..ae47cb0
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2 -fipa-pta" } */
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+#define hot __attribute__((hot))
+
+static hot void multiver_default(unsigned int in, bool *ret)
+{
+       if ( in & 1 ) {
+               *ret = false;
+       }else{
+               *ret = true;
+       }
+}
+
+static void (*resolve_multiver(void))(unsigned int in, bool *out)
+{
+       return &multiver_default;
+}
+
+__attribute__ ((ifunc("resolve_multiver")))
+static void multiver_test(unsigned int val, bool *ret);
+
+static hot bool do_test(unsigned int val)
+{
+       bool ret = false;
+
+       multiver_test(val, &ret);
+
+       return (ret == !(val & 0x1));
+}
+
+volatile unsigned int x = 2;
+int main()
+{
+  int i;
+  for(i = 1; i < x; i++) {
+      unsigned int val = x;
+      if ( !do_test(val) )
+       abort ();
+  }
+  return 0;
+}
index 14ab83a9469d6c4378fed54ede3771779bd0c6dd..73e500bb616ca7d9de7b9d316023ee37d6ddcc23 100644 (file)
@@ -3903,7 +3903,7 @@ get_function_part_constraint (varinfo_t fi, unsigned part)
       c.offset = 0;
       c.type = SCALAR;
     }
-  else if (TREE_CODE (fi->decl) == FUNCTION_DECL)
+  else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
     {
       varinfo_t ai = first_vi_for_offset (fi, part);
       if (ai)
@@ -4735,7 +4735,7 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
 
   fi = get_fi_for_callee (t);
   if (!in_ipa_mode
-      || (fndecl && !fi->is_fn_info))
+      || (fi->decl && fndecl && !fi->is_fn_info))
     {
       auto_vec<ce_s, 16> rhsc;
       int flags = gimple_call_flags (t);
@@ -5352,7 +5352,7 @@ find_func_clobbers (struct function *fn, gimple *origt)
 
       /* For callees without function info (that's external functions),
         ESCAPED is clobbered and used.  */
-      if (gimple_call_fndecl (t)
+      if (cfi->decl
          && !cfi->is_fn_info)
        {
          varinfo_t vi;
@@ -6115,6 +6115,27 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id,
 static unsigned int
 create_variable_info_for (tree decl, const char *name, bool add_id)
 {
+  /* First see if we are dealing with an ifunc resolver call and
+     assiociate that with a call to the resolver function result.  */
+  cgraph_node *node;
+  if (in_ipa_mode
+      && TREE_CODE (decl) == FUNCTION_DECL
+      && (node = cgraph_node::get (decl))->ifunc_resolver)
+    {
+      varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
+      constraint_expr rhs
+       = get_function_part_constraint (fi, fi_result);
+      fi = new_var_info (NULL_TREE, "ifuncres", true);
+      fi->is_reg_var = true;
+      constraint_expr lhs;
+      lhs.type = SCALAR;
+      lhs.var = fi->id;
+      lhs.offset = 0;
+      process_constraint (new_constraint (lhs, rhs));
+      insert_vi_for_tree (decl, fi);
+      return fi->id;
+    }
+
   varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
   unsigned int id = vi->id;
 
@@ -7715,7 +7736,8 @@ associate_varinfo_to_alias (struct cgraph_node *node, void *data)
   if ((node->alias
        || (node->thunk.thunk_p
           && ! node->global.inlined_to))
-      && node->analyzed)
+      && node->analyzed
+      && !node->ifunc_resolver)
     insert_vi_for_tree (node->decl, (varinfo_t)data);
   return false;
 }
@@ -8087,7 +8109,7 @@ ipa_pta_execute (void)
                         (node->decl, first_vi_for_offset (fi, fi_uses));
                }
              /* Handle direct calls to external functions.  */
-             else if (decl)
+             else if (decl && (!fi || fi->decl))
                {
                  pt = gimple_call_use_set (stmt);
                  if (gimple_call_flags (stmt) & ECF_CONST)
@@ -8132,8 +8154,7 @@ ipa_pta_execute (void)
                    }
                }
              /* Handle indirect calls.  */
-             else if (!decl
-                      && (fi = get_fi_for_callee (stmt)))
+             else if ((fi = get_fi_for_callee (stmt)))
                {
                  /* We need to accumulate all clobbers/uses of all possible
                     callees.  */
@@ -8189,6 +8210,8 @@ ipa_pta_execute (void)
                        }
                    }
                }
+             else
+               gcc_unreachable ();
            }
        }