diff mbox

[RFC] Extend ipa-bitwise-cp with pointer alignment propagation

Message ID CAAgBjMkKUS+jkqQc4sRWZO=WDumTsNLH228uSAHm_UVrKAXGHQ@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni Oct. 6, 2016, 4:55 a.m. UTC
On 5 October 2016 at 19:45, Martin Jambor <mjambor@suse.cz> wrote:
> Hi,
>
> sorry, my main desktop disk has died (a slow but certain) death so I
> am not particularly responsive either.
>
> On Tue, Oct 04, 2016 at 12:37:38AM +0530, Prathamesh Kulkarni wrote:
>> On 22 September 2016 at 17:26, Jan Hubicka <hubicka@ucw.cz> wrote:
>> > Yes, can you please verify that alignments it computes are monotonously
>> > worse than those your new code computes and include the removal in the
>> > next iteration of the patch?
>> >>
>> > Otherwise the patch seems fine to me (modulo Richard's comments)
>
>
>> I tried to verify the alignments are monotonously worse with the
>> attached patch (verify.diff),
>> which asserts that alignment lattice is not better than bits lattice
>> during each propagation
>> step in propagate_constants_accross_call().
>> Does that look OK ?
>
> After propagation, here should be no TOP lattices anywhere.  That
> would mean we have not delteted an unreachable node.  Apart from that,
> yes.
>
>>
>> ipa-cp-alignment has better alignments than ipa-bit-cp in following cases:
>>
>> a) ipa_get_type() returns NULL: ipa-bits-cp sets lattice to bottom if
>> ipa_get_type (param) returns NULL,
>> for instance in case of K&R function, while ipa-cp-alignment doesn't
>
> What do you mean by "for instance?"  What are the other cases when it
> happens?
Well ipa_get_type() returned NULL for 481.wrf, and I assumed it was a
fortran-only
code-base but apparently it's a mix of C and fortran.
ipa_get_type() returned NULL for param 'n' in
get_initial_data_value_() which is defined
as K&R style function in wrf_num_bytes_between.c, so it seems K&R is the
only case where ipa_get_type() returns NULL.

I have a question though on how to reduce fortran test-cases or a mix
of fortran/C
like 481.wrf ? For C/C++ only tests-cases, I use creduce.
>
>> look at param types,
>> and can propagate alignments.
>> The following assert:
>> if (bits_lattice.bottom_p ())
>>   gcc_assert (align_lattice.bottom_p())
>>
>> triggered for 400.perlbench, 403.gcc, 456.hmmer and 481.wrf due to
>
> that is quite many more examples than I have anticipated, so they all
> used K&R?   (But thanks for trying benchmarks diligently).
>
> Have also tried this with LTO?
Yes, the benchmarks were built with -O2 -flto.
>
>> ipa_get_type()
>> returning NULL. I am not really sure how to handle this case, since we
>> need to know parameter's
>> type during bits propagation for obtaining precision.
>>
>> b) This happens for attached test-case (test.i),
>> which is a reduced (and slightly modified) test-case from 458.sjeng.
>> Bits propagation sets lattice to bottom, while alignment propagation
>> propagates <align 1, misalign 0>.
>
> yes, I agree we do not need to worry about the case when alignment is 1.
>
> I am only slightly concerned how often ipa_get_type is NULL, so it
> would be nice if you looked into those cases once more to make sure
> that we do not miss some bug or something that we could handle easily.
> But if it is only K&R, I think it is fine.
Yes, I think it is only for K&R case.
The attached patch marks option -fipa-cp-alignment as obsolete instead
of removing it.
I just added a note to invoke.texi for @item -fipa-cp-alignment.
Not sure if that's entirely correct.

Bootstrapped+tested on x86_64-unknown-linux-gnu, ppc64le-linux-gnu
Cross tested on arm*-*-*, aarch64*-*-*.
OK for trunk ?

Thanks,
Prathamesh
>
> Thanks,
>
> Martin
2016-10-06  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	* ipa-cp.c (ipcp_alignment_lattice): Remove.
	(ipcp_param_lattices): Remove field alignment.
	(print_all_lattices): Remove call to ipcp_alignment_lattice::print.
	(set_all_contains_variable): Remove call to
	ipcp_alignment_lattice::set_to_bottom.
	(initialize_node_lattices): Likewise.
	(propagate_alignment_accross_jump_function): Remove.
	(propagate_constants_accross_call): Remove call to
	propagate_alignment_accross_jump_function.
	(ipcp_store_alignment_results): Remove.
	(ipcp_driver): Remove call to ipcp_store_alignment_results.
	(propagate_bits_accross_jump_function): Handle ancestor jump function.
	* ipa-prop.c (ipa_print_node_jump_functions_for_edge): Remove
	pretty-printing of alignment jump function.
	(ipa_set_jf_unknown): Remove assignment to jfunc->alignment.known.
	(ipa_compute_jump_functions_for_edge): Adjust ipa_bits jump function for
	alignments and remove computing ipa_alignment jump function.
	(ipa_node_params_t::duplicate): Remove copying of src_trans->alignments.
	(ipa_write_jump_functions): Remove streaming for ipa_alignment.
	(ipa_read_jump_function): Remove reading of ipa_alignment.
	(write_ipcp_transformation_info): Remove streaming for alignment
	propagation summary.
	(read_ipcp_transformation_info): Remove reading of alignment
	propagation summary. 
	(ipcp_update_alignments): Remove.
	(ipcp_update_bits): Adjust to set alignment for parameters of pointer
	type.
	(ipcp_transform_function): Remove call to ipcp_update_alignments()
	and remove assignment to (*ipcp_transformations)[node->uid].alignments.
	* ipa-prop.h (ipa_alignment): Remove.
	(ipa_jump_func): Remove field alignment.
	(ipcp_transformation_summary): Remove field alignments. 
	* doc/invoke.texi: Mark fipa-cp-alignment as obsolete.
	* opts.c (default_options_table): Remove entry for fipa-cp-alignment.
	(enable_fdo_optimizations): Remove checking for fipa-cp-alignment.

