From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-00230701.pphosted.com (mx0b-00230701.pphosted.com [148.163.158.9]) by sourceware.org (Postfix) with ESMTPS id DF5613858C78 for ; Wed, 6 Sep 2023 12:50:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DF5613858C78 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=synopsys.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=synopsys.com Received: from pps.filterd (m0098572.ppops.net [127.0.0.1]) by mx0b-00230701.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 386BOrOB019198; Wed, 6 Sep 2023 05:50:38 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=synopsys.com; h=from : to : cc : subject : date : message-id : mime-version : content-transfer-encoding; s=pfptdkimsnps; bh=0P36tBPdoVlOhyTsXLG/q/EojCCl8H8lT9vNiSMJjfQ=; b=D9Frjs5UjvyKgdOl1G8UTEgPqS4wcIgjnw8n2cC+ocVVqDClws3Yg11PBVC0dPKHKs2Y 4Wa7KF5KZCflfkYptGnfkSJKgaCNJYs0kPvw1TN49Wsh4LvBtnuo27E2Nuld/S3jeoer lhc4d4YbNHOgpYwZ6Q4RSdzFNK9xN3OnTTuxhO9CT81Qa+3JUBPCBthslS6KxDON8L0Z jVjXfFMeeAaSA5G137BuUUdp42umLcYK7m/95+ylQV3NKoPurfJ5oRYlI2Cbz3WCFvnn er0ukbEE3DgWa+g02G55dxJlev+kfeAOcKbxzPSYQitUvyZTZ7E/KaIND9YUvVZkCAq8 gw== Received: from smtprelay-out1.synopsys.com (smtprelay-out1.synopsys.com [149.117.87.133]) by mx0b-00230701.pphosted.com (PPS) with ESMTPS id 3sxm73ht44-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 06 Sep 2023 05:50:38 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1694004637; bh=W+l0QdWIJEIMr9V2ODB+EfYFrfviBrql2n8LjLK8w38=; h=From:To:Cc:Subject:Date:From; b=LE59qjd1HcYM4/sKfKus7Up15u90fqonqkdkTQzXfpkj5+7FIVipvdS51GoPV/lLT 6BH1r+4qbbAHXDM6r5lWhoaMW1Ky72lWwYasMRAIOxnxkaDMgzAeVFzCjTizRHDH1F wJUc+RKEE+PYII27uewHN6mcw3DyHSYtLZdX79gz1oqa1jsMxcSHYkTJX2+x8AA4WB fLa4GreKwBgcFSSAk6Rslb61nPLw9D3LcbafV9DslO8Dg81fAvfiuZX27182dq03t0 z/WuBa45RISWxMCMoZ/ns5ymtn/SlcFCErGEQjOaGqS+XPQSJDRC9cibEPO0P3LTpk vwKUK3+IrdDPQ== Received: from mailhost.synopsys.com (sv2-mailhost2.synopsys.com [10.205.2.134]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "mailhost.synopsys.com", Issuer "SNPSica2" (verified OK)) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 1CF1B40127; Wed, 6 Sep 2023 12:50:36 +0000 (UTC) Received: from atlantis.internal.synopsys.com (unknown [10.100.25.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client did not present a certificate) by mailhost.synopsys.com (Postfix) with ESMTPSA id 0A732A007B; Wed, 6 Sep 2023 12:50:34 +0000 (UTC) X-SNPS-Relay: synopsys.com From: Shahab Vahedi To: Claudiu Zissulescu , gcc-patches@gcc.gnu.org Cc: Shahab Vahedi , Claudiu Zissulescu Subject: [PATCH 1/2] ARC: Use intrinsics for __builtin_add_overflow*() Date: Wed, 6 Sep 2023 14:50:25 +0200 Message-ID: <20230906125026.16091-1-shahab@synopsys.com> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Proofpoint-GUID: PJaETUy8qjpU7S5zI1nymgjGcqHHXouV X-Proofpoint-ORIG-GUID: PJaETUy8qjpU7S5zI1nymgjGcqHHXouV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-09-06_06,2023-09-05_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_active_cloned_notspam policy=outbound_active_cloned score=0 suspectscore=0 mlxscore=0 bulkscore=0 mlxlogscore=999 spamscore=0 clxscore=1011 lowpriorityscore=0 priorityscore=1501 phishscore=0 malwarescore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2308100000 definitions=main-2309060111 X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,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 List-Id: This patch covers signed and unsigned additions. The generated code would be something along these lines: signed: add.f r0, r1, r2 b.v @label unsigned: add.f r0, r1, r2 b.c @label gcc/ChangeLog: * config/arc/arc-modes.def: Add CC_V mode. * config/arc/predicates.md (proper_comparison_operator): Handle E_CC_Vmode. (equality_comparison_operator): Exclude CC_Vmode from eq/ne. (cc_set_register): Handle CC_Vmode. (cc_use_register): Likewise. * config/arc/arc.md (addsi3_v): New insn. (addvsi4): New expand. (addsi3_c): New insn. (uaddvsi4): New expand. * config/arc/arc-protos.h (arc_gen_unlikely_cbranch): New. * config/arc/arc.cc (arc_gen_unlikely_cbranch): New. (get_arc_condition_code): Handle E_CC_Vmode. (arc_init_reg_tables): Handle CC_Vmode. gcc/testsuite/ChangeLog: * gcc.target/arc/overflow-1.c: New. Signed-off-by: Shahab Vahedi --- gcc/config/arc/arc-modes.def | 1 + gcc/config/arc/arc-protos.h | 1 + gcc/config/arc/arc.cc | 26 +++++- gcc/config/arc/arc.md | 49 +++++++++++ gcc/config/arc/predicates.md | 14 ++- gcc/testsuite/gcc.target/arc/overflow-1.c | 100 ++++++++++++++++++++++ 6 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arc/overflow-1.c diff --git a/gcc/config/arc/arc-modes.def b/gcc/config/arc/arc-modes.def index 763e880317d..69eeec5935a 100644 --- a/gcc/config/arc/arc-modes.def +++ b/gcc/config/arc/arc-modes.def @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see CC_MODE (CC_ZN); CC_MODE (CC_Z); +CC_MODE (CC_V); CC_MODE (CC_C); CC_MODE (CC_FP_GT); CC_MODE (CC_FP_GE); diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h index 4f2db7ffb59..bc78fb0b370 100644 --- a/gcc/config/arc/arc-protos.h +++ b/gcc/config/arc/arc-protos.h @@ -50,6 +50,7 @@ extern bool arc_check_mov_const (HOST_WIDE_INT ); extern bool arc_split_mov_const (rtx *); extern bool arc_can_use_return_insn (void); extern bool arc_split_move_p (rtx *); +extern void arc_gen_unlikely_cbranch (enum rtx_code, machine_mode, rtx); #endif /* RTX_CODE */ extern bool arc_ccfsm_branch_deleted_p (void); diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc index f8c9bf17e2c..ec93d40aeb9 100644 --- a/gcc/config/arc/arc.cc +++ b/gcc/config/arc/arc.cc @@ -1538,6 +1538,13 @@ get_arc_condition_code (rtx comparison) case GEU : return ARC_CC_NC; default : gcc_unreachable (); } + case E_CC_Vmode: + switch (GET_CODE (comparison)) + { + case EQ : return ARC_CC_NV; + case NE : return ARC_CC_V; + default : gcc_unreachable (); + } case E_CC_FP_GTmode: if (TARGET_ARGONAUT_SET && TARGET_SPFP) switch (GET_CODE (comparison)) @@ -1868,7 +1875,7 @@ arc_init_reg_tables (void) /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so we must explicitly check for them here. */ if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode - || i == (int) CC_Cmode + || i == (int) CC_Cmode || i == (int) CC_Vmode || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode || i == CC_FPUmode || i == CC_FPUEmode || i == CC_FPU_UNEQmode) arc_mode_class[i] = 1 << (int) C_MODE; @@ -11852,6 +11859,23 @@ arc_libm_function_max_error (unsigned cfn, machine_mode mode, return default_libm_function_max_error (cfn, mode, boundary_p); } +/* Generate RTL for conditional branch with rtx comparison CODE in mode + CC_MODE. */ + +void +arc_gen_unlikely_cbranch (enum rtx_code cmp, machine_mode cc_mode, rtx label) +{ + rtx cc_reg, x; + + cc_reg = gen_rtx_REG (cc_mode, CC_REG); + label = gen_rtx_LABEL_REF (VOIDmode, label); + + x = gen_rtx_fmt_ee (cmp, VOIDmode, cc_reg, const0_rtx); + x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx); + + emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); +} + #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index d37ecbf4292..9d011f6b4a9 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -2725,6 +2725,55 @@ archs4x, archs4xd" } ") +(define_insn "addsi3_v" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (plus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_V CC_REG) + (compare:CC_V (sign_extend:DI (plus:SI (match_dup 1) + (match_dup 2))) + (plus:DI (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2)))))] + "" + "add.f\\t%0,%1,%2" + [(set_attr "cond" "set") + (set_attr "type" "compare") + (set_attr "length" "4,4,4,8")]) + +(define_expand "addvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_addsi3_v (operands[0], operands[1], operands[2])); + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + DONE;") + +(define_insn "addsi3_c" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (plus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_C CC_REG) + (compare:CC_C (plus:SI (match_dup 1) + (match_dup 2)) + (match_dup 1)))] + "" + "add.f\\t%0,%1,%2" + [(set_attr "cond" "set") + (set_attr "type" "compare") + (set_attr "length" "4,4,4,8")]) + +(define_expand "uaddvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_addsi3_c (operands[0], operands[1], operands[2])); + arc_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); + DONE;") + (define_expand "adddi3" [(set (match_operand:DI 0 "register_operand" "") (plus:DI (match_operand:DI 1 "register_operand" "") diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md index 7650e47694d..9a4ecee9bbd 100644 --- a/gcc/config/arc/predicates.md +++ b/gcc/config/arc/predicates.md @@ -426,6 +426,8 @@ return code == EQ || code == NE; case E_CC_Cmode: return code == LTU || code == GEU; + case E_CC_Vmode: + return code == EQ || code == NE; case E_CC_FP_GTmode: return code == GT || code == UNLE; case E_CC_FP_GEmode: @@ -458,7 +460,12 @@ }) (define_predicate "equality_comparison_operator" - (match_code "eq, ne")) + (match_code "eq, ne") + { + machine_mode opmode = GET_MODE (XEXP (op, 0)); + return opmode != CC_Vmode; + } +) (define_predicate "ge_lt_comparison_operator" (match_code "ge, lt")) @@ -511,7 +518,8 @@ || (mode == CC_ZNmode && rmode == CC_Zmode) || (mode == CCmode && rmode == CC_Zmode) || (mode == CCmode && rmode == CC_ZNmode) - || (mode == CCmode && rmode == CC_Cmode)) + || (mode == CCmode && rmode == CC_Cmode) + || (mode == CCmode && rmode == CC_Vmode)) return TRUE; return FALSE; @@ -531,7 +539,7 @@ if (GET_MODE (op) == CC_ZNmode) return 1; /* Fall through. */ - case E_CC_ZNmode: case E_CC_Cmode: + case E_CC_ZNmode: case E_CC_Cmode: case E_CC_Vmode: return GET_MODE (op) == CCmode; default: gcc_unreachable (); diff --git a/gcc/testsuite/gcc.target/arc/overflow-1.c b/gcc/testsuite/gcc.target/arc/overflow-1.c new file mode 100644 index 00000000000..01b3e8ad0fa --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/overflow-1.c @@ -0,0 +1,100 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +#include +#include + +/* + * add.f r0,r0,r1 + * st_s r0,[r2] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool add_overflow (int32_t a, int32_t b, int32_t *res) +{ + return __builtin_add_overflow (a, b, res); +} + +/* + * add.f r0,r0,-1234 + * st_s r0,[r1] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool addi_overflow (int32_t a, int32_t *res) +{ + return __builtin_add_overflow (a, -1234, res); +} + +/* + * add.f r0,r0,r1 + * st_s r0,[r2] + * mov_s r0,1 + * j_s.d [blink] + * mov.hs r0,0 + */ +bool uadd_overflow (uint32_t a, uint32_t b, uint32_t *res) +{ + return __builtin_add_overflow (a, b, res); +} + +/* + * add.f r2,r0, 4321 + * seths r0,r0,-4321 + * j_s.d [blink] + * st_s r2,[r1] + */ +bool uaddi_overflow (uint32_t a, uint32_t *res) +{ + return __builtin_add_overflow (a, 4321, res); +} + +/* + * add.f r0,r0,r1 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool add_overflow_p (int32_t a, int32_t b, int32_t res) +{ + return __builtin_add_overflow_p (a, b, res); +} + +/* + * add.f r0,r0,-1000 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool addi_overflow_p (int32_t a, int32_t res) +{ + return __builtin_add_overflow_p (a, -1000, res); +} + +/* + * add.f 0,r0,r1 + * mov_s r0,1 + * j_s.d [blink] + * mov.hs r0,0 + */ +bool uadd_overflow_p (uint32_t a, uint32_t b, uint32_t res) +{ + return __builtin_add_overflow_p (a, b, res); +} + +/* + * j_s.d [blink] + * seths r0,r0,-2000 + */ +bool uaddi_overflow_p (uint32_t a, uint32_t res) +{ + return __builtin_add_overflow_p (a, 2000, res); +} + +/* { dg-final { scan-assembler-times "add.f\\s\+" 7 } } */ +/* { dg-final { scan-assembler-times "mov\.nv\\s\+" 4 } } */ +/* { dg-final { scan-assembler-times "mov\.hs\\s\+" 2 } } */ +/* { dg-final { scan-assembler-times "seths\\s\+" 2 } } */ +/* { dg-final { scan-assembler-not "cmp" } } */ -- 2.42.0