On Tue, Nov 4, 2014 at 10:46 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
>> Following patch fixes PR 63538, where the data in the large data >> section was accessed through 32bit address. The patch unifies places >> where large data sections are determined and passes all declarations >> to ix86_in_large_data_p only. >> >> The patch fixes the testcase form the PR. Also, the code from several >> tests involving various -mlarge-data-threshold= settings looks >> consistent now. [...] > We probably want to avoid putting automatic variables (and STRING_CSTs > ?) to large data section. However, it is important that we use the > same condition in ix86_encode_section_info and > x86_64_elf_select_section (and likes), otherwise the data can go into > large section, while the access to the data will be via limited 32bit > pointers. > > The attached alternative patch rejects automatic variables and > STRING_CSTs from large data sections. Please note, that it still > access the data with the correct instructions. Considering that STRING_CSTs always have TREE_STATIC set, the patch should allow them, similar to the patch at [1]. Attached is the final patch. 2014-11-04 Uros Bizjak <ubiz...@gmail.com> PR target/63538 * config/i386/i386.c (in_large_data_p): Reject automatic variables. (ix86_encode_section_info): Do not check for non-automatic varibles when setting SYMBOL_FLAG_FAR_ADDR flag. (x86_64_elf_select_section): Do not check ix86_cmodel here. (x86_64_elf_unique_section): Ditto. (x86_elf_aligned_common): Emit tab before .largecomm. testsuite/ChangeLog: 2014-11-03 Uros Bizjak <ubiz...@gmail.com> PR target/63538 * gcc.target/i386/pr63538.c: New test. I plan to commit the patch in a couple of days to mainline and 4.9 branch. [1] https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01963.html Uros.
Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 217089) +++ gcc/config/i386/i386.c (working copy) @@ -5066,6 +5066,10 @@ ix86_in_large_data_p (tree exp) if (TREE_CODE (exp) == FUNCTION_DECL) return false; + /* Automatic variables are never large data. */ + if (TREE_CODE (exp) == VAR_DECL && !is_global_var (exp)) + return false; + if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) { const char *section = DECL_SECTION_NAME (exp); @@ -5099,8 +5103,7 @@ ATTRIBUTE_UNUSED static section * x86_64_elf_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) { - if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC) - && ix86_in_large_data_p (decl)) + if (ix86_in_large_data_p (decl)) { const char *sname = NULL; unsigned int flags = SECTION_WRITE; @@ -5186,8 +5189,7 @@ x86_64_elf_section_type_flags (tree decl, const ch static void ATTRIBUTE_UNUSED x86_64_elf_unique_section (tree decl, int reloc) { - if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC) - && ix86_in_large_data_p (decl)) + if (ix86_in_large_data_p (decl)) { const char *prefix = NULL; /* We only need to use .gnu.linkonce if we don't have COMDAT groups. */ @@ -5256,7 +5258,7 @@ x86_elf_aligned_common (FILE *file, { if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC) && size > (unsigned int)ix86_section_threshold) - fputs (".largecomm\t", file); + fputs ("\t.largecomm\t", file); else fputs (COMMON_ASM_OP, file); assemble_name (file, name); @@ -44230,9 +44232,7 @@ ix86_encode_section_info (tree decl, rtx rtl, int { default_encode_section_info (decl, rtl, first); - if (TREE_CODE (decl) == VAR_DECL - && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) - && ix86_in_large_data_p (decl)) + if (ix86_in_large_data_p (decl)) SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR; } Index: gcc/testsuite/gcc.target/i386/pr63538.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr63538.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr63538.c (working copy) @@ -0,0 +1,13 @@ +/* PR target/63538 */ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -mcmodel=medium -mlarge-data-threshold=0" } */ + +static char *str = "Hello World"; + +char *foo () +{ + return str; +} + +/* { dg-final { scan-assembler "movabs" } } */