testsuite/
	* gcc.dg/ipa/propalign-1.c: Adjust scan-ipa-dump.
	* gcc.dg/ipa/propalign-2.c: Likewise
	* gcc.dg/ipa/propalign-3.c: Likewise.
	* gcc.dg/ipa/propalign-4.c: Likewise.
	* gcc.dg/ipa/propalign-5.c: Likewise.

Comments

Jan Hubicka Oct. 6, 2016, 1:21 p.m. UTC | #1
> >
> > What do you mean by "for instance?"  What are the other cases when it
> > happens?
> Well ipa_get_type() returned NULL for 481.wrf, and I assumed it was a
> fortran-only
> code-base but apparently it's a mix of C and fortran.

Yep, I also have expreinece that the K&R style declarations are more common
than one would expect 30 years after the language was obsoletted.
> ipa_get_type() returned NULL for param 'n' in
> get_initial_data_value_() which is defined
> as K&R style function in wrf_num_bytes_between.c, so it seems K&R is the
> only case where ipa_get_type() returns NULL.
> 
> I have a question though on how to reduce fortran test-cases or a mix
> of fortran/C
> like 481.wrf ? For C/C++ only tests-cases, I use creduce.

I use delta/multidelta
https://gcc.gnu.org/wiki/A_guide_to_testcase_reduction

It works pretty well and one can reduce first list of files and then file at a
time.

Honza
Prathamesh Kulkarni Oct. 6, 2016, 8:54 p.m. UTC | #2
On 6 October 2016 at 18:51, Jan Hubicka <hubicka@ucw.cz> wrote:
>> >
>> > What do you mean by "for instance?"  What are the other cases when it
>> > happens?
>> Well ipa_get_type() returned NULL for 481.wrf, and I assumed it was a
>> fortran-only
>> code-base but apparently it's a mix of C and fortran.
>
> Yep, I also have expreinece that the K&R style declarations are more common
> than one would expect 30 years after the language was obsoletted.
>> ipa_get_type() returned NULL for param 'n' in
>> get_initial_data_value_() which is defined
>> as K&R style function in wrf_num_bytes_between.c, so it seems K&R is the
>> only case where ipa_get_type() returns NULL.
>>
>> I have a question though on how to reduce fortran test-cases or a mix
>> of fortran/C
>> like 481.wrf ? For C/C++ only tests-cases, I use creduce.
>
> I use delta/multidelta
> https://gcc.gnu.org/wiki/A_guide_to_testcase_reduction
>
> It works pretty well and one can reduce first list of files and then file at a
> time.
Thanks! I will try to reduce 481.wrf assert ICE for practice -;)
Is the alignment propagation patch OK to commit ?

Thanks,
Prathamesh
>
> Honza
Jan Hubicka Oct. 8, 2016, 5:31 p.m. UTC | #3
> On 6 October 2016 at 18:51, Jan Hubicka <hubicka@ucw.cz> wrote:
> >> >
> >> > What do you mean by "for instance?"  What are the other cases when it
> >> > happens?
> >> Well ipa_get_type() returned NULL for 481.wrf, and I assumed it was a
> >> fortran-only
> >> code-base but apparently it's a mix of C and fortran.
> >
> > Yep, I also have expreinece that the K&R style declarations are more common
> > than one would expect 30 years after the language was obsoletted.
> >> ipa_get_type() returned NULL for param 'n' in
> >> get_initial_data_value_() which is defined
> >> as K&R style function in wrf_num_bytes_between.c, so it seems K&R is the
> >> only case where ipa_get_type() returns NULL.
> >>
> >> I have a question though on how to reduce fortran test-cases or a mix
> >> of fortran/C
> >> like 481.wrf ? For C/C++ only tests-cases, I use creduce.
> >
> > I use delta/multidelta
> > https://gcc.gnu.org/wiki/A_guide_to_testcase_reduction
> >
> > It works pretty well and one can reduce first list of files and then file at a
> > time.
> Thanks! I will try to reduce 481.wrf assert ICE for practice -;)
> Is the alignment propagation patch OK to commit ?
OK,
Honza
> 
> Thanks,
> Prathamesh
> >
> > Honza
diff mbox

