Hi,

the attached C testcase exhibits a wrong-code regression present since the 
specific support for the static chain was added to the IPA mod/ref pass (GCC 
12 and later) although the underlying issue might have been present before.

When a memory copy operation is analyzed by analyze_ssa_name, if both the load 
and the store are made through the same SSA name, the store is overlooked.

Tested on x86-64/Linux, OK for all active branches?


2024-09-20  Eric Botcazou  <ebotca...@adacore.com>

        * ipa-modref.cc (modref_eaf_analysis::analyze_ssa_name): Always
        process both the load and the store of a memory copy operation.


2024-09-20  Eric Botcazou  <ebotca...@adacore.com>

        * gcc.dg/ipa/modref-4.c: New test.

-- 
Eric Botcazou
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 9275030c254..400a8856de2 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -2610,8 +2610,9 @@ modref_eaf_analysis::analyze_ssa_name (tree name, bool deferred)
 		 is used arbitrarily.  */
 	      if (memory_access_to (gimple_assign_rhs1 (assign), name))
 		m_lattice[index].merge (deref_flags (0, false));
+
 	      /* Handle *name = *exp.  */
-	      else if (memory_access_to (gimple_assign_lhs (assign), name))
+	      if (memory_access_to (gimple_assign_lhs (assign), name))
 		m_lattice[index].merge_direct_store ();
 	    }
 	  /* Handle lhs = *name.  */
/* { dg-options "-O"  } */
/* { dg-do run } */

static __attribute__((noipa)) int foo (void)
{
  return 1;
}

int main (void)
{
  struct S { int a; int b; };
  struct T { struct S s; };

  struct T t = { { 0, 0 } };
  struct T u;

  __attribute__((noinline)) void bar (void)
  {
    if (foo ())
      {
	u = t;
        /* OK with u.s.a = 0; */
      }
  }

  u.s.a = 1;

  bar ();

  if (u.s.a != 0)
    __builtin_abort ();

  return 0;
}

Reply via email to