> 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" } } */