diff mbox

[RFC] Convert TYPE_ALIGN_OK into an TYPE_LANG_FLAG

Message ID AM4PR0701MB21623E5D6061FE9F75516A0BE43B0@AM4PR0701MB2162.eurprd07.prod.outlook.com
State New
Headers show

Commit Message

Bernd Edlinger July 7, 2016, 2:53 p.m. UTC
Hi,

this patch re-factors the TYPE_ALIGN_OK into a new TYPE_LANG_FLAG,
and removes one of the 9 parameters of get_inner_reference.  It therefore
simplifies the middle end slightly.

It is quite a while ago, when I last proposed a similar patch, which focused
only on get_inner_referene.  According to Eric's comment, I extended
it to cover also the TYPE_ALIGN_OK which is only in use by Ada today.

As it turns out, the middle end does not need the TYPE_ALIGN_OK,
but it cannot be completely removed, because Ada reads it back again,
and it plays therefore the role of an additional TYPE_LANG_FLAG.

Removing the use of TYPE_ALIGN_OK in the pa backend can't have any
side-effect, because when I look at the definition of mark_reg_pointer
the align parameter only has an influence on REGNO_POINTER_ALIGN.
Because that is never used by the pa backend, the only other place where
it is used in the middle end is in rtlanal.c, where it is only evaluated for
stack_pointer_rtx, frame_pointer_rtx, and arg_pointer_rtx, but these
registers do not hold arbitrary pointer values.


Boot-strapped and Reg-tested on arm-linux-gnueabihf and x86_64-pc-linux.
I have also built cross-compilers for hppa and mips targets.
Is it OK for trunk?


Thanks
Bernd.

Comments

Jeff Law July 7, 2016, 3:40 p.m. UTC | #1
On 07/07/2016 08:53 AM, Bernd Edlinger wrote:
> Hi,
>
> this patch re-factors the TYPE_ALIGN_OK into a new TYPE_LANG_FLAG,
> and removes one of the 9 parameters of get_inner_reference.  It therefore
> simplifies the middle end slightly.
>
> It is quite a while ago, when I last proposed a similar patch, which focused
> only on get_inner_referene.  According to Eric's comment, I extended
> it to cover also the TYPE_ALIGN_OK which is only in use by Ada today.
>
> As it turns out, the middle end does not need the TYPE_ALIGN_OK,
> but it cannot be completely removed, because Ada reads it back again,
> and it plays therefore the role of an additional TYPE_LANG_FLAG.
>
> Removing the use of TYPE_ALIGN_OK in the pa backend can't have any
> side-effect, because when I look at the definition of mark_reg_pointer
> the align parameter only has an influence on REGNO_POINTER_ALIGN.
> Because that is never used by the pa backend, the only other place where
> it is used in the middle end is in rtlanal.c, where it is only evaluated for
> stack_pointer_rtx, frame_pointer_rtx, and arg_pointer_rtx, but these
> registers do not hold arbitrary pointer values.
My recollection of REGNO_POINTER_ALIGN is that it exists primarily to 
allow the backends to emit better code in their block move/block zero 
patterns.  It may also allow for removal of redundant masking, 
particularly for the alpha as we can track low order zero/nonzero bits 
in pointers.

The middle end's expander code wasn't ever really made aware of 
REGNO_POINTER_ALIGN -- it was primarily queried by the target expander code.

In other words, not having accurate REGNO_POINTER_ALIGN should never be 
a correctness issue, just a potential performance issue.  Furthermore, 
if the backend isn't explicitly using REGNO_POINTER_ALIGN, then it's 
highly unlikely that losing that information is ever going to be noticed 
for block moves/initialization.  Which just leaves the uses for removing 
masking of low order bits in pointers, which doesn't really come up on 
the PA often enough to matter.  So I see no issues with losing the data 
on the PA.

So I'm on board with what you're trying to do.

The only nit is whether or not to continue to use the nothrow_flag field 
to carry this information.  Given this is moving to a language specific, 
I'd like to avoid that.

Can we allocate one of the "spare" bits in tree_type_common for lang_flag_7?

