> On Fri, Feb 20, 2015 at 12:39:29AM +0100, Jan Hubicka wrote:
> > Hi,
> > this patch fixes alignment propagation that causes wrong code on solex and 
> > firefox.
> > Patch is by Martin, I just added the obvous MINUS_EXPR fix (the offset 
> > would be wrong,
> > but I see no reason for MINUX_ExPR appearing there with constant 
> > parameter), went
> > ahead and commited the fix.
> > 
> > Tested on x86_64-linux.
> 
> Two nits:
> 
> > Index: ChangeLog
> > ===================================================================
> > --- ChangeLog       (revision 220825)
> > +++ ChangeLog       (working copy)
> > @@ -1,3 +1,10 @@
> > +2015-02-19  Martin Jambor  <mjma...@suse.cz>
> 
> Typo in the e-mail address.
> 
> 
> Two ;'s at the end of the line.

Oops, looks like celebrations of lunar new year was bit too devastating.
This is followup patch that also fixes ;; issue.
It makes the alignment propagation to do proper lattice operations instead
of requiring perfect match and dropping everything to bottom otherwise.
Martin, does it look OK?

        * ipa-cp.c (ipcp_verify_propagated_values): Verify that there
        are no bottoms in alignment.
        (decrease_alignment, increase_alignment): New functions.
        (propagate_alignment_accross_jump_function): Use proper lattice
        operations
        * ipa-cp-1.c: New testcase.
        * ipa-cp-2.c: New testcase.
