diff -Nur gcc-10.3.0.orig/gcc/config/sparc/sparc.c gcc-10.3.0/gcc/config/sparc/sparc.c --- gcc-10.3.0.orig/gcc/config/sparc/sparc.c 2021-04-08 13:56:28.201742273 +0200 +++ gcc-10.3.0/gcc/config/sparc/sparc.c 2022-01-24 10:19:53.724121161 +0100 @@ -4157,6 +4157,13 @@ static bool sparc_cannot_force_const_mem (machine_mode mode, rtx x) { + /* After IRA has run in PIC mode, it is too late to put anything into the + constant pool if the PIC register hasn't already been initialized. */ + if ((lra_in_progress || reload_in_progress) + && flag_pic + && !crtl->uses_pic_offset_table) + return true; + switch (GET_CODE (x)) { case CONST_INT: @@ -4192,11 +4199,9 @@ } /* Global Offset Table support. */ -static GTY(()) rtx got_symbol_rtx = NULL_RTX; -static GTY(()) rtx got_register_rtx = NULL_RTX; static GTY(()) rtx got_helper_rtx = NULL_RTX; - -static GTY(()) bool got_helper_needed = false; +static GTY(()) rtx got_register_rtx = NULL_RTX; +static GTY(()) rtx got_symbol_rtx = NULL_RTX; /* Return the SYMBOL_REF for the Global Offset Table. */ @@ -4209,6 +4214,27 @@ return got_symbol_rtx; } +#ifdef HAVE_GAS_HIDDEN +# define USE_HIDDEN_LINKONCE 1 +#else +# define USE_HIDDEN_LINKONCE 0 +#endif + +static void +get_pc_thunk_name (char name[32], unsigned int regno) +{ + const char *reg_name = reg_names[regno]; + + /* Skip the leading '%' as that cannot be used in a + symbol name. */ + reg_name += 1; + + if (USE_HIDDEN_LINKONCE) + sprintf (name, "__sparc_get_pc_thunk.%s", reg_name); + else + ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", regno); +} + /* Wrapper around the load_pcrel_sym{si,di} patterns. */ static rtx @@ -4228,78 +4254,30 @@ return insn; } -/* Output the load_pcrel_sym{si,di} patterns. */ - -const char * -output_load_pcrel_sym (rtx *operands) -{ - if (flag_delayed_branch) - { - output_asm_insn ("sethi\t%%hi(%a1-4), %0", operands); - output_asm_insn ("call\t%a2", operands); - output_asm_insn (" add\t%0, %%lo(%a1+4), %0", operands); - } - else - { - output_asm_insn ("sethi\t%%hi(%a1-8), %0", operands); - output_asm_insn ("add\t%0, %%lo(%a1-4), %0", operands); - output_asm_insn ("call\t%a2", operands); - output_asm_insn (" nop", NULL); - } - - if (operands[2] == got_helper_rtx) - got_helper_needed = true; - - return ""; -} - -#ifdef HAVE_GAS_HIDDEN -# define USE_HIDDEN_LINKONCE 1 -#else -# define USE_HIDDEN_LINKONCE 0 -#endif - /* Emit code to load the GOT register. */ void load_got_register (void) { - rtx insn; + if (!got_register_rtx) + got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM); if (TARGET_VXWORKS_RTP) - { - if (!got_register_rtx) - got_register_rtx = pic_offset_table_rtx; - - insn = gen_vxworks_load_got (); - } + emit_insn (gen_vxworks_load_got ()); else { - if (!got_register_rtx) - got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM); - /* The GOT symbol is subject to a PC-relative relocation so we need a helper function to add the PC value and thus get the final value. */ if (!got_helper_rtx) { char name[32]; - - /* Skip the leading '%' as that cannot be used in a symbol name. */ - if (USE_HIDDEN_LINKONCE) - sprintf (name, "__sparc_get_pc_thunk.%s", - reg_names[REGNO (got_register_rtx)] + 1); - else - ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", - REGNO (got_register_rtx)); - + get_pc_thunk_name (name, GLOBAL_OFFSET_TABLE_REGNUM); got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); } - insn - = gen_load_pcrel_sym (got_register_rtx, sparc_got (), got_helper_rtx); + emit_insn (gen_load_pcrel_sym (got_register_rtx, sparc_got (), + got_helper_rtx)); } - - emit_insn (insn); } /* Ensure that we are not using patterns that are not OK with PIC. */ @@ -5464,7 +5442,7 @@ return true; /* GOT register (%l7) if needed. */ - if (got_register_rtx && regno == REGNO (got_register_rtx)) + if (regno == GLOBAL_OFFSET_TABLE_REGNUM && got_register_rtx) return true; /* If the function accesses prior frames, the frame pointer and the return @@ -12507,9 +12485,10 @@ sparc_file_end (void) { /* If we need to emit the special GOT helper function, do so now. */ - if (got_helper_needed) + if (got_helper_rtx) { const char *name = XSTR (got_helper_rtx, 0); + const char *reg_name = reg_names[GLOBAL_OFFSET_TABLE_REGNUM]; #ifdef DWARF2_UNWIND_INFO bool do_cfi; #endif @@ -12546,22 +12525,17 @@ #ifdef DWARF2_UNWIND_INFO do_cfi = dwarf2out_do_cfi_asm (); if (do_cfi) - output_asm_insn (".cfi_startproc", NULL); + fprintf (asm_out_file, "\t.cfi_startproc\n"); #endif if (flag_delayed_branch) - { - output_asm_insn ("jmp\t%%o7+8", NULL); - output_asm_insn (" add\t%%o7, %0, %0", &got_register_rtx); - } + fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n", + reg_name, reg_name); else - { - output_asm_insn ("add\t%%o7, %0, %0", &got_register_rtx); - output_asm_insn ("jmp\t%%o7+8", NULL); - output_asm_insn (" nop", NULL); - } + fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n", + reg_name, reg_name); #ifdef DWARF2_UNWIND_INFO if (do_cfi) - output_asm_insn (".cfi_endproc", NULL); + fprintf (asm_out_file, "\t.cfi_endproc\n"); #endif } @@ -13056,10 +13030,7 @@ edge entry_edge; rtx_insn *seq; - /* In PIC mode, we need to always initialize the PIC register if optimization - is enabled, because we are called from IRA and LRA may later force things - to the constant pool for optimization purposes. */ - if (!flag_pic || (!crtl->uses_pic_offset_table && !optimize)) + if (!crtl->uses_pic_offset_table) return; start_sequence (); diff -Nur gcc-10.3.0.orig/gcc/config/sparc/sparc.md gcc-10.3.0/gcc/config/sparc/sparc.md --- gcc-10.3.0.orig/gcc/config/sparc/sparc.md 2021-04-08 13:56:28.205742322 +0200 +++ gcc-10.3.0/gcc/config/sparc/sparc.md 2022-01-24 10:19:54.504102046 +0100 @@ -1601,7 +1601,10 @@ (clobber (reg:P O7_REG))] "REGNO (operands[0]) == INTVAL (operands[3])" { - return output_load_pcrel_sym (operands); + if (flag_delayed_branch) + return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0"; + else + return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop"; } [(set (attr "type") (const_string "multi")) (set (attr "length") diff -Nur gcc-10.3.0.orig/gcc/config/sparc/sparc-protos.h gcc-10.3.0/gcc/config/sparc/sparc-protos.h --- gcc-10.3.0.orig/gcc/config/sparc/sparc-protos.h 2021-04-08 13:56:28.201742273 +0200 +++ gcc-10.3.0/gcc/config/sparc/sparc-protos.h 2022-01-24 10:19:54.548100968 +0100 @@ -69,7 +69,6 @@ extern void sparc_split_mem_reg (rtx, rtx, machine_mode); extern int sparc_split_reg_reg_legitimate (rtx, rtx); extern void sparc_split_reg_reg (rtx, rtx, machine_mode); -extern const char *output_load_pcrel_sym (rtx *); extern const char *output_ubranch (rtx, rtx_insn *); extern const char *output_cbranch (rtx, rtx, int, int, int, rtx_insn *); extern const char *output_return (rtx_insn *); diff -Nur gcc-10.3.0.orig/gcc/testsuite/gcc.c-torture/compile/20191108-1.c gcc-10.3.0/gcc/testsuite/gcc.c-torture/compile/20191108-1.c --- gcc-10.3.0.orig/gcc/testsuite/gcc.c-torture/compile/20191108-1.c 2021-04-08 13:56:28.929751064 +0200 +++ gcc-10.3.0/gcc/testsuite/gcc.c-torture/compile/20191108-1.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,14 +0,0 @@ -/* PR target/92095 */ -/* Testcase by Sergei Trofimovich */ - -typedef union { - double a; - int b[2]; -} c; - -double d(int e) -{ - c f; - (&f)->b[0] = 15728640; - return e ? -(&f)->a : (&f)->a; -} diff -Nur gcc-10.3.0.orig/gcc/testsuite/gcc.target/sparc/overflow-3.c gcc-10.3.0/gcc/testsuite/gcc.target/sparc/overflow-3.c --- gcc-10.3.0.orig/gcc/testsuite/gcc.target/sparc/overflow-3.c 2021-04-08 13:56:29.453757389 +0200 +++ gcc-10.3.0/gcc/testsuite/gcc.target/sparc/overflow-3.c 2022-01-24 10:19:54.688097536 +0100 @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target lp64 } */ -/* { dg-options "-O -fno-pie" } */ +/* { dg-options "-O" } */ #include #include diff -Nur gcc-10.3.0.orig/gcc/testsuite/gcc.target/sparc/overflow-4.c gcc-10.3.0/gcc/testsuite/gcc.target/sparc/overflow-4.c --- gcc-10.3.0.orig/gcc/testsuite/gcc.target/sparc/overflow-4.c 2021-04-08 13:56:29.453757389 +0200 +++ gcc-10.3.0/gcc/testsuite/gcc.target/sparc/overflow-4.c 2022-01-24 10:19:55.336081656 +0100 @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target lp64 } */ -/* { dg-options "-O -fno-pie -mno-vis3 -mno-vis4" } */ +/* { dg-options "-O -mno-vis3 -mno-vis4" } */ #include #include diff -Nur gcc-10.3.0.orig/gcc/testsuite/gcc.target/sparc/overflow-5.c gcc-10.3.0/gcc/testsuite/gcc.target/sparc/overflow-5.c --- gcc-10.3.0.orig/gcc/testsuite/gcc.target/sparc/overflow-5.c 2021-04-08 13:56:29.453757389 +0200 +++ gcc-10.3.0/gcc/testsuite/gcc.target/sparc/overflow-5.c 2022-01-24 10:19:55.336081656 +0100 @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target lp64 } */ -/* { dg-options "-O -fno-pie -mvis3" } */ +/* { dg-options "-O -mvis3" } */ #include #include