From patchwork Wed Jul 3 02:20:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2" X-Patchwork-Id: 1955793 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=eW9etoY9; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WDNmn085kz1xqh for ; Wed, 3 Jul 2024 12:20:55 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 44A1D388264A for ; Wed, 3 Jul 2024 02:20:53 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) by sourceware.org (Postfix) with ESMTPS id 79817386103B for ; Wed, 3 Jul 2024 02:20:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 79817386103B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 79817386103B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719973229; cv=none; b=pHnTtdgA0Na8/8icDrntq+1qsFKd/wdHOQgXmUyDgB+xOESCk577la6sJHTaRKm6SAplgKOBFpTU+ffzNxsqLfpTn9xoMl0faoggqHvKVpnoL47Y3JIH7xyCkMe/JtdOb2tuOZH0k7LPCbDo8BcC+e/K9/56/z179bQSKdwSMfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719973229; c=relaxed/simple; bh=9vCmgknkvnCBaiX5V41A6Fp/6iH3tHunR4w2Cl/G6LA=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=rUECYuqmC2fozwFs8nUp6qABHnUyjAo55Oi8MMOEnwz0G4HBZd+4FPfs30ouu3pYLAD2H5f1FkBZKzaQ83ShYdqVeB8eJowpwgJU4lEzgEXnvEdvU9hyFAlLk7jLqbqigrq2E/vMaoicpYfw8evXJRhI3RhEQhmFG85fPTDPUPI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719973226; x=1751509226; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9vCmgknkvnCBaiX5V41A6Fp/6iH3tHunR4w2Cl/G6LA=; b=eW9etoY9bYSGrgKB2W5VMWK9xqitOGWuSBFrVcQ4axlrPOed8uN/okwZ +u4y2W6BXqcs7jByVS7UFbD+jzAY/DTjdcdjAvK75xET47VDMhp2NgsTL upFPYGyQRdokilOITth8rsMsEInT/2dSyIr1yQkjKk2Xx2c6v2kFJChxQ d2FdI/C6gWYoMNSUCwrPEXZnZGBFwufsyLv5/ULWijRE/w7mJOTt4jMwd nsYmyw7lwvu2+vcTsqdzxdLG9ggJoww0PFS0+nt/8aSQhmO+NJ/++TIy7 XStX5VYOl7dcjgs6Dmq6DhYM3xFcts4j800vRXbcY7BsI6I5HFJO1Sf3/ g==; X-CSE-ConnectionGUID: P+a6lIL9Qr+Pj2kIRFEXIg== X-CSE-MsgGUID: fn5wxdIARaK7RB3mwbXGcQ== X-IronPort-AV: E=McAfee;i="6700,10204,11121"; a="12367339" X-IronPort-AV: E=Sophos;i="6.09,180,1716274800"; d="scan'208";a="12367339" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2024 19:20:25 -0700 X-CSE-ConnectionGUID: +brdJGIkQf+MDtGTjoWNfA== X-CSE-MsgGUID: d+amZbWMQp6OlRIuSkYM5Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,180,1716274800"; d="scan'208";a="45878398" Received: from shvmail03.sh.intel.com ([10.239.245.20]) by fmviesa006.fm.intel.com with ESMTP; 02 Jul 2024 19:20:22 -0700 Received: from pli-ubuntu.sh.intel.com (pli-ubuntu.sh.intel.com [10.239.159.47]) by shvmail03.sh.intel.com (Postfix) with ESMTP id B0EA91005668; Wed, 3 Jul 2024 10:20:20 +0800 (CST) From: pan2.li@intel.com To: gcc-patches@gcc.gnu.org Cc: juzhe.zhong@rivai.ai, kito.cheng@gmail.com, jeffreyalaw@gmail.com, rdapp.gcc@gmail.com, Pan Li Subject: [PATCH v2] RISC-V: Implement the .SAT_TRUNC for scalar Date: Wed, 3 Jul 2024 10:20:19 +0800 Message-Id: <20240703022019.4171465-1-pan2.li@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240701091303.1968994-1-pan2.li@intel.com> References: <20240701091303.1968994-1-pan2.li@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, 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~incoming=patchwork.ozlabs.org@gcc.gnu.org From: Pan Li This patch would like to implement the simple .SAT_TRUNC pattern in the riscv backend. Aka: Form 1: #define DEF_SAT_U_TRUC_FMT_1(NT, WT) \ NT __attribute__((noinline)) \ sat_u_truc_##WT##_to_##NT##_fmt_1 (WT x) \ { \ bool overflow = x > (WT)(NT)(-1); \ return ((NT)x) | (NT)-overflow; \ } DEF_SAT_U_TRUC_FMT_1(uint32_t, uint64_t) Before this patch: __attribute__((noinline)) uint8_t sat_u_truc_uint16_t_to_uint8_t_fmt_1 (uint16_t x) { _Bool overflow; unsigned char _1; unsigned char _2; unsigned char _3; uint8_t _6; ;; basic block 2, loop depth 0 ;; pred: ENTRY overflow_5 = x_4(D) > 255; _1 = (unsigned char) x_4(D); _2 = (unsigned char) overflow_5; _3 = -_2; _6 = _1 | _3; return _6; ;; succ: EXIT } After this patch: __attribute__((noinline)) uint8_t sat_u_truc_uint16_t_to_uint8_t_fmt_1 (uint16_t x) { uint8_t _6; ;; basic block 2, loop depth 0 ;; pred: ENTRY _6 = .SAT_TRUNC (x_4(D)); [tail call] return _6; ;; succ: EXIT } The below tests suites are passed for this patch 1. The rv64gcv fully regression test. 2. The rv64gcv build with glibc gcc/ChangeLog: * config/riscv/iterators.md (ANYI_DOUBLE_TRUNC): Add new iterator for int double truncation. (ANYI_DOUBLE_TRUNCATED): Add new attr for int double truncation. (anyi_double_truncated): Ditto but for lowercase. * config/riscv/riscv-protos.h (riscv_expand_ustrunc): Add new func decl for expanding ustrunc * config/riscv/riscv.cc (riscv_expand_ustrunc): Add new func impl to expand ustrunc. * config/riscv/riscv.md (ustrunc2): Impl the new pattern ustrunc2 for int. gcc/testsuite/ChangeLog: * gcc.target/riscv/sat_arith.h: Add test helper macro. * gcc.target/riscv/sat_arith_data.h: New test. * gcc.target/riscv/sat_u_trunc-1.c: New test. * gcc.target/riscv/sat_u_trunc-2.c: New test. * gcc.target/riscv/sat_u_trunc-3.c: New test. * gcc.target/riscv/sat_u_trunc-run-1.c: New test. * gcc.target/riscv/sat_u_trunc-run-2.c: New test. * gcc.target/riscv/sat_u_trunc-run-3.c: New test. * gcc.target/riscv/scalar_sat_unary.h: New test. Signed-off-by: Pan Li --- gcc/config/riscv/iterators.md | 10 ++++ gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv.cc | 40 +++++++++++++ gcc/config/riscv/riscv.md | 10 ++++ gcc/testsuite/gcc.target/riscv/sat_arith.h | 16 ++++++ .../gcc.target/riscv/sat_arith_data.h | 56 +++++++++++++++++++ .../gcc.target/riscv/sat_u_trunc-1.c | 17 ++++++ .../gcc.target/riscv/sat_u_trunc-2.c | 20 +++++++ .../gcc.target/riscv/sat_u_trunc-3.c | 19 +++++++ .../gcc.target/riscv/sat_u_trunc-run-1.c | 16 ++++++ .../gcc.target/riscv/sat_u_trunc-run-2.c | 16 ++++++ .../gcc.target/riscv/sat_u_trunc-run-3.c | 16 ++++++ .../gcc.target/riscv/scalar_sat_unary.h | 22 ++++++++ 13 files changed, 259 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/sat_arith_data.h create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_trunc-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_trunc-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_trunc-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/scalar_sat_unary.h diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md index 20745faa55e..7377a40407e 100644 --- a/gcc/config/riscv/iterators.md +++ b/gcc/config/riscv/iterators.md @@ -65,6 +65,16 @@ (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")]) ;; Iterator for hardware-supported integer modes. (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")]) +(define_mode_iterator ANYI_DOUBLE_TRUNC [HI SI (DI "TARGET_64BIT")]) + +(define_mode_attr ANYI_DOUBLE_TRUNCATED [ + (HI "QI") (SI "HI") (DI "SI") +]) + +(define_mode_attr anyi_double_truncated [ + (HI "qi") (SI "hi") (DI "si") +]) + ;; Iterator for hardware-supported floating-point modes. (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT || TARGET_ZFINX") (DF "TARGET_DOUBLE_FLOAT || TARGET_ZDINX") diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index a8b76173fa0..61a22a187df 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -135,6 +135,7 @@ riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT, int); extern void riscv_legitimize_poly_move (machine_mode, rtx, rtx, rtx); extern void riscv_expand_usadd (rtx, rtx, rtx); extern void riscv_expand_ussub (rtx, rtx, rtx); +extern void riscv_expand_ustrunc (rtx, rtx); #ifdef RTX_CODE extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx, bool *invert_ptr = 0); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 9bba5da016e..02116c8c00b 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -11649,6 +11649,46 @@ riscv_expand_ussub (rtx dest, rtx x, rtx y) emit_move_insn (dest, gen_lowpart (mode, pmode_dest)); } +/* Implement the unsigned saturation truncation for int mode. + + b = SAT_TRUNC (a); + => + 1. max = half truncated max + 2. lt = a < max + 3. lt = lt - 1 (lt 0, ge -1) + 4. d = a | lt + 5. b = (trunc)d */ + +void +riscv_expand_ustrunc (rtx dest, rtx src) +{ + machine_mode mode = GET_MODE (dest); + rtx xmode_max = gen_reg_rtx (Xmode); + unsigned precision = GET_MODE_PRECISION (mode).to_constant (); + + gcc_assert (precision < 64); + + uint64_t max = ((uint64_t)1u << precision) - 1u; + rtx xmode_src = gen_lowpart (Xmode, src); + rtx xmode_dest = gen_reg_rtx (Xmode); + rtx xmode_lt = gen_reg_rtx (Xmode); + + /* Step-1: max = half truncated max */ + emit_move_insn (xmode_max, gen_int_mode (max, Xmode)); + + /* Step-2: lt = src < max */ + riscv_emit_binary (LTU, xmode_lt, xmode_src, xmode_max); + + /* Step-3: lt = lt - 1 */ + riscv_emit_binary (PLUS, xmode_lt, xmode_lt, CONSTM1_RTX (Xmode)); + + /* Step-4: xmode_dest = lt | src */ + riscv_emit_binary (IOR, xmode_dest, xmode_lt, xmode_src); + + /* Step-5: dest = xmode_dest */ + emit_move_insn (dest, gen_lowpart (mode, xmode_dest)); +} + /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE. Return TFmode for TI_LONG_DOUBLE_TYPE which is for long double type, go with the default one for the others. */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index c0c960353eb..16e5f8163e3 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4271,6 +4271,16 @@ (define_expand "ussub3" } ) +(define_expand "ustrunc2" + [(match_operand: 0 "register_operand") + (match_operand:ANYI_DOUBLE_TRUNC 1 "register_operand")] + "" + { + riscv_expand_ustrunc (operands[0], operands[1]); + DONE; + } +) + ;; These are forms of (x << C1) + C2, potentially canonicalized from ;; ((x + C2') << C1. Depending on the cost to load C2 vs C2' we may ;; want to go ahead and recognize this form as C2 may be cheaper to diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h index 0c2e44af718..b4c626b59da 100644 --- a/gcc/testsuite/gcc.target/riscv/sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h @@ -172,4 +172,20 @@ sat_u_sub_##T##_fmt_12 (T x, T y) \ #define RUN_SAT_U_SUB_FMT_11(T, x, y) sat_u_sub_##T##_fmt_11(x, y) #define RUN_SAT_U_SUB_FMT_12(T, x, y) sat_u_sub_##T##_fmt_12(x, y) +/******************************************************************************/ +/* Saturation Truncate (unsigned and signed) */ +/******************************************************************************/ + +#define DEF_SAT_U_TRUC_FMT_1(NT, WT) \ +NT __attribute__((noinline)) \ +sat_u_truc_##WT##_to_##NT##_fmt_1 (WT x) \ +{ \ + bool overflow = x > (WT)(NT)(-1); \ + return ((NT)x) | (NT)-overflow; \ +} +#define DEF_SAT_U_TRUC_FMT_1_WRAP(NT, WT) DEF_SAT_U_TRUC_FMT_1(NT, WT) + +#define RUN_SAT_U_TRUC_FMT_1(NT, WT, x) sat_u_truc_##WT##_to_##NT##_fmt_1 (x) +#define RUN_SAT_U_TRUC_FMT_1_WRAP(NT, WT, x) RUN_SAT_U_TRUC_FMT_1(NT, WT, x) + #endif diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith_data.h b/gcc/testsuite/gcc.target/riscv/sat_arith_data.h new file mode 100644 index 00000000000..b991f8aa955 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_arith_data.h @@ -0,0 +1,56 @@ +#ifndef HAVE_DEFINED_SAT_ARITH_DATA_H +#define HAVE_DEFINED_SAT_ARITH_DATA_H + +#define TEST_UNARY_STRUCT_NAME(T1, T2) test_##T1##_##T2##_s +#define TEST_UNARY_STRUCT_DECL(T1, T2) struct TEST_UNARY_STRUCT_NAME(T1, T2) +#define TEST_UNARY_STRUCT(T1, T2) \ + struct TEST_UNARY_STRUCT_NAME(T1, T2) \ + { \ + T1 to; \ + T2 from; \ + }; + +#define TEST_UNARY_DATA(T1, T2) t_##T1##_##T2##_s +#define TEST_UNARY_DATA_WRAP(T1, T2) TEST_UNARY_DATA(T1, T2) + +TEST_UNARY_STRUCT (uint8_t, uint16_t) +TEST_UNARY_STRUCT (uint16_t, uint32_t) +TEST_UNARY_STRUCT (uint32_t, uint64_t) + +TEST_UNARY_STRUCT_DECL(uint8_t, uint16_t) \ + TEST_UNARY_DATA(uint8_t, uint16_t)[] = +{ + { 0, 0}, + { 2, 2}, + {254, 254}, + {255, 255}, + {255, 256}, + {255, 65534}, + {255, 65535}, +}; + +TEST_UNARY_STRUCT_DECL(uint16_t, uint32_t) \ + TEST_UNARY_DATA(uint16_t, uint32_t)[] = +{ + { 0, 0}, + { 5, 5}, + {65534, 65534}, + {65535, 65535}, + {65535, 65536}, + {65535, 4294967294}, + {65535, 4294967295}, +}; + +TEST_UNARY_STRUCT_DECL(uint32_t, uint64_t) \ + TEST_UNARY_DATA(uint32_t, uint64_t)[] = +{ + { 0, 0}, + { 9, 9}, + {4294967294, 4294967294}, + {4294967295, 4294967295}, + {4294967295, 4294967296}, + {4294967295, 18446744073709551614u}, + {4294967295, 18446744073709551615u}, +}; + +#endif diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_trunc-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-1.c new file mode 100644 index 00000000000..354831005b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_u_truc_uint16_t_to_uint8_t_fmt_1: +** sltiu\s+[atx][0-9]+,\s*a0,\s*255 +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff +** ret +*/ +DEF_SAT_U_TRUC_FMT_1(uint8_t, uint16_t) + +/* { dg-final { scan-rtl-dump-times ".SAT_TRUNC " 2 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_trunc-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-2.c new file mode 100644 index 00000000000..0001d8a9ed9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_u_truc_uint32_t_to_uint16_t_fmt_1: +** li\s+[atx][0-9]+,\s*65536 +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** slli\s+a0,\s*a0,\s*48 +** srli\s+a0,\s*a0,\s*48 +** ret +*/ +DEF_SAT_U_TRUC_FMT_1(uint16_t, uint32_t) + +/* { dg-final { scan-rtl-dump-times ".SAT_TRUNC " 2 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_trunc-3.c b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-3.c new file mode 100644 index 00000000000..4359935a9d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-3.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_u_truc_uint64_t_to_uint32_t_fmt_1: +** li\s+[atx][0-9]+,\s*-1 +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 +** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** sext.w\s+a0,\s*a0 +** ret +*/ +DEF_SAT_U_TRUC_FMT_1(uint32_t, uint64_t) + +/* { dg-final { scan-rtl-dump-times ".SAT_TRUNC " 2 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-1.c new file mode 100644 index 00000000000..39a5ce2b675 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-1.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint8_t +#define T2 uint16_t + +DEF_SAT_U_TRUC_FMT_1_WRAP(T1, T2) + +#define DATA TEST_UNARY_DATA_WRAP(T1, T2) +#define T TEST_UNARY_STRUCT_DECL(T1, T2) +#define RUN_UNARY(x) RUN_SAT_U_TRUC_FMT_1_WRAP(T1, T2, x) + +#include "scalar_sat_unary.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-2.c new file mode 100644 index 00000000000..b98114a7dfc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-2.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint16_t +#define T2 uint32_t + +DEF_SAT_U_TRUC_FMT_1_WRAP(T1, T2) + +#define DATA TEST_UNARY_DATA_WRAP(T1, T2) +#define T TEST_UNARY_STRUCT_DECL(T1, T2) +#define RUN_UNARY(x) RUN_SAT_U_TRUC_FMT_1_WRAP(T1, T2, x) + +#include "scalar_sat_unary.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-3.c b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-3.c new file mode 100644 index 00000000000..8a92a8c1f55 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_u_trunc-run-3.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint32_t +#define T2 uint64_t + +DEF_SAT_U_TRUC_FMT_1_WRAP(T1, T2) + +#define DATA TEST_UNARY_DATA_WRAP(T1, T2) +#define T TEST_UNARY_STRUCT_DECL(T1, T2) +#define RUN_UNARY(x) RUN_SAT_U_TRUC_FMT_1_WRAP(T1, T2, x) + +#include "scalar_sat_unary.h" diff --git a/gcc/testsuite/gcc.target/riscv/scalar_sat_unary.h b/gcc/testsuite/gcc.target/riscv/scalar_sat_unary.h new file mode 100644 index 00000000000..2ae058724b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/scalar_sat_unary.h @@ -0,0 +1,22 @@ +#ifndef HAVE_DEFINED_SCALAR_SAT_UNARY +#define HAVE_DEFINED_SCALAR_SAT_UNARY + +int +main () +{ + unsigned i; + T d; + + for (i = 0; i < sizeof (DATA) / sizeof (DATA[0]); i++) + { + d = DATA[i]; + + if (RUN_UNARY (d.from) != d.to) + __builtin_abort (); + } + + return 0; +} + +#endif +