The attached patch implements ASM_OUTPUT_ALIGNED_DECL_LOCAL for msp430. The
default handler needs to be overridden so local common symbols which need
their own section (e.g. variables with the "noinit" attribute) will be placed
in that section rather than the common block.

This fixes "gcc.c-torture/execute/noinit-attribute.c   -O2 -flto
-fuse-linker-plugin -fno-fat-lto-objects  execution test", which was failing
because the global noinit variable would get optimized into a local common
variable by LTO and placed in the common block, which always get initialized to
0.

The attached patch also skips the noinit-attribute test for msp430 when -mlarge
is being tested. The simulator linker script for -mlarge simulates the copying
of data from ROM to RAM at startup, so a variable in the test which is supposed
to check if this is the first or second time round the test, is always reset to
its initial value, causing the test to loop forever and eventually timeout.

Successfully regtested for msp430-elf in the default, -mcpu=msp430 and -mlarge
configurations.

Committed as obvious.
>From e8fb1a3892f4e2f8268ac2649776a7bd0a967643 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <joze...@mittosystems.com>
Date: Fri, 8 May 2020 14:45:20 +0100
Subject: [PATCH] MSP430: Define ASM_OUTPUT_ALIGNED_DECL_LOCAL

gcc/ChangeLog:

2020-05-12  Jozef Lawrynowicz  <joze...@mittosystems.com>

	* config/msp430/msp430-protos.h (msp430_output_aligned_decl_common):
	Update prototype to include "local" argument.
	* config/msp430/msp430.c (msp430_output_aligned_decl_common): Add
	"local" argument.  Handle local common decls.
	* config/msp430/msp430.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Adjust
	msp430_output_aligned_decl_common call with 0 for "local" argument.
	(ASM_OUTPUT_ALIGNED_DECL_LOCAL): Define.

gcc/testsuite/ChangeLog:

2020-05-12  Jozef Lawrynowicz  <joze...@mittosystems.com>

	* gcc.c-torture/execute/noinit-attribute.c: Skip for msp430
	in the large memory model.
---
 gcc/ChangeLog                                 | 10 ++++++++++
 gcc/config/msp430/msp430-protos.h             |  3 ++-
 gcc/config/msp430/msp430.c                    | 19 +++++++++++++++----
 gcc/config/msp430/msp430.h                    |  8 +++++++-
 gcc/testsuite/ChangeLog                       |  5 +++++
 .../gcc.c-torture/execute/noinit-attribute.c  |  6 +++++-
 6 files changed, 44 insertions(+), 7 deletions(-)

diff --git gcc/ChangeLog gcc/ChangeLog
index b0a9212688a..e2b01aaae27 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,3 +1,13 @@
+2020-05-12  Jozef Lawrynowicz  <joze...@mittosystems.com>
+
+	* config/msp430/msp430-protos.h (msp430_output_aligned_decl_common):
+	Update prototype to include "local" argument.
+	* config/msp430/msp430.c (msp430_output_aligned_decl_common): Add
+	"local" argument.  Handle local common decls.
+	* config/msp430/msp430.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Adjust
+	msp430_output_aligned_decl_common call with 0 for "local" argument.
+	(ASM_OUTPUT_ALIGNED_DECL_LOCAL): Define.
+
 2020-05-12  Richard Biener  <rguent...@suse.de>
 
 	* cfghooks.c (split_edge): Preserve EDGE_DFS_BACK if set.
diff --git gcc/config/msp430/msp430-protos.h gcc/config/msp430/msp430-protos.h
index 657af4c7075..29ce9babc4a 100644
--- gcc/config/msp430/msp430-protos.h
+++ gcc/config/msp430/msp430-protos.h
@@ -39,7 +39,8 @@ bool    msp430_is_interrupt_func (void);
 const char * msp430x_logical_shift_right (rtx);
 const char * msp430_mcu_name (void);
 void    msp430_output_aligned_decl_common (FILE *, const tree, const char *,
-					   unsigned HOST_WIDE_INT, unsigned);
+					   unsigned HOST_WIDE_INT, unsigned,
+					   int);
 void	msp430_output_labelref (FILE *, const char *);
 void	msp430_register_pragmas (void);
 rtx	msp430_return_addr_rtx (int);
