Hi,
this patch makes stmt_may_be_vtbl_ptr_store to skip clobbers as discussed
previously.
Martin, I do not fully follow the logic of this function.  Can't we just
ignore all stores that are not of pointer type that looks like vptr
type?  All those tores are compiler generated and we probably can just
annotate them, right?

Bootstrapped/regtested x86_64-linux, comitted.

Honza

        * ipa-prop.c (stmt_may_be_vtbl_ptr_store): Skip clobbers.
        * g++.dg/ipa/devirt-19.C: New testcase.
Index: ipa-prop.c
===================================================================
--- ipa-prop.c  (revision 205987)
+++ ipa-prop.c  (working copy)
@@ -560,6 +560,8 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
 {
   if (is_gimple_call (stmt))
     return false;
+  else if (gimple_clobber_p (stmt))
+    return false;
   else if (is_gimple_assign (stmt))
     {
       tree lhs = gimple_assign_lhs (stmt);
Index: testsuite/g++.dg/ipa/devirt-19.C
===================================================================
--- testsuite/g++.dg/ipa/devirt-19.C    (revision 0)
+++ testsuite/g++.dg/ipa/devirt-19.C    (revision 0)
@@ -0,0 +1,32 @@
+/* We should specialize for &b and devirtualize the call.
+   Previously we were failing by considering CLOBBER statement to be
+   a type change.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp"  } */
+struct A {
+  void operator==(const A &);
+};
+class B {
+public:
+  A m_fn1();
+  A m_fn2();
+};
+template <typename T, typename M> class C {
+public:
+  T Key;
+  const M &m_fn2(const T &);
+  virtual void m_fn1() {}
+  B _map;
+};
+
+C<int, int> b;
+template <typename T, typename M> const M &C<T, M>::m_fn2(const T &) {
+  A a = _map.m_fn2();
+  a == _map.m_fn1();
+  m_fn1();
+}
+
+void fn1() { b.m_fn2(0); }
+/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known 
target" 1 "cp"  } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+

Reply via email to