From patchwork Wed Sep 11 13:17:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joshi X-Patchwork-Id: 1160965 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-508850-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="LTpTbTX8"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LvU3wtqA"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46T2NQ00bkz9s4Y for ; Wed, 11 Sep 2019 23:11:33 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=lsyZOCJIYwV3dcFNNr2M+FMaSuMB1NDm7GQz6a3li8q rLmPODemaS2d6BaLDc2tmLp4bOwyiQjwwnyo9qPvG8jGLdo9xoQ7p079mtUsn0/6 wV36AaEjw1T5e46gGN3JeSGlgkB2jJ3Itu/ShqYdaZ5OoPmCG7kNvQ5jPYdj8IdI = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=QxcoGdg4jcCWVhlBN3JAYw0WHTg=; b=LTpTbTX8Xz7IEPfns cTon0REMC2s6yLEE/g54u8+wt9Xx+AxjQbRf8qq9ROhd6zCfiCyXwrrzghI/E+cf ynP6xUJDAB6IU60bBiZZb8pvI3wsTJFgBt770b2EjIfPhpKWX5oWbXXgvgW1RP9A sRu1dqZrwFOCplT3iZV+BCoxsQ= Received: (qmail 92086 invoked by alias); 11 Sep 2019 13:11:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 92077 invoked by uid 89); 11 Sep 2019 13:11:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=0.8, 08, Builtin X-HELO: mail-ed1-f41.google.com Received: from mail-ed1-f41.google.com (HELO mail-ed1-f41.google.com) (209.85.208.41) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 11 Sep 2019 13:11:24 +0000 Received: by mail-ed1-f41.google.com with SMTP id z9so20563794edq.8 for ; Wed, 11 Sep 2019 06:11:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=SIxderqpLMYxp4ifSO0g3ZFJHRADQHYplsqjmpIkA5o=; b=LvU3wtqAp79R8IXbqsJWexOnx7nCW7P0+QnJOH6NQpMGkXa80wXUz3ohT/EXMi6Fgt LfBk7GG0HA34I61DsnayfC/SUxfdgRqpx4LSoEsLvjNRM9z8IoQaQAd+mDF6murI9KK9 5YK64+ycDiypzHL8dJ8/FcUNQUbls/yPDPkt84VLUgox8N6ZJrE21bAFcMN8ASJ5m/In YwfcIEuOuT/aARMTdOl6iq5wHF1hizGu9t+i2gVdE/Hu89q4IFbZUvaHsF2baeQZpzQc MVoDbD4jFOHD4PRPPSdZegGsB55QNVC8RvMBuAqRT4j1Bfc9Wgh0PDSxpg79Uk81x7Au QRAA== MIME-Version: 1.0 From: Tejas Joshi Date: Wed, 11 Sep 2019 18:47:56 +0530 Message-ID: Subject: [PATCH] Builtin fadd variants folding implementation To: gcc-patches@gcc.gnu.org Cc: joseph@codesourcery.com, Martin Jambor Hi. This patch includes implementation of fadd, faddl, daddl functions. The patch boostraps on x86_64-linux-gnu and passes regression tests. Thanks, Tejas gcc/ChangeLog: 2019-09-11 Tejas Joshi * builtin-types.def: Define narrowing function types. * builtins.def: Define fadd variants builtin functions. * fold-const-call.c (fold_const_narrow_binary): New. Folding calls and conditions for standard arithmetic functions. (fold_const_call): Add case for fadd variants. gcc/testsuite/ChangeLog: 2019-09-11 Tejas Joshi * gcc.dg/builtin-fadd-1.c: New test. * gcc.dg/builtin-fadd-2.c: New test. * gcc.dg/builtin-fadd-3.c: New test. * gcc.dg/builtin-fadd-4.c: New test. * gcc.dg/builtin-fadd-5.c: New test. * gcc.dg/builtin-fadd-6.c: New test. diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index e5c9e063c48..6bc552fa71a 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -387,8 +387,14 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_PTR, BT_VOID, BT_UINT, BT_PTR) DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOAT, BT_FLOAT, BT_FLOAT, BT_FLOAT) +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_DOUBLE_DOUBLE, + BT_FLOAT, BT_DOUBLE, BT_DOUBLE) +DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_LONGDOUBLE_LONGDOUBLE, + BT_FLOAT, BT_LONGDOUBLE, BT_LONGDOUBLE) DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_DOUBLE) +DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_LONGDOUBLE_LONGDOUBLE, + BT_DOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE) DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE) DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT16_FLOAT16_FLOAT16, diff --git a/gcc/builtins.def b/gcc/builtins.def index 8bb7027aac7..2df616c477e 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -355,6 +355,9 @@ DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, ATTR_CONST_NOT DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FADD, "fadd", BT_FN_FLOAT_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FADDL, "faddl", BT_FN_FLOAT_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_DADDL, "daddl", BT_FN_DOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index 3a14d2a41c1..f6b4508a101 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -570,6 +570,44 @@ fold_const_nextafter (real_value *result, const real_value *arg0, return true; } +/* Try to evaluate: + + *RESULT = add (*ARG0, *ARG1) + + in format FORMAT. Return true on success. */ + +static bool +fold_const_narrow_binary (real_value *result, const real_value *arg0, + int icode, const real_value *arg1, + const real_format *format) +{ + if (REAL_VALUE_ISSIGNALING_NAN (*arg0) + || REAL_VALUE_ISSIGNALING_NAN (*arg1)) + return false; + + real_arithmetic (result, icode, arg0, arg1); + /* Underflow condition. */ + if (flag_errno_math + && result->cl == rvc_normal + && REAL_EXP (result) < format->emin) + return false; + + if (!exact_real_truncate (format, result) + && (flag_rounding_math || flag_trapping_math)) + return false; + + real_convert (result, format, result); + /* Overflow condition. */ + if (!real_isfinite (result) && flag_errno_math) + return false; + + if (REAL_VALUE_ISNAN (*result) + && (flag_errno_math || flag_trapping_math)) + return false; + + return true; +} + /* Try to evaluate: *RESULT = ldexp (*ARG0, ARG1) @@ -1674,6 +1712,25 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1) case CFN_FOLD_LEFT_PLUS: return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR); + case CFN_BUILT_IN_FADD: + case CFN_BUILT_IN_FADDL: + case CFN_BUILT_IN_DADDL: + { + if (real_cst_p (arg0) + && real_cst_p (arg1)) + { + machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0)); + gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode)); + REAL_VALUE_TYPE result; + machine_mode mode = TYPE_MODE (type); + if (fold_const_narrow_binary (&result, TREE_REAL_CST_PTR (arg0), + PLUS_EXPR, TREE_REAL_CST_PTR (arg1), + REAL_MODE_FORMAT (mode))) + return build_real (type, result); + } + } + return NULL_TREE; + default: return fold_const_call_1 (fn, type, arg0, arg1); } diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-1.c b/gcc/testsuite/gcc.dg/builtin-fadd-1.c new file mode 100644 index 00000000000..66280e9f72b --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-fadd-1.c @@ -0,0 +1,54 @@ +/* { dg-do link } */ +/* { dg-options "-O2 -fno-trapping-math" } */ + +extern int link_error (int); + +#define TEST(FN, VAL1, VAL2, RESULT) \ + if (__builtin_##FN (VAL1, VAL2) != RESULT) link_error (__LINE__); + +int +main (void) +{ + TEST(fadd, 0, 0, 0.0F); + TEST(fadd, 1, -1, 0.0F); + TEST(fadd, -1, -1.5, -2.5F); + TEST(fadd, 1.4, 1.6, 3.0F); + TEST(fadd, 2.5, 1.5, 4.0F); + + TEST(fadd, 1, 1.1, 2.1F); + TEST(fadd, 2, 4.3, 6.3F); + TEST(fadd, -3, -3.6, -6.6F); + TEST(fadd, 8, 0.8, 8.8F); + + if (__builtin_fadd (0x1.000001p0, __FLT_MIN__) + == (float) (0x1.000001p0 + __FLT_MIN__)) + link_error (__LINE__); + + TEST(faddl, 0.0L, 0.0L, 0.0F); + TEST(faddl, 1.0L, -1.0L, 0.0F); + TEST(faddl, -1.0L, -1.5L, -2.5F); + TEST(faddl, 1.4L, 1.6L, 3.0F); + TEST(faddl, 2.5L, 1.5L, 4.0F); + + TEST(faddl, 1.0L, 1.1L, 2.1F); + TEST(faddl, 2.0L, 4.3L, 6.3F); + TEST(faddl, -3.0L, -3.6L, -6.6F); + TEST(faddl, 8.0L, 0.8L, 8.8F); + + if (__builtin_faddl (0x1.000001p0, __FLT_MIN__) + == (float) (0x1.000001p0 + __FLT_MIN__)) + link_error (__LINE__); + + TEST(daddl, 0L, 0L, 0.0); + TEST(daddl, 1.0L, -1.0L, 0.0); + TEST(daddl, -1.0L, -1.5L, -2.5); + TEST(daddl, 1.4L, 1.6L, 3.0); + TEST(daddl, 2.5L, 1.5L, 4.0); + + TEST(daddl, 1.0L, 1.1L, 2.1); + TEST(daddl, 2.0L, 4.3L, 6.3); + TEST(daddl, -3.0L, -3.6L, -6.6); + TEST(daddl, 8.0L, 0.8L, 8.8); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-2.c b/gcc/testsuite/gcc.dg/builtin-fadd-2.c new file mode 100644 index 00000000000..006f1c6d21b --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-fadd-2.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ + +#define TEST(FN, VAL1, VAL2, RESULT) \ + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); + +int +main (void) +{ + TEST(fadd, 1, 1.1, 2.1F); + TEST(fadd, 2, 4.3, 6.3F); + TEST(fadd, -3, -3.6, -6.6F); + TEST(fadd, 8, 0.8, 8.8F); + + TEST(faddl, 1.0L, 1.1L, 2.1F); + TEST(faddl, 2.0L, 4.3L, 6.3F); + TEST(faddl, -3.0L, -3.6L, -6.6F); + TEST(faddl, 8.0L, 0.8L, 8.8F); + + TEST(daddl, 1.0L, 1.1L, 2.1); + TEST(daddl, 2.0L, 4.3L, 6.3); + TEST(daddl, -3.0L, -3.6L, -6.6); + TEST(daddl, 8.0L, 0.8L, 8.8); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-3.c b/gcc/testsuite/gcc.dg/builtin-fadd-3.c new file mode 100644 index 00000000000..dd8a2040cb7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-fadd-3.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-trapping-math -frounding-math -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ + +#define TEST(FN, VAL1, VAL2, RESULT) \ + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); + +#include "builtin-fadd-2.c" diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-4.c b/gcc/testsuite/gcc.dg/builtin-fadd-4.c new file mode 100644 index 00000000000..9091be49b9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-fadd-4.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -frounding-math -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ + +#define TEST(FN, VAL1, VAL2, RESULT) \ + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); + +#include "builtin-fadd-2.c" diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-5.c b/gcc/testsuite/gcc.dg/builtin-fadd-5.c new file mode 100644 index 00000000000..ac3b547724c --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-fadd-5.c @@ -0,0 +1,26 @@ +/* { dg-do link } */ +/* { dg-options "-O2 -fno-trapping-math -fno-math-errno" } */ + +extern int link_error (int); + +#define TEST(FN, VAL1, VAL2, RESULT) \ + if (__builtin_##FN (VAL1, VAL2) != RESULT) link_error (__LINE__); + +int +main (void) +{ + TEST(fadd, __DBL_MAX__, __DBL_MAX__, __builtin_inff()); + TEST(fadd, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); + TEST(fadd, __DBL_MIN__, __DBL_MIN__, 0.0); + + TEST(faddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inff()); + TEST(faddl, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); + TEST(faddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); + + TEST(daddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inf()); + TEST(daddl, __DBL_MAX__, __DBL_MAX__, __builtin_inf()); + TEST(daddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/builtin-fadd-6.c b/gcc/testsuite/gcc.dg/builtin-fadd-6.c new file mode 100644 index 00000000000..11c63f06463 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-fadd-6.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-trapping-math -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump "fadd" "optimized" } } */ +/* { dg-final { scan-tree-dump "faddl" "optimized" } } */ +/* { dg-final { scan-tree-dump "daddl" "optimized" } } */ + +#define TEST(FN, VAL1, VAL2, RESULT) \ + if (__builtin_##FN (VAL1, VAL2) != RESULT) __builtin_abort (); + +int +main (void) +{ + TEST(fadd, __DBL_MAX__, __DBL_MAX__, __builtin_inff()); + TEST(fadd, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); + TEST(fadd, __DBL_MIN__, __DBL_MIN__, 0.0); + + TEST(faddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inff()); + TEST(faddl, __FLT_MAX__, __FLT_MAX__, __builtin_inff()); + TEST(faddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); + + TEST(daddl, __LDBL_MAX__, __LDBL_MAX__, __builtin_inf()); + TEST(daddl, __DBL_MAX__, __DBL_MAX__, __builtin_inf()); + TEST(daddl, __LDBL_MIN__, __LDBL_MIN__, 0.0); + + return 0; +} +