From patchwork Mon Jul 15 10:35:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2" X-Patchwork-Id: 1960589 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=Tq0nX7wI; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; 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 [8.43.85.97]) (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 4WMzBX2p9rz1xqc for ; Mon, 15 Jul 2024 20:36:04 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E81393865491 for ; Mon, 15 Jul 2024 10:36:01 +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.13]) by sourceware.org (Postfix) with ESMTPS id 4E02C385841E for ; Mon, 15 Jul 2024 10:35:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4E02C385841E 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 4E02C385841E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=192.198.163.13 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721039739; cv=none; b=gK2/iVhYOOegGpgfX0u/ob6WmZbs1meJSw0u0STsQK/8o57DkCNSJSF7ioEwmclwu9Ytn5Mms6CxvEvGA6ZsCi5A7Zc4BEU20qfBowGHrZd9HskrmyIUgth69ebUZG2caD92QkLB6f94KHDOgfAsvwCNp6jXMquvbwZlqL5Jye0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721039739; c=relaxed/simple; bh=YX1cnIj9q7PDOjn7JWMAMcJ7W3oWiXlFS6EPZw3zla4=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=rTpKc995JSyt8fucpsBUM+2lUv20xH1DSqsD1XQrxKW9fmq62sgWu944I+fWEKPDTUNMeIh3kFaeJQ5PpOJxxHQQ3N5unNjWBtLmTTICuLwnrF4djxkEi59/TPcQKWq8IhC90mTxCahgs3FI6zg97wYzWA6tL15Zj0FMhwK8ZeU= 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=1721039736; x=1752575736; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=YX1cnIj9q7PDOjn7JWMAMcJ7W3oWiXlFS6EPZw3zla4=; b=Tq0nX7wI0e4e8fYFcvURVIhcfJvLw2rGHScqkc2UHIeDGJwCGLb31HEa xHgW3X01M7QYa2bRl1FqB4F2zJWykA8MJD/DmqM1xuJm0WYIMoIgD/Hoo bAZAVDTuzCmsCWyfCtBRdZJLDBb0uBei4A6wK4ElIuCvCyYpncEFxX9jQ 8RxiwiEOwKfABUKhSnkvT8wLnIE8cWRRPxRh9QRTfBYJf0pljRdKBYj+9 TPfu/I+RoUWHtylOs1crNi8IXujpfOGGkZsvhSHUPbBUZcfNlToa0YD6F DK8soBCTWdveCciQ0QtPjRZalIknlyMyotjckhIvOQPCzjylJGUqS86J4 A==; X-CSE-ConnectionGUID: HDhyJrUmRi+MhT0YHagpvA== X-CSE-MsgGUID: asKYo3irQ0eU5mQsWT0xog== X-IronPort-AV: E=McAfee;i="6700,10204,11133"; a="21321230" X-IronPort-AV: E=Sophos;i="6.09,210,1716274800"; d="scan'208";a="21321230" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2024 03:35:35 -0700 X-CSE-ConnectionGUID: bVK3FBtYQ9SniNQf8d7lWg== X-CSE-MsgGUID: dp+G4FhuRyW7w4W29e6D8Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,210,1716274800"; d="scan'208";a="50349646" Received: from shvmail03.sh.intel.com ([10.239.245.20]) by orviesa008.jf.intel.com with ESMTP; 15 Jul 2024 03:35:31 -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 A753510056F8; Mon, 15 Jul 2024 18:35:30 +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 v3] RISC-V: Implement the .SAT_TRUNC for scalar Date: Mon, 15 Jul 2024 18:35:28 +0800 Message-Id: <20240715103528.2326447-1-pan2.li@intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 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 Update in v3: * Rebase the upstream. * Adjust asm check. Original log: 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/rvv/autovec/unop/vec_sat_u_trunc-1.c: Adjust asm check times from 2 to 4. * 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 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 ++++ .../rvv/autovec/unop/vec_sat_u_trunc-1.c | 2 +- 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 ++++++++ 14 files changed, 260 insertions(+), 1 deletion(-) 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 d61ed53a8b1..734da041f0c 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 7c0ea1b445b..ce5e38d3dbb 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 d50ac611e1a..cc991ee8bab 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -11603,6 +11603,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 5dee837a587..2963cfa1a86 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4301,6 +4301,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/rvv/autovec/unop/vec_sat_u_trunc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vec_sat_u_trunc-1.c index dc9653947fc..1812828afe8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vec_sat_u_trunc-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vec_sat_u_trunc-1.c @@ -16,4 +16,4 @@ */ DEF_VEC_SAT_U_TRUNC_FMT_1 (uint8_t, uint16_t) -/* { dg-final { scan-rtl-dump-times ".SAT_TRUNC " 2 "expand" } } */ +/* { dg-final { scan-rtl-dump-times ".SAT_TRUNC " 4 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h index 75442c94dc1..37e0a60f21b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h @@ -214,4 +214,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 +