The following fixes PR60912 - a bug with IPA PTA computing
the use/clobber sets for direct calls where it "optimized"
walking using the cgraph nodes caller list.  But that can
be incomplete in the face of aliases.  Luckily that
optimization is no longer necessary because we now cache
the outcome of find_what_var_points_to, thus removing it
fixes the issue.

Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu,
will apply to trunk and 4.9 branch.

Thanks,
Richard.

2014-04-24  Richard Biener  <rguent...@suse.de>

        PR ipa/60912
        * tree-ssa-structalias.c (ipa_pta_execute): Compute direct
        call stmt use/clobber sets during stmt walk instead of
        walking the possibly incomplete set of caller edges.

        * g++.dg/opt/pr60912.C: New testcase.

Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c  (revision 209744)
--- gcc/tree-ssa-structalias.c  (working copy)
*************** ipa_pta_execute (void)
*** 7244,7253 ****
        tree ptr;
        struct function *fn;
        unsigned i;
-       varinfo_t fi;
        basic_block bb;
-       struct pt_solution uses, clobbers;
-       struct cgraph_edge *e;
  
        /* Nodes without a body are not interesting.  */
        if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
--- 7244,7250 ----
*************** ipa_pta_execute (void)
*** 7263,7283 ****
            find_what_p_points_to (ptr);
        }
  
-       /* Compute the call-use and call-clobber sets for all direct calls.  */
-       fi = lookup_vi_for_tree (node->decl);
-       gcc_assert (fi->is_fn_info);
-       clobbers
-       = find_what_var_points_to (first_vi_for_offset (fi, fi_clobbers));
-       uses = find_what_var_points_to (first_vi_for_offset (fi, fi_uses));
-       for (e = node->callers; e; e = e->next_caller)
-       {
-         if (!e->call_stmt)
-           continue;
- 
-         *gimple_call_clobber_set (e->call_stmt) = clobbers;
-         *gimple_call_use_set (e->call_stmt) = uses;
-       }
- 
        /* Compute the call-use and call-clobber sets for indirect calls
         and calls to external functions.  */
        FOR_EACH_BB_FN (bb, fn)
--- 7260,7265 ----
*************** ipa_pta_execute (void)
*** 7288,7304 ****
            {
              gimple stmt = gsi_stmt (gsi);
              struct pt_solution *pt;
!             varinfo_t vi;
              tree decl;
  
              if (!is_gimple_call (stmt))
                continue;
  
!             /* Handle direct calls to external functions.  */
              decl = gimple_call_fndecl (stmt);
              if (decl
!                 && (!(fi = lookup_vi_for_tree (decl))
!                     || !fi->is_fn_info))
                {
                  pt = gimple_call_use_set (stmt);
                  if (gimple_call_flags (stmt) & ECF_CONST)
--- 7270,7296 ----
            {
              gimple stmt = gsi_stmt (gsi);
              struct pt_solution *pt;
!             varinfo_t vi, fi;
              tree decl;
  
              if (!is_gimple_call (stmt))
                continue;
  
!             /* Handle direct calls to functions with body.  */
              decl = gimple_call_fndecl (stmt);
              if (decl
!                 && (fi = lookup_vi_for_tree (decl))
!                 && fi->is_fn_info)
!               {
!                 *gimple_call_clobber_set (stmt)
!                    = find_what_var_points_to
!                        (first_vi_for_offset (fi, fi_clobbers));
!                 *gimple_call_use_set (stmt)
!                    = find_what_var_points_to
!                        (first_vi_for_offset (fi, fi_uses));
!               }
!             /* Handle direct calls to external functions.  */
!             else if (decl)
                {
                  pt = gimple_call_use_set (stmt);
                  if (gimple_call_flags (stmt) & ECF_CONST)
*************** ipa_pta_execute (void)
*** 7342,7351 ****
                      pt->nonlocal = 1;
                    }
                }
- 
              /* Handle indirect calls.  */
!             if (!decl
!                 && (fi = get_fi_for_callee (stmt)))
                {
                  /* We need to accumulate all clobbers/uses of all possible
                     callees.  */
--- 7334,7342 ----
                      pt->nonlocal = 1;
                    }
                }
              /* Handle indirect calls.  */
!             else if (!decl
!                      && (fi = get_fi_for_callee (stmt)))
                {
                  /* We need to accumulate all clobbers/uses of all possible
                     callees.  */
Index: gcc/testsuite/g++.dg/opt/pr60912.C
===================================================================
*** gcc/testsuite/g++.dg/opt/pr60912.C  (revision 0)
--- gcc/testsuite/g++.dg/opt/pr60912.C  (working copy)
***************
*** 0 ****
--- 1,18 ----
+ // { dg-do run }
+ // { dg-options "-O -fno-inline -fipa-pta" }
+ 
+ struct IFoo
+ {
+   virtual void Foo () = 0;
+ };
+ 
+ struct Bar:IFoo
+ {
+   void Foo () {}
+ };
+ 
+ int main ()
+ {
+   (new Bar ())->Foo ();
+   return 0;
+ }

Reply via email to