Patch

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d9667e7..b7ca2b6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -7657,6 +7657,7 @@  parameters to support better vectorization and string operations.
 
 This flag is enabled by default at @option{-O2} and @option{-Os}.  It
 requires that @option{-fipa-cp} is enabled.
+@option{-fipa-cp-alignment} is obsolete, use @option{-fipa-bit-cp} instead.
 
 @item -fipa-bit-cp
 @opindex -fipa-bit-cp
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 7380b2a..1dc5cb6 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -238,36 +238,6 @@  public:
   struct ipcp_agg_lattice *next;
 };
 
-/* Lattice of pointer alignment.  Unlike the previous types of lattices, this
-   one is only capable of holding one value.  */
-
-class ipcp_alignment_lattice
-{
-public:
-  /* If bottom and top are both false, these two fields hold values as given by
-     ptr_info_def and get_pointer_alignment_1.  */
-  unsigned align;
-  unsigned misalign;
-
-  inline bool bottom_p () const;
-  inline bool top_p () const;
-  inline bool set_to_bottom ();
-  bool meet_with (unsigned new_align, unsigned new_misalign);
-  bool meet_with (const ipcp_alignment_lattice &other, HOST_WIDE_INT offset);
-  void print (FILE * f);
-private:
-  /* If set, this lattice is bottom and all other fields should be
-     disregarded.  */
-  bool bottom;
-  /* If bottom and not_top are false, the lattice is TOP.  If not_top is true,
-     the known alignment is stored in the fields align and misalign.  The field
-     is negated so that memset to zero initializes the lattice to TOP
-     state.  */
-  bool not_top;
-
-  bool meet_with_1 (unsigned new_align, unsigned new_misalign);
-};
-
 /* Lattice of known bits, only capable of holding one value.
    Bitwise constant propagation propagates which bits of a
    value are constant.
@@ -354,8 +324,6 @@  public:
   ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
   /* Lattices describing aggregate parts.  */
   ipcp_agg_lattice *aggs;
-  /* Lattice describing known alignment.  */
-  ipcp_alignment_lattice alignment;
   /* Lattice describing known bits.  */
   ipcp_bits_lattice bits_lattice;
   /* Lattice describing value range.  */
@@ -534,19 +502,6 @@  ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
     fprintf (f, "\n");
 }
 
-/* Print alignment lattice to F.  */
-
-void
-ipcp_alignment_lattice::print (FILE * f)
-{
-  if (top_p ())
-    fprintf (f, "         Alignment unknown (TOP)\n");
-  else if (bottom_p ())
-    fprintf (f, "         Alignment unusable (BOTTOM)\n");
-  else
-    fprintf (f, "         Alignment %u, misalignment %u\n", align, misalign);
-}
-
 void
 ipcp_bits_lattice::print (FILE *f)
 {
@@ -595,7 +550,6 @@  print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
 	  plats->itself.print (f, dump_sources, dump_benefits);
 	  fprintf (f, "         ctxs: ");
 	  plats->ctxlat.print (f, dump_sources, dump_benefits);
-	  plats->alignment.print (f);
 	  plats->bits_lattice.print (f);
 	  fprintf (f, "         ");
 	  plats->m_value_range.print (f);
@@ -922,38 +876,6 @@  set_agg_lats_contain_variable (struct ipcp_param_lattices *plats)
   return ret;
 }
 
-/* Return true if alignment information in the lattice is yet unknown.  */
-
-bool
-ipcp_alignment_lattice::top_p () const
-{
-  return !bottom && !not_top;
-}
-
-/* Return true if alignment information in the lattice is known to be
-   unusable.  */
-
-bool
-ipcp_alignment_lattice::bottom_p () const
-{
-  return bottom;
-}
-
-/* Set alignment information in the lattice to bottom.  Return true if it
-   previously was in a different state.  */
-
-bool
-ipcp_alignment_lattice::set_to_bottom ()
-{
-  if (bottom_p ())
-    return false;
-  bottom = true;
-  return true;
-}
-
-/* Meet the current value of the lattice with described by OTHER
-   lattice.  */
-
 bool
 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
 {
@@ -1022,82 +944,6 @@  ipcp_vr_lattice::set_to_bottom ()
   return true;
 }
 
