From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2140) id B80C9386075C; Thu, 9 Nov 2023 01:58:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B80C9386075C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1699495090; bh=dvD99Zer8y7z0xR1IwV0DN+gLxkrQ4riThVxzqq5izM=; h=From:To:Subject:Date:From; b=i9/xMQYYrvGG1Jx5ro+GNQSIHDRSAT7TotMV8obB0AT6dbnH4o4PVYPXx2KHQihDn WQrtVxNPkj/dKMYdR70NcQOdIUttbt57Nw+CG27tSU5nPCBfuBWp9UpEjI1CwUHSKR AUCN1WnheUhNU8b5fbupkgZyWO0YSYCFeXqVO2fQ= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Alexandre Oliva To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/aoliva/heads/testme)] i386 PIE: accept @GOTOFF in load/store multi base address X-Act-Checkin: gcc X-Git-Author: Alexandre Oliva X-Git-Refname: refs/users/aoliva/heads/testme X-Git-Oldrev: 1e96d7b7b6a9abd07b210c4a2d1fc9ae5f9558aa X-Git-Newrev: 579dcd677619b4046941c0a9f72e38c28b0a431f Message-Id: <20231109015810.B80C9386075C@sourceware.org> Date: Thu, 9 Nov 2023 01:58:10 +0000 (GMT) List-Id: https://gcc.gnu.org/g:579dcd677619b4046941c0a9f72e38c28b0a431f commit 579dcd677619b4046941c0a9f72e38c28b0a431f Author: Alexandre Oliva Date: Tue Jul 26 00:37:25 2022 -0300 i386 PIE: accept @GOTOFF in load/store multi base address Looking at the code generated for sse2-{load,store}-multi.c with PIE, I realized we could use UNSPEC_GOTOFF as a base address, and that this would enable the test to use the vector insns expected by the tests even with PIC, so I extended the base + offset logic used by the SSE2 multi-load/store peepholes to accept reg + symbolic base + offset too, so that the test generated the expected insns even with PIE. for gcc/ChangeLog * config/i386/i386.cc (symbolic_base_address_p, base_address_p): New, factored out from... (extract_base_offset_in_addr): ... here and extended to recognize REG+GOTOFF, as in gcc.target/i386/sse2-load-multi.c and sse2-store-multi.c with PIE enabled by default. Diff: --- gcc/config/i386/i386.cc | 89 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index c2bd07fced7..eec9b42396e 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -25198,11 +25198,40 @@ ix86_reloc_rw_mask (void) } #endif -/* If MEM is in the form of [base+offset], extract the two parts - of address and set to BASE and OFFSET, otherwise return false. */ +/* Return true iff ADDR can be used as a symbolic base address. */ static bool -extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset) +symbolic_base_address_p (rtx addr) +{ + if (GET_CODE (addr) == SYMBOL_REF) + return true; + + if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF) + return true; + + return false; +} + +/* Return true iff ADDR can be used as a base address. */ + +static bool +base_address_p (rtx addr) +{ + if (REG_P (addr)) + return true; + + if (symbolic_base_address_p (addr)) + return true; + + return false; +} + +/* If MEM is in the form of [(base+symbase)+offset], extract the three + parts of address and set to BASE, SYMBASE and OFFSET, otherwise + return false. */ + +static bool +extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset) { rtx addr; @@ -25213,21 +25242,52 @@ extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset) if (GET_CODE (addr) == CONST) addr = XEXP (addr, 0); - if (REG_P (addr) || GET_CODE (addr) == SYMBOL_REF) + if (base_address_p (addr)) { *base = addr; + *symbase = const0_rtx; *offset = const0_rtx; return true; } if (GET_CODE (addr) == PLUS - && (REG_P (XEXP (addr, 0)) - || GET_CODE (XEXP (addr, 0)) == SYMBOL_REF) - && CONST_INT_P (XEXP (addr, 1))) + && base_address_p (XEXP (addr, 0))) { - *base = XEXP (addr, 0); - *offset = XEXP (addr, 1); - return true; + rtx addend = XEXP (addr, 1); + + if (GET_CODE (addend) == CONST) + addend = XEXP (addend, 0); + + if (CONST_INT_P (addend)) + { + *base = XEXP (addr, 0); + *symbase = const0_rtx; + *offset = addend; + return true; + } + + /* Also accept REG + symbolic ref, with or without a CONST_INT + offset. */ + if (REG_P (XEXP (addr, 0))) + { + if (symbolic_base_address_p (addend)) + { + *base = XEXP (addr, 0); + *symbase = addend; + *offset = const0_rtx; + return true; + } + + if (GET_CODE (addend) == PLUS + && symbolic_base_address_p (XEXP (addend, 0)) + && CONST_INT_P (XEXP (addend, 1))) + { + *base = XEXP (addr, 0); + *symbase = XEXP (addend, 0); + *offset = XEXP (addend, 1); + return true; + } + } } return false; @@ -25242,7 +25302,8 @@ ix86_operands_ok_for_move_multiple (rtx *operands, bool load, machine_mode mode) { HOST_WIDE_INT offval_1, offval_2, msize; - rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2, offset_1, offset_2; + rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2, + symbase_1, symbase_2, offset_1, offset_2; if (load) { @@ -25265,13 +25326,13 @@ ix86_operands_ok_for_move_multiple (rtx *operands, bool load, return false; /* Check if the addresses are in the form of [base+offset]. */ - if (!extract_base_offset_in_addr (mem_1, &base_1, &offset_1)) + if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1)) return false; - if (!extract_base_offset_in_addr (mem_2, &base_2, &offset_2)) + if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2)) return false; /* Check if the bases are the same. */ - if (!rtx_equal_p (base_1, base_2)) + if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2)) return false; offval_1 = INTVAL (offset_1);