Index: ipa-cp.c
===================================================================
--- ipa-cp.c    (revision 220826)
+++ ipa-cp.c    (working copy)
@@ -1041,10 +1041,14 @@ ipcp_verify_propagated_values (void)
       for (i = 0; i < count; i++)
        {
          ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
+         struct ipcp_param_lattices *plats;
+         plats = ipa_get_parm_lattices (info, i);
 
-         if (!lat->bottom
-             && !lat->contains_variable
-             && lat->values_count == 0)
+         if ((!lat->bottom
+              && !lat->contains_variable
+              && lat->values_count == 0)
+             || (!plats->alignment.known
+                 && opt_for_fn (node->decl, flag_ipa_cp_alignment)))
            {
              if (dump_file)
                {
@@ -1409,6 +1413,60 @@ propagate_context_accross_jump_function
   return ret;
 }
 
+/* Decrease alignment info DEST to be at most CUR.  */
+
+static bool
+decrease_alignment (ipa_alignment *dest, ipa_alignment cur)
+{
+  bool changed = false;
+
+  if (!cur.known)
+    return false;
+  if (!dest->known)
+    {
+      *dest = cur;
+      return true;
+    }
+  if (dest->align == cur.align
+      && dest->misalign == cur.misalign)
+    return false;
+
+  if (dest->align > cur.align)
+    {
+      dest->align = cur.align;
+      if (cur.align)
+       dest->misalign
+         = dest->misalign % cur.align;
+      changed = true;
+    }
+  if (dest->align && (dest->misalign != (cur.misalign % dest->align)))
+    {
+      int diff = abs (dest->misalign
+                     - (cur.misalign % dest->align));
+      dest->align = MIN (dest->align, (unsigned)diff & - diff);
+      if (dest->align)
+       dest->misalign
+         = dest->misalign % dest->align;
+      changed = true;
+    }
+  return changed;
+}
+
+/* Increase alignment info DEST to be at least CUR.  */
+
+static bool
+increase_alignment (ipa_alignment *dest, ipa_alignment cur)
+{
+  if (!dest->known)
+    return false;
+  if (!cur.known || dest->align < cur.align)
+    {
+      *dest = cur;
+      return true;
+    }
+  return false;
+}
+
 /* Propagate alignments across jump function JFUNC that is associated with
    edge CS and update DEST_LAT accordingly.  */
 
@@ -1420,17 +1478,25 @@ propagate_alignment_accross_jump_functio
   if (alignment_bottom_p (dest_lat))
     return false;
 
-  ipa_alignment cur;
-  cur.known = false;
-  if (jfunc->alignment.known)
-    cur = jfunc->alignment;
-  else if (jfunc->type == IPA_JF_PASS_THROUGH
-          || jfunc->type == IPA_JF_ANCESTOR)
+  ipa_alignment cur = jfunc->alignment;
+
+  /* For some reason UNKNOWN jump function gets alignment to be TOP
+     instead of BOTTOM.  */
+  if (!cur.known)
+    {
+      cur.known = true;
+      cur.align = 0;
+    }
+
+  if (jfunc->type == IPA_JF_PASS_THROUGH
+      || jfunc->type == IPA_JF_ANCESTOR)
     {
       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
       struct ipcp_param_lattices *src_lats;
       HOST_WIDE_INT offset = 0;
       int src_idx;
+      ipa_alignment incomming_cur;
+      bool ok = true;
 
       if (jfunc->type == IPA_JF_PASS_THROUGH)
        {
@@ -1439,44 +1505,34 @@ propagate_alignment_accross_jump_functio
            {
              if (op != POINTER_PLUS_EXPR
                  && op != PLUS_EXPR)
-               goto prop_fail;
+               ok = false;
              tree operand = ipa_get_jf_pass_through_operand (jfunc);
              if (!tree_fits_shwi_p (operand))
-               goto prop_fail;
-             offset = tree_to_shwi (operand);
+               ok = false;
+             else
+               offset = tree_to_shwi (operand);
            }
          src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
        }
       else
        {
          src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
-         offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;;
+         offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
        }
 
-      src_lats = ipa_get_parm_lattices (caller_info, src_idx);
-      if (!src_lats->alignment.known
-         || alignment_bottom_p (src_lats))
-       goto prop_fail;
-
-      cur = src_lats->alignment;
-      cur.misalign = (cur.misalign + offset) % cur.align;
-    }
-
-  if (cur.known)
-    {
-      if (!dest_lat->alignment.known)
+      if (ok)
        {
-         dest_lat->alignment = cur;
-         return true;
+         src_lats = ipa_get_parm_lattices (caller_info, src_idx);
+
+         incomming_cur = src_lats->alignment;
+         if (incomming_cur.known && incomming_cur.align)
+           incomming_cur.misalign = (incomming_cur.misalign + offset)
+                                    % incomming_cur.align;
+         increase_alignment (&cur, incomming_cur);
        }
-      else if (dest_lat->alignment.align == cur.align
-              && dest_lat->alignment.misalign == cur.misalign)
-       return false;
     }
 
- prop_fail:
-  set_alignment_to_bottom (dest_lat);
-  return true;
+  return decrease_alignment (&dest_lat->alignment, cur);
 }
 
 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
Index: testsuite/gcc.dg/ipa/ipa-cp-2.c
===================================================================
--- testsuite/gcc.dg/ipa/ipa-cp-2.c     (revision 0)
+++ testsuite/gcc.dg/ipa/ipa-cp-2.c     (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp"  } */
+int n;
+
+static void
+__attribute__ ((noinline))
+test(void *a)
+{
+  __builtin_memset (a,0,n);
+}
+
+static __attribute__ ((aligned(16))) int aa[10];
+
+int
+main()
+{
+  test (&aa[1]);
+  test (&aa[3]);
+  return 0;
+}
+/* { dg-final { scan-ipa-dump "Alignment 8, misalignment 4"  "cp"  } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
Index: testsuite/gcc.dg/ipa/ipa-cp-1.c
===================================================================
--- testsuite/gcc.dg/ipa/ipa-cp-1.c     (revision 0)
+++ testsuite/gcc.dg/ipa/ipa-cp-1.c     (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp"  } */
+int n;
+
+static void
+__attribute__ ((noinline))
+test(void *a)
+{
+  __builtin_memset (a,0,n);
+}
+
+int
+main()
+{
+  int aa;
+  short bb;
+  test (&aa);
+  test (&bb);
+  return 0;
+}
+/* { dg-final { scan-ipa-dump "Alignment 2"  "cp"  } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */

Reply via email to