-/* Meet the current value of the lattice with alignment described by NEW_ALIGN
-   and NEW_MISALIGN, assuming that we know the current value is neither TOP nor
-   BOTTOM.  Return true if the value of lattice has changed.  */
-
-bool
-ipcp_alignment_lattice::meet_with_1 (unsigned new_align, unsigned new_misalign)
-{
-  gcc_checking_assert (new_align != 0);
-  if (align == new_align && misalign == new_misalign)
-    return false;
-
-  bool changed = false;
-  if (align > new_align)
-    {
-      align = new_align;
-      misalign = misalign % new_align;
-      changed = true;
-    }
-  if (misalign != (new_misalign % align))
-    {
-      int diff = abs ((int) misalign - (int) (new_misalign % align));
-      align = least_bit_hwi (diff);
-      if (align)
-	misalign = misalign % align;
-      else
-	set_to_bottom ();
-      changed = true;
-    }
-  gcc_checking_assert (bottom_p () || align != 0);
-  return changed;
-}
-
-/* Meet the current value of the lattice with alignment described by NEW_ALIGN
-   and NEW_MISALIGN.  Return true if the value of lattice has changed.  */
-
-bool
-ipcp_alignment_lattice::meet_with (unsigned new_align, unsigned new_misalign)
-{
-  gcc_assert (new_align != 0);
-  if (bottom_p ())
-    return false;
-  if (top_p ())
-    {
-      not_top = true;
-      align = new_align;
-      misalign = new_misalign;
-      return true;
-    }
-  return meet_with_1 (new_align, new_misalign);
-}
-
-/* Meet the current value of the lattice with OTHER, taking into account that
-   OFFSET has been added to the pointer value.  Return true if the value of
-   lattice has changed.  */
-
-bool
-ipcp_alignment_lattice::meet_with (const ipcp_alignment_lattice &other,
-				   HOST_WIDE_INT offset)
-{
-  if (other.bottom_p ())
-    return set_to_bottom ();
-  if (bottom_p () || other.top_p ())
-    return false;
-
-  unsigned adjusted_misalign = (other.misalign + offset) % other.align;
-  if (top_p ())
-    {
-      not_top = true;
-      align = other.align;
-      misalign = adjusted_misalign;
-      return true;
-    }
-
-  return meet_with_1 (other.align, adjusted_misalign);
-}
-
 /* Set lattice value to bottom, if it already isn't the case.  */
 
 bool
@@ -1253,7 +1099,6 @@  set_all_contains_variable (struct ipcp_param_lattices *plats)
   ret = plats->itself.set_contains_variable ();
   ret |= plats->ctxlat.set_contains_variable ();
   ret |= set_agg_lats_contain_variable (plats);
-  ret |= plats->alignment.set_to_bottom ();
   ret |= plats->bits_lattice.set_to_bottom ();
   ret |= plats->m_value_range.set_to_bottom ();
   return ret;
@@ -1342,7 +1187,6 @@  initialize_node_lattices (struct cgraph_node *node)
 	      plats->itself.set_to_bottom ();
 	      plats->ctxlat.set_to_bottom ();
 	      set_agg_lats_to_bottom (plats);
-	      plats->alignment.set_to_bottom ();
 	      plats->bits_lattice.set_to_bottom ();
 	      plats->m_value_range.set_to_bottom ();
 	    }
@@ -1910,59 +1754,6 @@  propagate_context_accross_jump_function (cgraph_edge *cs,
   return ret;
 }
 
-/* Propagate alignments across jump function JFUNC that is associated with
-   edge CS and update DEST_LAT accordingly.  */
-
-static bool
-propagate_alignment_accross_jump_function (cgraph_edge *cs,
-					   ipa_jump_func *jfunc,
-					   ipcp_alignment_lattice *dest_lat)
-{
-  if (dest_lat->bottom_p ())
-    return false;
-
-  if (jfunc->type == IPA_JF_PASS_THROUGH
-	   || jfunc->type == IPA_JF_ANCESTOR)
-    {
-      struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
-      HOST_WIDE_INT offset = 0;
-      int src_idx;
-
-      if (jfunc->type == IPA_JF_PASS_THROUGH)
-	{
-	  enum tree_code op = ipa_get_jf_pass_through_operation (jfunc);
-	  if (op != NOP_EXPR)
-	    {
-	      if (op != POINTER_PLUS_EXPR
-		  && op != PLUS_EXPR)
-		return dest_lat->set_to_bottom ();
-	      tree operand = ipa_get_jf_pass_through_operand (jfunc);
-	      if (!tree_fits_shwi_p (operand))
-		return dest_lat->set_to_bottom ();
-	      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;
-	}
-
-      struct ipcp_param_lattices *src_lats;
-      src_lats = ipa_get_parm_lattices (caller_info, src_idx);
-      return dest_lat->meet_with (src_lats->alignment, offset);
-    }
-  else
-    {
-      if (jfunc->alignment.known)
-	return dest_lat->meet_with (jfunc->alignment.align,
-				    jfunc->alignment.misalign);
-      else
-	return dest_lat->set_to_bottom ();
-    }
-}
-
 /* Propagate bits across jfunc that is associated with
    edge cs and update dest_lattice accordingly.  */
 
@@ -1993,16 +1784,29 @@  propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j
   unsigned precision = TYPE_PRECISION (parm_type);
   signop sgn = TYPE_SIGN (parm_type);
 
-  if (jfunc->type == IPA_JF_PASS_THROUGH)
+  if (jfunc->type == IPA_JF_PASS_THROUGH
+      || jfunc->type == IPA_JF_ANCESTOR)
     {
       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
-      enum tree_code code = ipa_get_jf_pass_through_operation (jfunc);
       tree operand = NULL_TREE;
+      enum tree_code code;
+      unsigned src_idx;
 
-      if (code != NOP_EXPR)
-	operand = ipa_get_jf_pass_through_operand (jfunc);
+      if (jfunc->type == IPA_JF_PASS_THROUGH)
+	{
+	  code = ipa_get_jf_pass_through_operation (jfunc);
+	  src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
+	  if (code != NOP_EXPR)
+	    operand = ipa_get_jf_pass_through_operand (jfunc);
+	}
+      else
+	{
+	  code = POINTER_PLUS_EXPR; 
+	  src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
+	  unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
+	  operand = build_int_cstu (size_type_node, offset);
+	}
 
-      int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
       struct ipcp_param_lattices *src_lats
 	= ipa_get_parm_lattices (caller_info, src_idx);
 
@@ -2426,8 +2230,6 @@  propagate_constants_accross_call (struct cgraph_edge *cs)
 							 &dest_plats->itself);
 	  ret |= propagate_context_accross_jump_function (cs, jump_func, i,
 							  &dest_plats->ctxlat);
-	  ret |= propagate_alignment_accross_jump_function (cs, jump_func,
-							 &dest_plats->alignment);
 	  ret |= propagate_bits_accross_jump_function (cs, i, jump_func,
 						       &dest_plats->bits_lattice);
 	  ret |= propagate_aggs_accross_jump_function (cs, jump_func,
@@ -4997,81 +4799,6 @@  ipcp_decision_stage (struct ipa_topo_info *topo)
     }
 }
 
