From patchwork Tue Jan 7 11:38:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lulu Cheng X-Patchwork-Id: 104225 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 50F5F3858280 for ; Tue, 7 Jan 2025 11:45:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 50F5F3858280 X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id A400F3858D29 for ; Tue, 7 Jan 2025 11:38:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A400F3858D29 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A400F3858D29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736249883; cv=none; b=GE0NGc4jwdsaISzsYB+nVP7UlhqqhUrPFbZvnfsegj6bvhyYz2HEbcVOiNsJe/apfn+laN1KopdUegfYs/gJSPZq6XPtQxNv5vnvLaAYX+vjL9N0dtrq6YABmLYZSUNgtTu0UiBi/zaVGlKHRZGlkU/F1B1NpQaDRfw2naQBsng= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736249883; c=relaxed/simple; bh=kq4Y0J6BGS3rMskv1XkxKM9hZgo0q4zCznOYkBTbteY=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=qEZ2MyFKBCDtYWhtk2/2frH5gVzCVkx/aAF0GZFwEdnT6Qa8aU96Xe4y4kSfMli7INiMviBFeJTbc4BmYVuRyObrj2fHNwenTPs80R5wiBrsJi0S0GFD8uD2kw/G/CpQq3ucMgjDYG/MsEaRSLgdiW9d0nTM7XQMeVpfFc+2krQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A400F3858D29 Received: from loongson.cn (unknown [10.20.4.107]) by gateway (Coremail) with SMTP id _____8BxjawWEn1n4jVfAA--.1765S3; Tue, 07 Jan 2025 19:37:58 +0800 (CST) Received: from loongson-pc.loongson.cn (unknown [10.20.4.107]) by front1 (Coremail) with SMTP id qMiowMCx78cLEn1n7wUYAA--.36870S3; Tue, 07 Jan 2025 19:37:55 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn, chenglulu@loongson.cn Subject: [PATCH 1/2] LoongArch: Implement target attribute. Date: Tue, 7 Jan 2025 19:38:02 +0800 Message-Id: <20250107113803.25633-2-chenglulu@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20250107113803.25633-1-chenglulu@loongson.cn> References: <20250107113803.25633-1-chenglulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: qMiowMCx78cLEn1n7wUYAA--.36870S3 X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj9fXoWftFWDuw1ftry5Cr4xKr1xJFc_yoWrJw1kZo ZIyFWYvw1kGr1Skr48Krn3WryjgrW8Zr45AFZxZ3Z8GF4kAr90k3sxKw1Yv347AFn3Xr4D Aa47Ga9rJ34IqFyDl-sFpf9Il3svdjkaLaAFLSUrUUUUbb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUY17kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUGVWUXwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI 0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUAVWUtwAv7VC2z280 aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aV CY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxU7MmhUUUUU X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org Add function attributes support for LoongArch. Currently, the following items are supported: __attribute__ ((target ("{no-}strict-align"))) __attribute__ ((target ("cmodel="))) __attribute__ ((target ("arch="))) __attribute__ ((target ("tune="))) __attribute__ ((target ("{no-}lsx"))) __attribute__ ((target ("{no-}lasx"))) This implementation is derived from AArch64. gcc/ChangeLog: * attr-urls.def: Regenerate. * config.gcc: Add loongarch-target-attr.o to extra_objs. * config/loongarch/loongarch-protos.h (loongarch_option_valid_attribute_p): Function declaration. (loongarch_option_override_internal): Likewise. * config/loongarch/loongarch.cc (loongarch_option_override_internal): Delete the modifications to target_option_default_node and target_option_current_node. (loongarch_set_current_function): Add annotation information. (loongarch_option_override): add assignment operations to target_option_default_node and target_option_current_node. (TARGET_OPTION_VALID_ATTRIBUTE_P): Define. * config/loongarch/t-loongarch: Add compilation of target file loongarch-target-attr.o. * doc/extend.texi: Add description information of LoongArch Function Attributes. * config/loongarch/loongarch-target-attr.cc: New file. gcc/testsuite/ChangeLog: * gcc.target/loongarch/arch-func-attr-1.c: New test. * gcc.target/loongarch/cmodel-func-attr-1.c: New test. * gcc.target/loongarch/lasx-func-attr-1.c: New test. * gcc.target/loongarch/lasx-func-attr-2.c: New test. * gcc.target/loongarch/lsx-func-attr-1.c: New test. * gcc.target/loongarch/lsx-func-attr-2.c: New test. * gcc.target/loongarch/strict_align-func-attr-1.c: New test. * gcc.target/loongarch/strict_align-func-attr-2.c: New test. * gcc.target/loongarch/vector-func-attr-1.c: New test. * gcc.target/loongarch/attr-check-error-message.c: New test. --- gcc/attr-urls.def | 6 + gcc/config.gcc | 2 +- gcc/config/loongarch/loongarch-protos.h | 2 + gcc/config/loongarch/loongarch-target-attr.cc | 413 ++++++++++++++++++ gcc/config/loongarch/loongarch.cc | 26 +- gcc/config/loongarch/t-loongarch | 6 + gcc/doc/extend.texi | 49 +++ .../gcc.target/loongarch/arch-func-attr-1.c | 16 + .../loongarch/attr-check-error-message.c | 30 ++ .../gcc.target/loongarch/cmodel-func-attr-1.c | 17 + .../gcc.target/loongarch/lasx-func-attr-1.c | 15 + .../gcc.target/loongarch/lasx-func-attr-2.c | 12 + .../gcc.target/loongarch/lsx-func-attr-1.c | 15 + .../gcc.target/loongarch/lsx-func-attr-2.c | 12 + .../loongarch/strict_align-func-attr-1.c | 17 + .../loongarch/strict_align-func-attr-2.c | 17 + .../gcc.target/loongarch/vector-func-attr-1.c | 15 + 17 files changed, 665 insertions(+), 5 deletions(-) create mode 100644 gcc/config/loongarch/loongarch-target-attr.cc create mode 100644 gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-check-error-message.c create mode 100644 gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lasx-func-attr-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lsx-func-attr-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c diff --git a/gcc/attr-urls.def b/gcc/attr-urls.def index e8417cff43c..0d27400d218 100644 --- a/gcc/attr-urls.def +++ b/gcc/attr-urls.def @@ -18,6 +18,7 @@ const attr_url_entry function_attrs[] = { { "amdgpu_hsa_kernel", "gcc/AMD-GCN-Function-Attributes.html#index-amdgpu_005fhsa_005fkernel-function-attribute_002c-AMD-GCN", "AMD GCN", 17}, { "arch=", "gcc/AArch64-Function-Attributes.html#index-arch_003d-function-attribute_002c-AArch64", "AArch64", 5}, { "arch=", "gcc/ARM-Function-Attributes.html#index-arch_003d-function-attribute_002c-ARM", "ARM", 5}, + { "arch=", "gcc/LoongArch-Function-Attributes.html#index-arch_003d-function-attribute_002c-LoongArch", "LoongArch", 5}, { "arch=", "gcc/RISC-V-Function-Attributes.html#index-arch_003d-function-attribute_002c-RISC-V", "RISC-V", 5}, { "artificial", "gcc/Common-Function-Attributes.html#index-artificial-function-attribute", "", 10}, { "assume_aligned", "gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute", "", 14}, @@ -29,6 +30,7 @@ const attr_url_entry function_attrs[] = { { "cdecl", "gcc/x86-Function-Attributes.html#index-cdecl-function-attribute_002c-x86-32", "x86-32", 5}, { "cf_check", "gcc/x86-Function-Attributes.html#index-cf_005fcheck-function-attribute_002c-x86", "x86", 8}, { "cmodel=", "gcc/AArch64-Function-Attributes.html#index-cmodel_003d-function-attribute_002c-AArch64", "AArch64", 7}, + { "cmodel=", "gcc/LoongArch-Function-Attributes.html#index-cmodel_003d-function-attribute_002c-LoongArch", "LoongArch", 7}, { "code_readable", "gcc/MIPS-Function-Attributes.html#index-code_005freadable-function-attribute_002c-MIPS", "MIPS", 13}, { "cold", "gcc/Common-Function-Attributes.html#index-cold-function-attribute", "", 4}, { "const", "gcc/Common-Function-Attributes.html#index-const-function-attribute", "", 5}, @@ -113,6 +115,7 @@ const attr_url_entry function_attrs[] = { { "kspisusp", "gcc/Blackfin-Function-Attributes.html#index-kspisusp-function-attribute_002c-Blackfin", "Blackfin", 8}, { "l1_text", "gcc/Blackfin-Function-Attributes.html#index-l1_005ftext-function-attribute_002c-Blackfin", "Blackfin", 7}, { "l2", "gcc/Blackfin-Function-Attributes.html#index-l2-function-attribute_002c-Blackfin", "Blackfin", 2}, + { "lasx", "gcc/LoongArch-Function-Attributes.html#index-lasx-function-attribute_002c-LoongArch", "LoongArch", 4}, { "leaf", "gcc/Common-Function-Attributes.html#index-leaf-function-attribute", "", 4}, { "long_call", "gcc/ARC-Function-Attributes.html#index-long_005fcall-function-attribute_002c-ARC", "ARC", 9}, { "long_call", "gcc/ARM-Function-Attributes.html#index-long_005fcall-function-attribute_002c-ARM", "ARM", 9}, @@ -121,6 +124,7 @@ const attr_url_entry function_attrs[] = { { "longcall", "gcc/Blackfin-Function-Attributes.html#index-longcall-function-attribute_002c-Blackfin", "Blackfin", 8}, { "longcall", "gcc/PowerPC-Function-Attributes.html#index-longcall-function-attribute_002c-PowerPC", "PowerPC", 8}, { "lower", "gcc/MSP430-Function-Attributes.html#index-lower-function-attribute_002c-MSP430", "MSP430", 5}, + { "lsx", "gcc/LoongArch-Function-Attributes.html#index-lsx-function-attribute_002c-LoongArch", "LoongArch", 3}, { "malloc", "gcc/Common-Function-Attributes.html#index-malloc-function-attribute", "", 6}, { "medium_call", "gcc/ARC-Function-Attributes.html#index-medium_005fcall-function-attribute_002c-ARC", "ARC", 11}, { "micromips", "gcc/MIPS-Function-Attributes.html#index-micromips-function-attribute", "", 9}, @@ -217,6 +221,7 @@ const attr_url_entry function_attrs[] = { { "stack_protect", "gcc/Common-Function-Attributes.html#index-stack_005fprotect-function-attribute", "", 13}, { "stdcall", "gcc/x86-Function-Attributes.html#index-stdcall-function-attribute_002c-x86-32", "x86-32", 7}, { "strict-align", "gcc/AArch64-Function-Attributes.html#index-strict-align-function-attribute_002c-AArch64", "AArch64", 12}, + { "strict-align", "gcc/LoongArch-Function-Attributes.html#index-strict-align-function-attribute_002c-LoongArch", "LoongArch", 12}, { "symver", "gcc/Common-Function-Attributes.html#index-symver-function-attribute", "", 6}, { "syscall_linkage", "gcc/IA-64-Function-Attributes.html#index-syscall_005flinkage-function-attribute_002c-IA-64", "IA-64", 15}, { "sysv_abi", "gcc/x86-Function-Attributes.html#index-sysv_005fabi-function-attribute_002c-x86", "x86", 8}, @@ -232,6 +237,7 @@ const attr_url_entry function_attrs[] = { { "trap_exit", "gcc/SH-Function-Attributes.html#index-trap_005fexit-function-attribute_002c-SH", "SH", 9}, { "trapa_handler", "gcc/SH-Function-Attributes.html#index-trapa_005fhandler-function-attribute_002c-SH", "SH", 13}, { "tune=", "gcc/AArch64-Function-Attributes.html#index-tune_003d-function-attribute_002c-AArch64", "AArch64", 5}, + { "tune=", "gcc/LoongArch-Function-Attributes.html#index-tune_003d-function-attribute_002c-LoongArch", "LoongArch", 5}, { "tune=", "gcc/RISC-V-Function-Attributes.html#index-tune_003d-function-attribute_002c-RISC-V", "RISC-V", 5}, { "unavailable", "gcc/Common-Function-Attributes.html#index-unavailable-function-attribute", "", 11}, { "unused", "gcc/Common-Function-Attributes.html#index-unused-function-attribute", "", 6}, diff --git a/gcc/config.gcc b/gcc/config.gcc index 55e37146ee0..89740e08bbc 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -494,7 +494,7 @@ loongarch*-*-*) cpu_type=loongarch d_target_objs="loongarch-d.o" extra_headers="larchintrin.h lsxintrin.h lasxintrin.h" - extra_objs="loongarch-c.o loongarch-builtins.o loongarch-cpu.o loongarch-opts.o loongarch-def.o loongarch-evolution.o" + extra_objs="loongarch-c.o loongarch-builtins.o loongarch-cpu.o loongarch-opts.o loongarch-def.o loongarch-evolution.o loongarch-target-attr.o" extra_gcc_objs="loongarch-driver.o loongarch-cpu.o loongarch-opts.o loongarch-def.o" extra_options="${extra_options} g.opt fused-madd.opt" ;; diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index fb544ad75ca..531b0bcb636 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -212,4 +212,6 @@ extern void loongarch_emit_swrsqrtsf (rtx, rtx, machine_mode, bool); extern void loongarch_emit_swdivsf (rtx, rtx, rtx, machine_mode); extern bool loongarch_explicit_relocs_p (enum loongarch_symbol_type); extern bool loongarch_symbol_extreme_p (enum loongarch_symbol_type); +extern bool loongarch_option_valid_attribute_p (tree, tree, tree, int); +extern void loongarch_option_override_internal (struct loongarch_target *, struct gcc_options *, struct gcc_options *); #endif /* ! GCC_LOONGARCH_PROTOS_H */ diff --git a/gcc/config/loongarch/loongarch-target-attr.cc b/gcc/config/loongarch/loongarch-target-attr.cc new file mode 100644 index 00000000000..1fafd4c4466 --- /dev/null +++ b/gcc/config/loongarch/loongarch-target-attr.cc @@ -0,0 +1,413 @@ +/* Subroutines used for LoongArch code generation. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by Loongson Ltd. + Based on AArch64 target for GNU compiler. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#define IN_TARGET_CODE 1 + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "target.h" +#include "tree.h" +#include "tm_p.h" +#include "diagnostic.h" +#include "opts.h" + +/* Enum describing the various ways we can handle attributes. + In many cases we can reuse the generic option handling machinery. */ + +enum loongarch_attr_opt_type +{ + loongarch_attr_mask, /* Attribute should set a bit in target_flags. */ + loongarch_attr_enum, /* Attribute sets an enum variable. */ + loongarch_attr_bool /* Attribute sets or unsets a boolean variable. */ +}; + +/* All the information needed to handle a target attribute. + NAME is the name of the attribute. + ATTR_TYPE specifies the type of behavior of the attribute as described + in the definition of enum loongarch_attr_opt_type. + ALLOW_NEG is true if the attribute supports a "no-" form. + OPT_NUM is the enum specifying the option that the attribute modifies. + This is needed for attributes that mirror the behavior of a command-line + option, that is it has ATTR_TYPE loongarch_attr_mask. */ + +struct loongarch_attribute_info +{ + const char *name; + enum loongarch_attr_opt_type attr_type; + bool allow_neg; + enum opt_code opt_num; +}; +/* The target attributes that we support. */ + +static const struct loongarch_attribute_info loongarch_attributes[] = +{ + { "strict-align", loongarch_attr_mask, true, OPT_mstrict_align }, + { "cmodel", loongarch_attr_enum, false, OPT_mcmodel_ }, + { "arch", loongarch_attr_enum, false, OPT_march_ }, + { "tune", loongarch_attr_enum, false, OPT_mtune_ }, + { "lsx", loongarch_attr_bool, true, OPT_mlsx }, + { "lasx", loongarch_attr_bool, true, OPT_mlasx }, + { NULL, loongarch_attr_bool, false, OPT____ } +}; + +bool +loongarch_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + int val = decoded->value; + + switch (code) + { + case OPT_mstrict_align: + if (val) + opts->x_target_flags |= MASK_STRICT_ALIGN; + else + opts->x_target_flags &= ~MASK_STRICT_ALIGN; + return true; + + case OPT_mcmodel_: + opts->x_la_opt_cmodel = val; + return true; + + case OPT_march_: + opts->x_la_opt_cpu_arch = val; + + /* Set these variables to the initial values so that they can be reset + in the loongarch_config_target function according to the ARCH + settings. */ + opts->x_la_opt_simd = M_OPT_UNSET; + opts->x_la_opt_fpu = M_OPT_UNSET; + opts->x_la_isa_evolution = 0; + return true; + + case OPT_mtune_: + opts->x_la_opt_cpu_tune = val; + + /* Set these variables to the initial values so that they can be reset + in the loongarch_target_option_override function according to the TUNE + settings. */ + opts->x_str_align_functions = NULL; + opts->x_str_align_loops = NULL; + opts->x_str_align_jumps = NULL; + return true; + + case OPT_mlsx: + opts->x_la_opt_simd = val ? (la_opt_simd == ISA_EXT_SIMD_LASX + ? ISA_EXT_SIMD_LASX : ISA_EXT_SIMD_LSX) : ISA_EXT_NONE; + return true; + + case OPT_mlasx: + opts->x_la_opt_simd = val ? ISA_EXT_SIMD_LASX + : (la_opt_simd == ISA_EXT_SIMD_LSX || la_opt_simd == ISA_EXT_SIMD_LSX + ? ISA_EXT_SIMD_LSX : ISA_EXT_NONE); + return true; + + default: + return true; + } +} + +/* Parse ARG_STR which contains the definition of one target attribute. + Show appropriate errors if any or return true if the attribute is valid. */ + +static bool +loongarch_process_one_target_attr (char *arg_str, location_t loc) +{ + bool invert = false; + + size_t len = strlen (arg_str); + + if (len == 0) + { + error_at (loc, "malformed % pragma or attribute"); + return false; + } + + char *str_to_check = (char *) alloca (len + 1); + strcpy (str_to_check, arg_str); + + if (len > 3 && startswith (str_to_check, "no-")) + { + invert = true; + str_to_check += 3; + } + char *arg = strchr (str_to_check, '='); + + /* If we found opt=foo then terminate STR_TO_CHECK at the '=' + and point ARG to "foo". */ + if (arg) + { + *arg = '\0'; + arg++; + } + const struct loongarch_attribute_info *p_attr; + bool found = false; + for (p_attr = loongarch_attributes; p_attr->name; p_attr++) + { + /* If the names don't match up, or the user has given an argument + to an attribute that doesn't accept one, or didn't give an argument + to an attribute that expects one, fail to match. */ + if (strcmp (str_to_check, p_attr->name) != 0) + continue; + + found = true; + + /* If the name matches but the attribute does not allow "no-" versions + then we can't match. */ + if (invert && !p_attr->allow_neg) + { + error_at (loc, "pragma or attribute % does not " + "allow a negated form", str_to_check); + return false; + } + + switch (p_attr->attr_type) + { + /* Either set or unset a boolean option. */ + case loongarch_attr_mask: + { + struct cl_decoded_option decoded; + + /* We only need to specify the option number. + loongarch_handle_option will know which mask to apply. */ + decoded.opt_index = p_attr->opt_num; + decoded.value = !invert; + + loongarch_handle_option (&global_options, &global_options_set, + &decoded, input_location); + break; + } + + /* Use the option setting machinery to set an option to an enum. */ + case loongarch_attr_enum: + { + gcc_assert (arg); + bool valid; + int value; + struct cl_decoded_option decoded; + valid = opt_enum_arg_to_value (p_attr->opt_num, arg, + &value, CL_TARGET); + + decoded.opt_index = p_attr->opt_num; + decoded.value = value; + + if (valid) + loongarch_handle_option (&global_options, + &global_options_set, + &decoded, input_location); + else + error_at (loc, "pragma or attribute % is " + "not valid", str_to_check, arg); + break; + } + + /* Either set or unset a boolean option. */ + case loongarch_attr_bool: + { + struct cl_decoded_option decoded; + + generate_option (p_attr->opt_num, NULL, !invert, + CL_TARGET, &decoded); + loongarch_handle_option (&global_options, &global_options_set, + &decoded, input_location); + break; + } + default: + gcc_unreachable (); + } + } + + /* If we reached here we either have found an attribute and validated + it or didn't match any. If we matched an attribute but its arguments + were malformed we will have returned false already. */ + if (!found) + error_at (loc, "attribute % argument %qs is unknown", + str_to_check); + + return found; +} + +/* Count how many times the character C appears in + NULL-terminated string STR. */ + +static unsigned int +num_occurences_in_str (char c, char *str) +{ + unsigned int res = 0; + while (*str != '\0') + { + if (*str == c) + res++; + + str++; + } + + return res; +} + +/* Parse the tree in ARGS that contains the target attribute information + and update the global target options space. */ + +bool +loongarch_process_target_attr (tree args, tree fndecl) +{ + location_t loc + = fndecl == NULL ? UNKNOWN_LOCATION : DECL_SOURCE_LOCATION (fndecl); + + if (TREE_CODE (args) == TREE_LIST) + { + do + { + tree head = TREE_VALUE (args); + if (head) + { + if (!loongarch_process_target_attr (head, fndecl)) + return false; + } + args = TREE_CHAIN (args); + } while (args); + + return true; + } + + if (TREE_CODE (args) != STRING_CST) + { + error_at (loc, "attribute % argument not a string"); + return false; + } + + size_t len = strlen (TREE_STRING_POINTER (args)); + auto_vec buffer; + buffer.safe_grow (len + 1); + char *str_to_check = buffer.address (); + memcpy (str_to_check, TREE_STRING_POINTER (args), len + 1); + + if (len == 0) + { + error_at (loc, "malformed % pragma or attribute"); + return false; + } + + /* Used to catch empty spaces between commas i.e. + attribute ((target ("attr1,,attr2"))). */ + unsigned int num_commas = num_occurences_in_str (',', str_to_check); + + /* Handle multiple target attributes separated by ','. */ + char *token = strtok_r (str_to_check, ",", &str_to_check); + + unsigned int num_attrs = 0; + while (token) + { + num_attrs++; + if (!loongarch_process_one_target_attr (token, loc)) + return false; + + token = strtok_r (NULL, ",", &str_to_check); + } + + if (num_attrs != num_commas + 1) + { + error_at (loc, "malformed % pragma or attribute", + TREE_STRING_POINTER (args)); + return false; + } + + return true; +} + +/* Implement TARGET_OPTION_VALID_ATTRIBUTE_P. This is used to + process attribute ((target ("..."))). */ + +bool +loongarch_option_valid_attribute_p (tree fndecl, tree, tree args, int) +{ + struct cl_target_option cur_target; + bool ret; + tree old_optimize; + tree new_target, new_optimize; + tree existing_target = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + + tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); + + old_optimize + = build_optimization_node (&global_options, &global_options_set); + + /* If the function changed the optimization levels as well as setting + target options, start with the optimizations specified. */ + if (func_optimize && func_optimize != old_optimize) + cl_optimization_restore (&global_options, &global_options_set, + TREE_OPTIMIZATION (func_optimize)); + + /* Save the current target options to restore at the end. */ + cl_target_option_save (&cur_target, &global_options, &global_options_set); + + /* If fndecl already has some target attributes applied to it, unpack + them so that we add this attribute on top of them, rather than + overwriting them. */ + if (existing_target) + { + struct cl_target_option *existing_options + = TREE_TARGET_OPTION (existing_target); + + if (existing_options) + cl_target_option_restore (&global_options, &global_options_set, + existing_options); + } + else + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (target_option_current_node)); + + ret = loongarch_process_target_attr (args, fndecl); + + /* Set up any additional state. */ + if (ret) + { + loongarch_option_override_internal (&la_target, + &global_options, + &global_options_set); + new_target = build_target_option_node (&global_options, + &global_options_set); + } + else + new_target = NULL; + + new_optimize = build_optimization_node (&global_options, + &global_options_set); + + if (fndecl && ret) + { + DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target; + + if (old_optimize != new_optimize) + DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; + } + + cl_target_option_restore (&global_options, &global_options_set, &cur_target); + + if (old_optimize != new_optimize) + cl_optimization_restore (&global_options, &global_options_set, + TREE_OPTIMIZATION (old_optimize)); + return ret; +} diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index d5e90bfd1e1..f3514073cea 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -7644,7 +7644,7 @@ loongarch_reg_init (void) = loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode); } -static void +void loongarch_option_override_internal (struct loongarch_target *target, struct gcc_options *opts, struct gcc_options *opts_set) @@ -7670,9 +7670,6 @@ loongarch_option_override_internal (struct loongarch_target *target, /* Override some options according to the resolved target. */ loongarch_target_option_override (target, opts, opts_set); - target_option_default_node = target_option_current_node - = build_target_option_node (opts, opts_set); - loongarch_reg_init (); } @@ -7711,10 +7708,15 @@ loongarch_set_current_function (tree fndecl) else old_tree = target_option_default_node; + /* When the function is optimized, the pop_cfun will be called, and + the fndecl will be NULL. */ if (fndecl == NULL_TREE) { if (old_tree != target_option_current_node) { + /* When this function is set with special options, we need to + restore the original global optimization options at the end + of function optimization. */ loongarch_previous_fndecl = NULL_TREE; cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION @@ -7724,6 +7726,9 @@ loongarch_set_current_function (tree fndecl) } tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + + /* When no separate compilation parameters are set for the function, + new_tree is NULL. */ if (new_tree == NULL_TREE) new_tree = target_option_default_node; @@ -7732,9 +7737,14 @@ loongarch_set_current_function (tree fndecl) if (new_tree == old_tree) return; + /* According to the settings of the functions attribute and pragma, + the options is corrected. */ cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (new_tree)); + /* After correcting the value of options, we need to update the + rules for using the hardware registers to ensure that the + rules correspond to the options. */ loongarch_reg_init (); loongarch_save_restore_target_globals (new_tree); @@ -7755,6 +7765,11 @@ loongarch_option_override (void) &global_options, &global_options_set); + /* Save the initial options so that we can restore the initial option + settings later when processing attributes and pragmas. */ + target_option_default_node = target_option_current_node + = build_target_option_node (&global_options, &global_options_set); + } /* Implement TARGET_OPTION_SAVE. */ @@ -11324,6 +11339,9 @@ loongarch_asm_code_end (void) #undef TARGET_C_MODE_FOR_FLOATING_TYPE #define TARGET_C_MODE_FOR_FLOATING_TYPE loongarch_c_mode_for_floating_type +#undef TARGET_OPTION_VALID_ATTRIBUTE_P +#define TARGET_OPTION_VALID_ATTRIBUTE_P loongarch_option_valid_attribute_p + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-loongarch.h" diff --git a/gcc/config/loongarch/t-loongarch b/gcc/config/loongarch/t-loongarch index 8f2f57f27ba..b7dbb4befc5 100644 --- a/gcc/config/loongarch/t-loongarch +++ b/gcc/config/loongarch/t-loongarch @@ -47,6 +47,12 @@ loongarch-c.o: $(srcdir)/config/loongarch/loongarch-c.cc $(CONFIG_H) $(SYSTEM_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/loongarch/loongarch-c.cc +loongarch-target-attr.o: $(srcdir)/config/loongarch/loongarch-target-attr.cc \ + $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) $(TREE_H) $(TM_H) \ + $(DIAGNOSTIC_CORE_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/loongarch/loongarch-target-attr.cc + loongarch-builtins.o: $(srcdir)/config/loongarch/loongarch-builtins.cc $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(RECOG_H) langhooks.h \ $(DIAGNOSTIC_CORE_H) $(OPTABS_H) $(srcdir)/config/loongarch/loongarch-ftypes.def \ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 1e1b4cc837d..d896677fd3a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2642,6 +2642,7 @@ GCC plugins may provide their own attributes. * Epiphany Function Attributes:: * H8/300 Function Attributes:: * IA-64 Function Attributes:: +* LoongArch Function Attributes:: * M32C Function Attributes:: * M32R/D Function Attributes:: * m68k Function Attributes:: @@ -5642,6 +5643,54 @@ extern int foo () __attribute__((version_id ("20040821"))); Calls to @code{foo} are mapped to calls to @code{foo@{20040821@}}. @end table +@node LoongArch Function Attributes +@subsection LoongArch Function Attributes + +These function attributes are supported by the LoongArch end: + +@table @code +@cindex @code{strict-align} function attribute, LoongArch +@item strict-align +@itemx no-strict-align +@code{strict-align} indicates that the compiler should not assume that unaligned +memory references are handled by the system. To allow the compiler to assume +that aligned memory references are handled by the system, the inverse attribute +@code{no-strict-align} can be specified. The behavior is same as for the +command-line option @option{-mstrict-align} and @option{-mno-strict-align}. + +@cindex @code{cmodel=} function attribute, LoongArch +@item cmodel= +Indicates that code should be generated for a particular code model for +this function. The behavior and permissible arguments are the same as +for the command-line option @option{-mcmodel=}. + +@cindex @code{arch=} function attribute, LoongArch +@item arch= +Specifies the architecture version and architectural extensions to use +for this function. The behavior and permissible arguments are the same as +for the @option{-march=} command-line option. + +@cindex @code{tune=} function attribute, LoongArch +@item tune= +Specifies the core for which to tune the performance of this function. +The behavior and permissible arguments are the same as for the @option{-mtune=} +command-line option. + +@cindex @code{lsx} function attribute, LoongArch +@item lsx +@itemx no-lsx +@code{lsx} indicates that vector instruction generation is allowed (not allowed) +when compiling the function. The behavior is same as for the command-line option +@option{-mlsx} and @option{-mno-lsx}. + +@cindex @code{lasx} function attribute, LoongArch +@item lasx +@itemx no-lasx +@code{lasx} indicates that lasx instruction generation is allowed (not allowed) +when compiling the function. The behavior is same as for the command-line option +@option{-mlasx} and @option{-mno-lasx}. +@end table + @node M32C Function Attributes @subsection M32C Function Attributes diff --git a/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c new file mode 100644 index 00000000000..98cc7e577e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mno-lsx" } */ + +extern char a[64]; +extern char b[64]; + +__attribute__ ((target ("arch=la64v1.1"))) +void +test (void) +{ + for (int i = 0; i < 64; i++) + a[i] = b[i]; +} + + +/* { dg-final { scan-assembler "vld" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/attr-check-error-message.c b/gcc/testsuite/gcc.target/loongarch/attr-check-error-message.c new file mode 100644 index 00000000000..82dcd172555 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/attr-check-error-message.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wno-attributes" } */ + +__attribute__ ((target ("mno-lsx"))) void +test1 (void) /* { dg-error "attribute \\\'target\\\' argument \\\'mno-lsx\\\' is unknown" } */ +{} + +__attribute__ ((target (""))) void +test2 (void) /* { dg-error "malformed \\\'target\\\(\\\)\\\' pragma or attribute" } */ +{} + +__attribute__ ((target ("no-cmodel="))) void +test3 (void) /* { dg-error "pragma or attribute \\\'target\\\(\\\"cmodel\\\"\\\)\\\' does not allow a negated form" } */ +{} + +__attribute__ ((target ("cmodel=test"))) void +test4 (void) /* { dg-error "pragma or attribute \\\'target\\\(\\\"cmodel=test\\\"\\\)\\\' is not valid" } */ +{} + +__attribute__ ((target ("test"))) void +test5 (void) /* { dg-error "attribute \\\'target\\\' argument \\\'test\\\' is unknown" } */ +{} + +__attribute__ ((target (lsx))) void /* { dg-error "\\\'lsx\\\' undeclared here" } */ +test6 (void) /* { dg-error "attribute \\\'target\\\' argument not a string" } */ +{} + +__attribute__ ((target ("lsx,"))) void +test7 (void) /* { dg-error "malformed \\\'target\\\(\\\"lsx,\\\"\\\)\\\' pragma or attribute" } */ +{} diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c new file mode 100644 index 00000000000..119cd0e1646 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs=none" } */ + +extern char a[8]; +extern char b[8]; + +__attribute__ ((target ("cmodel=extreme"))) +void +test (void) +{ + a[0] = b[1]; + a[1] = b[2]; + a[2] = b[3]; + a[3] = b[4]; +} + +/* { dg-final { scan-assembler "la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,a" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c new file mode 100644 index 00000000000..5dad9821f03 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +typedef int v8i32 __attribute__ ((vector_size(32), aligned(32))); +extern v8i32 a, b, c; + +__attribute__ ((target ("lasx"))) +void +test (void) +{ + a = b + c; +} + + +/* { dg-final { scan-assembler "xvadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-2.c b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-2.c new file mode 100644 index 00000000000..33cc924d0e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ + +typedef int v8i32 __attribute__ ((vector_size(32), aligned(32))); +extern v8i32 a, b, c; + +__attribute__ ((target ("no-lasx"))) +void +test (void) +{ + a = __builtin_lasx_xvadd_w (b, c); /* { dg-error "built-in function '__builtin_lasx_xvadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c new file mode 100644 index 00000000000..3e2c1dc3359 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +__attribute__ ((target ("lsx"))) +void +test (void) +{ + a = b + c; +} + + +/* { dg-final { scan-assembler "vadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-2.c b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-2.c new file mode 100644 index 00000000000..97475fff579 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +__attribute__ ((target ("no-lsx"))) +void +test (void) +{ + a = __builtin_lsx_vadd_w (b, c); /* { dg-error "built-in function '__builtin_lsx_vadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c new file mode 100644 index 00000000000..04893746de8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mstrict-align" } */ +extern char a[8]; +extern char b[8]; + +__attribute__ ((target ("no-strict-align"))) +void +test (void) +{ + a[0] = b[1]; + a[1] = b[2]; + a[2] = b[3]; + a[3] = b[4]; +} + + +/* { dg-final { scan-assembler-not "ld.bu" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c new file mode 100644 index 00000000000..0e81486cd53 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-strict-align" } */ +extern char a[8]; +extern char b[8]; + +__attribute__ ((target ("strict-align"))) +void +test (void) +{ + a[0] = b[1]; + a[1] = b[2]; + a[2] = b[3]; + a[3] = b[4]; +} + + +/* { dg-final { scan-assembler-not "ld.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c new file mode 100644 index 00000000000..655ca234be0 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +__attribute__ ((target ("no-lasx"))) +void +test (void) +{ + a = b + c; +} + + +/* { dg-final { scan-assembler "vadd.w" } } */ From patchwork Tue Jan 7 11:38:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lulu Cheng X-Patchwork-Id: 104224 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9B3FD385841E for ; Tue, 7 Jan 2025 11:41:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B3FD385841E X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 126F33858423 for ; Tue, 7 Jan 2025 11:38:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 126F33858423 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 126F33858423 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736249888; cv=none; b=N6Qn9l6QcXkYfvdGH2fK6wNUVnJVLdwvVKUsraHQkJD1afCcLsVqKeQZ/Ot0fhUf+7AySUkXm5ppDI8b58AE7rGxeVZI2As74Lr/5OcAAKippv3ZFefHvdVWsnCZz+lEBlaJm+R3eOfux1g7oZC8GoEiw0bUSuVfLr88hQm4DIM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736249888; c=relaxed/simple; bh=0qBcZgytwprBtv/wQ9cjTaQ5oC/3fztQB2IOGwFFIzg=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=mBHIdMXOeUMA3c2ZodRR2iV8awnzf5WsFTtzuG37y2f6rmro8kSZGZbdh1zL7HnUxD6Fvjotgyvg1whUB1gOufVLuhEqwCaYYz2LMAyMxXqxueIN9cTvTZ4JMjvAJYvBqqkp6njj7QBKzLE52Wu3kaqSj2ljxywAoVFDqji1Q6M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 126F33858423 Received: from loongson.cn (unknown [10.20.4.107]) by gateway (Coremail) with SMTP id _____8Bx364ZEn1n5TVfAA--.16273S3; Tue, 07 Jan 2025 19:38:01 +0800 (CST) Received: from loongson-pc.loongson.cn (unknown [10.20.4.107]) by front1 (Coremail) with SMTP id qMiowMCx78cLEn1n7wUYAA--.36870S4; Tue, 07 Jan 2025 19:38:00 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn, chenglulu@loongson.cn Subject: [PATCH 2/2] LoongArch: Implement target pragma. Date: Tue, 7 Jan 2025 19:38:03 +0800 Message-Id: <20250107113803.25633-3-chenglulu@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20250107113803.25633-1-chenglulu@loongson.cn> References: <20250107113803.25633-1-chenglulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: qMiowMCx78cLEn1n7wUYAA--.36870S4 X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj9fXoWfuF47CFy5CF4UtF1DCFy8Zwc_yoW8Zw1xGo Z8AFWUXw1xGr1Skr4DKrn3Xr92q34jkw45Za9I9wn8Ca1kAw15A343Kw1avrW7Xrn7XrW5 ua47CayDXF92y34Dl-sFpf9Il3svdjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYI7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUGVWUXwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI 0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUAVWUtwAv7VC2z280 aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMxCIbckI1I0E14v26r1Y6r17MI8I3I0E 5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAV WUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY 1x0267AKxVWUJVW8JwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI 0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxU csjjDUUUU X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org The target pragmas defined correspond to the target function attributes. This implementation is derived from AArch64. gcc/ChangeLog: * config/loongarch/loongarch-protos.h (loongarch_reset_previous_fndecl): Add function declaration. (loongarch_save_restore_target_globals): Likewise. (loongarch_register_pragmas): Likewise. * config/loongarch/loongarch-target-attr.cc (loongarch_option_valid_attribute_p): Optimize the processing of attributes. (loongarch_pragma_target_parse): New functions. (loongarch_register_pragmas): Likewise. * config/loongarch/loongarch.cc (loongarch_reset_previous_fndecl): New functions. (loongarch_set_current_function): When the old_tree is the same as the new_tree, the rules for using registers, etc., are set according to the option values to ensure that the pragma can be processed correctly. * config/loongarch/loongarch.h (REGISTER_TARGET_PRAGMAS): Define macro. * doc/extend.texi: Supplemental Documentation. gcc/testsuite/ChangeLog: * gcc.target/loongarch/arch-func-attr-1.c: Add '#pragma'. * gcc.target/loongarch/cmodel-func-attr-1.c: Likewise. * gcc.target/loongarch/lasx-func-attr-1.c: Likewise. * gcc.target/loongarch/lsx-func-attr-1.c: Likewise. * gcc.target/loongarch/strict_align-func-attr-1.c: Likewise. * gcc.target/loongarch/strict_align-func-attr-2.c: Likewise. * gcc.target/loongarch/vector-func-attr-1.c: Likewise. * gcc.target/loongarch/arch-pragma-attr-1.c: Likewise. * gcc.target/loongarch/cmodel-pragma-attr-1.c: New test. * gcc.target/loongarch/lasx-pragma-attr-1.c: New test. * gcc.target/loongarch/lasx-pragma-attr-2.c: New test. * gcc.target/loongarch/lsx-pragma-attr-1.c: New test. * gcc.target/loongarch/lsx-pragma-attr-2.c: New test. * gcc.target/loongarch/strict_align-pragma-attr-1.c: New test. * gcc.target/loongarch/strict_align-pragma-attr-2.c: New test. * gcc.target/loongarch/vector-pragma-attr-1.c: New test. * gcc.target/loongarch/pragma-push-pop.c: New test. --- gcc/config/loongarch/loongarch-protos.h | 3 + gcc/config/loongarch/loongarch-target-attr.cc | 59 +++++++++++++++++++ gcc/config/loongarch/loongarch.cc | 19 +++--- gcc/config/loongarch/loongarch.h | 2 + gcc/doc/extend.texi | 13 ++++ .../gcc.target/loongarch/arch-func-attr-1.c | 6 +- .../gcc.target/loongarch/arch-pragma-attr-1.c | 7 +++ .../gcc.target/loongarch/cmodel-func-attr-1.c | 4 ++ .../loongarch/cmodel-pragma-attr-1.c | 7 +++ .../gcc.target/loongarch/lasx-func-attr-1.c | 4 ++ .../gcc.target/loongarch/lasx-pragma-attr-1.c | 7 +++ .../gcc.target/loongarch/lasx-pragma-attr-2.c | 12 ++++ .../gcc.target/loongarch/lsx-func-attr-1.c | 4 ++ .../gcc.target/loongarch/lsx-pragma-attr-1.c | 7 +++ .../gcc.target/loongarch/lsx-pragma-attr-2.c | 12 ++++ .../gcc.target/loongarch/pragma-push-pop.c | 22 +++++++ .../loongarch/strict_align-func-attr-1.c | 4 ++ .../loongarch/strict_align-func-attr-2.c | 4 ++ .../loongarch/strict_align-pragma-attr-1.c | 7 +++ .../loongarch/strict_align-pragma-attr-2.c | 7 +++ .../gcc.target/loongarch/vector-func-attr-1.c | 4 ++ .../loongarch/vector-pragma-attr-1.c | 7 +++ 22 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c create mode 100644 gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index 531b0bcb636..967f1633ae6 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -214,4 +214,7 @@ extern bool loongarch_explicit_relocs_p (enum loongarch_symbol_type); extern bool loongarch_symbol_extreme_p (enum loongarch_symbol_type); extern bool loongarch_option_valid_attribute_p (tree, tree, tree, int); extern void loongarch_option_override_internal (struct loongarch_target *, struct gcc_options *, struct gcc_options *); +extern void loongarch_reset_previous_fndecl (void); +extern void loongarch_save_restore_target_globals (tree new_tree); +extern void loongarch_register_pragmas (void); #endif /* ! GCC_LOONGARCH_PROTOS_H */ diff --git a/gcc/config/loongarch/loongarch-target-attr.cc b/gcc/config/loongarch/loongarch-target-attr.cc index 1fafd4c4466..61d5c85c680 100644 --- a/gcc/config/loongarch/loongarch-target-attr.cc +++ b/gcc/config/loongarch/loongarch-target-attr.cc @@ -349,6 +349,16 @@ loongarch_option_valid_attribute_p (tree fndecl, tree, tree args, int) tree new_target, new_optimize; tree existing_target = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + /* If what we're processing is the current pragma string then the + target option node is already stored in target_option_current_node + by loongarch_pragma_target_parse in loongarch-target-attr.cc. + Use that to avoid having to re-parse the string. */ + if (!existing_target && args == current_target_pragma) + { + DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = target_option_current_node; + return true; + } + tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); old_optimize @@ -411,3 +421,52 @@ loongarch_option_valid_attribute_p (tree fndecl, tree, tree args, int) TREE_OPTIMIZATION (old_optimize)); return ret; } + +/* Hook to validate the current #pragma GCC target and set the state, and + update the macros based on what was changed. If ARGS is NULL, then + POP_TARGET is used to reset the options. */ + +static bool +loongarch_pragma_target_parse (tree args, tree pop_target) +{ + /* If args is not NULL then process it and setup the target-specific + information that it specifies. */ + if (args) + { + if (!loongarch_process_target_attr (args, NULL)) + return false; + + loongarch_option_override_internal (&la_target, + &global_options, + &global_options_set); + } + + /* args is NULL, restore to the state described in pop_target. */ + else + { + pop_target = pop_target ? pop_target : target_option_default_node; + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (pop_target)); + } + + target_option_current_node + = build_target_option_node (&global_options, &global_options_set); + + loongarch_reset_previous_fndecl (); + + /* If we're popping or reseting make sure to update the globals so that + the optab availability predicates get recomputed. */ + if (pop_target) + loongarch_save_restore_target_globals (pop_target); + + return true; +} + +/* Implement REGISTER_TARGET_PRAGMAS. */ + +void +loongarch_register_pragmas (void) +{ + /* Update pragma hook to allow parsing #pragma GCC target. */ + targetm.target_option.pragma_parse = loongarch_pragma_target_parse; +} diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index f3514073cea..5b73e2a9f85 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -7677,11 +7677,17 @@ loongarch_option_override_internal (struct loongarch_target *target, static GTY(()) tree loongarch_previous_fndecl; +void +loongarch_reset_previous_fndecl (void) +{ + loongarch_previous_fndecl = NULL; +} + /* Restore or save the TREE_TARGET_GLOBALS from or to new_tree. Used by loongarch_set_current_function to make sure optab availability predicates are recomputed when necessary. */ -static void +void loongarch_save_restore_target_globals (tree new_tree) { if (TREE_TARGET_GLOBALS (new_tree)) @@ -7734,13 +7740,12 @@ loongarch_set_current_function (tree fndecl) loongarch_previous_fndecl = fndecl; - if (new_tree == old_tree) - return; + if (new_tree != old_tree) + /* According to the settings of the functions attribute and pragma, + the options is corrected. */ + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); - /* According to the settings of the functions attribute and pragma, - the options is corrected. */ - cl_target_option_restore (&global_options, &global_options_set, - TREE_TARGET_OPTION (new_tree)); /* After correcting the value of options, we need to update the rules for using the hardware registers to ensure that the diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index 4ee01618de1..42a38a44efe 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see #define SWITCHABLE_TARGET 1 +#define REGISTER_TARGET_PRAGMAS() loongarch_register_pragmas () + #define TARGET_SUPPORTS_WIDE_INT 1 /* Macros to silence warnings about numbers being signed in traditional diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d896677fd3a..d72fa0764f6 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -28413,6 +28413,7 @@ option is specified. @xref{OpenMP}, and @ref{OpenACC}. @menu * AArch64 Pragmas:: * ARM Pragmas:: +* LoongArch Pragmas:: * M32C Pragmas:: * PRU Pragmas:: * RS/6000 and PowerPC Pragmas:: @@ -28465,6 +28466,18 @@ Do not affect the @code{long_call} or @code{short_call} attributes of subsequent functions. @end table +@node LoongArch Pragmas +@subsection LoongArch Pragmas + +The list of attributes supported by Pragma is the same as that of target +function attributres. @xref{LoongArch Function Attributes}. + +Example: + +@smallexample +#pragma GCC target("strict-align") +@end smallexample + @node M32C Pragmas @subsection M32C Pragmas diff --git a/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c index 98cc7e577e3..b8e51e6d9e1 100644 --- a/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c +++ b/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c @@ -1,10 +1,14 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -march=loongarch64 -mno-lsx" } */ +/* { dg-options "-O2 -march=loongarch64 -mno-lsx -std=gnu11" } */ extern char a[64]; extern char b[64]; +#ifndef TEST_TARGET_PRAGMA __attribute__ ((target ("arch=la64v1.1"))) +#else +#pragma GCC target ("arch=la64v1.1") +#endif void test (void) { diff --git a/gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c new file mode 100644 index 00000000000..bd918e70926 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mno-lsx -std=gnu11" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./arch-func-attr-1.c" + +/* { dg-final { scan-assembler "vld" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c index 119cd0e1646..9f44dc66bfd 100644 --- a/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c +++ b/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c @@ -4,7 +4,11 @@ extern char a[8]; extern char b[8]; +#ifndef TEST_TARGET_PRAGMA __attribute__ ((target ("cmodel=extreme"))) +#else +#pragma GCC target ("cmodel=extreme") +#endif void test (void) { diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c new file mode 100644 index 00000000000..b522891487c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs=none" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./cmodel-func-attr-1.c" + +/* { dg-final { scan-assembler "la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,a" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c index 5dad9821f03..720719e80b8 100644 --- a/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c +++ b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c @@ -4,7 +4,11 @@ typedef int v8i32 __attribute__ ((vector_size(32), aligned(32))); extern v8i32 a, b, c; +#ifndef TEST_TARGET_PRAGMA __attribute__ ((target ("lasx"))) +#else +#pragma GCC target ("lasx") +#endif void test (void) { diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c new file mode 100644 index 00000000000..d5bc68f1cb8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./lasx-func-attr-1.c" + +/* { dg-final { scan-assembler "xvadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c new file mode 100644 index 00000000000..67e4f7179fa --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ + +typedef int v8i32 __attribute__ ((vector_size(32), aligned(32))); +extern v8i32 a, b, c; + +#pragma GCC target ("no-lasx") +void +test (void) +{ + a = __builtin_lasx_xvadd_w (b, c); /* { dg-error "built-in function '__builtin_lasx_xvadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c index 3e2c1dc3359..3558898d353 100644 --- a/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c +++ b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c @@ -4,7 +4,11 @@ typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); extern v4i32 a, b, c; +#ifndef TEST_TARGET_PRAGMA __attribute__ ((target ("lsx"))) +#else +#pragma GCC target ("lsx") +#endif void test (void) { diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c new file mode 100644 index 00000000000..c499f18fc42 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./lsx-func-attr-1.c" + +/* { dg-final { scan-assembler "vadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c new file mode 100644 index 00000000000..40314d026eb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +#pragma GCC target ("no-lsx") +void +test (void) +{ + a = __builtin_lsx_vadd_w (b, c); /* { dg-error "built-in function '__builtin_lsx_vadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c b/gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c new file mode 100644 index 00000000000..a2bcdcb10d5 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ +/* { dg-final { scan-assembler-not "xvadd\\\.w" } } */ +/* { dg-final { scan-assembler "xvsll\\\.w" } } */ + +#include + +extern v8i32 a, b, c; +#pragma GCC push_options +#pragma GCC target ("no-lasx") +void +test (void) +{ + a = b + c; +} +#pragma GCC pop_options + +void +test1 (void) +{ + c = __builtin_lasx_xvsll_w (a, b); +} diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c index 04893746de8..c1ed6515ccf 100644 --- a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c +++ b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c @@ -3,7 +3,11 @@ extern char a[8]; extern char b[8]; +#ifndef TEST_TARGET_PRAGMA __attribute__ ((target ("no-strict-align"))) +#else +#pragma GCC target ("no-strict-align") +#endif void test (void) { diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c index 0e81486cd53..70bf810037e 100644 --- a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c +++ b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c @@ -3,7 +3,11 @@ extern char a[8]; extern char b[8]; +#ifndef TEST_TARGET_PRAGMA __attribute__ ((target ("strict-align"))) +#else +#pragma GCC target ("strict-align") +#endif void test (void) { diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c new file mode 100644 index 00000000000..a95d0b97282 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mstrict-align" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./strict_align-func-attr-1.c" + +/* { dg-final { scan-assembler-not "ld.bu" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c new file mode 100644 index 00000000000..93b76c59b6c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-strict-align" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./strict_align-func-attr-2.c" + +/* { dg-final { scan-assembler-not "ld.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c index 655ca234be0..4e00606b1c6 100644 --- a/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c +++ b/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c @@ -4,7 +4,11 @@ typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); extern v4i32 a, b, c; +#ifndef TEST_TARGET_PRAGMA __attribute__ ((target ("no-lasx"))) +#else +#pragma GCC target ("no-lasx") +#endif void test (void) { diff --git a/gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c new file mode 100644 index 00000000000..7bbb1690113 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./vector-func-attr-1.c" + +/* { dg-final { scan-assembler "vadd.w" } } */