From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sender-0.a4lg.com (mail-sender.a4lg.com [153.120.152.154]) by sourceware.org (Postfix) with ESMTPS id 11A373856964 for ; Fri, 22 Sep 2023 07:11:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 11A373856964 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=irq.a4lg.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=irq.a4lg.com Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id 7F6B4300089; Fri, 22 Sep 2023 07:11:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=irq.a4lg.com; s=2017s01; t=1695366703; bh=eN8uIb/S4Va7lu+kuYZUGAypfPw/n+RoZny7rQD3Bno=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Mime-Version:Content-Transfer-Encoding; b=GPd73oGRo2y38pxlFay68R/ci+r8cJGeb6MI1hO0hRGMtgHuZgRSfzC9YSL6PtdTl B6UZ7XJnpaCUerEtwc7gLvLx3VZ6dg6b7CaqwBUu5SqMvlRkuiOamJC8Oo3KPc7o9N xx5Fzo2xOBIyXSLNWjuZ5uHuvp7mTEaZYphg06jg= From: Tsukasa OI To: Tsukasa OI , Kito Cheng , Palmer Dabbelt , Andrew Waterman , Jim Wilson , Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 1/2] RISC-V: Define not broken prefetch builtins Date: Fri, 22 Sep 2023 07:11:16 +0000 Message-ID: <47f74393e89e5faefb19ba3f5ef5a0054e4fad71.1695366672.git.research_trasio@irq.a4lg.com> In-Reply-To: References: Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,GIT_PATCH_0,KAM_MANYTO,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 List-Id: From: Tsukasa OI __builtin_riscv_zicbop_cbo_prefetchi (corresponding "prefetch.i" instruction from the 'Zicbop' extension) is completely broken and new builtin is required for replacement. However, it required more than defining new builtin and/or instruction. 1. Support for variable argument function prototype for RISC-V builtins (corresponding "..." on C-based languages) 2. Support for (non-vector) RISC-V builtins with custom expansion (on RVV intrinsics, custom expansion is already implemented) Along with other minor changes, not broken "prefetch.i" intrinsic is defined as follows: void __builtin_riscv_prefetch_i (void *addr, ...); Optional second argument (defaults to zero and must be a compile-time constant integer) is the offset from given address (-2048 <= x < 2048 and must be a multiple of 32, due to "prefetch.i" constraints). Third or later arguments are ignored (like other builtin functions). This commit also defines builtin functions for "prefetch.r" and "prefetch.w" instructions for consistency: void __builtin_riscv_prefetch_r (void *addr, ...); void __builtin_riscv_prefetch_w (void *addr, ...); Those instructions can be emitted using __builtin_prefetch but has no control of the offset field. gcc/ChangeLog: * config/riscv/riscv-builtins.cc: Rename availabilities "prefetchi{32,64}" to "prefetch{32,64}". (RISCV_FTYPE_NAME_VAR1): Similar to RISCV_FTYPE_NAME1 but for variable argument function prototype. (DEF_RISCV_FTYPE_VAR): Similar to DEF_RISCV_FTYPE but calls RISCV_FTYPE_NAME_VAR* instead. (enum riscv_builtin_type): Add RISCV_BUILTIN_CUSTOM for builtin with custom expansion. (struct riscv_builtin_description): Add custom expansion function. (RISCV_BUILTIN): Modified to set "expand_function". (RISCV_CUSTOM_BUILTIN): New. Similar to RISCV_BUILTIN but only for builtins with custom expansion function. (riscv_expand_builtin): Handle RISCV_BUILTIN_CUSTOM builtin. (expand_builtin_prefetch_riscv): New custom expansion function for "prefetch.[irw]" instructions from the 'Zicbop' extension. * config/riscv/riscv-cmo.def (__builtin_riscv_zicbop_cbo_prefetchi): Remove since it's broken. (__builtin_riscv_prefetch_i): New. (__builtin_riscv_prefetch_r): New. (__builtin_riscv_prefetch_w): New. * config/riscv/riscv-ftypes.def: Add variable argument prototype for "void func(void*, ...)". * config/riscv/riscv.md (unspecv): Remove UNSPECV_PREI and add UNSPECV_PREFETCH_[IRW]. (riscv_prefetchi_): Remove. (riscv_prefetch_i_): New. (riscv_prefetch_r_): New. (riscv_prefetch_w_): New. gcc/testsuite/ChangeLog: * gcc.target/riscv/cmo-zicbop-1.c: Refine to test new builtins. * gcc.target/riscv/cmo-zicbop-2.c: Ditto. * gcc.target/riscv/cmo-zicbop-3.c: New NULL prefetching test. * gcc.target/riscv/cmo-zicbop-4.c: New failure test. * gcc.target/riscv/cmo-zicbop-5.c: Ditto. * gcc.target/riscv/cmo-zicbop-6.c: Ditto. * gcc.target/riscv/cmo-zicbop-by-common-1.c: New test for __builtin_prefetch and the 'Zicbop' extension. * gcc.target/riscv/cmo-zicbop-by-common-2.c: Ditto. * gcc.target/riscv/cmo-zicbop-by-common-3.c: Ditto. --- gcc/config/riscv/riscv-builtins.cc | 112 +++++++++++++++++- gcc/config/riscv/riscv-cmo.def | 8 +- gcc/config/riscv/riscv-ftypes.def | 1 + gcc/config/riscv/riscv.md | 30 ++++- gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c | 41 ++++--- gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c | 33 ++---- gcc/testsuite/gcc.target/riscv/cmo-zicbop-3.c | 29 +++++ gcc/testsuite/gcc.target/riscv/cmo-zicbop-4.c | 14 +++ gcc/testsuite/gcc.target/riscv/cmo-zicbop-5.c | 14 +++ gcc/testsuite/gcc.target/riscv/cmo-zicbop-6.c | 38 ++++++ .../gcc.target/riscv/cmo-zicbop-by-common-1.c | 17 +++ .../gcc.target/riscv/cmo-zicbop-by-common-2.c | 7 ++ .../gcc.target/riscv/cmo-zicbop-by-common-3.c | 13 ++ 13 files changed, 305 insertions(+), 52 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-3.c diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc index 3fe3a89dcc25..4f422e0891c2 100644 --- a/gcc/config/riscv/riscv-builtins.cc +++ b/gcc/config/riscv/riscv-builtins.cc @@ -47,12 +47,16 @@ along with GCC; see the file COPYING3. If not see #define RISCV_FTYPE_NAME1(A, B) RISCV_##A##_FTYPE_##B #define RISCV_FTYPE_NAME2(A, B, C) RISCV_##A##_FTYPE_##B##_##C #define RISCV_FTYPE_NAME3(A, B, C, D) RISCV_##A##_FTYPE_##B##_##C##_##D +/* Similar, but for variable argument function prototype. */ +#define RISCV_FTYPE_NAME_VAR1(A, B) RISCV_##A##_FTYPE_##B##_VAR /* Classifies the prototype of a built-in function. */ enum riscv_function_type { #define DEF_RISCV_FTYPE(NARGS, LIST) RISCV_FTYPE_NAME##NARGS LIST, +#define DEF_RISCV_FTYPE_VAR(NARGS, LIST) RISCV_FTYPE_NAME_VAR##NARGS LIST, #include "config/riscv/riscv-ftypes.def" #undef DEF_RISCV_FTYPE +#undef DEF_RISCV_FTYPE_VAR RISCV_MAX_FTYPE_MAX }; @@ -62,7 +66,10 @@ enum riscv_builtin_type { RISCV_BUILTIN_DIRECT, /* Likewise, but with return type VOID. */ - RISCV_BUILTIN_DIRECT_NO_TARGET + RISCV_BUILTIN_DIRECT_NO_TARGET, + + /* The function which requires custom expansion. */ + RISCV_BUILTIN_CUSTOM, }; /* Declare an availability predicate for built-in functions. */ @@ -90,6 +97,9 @@ struct riscv_builtin_description { /* Whether the function is available. */ unsigned int (*avail) (void); + + /* Custom expansion function if builtin_type is RISCV_BUILTIN_CUSTOM. */ + rtx (*expand_function) (enum insn_code icode, rtx target, tree exp); }; AVAIL (hard_float, TARGET_HARD_FLOAT || TARGET_ZFINX) @@ -101,8 +111,8 @@ AVAIL (inval32, TARGET_ZICBOM && !TARGET_64BIT) AVAIL (inval64, TARGET_ZICBOM && TARGET_64BIT) AVAIL (zero32, TARGET_ZICBOZ && !TARGET_64BIT) AVAIL (zero64, TARGET_ZICBOZ && TARGET_64BIT) -AVAIL (prefetchi32, TARGET_ZICBOP && !TARGET_64BIT) -AVAIL (prefetchi64, TARGET_ZICBOP && TARGET_64BIT) +AVAIL (prefetch32, TARGET_ZICBOP && !TARGET_64BIT) +AVAIL (prefetch64, TARGET_ZICBOP && TARGET_64BIT) AVAIL (crypto_zbkb32, TARGET_ZBKB && !TARGET_64BIT) AVAIL (crypto_zbkb64, TARGET_ZBKB && TARGET_64BIT) AVAIL (crypto_zbkx32, TARGET_ZBKX && !TARGET_64BIT) @@ -123,7 +133,7 @@ AVAIL (clmulr_zbc32, TARGET_ZBC && !TARGET_64BIT) AVAIL (clmulr_zbc64, TARGET_ZBC && TARGET_64BIT) AVAIL (hint_pause, (!0)) -/* Construct a riscv_builtin_description from the given arguments. +/* Construct a simple riscv_builtin_description from the given arguments. INSN is the name of the associated instruction pattern, without the leading CODE_FOR_riscv_. @@ -137,7 +147,7 @@ AVAIL (hint_pause, (!0)) riscv_builtin_avail_. */ #define RISCV_BUILTIN(INSN, NAME, BUILTIN_TYPE, FUNCTION_TYPE, AVAIL) \ { CODE_FOR_riscv_ ## INSN, "__builtin_riscv_" NAME, \ - BUILTIN_TYPE, FUNCTION_TYPE, riscv_builtin_avail_ ## AVAIL } + BUILTIN_TYPE, FUNCTION_TYPE, riscv_builtin_avail_ ## AVAIL, NULL } /* Define __builtin_riscv_, which is a RISCV_BUILTIN_DIRECT function mapped to instruction CODE_FOR_riscv_, FUNCTION_TYPE and AVAIL @@ -152,6 +162,25 @@ AVAIL (hint_pause, (!0)) RISCV_BUILTIN (INSN, #INSN, RISCV_BUILTIN_DIRECT_NO_TARGET, \ FUNCTION_TYPE, AVAIL) +/* Construct a custom riscv_builtin_description from the given arguments. + + INSN is the name of the associated instruction pattern, without the + leading CODE_FOR_riscv_. + + NAME is the name of the function itself, without the leading + "__builtin_riscv_". + + FTYPE is the prototype field in riscv_builtin_description. + + AVAIL is the name of the availability predicate, without the leading + riscv_builtin_avail_. + + EXPANDER is the function to expand the builtin. */ +#define RISCV_CUSTOM_BUILTIN(INSN, NAME, FTYPE, AVAIL, EXPANDER) \ + { CODE_FOR_riscv_ ## INSN, "__builtin_riscv_" NAME, \ + RISCV_BUILTIN_CUSTOM, FTYPE, \ + riscv_builtin_avail_ ## AVAIL, EXPANDER } + /* Argument types. */ #define RISCV_ATYPE_VOID void_type_node #define RISCV_ATYPE_UQI unsigned_intQI_type_node @@ -171,6 +200,8 @@ AVAIL (hint_pause, (!0)) #define RISCV_FTYPE_ATYPES3(A, B, C, D) \ RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C, RISCV_ATYPE_##D +static rtx expand_builtin_prefetch_riscv (enum insn_code icode, rtx target, tree exp); + static const struct riscv_builtin_description riscv_builtins[] = { #include "riscv-cmo.def" #include "riscv-scalar-crypto.def" @@ -209,8 +240,15 @@ riscv_build_function_type (enum riscv_function_type type) = build_function_type_list (RISCV_FTYPE_ATYPES##NUM ARGS, \ NULL_TREE); \ break; +#define DEF_RISCV_FTYPE_VAR(NUM, ARGS) \ + case RISCV_FTYPE_NAME_VAR##NUM ARGS: \ + types[(int) type] \ + = build_varargs_function_type_list (RISCV_FTYPE_ATYPES##NUM ARGS, \ + NULL_TREE); \ + break; #include "config/riscv/riscv-ftypes.def" #undef DEF_RISCV_FTYPE +#undef DEF_RISCV_FTYPE_VAR default: gcc_unreachable (); } @@ -387,6 +425,9 @@ riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, case RISCV_BUILTIN_DIRECT_NO_TARGET: return riscv_expand_builtin_direct (d->icode, target, exp, false); + + case RISCV_BUILTIN_CUSTOM: + return d->expand_function (d->icode, target, exp); } } } @@ -394,6 +435,67 @@ riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, gcc_unreachable (); } +static rtx +expand_builtin_prefetch_riscv (enum insn_code icode, + rtx target ATTRIBUTE_UNUSED, + tree exp) +{ + struct expand_operand ops[2]; + tree arg0, arg1; + rtx op1; + + char name_suffix = 'i'; + switch (icode) + { + case CODE_FOR_riscv_prefetch_i_si: + case CODE_FOR_riscv_prefetch_i_di: + break; + case CODE_FOR_riscv_prefetch_r_si: + case CODE_FOR_riscv_prefetch_r_di: + name_suffix = 'r'; + break; + case CODE_FOR_riscv_prefetch_w_si: + case CODE_FOR_riscv_prefetch_w_di: + name_suffix = 'w'; + break; + default: + gcc_unreachable (); + } + + /* Argument 0 is an address. */ + arg0 = CALL_EXPR_ARG (exp, 0); + + /* Argument 1 (offset) is an optional compile-time constant and defaults + to zero. It must be a valid offset for a S-type instruction AND must be + a multiple of 32. */ + if (call_expr_nargs (exp) > 1) + arg1 = CALL_EXPR_ARG (exp, 1); + else + arg1 = integer_zero_node; + if (TREE_CODE (arg1) != INTEGER_CST) + { + error ("second argument to %<__builtin_riscv_prefetch_%c%> must be a" + " constant", name_suffix); + arg1 = integer_zero_node; + } + op1 = expand_normal (arg1); + if (INTVAL (op1) < -IMM_REACH / 2 + || INTVAL (op1) >= IMM_REACH / 2 + || INTVAL (op1) % 32 != 0) + { + error ("second argument to %<__builtin_riscv_prefetch_%c%> must be a" + " valid offset for the prefetch instruction", name_suffix); + arg1 = integer_zero_node; + op1 = expand_normal (arg1); + } + + create_input_operand (&ops[0], expand_normal (arg0), + TYPE_MODE (TREE_TYPE (arg0))); + create_input_operand (&ops[1], op1, + TYPE_MODE (TREE_TYPE (arg1))); + return riscv_expand_builtin_insn (icode, 2, ops, false); +} + /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */ void diff --git a/gcc/config/riscv/riscv-cmo.def b/gcc/config/riscv/riscv-cmo.def index ff713b78e19e..3be77710095e 100644 --- a/gcc/config/riscv/riscv-cmo.def +++ b/gcc/config/riscv/riscv-cmo.def @@ -13,8 +13,12 @@ RISCV_BUILTIN (zero_si, "zicboz_cbo_zero", RISCV_BUILTIN_DIRECT_NO_TARGET, RISCV RISCV_BUILTIN (zero_di, "zicboz_cbo_zero", RISCV_BUILTIN_DIRECT_NO_TARGET, RISCV_VOID_FTYPE_VOID_PTR, zero64), // zicbop -RISCV_BUILTIN (prefetchi_si, "zicbop_cbo_prefetchi", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI, prefetchi32), -RISCV_BUILTIN (prefetchi_di, "zicbop_cbo_prefetchi", RISCV_BUILTIN_DIRECT, RISCV_UDI_FTYPE_UDI, prefetchi64), +RISCV_CUSTOM_BUILTIN (prefetch_i_si, "prefetch_i", RISCV_VOID_FTYPE_VOID_PTR_VAR, prefetch32, expand_builtin_prefetch_riscv), +RISCV_CUSTOM_BUILTIN (prefetch_i_di, "prefetch_i", RISCV_VOID_FTYPE_VOID_PTR_VAR, prefetch64, expand_builtin_prefetch_riscv), +RISCV_CUSTOM_BUILTIN (prefetch_r_si, "prefetch_r", RISCV_VOID_FTYPE_VOID_PTR_VAR, prefetch32, expand_builtin_prefetch_riscv), +RISCV_CUSTOM_BUILTIN (prefetch_r_di, "prefetch_r", RISCV_VOID_FTYPE_VOID_PTR_VAR, prefetch64, expand_builtin_prefetch_riscv), +RISCV_CUSTOM_BUILTIN (prefetch_w_si, "prefetch_w", RISCV_VOID_FTYPE_VOID_PTR_VAR, prefetch32, expand_builtin_prefetch_riscv), +RISCV_CUSTOM_BUILTIN (prefetch_w_di, "prefetch_w", RISCV_VOID_FTYPE_VOID_PTR_VAR, prefetch64, expand_builtin_prefetch_riscv), // zbkc or zbc RISCV_BUILTIN (clmul_si, "clmul", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI, clmul_zbkc32_or_zbc32), diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def index 33620c57ca06..052acf0159d3 100644 --- a/gcc/config/riscv/riscv-ftypes.def +++ b/gcc/config/riscv/riscv-ftypes.def @@ -41,3 +41,4 @@ DEF_RISCV_FTYPE (2, (UDI, USI, USI)) DEF_RISCV_FTYPE (2, (UDI, UDI, USI)) DEF_RISCV_FTYPE (2, (UDI, UDI, UDI)) DEF_RISCV_FTYPE (3, (USI, USI, USI, USI)) +DEF_RISCV_FTYPE_VAR (1, (VOID, VOID_PTR)) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index e00b8ee3579d..eaa8b6a9f085 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -118,7 +118,9 @@ UNSPECV_FLUSH UNSPECV_INVAL UNSPECV_ZERO - UNSPECV_PREI + UNSPECV_PREFETCH_I + UNSPECV_PREFETCH_R + UNSPECV_PREFETCH_W ;; Zihintpause unspec UNSPECV_PAUSE @@ -3464,12 +3466,28 @@ } [(set_attr "type" "cbo")]) -(define_insn "riscv_prefetchi_" - [(unspec_volatile:X [(match_operand:X 0 "address_operand" "r") - (match_operand:X 1 "imm5_operand" "i")] - UNSPECV_PREI)] +(define_insn "riscv_prefetch_i_" + [(unspec_volatile:X [(match_operand:X 0 "register_operand" "r") + (match_operand:X 1 "const_int_operand" "n")] + UNSPECV_PREFETCH_I)] "TARGET_ZICBOP" - "prefetch.i\t%a0" + "prefetch.i\t%1(%0)" + [(set_attr "type" "cbo")]) + +(define_insn "riscv_prefetch_r_" + [(unspec_volatile:X [(match_operand:X 0 "register_operand" "r") + (match_operand:X 1 "const_int_operand" "n")] + UNSPECV_PREFETCH_R)] + "TARGET_ZICBOP" + "prefetch.r\t%1(%0)" + [(set_attr "type" "cbo")]) + +(define_insn "riscv_prefetch_w_" + [(unspec_volatile:X [(match_operand:X 0 "register_operand" "r") + (match_operand:X 1 "const_int_operand" "n")] + UNSPECV_PREFETCH_W)] + "TARGET_ZICBOP" + "prefetch.w\t%1(%0)" [(set_attr "type" "cbo")]) (define_expand "extv" diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c index c5d78c1763d3..f275d4633cce 100644 --- a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c @@ -1,23 +1,28 @@ -/* { dg-do compile target { { rv64-*-*}}} */ -/* { dg-options "-march=rv64gc_zicbop -mabi=lp64" } */ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicbop -mabi=ilp32" } */ void foo (char *p) { - __builtin_prefetch (p, 0, 0); - __builtin_prefetch (p, 0, 1); - __builtin_prefetch (p, 0, 2); - __builtin_prefetch (p, 0, 3); - __builtin_prefetch (p, 1, 0); - __builtin_prefetch (p, 1, 1); - __builtin_prefetch (p, 1, 2); - __builtin_prefetch (p, 1, 3); + __builtin_riscv_prefetch_i (p); + __builtin_riscv_prefetch_i (p, 0); + __builtin_riscv_prefetch_i (p, 32); + __builtin_riscv_prefetch_i (p, -64); + __builtin_riscv_prefetch_r (p); + __builtin_riscv_prefetch_r (p, 0); + __builtin_riscv_prefetch_r (p, 32); + __builtin_riscv_prefetch_r (p, -64); + __builtin_riscv_prefetch_w (p); + __builtin_riscv_prefetch_w (p, 0); + __builtin_riscv_prefetch_w (p, 32); + __builtin_riscv_prefetch_w (p, -64); } -int foo1() -{ - return __builtin_riscv_zicbop_cbo_prefetchi(1); -} - -/* { dg-final { scan-assembler-times "prefetch.i" 1 } } */ -/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */ -/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t-64\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t-64\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t-64\\(" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c index 6576365b39ca..17fff9e199da 100644 --- a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c @@ -1,23 +1,14 @@ -/* { dg-do compile target { { rv32-*-*}}} */ -/* { dg-options "-march=rv32gc_zicbop -mabi=ilp32" } */ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_zicbop -mabi=lp64" } */ -void foo (char *p) -{ - __builtin_prefetch (p, 0, 0); - __builtin_prefetch (p, 0, 1); - __builtin_prefetch (p, 0, 2); - __builtin_prefetch (p, 0, 3); - __builtin_prefetch (p, 1, 0); - __builtin_prefetch (p, 1, 1); - __builtin_prefetch (p, 1, 2); - __builtin_prefetch (p, 1, 3); -} +#include "cmo-zicbop-1.c" -int foo1() -{ - return __builtin_riscv_zicbop_cbo_prefetchi(1); -} - -/* { dg-final { scan-assembler-times "prefetch.i" 1 } } */ -/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */ -/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t-64\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t-64\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t-64\\(" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-3.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-3.c new file mode 100644 index 000000000000..89bf6c57a390 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-3.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicbop -mabi=ilp32" } */ + +void foo (void) +{ + /* Use NULL (0) instead of a pointer. */ + __builtin_riscv_prefetch_i (0); + __builtin_riscv_prefetch_i (0, 0); + __builtin_riscv_prefetch_i (0, 32); + __builtin_riscv_prefetch_i (0, -64); + __builtin_riscv_prefetch_r (0); + __builtin_riscv_prefetch_r (0, 0); + __builtin_riscv_prefetch_r (0, 32); + __builtin_riscv_prefetch_r (0, -64); + __builtin_riscv_prefetch_w (0); + __builtin_riscv_prefetch_w (0, 0); + __builtin_riscv_prefetch_w (0, 32); + __builtin_riscv_prefetch_w (0, -64); +} + +/* { dg-final { scan-assembler-times "prefetch\\.i\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.i\t-64\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.r\t-64\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t0\\(" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t32\\(" 1 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w\t-64\\(" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-4.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-4.c new file mode 100644 index 000000000000..372fdfa3d868 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-4.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicbop -mabi=ilp32" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +int foo (char* p, int offset) +{ + __builtin_riscv_prefetch_i(); + __builtin_riscv_prefetch_r(); + __builtin_riscv_prefetch_w(); +} + +/* { dg-error "too few arguments to function '__builtin_riscv_prefetch_i'" "" { target *-*-* } 7 } */ +/* { dg-error "too few arguments to function '__builtin_riscv_prefetch_r'" "" { target *-*-* } 8 } */ +/* { dg-error "too few arguments to function '__builtin_riscv_prefetch_w'" "" { target *-*-* } 9 } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-5.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-5.c new file mode 100644 index 000000000000..7dbfe49b24fd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-5.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicbop -mabi=ilp32" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +int foo (char* p, int offset) +{ + __builtin_riscv_prefetch_i(p, offset); + __builtin_riscv_prefetch_r(p, offset); + __builtin_riscv_prefetch_w(p, offset); +} + +/* { dg-error "second argument to '__builtin_riscv_prefetch_i' must be a constant" "not compile-time constant" { target *-*-* } 7 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_r' must be a constant" "not compile-time constant" { target *-*-* } 8 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_w' must be a constant" "not compile-time constant" { target *-*-* } 9 } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-6.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-6.c new file mode 100644 index 000000000000..b8deb2d6c807 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-6.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicbop -mabi=ilp32" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +int foo (char* p) +{ + __builtin_riscv_prefetch_i(p, 1); + __builtin_riscv_prefetch_r(p, 1); + __builtin_riscv_prefetch_w(p, 1); + __builtin_riscv_prefetch_i(p, 16); + __builtin_riscv_prefetch_r(p, 16); + __builtin_riscv_prefetch_w(p, 16); + __builtin_riscv_prefetch_i(p, -2080); + __builtin_riscv_prefetch_r(p, -2080); + __builtin_riscv_prefetch_w(p, -2080); + __builtin_riscv_prefetch_i(p, +2048); + __builtin_riscv_prefetch_r(p, +2048); + __builtin_riscv_prefetch_w(p, +2048); + __builtin_riscv_prefetch_i(p, 0x800000000000000llu); + __builtin_riscv_prefetch_r(p, 0x800000000000000llu); + __builtin_riscv_prefetch_w(p, 0x800000000000000llu); +} + +/* { dg-error "second argument to '__builtin_riscv_prefetch_i' must be a valid offset for the prefetch instruction" "unaligned offset 1" { target *-*-* } 7 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_r' must be a valid offset for the prefetch instruction" "unaligned offset 1" { target *-*-* } 8 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_w' must be a valid offset for the prefetch instruction" "unaligned offset 1" { target *-*-* } 9 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_i' must be a valid offset for the prefetch instruction" "unaligned offset 2" { target *-*-* } 10 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_r' must be a valid offset for the prefetch instruction" "unaligned offset 2" { target *-*-* } 11 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_w' must be a valid offset for the prefetch instruction" "unaligned offset 2" { target *-*-* } 12 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_i' must be a valid offset for the prefetch instruction" "out of range (negative)" { target *-*-* } 13 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_r' must be a valid offset for the prefetch instruction" "out of range (negative)" { target *-*-* } 14 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_w' must be a valid offset for the prefetch instruction" "out of range (negative)" { target *-*-* } 15 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_i' must be a valid offset for the prefetch instruction" "out of range (positive 1)" { target *-*-* } 16 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_r' must be a valid offset for the prefetch instruction" "out of range (positive 1)" { target *-*-* } 17 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_w' must be a valid offset for the prefetch instruction" "out of range (positive 1)" { target *-*-* } 18 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_i' must be a valid offset for the prefetch instruction" "out of range (positive 2)" { target *-*-* } 19 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_r' must be a valid offset for the prefetch instruction" "out of range (positive 2)" { target *-*-* } 20 } */ +/* { dg-error "second argument to '__builtin_riscv_prefetch_w' must be a valid offset for the prefetch instruction" "out of range (positive 2)" { target *-*-* } 21 } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-1.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-1.c new file mode 100644 index 000000000000..14b89b8ddf35 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicbop -mabi=ilp32" } */ + +void foo (char *p) +{ + __builtin_prefetch (p, 0, 0); + __builtin_prefetch (p, 0, 1); + __builtin_prefetch (p, 0, 2); + __builtin_prefetch (p, 0, 3); + __builtin_prefetch (p, 1, 0); + __builtin_prefetch (p, 1, 1); + __builtin_prefetch (p, 1, 2); + __builtin_prefetch (p, 1, 3); +} + +/* { dg-final { scan-assembler-times "prefetch\\.r" 4 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-2.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-2.c new file mode 100644 index 000000000000..2fa38dccfcb0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_zicbop -mabi=lp64" } */ + +#include "cmo-zicbop-by-common-1.c" + +/* { dg-final { scan-assembler-times "prefetch\\.r" 4 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-3.c b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-3.c new file mode 100644 index 000000000000..37505d3d13c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-by-common-3.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zicbop -mabi=ilp32" } */ + +void foo (char *p) +{ + /* Second argument defaults to zero (read). */ + __builtin_prefetch (p); + __builtin_prefetch (p, 0); + __builtin_prefetch (p, 1); +} + +/* { dg-final { scan-assembler-times "prefetch\\.r" 2 } } */ +/* { dg-final { scan-assembler-times "prefetch\\.w" 1 } } */ -- 2.42.0