-/* Look up all alignment information that we have discovered and copy it over
-   to the transformation summary.  */
-
-static void
-ipcp_store_alignment_results (void)
-{
-  cgraph_node *node;
-
-  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
-  {
-    ipa_node_params *info = IPA_NODE_REF (node);
-    bool dumped_sth = false;
-    bool found_useful_result = false;
-
-    if (!opt_for_fn (node->decl, flag_ipa_cp_alignment))
-      {
-	if (dump_file)
-	  fprintf (dump_file, "Not considering %s for alignment discovery "
-		   "and propagate; -fipa-cp-alignment: disabled.\n",
-		   node->name ());
-	continue;
-      }
-
-   if (info->ipcp_orig_node)
-      info = IPA_NODE_REF (info->ipcp_orig_node);
-
-   unsigned count = ipa_get_param_count (info);
-   for (unsigned i = 0; i < count ; i++)
-     {
-       ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
-       if (!plats->alignment.bottom_p ()
-	   && !plats->alignment.top_p ())
-	 {
-	   gcc_checking_assert (plats->alignment.align > 0);
-	   found_useful_result = true;
-	   break;
-	 }
-     }
-   if (!found_useful_result)
-     continue;
-
-   ipcp_grow_transformations_if_necessary ();
-   ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-   vec_safe_reserve_exact (ts->alignments, count);
-
-   for (unsigned i = 0; i < count ; i++)
-     {
-       ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
-       ipa_alignment al;
-
-       if (!plats->alignment.bottom_p ()
-	   && !plats->alignment.top_p ())
-	 {
-	   al.known = true;
-	   al.align = plats->alignment.align;
-	   al.misalign = plats->alignment.misalign;
-	 }
-       else
-	 al.known = false;
-
-       ts->alignments->quick_push (al);
-       if (!dump_file || !al.known)
-	 continue;
-       if (!dumped_sth)
-	 {
-	   fprintf (dump_file, "Propagated alignment info for function %s/%i:\n",
-		    node->name (), node->order);
-	   dumped_sth = true;
-	 }
-       fprintf (dump_file, "  param %i: align: %u, misalign: %u\n",
-		i, al.align, al.misalign);
-     }
-  }
-}
-
 /* Look up all the bits information that we have discovered and copy it over
    to the transformation summary.  */
 
@@ -5246,8 +4973,6 @@  ipcp_driver (void)
   ipcp_propagate_stage (&topo);
   /* Decide what constant propagation and cloning should be performed.  */
   ipcp_decision_stage (&topo);
-  /* Store results of alignment propagation. */
-  ipcp_store_alignment_results ();
   /* Store results of bits propagation.  */
   ipcp_store_bits_results ();
   /* Store results of value range propagation.  */
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 302a479..a981efd 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -294,15 +294,6 @@  ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 	  ctx->dump (dump_file);
 	}
 
-      if (jump_func->alignment.known)
-	{
-	  fprintf (f, "         Alignment: %u, misalignment: %u\n",
-		   jump_func->alignment.align,
-		   jump_func->alignment.misalign);
-	}
-      else
-	fprintf (f, "         Unknown alignment\n");
-
       if (jump_func->bits.known)
 	{
 	  fprintf (f, "         value: "); print_hex (jump_func->bits.value, f);
@@ -402,7 +393,6 @@  static void
 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
 {
   jfunc->type = IPA_JF_UNKNOWN;
-  jfunc->alignment.known = false;
   jfunc->bits.known = false;
   jfunc->vr_known = false;
 }
@@ -1678,25 +1668,7 @@  ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	    useful_context = true;
 	}
 
