Patchwork [PR,56294] Fix omissions in intersect_aggregates_with_edge

login
register
mail settings
Submitter Martin Jambor
Date Feb. 20, 2013, 3:01 p.m.
Message ID <20130220150104.GE19120@virgil.suse>
Download mbox | patch
Permalink /patch/222096/
State New
Headers show

Comments

Martin Jambor - Feb. 20, 2013, 3:01 p.m.
Hi,

this patch fixes an omission in IPA-CP's agg_replacements_to_vector
which needs to filter the vector by index and offset and a typo in
intersect_aggregates_with_edge which in one call passed the wrong
index to agg_replacements_to_vector.  This combined lead to empty
intersections which were caught by an assert checking exactly that.

Bootstrapped and tested on x86_64-linux (all languages + Ada) with
default BOOT_CFLAGS and also with BOOT_CFLAGS='-O2 -g -fipa-cp-clone
--param=ipa-cp-eval-threshold=100' (C, C++ and Fortran only), I'm
currently bootstrapping with the param set to 1.

OK for trunk?

Thanks,

Martin


2013-02-19  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/56310
	* ipa-cp.c (agg_replacements_to_vector): New parameter index, copy
	only matching indices and non-negative final offsets.
	(intersect_aggregates_with_edge): Pass src_idx to
	agg_replacements_to_vector.  Pass src_idx insstead of index to
	intersect_with_agg_replacements.

testsuite/
	* g++.dg/ipa/pr56310.C: New test.
Jan Hubicka - Feb. 20, 2013, 8:56 p.m.
> Hi,
> 
> this patch fixes an omission in IPA-CP's agg_replacements_to_vector
> which needs to filter the vector by index and offset and a typo in
> intersect_aggregates_with_edge which in one call passed the wrong
> index to agg_replacements_to_vector.  This combined lead to empty
> intersections which were caught by an assert checking exactly that.
> 
> Bootstrapped and tested on x86_64-linux (all languages + Ada) with
> default BOOT_CFLAGS and also with BOOT_CFLAGS='-O2 -g -fipa-cp-clone
> --param=ipa-cp-eval-threshold=100' (C, C++ and Fortran only), I'm
> currently bootstrapping with the param set to 1.
> 
> OK for trunk?
OK, thanks!
Honza

Patch

Index: src/gcc/ipa-cp.c
===================================================================
--- src.orig/gcc/ipa-cp.c
+++ src/gcc/ipa-cp.c
@@ -2807,12 +2807,15 @@  intersect_with_plats (struct ipcp_param_
    vector result while subtracting OFFSET from the individual value offsets.  */
 
 static vec<ipa_agg_jf_item_t>
-agg_replacements_to_vector (struct cgraph_node *node, HOST_WIDE_INT offset)
+agg_replacements_to_vector (struct cgraph_node *node, int index,
+			    HOST_WIDE_INT offset)
 {
   struct ipa_agg_replacement_value *av;
   vec<ipa_agg_jf_item_t> res = vNULL;
 
   for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
+    if (av->index == index
+	&& (av->offset - offset) >= 0)
     {
       struct ipa_agg_jf_item item;
       gcc_checking_assert (av->value);
@@ -2892,7 +2895,7 @@  intersect_aggregates_with_edge (struct c
 	  if (agg_pass_through_permissible_p (orig_plats, jfunc))
 	    {
 	      if (!inter.exists ())
-		inter = agg_replacements_to_vector (cs->caller, 0);
+		inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
 	      else
 		intersect_with_agg_replacements (cs->caller, src_idx,
 						 &inter, 0);
@@ -2925,9 +2928,9 @@  intersect_aggregates_with_edge (struct c
       if (caller_info->ipcp_orig_node)
 	{
 	  if (!inter.exists ())
-	    inter = agg_replacements_to_vector (cs->caller, delta);
+	    inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
 	  else
-	    intersect_with_agg_replacements (cs->caller, index, &inter,
+	    intersect_with_agg_replacements (cs->caller, src_idx, &inter,
 					     delta);
 	}
       else
Index: src/gcc/testsuite/g++.dg/ipa/pr56310.C
===================================================================
--- /dev/null
+++ src/gcc/testsuite/g++.dg/ipa/pr56310.C
@@ -0,0 +1,36 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fipa-cp -std=gnu++0x -fno-early-inlining -fipa-cp-clone --param=ipa-cp-eval-threshold=1" } */
+
+void bar (void *, void *);
+
+struct C
+{
+  constexpr C ():p (0)
+  {
+  }
+  void *get ()
+  {
+    return p;
+  }
+  void *p;
+};
+
+struct B:C
+{
+};
+
+struct A
+{
+  void f (B * x, B * y)
+  {
+    bar (x->get (), y->get ());
+  }
+};
+
+void
+foo ()
+{
+  A a;
+  B b;
+  a.f (&b, &b);
+}