From patchwork Fri Jan 12 11:29:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 859774 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-470961-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="cbWA3rx2"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zJ0sC0279z9sQm for ; Fri, 12 Jan 2018 22:29:49 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=Zl7CJ0vE3lTzjMKu rZTkaNuv2Jf9OfZaTaKsxQYNaFeIB1mvPFpoJzmYx4cr10bT9t5/f1IbbFcG4na8 zYu+JMjHeTaoagjn3bJ3jsqsazUDm5IyF7dfDSsDzpIjQD4Q7a++dk4dQO1Xns8M 86R6FsrExAkUp8xxBthCA3JRTDQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=0n/Pm1xWCu8CYVgv7/oUmb ixqEQ=; b=cbWA3rx2JzaaMSZXlkZf0vXfl3vlEYkb/wbvocUVBGAqGrtuGuTfW7 MLREP9mkmD+aCJLgcY3QLebMvgwenaq/pDfOvPv3QW9k+sRfy/vX8InODUE+r4in wLnA4xcdZxoYABDDD+4skzVJpwW9KV3VCzJ0erzjkpXp3Uce93+XQ= Received: (qmail 63590 invoked by alias); 12 Jan 2018 11:29:42 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 63570 invoked by uid 89); 12 Jan 2018 11:29:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-9.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=screw, 6626, Advertise X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 12 Jan 2018 11:29:38 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 8403E82326 for ; Fri, 12 Jan 2018 12:29:36 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9HVrZMqbuszB for ; Fri, 12 Jan 2018 12:29:36 +0100 (CET) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 48EB0814FA for ; Fri, 12 Jan 2018 12:29:36 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: Fix PR target/83368 Date: Fri, 12 Jan 2018 12:29:35 +0100 Message-ID: <9596295.9SGXmIeu7d@polaris> MIME-Version: 1.0 This fixes a somewhat obscure interaction between alloca and setjmp/longjmp in PIC mode on the SPARC architecture. The problem is that the canonical PIC register on SPARC (%l7) is call-saved like on other architectures but, unlike on other architectures, not (always) preserved by setjmp. There is a note in the SCD about this quirk of setjmp so we must probably live with it. Tested on SPARC64/Linux and SPARC/Solaris, applied on the mainline. 2018-01-12 Eric Botcazou PR target/83368 * config/sparc/sparc.h (PIC_OFFSET_TABLE_REGNUM): Set to INVALID_REGNUM in PIC mode except for TARGET_VXWORKS_RTP. * config/sparc/sparc.c: Include cfgrtl.h. (TARGET_INIT_PIC_REG): Define. (TARGET_USE_PSEUDO_PIC_REG): Likewise. (sparc_pic_register_p): New predicate. (sparc_legitimate_address_p): Use it. (sparc_legitimize_pic_address): Likewise. (sparc_delegitimize_address): Likewise. (sparc_mode_dependent_address_p): Likewise. (gen_load_pcrel_sym): Remove 4th parameter. (load_got_register): Adjust call to above. Remove obsolete stuff. (sparc_expand_prologue): Do not call load_got_register here. (sparc_flat_expand_prologue): Likewise. (sparc_output_mi_thunk): Set the pic_offset_table_rtx object. (sparc_use_pseudo_pic_reg): New function. (sparc_init_pic_reg): Likewise. * config/sparc/sparc.md (vxworks_load_got): Set the GOT register. (builtin_setjmp_receiver): Enable only for TARGET_VXWORKS_RTP. 2018-01-12 Eric Botcazou * gcc.target/sparc/setjmp-1.c: New test. Index: config/sparc/sparc.c =================================================================== --- config/sparc/sparc.c (revision 256275) +++ config/sparc/sparc.c (working copy) @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. #include "explow.h" #include "expr.h" #include "debug.h" +#include "cfgrtl.h" #include "common/common-target.h" #include "gimplify.h" #include "langhooks.h" @@ -662,6 +663,8 @@ static bool sparc_frame_pointer_required static bool sparc_can_eliminate (const int, const int); static rtx sparc_builtin_setjmp_frame_value (void); static void sparc_conditional_register_usage (void); +static bool sparc_use_pseudo_pic_reg (void); +static void sparc_init_pic_reg (void); #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING static const char *sparc_mangle_type (const_tree); #endif @@ -877,6 +880,12 @@ char sparc_hard_reg_printed[8]; #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE sparc_conditional_register_usage +#undef TARGET_INIT_PIC_REG +#define TARGET_INIT_PIC_REG sparc_init_pic_reg + +#undef TARGET_USE_PSEUDO_PIC_REG +#define TARGET_USE_PSEUDO_PIC_REG sparc_use_pseudo_pic_reg + #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING #undef TARGET_MANGLE_TYPE #define TARGET_MANGLE_TYPE sparc_mangle_type @@ -4361,6 +4370,25 @@ legitimate_pic_operand_p (rtx x) return true; } +/* Return true if X is a representation of the PIC register. */ + +static bool +sparc_pic_register_p (rtx x) +{ + if (!REG_P (x) || !pic_offset_table_rtx) + return false; + + if (x == pic_offset_table_rtx) + return true; + + if (!HARD_REGISTER_P (pic_offset_table_rtx) + && (HARD_REGISTER_P (x) || lra_in_progress) + && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx)) + return true; + + return false; +} + #define RTX_OK_FOR_OFFSET_P(X, MODE) \ (CONST_INT_P (X) \ && INTVAL (X) >= -0x1000 \ @@ -4401,7 +4429,7 @@ sparc_legitimate_address_p (machine_mode } if ((flag_pic == 1 - && rs1 == pic_offset_table_rtx + && sparc_pic_register_p (rs1) && !REG_P (rs2) && GET_CODE (rs2) != SUBREG && GET_CODE (rs2) != LO_SUM @@ -4796,7 +4824,7 @@ sparc_legitimize_pic_address (rtx orig, rtx base, offset; if (GET_CODE (XEXP (orig, 0)) == PLUS - && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) + && sparc_pic_register_p (XEXP (XEXP (orig, 0), 0))) return orig; if (reg == 0) @@ -4901,8 +4929,7 @@ sparc_delegitimize_address (rtx x) /* This is generated by mov{si,di}_pic_label_ref in PIC mode. */ if (GET_CODE (x) == MINUS - && REG_P (XEXP (x, 0)) - && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM + && sparc_pic_register_p (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) == LO_SUM && GET_CODE (XEXP (XEXP (x, 1), 1)) == UNSPEC && XINT (XEXP (XEXP (x, 1), 1), 1) == UNSPEC_MOVE_PIC_LABEL) @@ -4981,14 +5008,10 @@ static bool sparc_mode_dependent_address_p (const_rtx addr, addr_space_t as ATTRIBUTE_UNUSED) { - if (flag_pic && GET_CODE (addr) == PLUS) - { - rtx op0 = XEXP (addr, 0); - rtx op1 = XEXP (addr, 1); - if (op0 == pic_offset_table_rtx - && symbolic_operand (op1, VOIDmode)) - return true; - } + if (GET_CODE (addr) == PLUS + && sparc_pic_register_p (XEXP (addr, 0)) + && symbolic_operand (XEXP (addr, 1), VOIDmode)) + return true; return false; } @@ -5017,7 +5040,7 @@ get_pc_thunk_name (char name[32], unsign /* Wrapper around the load_pcrel_sym{si,di} patterns. */ static rtx -gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2, rtx op3) +gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2) { int orig_flag_pic = flag_pic; rtx insn; @@ -5025,9 +5048,9 @@ gen_load_pcrel_sym (rtx op0, rtx op1, rt /* The load_pcrel_sym{si,di} patterns require absolute addressing. */ flag_pic = 0; if (TARGET_ARCH64) - insn = gen_load_pcrel_symdi (op0, op1, op2, op3); + insn = gen_load_pcrel_symdi (op0, op1, op2, GEN_INT (REGNO (op0))); else - insn = gen_load_pcrel_symsi (op0, op1, op2, op3); + insn = gen_load_pcrel_symsi (op0, op1, op2, GEN_INT (REGNO (op0))); flag_pic = orig_flag_pic; return insn; @@ -5038,7 +5061,6 @@ gen_load_pcrel_sym (rtx op0, rtx op1, rt void load_got_register (void) { - /* In PIC mode, this will retrieve pic_offset_table_rtx. */ if (!global_offset_table_rtx) global_offset_table_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM); @@ -5056,15 +5078,8 @@ load_got_register (void) } emit_insn (gen_load_pcrel_sym (global_offset_table_rtx, sparc_got (), - got_helper_rtx, - GEN_INT (GLOBAL_OFFSET_TABLE_REGNUM))); + got_helper_rtx)); } - - /* Need to emit this whether or not we obey regdecls, - since setjmp/longjmp can cause life info to screw up. - ??? In the case where we don't obey regdecls, this is not sufficient - since we may not fall out the bottom. */ - emit_use (global_offset_table_rtx); } /* Emit a call instruction with the pattern given by PAT. ADDR is the @@ -6039,10 +6054,6 @@ sparc_expand_prologue (void) - sparc_apparent_frame_size, SORR_SAVE); - /* Load the GOT register if needed. */ - if (crtl->uses_pic_offset_table) - load_got_register (); - /* Advertise that the data calculated just above are now valid. */ sparc_prologue_data_valid_p = true; } @@ -6161,10 +6172,6 @@ sparc_flat_expand_prologue (void) - sparc_apparent_frame_size, SORR_SAVE); - /* Load the GOT register if needed. */ - if (crtl->uses_pic_offset_table) - load_got_register (); - /* Advertise that the data calculated just above are now valid. */ sparc_prologue_data_valid_p = true; } @@ -12305,6 +12312,8 @@ sparc_output_mi_thunk (FILE *file, tree spill_reg = gen_rtx_REG (word_mode, 15); /* %o7 */ start_sequence (); load_got_register (); /* clobbers %o7 */ + if (!TARGET_VXWORKS_RTP) + pic_offset_table_rtx = global_offset_table_rtx; scratch = sparc_legitimize_pic_address (funexp, scratch); seq = get_insns (); end_sequence (); @@ -12950,6 +12959,37 @@ sparc_conditional_register_usage (void) global_regs[SPARC_GSR_REG] = 1; } +/* Implement TARGET_USE_PSEUDO_PIC_REG. */ + +static bool +sparc_use_pseudo_pic_reg (void) +{ + return !TARGET_VXWORKS_RTP && flag_pic; +} + +/* Implement TARGET_INIT_PIC_REG. */ + +static void +sparc_init_pic_reg (void) +{ + edge entry_edge; + rtx_insn *seq; + + if (!crtl->uses_pic_offset_table) + return; + + start_sequence (); + load_got_register (); + if (!TARGET_VXWORKS_RTP) + emit_move_insn (pic_offset_table_rtx, global_offset_table_rtx); + seq = get_insns (); + end_sequence (); + + entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + insert_insn_on_edge (seq, entry_edge); + commit_one_edge_insertion (entry_edge); +} + /* Implement TARGET_PREFERRED_RELOAD_CLASS: - We can't load constants into FP registers. Index: config/sparc/sparc.h =================================================================== --- config/sparc/sparc.h (revision 256275) +++ config/sparc/sparc.h (working copy) @@ -808,11 +808,14 @@ extern enum cmodel sparc_cmodel; #define GLOBAL_OFFSET_TABLE_REGNUM 23 -/* Register which holds offset table for position-independent - data references. */ +/* Register which holds offset table for position-independent data references. + The original SPARC ABI imposes no requirement on the choice of the register + so we use a pseudo-register to make sure it is properly saved and restored + around calls to setjmp. Now the ABI of VxWorks RTP makes it live on entry + to PLT entries so we use the canonical GOT register in this case. */ #define PIC_OFFSET_TABLE_REGNUM \ - (flag_pic ? GLOBAL_OFFSET_TABLE_REGNUM : INVALID_REGNUM) + (TARGET_VXWORKS_RTP && flag_pic ? GLOBAL_OFFSET_TABLE_REGNUM : INVALID_REGNUM) /* Pick a default value we can notice from override_options: !v9: Default is on. Index: config/sparc/sparc.md =================================================================== --- config/sparc/sparc.md (revision 256275) +++ config/sparc/sparc.md (working copy) @@ -1797,7 +1797,7 @@ (define_insn "*movsi_lo_sum_pic_label_re "flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") -;; Set up the PIC register for VxWorks. +;; Set up the GOT register for VxWorks. (define_expand "vxworks_load_got" [(set (match_dup 0) @@ -1808,7 +1808,7 @@ (define_expand "vxworks_load_got" (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))] "TARGET_VXWORKS_RTP" { - operands[0] = pic_offset_table_rtx; + operands[0] = global_offset_table_rtx; operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE); operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX); }) @@ -7475,7 +7475,7 @@ (define_expand "nonlocal_goto" (define_expand "builtin_setjmp_receiver" [(label_ref (match_operand 0 "" ""))] - "flag_pic" + "TARGET_VXWORKS_RTP && flag_pic" { load_got_register (); DONE;