-      if (POINTER_TYPE_P (TREE_TYPE(arg)))
-	{
-	  unsigned HOST_WIDE_INT hwi_bitpos;
-	  unsigned align;
-
-	  get_pointer_alignment_1 (arg, &align, &hwi_bitpos);
-	  if (align > BITS_PER_UNIT
-	      && align % BITS_PER_UNIT == 0
-	      && hwi_bitpos % BITS_PER_UNIT == 0)
-	    {
-	      jfunc->alignment.known = true;
-	      jfunc->alignment.align = align / BITS_PER_UNIT;
-	      jfunc->alignment.misalign = hwi_bitpos / BITS_PER_UNIT;
-	    }
-	  else
-	    gcc_assert (!jfunc->alignment.known);
-	  gcc_assert (!jfunc->vr_known);
-	}
-      else
+      if (!POINTER_TYPE_P (TREE_TYPE (arg)))
 	{
 	  wide_int min, max;
 	  value_range_type type;
@@ -1723,7 +1695,6 @@  ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	    }
 	  else
 	    gcc_assert (!jfunc->vr_known);
-	  gcc_assert (!jfunc->alignment.known);
 	}
 
       if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
@@ -1743,6 +1714,17 @@  ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	      jfunc->bits.mask = 0;
 	    }
 	}
+      else if (POINTER_TYPE_P (TREE_TYPE (arg)))
+	{
+	  unsigned HOST_WIDE_INT bitpos;
+	  unsigned align;
+
+	  jfunc->bits.known = true;
+	  get_pointer_alignment_1 (arg, &align, &bitpos);
+	  jfunc->bits.mask = wi::mask<widest_int>(TYPE_PRECISION (TREE_TYPE (arg)), false)
+			     .and_not (align / BITS_PER_UNIT - 1);
+	  jfunc->bits.value = bitpos / BITS_PER_UNIT;
+	}
       else
 	gcc_assert (!jfunc->bits.known);
 
