From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 3134A3856DDC for ; Thu, 19 Oct 2023 14:03:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3134A3856DDC Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3134A3856DDC Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697724226; cv=none; b=Nh6QikdEpHUL1J8ZfGVDojA9WFy1ngMYwtriDQbPY3Jg7VMzp3RDgTp4BeOPOHOfAfR22yDWQbV9ThZEq8UtrLmtSm9bObm9z6HojO56bLI/eaIJS372iGUbJW9rSDjfvYXpobxCwxxmsTk2OQowD8ffuCPHkTZuFtn/USNZgR0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697724226; c=relaxed/simple; bh=4NspqbLXU8iJlUTtrO6EfWDweZ8Mhv8uqKAunmci0jc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=ur9rn6ea+s0ghvcYbxs4RJYmmRNDZIxjfv+3Kbf6205sBFUYpbkY0w69jcZUsWAT0XqNMDSo27QxSTGcS9gJGF6m0caGMrZeTeJ9AJwgBd3BlCr/U8J7mHjr4DVRuoWwlYJ47fyp3jxEzGEsfPgdIe5vZYEHUEl7jV0qq/La0GU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1697724222; bh=4NspqbLXU8iJlUTtrO6EfWDweZ8Mhv8uqKAunmci0jc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cSRq5HBVmC5tDFdUgMfcwPHbDXB6yedi/ZaE3cWrXhT0c5kOJBQGJfR1kCT2xvMCe 6RqQU9fl47+4mDTSIlAvDAH7HXui25pJF/g/2ZzRxTyXSflfISCvjgjBA2PFOO+pug BTRp5tdawAVKHclq9JV2wv33zgVoPRuBt3XK7mhw= Received: from stargazer.. (unknown [IPv6:240e:358:1126:f000:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id A241366AF5; Thu, 19 Oct 2023 10:03:38 -0400 (EDT) From: Xi Ruoyao To: gcc-patches@gcc.gnu.org Cc: chenglulu , i@xen0n.name, xuchenghua@loongson.cn, mengqinggang , Xi Ruoyao Subject: [PATCH 4/5] LoongArch: Use explicit relocs for addresses only used for one load or store with -mexplicit-relocs=auto and -mcmodel={normal,medium} Date: Thu, 19 Oct 2023 22:02:59 +0800 Message-ID: <20231019140300.50323-5-xry111@xry111.site> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231019140300.50323-1-xry111@xry111.site> References: <20231019140300.50323-1-xry111@xry111.site> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,KAM_STOCKGEN,LIKELY_SPAM_FROM,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: In these cases, if we use explicit relocs, we end up with 2 instructions: pcalau12i t0, %pc_hi20(x) ld.d t0, t0, %pc_lo12(x) If we use la.local pseudo-op, in the best scenario (x is in +/- 2MiB range) we still have 2 instructions: pcaddi t0, %pcrel_20(x) ld.d t0, t0, 0 If x is out of the range we'll have 3 instructions. So for these cases just emit machine instructions with explicit relocs. gcc/ChangeLog: * config/loongarch/predicates.md (symbolic_pcrel_operand): New predicate. * config/loongarch/loongarch.md (define_peephole2): Optimize la.local + ld/st to pcalau12i + ld/st if the address is only used once if -mexplicit-relocs=auto and -mcmodel=normal or medium. gcc/testsuite/ChangeLog: * gcc.target/loongarch/explicit-relocs-auto-single-load-store.c: New test. * gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c: New test. --- gcc/config/loongarch/loongarch.md | 122 ++++++++++++++++++ gcc/config/loongarch/predicates.md | 7 + ...-relocs-auto-single-load-store-no-anchor.c | 6 + .../explicit-relocs-auto-single-load-store.c | 14 ++ 4 files changed, 149 insertions(+) create mode 100644 gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c create mode 100644 gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 695c8eb9a6f..13473472171 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -65,6 +65,7 @@ (define_c_enum "unspec" [ UNSPEC_LOAD_FROM_GOT UNSPEC_PCALAU12I + UNSPEC_PCALAU12I_GR UNSPEC_ORI_L_LO12 UNSPEC_LUI_L_HI20 UNSPEC_LUI_H_LO20 @@ -2297,6 +2298,16 @@ (define_insn "@pcalau12i" "pcalau12i\t%0,%%pc_hi20(%1)" [(set_attr "type" "move")]) +;; @pcalau12i may be used for sibcall so it has a strict constraint. This +;; allows any general register as the operand. +(define_insn "@pcalau12i_gr" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "symbolic_operand" "")] + UNSPEC_PCALAU12I_GR))] + "" + "pcalau12i\t%0,%%pc_hi20(%1)" + [(set_attr "type" "move")]) + (define_insn "@ori_l_lo12" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(match_operand:P 1 "register_operand" "r") @@ -3748,6 +3759,117 @@ (define_insn "loongarch_crcc_w__w" [(set_attr "type" "unknown") (set_attr "mode" "")]) +;; With normal or medium code models, if the only use of a pc-relative +;; address is for loading or storing a value, then relying on linker +;; relaxation is not better than emitting the machine instruction directly. +;; Even if the la.local pseudo op can be relaxed, we get: +;; +;; pcaddi $t0, %pcrel_20(x) +;; ld.d $t0, $t0, 0 +;; +;; There are still two instructions, same as using the machine instructions +;; and explicit relocs: +;; +;; pcalau12i $t0, %pc_hi20(x) +;; ld.d $t0, $t0, %pc_lo12(x) +;; +;; And if the pseudo op cannot be relaxed, we'll get a worse result (with +;; 3 instructions). +(define_peephole2 + [(set (match_operand:P 0 "register_operand") + (match_operand:P 1 "symbolic_pcrel_operand")) + (set (match_operand:GPR 2 "register_operand") + (mem:GPR (match_dup 0)))] + "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \ + && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \ + && (peep2_reg_dead_p (2, operands[0]) \ + || REGNO (operands[0]) == REGNO (operands[2]))" + [(set (match_dup 2) (mem:GPR (lo_sum:P (match_dup 0) (match_dup 1))))] + { + emit_insn (gen_pcalau12i_gr (operands[0], operands[1])); + }) + +(define_peephole2 + [(set (match_operand:P 0 "register_operand") + (match_operand:P 1 "symbolic_pcrel_operand")) + (set (match_operand:GPR 2 "register_operand") + (mem:GPR (plus (match_dup 0) + (match_operand 3 "const_int_operand"))))] + "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \ + && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \ + && (peep2_reg_dead_p (2, operands[0]) \ + || REGNO (operands[0]) == REGNO (operands[2]))" + [(set (match_dup 2) (mem:GPR (lo_sum:P (match_dup 0) (match_dup 1))))] + { + operands[1] = plus_constant (Pmode, operands[1], INTVAL (operands[3])); + emit_insn (gen_pcalau12i_gr (operands[0], operands[1])); + }) + +(define_peephole2 + [(set (match_operand:P 0 "register_operand") + (match_operand:P 1 "symbolic_pcrel_operand")) + (set (match_operand:GPR 2 "register_operand") + (any_extend:GPR (mem:SUBDI (match_dup 0))))] + "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \ + && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \ + && (peep2_reg_dead_p (2, operands[0]) \ + || REGNO (operands[0]) == REGNO (operands[2]))" + [(set (match_dup 2) + (any_extend:GPR (mem:SUBDI (lo_sum:P (match_dup 0) + (match_dup 1)))))] + { + emit_insn (gen_pcalau12i_gr (operands[0], operands[1])); + }) + +(define_peephole2 + [(set (match_operand:P 0 "register_operand") + (match_operand:P 1 "symbolic_pcrel_operand")) + (set (match_operand:GPR 2 "register_operand") + (any_extend:GPR + (mem:SUBDI (plus (match_dup 0) + (match_operand 3 "const_int_operand")))))] + "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \ + && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \ + && (peep2_reg_dead_p (2, operands[0]) \ + || REGNO (operands[0]) == REGNO (operands[2]))" + [(set (match_dup 2) + (any_extend:GPR (mem:SUBDI (lo_sum:P (match_dup 0) + (match_dup 1)))))] + { + operands[1] = plus_constant (Pmode, operands[1], INTVAL (operands[3])); + emit_insn (gen_pcalau12i_gr (operands[0], operands[1])); + }) + +(define_peephole2 + [(set (match_operand:P 0 "register_operand") + (match_operand:P 1 "symbolic_pcrel_operand")) + (set (mem:QHWD (match_dup 0)) + (match_operand:QHWD 2 "register_operand"))] + "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \ + && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \ + && (peep2_reg_dead_p (2, operands[0])) \ + && REGNO (operands[0]) != REGNO (operands[2])" + [(set (mem:QHWD (lo_sum:P (match_dup 0) (match_dup 1))) (match_dup 2))] + { + emit_insn (gen_pcalau12i_gr (operands[0], operands[1])); + }) + +(define_peephole2 + [(set (match_operand:P 0 "register_operand") + (match_operand:P 1 "symbolic_pcrel_operand")) + (set (mem:QHWD (plus (match_dup 0) + (match_operand 3 "const_int_operand"))) + (match_operand:QHWD 2 "register_operand"))] + "la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO \ + && (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM) \ + && (peep2_reg_dead_p (2, operands[0])) \ + && REGNO (operands[0]) != REGNO (operands[2])" + [(set (mem:QHWD (lo_sum:P (match_dup 0) (match_dup 1))) (match_dup 2))] + { + operands[1] = plus_constant (Pmode, operands[1], INTVAL (operands[3])); + emit_insn (gen_pcalau12i_gr (operands[0], operands[1])); + }) + ;; Synchronization instructions. (include "sync.md") diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md index 359878f5bcf..946ed0d8212 100644 --- a/gcc/config/loongarch/predicates.md +++ b/gcc/config/loongarch/predicates.md @@ -563,6 +563,13 @@ (define_predicate "symbolic_operand" return loongarch_symbolic_constant_p (op, &type); }) +(define_predicate "symbolic_pcrel_operand" + (match_code "const,symbol_ref,label_ref") +{ + enum loongarch_symbol_type type; + return loongarch_symbolic_constant_p (op, &type) && type == SYMBOL_PCREL; +}) + (define_predicate "equality_operator" (match_code "eq,ne")) diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c new file mode 100644 index 00000000000..fb03403d756 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store-no-anchor.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mexplicit-relocs=auto -fno-section-anchors" } */ + +#include "explicit-relocs-auto-single-load-store.c" + +/* { dg-final { scan-assembler-not "la.local" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c new file mode 100644 index 00000000000..0d53644cda7 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-single-load-store.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mexplicit-relocs=auto" } */ + +long a; +int b; +unsigned int c; + +long load_a() { return a; } +long load_b() { return b; } +long load_c() { return c; } +void store_a(long x) { a = x; } +void store_b(int x) { b = x; } + +/* { dg-final { scan-assembler-not "la.local" } } */ -- 2.42.0