From patchwork Fri Nov 20 03:34:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 1403441 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux-mips.org Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CchxL3xQWz9sSs for ; Fri, 20 Nov 2020 14:34:30 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4AFAE38708BA; Fri, 20 Nov 2020 03:34:27 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from cvs.linux-mips.org (eddie.linux-mips.org [148.251.95.138]) by sourceware.org (Postfix) with ESMTP id 0ABBC38708BA for ; Fri, 20 Nov 2020 03:34:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0ABBC38708BA Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux-mips.org Authentication-Results: sourceware.org; spf=none smtp.mailfrom=macro@linux-mips.org Received: from localhost.localdomain ([127.0.0.1]:41486 "EHLO localhost" rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP id S23990678AbgKTDeWsRE5Z (ORCPT ); Fri, 20 Nov 2020 04:34:22 +0100 Date: Fri, 20 Nov 2020 03:34:22 +0000 (GMT) From: "Maciej W. Rozycki" To: gcc-patches@gcc.gnu.org Subject: [PATCH 03/31] VAX: Define LEGITIMATE_PIC_OPERAND_P In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_STOCKGEN, KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anders Magnusson Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The VAX ELF psABI does not permit the use of all hardware operand modes for PIC symbol references due to the need to use PC-relative addressing for symbols that end up local and the need to make references indirect symbols that end up global. Therefore symbols referred as immediates may only be used with the move and push address (MOVA and PUSHA) instructions and their PC-relative displacement address mode, as there is no genuine PC-relative immediate available that all the other instructions would have to use. Furthermore global symbol references must not have an offset applied, which has to be added with a separate instruction, because there is no support now for GOT entries for external `symbol+offset' references, so any indirect GOT references made by the static linker from the original direct symbol references must not have an addend applied. Consequently no addend is allowed even if a given external symbol turns out local, for whatever reason, at the static link time. Define the LEGITIMATE_PIC_OPERAND_P macro then, a corresponding function and predicate to exclude the relevant expressions as required, and then a constraint so that reloads are produced where needed, and use the new facilities in the machine description, folding corresponding duplicated patterns for local and external symbols together. Rewrite predicates to make use of the new function, rename them to match their sense and also remove ones no longer used. All this fixing an ICE like this: during RTL pass: postreload .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c: In function 'testE': .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:89:1: internal compiler error: in reload_combine_note_use, at postreload.c:1559 .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:96:65: note: in expansion of macro 'T' 0x10fe84cb reload_combine_note_use .../gcc/postreload.c:1559 0x10fe8857 reload_combine_note_use .../gcc/postreload.c:1621 0x10fe8303 reload_combine_note_use .../gcc/postreload.c:1517 0x10fe7c7b reload_combine .../gcc/postreload.c:1408 0x10fe3417 reload_cse_regs .../gcc/postreload.c:67 0x10feaf9f execute .../gcc/postreload.c:2358 due to the presence of a pseudo register post-reload: (insn 435 228 229 13 (set (reg:SI 1 %r1) (mem/c:SI (reg/f:SI 341) [25 sE+12 S4 A8])) ".../gcc/testsuite/gcc.c-torture/execute/20040709-2.c":96:65 12 {movsi_2} (nil)) (due to the use of an offset `sE+12' symbol reference) and removing these regressions: FAIL: gcc.c-torture/execute/20040709-2.c -O2 (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O2 (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -g (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -g (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -Os (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -Os (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -O2 (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -O2 (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -O3 -g (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -O3 -g (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -Os (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -Os (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors) FAIL: gcc.dg/torture/pr52028.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) FAIL: gcc.dg/torture/pr52028.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) gcc/ * config/vax/constraints.md (A): New constraint. * config/vax/predicates.md (external_symbolic_operand) (external_const_operand): Remove predicates. (local_symbolic_operand): Rename to... (pic_symbolic_operand): ... this, and rework. (external_memory_operand): Rename to... (non_pic_external_memory_operand): ... this, and rework. (illegal_blk_memory_operand, illegal_addsub_di_memory_operand): Update accordingly. * config/vax/vax-protos.h (vax_acceptable_pic_operand_p): New prototype. * config/vax/vax.c (vax_acceptable_pic_operand_p): New function. (vax_output_int_add): Update according to predicate rework. * config/vax/vax.h (LEGITIMATE_PIC_OPERAND_P): New macro. * config/vax/vax.md (pushlclsymreg, pushextsymreg): Fold together, and rename to... (*pushsymreg): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. (movlclsymreg, movextsymreg): Fold together, and rename to... (*movsymreg): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. (pushextsym, pushlclsym): Fold together, and rename to... (*pushsym): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. (movextsym, movlclsym): Fold together, and rename to... (*movsym): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. --- gcc/config/vax/constraints.md | 4 ++++ gcc/config/vax/predicates.md | 34 ++++++++------------------- gcc/config/vax/vax-protos.h | 1 + gcc/config/vax/vax.c | 39 +++++++++++++++++++++++++++++-- gcc/config/vax/vax.h | 5 ++++ gcc/config/vax/vax.md | 54 +++++++++++-------------------------------- 6 files changed, 70 insertions(+), 67 deletions(-) diff --git a/gcc/config/vax/constraints.md b/gcc/config/vax/constraints.md index b8262b6da6f..d4eddb82a66 100644 --- a/gcc/config/vax/constraints.md +++ b/gcc/config/vax/constraints.md @@ -112,6 +112,10 @@ (define_memory_constraint "R" (and (match_operand:DI 0 "memory_operand") (not (match_operand:DI 0 "illegal_addsub_di_memory_operand" "")))) +(define_constraint "A" + "@internal An integer constant suitable for address load operations." + (match_test ("CONSTANT_P (op) && pic_symbolic_operand (op, mode)"))) + (define_constraint "T" "@internal satisfies CONSTANT_P and, if pic is enabled, is not a SYMBOL_REF, LABEL_REF, or CONST." (and (match_test ("CONSTANT_P (op)")) diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md index 7eefc605e98..93e91e499a6 100644 --- a/gcc/config/vax/predicates.md +++ b/gcc/config/vax/predicates.md @@ -23,33 +23,17 @@ (define_predicate "symbolic_operand" (match_code "const,symbol_ref,label_ref")) -(define_predicate "local_symbolic_operand" - (match_code "const,symbol_ref,label_ref") -{ - if (GET_CODE (op) == LABEL_REF) - return 1; - if (GET_CODE (op) == SYMBOL_REF) - return !flag_pic || SYMBOL_REF_LOCAL_P (op); - if (GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF) - return 1; - return !flag_pic || SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0)); -}) - -(define_predicate "external_symbolic_operand" - (and (match_code "symbol_ref") - (not (match_operand 0 "local_symbolic_operand" "")))) - -(define_predicate "external_const_operand" - (and (match_code "const") - (match_test "GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF - && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0))"))) +(define_predicate "pic_symbolic_operand" + (and (match_code "const,symbol_ref,label_ref") + (match_test "!flag_pic + || vax_acceptable_pic_operand_p (op, false, true)"))) (define_predicate "nonsymbolic_operand" (and (ior (match_test "!flag_pic") (not (match_operand 0 "symbolic_operand"))) (match_operand 0 "general_operand" ""))) -(define_predicate "external_memory_operand" +(define_predicate "non_pic_external_memory_operand" (match_code "mem") { rtx addr = XEXP (op, 0); @@ -61,8 +45,8 @@ (define_predicate "external_memory_operand" addr = XEXP (addr, 0); if (GET_CODE (addr) == PLUS) addr = XEXP (addr, 1); - return external_symbolic_operand (addr, SImode) - || external_const_operand (addr, SImode); + return (symbolic_operand (addr, SImode) + && !vax_acceptable_pic_operand_p (addr, true, true)); }) (define_predicate "indirect_memory_operand" @@ -87,7 +71,7 @@ (define_predicate "indexed_memory_operand" (define_predicate "illegal_blk_memory_operand" (and (match_code "mem") (ior (and (match_test "flag_pic") - (match_operand 0 "external_memory_operand" "")) + (match_operand 0 "non_pic_external_memory_operand" "")) (ior (match_operand 0 "indexed_memory_operand" "") (ior (match_operand 0 "indirect_memory_operand" "") (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))))) @@ -95,7 +79,7 @@ (define_predicate "illegal_blk_memory_operand" (define_predicate "illegal_addsub_di_memory_operand" (and (match_code "mem") (ior (and (match_test "flag_pic") - (match_operand 0 "external_memory_operand" "")) + (match_operand 0 "non_pic_external_memory_operand" "")) (ior (match_operand 0 "indexed_memory_operand" "") (ior (match_operand 0 "indirect_memory_operand" "") (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))))) diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index cda2544f7d5..454d35e3383 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -21,6 +21,7 @@ extern bool legitimate_constant_address_p (rtx); extern void vax_expand_prologue (void); #ifdef RTX_CODE +extern bool vax_acceptable_pic_operand_p (rtx, bool, bool); extern const char *cond_name (rtx); extern bool adjacent_operands_p (rtx, rtx, machine_mode); extern const char *rev_cond_name (rtx); diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 0b3b76ed6da..37f5dadc74c 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1033,6 +1033,39 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, return true; } +/* With ELF we do not support GOT entries for external `symbol+offset' + references, so do not accept external symbol references if an offset + is to be added. Do not accept external symbol references at all if + LOCAL_P is set. This is for cases where making a reference indirect + would make it invalid. Do not accept any kind of symbols if SYMBOL_P + is clear. This is for situations where the a reference is used as an + immediate value for operations other than address loads (MOVA/PUSHA), + as those operations do not support PC-relative immediates. */ + +bool +vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED, + bool local_p ATTRIBUTE_UNUSED, + bool symbol_p ATTRIBUTE_UNUSED) +{ +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) + { + x = XEXP (XEXP (x, 0), 0); + local_p = true; + } + switch (GET_CODE (x)) + { + case SYMBOL_REF: + return symbol_p && !(local_p && !SYMBOL_REF_LOCAL_P (x)); + case LABEL_REF: + return symbol_p && !(local_p && LABEL_REF_NONLOCAL_P (x)); + default: + break; + } +#endif + return true; +} + /* Output code to add DELTA to the first argument, and then jump to FUNCTION. Used for C++ multiple inheritance. .mask ^m #conservative entry mask @@ -1370,8 +1403,10 @@ vax_output_int_add (rtx_insn *insn, rtx *operands, machine_mode mode) { gcc_assert (rtx_equal_p (operands[0], operands[1])); #ifdef NO_EXTERNAL_INDIRECT_ADDRESS - gcc_assert (!flag_pic || !external_memory_operand (low[2], SImode)); - gcc_assert (!flag_pic || !external_memory_operand (low[0], SImode)); + gcc_assert (!flag_pic + || !non_pic_external_memory_operand (low[2], SImode)); + gcc_assert (!flag_pic + || !non_pic_external_memory_operand (low[0], SImode)); #endif /* No reason to add a 0 to the low part and thus no carry, so just diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index c1d0171d94d..146b0a6e2b2 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -442,6 +442,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; of a shift count. */ /* #define SHIFT_COUNT_TRUNCATED */ +/* We need to reject symbol references in PIC code except for address + loads, handled elsewhere. */ +#define LEGITIMATE_PIC_OPERAND_P(x) \ + vax_acceptable_pic_operand_p ((x), false, false) + /* Specify the machine mode that pointers have. After generation of rtl, the compiler makes no further distinction between pointers and any other objects of this machine mode. */ diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index e3018a0ee06..e6b217fd0d7 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -338,34 +338,6 @@ (define_insn "add3" add2 %1,%0 add3 %1,%2,%0") -(define_insn "pushlclsymreg" - [(set (match_operand:SI 0 "push_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "local_symbolic_operand" "i")))] - "flag_pic" - "pushab %a2[%1]") - -(define_insn "pushextsymreg" - [(set (match_operand:SI 0 "push_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "external_symbolic_operand" "i")))] - "flag_pic" - "pushab %a2[%1]") - -(define_insn "movlclsymreg" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "local_symbolic_operand" "i")))] - "flag_pic" - "movab %a2[%1],%0") - -(define_insn "movextsymreg" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "external_symbolic_operand" "i")))] - "flag_pic" - "movab %a2[%1],%0") - (define_insn "add3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") @@ -1525,29 +1497,31 @@ (define_insn "casesi1" "" "casel %0,$0,%1") -(define_insn "pushextsym" +(define_insn "*pushsym" [(set (match_operand:SI 0 "push_operand" "=g") - (match_operand:SI 1 "external_symbolic_operand" "i"))] + (match_operand:SI 1 "pic_symbolic_operand" "A"))] "" "pushab %a1") -(define_insn "movextsym" +(define_insn "*movsym" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (match_operand:SI 1 "external_symbolic_operand" "i"))] + (match_operand:SI 1 "pic_symbolic_operand" "A"))] "" "movab %a1,%0") -(define_insn "pushlclsym" +(define_insn "*pushsymreg" [(set (match_operand:SI 0 "push_operand" "=g") - (match_operand:SI 1 "local_symbolic_operand" "i"))] - "" - "pushab %a1") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A")))] + "flag_pic" + "pushab %a2[%1]") -(define_insn "movlclsym" +(define_insn "*movsymreg" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (match_operand:SI 1 "local_symbolic_operand" "i"))] - "" - "movab %a1,%0") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A")))] + "flag_pic" + "movab %a2[%1],%0") ;;- load or push effective address ;; These come after the move and add/sub patterns