@@ -3755,18 +3737,9 @@  ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
     {
       ipcp_grow_transformations_if_necessary ();
       src_trans = ipcp_get_transformation_summary (src);
-      const vec<ipa_alignment, va_gc> *src_alignments = src_trans->alignments;
       const vec<ipa_vr, va_gc> *src_vr = src_trans->m_vr;
-      vec<ipa_alignment, va_gc> *&dst_alignments
-	= ipcp_get_transformation_summary (dst)->alignments;
       vec<ipa_vr, va_gc> *&dst_vr
 	= ipcp_get_transformation_summary (dst)->m_vr;
-      if (vec_safe_length (src_trans->alignments) > 0)
-	{
-	  vec_safe_reserve_exact (dst_alignments, src_alignments->length ());
-	  for (unsigned i = 0; i < src_alignments->length (); ++i)
-	    dst_alignments->quick_push ((*src_alignments)[i]);
-	}
       if (vec_safe_length (src_trans->m_vr) > 0)
 	{
 	  vec_safe_reserve_exact (dst_vr, src_vr->length ());
@@ -4698,15 +4671,6 @@  ipa_write_jump_function (struct output_block *ob,
     }
 
   bp = bitpack_create (ob->main_stream);
-  bp_pack_value (&bp, jump_func->alignment.known, 1);
-  streamer_write_bitpack (&bp);
-  if (jump_func->alignment.known)
-    {
-      streamer_write_uhwi (ob, jump_func->alignment.align);
-      streamer_write_uhwi (ob, jump_func->alignment.misalign);
-    }
-
-  bp = bitpack_create (ob->main_stream);
   bp_pack_value (&bp, jump_func->bits.known, 1);
   streamer_write_bitpack (&bp);
   if (jump_func->bits.known)
@@ -4790,17 +4754,6 @@  ipa_read_jump_function (struct lto_input_block *ib,
     }
 
   struct bitpack_d bp = streamer_read_bitpack (ib);
-  bool alignment_known = bp_unpack_value (&bp, 1);
-  if (alignment_known)
-    {
-      jump_func->alignment.known = true;
-      jump_func->alignment.align = streamer_read_uhwi (ib);
-      jump_func->alignment.misalign = streamer_read_uhwi (ib);
-    }
-  else
-    jump_func->alignment.known = false;
-
-  bp = streamer_read_bitpack (ib);
   bool bits_known = bp_unpack_value (&bp, 1);
   if (bits_known)
     {
@@ -5166,30 +5119,6 @@  write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
     }
 
   ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-  if (ts && vec_safe_length (ts->alignments) > 0)
-    {
-      count = ts->alignments->length ();
-
-      streamer_write_uhwi (ob, count);
-      for (unsigned i = 0; i < count; ++i)
-	{
-	  ipa_alignment *parm_al = &(*ts->alignments)[i];
-
-	  struct bitpack_d bp;
-	  bp = bitpack_create (ob->main_stream);
-	  bp_pack_value (&bp, parm_al->known, 1);
-	  streamer_write_bitpack (&bp);
-	  if (parm_al->known)
-	    {
-	      streamer_write_uhwi (ob, parm_al->align);
-	      streamer_write_hwi_in_range (ob->main_stream, 0, parm_al->align,
-					   parm_al->misalign);
-	    }
-	}
-    }
-  else
-    streamer_write_uhwi (ob, 0);
-
   if (ts && vec_safe_length (ts->m_vr) > 0)
     {
       count = ts->m_vr->length ();
@@ -5260,32 +5189,7 @@  read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
       aggvals = av;
     }
   ipa_set_node_agg_value_chain (node, aggvals);
-
-  count = streamer_read_uhwi (ib);
-  if (count > 0)
-    {
-      ipcp_grow_transformations_if_necessary ();
-
-      ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-      vec_safe_grow_cleared (ts->alignments, count);
-
-      for (i = 0; i < count; i++)
-	{
-	  ipa_alignment *parm_al;
-	  parm_al = &(*ts->alignments)[i];
-	  struct bitpack_d bp;
-	  bp = streamer_read_bitpack (ib);
-	  parm_al->known = bp_unpack_value (&bp, 1);
-	  if (parm_al->known)
-	    {
-	      parm_al->align = streamer_read_uhwi (ib);
-	      parm_al->misalign
-		= streamer_read_hwi_in_range (ib, "ipa-prop misalign",
-					      0, parm_al->align);
-	    }
-	}
-    }
-
+  
   count = streamer_read_uhwi (ib);
   if (count > 0)
     {
@@ -5579,58 +5483,6 @@  ipcp_modif_dom_walker::before_dom_children (basic_block bb)
   return NULL;
 }
 
-/* Update alignment of formal parameters as described in
-   ipcp_transformation_summary.  */
-
-static void
-ipcp_update_alignments (struct cgraph_node *node)
-{
-  tree fndecl = node->decl;
-  tree parm = DECL_ARGUMENTS (fndecl);
-  tree next_parm = parm;
-  ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-  if (!ts || vec_safe_length (ts->alignments) == 0)
-    return;
-  const vec<ipa_alignment, va_gc> &alignments = *ts->alignments;
-  unsigned count = alignments.length ();
-
-  for (unsigned i = 0; i < count; ++i, parm = next_parm)
-    {
-      if (node->clone.combined_args_to_skip
-	  && bitmap_bit_p (node->clone.combined_args_to_skip, i))
-	continue;
-      gcc_checking_assert (parm);
-      next_parm = DECL_CHAIN (parm);
-
-      if (!alignments[i].known || !is_gimple_reg (parm))
-	continue;
-      tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
-      if (!ddef)
-	continue;
-
-      if (dump_file)
-	fprintf (dump_file, "  Adjusting alignment of param %u to %u, "
-		 "misalignment to %u\n", i, alignments[i].align,
-		 alignments[i].misalign);
-
-      struct ptr_info_def *pi = get_ptr_info (ddef);
-      gcc_checking_assert (pi);
-      unsigned old_align;
-      unsigned old_misalign;
-      bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
-
-      if (old_known
-	  && old_align >= alignments[i].align)
-	{
-	  if (dump_file)
-	    fprintf (dump_file, "    But the alignment was already %u.\n",
-		     old_align);
-	  continue;
-	}
-      set_ptr_info_alignment (pi, alignments[i].align, alignments[i].misalign);
-    }
-}
-
 /* Update bits info of formal parameters as described in
    ipcp_transformation_summary.  */
 
@@ -5657,7 +5509,7 @@  ipcp_update_bits (struct cgraph_node *node)
       next_parm = DECL_CHAIN (parm);
 
       if (!bits[i].known
-	  || !INTEGRAL_TYPE_P (TREE_TYPE (parm))
+	  || !(INTEGRAL_TYPE_P (TREE_TYPE (parm)) || POINTER_TYPE_P (TREE_TYPE (parm)))
 	  || !is_gimple_reg (parm))
 	continue;       
 
@@ -5672,12 +5524,53 @@  ipcp_update_bits (struct cgraph_node *node)
 	  fprintf (dump_file, "\n");
 	}
 
-      unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
-      signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
+      if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
+	{
+	  unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
+	  signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
+
+	  wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED)
+				  | wide_int::from (bits[i].value, prec, sgn);
+	  set_nonzero_bits (ddef, nonzero_bits);
+	}
+      else
+	{
+	  unsigned tem = bits[i].mask.to_uhwi ();
+	  unsigned HOST_WIDE_INT bitpos = bits[i].value.to_uhwi (); 
+	  unsigned align = tem & -tem;
+	  unsigned misalign = bitpos & (align - 1);
 
-      wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED)
-			      | wide_int::from (bits[i].value, prec, sgn);
-      set_nonzero_bits (ddef, nonzero_bits);
+	  if (align > 1)
+	    {
+	      if (dump_file)
+		fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign); 
+
+	      unsigned old_align, old_misalign;
+	      struct ptr_info_def *pi = get_ptr_info (ddef);
+	      bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
+
+	      if (old_known
+		  && old_align > align)
+		{
+		  if (dump_file)
+		    {
+		      fprintf (dump_file, "But alignment was already %u.\n", old_align);
+		      if ((old_misalign & (align - 1)) != misalign)
+			fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
+				 old_misalign, misalign);
+		    }
+		  continue;
+		}
+
+	      if (old_known
+		  && ((misalign & (old_align - 1)) != old_misalign)
+		  && dump_file)
+		fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
+			 old_misalign, misalign);
+
+	      set_ptr_info_alignment (pi, align, misalign); 
+	    }
+	}
     }
 }
 