jeff
Bernd Edlinger July 7, 2016, 4:24 p.m. UTC | #2
On 07/07/16 17:40, Jeff Law wrote:
> On 07/07/2016 08:53 AM, Bernd Edlinger wrote:
>> Hi,
>>
>> this patch re-factors the TYPE_ALIGN_OK into a new TYPE_LANG_FLAG,
>> and removes one of the 9 parameters of get_inner_reference.  It therefore
>> simplifies the middle end slightly.
>>
>> It is quite a while ago, when I last proposed a similar patch, which
>> focused
>> only on get_inner_referene.  According to Eric's comment, I extended
>> it to cover also the TYPE_ALIGN_OK which is only in use by Ada today.
>>
>> As it turns out, the middle end does not need the TYPE_ALIGN_OK,
>> but it cannot be completely removed, because Ada reads it back again,
>> and it plays therefore the role of an additional TYPE_LANG_FLAG.
>>
>> Removing the use of TYPE_ALIGN_OK in the pa backend can't have any
>> side-effect, because when I look at the definition of mark_reg_pointer
>> the align parameter only has an influence on REGNO_POINTER_ALIGN.
>> Because that is never used by the pa backend, the only other place where
>> it is used in the middle end is in rtlanal.c, where it is only
>> evaluated for
>> stack_pointer_rtx, frame_pointer_rtx, and arg_pointer_rtx, but these
>> registers do not hold arbitrary pointer values.
> My recollection of REGNO_POINTER_ALIGN is that it exists primarily to
> allow the backends to emit better code in their block move/block zero
> patterns.  It may also allow for removal of redundant masking,
> particularly for the alpha as we can track low order zero/nonzero bits
> in pointers.
>
> The middle end's expander code wasn't ever really made aware of
> REGNO_POINTER_ALIGN -- it was primarily queried by the target expander
> code.
>
> In other words, not having accurate REGNO_POINTER_ALIGN should never be
> a correctness issue, just a potential performance issue.  Furthermore,
> if the backend isn't explicitly using REGNO_POINTER_ALIGN, then it's
> highly unlikely that losing that information is ever going to be noticed
> for block moves/initialization.  Which just leaves the uses for removing
> masking of low order bits in pointers, which doesn't really come up on
> the PA often enough to matter.  So I see no issues with losing the data
> on the PA.
>
> So I'm on board with what you're trying to do.
>
> The only nit is whether or not to continue to use the nothrow_flag field
> to carry this information.  Given this is moving to a language specific,
> I'd like to avoid that.
>
> Can we allocate one of the "spare" bits in tree_type_common for
> lang_flag_7?
>

Yes I agree, there are still 26 spare bits, so there is absolutely no
need to squeeze that info in the base.nothrow_flag.


Thanks
Bernd.
Richard Biener July 8, 2016, 7:39 a.m. UTC | #3
On Thu, 7 Jul 2016, Bernd Edlinger wrote:

> Hi,
> 
> this patch re-factors the TYPE_ALIGN_OK into a new TYPE_LANG_FLAG,
> and removes one of the 9 parameters of get_inner_reference.  It therefore
> simplifies the middle end slightly.
> 
> It is quite a while ago, when I last proposed a similar patch, which focused
> only on get_inner_referene.  According to Eric's comment, I extended
> it to cover also the TYPE_ALIGN_OK which is only in use by Ada today.
> 
> As it turns out, the middle end does not need the TYPE_ALIGN_OK,
> but it cannot be completely removed, because Ada reads it back again,
> and it plays therefore the role of an additional TYPE_LANG_FLAG.
> 
> Removing the use of TYPE_ALIGN_OK in the pa backend can't have any
> side-effect, because when I look at the definition of mark_reg_pointer
> the align parameter only has an influence on REGNO_POINTER_ALIGN.
> Because that is never used by the pa backend, the only other place where
> it is used in the middle end is in rtlanal.c, where it is only evaluated for
> stack_pointer_rtx, frame_pointer_rtx, and arg_pointer_rtx, but these
> registers do not hold arbitrary pointer values.
> 
> 
> Boot-strapped and Reg-tested on arm-linux-gnueabihf and x86_64-pc-linux.
> I have also built cross-compilers for hppa and mips targets.
> Is it OK for trunk?

The discussion last time ended with a mail from you that TYPE_ALIGN_OK
is "somehow" relevant in the Ada FE, but I didn't see any feedback
from Eric nor results from the "extended" testing we wanted to perform.

So is there any news on that front?  That said, if we can remove
TYPE_ALIGN_OK setting from the Ada frontend then this patch becomes
much more obvious (and no need to find a lang-specific place for
TYPE_ALIGN_OK).

Richard.
Eric Botcazou July 8, 2016, 7:57 a.m. UTC | #4
> The discussion last time ended with a mail from you that TYPE_ALIGN_OK
> is "somehow" relevant in the Ada FE, but I didn't see any feedback
> from Eric nor results from the "extended" testing we wanted to perform.

