2015-09-29 Christian Bruel PR target/67745 * config/arm/arm.h (FUNCTION_BOUNDARY): Move optimize_size condition to: * config/arm/arm.c (arm_option_override_internal): Call arm_override_options_after_change_1. (arm_override_options_after_change): New function. (arm_override_options_after_change_1): Likewise. (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): Define hook. 2015-09-29 Christian Bruel PR target/67745 * gcc.target/arm/attr-align1.c: New test. * gcc.target/arm/attr-align2.c: New test. * gcc.target/arm/attr-align3.c: New test. Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 228229) +++ gcc/config/arm/arm.c (working copy) @@ -246,6 +246,7 @@ static tree arm_build_builtin_va_list (v static void arm_expand_builtin_va_start (tree, rtx); static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); static void arm_option_override (void); +static void arm_override_options_after_change (void); static void arm_option_print (FILE *, int, struct cl_target_option *); static void arm_set_current_function (tree); static bool arm_can_inline_p (tree, tree); @@ -407,6 +408,9 @@ static const struct attribute_spec arm_a #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE arm_option_override +#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE +#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE arm_override_options_after_change + #undef TARGET_OPTION_PRINT #define TARGET_OPTION_PRINT arm_option_print @@ -2810,11 +2814,29 @@ static GTY(()) bool thumb_flipper; /* Options after initial target override. */ static GTY(()) tree init_optimize; +static void +arm_override_options_after_change_1 (struct gcc_options *opts) +{ + if (opts->x_align_functions <= 0) + opts->x_align_functions = TARGET_THUMB_P (opts->x_target_flags) + && opts->x_optimize_size ? 2 : 4; +} + +/* Implement targetm.override_options_after_change. */ + +static void +arm_override_options_after_change (void) +{ + arm_override_options_after_change_1 (&global_options); +} + /* Reset options between modes that the user has specified. */ static void arm_option_override_internal (struct gcc_options *opts, struct gcc_options *opts_set) { + arm_override_options_after_change_1 (opts); + if (TARGET_THUMB_P (opts->x_target_flags) && !(ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB))) { Index: gcc/config/arm/arm.h =================================================================== --- gcc/config/arm/arm.h (revision 228229) +++ gcc/config/arm/arm.h (working copy) @@ -565,7 +565,7 @@ extern int arm_arch_crc; #define PREFERRED_STACK_BOUNDARY \ (arm_abi == ARM_ABI_ATPCS ? 64 : STACK_BOUNDARY) -#define FUNCTION_BOUNDARY ((TARGET_THUMB && optimize_size) ? 16 : 32) +#define FUNCTION_BOUNDARY (TARGET_THUMB ? 16 : 32) /* The lowest bit is used to indicate Thumb-mode functions, so the vbit must go into the delta field of pointers to member Index: gcc/testsuite/gcc.target/arm/attr-align1.c =================================================================== --- gcc/testsuite/gcc.target/arm/attr-align1.c (revision 0) +++ gcc/testsuite/gcc.target/arm/attr-align1.c (working copy) @@ -0,0 +1,13 @@ +/* PR target/67745 + Verify alignment when attribute target is used with -falign-functions. */ +/* { dg-do compile } */ +/* { dg-options "-falign-functions=2" } */ + +/* Check that arm code is always 4 bytes aligned. */ +void __attribute__ ((target ("arm"))) +c(void) +{ +} + + +/* { dg-final { scan-assembler-not ".align\[ \t]*1" } } */ Index: gcc/testsuite/gcc.target/arm/attr-align2.c =================================================================== --- gcc/testsuite/gcc.target/arm/attr-align2.c (revision 0) +++ gcc/testsuite/gcc.target/arm/attr-align2.c (working copy) @@ -0,0 +1,15 @@ +/* PR target/67745 + Verify alignment when attribute optimize is used. */ +/* { dg-do compile } */ +/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */ +/* { dg-options "-O2 -mthumb" } */ + +/* Check that thumb code is always 2 bytes aligned for -Os. */ + +void +__attribute__ ((optimize("Os"))) +foo() +{ +} + +/* { dg-final { scan-assembler ".align\[ \t]*1" } } */ Index: gcc/testsuite/gcc.target/arm/attr-align3.c =================================================================== --- gcc/testsuite/gcc.target/arm/attr-align3.c (revision 0) +++ gcc/testsuite/gcc.target/arm/attr-align3.c (working copy) @@ -0,0 +1,13 @@ +/* PR target/67745 + Verify alignment when attribute target is used. */ +/* { dg-do compile } */ +/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */ +/* { dg-options "-Os -mthumb" } */ + +/* Check that thumb code is always 4 bytes aligned. */ +void __attribute__ ((target ("arm"))) +c(void) +{ +} + +/* { dg-final { scan-assembler-not ".align\[ \t]*1" } } */