diff --git gcc/config/msp430/msp430.c gcc/config/msp430/msp430.c
index e77ca101599..6bb1714f465 100644
--- gcc/config/msp430/msp430.c
+++ gcc/config/msp430/msp430.c
@@ -2019,13 +2019,15 @@ msp430_unique_section (tree decl, int reloc)
 
 /* Emit a declaration of a common symbol.
    If a data region is in use then put the symbol into the
-   equivalent .bss section instead.  */
+   equivalent .bss section instead.
+   If LOCAL is 1, then DECL is for a local common variable.  */
 void
 msp430_output_aligned_decl_common (FILE *		  stream,
 				   const tree		  decl,
 				   const char *		  name,
 				   unsigned HOST_WIDE_INT size,
-				   unsigned int		  align)
+				   unsigned int		  align,
+				   int local)
 {
   /* Only emit a common symbol if the variable does not have a specific section
      assigned.  */
@@ -2039,6 +2041,12 @@ msp430_output_aligned_decl_common (FILE *		  stream,
       && !has_attr (ATTR_PERSIST, decl)
       && !has_attr (ATTR_NOINIT, decl))
     {
+      if (local)
+	{
+	  fprintf (stream, LOCAL_ASM_OP);
+	  assemble_name (stream, name);
+	  fprintf (stream, "\n");
+	}
       fprintf (stream, COMMON_ASM_OP);
       assemble_name (stream, name);
       fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
@@ -2069,8 +2077,11 @@ msp430_output_aligned_decl_common (FILE *		  stream,
 
       switch_to_section (sec);
       ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
-      targetm.asm_out.globalize_label (stream, name);
-      ASM_WEAKEN_LABEL (stream, name);
+      if (!local)
+	{
+	  targetm.asm_out.globalize_label (stream, name);
+	  ASM_WEAKEN_LABEL (stream, name);
+	}
       ASM_OUTPUT_LABEL (stream, name);
       ASM_OUTPUT_SKIP (stream, size ? size : 1);
     }
diff --git gcc/config/msp430/msp430.h gcc/config/msp430/msp430.h
index 1042c592694..f198981ad9e 100644
--- gcc/config/msp430/msp430.h
+++ gcc/config/msp430/msp430.h
@@ -517,7 +517,13 @@ void msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
 #undef  USE_SELECT_SECTION_FOR_FUNCTIONS
 #define USE_SELECT_SECTION_FOR_FUNCTIONS 1
 
+#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
 #define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN)	\
-  msp430_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
+  msp430_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), (ALIGN), 0)
+
+#undef  ASM_OUTPUT_ALIGNED_DECL_LOCAL
+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
+  msp430_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), (ALIGN), 1)
+
 
 #define SYMBOL_FLAG_LOW_MEM (SYMBOL_FLAG_MACH_DEP << 0)
diff --git gcc/testsuite/ChangeLog gcc/testsuite/ChangeLog
index da776417bd5..b83e0ee45a5 100644
--- gcc/testsuite/ChangeLog
+++ gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-05-12  Jozef Lawrynowicz  <joze...@mittosystems.com>
+
+	* gcc.c-torture/execute/noinit-attribute.c: Skip for msp430
+	in the large memory model.
+
 2020-05-12  Jozef Lawrynowicz  <joze...@mittosystems.com>
 
 	* gcc.target/msp430/region-attribute-misuse.c: Allow a .bss section to
diff --git gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
index b99417c404e..20a2a452e79 100644
--- gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
+++ gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
@@ -1,8 +1,12 @@
 /* { dg-do run } */
 /* { dg-require-effective-target noinit } */
 /* { dg-options "-O2" } */
+/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
 
-/* This test checks that noinit data is handled correctly.  */
+/* This test checks that noinit data is handled correctly.
+   If data LMA != VMA (e.g. for simulating the copy of data from ROM to RAM),
+   then var_init will always be re-initialized to 2 and this test will loop
+   forever.  */
 
 extern void _start (void) __attribute__ ((noreturn));
 extern void abort (void) __attribute__ ((noreturn));
-- 
2.17.1

Reply via email to