TYPE_ALIGN_OK is definitely relevant in the Ada FE, the question being whether 
it is still relevant in the middle-end, in which case this would most likely 
be for strict-alignment platforms.  So we need a serious evaluation of the 
patch on a strict-alignment platform (no, the compiler bootstrap + testsuite 
alone doesn't qualify here).

> So is there any news on that front?

I should have meaningful results tomorrow morning baring unexpected issues.
Richard Biener July 8, 2016, 8:22 a.m. UTC | #5
On Fri, 8 Jul 2016, Eric Botcazou wrote:

> > The discussion last time ended with a mail from you that TYPE_ALIGN_OK
> > is "somehow" relevant in the Ada FE, but I didn't see any feedback
> > from Eric nor results from the "extended" testing we wanted to perform.
> 
> TYPE_ALIGN_OK is definitely relevant in the Ada FE, the question being whether 
> it is still relevant in the middle-end, in which case this would most likely 
> be for strict-alignment platforms.  So we need a serious evaluation of the 
> patch on a strict-alignment platform (no, the compiler bootstrap + testsuite 
> alone doesn't qualify here).

I expect it still has an effect due to the same reason as the
DECL_OFFSET_ALIGN thing - memory reference expansion doesn't gather
information from the full reference but tries to re-cover it from
the pieces returned from get_inner_reference.  So I guess we need
to fix that first.

> > So is there any news on that front?
> 
> I should have meaningful results tomorrow morning baring unexpected issues.

Thanks,
Richard.
Eric Botcazou July 10, 2016, 8:23 a.m. UTC | #6
> I expect it still has an effect due to the same reason as the
> DECL_OFFSET_ALIGN thing - memory reference expansion doesn't gather
> information from the full reference but tries to re-cover it from
> the pieces returned from get_inner_reference.  So I guess we need
> to fix that first.

The situation is a bit different though, because the main (and single?) case 
for which TYPE_ALIGN_OK had been necessary in the middle-end was made obsolete 
by a gigi change at some point.  And indeed extensive testing of Bernd's patch 
on a strict-alignment platform didn't reveal any issue.

So no objection to the patch on principle by me.
diff mbox

Patch

Index: gcc/ada/gcc-interface/ada-tree.h
===================================================================
--- gcc/ada/gcc-interface/ada-tree.h	(revision 237702)
+++ gcc/ada/gcc-interface/ada-tree.h	(working copy)
@@ -199,6 +199,9 @@  do {							 \
    alignment value the type ought to have.  */
 #define TYPE_MAX_ALIGN(NODE) (TYPE_PRECISION (RECORD_OR_UNION_CHECK (NODE)))
 
+/* True if objects of tagged types are guaranteed to be properly aligned.  */
+#define TYPE_ALIGN_OK(NODE) TYPE_LANG_FLAG_7 (NODE)
+
 /* For an UNCONSTRAINED_ARRAY_TYPE, this is the record containing both the
    template and the object.
 
Index: gcc/ada/gcc-interface/trans.c
===================================================================
--- gcc/ada/gcc-interface/trans.c	(revision 237702)
+++ gcc/ada/gcc-interface/trans.c	(working copy)
@@ -2176,7 +2176,7 @@  Attribute_to_gnu (Node_Id gnat_node, tree *gnu_res
 			  && TREE_CODE (gnu_prefix) == FIELD_DECL));
 
 	get_inner_reference (gnu_prefix, &bitsize, &bitpos, &gnu_offset,
-			     &mode, &unsignedp, &reversep, &volatilep, false);
+			     &mode, &unsignedp, &reversep, &volatilep);
 
 	if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
 	  {
Index: gcc/ada/gcc-interface/utils2.c
===================================================================
--- gcc/ada/gcc-interface/utils2.c	(revision 237702)
+++ gcc/ada/gcc-interface/utils2.c	(working copy)
@@ -1418,7 +1418,7 @@  build_unary_op (enum tree_code op_code, tree resul
 
 	      inner = get_inner_reference (operand, &bitsize, &bitpos, &offset,
 					   &mode, &unsignedp, &reversep,
-					   &volatilep, false);
+					   &volatilep);
 
 	      /* If INNER is a padding type whose field has a self-referential
 		 size, convert to that inner type.  We know the offset is zero
Index: gcc/asan.c
===================================================================
--- gcc/asan.c	(revision 237702)
+++ gcc/asan.c	(working copy)
@@ -1793,7 +1793,7 @@  instrument_derefs (gimple_stmt_iterator *iter, tre
   machine_mode mode;
   int unsignedp, reversep, volatilep = 0;
   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
-				    &unsignedp, &reversep, &volatilep, false);
+				    &unsignedp, &reversep, &volatilep);
 
   if (TREE_CODE (t) == COMPONENT_REF
       && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 237702)
+++ gcc/builtins.c	(working copy)
@@ -259,7 +259,7 @@  get_object_alignment_2 (tree exp, unsigned int *al
   /* Get the innermost object and the constant (bitpos) and possibly
      variable (offset) offset of the access.  */
   exp = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
-			     &unsignedp, &reversep, &volatilep, true);
+			     &unsignedp, &reversep, &volatilep);
 
   /* Extract alignment information from the innermost object and
      possibly adjust bitpos and offset.  */
@@ -289,10 +289,6 @@  get_object_alignment_2 (tree exp, unsigned int *al
       align = DECL_ALIGN (exp);
       known_alignment = true;
     }
-  else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
-    {
-      align = TYPE_ALIGN (TREE_TYPE (exp));
-    }
   else if (TREE_CODE (exp) == INDIRECT_REF
 	   || TREE_CODE (exp) == MEM_REF
 	   || TREE_CODE (exp) == TARGET_MEM_REF)
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c	(revision 237702)
+++ gcc/cfgexpand.c	(working copy)
@@ -4444,7 +4444,7 @@  expand_debug_expr (tree exp)
 	int reversep, volatilep = 0;
 	tree tem
 	  = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
-				 &unsignedp, &reversep, &volatilep, false);
+				 &unsignedp, &reversep, &volatilep);
 	rtx orig_op0;
 
 	if (bitsize == 0)
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	(revision 237702)
+++ gcc/config/mips/mips.c	(working copy)
@@ -17470,7 +17470,7 @@  r10k_safe_mem_expr_p (tree expr, unsigned HOST_WID
   int unsigned_p, reverse_p, volatile_p;
 
   inner = get_inner_reference (expr, &bitsize, &bitoffset, &var_offset, &mode,
-			       &unsigned_p, &reverse_p, &volatile_p, false);
+			       &unsigned_p, &reverse_p, &volatile_p);
   if (!DECL_P (inner) || !DECL_SIZE_UNIT (inner) || var_offset)
     return false;
 
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	(revision 237702)
+++ gcc/config/pa/pa.c	(working copy)
@@ -1929,16 +1929,7 @@  pa_emit_move_sequence (rtx *operands, machine_mode
 		  type = strip_array_types (type);
 
 		  if (POINTER_TYPE_P (type))
-		    {
-		      int align;
-
-		      type = TREE_TYPE (type);
-		      /* Using TYPE_ALIGN_OK is rather conservative as
-			 only the ada frontend actually sets it.  */
-		      align = (TYPE_ALIGN_OK (type) ? TYPE_ALIGN (type)
-			       : BITS_PER_UNIT);
-		      mark_reg_pointer (operand0, align);
-		    }
+		    mark_reg_pointer (operand0, BITS_PER_UNIT);
 		}
 	    }
 
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c	(revision 237702)
+++ gcc/dbxout.c	(working copy)
@@ -2485,7 +2485,7 @@  dbxout_expand_expr (tree expr)
 	rtx x;
 
 	tem = get_inner_reference (expr, &bitsize, &bitpos, &offset, &mode,
-				   &unsignedp, &reversep, &volatilep, true);
+				   &unsignedp, &reversep, &volatilep);
 
 	x = dbxout_expand_expr (tem);
 	if (x == NULL || !MEM_P (x))
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 237702)
+++ gcc/dwarf2out.c	(working copy)
@@ -15140,7 +15140,7 @@  loc_list_for_address_of_addr_expr_of_indirect_ref
 
   obj = get_inner_reference (TREE_OPERAND (loc, 0),
 			     &bitsize, &bitpos, &offset, &mode,
-			     &unsignedp, &reversep, &volatilep, false);
+			     &unsignedp, &reversep, &volatilep);
   STRIP_NOPS (obj);
   if (bitpos % BITS_PER_UNIT)
     {
@@ -16077,7 +16077,7 @@  loc_list_from_tree_1 (tree loc, int want_address,
 	int unsignedp, reversep, volatilep = 0;
 
 	obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
-				   &unsignedp, &reversep, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep);
 
 	gcc_assert (obj != loc);
 
@@ -17552,7 +17552,7 @@  fortran_common (tree decl, HOST_WIDE_INT *value)
     return NULL_TREE;
 
   cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset, &mode,
-			      &unsignedp, &reversep, &volatilep, true);
+			      &unsignedp, &reversep, &volatilep);
 
   if (cvar == NULL_TREE
       || TREE_CODE (cvar) != VAR_DECL
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	(revision 237702)
+++ gcc/emit-rtl.c	(working copy)
@@ -1813,9 +1813,9 @@  set_mem_attributes_minus_bitpos (rtx ref, tree t,
 	 able to simply always use TYPE_ALIGN?  */
     }
 
-  /* We can set the alignment from the type if we are making an object,
-     this is an INDIRECT_REF, or if TYPE_ALIGN_OK.  */
-  if (objectp || TREE_CODE (t) == INDIRECT_REF || TYPE_ALIGN_OK (type))
+  /* We can set the alignment from the type if we are making an object or if
+     this is an INDIRECT_REF.  */
+  if (objectp || TREE_CODE (t) == INDIRECT_REF)
     attrs.align = MAX (attrs.align, TYPE_ALIGN (type));
 
   /* If the size is known, we can set that.  */
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(revision 237702)
+++ gcc/expr.c	(working copy)
@@ -4828,7 +4828,7 @@  get_bit_range (unsigned HOST_WIDE_INT *bitstart,
       int unsignedp, reversep, volatilep = 0;
       get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
 			   &roffset, &rmode, &unsignedp, &reversep,
-			   &volatilep, false);
+			   &volatilep);
       if ((rbitpos % BITS_PER_UNIT) != 0)
 	{
 	  *bitstart = *bitend = 0;
@@ -4984,7 +4984,7 @@  expand_assignment (tree to, tree from, bool nontem
 
       push_temp_slots ();
       tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
-				 &unsignedp, &reversep, &volatilep, true);
+				 &unsignedp, &reversep, &volatilep);
 
       /* Make sure bitpos is not negative, it can wreak havoc later.  */
       if (bitpos < 0)