@@ -5752,7 +5645,6 @@  ipcp_transform_function (struct cgraph_node *node)
     fprintf (dump_file, "Modification phase of node %s/%i\n",
 	     node->name (), node->order);
 
-  ipcp_update_alignments (node);
   ipcp_update_bits (node);
   ipcp_update_vr (node);
   aggval = ipa_get_agg_replacements_for_node (node);
@@ -5785,7 +5677,6 @@  ipcp_transform_function (struct cgraph_node *node)
   fbi.bb_infos.release ();
   free_dominance_info (CDI_DOMINATORS);
   (*ipcp_transformations)[node->uid].agg_values = NULL;
-  (*ipcp_transformations)[node->uid].alignments = NULL;
   descriptors.release ();
 
   if (!something_changed)
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index a123978..4eeae88 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -143,17 +143,6 @@  struct GTY(()) ipa_agg_jump_function
 
 typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
 
-/* Info about pointer alignments. */
-struct GTY(()) ipa_alignment
-{
-  /* The data fields below are valid only if known is true.  */
-  bool known;
-  /* See ptr_info_def and get_pointer_alignment_1 for description of these
-     two.  */
-  unsigned align;
-  unsigned misalign;
-};
-
 /* Information about zero/non-zero bits.  */
 struct GTY(()) ipa_bits
 {
@@ -186,9 +175,6 @@  struct GTY (()) ipa_jump_func
      description.  */
   struct ipa_agg_jump_function agg;
 
-  /* Information about alignment of pointers. */
-  struct ipa_alignment alignment;
-
   /* Information about zero/non-zero bits.  */
   struct ipa_bits bits;
 
@@ -531,8 +517,6 @@  struct GTY(()) ipcp_transformation_summary
 {
   /* Linked list of known aggregate values.  */
   ipa_agg_replacement_value *agg_values;
-  /* Alignment information for pointers.  */
-  vec<ipa_alignment, va_gc> *alignments;
   /* Known bits information.  */
   vec<ipa_bits, va_gc> *bits;
   /* Value range information.  */
diff --git a/gcc/opts.c b/gcc/opts.c
index 45f1f89c..90e6186 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -504,7 +504,6 @@  static const struct default_options default_options_table[] =
     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
-    { OPT_LEVELS_2_PLUS, OPT_fipa_cp_alignment, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
@@ -1423,9 +1422,6 @@  enable_fdo_optimizations (struct gcc_options *opts,
   if (!opts_set->x_flag_ipa_cp_clone
       && value && opts->x_flag_ipa_cp)
     opts->x_flag_ipa_cp_clone = value;
-  if (!opts_set->x_flag_ipa_cp_alignment
-      && value && opts->x_flag_ipa_cp)
-    opts->x_flag_ipa_cp_alignment = value;
   if (!opts_set->x_flag_ipa_bit_cp
       && value && opts->x_flag_ipa_cp)
     opts->x_flag_ipa_bit_cp = value;
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-1.c b/gcc/testsuite/gcc.dg/ipa/propalign-1.c
index f34552c..1491de8 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-1.c
@@ -27,5 +27,5 @@  bar (void)
 }
 
 
-/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */
 /* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-2.c b/gcc/testsuite/gcc.dg/ipa/propalign-2.c
index 67b149a..51799c7 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-2.c
@@ -53,5 +53,5 @@  bar2 (void)
   through (c.buf);
 }
 
-/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */
 /* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-3.c b/gcc/testsuite/gcc.dg/ipa/propalign-3.c
index d3bc2c4..4f5df4a 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-3.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-3.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-ipa-cp-alignment -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fno-ipa-bit-cp -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */
 /* { dg-skip-if "No alignment restrictions" { { ! natural_alignment_32 } && { ! natural_alignment_64 } } } */
 
 #include <stdint.h>
@@ -53,5 +53,5 @@  bar2 (void)
   through (c.buf);
 }
 
-/* { dg-final { scan-ipa-dump-not "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump-not "align:" "cp" } } */
 /* { dg-final { scan-tree-dump "fail_the_test" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-4.c b/gcc/testsuite/gcc.dg/ipa/propalign-4.c
index b680813..bd32bf0 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-4.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-4.c
@@ -20,4 +20,4 @@  main()
   test (&aa[3]);
   return 0;
 }
-/* { dg-final { scan-ipa-dump "Alignment 8, misalignment 4"  "cp"  } } */
+/* { dg-final { scan-ipa-dump "align: 8, misalign: 4"  "cp"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-5.c b/gcc/testsuite/gcc.dg/ipa/propalign-5.c
index f2cf600..68e57da 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-5.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-5.c
@@ -20,4 +20,4 @@  main()
   test (&bb);
   return 0;
 }
-/* { dg-final { scan-ipa-dump "Alignment 2"  "cp"  } } */
+/* { dg-final { scan-ipa-dump "align: 2"  "cp"  } } */