From patchwork Thu Jul 19 21:46:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 172084 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id C7E412C010E for ; Fri, 20 Jul 2012 07:47:03 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1343339226; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Received:Received:Date:From:To:Subject: Message-Id:Mime-Version:Content-Type:Content-Transfer-Encoding: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=d+8qtrq792iCLkU8611+ w+r4TrY=; b=VMsOJ78QGUQpvNMeSNa1ksK+c9Hj5i9r+TIP7Wts+58z/nCQIG8S PlDt8vnyW6OKaALrEMt7TQc3cVDQHmv4uLCb1g+LJkJ9k/XNVNhA+ynD+8GZy/bP OFDqfP3PerP67iSnMclu/HEhxeL1yGR1kg/vsXE5g9toT32BMJPPvRo= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Received:Received:Date:From:To:Subject:Message-Id:Mime-Version:Content-Type:Content-Transfer-Encoding:X-Content-Scanned:x-cbid:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=SXMBQOqyU2aAfFi4Zkuhs5Qb+5OMARq9LvhO+LsPlCzqsHjXJixT1ToihQpnA5 cBs9tSM5E9E3wTWa9VEq9V5nemlqaumGSSXChDcuR38+UpYak9VZWBHBY0suOmdN P1z+13cWDwptVMifOhKfjkEZ11Q12sIoE7J4VVvJkr8KA=; Received: (qmail 30044 invoked by alias); 19 Jul 2012 21:46:59 -0000 Received: (qmail 30035 invoked by uid 22791); 19 Jul 2012 21:46:58 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, SPF_SOFTFAIL, TW_DF, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e9.ny.us.ibm.com (HELO e9.ny.us.ibm.com) (32.97.182.139) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 19 Jul 2012 21:46:45 +0000 Received: from /spool/local by e9.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 19 Jul 2012 17:46:23 -0400 Received: from d01dlp03.pok.ibm.com (9.56.224.17) by e9.ny.us.ibm.com (192.168.1.109) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 19 Jul 2012 17:46:21 -0400 Received: from d01relay04.pok.ibm.com (d01relay04.pok.ibm.com [9.56.227.236]) by d01dlp03.pok.ibm.com (Postfix) with ESMTP id 829DAC9001D for ; Thu, 19 Jul 2012 17:46:20 -0400 (EDT) Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay04.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6JLkJeZ202220 for ; Thu, 19 Jul 2012 17:46:20 -0400 Received: from d01av01.pok.ibm.com (loopback [127.0.0.1]) by d01av01.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q6K3H3Z2009298 for ; Thu, 19 Jul 2012 23:17:03 -0400 Received: from otta ([9.49.211.191]) by d01av01.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id q6K3H17J009199; Thu, 19 Jul 2012 23:17:02 -0400 Date: Thu, 19 Jul 2012 16:46:07 -0500 From: Peter Bergner To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix PR C++/54036, problem negating DFP NaNs Message-Id: <20120719164607.0d1ffd1f03762f7f3bb5bf21@vnet.ibm.com> Mime-Version: 1.0 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12071921-7182-0000-0000-00000208BFEF X-IsSubscribed: yes 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 When negating a DFP NaN in C++, we produce another NaN and not a -NaN like we do when using a C test case or with binary floating point (C or C++). This happens on both my power64-linux and x86_64-linux systems. bergner@bns:~> cat dfp-nan.C #include #include using namespace std; decimal::decimal64 my_nan (void) { decimal::decimal64 z = 0.0DD; decimal::decimal64 v = z/z; return v; } int main (void) { decimal::decimal64 v; v = my_nan (); printf ("value is %Dg\n", v); v = -v; printf ("-value is %Dg\n", v); return 0; } bergner@bns:~> g++ dfp-nan.C -ldfp bergner@bns:~> ./a.out value is nan -value is nan The problem is that the decimal class implementing unary operators uses binary operations, so a -nan is computed with a "0 - nan" which does not produce a -nan. The patch below fixes the problem for me and passes bootstrap and regtesting on powerpc64-linux. Ok for mainline? The same problem exists in 4.7 and 4.6, is this patch ok for the release branches too assuming my testing there passes without problems? Peter libstdc++-v3/ PR c++/54036 * include/decimal/decimal.h (_DEFINE_DECIMAL_UNARY_OP): Use _Op as a unary operator. gcc/testsuite/ PR c++/54036 * g++.dg/dfp/pr54036-1.C: New test. * g++.dg/dfp/pr54036-2.C: Likewise. * g++.dg/dfp/pr54036-3.C: Likewise. Index: libstdc++-v3/include/decimal/decimal.h =================================================================== --- libstdc++-v3/include/decimal/decimal.h (revision 189599) +++ libstdc++-v3/include/decimal/decimal.h (working copy) @@ -288,7 +288,7 @@ inline _Tp operator _Op(_Tp __rhs) \ { \ _Tp __tmp; \ - __tmp.__setval(0 _Op __rhs.__getval()); \ + __tmp.__setval(_Op __rhs.__getval()); \ return __tmp; \ } Index: gcc/testsuite/g++.dg/dfp/pr54036-1.C =================================================================== --- gcc/testsuite/g++.dg/dfp/pr54036-1.C (revision 0) +++ gcc/testsuite/g++.dg/dfp/pr54036-1.C (revision 0) @@ -0,0 +1,56 @@ +#include +using namespace std; + +decimal::decimal32 +__attribute__ ((noinline)) +my_nan32 (void) +{ + decimal::decimal32 z = 0; + decimal::decimal32 v = z/z; + return v; +} + +decimal::decimal32 +__attribute__ ((noinline)) +my_inf32 (void) +{ + decimal::decimal32 o = 1; + decimal::decimal32 z = 0; + decimal::decimal32 v = o/z; + return v; +} + +int +main (void) +{ + decimal::decimal32 v; + + v = my_nan32 (); + if (!__builtin_isnand32 (v.__getval ())) + __builtin_abort (); + if (__builtin_signbitd32 (v.__getval ())) + __builtin_abort (); + + v = -v; + + if (!__builtin_isnand32 (v.__getval ())) + __builtin_abort (); + if (!__builtin_signbitd32 (v.__getval ())) + __builtin_abort (); + + v = my_inf32 (); + if (!__builtin_isinfd32 (v.__getval ())) + __builtin_abort (); + if (__builtin_signbitd32 (v.__getval ())) + __builtin_abort (); + + v = -v; + + if (!__builtin_isinfd32 (v.__getval ())) + __builtin_abort (); + if (!__builtin_signbitd32 (v.__getval ())) + __builtin_abort (); + + return 0; +} + Index: gcc/testsuite/g++.dg/dfp/pr54036-2.C =================================================================== --- gcc/testsuite/g++.dg/dfp/pr54036-2.C (revision 0) +++ gcc/testsuite/g++.dg/dfp/pr54036-2.C (revision 0) @@ -0,0 +1,56 @@ +#include +using namespace std; + +decimal::decimal64 +__attribute__ ((noinline)) +my_nan64 (void) +{ + decimal::decimal64 z = 0; + decimal::decimal64 v = z/z; + return v; +} + +decimal::decimal64 +__attribute__ ((noinline)) +my_inf64 (void) +{ + decimal::decimal64 o = 1; + decimal::decimal64 z = 0; + decimal::decimal64 v = o/z; + return v; +} + +int +main (void) +{ + decimal::decimal64 v; + + v = my_nan64 (); + if (!__builtin_isnand64 (v.__getval ())) + __builtin_abort (); + if (__builtin_signbitd64 (v.__getval ())) + __builtin_abort (); + + v = -v; + + if (!__builtin_isnand64 (v.__getval ())) + __builtin_abort (); + if (!__builtin_signbitd64 (v.__getval ())) + __builtin_abort (); + + v = my_inf64 (); + if (!__builtin_isinfd64 (v.__getval ())) + __builtin_abort (); + if (__builtin_signbitd64 (v.__getval ())) + __builtin_abort (); + + v = -v; + + if (!__builtin_isinfd64 (v.__getval ())) + __builtin_abort (); + if (!__builtin_signbitd64 (v.__getval ())) + __builtin_abort (); + + return 0; +} + Index: gcc/testsuite/g++.dg/dfp/pr54036-3.C =================================================================== --- gcc/testsuite/g++.dg/dfp/pr54036-3.C (revision 0) +++ gcc/testsuite/g++.dg/dfp/pr54036-3.C (revision 0) @@ -0,0 +1,56 @@ +#include +using namespace std; + +decimal::decimal128 +__attribute__ ((noinline)) +my_nan128 (void) +{ + decimal::decimal128 z = 0; + decimal::decimal128 v = z/z; + return v; +} + +decimal::decimal128 +__attribute__ ((noinline)) +my_inf128 (void) +{ + decimal::decimal128 o = 1; + decimal::decimal128 z = 0; + decimal::decimal128 v = o/z; + return v; +} + +int +main (void) +{ + decimal::decimal128 v; + + v = my_nan128 (); + if (!__builtin_isnand128 (v.__getval ())) + __builtin_abort (); + if (__builtin_signbitd128 (v.__getval ())) + __builtin_abort (); + + v = -v; + + if (!__builtin_isnand128 (v.__getval ())) + __builtin_abort (); + if (!__builtin_signbitd128 (v.__getval ())) + __builtin_abort (); + + v = my_inf128 (); + if (!__builtin_isinfd128 (v.__getval ())) + __builtin_abort (); + if (__builtin_signbitd128 (v.__getval ())) + __builtin_abort (); + + v = -v; + + if (!__builtin_isinfd128 (v.__getval ())) + __builtin_abort (); + if (!__builtin_signbitd128 (v.__getval ())) + __builtin_abort (); + + return 0; +} +