From patchwork Sat Feb 17 10:30:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2" X-Patchwork-Id: 85922 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 603E8385E02E for ; Sat, 17 Feb 2024 10:31:04 +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.7]) by sourceware.org (Postfix) with ESMTPS id 960A63858D33 for ; Sat, 17 Feb 2024 10:30:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 960A63858D33 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 960A63858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708165839; cv=none; b=bruHL6DG+nhH01x4X6addhEEnKgDaVhkJhLx2gyKWiE1vIYJ+xtUMP0woM9YUnoF7z57EhNpUlhj4KqP9m2pr9pRh07ehY4y+L9RXSsmR+yARjv5ggj1vPXPvluF/iIogqztuR9CzPY3xj5o9bzHi215a3RvjJsCJE++jaeSeqI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708165839; c=relaxed/simple; bh=vXE3z9uM8je5kVG6fOWszsLP1nI06Z9lV6hBuUMlwGU=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=vGEhfEe2SjQd2incAQ1y1LZm8Mq+slko6HoFYLagxJUj9BnfhtFkj5bolCWRFCFMWEiItXPksbs4Hhb1SitaBdT+x0QzmqRS4SmsC6W2kb4CvyVZpiDbs3RLbOfa02nzvse8V3WPGo9CgCxZ+nChWCpptQYVHWPeHUzm0NEcKwQ= 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=1708165836; x=1739701836; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=vXE3z9uM8je5kVG6fOWszsLP1nI06Z9lV6hBuUMlwGU=; b=JUi4Ap+fZJi7wgT+Qcgy6xqh0Emi8hmRDoRtcsAI6wWUcEM+q6E9v/3O t+xixwdwtQKrWzN0T1vQ/UyGcgBGkngsQYaBJsfwi/B7QQNefNAM6Mdup pQmIjwMDEQ+NvJsmxz8vdv95fRo80pFFrgt9sKGrMKyqHDKhZleIub4Ca 58Gn1XmpZAAztOmczIANfZ4jPBGYW/vBjHDfxIRKPgngHXb171LfSsUKU NduBJnZ7dJH2m7bgUQllvTIVhymw/QAxa15MO2CfatDdtqbOvWejtduAl ek9ruvMmm+vHE5IMzO9pm9WHE+7GlSRsG5BDO4Haps8DCy5PvObTKySZL A==; X-IronPort-AV: E=McAfee;i="6600,9927,10986"; a="27745773" X-IronPort-AV: E=Sophos;i="6.06,166,1705392000"; d="scan'208";a="27745773" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2024 02:30:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,166,1705392000"; d="scan'208";a="4445630" Received: from shvmail02.sh.intel.com ([10.239.244.9]) by orviesa008.jf.intel.com with ESMTP; 17 Feb 2024 02:30:32 -0800 Received: from pli-ubuntu.sh.intel.com (pli-ubuntu.sh.intel.com [10.239.159.47]) by shvmail02.sh.intel.com (Postfix) with ESMTP id 3A3FB1007EB4; Sat, 17 Feb 2024 18:30:31 +0800 (CST) From: pan2.li@intel.com To: gcc-patches@gcc.gnu.org Cc: juzhe.zhong@rivai.ai, pan2.li@intel.com, yanzhang.wang@intel.com, kito.cheng@gmail.com, richard.guenther@gmail.com, Tamar.Christina@arm.com Subject: [PATCH v1] Internal-fn: Add new internal function SAT_ADDU Date: Sat, 17 Feb 2024 18:30:29 +0800 Message-Id: <20240217103029.3120318-1-pan2.li@intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE, URIBL_BLACK 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 From: Pan Li This patch would like to add the middle-end presentation for the unsigned saturation add. Aka set the result of add to the max when overflow. It will take the pattern similar as below. SAT_ADDU (x, y) => (x + y) | (-(TYPE)((TYPE)(x + y) < x)) Take uint8_t as example, we will have: * SAT_ADDU (1, 254) => 255. * SAT_ADDU (1, 255) => 255. * SAT_ADDU (2, 255) => 255. * SAT_ADDU (255, 255) => 255. The patch also implement the SAT_ADDU in the riscv backend as the sample. Given below example: uint64_t sat_add_u64 (uint64_t x, uint64_t y) { return (x + y) | (- (uint64_t)((uint64_t)(x + y) < x)); } Before this patch: uint64_t sat_add_uint64_t (uint64_t x, uint64_t y) { long unsigned int _1; _Bool _2; long unsigned int _3; long unsigned int _4; uint64_t _7; long unsigned int _10; __complex__ long unsigned int _11; ;; basic block 2, loop depth 0 ;; pred: ENTRY _11 = .ADD_OVERFLOW (x_5(D), y_6(D)); _1 = REALPART_EXPR <_11>; _10 = IMAGPART_EXPR <_11>; _2 = _10 != 0; _3 = (long unsigned int) _2; _4 = -_3; _7 = _1 | _4; return _7; ;; succ: EXIT } After this patch: uint64_t sat_add_uint64_t (uint64_t x, uint64_t y) { uint64_t _7; ;; basic block 2, loop depth 0 ;; pred: ENTRY _7 = .SAT_ADDU (x_5(D), y_6(D)); [tail call] return _7; ;; succ: EXIT } Then we will have the middle-end representation like .SAT_ADDU after this patch. PR target/51492 PR target/112600 gcc/ChangeLog: * config/riscv/riscv-protos.h (riscv_expand_saturation_addu): New func decl for the SAT_ADDU expand. * config/riscv/riscv.cc (riscv_expand_saturation_addu): New func impl for the SAT_ADDU expand. * config/riscv/riscv.md (sat_addu_3): New pattern to impl the standard name SAT_ADDU. * doc/md.texi: Add doc for SAT_ADDU. * internal-fn.cc (commutative_binary_fn_p): Add type IFN_SAT_ADDU. * internal-fn.def (SAT_ADDU): Add SAT_ADDU. * match.pd: Add simplify pattern patch for SAT_ADDU. * optabs.def (OPTAB_D): Add sat_addu_optab. gcc/testsuite/ChangeLog: * gcc.target/riscv/sat_addu-1.c: New test. * gcc.target/riscv/sat_addu-2.c: New test. * gcc.target/riscv/sat_addu-3.c: New test. * gcc.target/riscv/sat_addu-4.c: New test. * gcc.target/riscv/sat_addu-run-1.c: New test. * gcc.target/riscv/sat_addu-run-2.c: New test. * gcc.target/riscv/sat_addu-run-3.c: New test. * gcc.target/riscv/sat_addu-run-4.c: New test. * gcc.target/riscv/sat_arith.h: New test. Signed-off-by: Pan Li --- gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv.cc | 46 +++++++++++++++++ gcc/config/riscv/riscv.md | 11 +++++ gcc/doc/md.texi | 11 +++++ gcc/internal-fn.cc | 1 + gcc/internal-fn.def | 1 + gcc/match.pd | 22 +++++++++ gcc/optabs.def | 2 + gcc/testsuite/gcc.target/riscv/sat_addu-1.c | 18 +++++++ gcc/testsuite/gcc.target/riscv/sat_addu-2.c | 20 ++++++++ gcc/testsuite/gcc.target/riscv/sat_addu-3.c | 17 +++++++ gcc/testsuite/gcc.target/riscv/sat_addu-4.c | 16 ++++++ .../gcc.target/riscv/sat_addu-run-1.c | 42 ++++++++++++++++ .../gcc.target/riscv/sat_addu-run-2.c | 42 ++++++++++++++++ .../gcc.target/riscv/sat_addu-run-3.c | 42 ++++++++++++++++ .../gcc.target/riscv/sat_addu-run-4.c | 49 +++++++++++++++++++ gcc/testsuite/gcc.target/riscv/sat_arith.h | 15 ++++++ 17 files changed, 356 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_addu-run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/sat_arith.h diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index ae1685850ac..f201b2384f9 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -132,6 +132,7 @@ extern void riscv_asm_output_external (FILE *, const tree, const char *); extern bool 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_saturation_addu (rtx, 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 799d7919a4a..84e86eb5d49 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -10657,6 +10657,52 @@ riscv_vector_mode_supported_any_target_p (machine_mode) return true; } +/* Emit insn for the saturation addu, aka (x + y) | - ((x + y) < x). */ +void +riscv_expand_saturation_addu (rtx dest, rtx x, rtx y) +{ + machine_mode mode = GET_MODE (dest); + rtx pmode_sum = gen_reg_rtx (Pmode); + rtx pmode_lt = gen_reg_rtx (Pmode); + rtx pmode_x = gen_lowpart (Pmode, x); + rtx pmode_y = gen_lowpart (Pmode, y); + rtx pmode_dest = gen_reg_rtx (Pmode); + + /* Step-1: sum = x + y */ + if (mode == SImode && mode != Pmode) + { /* Take addw to avoid the sum truncate. */ + rtx simode_sum = gen_reg_rtx (SImode); + riscv_emit_binary (PLUS, simode_sum, x, y); + emit_move_insn (pmode_sum, gen_lowpart (Pmode, simode_sum)); + } + else + riscv_emit_binary (PLUS, pmode_sum, pmode_x, pmode_y); + + /* Step-1.1: truncate sum for HI and QI as we have no insn for add QI/HI. */ + if (mode == HImode || mode == QImode) + { + int shift_bits = GET_MODE_BITSIZE (Pmode) + - GET_MODE_BITSIZE (mode).to_constant (); + + gcc_assert (shift_bits > 0); + + riscv_emit_binary (ASHIFT, pmode_sum, pmode_sum, GEN_INT (shift_bits)); + riscv_emit_binary (LSHIFTRT, pmode_sum, pmode_sum, GEN_INT (shift_bits)); + } + + /* Step-2: lt = sum < x */ + riscv_emit_binary (LTU, pmode_lt, pmode_sum, pmode_x); + + /* Step-3: lt = -lt */ + riscv_emit_unary (NEG, pmode_lt, pmode_lt); + + /* Step-4: pmode_dest = sum | lt */ + riscv_emit_binary (IOR, pmode_dest, pmode_lt, pmode_sum); + + /* Step-5: dest = pmode_dest */ + emit_move_insn (dest, gen_lowpart (mode, pmode_dest)); +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 39b29795cd6..03cbe5a2ca9 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3841,6 +3841,17 @@ (define_insn "*large_load_address" [(set_attr "type" "load") (set (attr "length") (const_int 8))]) +(define_expand "sat_addu_3" + [(match_operand:ANYI 0 "register_operand") + (match_operand:ANYI 1 "register_operand") + (match_operand:ANYI 2 "register_operand")] + "" + { + riscv_expand_saturation_addu (operands[0], operands[1], operands[2]); + DONE; + } +) + (include "bitmanip.md") (include "crypto.md") (include "sync.md") diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index b0c61925120..5867afdb1a0 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -6653,6 +6653,17 @@ The operation is only supported for vector modes @var{m}. This pattern is not allowed to @code{FAIL}. +@cindex @code{sat_addu_@var{m}3} instruction pattern +@item @samp{sat_addu_@var{m}3} +Perform the saturation unsigned add for the operand 1 and operand 2 and +store the result into the operand 0. All operands have mode @var{m}, +which is a scalar integer mode. + +@smallexample + typedef unsigned char uint8_t; + uint8_t sat_addu (uint8_t x, uint8_t y) => return (x + y) | -((x + y) < x); +@end smallexample + @cindex @code{cmla@var{m}4} instruction pattern @item @samp{cmla@var{m}4} Perform a vector multiply and accumulate that is semantically the same as diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index a07f25f3aee..dee73dbc614 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -4159,6 +4159,7 @@ commutative_binary_fn_p (internal_fn fn) case IFN_VEC_WIDEN_PLUS_HI: case IFN_VEC_WIDEN_PLUS_EVEN: case IFN_VEC_WIDEN_PLUS_ODD: + case IFN_SAT_ADDU: return true; default: diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index c14d30365c1..a04592fc779 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -428,6 +428,7 @@ DEF_INTERNAL_WIDENING_OPTAB_FN (VEC_WIDEN_ABD, binary) DEF_INTERNAL_OPTAB_FN (VEC_FMADDSUB, ECF_CONST, vec_fmaddsub, ternary) DEF_INTERNAL_OPTAB_FN (VEC_FMSUBADD, ECF_CONST, vec_fmsubadd, ternary) +DEF_INTERNAL_OPTAB_FN (SAT_ADDU, ECF_CONST | ECF_NOTHROW, sat_addu, binary) /* FP scales. */ DEF_INTERNAL_FLT_FN (LDEXP, ECF_CONST, ldexp, binary) diff --git a/gcc/match.pd b/gcc/match.pd index 711c3a10c3f..9de1106adcf 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1994,6 +1994,28 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ) ) +#if GIMPLE + +/* Saturation add unsigned, aka: + SAT_ADDU = (X + Y) | - ((X + Y) < X) or + SAT_ADDU = (X + Y) | - ((X + Y) < Y). */ +(simplify + (bit_ior:c (plus:c@2 @0 @1) (negate (convert (lt @2 @0)))) + (if (optimize + && INTEGRAL_TYPE_P (type) + && TYPE_UNSIGNED (TREE_TYPE (@0)) + && types_match (type, TREE_TYPE (@0)) + && types_match (type, TREE_TYPE (@1)) + && direct_internal_fn_supported_p (IFN_SAT_ADDU, type, OPTIMIZE_FOR_BOTH)) + (IFN_SAT_ADDU @0 @1))) + +/* SAT_ADDU (X, 0) = X */ +(simplify + (IFN_SAT_ADDU:c @0 integer_zerop) + @0) + +#endif + /* A few cases of fold-const.cc negate_expr_p predicate. */ (match negate_expr_p INTEGER_CST diff --git a/gcc/optabs.def b/gcc/optabs.def index ad14f9328b9..a2c11b7707b 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -300,6 +300,8 @@ OPTAB_D (usubc5_optab, "usubc$I$a5") OPTAB_D (addptr3_optab, "addptr$a3") OPTAB_D (spaceship_optab, "spaceship$a3") +OPTAB_D (sat_addu_optab, "sat_addu_$a3") + OPTAB_D (smul_highpart_optab, "smul$a3_highpart") OPTAB_D (umul_highpart_optab, "umul$a3_highpart") diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-1.c b/gcc/testsuite/gcc.target/riscv/sat_addu-1.c new file mode 100644 index 00000000000..229abef0faa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_addu_uint8_t: +** add\s+[atx][0-9]+,\s*a0,\s*a1 +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff +** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** andi\s+a0,\s*a0,\s*0xff +** ret +*/ +DEF_SAT_ADDU(uint8_t) diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-2.c b/gcc/testsuite/gcc.target/riscv/sat_addu-2.c new file mode 100644 index 00000000000..4023b030811 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_addu_uint16_t: +** add\s+[atx][0-9]+,\s*a0,\s*a1 +** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 +** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** 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_ADDU(uint16_t) diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-3.c b/gcc/testsuite/gcc.target/riscv/sat_addu-3.c new file mode 100644 index 00000000000..4d0af97fb67 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-3.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_addu_uint32_t: +** addw\s+[atx][0-9]+,\s*a0,\s*a1 +** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** sext.w\s+a0,\s*a0 +** ret +*/ +DEF_SAT_ADDU(uint32_t) diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-4.c b/gcc/testsuite/gcc.target/riscv/sat_addu-4.c new file mode 100644 index 00000000000..926f31266e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-4.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_addu_uint64_t: +** add\s+[atx][0-9]+,\s*a0,\s*a1 +** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ +** ret +*/ +DEF_SAT_ADDU(uint64_t) diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-run-1.c b/gcc/testsuite/gcc.target/riscv/sat_addu-run-1.c new file mode 100644 index 00000000000..b19515c39d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-run-1.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_ADDU(uint8_t) + +int +main () +{ + if (RUN_SAT_ADDU (uint8_t, 0, 0) != 0) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 0, 1) != 1) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 1, 1) != 2) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 0, 254) != 254) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 1, 254) != 255) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 2, 254) != 255) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 0, 255) != 255) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 1, 255) != 255) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 2, 255) != 255) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint8_t, 255, 255) != 255) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-run-2.c b/gcc/testsuite/gcc.target/riscv/sat_addu-run-2.c new file mode 100644 index 00000000000..90073fbe4ba --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-run-2.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_ADDU(uint16_t) + +int +main () +{ + if (RUN_SAT_ADDU (uint16_t, 0, 0) != 0) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 0, 1) != 1) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 1, 1) != 2) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 0, 65534) != 65534) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 1, 65534) != 65535) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 2, 65534) != 65535) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 0, 65535) != 65535) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 1, 65535) != 65535) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 2, 65535) != 65535) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint16_t, 65535, 65535) != 65535) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-run-3.c b/gcc/testsuite/gcc.target/riscv/sat_addu-run-3.c new file mode 100644 index 00000000000..996dd3de737 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-run-3.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_ADDU(uint32_t) + +int +main () +{ + if (RUN_SAT_ADDU (uint32_t, 0, 0) != 0) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 0, 1) != 1) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 1, 1) != 2) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 0, 4294967294) != 4294967294) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 1, 4294967294) != 4294967295) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 2, 4294967294) != 4294967295) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 0, 4294967295) != 4294967295) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 1, 4294967295) != 4294967295) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 2, 4294967295) != 4294967295) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint32_t, 4294967295, 4294967295) != 4294967295) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/sat_addu-run-4.c b/gcc/testsuite/gcc.target/riscv/sat_addu-run-4.c new file mode 100644 index 00000000000..51a5421577b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_addu-run-4.c @@ -0,0 +1,49 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_ADDU(uint64_t) + +int +main () +{ + if (RUN_SAT_ADDU (uint64_t, 0, 0) != 0) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 0, 1) != 1) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 1, 1) != 2) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 0, 18446744073709551614u) + != 18446744073709551614u) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 1, 18446744073709551614u) + != 18446744073709551615u) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 2, 18446744073709551614u) + != 18446744073709551615u) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 0, 18446744073709551615u) + != 18446744073709551615u) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 1, 18446744073709551615u) + != 18446744073709551615u) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 2, 18446744073709551615u) + != 18446744073709551615u) + __builtin_abort (); + + if (RUN_SAT_ADDU (uint64_t, 18446744073709551615u, 18446744073709551615u) + != 18446744073709551615u) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h new file mode 100644 index 00000000000..4c00157685e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h @@ -0,0 +1,15 @@ +#ifndef HAVE_SAT_ARITH +#define HAVE_SAT_ARITH + +#include + +#define DEF_SAT_ADDU(TYPE) \ +TYPE __attribute__((noinline)) \ +sat_addu_##TYPE (TYPE x, TYPE y) \ +{ \ + return (x + y) | (-(TYPE)((TYPE)(x + y) < x)); \ +} + +#define RUN_SAT_ADDU(TYPE, x, y) sat_addu_##TYPE(x, y) + +#endif