@@ -6971,27 +6971,13 @@  store_field (rtx target, HOST_WIDE_INT bitsize, HO
 
    If the field describes a variable-sized object, *PMODE is set to
    BLKmode and *PBITSIZE is set to -1.  An access cannot be made in
-   this case, but the address of the object can be found.
+   this case, but the address of the object can be found.  */
 
-   If KEEP_ALIGNING is true and the target is STRICT_ALIGNMENT, we don't
-   look through nodes that serve as markers of a greater alignment than
-   the one that can be deduced from the expression.  These nodes make it
-   possible for front-ends to prevent temporaries from being created by
-   the middle-end on alignment considerations.  For that purpose, the
-   normal operating mode at high-level is to always pass FALSE so that
-   the ultimate containing object is really returned; moreover, the
-   associated predicate handled_component_p will always return TRUE
-   on these nodes, thus indicating that they are essentially handled
-   by get_inner_reference.  TRUE should only be passed when the caller
-   is scanning the expression in order to build another representation
-   and specifically knows how to handle these nodes; as such, this is
-   the normal operating mode in the RTL expanders.  */
-
 tree
 get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
 		     HOST_WIDE_INT *pbitpos, tree *poffset,
 		     machine_mode *pmode, int *punsignedp,
-		     int *preversep, int *pvolatilep, bool keep_aligning)
+		     int *preversep, int *pvolatilep)
 {
   tree size_tree = 0;
   machine_mode mode = VOIDmode;
@@ -7113,14 +7099,6 @@  get_inner_reference (tree exp, HOST_WIDE_INT *pbit
 	  break;
 
 	case VIEW_CONVERT_EXPR:
-	  if (keep_aligning && STRICT_ALIGNMENT
-	      && (TYPE_ALIGN (TREE_TYPE (exp))
-	       > TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))))
-	      && (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
-		  < BIGGEST_ALIGNMENT)
-	      && (TYPE_ALIGN_OK (TREE_TYPE (exp))
-		  || TYPE_ALIGN_OK (TREE_TYPE (TREE_OPERAND (exp, 0)))))
-	    goto done;
 	  break;
 
 	case MEM_REF:
