OSDN Git Service

2007-07-09 Geoffrey Keating <geoffk@apple.com>
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Jul 2007 23:08:52 +0000 (23:08 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Jul 2007 23:08:52 +0000 (23:08 +0000)
PR 32617
* c-common.c (c_alignof_expr): Look at DECL_ALIGN of
FUNCTION_DECLs.
(handle_aligned_attribute): Allow use on FUNCTION_DECLs.
* varasm.c (assemble_start_function): Honor DECL_ALIGN
for FUNCTION_DECLs.  Don't use align_functions_log if
DECL_USER_ALIGN.
* print-tree.c (print_node): Print DECL_ALIGN and DECL_USER_ALIGN
even for FUNCTION_DECLs.
* c-decl.c (merge_decls): Propagate DECL_ALIGN even for
FUNCTION_DECLs.
* tree.h (DECL_ALIGN): Update for new location of 'align'.
(DECL_FUNCTION_CODE): Update for new location and name of
'function_code'.
(DECL_OFFSET_ALIGN): Update for new location of 'off_align'.
(struct tree_decl_common): Move 'align' and 'off_align' out
of union, ensure they're still on a 32-bit boundary.  Remove
other fields in union 'u1'.
(struct tree_function_decl): Add field 'function_code' replacing
'u1.f' in tree_decl_common.
* tree.c (build_decl_stat): Set initial value of DECL_ALIGN.
* doc/extend.texi (Function Attributes): Add 'aligned' attribute.
(Variable Attributes): Cross-reference 'aligned' attribute
to Function Attributes.
* flags.h (force_align_functions_log): Delete.
* toplev.c (force_align_functions_log): Delete.

Index: gcc/testsuite/ChangeLog
2007-07-09  Geoffrey Keating  <geoffk@apple.com>

PR 32617
* gcc.c-torture/execute/align-3.c: New.

Index: gcc/java/ChangeLog
2007-07-09  Geoffrey Keating  <geoffk@apple.com>

PR 32617
* lang.c (java_init): Remove setting of force_align_functions_log.
* class.c (add_method_1): Set DECL_ALIGN of non-static method
to cope with ptrmemfunc_vbit_in_pfn.

Index: gcc/cp/ChangeLog
2007-07-09  Geoffrey Keating  <geoffk@apple.com>

PR 32617
* decl.c (cxx_init_decl_processing): Don't set
force_align_functions_log.
(grokfndecl): Honour ptrmemfunc_vbit_in_pfn.
* typeck.c (cxx_alignof_expr): When alignof is used on a plain
FUNCTION_DECL, return its alignment.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126529 138bc75d-0d04-0410-961f-82ee72b054a4

18 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-decl.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/typeck.c
gcc/doc/extend.texi
gcc/flags.h
gcc/java/ChangeLog
gcc/java/class.c
gcc/java/lang.c
gcc/print-tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/align-3.c [new file with mode: 0644]
gcc/toplev.c
gcc/tree.c
gcc/tree.h
gcc/varasm.c

index 6ebd9b0..8a29cb3 100644 (file)
@@ -1,3 +1,32 @@
+2007-07-09  Geoffrey Keating  <geoffk@apple.com>
+
+       PR 32617
+       * c-common.c (c_alignof_expr): Look at DECL_ALIGN of
+       FUNCTION_DECLs.
+       (handle_aligned_attribute): Allow use on FUNCTION_DECLs.
+       * varasm.c (assemble_start_function): Honor DECL_ALIGN
+       for FUNCTION_DECLs.  Don't use align_functions_log if
+       DECL_USER_ALIGN.
+       * print-tree.c (print_node): Print DECL_ALIGN and DECL_USER_ALIGN
+       even for FUNCTION_DECLs.
+       * c-decl.c (merge_decls): Propagate DECL_ALIGN even for
+       FUNCTION_DECLs.
+       * tree.h (DECL_ALIGN): Update for new location of 'align'.
+       (DECL_FUNCTION_CODE): Update for new location and name of
+       'function_code'.
+       (DECL_OFFSET_ALIGN): Update for new location of 'off_align'.
+       (struct tree_decl_common): Move 'align' and 'off_align' out
+       of union, ensure they're still on a 32-bit boundary.  Remove
+       other fields in union 'u1'.
+       (struct tree_function_decl): Add field 'function_code' replacing
+       'u1.f' in tree_decl_common.
+       * tree.c (build_decl_stat): Set initial value of DECL_ALIGN.
+       * doc/extend.texi (Function Attributes): Add 'aligned' attribute.
+       (Variable Attributes): Cross-reference 'aligned' attribute
+       to Function Attributes.
+       * flags.h (force_align_functions_log): Delete.
+       * toplev.c (force_align_functions_log): Delete.
+
 2007-07-10  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/32708
index cc8c7ff..b884be9 100644 (file)
@@ -3245,16 +3245,16 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
 }
 
 /* Implement the __alignof keyword: Return the minimum required
-   alignment of EXPR, measured in bytes.  For VAR_DECL's and
-   FIELD_DECL's return DECL_ALIGN (which can be set from an
-   "aligned" __attribute__ specification).  */
+   alignment of EXPR, measured in bytes.  For VAR_DECLs,
+   FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set
+   from an "aligned" __attribute__ specification).  */
 
 tree
 c_alignof_expr (tree expr)
 {
   tree t;
 
-  if (TREE_CODE (expr) == VAR_DECL)
+  if (VAR_OR_FUNCTION_DECL_P (expr))
     t = size_int (DECL_ALIGN_UNIT (expr));
 
   else if (TREE_CODE (expr) == COMPONENT_REF
@@ -5206,12 +5206,24 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
       TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT;
       TYPE_USER_ALIGN (*type) = 1;
     }
-  else if (TREE_CODE (decl) != VAR_DECL
+  else if (! VAR_OR_FUNCTION_DECL_P (decl)
           && TREE_CODE (decl) != FIELD_DECL)
     {
       error ("alignment may not be specified for %q+D", decl);
       *no_add_attrs = true;
     }
+  else if (TREE_CODE (decl) == FUNCTION_DECL
+          && DECL_ALIGN (decl) > (1 << i) * BITS_PER_UNIT)
+    {
+      if (DECL_USER_ALIGN (decl))
+       error ("alignment for %q+D was previously specified as %d "
+              "and may not be decreased", decl,
+              DECL_ALIGN (decl) / BITS_PER_UNIT);
+      else
+       error ("alignment for %q+D must be at least %d", decl,
+              DECL_ALIGN (decl) / BITS_PER_UNIT);
+      *no_add_attrs = true;
+    }
   else
     {
       DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
index 012339e..82e7c73 100644 (file)
@@ -1664,12 +1664,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
       DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
       DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
       DECL_MODE (newdecl) = DECL_MODE (olddecl);
-      if (TREE_CODE (olddecl) != FUNCTION_DECL)
-       if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
-         {
-           DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
-           DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
-         }
+      if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
+       {
+         DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+         DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
+       }
     }
 
 
index 60ae177..c9314be 100644 (file)
@@ -1,3 +1,12 @@
+2007-07-09  Geoffrey Keating  <geoffk@apple.com>
+
+       PR 32617
+       * decl.c (cxx_init_decl_processing): Don't set
+       force_align_functions_log.
+       (grokfndecl): Honour ptrmemfunc_vbit_in_pfn.
+       * typeck.c (cxx_alignof_expr): When alignof is used on a plain
+       FUNCTION_DECL, return its alignment.
+
 2007-07-09  Richard Guenther  <rguenther@suse.de>
 
        * decl.c (start_preparsed_function): Do not promote return type.
index b49bfc8..8b6684c 100644 (file)
@@ -3182,12 +3182,6 @@ cxx_init_decl_processing (void)
   if (flag_visibility_ms_compat)
     default_visibility = VISIBILITY_HIDDEN;
 
-  /* Force minimum function alignment if using the least significant
-     bit of function pointers to store the virtual bit.  */
-  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
-      && force_align_functions_log < 1)
-    force_align_functions_log = 1;
-
   /* Initially, C.  */
   current_lang_name = lang_name_c;
 
@@ -6146,6 +6140,14 @@ grokfndecl (tree ctype,
       break;
     }
 
+  /* If pointers to member functions use the least significant bit to
+     indicate whether a function is virtual, ensure a pointer
+     to this function will have that bit clear.  */
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && TREE_CODE (type) == METHOD_TYPE
+      && DECL_ALIGN (decl) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (decl) = 2 * BITS_PER_UNIT;
+
   if (friendp
       && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
     {
index 7985d85..3b8b914 100644 (file)
@@ -1361,7 +1361,10 @@ cxx_alignof_expr (tree e)
     {
       pedwarn ("ISO C++ forbids applying %<__alignof%> to an expression of "
               "function type");
-      t = size_one_node;
+      if (TREE_CODE (e) == FUNCTION_DECL)
+       t = size_int (DECL_ALIGN_UNIT (e));
+      else
+       t = size_one_node;
     }
   else if (type_unknown_p (e))
     {
index 0a1cdeb..f6fbbfa 100644 (file)
@@ -1605,18 +1605,19 @@ The keyword @code{__attribute__} allows you to specify special
 attributes when making a declaration.  This keyword is followed by an
 attribute specification inside double parentheses.  The following
 attributes are currently defined for functions on all targets:
-@code{alloc_size}, @code{noreturn}, @code{returns_twice}, @code{noinline},
-@code{always_inline}, @code{flatten}, @code{pure}, @code{const},
-@code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
+@code{aligned}, @code{alloc_size}, @code{noreturn},
+@code{returns_twice}, @code{noinline}, @code{always_inline},
+@code{flatten}, @code{pure}, @code{const}, @code{nothrow},
+@code{sentinel}, @code{format}, @code{format_arg},
 @code{no_instrument_function}, @code{section}, @code{constructor},
 @code{destructor}, @code{used}, @code{unused}, @code{deprecated},
 @code{weak}, @code{malloc}, @code{alias}, @code{warn_unused_result},
 @code{nonnull}, @code{gnu_inline} and @code{externally_visible},
 @code{hot}, @code{cold}.
-Several other attributes are defined for functions on particular target
-systems.  Other attributes, including @code{section} are supported for
-variables declarations (@pxref{Variable Attributes}) and for types (@pxref{Type
-Attributes}).
+Several other attributes are defined for functions on particular
+target systems.  Other attributes, including @code{section} are
+supported for variables declarations (@pxref{Variable Attributes}) and
+for types (@pxref{Type Attributes}).
 
 You may also specify attributes with @samp{__} preceding and following
 each keyword.  This allows you to use them in header files without
@@ -1645,6 +1646,27 @@ is not defined in the same translation unit.
 
 Not all target machines support this attribute.
 
+@item aligned (@var{alignment})
+@cindex @code{aligned} attribute
+This attribute specifies a minimum alignment for the function,
+measured in bytes.
+
+You cannot use this attribute to decrease the alignment of a function,
+only to increase it.  However, when you explicitly specify a function
+alignment this will override the effect of the
+@option{-falign-functions} (@pxref{Optimize Options}) option for this
+function.
+
+Note that the effectiveness of @code{aligned} attributes may be
+limited by inherent limitations in your linker.  On many systems, the
+linker is only able to arrange for functions to be aligned up to a
+certain maximum alignment.  (For some linkers, the maximum supported
+alignment may be very very small.)  See your linker documentation for
+further information.
+
+The @code{aligned} attribute can also be used for variables and fields
+(@pxref{Variable Attributes}.)
+
 @item alloc_size
 @cindex @code{alloc_size} attribute
 The @code{alloc_size} attribute is used to tell the compiler that the
@@ -3202,6 +3224,9 @@ up to a maximum of 8 byte alignment, then specifying @code{aligned(16)}
 in an @code{__attribute__} will still only provide you with 8 byte
 alignment.  See your linker documentation for further information.
 
+The @code{aligned} attribute can also be used for functions 
+(@pxref{Function Attributes}.)
+
 @item cleanup (@var{cleanup_function})
 @cindex @code{cleanup} attribute
 The @code{cleanup} attribute runs a function when the variable goes
index 07e5ec3..7927523 100644 (file)
@@ -250,10 +250,6 @@ extern int align_labels_log;
 extern int align_labels_max_skip;
 extern int align_functions_log;
 
-/* Like align_functions_log above, but used by front-ends to force the
-   minimum function alignment.  Zero means no alignment is forced.  */
-extern int force_align_functions_log;
-
 /* Nonzero if we dump in VCG format, not plain text.  */
 extern int dump_for_graph;
 
index 87a0113..f60c2bd 100644 (file)
@@ -1,3 +1,10 @@
+2007-07-09  Geoffrey Keating  <geoffk@apple.com>
+
+       PR 32617
+       * lang.c (java_init): Remove setting of force_align_functions_log.
+       * class.c (add_method_1): Set DECL_ALIGN of non-static method
+       to cope with ptrmemfunc_vbit_in_pfn.
+
 2007-07-03  David Daney  <ddaney@avtrex.com>
 
        * java/Make-lang.in (doc/gcj.info): Add $(gcc_docdir) to 
index 3d43726..bbfe4f2 100644 (file)
@@ -725,6 +725,14 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
   TREE_CHAIN (fndecl) = TYPE_METHODS (this_class);
   TYPE_METHODS (this_class) = fndecl;
 
+  /* If pointers to member functions use the least significant bit to
+     indicate whether a function is virtual, ensure a pointer
+     to this function will have that bit clear.  */
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && !(access_flags & ACC_STATIC)
+      && DECL_ALIGN (fndecl) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (fndecl) = 2 * BITS_PER_UNIT;
+
   /* Notice that this is a finalizer and update the class type
      accordingly. This is used to optimize instance allocation. */
   if (name == finalize_identifier_node
index 7fd6fcd..6a57cd2 100644 (file)
@@ -355,13 +355,6 @@ java_init (void)
   if (!flag_indirect_dispatch)
     flag_indirect_classes = false;
 
-  /* Force minimum function alignment if g++ uses the least significant
-     bit of function pointers to store the virtual bit. This is required
-     to keep vtables compatible.  */
-  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
-      && force_align_functions_log < 1)
-    force_align_functions_log = 1;
-
   jcf_path_seal (v_flag);
 
   java_init_decl_processing ();
index 7301f47..daa2451 100644 (file)
@@ -441,17 +441,15 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
              || DECL_INLINE (node) || DECL_BUILT_IN (node))
            indent_to (file, indent + 3);
          
-         if (TREE_CODE (node) != FUNCTION_DECL)
-           {
-             if (DECL_USER_ALIGN (node))
-               fprintf (file, " user");
-             
-             fprintf (file, " align %d", DECL_ALIGN (node));
-             if (TREE_CODE (node) == FIELD_DECL)
-               fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
-                        DECL_OFFSET_ALIGN (node));
-           }
-         else if (DECL_BUILT_IN (node))
+         if (DECL_USER_ALIGN (node))
+           fprintf (file, " user");
+         
+         fprintf (file, " align %d", DECL_ALIGN (node));
+         if (TREE_CODE (node) == FIELD_DECL)
+           fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
+                    DECL_OFFSET_ALIGN (node));
+
+         if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
            {
              if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
                fprintf (file, " built-in BUILT_IN_MD %d", DECL_FUNCTION_CODE (node));
index a473461..6463310 100644 (file)
@@ -1,3 +1,8 @@
+2007-07-09  Geoffrey Keating  <geoffk@apple.com>
+
+       PR 32617
+       * gcc.c-torture/execute/align-3.c: New.
+
 2007-07-10  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/32708
diff --git a/gcc/testsuite/gcc.c-torture/execute/align-3.c b/gcc/testsuite/gcc.c-torture/execute/align-3.c
new file mode 100644 (file)
index 0000000..12bb146
--- /dev/null
@@ -0,0 +1,14 @@
+void func(void) __attribute__((aligned(256)));
+
+void func(void) 
+{
+}
+
+int main()
+{
+  if (((long)func & 0xFF) != 0)
+    abort ();
+  if (__alignof__(func) != 256)
+    abort ();
+  return 0;
+}
index 8afce8b..c421e56 100644 (file)
@@ -357,10 +357,6 @@ int align_labels_log;
 int align_labels_max_skip;
 int align_functions_log;
 
-/* Like align_functions_log above, but used by front-ends to force the
-   minimum function alignment.  Zero means no alignment is forced.  */
-int force_align_functions_log;
-
 typedef struct
 {
   const char *const string;
index 06472ea..6359ff9 100644 (file)
@@ -3312,7 +3312,10 @@ build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL)
   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
     layout_decl (t, 0);
   else if (code == FUNCTION_DECL)
-    DECL_MODE (t) = FUNCTION_MODE;
+    {
+      DECL_MODE (t) = FUNCTION_MODE;
+      DECL_ALIGN (t) = FUNCTION_BOUNDARY;
+    }
 
   return t;
 }
index a28f20b..318980c 100644 (file)
@@ -2586,7 +2586,7 @@ struct tree_memory_partition_tag GTY(())
 /* Likewise for the size in bytes.  */
 #define DECL_SIZE_UNIT(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size_unit)
 /* Holds the alignment required for the datum, in bits.  */
-#define DECL_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.u1.a.align)
+#define DECL_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.align)
 /* The alignment of NODE, in bytes.  */
 #define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT)
 /* For FIELD_DECLs, off_align holds the number of low-order bits of
@@ -2603,7 +2603,8 @@ struct tree_memory_partition_tag GTY(())
    operation it is.  Note, however, that this field is overloaded, with
    DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be
    checked before any access to the former.  */
-#define DECL_FUNCTION_CODE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_common.u1.f)
+#define DECL_FUNCTION_CODE(NODE) \
+  (FUNCTION_DECL_CHECK (NODE)->function_decl.function_code)
 #define DECL_DEBUG_EXPR_IS_FROM(NODE) \
   (DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from)
 
@@ -2735,21 +2736,12 @@ struct tree_decl_common GTY(())
   unsigned gimple_reg_flag : 1;
   /* In a DECL with pointer type, set if no TBAA should be done.  */
   unsigned no_tbaa_flag : 1;
+  /* Padding so that 'align' can be on a 32-bit boundary.  */
+  unsigned decl_common_unused : 2;
 
-  union tree_decl_u1 {
-    /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
-       DECL_FUNCTION_CODE.  */
-    enum built_in_function f;
-    /* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this
-       is used by language-dependent code.  */
-    HOST_WIDE_INT i;
-    /* DECL_ALIGN and DECL_OFFSET_ALIGN.  (These are not used for
-       FUNCTION_DECLs).  */
-    struct tree_decl_u1_a {
-      unsigned int align : 24;
-      unsigned int off_align : 8;
-    } a;
-  } GTY ((skip)) u1;
+  unsigned int align : 24;
+  /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs.  */
+  unsigned int off_align : 8;
 
   tree size_unit;
   tree initial;
@@ -2834,11 +2826,11 @@ struct tree_decl_with_rtl GTY(())
    DECL_OFFSET_ALIGN thus returns the alignment that DECL_FIELD_OFFSET
    has.  */
 #define DECL_OFFSET_ALIGN(NODE) \
-  (((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl_common.u1.a.off_align)
+  (((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl_common.off_align)
 
 /* Specify that DECL_ALIGN(NODE) is a multiple of X.  */
 #define SET_DECL_OFFSET_ALIGN(NODE, X) \
-  (FIELD_DECL_CHECK (NODE)->decl_common.u1.a.off_align = exact_log2 ((X) & -(X)))
+  (FIELD_DECL_CHECK (NODE)->decl_common.off_align = exact_log2 ((X) & -(X)))
 /* 1 if the alignment for this type was requested by "aligned" attribute,
    0 if it is the default for this type.  */
 
@@ -3277,6 +3269,10 @@ struct tree_function_decl GTY(())
 {
   struct tree_decl_non_common common;
 
+  /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
+     DECL_FUNCTION_CODE.  Otherwise unused.  */
+  enum built_in_function function_code;
+
   unsigned static_ctor_flag : 1;
   unsigned static_dtor_flag : 1;
   unsigned uninlinable : 1;
index 511bf89..854a80d 100644 (file)
@@ -1679,18 +1679,17 @@ assemble_start_function (tree decl, const char *fnname)
     ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label);
 
   /* Tell assembler to move to target machine's alignment for functions.  */
-  align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-  if (align < force_align_functions_log)
-    align = force_align_functions_log;
+  align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
   if (align > 0)
     {
       ASM_OUTPUT_ALIGN (asm_out_file, align);
     }
 
   /* Handle a user-specified function alignment.
-     Note that we still need to align to FUNCTION_BOUNDARY, as above,
+     Note that we still need to align to DECL_ALIGN, as above,
      because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all.  */
-  if (align_functions_log > align
+  if (! DECL_USER_ALIGN (decl)
+      && align_functions_log > align
       && cfun->function_frequency != FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
     {
 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN