From patchwork Tue Aug 22 22:50:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Santos X-Patchwork-Id: 804678 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-460752-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="qiwxgaT1"; 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 3xcQdy5DWzz9sDB for ; Wed, 23 Aug 2017 08:46:30 +1000 (AEST) 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:in-reply-to:references; q=dns; s= default; b=tDJcgyUvm17uvCeZbd0u/AOxsB+ics9VLsCPQtCspZtkPb2I5qLR4 v0DylbTe/JKzcAVUnwb0uDilju+Yqrzd0VjXQB5RFcUDshIfsC7H+1BtnshmNmO2 Puj+W2Qy+8h9WoJlARArbxncUdoE+0RUeHNLk2Q6KbRz5v6uScazuY= 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:in-reply-to:references; s=default; bh=gAWtXhs73THuQWbbmmmO3TWXTM0=; b=qiwxgaT19tHyoQpihucJy6yCatPq qHAL3jTv6vbEcaIOivh9XXkF6AwQH0s7XciCMEkSa9LJCkqK2GVBpaqyACsm4evh 1fgeubnTtzihnR129wsx++e0aYYinzqiAHL3J+5n2/MvslmyBHfqWhVntMQdAmID nlNUsdhhF9exSaY= Received: (qmail 24849 invoked by alias); 22 Aug 2017 22:44:45 -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 24627 invoked by uid 89); 22 Aug 2017 22:44:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=recieve, forgotten X-HELO: sasl.smtp.pobox.com Received: from pb-smtp2.pobox.com (HELO sasl.smtp.pobox.com) (64.147.108.71) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 22 Aug 2017 22:44:39 +0000 Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by pb-smtp2.pobox.com (Postfix) with ESMTP id D0F06AB3B4; Tue, 22 Aug 2017 18:44:37 -0400 (EDT) Received: from pb-smtp2.nyi.icgroup.com (unknown [127.0.0.1]) by pb-smtp2.pobox.com (Postfix) with ESMTP id C820BAB3B3; Tue, 22 Aug 2017 18:44:37 -0400 (EDT) Received: from loudmouth.attlocal.net (unknown [76.215.41.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pb-smtp2.pobox.com (Postfix) with ESMTPSA id D1794AB3B0; Tue, 22 Aug 2017 18:44:35 -0400 (EDT) From: Daniel Santos To: gcc-patches , Uros Bizjak , Jan Hubicka , "H . J . Lu" Subject: [PATCH 3/4] [i386] Modify SP realignment in ix86_expand_prologue, et. al. Date: Tue, 22 Aug 2017 17:50:14 -0500 Message-Id: <20170822225015.10358-3-daniel.santos@pobox.com> In-Reply-To: <6bbd474b-d6f9-eed0-8035-0dd8d4b9379d@pobox.com> References: <6bbd474b-d6f9-eed0-8035-0dd8d4b9379d@pobox.com> X-Pobox-Relay-ID: 79C89EFA-878B-11E7-A145-9D2B0D78B957-06139138!pb-smtp2.pobox.com X-IsSubscribed: yes My first version of this patch inited m->fs.sp_realigned_fp_last with the value of m->fs.sp_offset prior to performing the stack realignment. I had forgotten, however, that when we're saving GP regs using MOV that we delay SP modification as long as possible so that the value of m->fs.sp_offset at this point is correct when we've used push, but incorrect when we've used mov. This has been tested on both x86_64-pc-linux-gnu{,x32} with --target_board=unix/\{-m64,-mx32,-m32\}. Original patch description: The SP allocation calculation is now done in ix86_compute_frame_layout and the result stored in ix86_frame::stack_realign_allocate. This change also updates comments for choose_baseaddr to clarify that the alignment returned doesn't necessarily reflect the alignment of the cfa_offset passed (e.g., you can pass cfa_offset 48 and it can return an alignment of 64 bytes). Since the alignment required may be more than 16-bytes, we cannot defer SP allocation to ix86_emit_outlined_ms2sysv_save (when it's enabled), so that function needs to be updated as well. Signed-off-by: Daniel Santos --- gcc/config/i386/i386.c | 58 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 30e84dd5303..dbc771da8aa 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13359,10 +13359,13 @@ choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg, } /* Return an RTX that points to CFA_OFFSET within the stack frame and - the alignment of address. If align is non-null, it should point to + the alignment of address. If ALIGN is non-null, it should point to an alignment value (in bits) that is preferred or zero and will - recieve the alignment of the base register that was selected. The - valid base registers are taken from CFUN->MACHINE->FS. */ + recieve the alignment of the base register that was selected, + irrespective of rather or not CFA_OFFSET is a multiple of that + alignment value. + + The valid base registers are taken from CFUN->MACHINE->FS. */ static rtx choose_baseaddr (HOST_WIDE_INT cfa_offset, unsigned int *align) @@ -14445,35 +14448,35 @@ ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame) rtx sym, addr; rtx rax = gen_rtx_REG (word_mode, AX_REG); const struct xlogue_layout &xlogue = xlogue_layout::get_instance (); - HOST_WIDE_INT rax_offset = xlogue.get_stub_ptr_offset () + m->fs.sp_offset; - HOST_WIDE_INT stack_alloc_size = frame.stack_pointer_offset - m->fs.sp_offset; - HOST_WIDE_INT stack_align_off_in = xlogue.get_stack_align_off_in (); + HOST_WIDE_INT allocate = frame.stack_pointer_offset - m->fs.sp_offset; + + /* AL should only be live with sysv_abi. */ + gcc_assert (!ix86_eax_live_at_start_p ()); + + /* Setup RAX as the stub's base pointer. We use stack_realign_offset rather + we've actually realigned the stack or not. */ + align = GET_MODE_ALIGNMENT (V4SFmode); + addr = choose_baseaddr (frame.stack_realign_offset + + xlogue.get_stub_ptr_offset (), &align); + gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode)); + emit_insn (gen_rtx_SET (rax, addr)); - /* Verify that the incoming stack 16-byte alignment offset matches the - layout we're using. */ - gcc_assert (stack_align_off_in == (m->fs.sp_offset & UNITS_PER_WORD)); + /* Allocate stack if not already done. */ + if (allocate > 0) + pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (-allocate), -1, false); /* Get the stub symbol. */ sym = xlogue.get_stub_rtx (frame_pointer_needed ? XLOGUE_STUB_SAVE_HFP : XLOGUE_STUB_SAVE); RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym); - /* Setup RAX as the stub's base pointer. */ - align = GET_MODE_ALIGNMENT (V4SFmode); - addr = choose_baseaddr (rax_offset, &align); - gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode)); - insn = emit_insn (gen_rtx_SET (rax, addr)); - - gcc_assert (stack_alloc_size >= xlogue.get_stack_space_used ()); - pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-stack_alloc_size), -1, - m->fs.cfa_reg == stack_pointer_rtx); for (i = 0; i < ncregs; ++i) { const xlogue_layout::reginfo &r = xlogue.get_reginfo (i); rtx reg = gen_rtx_REG ((SSE_REGNO_P (r.regno) ? V4SFmode : word_mode), r.regno); - RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset);; + RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset); } gcc_assert (vi == (unsigned)GET_NUM_ELEM (v)); @@ -14728,14 +14731,15 @@ ix86_expand_prologue (void) gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT); /* Record last valid frame pointer offset. */ - m->fs.sp_realigned_fp_last = m->fs.sp_offset; + m->fs.sp_realigned_fp_last = frame.reg_save_offset; /* The computation of the size of the re-aligned stack frame means that we must allocate the size of the register save area before performing the actual alignment. Otherwise we cannot guarantee that there's enough storage above the realignment point. */ - allocate = frame.stack_realign_allocate_offset - m->fs.sp_offset; - if (allocate && !m->call_ms2sysv) + allocate = frame.reg_save_offset - m->fs.sp_offset + + frame.stack_realign_allocate; + if (allocate) pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-allocate), -1, false); @@ -14744,8 +14748,8 @@ ix86_expand_prologue (void) stack_pointer_rtx, GEN_INT (-align_bytes))); m->fs.sp_offset = ROUND_UP (m->fs.sp_offset, align_bytes); - m->fs.sp_realigned = true; - m->fs.sp_realigned_offset = m->fs.sp_offset - frame.nsseregs * 16; + m->fs.sp_realigned_offset = m->fs.sp_offset + - frame.stack_realign_allocate; /* The stack pointer may no longer be equal to CFA - m->fs.sp_offset. Beyond this point, stack access should be done via choose_baseaddr or by using sp_valid_at and fp_valid_at to determine the correct base @@ -14753,6 +14757,8 @@ ix86_expand_prologue (void) and not physical. */ gcc_assert (m->fs.sp_realigned_offset >= m->fs.sp_realigned_fp_last); gcc_assert (m->fs.sp_realigned_offset == frame.stack_realign_offset); + m->fs.sp_realigned = true; + /* SEH unwind emit doesn't currently support REG_CFA_EXPRESSION, which is needed to describe where a register is saved using a realigned stack pointer, so we need to invalidate the stack pointer for that @@ -14814,7 +14820,7 @@ ix86_expand_prologue (void) so probe if the size is non-negative to preserve the protection area. */ if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK) { - /* We expect the registers to be saved when probes are used. */ + /* We expect the GP registers to be saved when probes are used. */ gcc_assert (int_registers_saved); if (STACK_CHECK_MOVING_SP)