@@ -7839,7 +7817,7 @@  expand_expr_addr_expr_1 (tree exp, rtx target, mac
 	 they won't change the final object whose address will be returned
 	 (they actually exist only for that purpose).  */
       inner = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
-				   &unsignedp, &reversep, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep);
       break;
     }
 
@@ -10369,7 +10347,7 @@  expand_expr_real_1 (tree exp, rtx target, machine_
 	int reversep, volatilep = 0, must_force_mem;
 	tree tem
 	  = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
-				 &unsignedp, &reversep, &volatilep, true);
+				 &unsignedp, &reversep, &volatilep);
 	rtx orig_op0, memloc;
 	bool clear_mem_expr = false;
 
@@ -10767,7 +10745,7 @@  expand_expr_real_1 (tree exp, rtx target, machine_
 	int unsignedp, reversep, volatilep = 0;
 	tree tem
 	  = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
-				 &unsignedp, &reversep, &volatilep, true);
+				 &unsignedp, &reversep, &volatilep);
 	rtx orig_op0;
 
 	/* ??? We should work harder and deal with non-zero offsets.  */
@@ -10878,21 +10856,12 @@  expand_expr_real_1 (tree exp, rtx target, machine_
 	{
 	  enum insn_code icode;
 
-	  if (TYPE_ALIGN_OK (type))
+	  if (modifier != EXPAND_WRITE
+	      && modifier != EXPAND_MEMORY
+	      && !inner_reference_p
+	      && mode != BLKmode
+	      && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
 	    {
-	      /* ??? Copying the MEM without substantially changing it might
-		 run afoul of the code handling volatile memory references in
-		 store_expr, which assumes that TARGET is returned unmodified
-		 if it has been used.  */
-	      op0 = copy_rtx (op0);
-	      set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
-	    }
-	  else if (modifier != EXPAND_WRITE
-		   && modifier != EXPAND_MEMORY
-		   && !inner_reference_p
-		   && mode != BLKmode
-		   && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
-	    {
 	      /* If the target does have special handling for unaligned
 		 loads of mode then use them.  */
 	      if ((icode = optab_handler (movmisalign_optab, mode))
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 237702)
+++ gcc/fold-const.c	(working copy)
@@ -3881,7 +3881,7 @@  optimize_bit_field_compare (location_t loc, enum t
      do anything if the inner expression is a PLACEHOLDER_EXPR since we
      then will no longer be able to replace it.  */
   linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
-				&lunsignedp, &lreversep, &lvolatilep, false);
+				&lunsignedp, &lreversep, &lvolatilep);
   if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
       || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR || lvolatilep)
     return 0;
@@ -3894,7 +3894,7 @@  optimize_bit_field_compare (location_t loc, enum t
 	sizes, signedness and storage order are the same.  */
      rinner
        = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
-			      &runsignedp, &rreversep, &rvolatilep, false);
+			      &runsignedp, &rreversep, &rvolatilep);
 
      if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
 	 || lunsignedp != runsignedp || lreversep != rreversep || offset != 0
@@ -4076,7 +4076,7 @@  decode_field_reference (location_t loc, tree *exp_
     }
 
   inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
-			       punsignedp, preversep, pvolatilep, false);
+			       punsignedp, preversep, pvolatilep);
   if ((inner == exp && and_mask == 0)
       || *pbitsize < 0 || offset != 0
       || TREE_CODE (inner) == PLACEHOLDER_EXPR)
@@ -7731,7 +7731,7 @@  fold_unary_loc (location_t loc, enum tree_code cod
 	  tree base
 	    = get_inner_reference (TREE_OPERAND (op0, 0), &bitsize, &bitpos,
 				   &offset, &mode, &unsignedp, &reversep,
-				   &volatilep, false);
+				   &volatilep);
 	  /* If the reference was to a (constant) zero offset, we can use
 	     the address of the base if it has the same base type
 	     as the result type and the pointer type is unqualified.  */
@@ -8335,7 +8335,7 @@  fold_comparison (location_t loc, enum tree_code co
 	  base0
 	    = get_inner_reference (TREE_OPERAND (arg0, 0),
 				   &bitsize, &bitpos0, &offset0, &mode,
-				   &unsignedp, &reversep, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep);
 	  if (TREE_CODE (base0) == INDIRECT_REF)
 	    base0 = TREE_OPERAND (base0, 0);
 	  else
@@ -8350,8 +8350,7 @@  fold_comparison (location_t loc, enum tree_code co
 	      base0
 		= get_inner_reference (TREE_OPERAND (base0, 0),
 				       &bitsize, &bitpos0, &offset0, &mode,
-				       &unsignedp, &reversep, &volatilep,
-				       false);
+				       &unsignedp, &reversep, &volatilep);
 	      if (TREE_CODE (base0) == INDIRECT_REF)
 		base0 = TREE_OPERAND (base0, 0);
 	      else
@@ -8382,7 +8381,7 @@  fold_comparison (location_t loc, enum tree_code co
 	  base1
 	    = get_inner_reference (TREE_OPERAND (arg1, 0),
 				   &bitsize, &bitpos1, &offset1, &mode,
-				   &unsignedp, &reversep, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep);
 	  if (TREE_CODE (base1) == INDIRECT_REF)
 	    base1 = TREE_OPERAND (base1, 0);
 	  else
@@ -8397,8 +8396,7 @@  fold_comparison (location_t loc, enum tree_code co
 	      base1
 		= get_inner_reference (TREE_OPERAND (base1, 0),
 				       &bitsize, &bitpos1, &offset1, &mode,
-				       &unsignedp, &reversep, &volatilep,
-				       false);
+				       &unsignedp, &reversep, &volatilep);
 	      if (TREE_CODE (base1) == INDIRECT_REF)
 		base1 = TREE_OPERAND (base1, 0);
 	      else
@@ -14292,7 +14290,7 @@  split_address_to_core_and_offset (tree exp,
     {
       core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
 				  poffset, &mode, &unsignedp, &reversep,
-				  &volatilep, false);
+				  &volatilep);
       core = build_fold_addr_expr_loc (loc, core);
     }
   else
Index: gcc/gimple-laddress.c
===================================================================
--- gcc/gimple-laddress.c	(revision 237702)
+++ gcc/gimple-laddress.c	(working copy)
@@ -105,7 +105,7 @@  pass_laddress::execute (function *fun)
 	  int volatilep = 0, reversep, unsignedp = 0;
 	  base = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize,
 				      &bitpos, &offset, &mode, &unsignedp,
-				      &reversep, &volatilep, false);
+				      &reversep, &volatilep);
 	  gcc_assert (base != NULL_TREE && (bitpos % BITS_PER_UNIT) == 0);
 	  if (offset != NULL_TREE)
 	    {
Index: gcc/gimple-ssa-strength-reduction.c
===================================================================
--- gcc/gimple-ssa-strength-reduction.c	(revision 237702)
+++ gcc/gimple-ssa-strength-reduction.c	(working copy)
@@ -987,7 +987,7 @@  slsr_process_ref (gimple *gs)
     return;
 
   base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode,
-			      &unsignedp, &reversep, &volatilep, false);
+			      &unsignedp, &reversep, &volatilep);
   if (reversep)
     return;
   widest_int index = bitpos;
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c	(revision 237702)
+++ gcc/gimplify.c	(working copy)
@@ -7046,7 +7046,7 @@  gimplify_scan_omp_clauses (tree *list_p, gimple_se
 		    base = TREE_OPERAND (base, 0);
 		  base = get_inner_reference (base, &bitsize, &bitpos, &offset,
 					      &mode, &unsignedp, &reversep,
-					      &volatilep, false);
+					      &volatilep);
 		  tree orig_base = base;
 		  if ((TREE_CODE (base) == INDIRECT_REF
 		       || (TREE_CODE (base) == MEM_REF
@@ -7182,8 +7182,7 @@  gimplify_scan_omp_clauses (tree *list_p, gimple_se
 			    base = get_inner_reference (base, &bitsize2,
 							&bitpos2, &offset2,
 							&mode, &unsignedp,
-							&reversep, &volatilep,
-							false);
+							&reversep, &volatilep);
 			    if ((TREE_CODE (base) == INDIRECT_REF
 				 || (TREE_CODE (base) == MEM_REF
 				     && integer_zerop (TREE_OPERAND (base,
Index: gcc/hsa-gen.c
===================================================================
--- gcc/hsa-gen.c	(revision 237702)
+++ gcc/hsa-gen.c	(working copy)
@@ -2045,7 +2045,7 @@  gen_hsa_addr (tree ref, hsa_bb *hbb, HOST_WIDE_INT
       int unsignedp, volatilep, preversep;
 
       ref = get_inner_reference (ref, &bitsize, &bitpos, &varoffset, &mode,
-				 &unsignedp, &preversep, &volatilep, false);
+				 &unsignedp, &preversep, &volatilep);
 
       offset = bitpos;
       offset = wi::rshift (offset, LOG2_BITS_PER_UNIT, SIGNED);
Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c	(revision 237702)
+++ gcc/simplify-rtx.c	(working copy)
@@ -305,7 +305,7 @@  delegitimize_mem_from_attrs (rtx x)
 
 	    decl
 	      = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
-				     &unsignedp, &reversep, &volatilep, false);
+				     &unsignedp, &reversep, &volatilep);
 	    if (bitsize != GET_MODE_BITSIZE (mode)
 		|| (bitpos % BITS_PER_UNIT)
 		|| (toffset && !tree_fits_shwi_p (toffset)))
Index: gcc/tree-affine.c
===================================================================
--- gcc/tree-affine.c	(revision 237702)
+++ gcc/tree-affine.c	(working copy)
@@ -318,7 +318,7 @@  tree_to_aff_combination (tree expr, tree type, aff
 	}
       core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos,
 				  &toffset, &mode, &unsignedp, &reversep,
-				  &volatilep, false);
+				  &volatilep);
       if (bitpos % BITS_PER_UNIT != 0)
 	break;
       aff_combination_const (comb, type, bitpos / BITS_PER_UNIT);
@@ -888,7 +888,7 @@  get_inner_reference_aff (tree ref, aff_tree *addr,
   int uns, rev, vol;
   aff_tree tmp;
   tree base = get_inner_reference (ref, &bitsize, &bitpos, &toff, &mode,
-				   &uns, &rev, &vol, false);
+				   &uns, &rev, &vol);
   tree base_addr = build_fold_addr_expr (base);
 
   /* ADDR = &BASE + TOFF + BITPOS / BITS_PER_UNIT.  */
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h	(revision 237702)
+++ gcc/tree-core.h	(working copy)
@@ -1154,7 +1154,7 @@  struct GTY(()) tree_base {
            CALL_EXPR
            FUNCTION_DECL
 
-       TYPE_ALIGN_OK in
+       TYPE_LANG_FLAG_7 in
            all types
 
        TREE_THIS_NOTRAP in
Index: gcc/tree-data-ref.c
===================================================================
--- gcc/tree-data-ref.c	(revision 237702)
+++ gcc/tree-data-ref.c	(working copy)
@@ -618,7 +618,7 @@  split_constant_offset_1 (tree type, tree op0, enum
 	op0 = TREE_OPERAND (op0, 0);
 	base
 	  = get_inner_reference (op0, &pbitsize, &pbitpos, &poffset, &pmode,
-				 &punsignedp, &preversep, &pvolatilep, false);
+				 &punsignedp, &preversep, &pvolatilep);
 
 	if (pbitpos % BITS_PER_UNIT != 0)
 	  return false;
@@ -771,7 +771,7 @@  dr_analyze_innermost (struct data_reference *dr, s
     fprintf (dump_file, "analyze_innermost: ");
 
   base = get_inner_reference (ref, &pbitsize, &pbitpos, &poffset, &pmode,
-			      &punsignedp, &preversep, &pvolatilep, false);
+			      &punsignedp, &preversep, &pvolatilep);
   gcc_assert (base != NULL_TREE);
 
   if (pbitpos % BITS_PER_UNIT != 0)
Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c	(revision 237702)
+++ gcc/tree-scalar-evolution.c	(working copy)
@@ -1744,8 +1744,7 @@  interpret_rhs_expr (struct loop *loop, gimple *at_
 
 	  base = get_inner_reference (TREE_OPERAND (rhs1, 0),
 				      &bitsize, &bitpos, &offset, &mode,
-				      &unsignedp, &reversep, &volatilep,
-				      false);
+				      &unsignedp, &reversep, &volatilep);
 
 	  if (TREE_CODE (base) == MEM_REF)
 	    {
Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c	(revision 237702)
+++ gcc/tree-sra.c	(working copy)
@@ -5230,7 +5230,7 @@  ipa_sra_check_caller (struct cgraph_node *node, vo
 	  machine_mode mode;
 	  int unsignedp, reversep, volatilep = 0;
 	  get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
-			       &unsignedp, &reversep, &volatilep, false);
+			       &unsignedp, &reversep, &volatilep);
 	  if (bitpos % BITS_PER_UNIT)
 	    {
 	      iscc->bad_arg_alignment = true;
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c	(revision 237702)
+++ gcc/tree-ssa-loop-ivopts.c	(working copy)
@@ -4522,7 +4522,7 @@  split_address_cost (struct ivopts_data *data,
   int unsignedp, reversep, volatilep;
 
   core = get_inner_reference (addr, &bitsize, &bitpos, &toffset, &mode,
-			      &unsignedp, &reversep, &volatilep, false);
+			      &unsignedp, &reversep, &volatilep);
 
   if (toffset != 0
       || bitpos % BITS_PER_UNIT != 0
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(revision 237702)
+++ gcc/tree-ssa-math-opts.c	(working copy)
@@ -2097,7 +2097,7 @@  find_bswap_or_nop_load (gimple *stmt, tree ref, st
     return false;
 
   base_addr = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode,
-				   &unsignedp, &reversep, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep);
 
   if (TREE_CODE (base_addr) == MEM_REF)
     {
@@ -2636,7 +2636,7 @@  bswap_replace (gimple *cur_stmt, gimple *src_stmt,
 	  tree offset;
 
 	  get_inner_reference (src, &bitsize, &bitpos, &offset, &mode,
-			       &unsignedp, &reversep, &volatilep, false);
+			       &unsignedp, &reversep, &volatilep);
 	  if (n->range < (unsigned HOST_WIDE_INT) bitsize)
 	    {
 	      load_offset = (bitsize - n->range) / BITS_PER_UNIT;
Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c	(revision 237702)
+++ gcc/tree-vect-data-refs.c	(working copy)
@@ -3234,7 +3234,7 @@  vect_check_gather_scatter (gimple *stmt, loop_vec_
      SSA_NAME OFF and put the loop invariants into a tree BASE
      that can be gimplified before the loop.  */
   base = get_inner_reference (base, &pbitsize, &pbitpos, &off, &pmode,
-			      &punsignedp, &reversep, &pvolatilep, false);
+			      &punsignedp, &reversep, &pvolatilep);
   gcc_assert (base && (pbitpos % BITS_PER_UNIT) == 0 && !reversep);
 
   if (TREE_CODE (base) == MEM_REF)
@@ -3704,7 +3704,7 @@  again:
 
 	  outer_base = get_inner_reference (inner_base, &pbitsize, &pbitpos,
 					    &poffset, &pmode, &punsignedp,
-					    &preversep, &pvolatilep, false);
+					    &preversep, &pvolatilep);
 	  gcc_assert (outer_base != NULL_TREE);
 
 	  if (pbitpos % BITS_PER_UNIT != 0)
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 237702)
+++ gcc/tree.c	(working copy)
@@ -13204,7 +13204,6 @@  verify_type_variant (const_tree t, tree tv)
     verify_variant_match (TYPE_REF_CAN_ALIAS_ALL);
   /* FIXME: TYPE_SIZES_GIMPLIFIED may differs for Ada build.  */
   verify_variant_match (TYPE_UNSIGNED);
-  verify_variant_match (TYPE_ALIGN_OK);
   verify_variant_match (TYPE_PACKED);
   if (TREE_CODE (t) == REFERENCE_TYPE)
     verify_variant_match (TYPE_REF_IS_RVALUE);
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 237702)
+++ gcc/tree.h	(working copy)
@@ -916,14 +916,6 @@  extern void omp_clause_range_check_failed (const_t
 /* In a CALL_EXPR, means call was instrumented by Pointer Bounds Checker.  */
 #define CALL_WITH_BOUNDS_P(NODE) (CALL_EXPR_CHECK (NODE)->base.deprecated_flag)
 
-/* In a type, nonzero means that all objects of the type are guaranteed by the
-   language or front-end to be properly aligned, so we can indicate that a MEM
-   of this type is aligned at least to the alignment of the type, even if it
-   doesn't appear that it is.  We see this, for example, in object-oriented
-   languages where a tag field may show this is an object of a more-aligned
-   variant of the more generic type.  */
-#define TYPE_ALIGN_OK(NODE) (TYPE_CHECK (NODE)->base.nothrow_flag)
-
 /* Used in classes in C++.  */
 #define TREE_PRIVATE(NODE) ((NODE)->base.private_flag)
 /* Used in classes in C++. */
@@ -1960,6 +1952,7 @@  extern machine_mode element_mode (const_tree t);
 #define TYPE_LANG_FLAG_4(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_4)
 #define TYPE_LANG_FLAG_5(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_5)
 #define TYPE_LANG_FLAG_6(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_6)
+#define TYPE_LANG_FLAG_7(NODE) (TYPE_CHECK (NODE)->base.nothrow_flag)
 
 /* Used to keep track of visited nodes in tree traversals.  This is set to
    0 by copy_node and make_node.  */
@@ -5387,8 +5380,7 @@  extern bool complete_ctor_at_level_p (const_tree,
    look for the ultimate containing object, which is returned and specify
    the access position and size.  */
 extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
-				 tree *, machine_mode *, int *, int *,
-				 int *, bool);
+				 tree *, machine_mode *, int *, int *, int *);
 
 extern tree build_personality_function (const char *);
 
Index: gcc/tsan.c
===================================================================
--- gcc/tsan.c	(revision 237702)
+++ gcc/tsan.c	(working copy)
@@ -110,7 +110,7 @@  instrument_expr (gimple_stmt_iterator gsi, tree ex
   machine_mode mode;
   int unsignedp, reversep, volatilep = 0;
   base = get_inner_reference (expr, &bitsize, &bitpos, &offset, &mode,
-			      &unsignedp, &reversep, &volatilep, false);
+			      &unsignedp, &reversep, &volatilep);
 
   /* No need to instrument accesses to decls that don't escape,
      they can't escape to other threads then.  */
Index: gcc/ubsan.c
===================================================================
--- gcc/ubsan.c	(revision 237702)
+++ gcc/ubsan.c	(working copy)
@@ -1360,7 +1360,7 @@  instrument_bool_enum_load (gimple_stmt_iterator *g
   machine_mode mode;
   int volatilep = 0, reversep, unsignedp = 0;
   tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
-				   &unsignedp, &reversep, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep);
   tree utype = build_nonstandard_integer_type (modebitsize, 1);
 
   if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
@@ -1781,7 +1781,7 @@  instrument_object_size (gimple_stmt_iterator *gsi,
   machine_mode mode;
   int volatilep = 0, reversep, unsignedp = 0;
   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
-				    &unsignedp, &reversep, &volatilep, false);
+				    &unsignedp, &reversep, &volatilep);
 
   if (bitpos % BITS_PER_UNIT != 0
       || bitsize != size_in_bytes * BITS_PER_UNIT)