From patchwork Tue Jul 26 15:23:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 652805 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rzMNM2vVNz9t0M for ; Wed, 27 Jul 2016 01:24:02 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=t77vk5vz; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:mime-version:content-type:message-id; q=dns; s=default; b=xC8rtbwPzP4coM1270xntSPDbO0dKi4c/KkuF9RZKAFeumGsJg E6oXu5bUXDBNFbg574k1hy6ZdeCf97WGSWIgUtXbhMVabfM5/1xNKlJNj0+I2rhF oAkiwJxUqtb6qzRbig4FdWqKOkL053wDo4jbietwpWWsXtr7wBIQx0stQ= 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:date :from:to:cc:subject:mime-version:content-type:message-id; s= default; bh=MvNib002SNN0E0RP1xo09wfdt+8=; b=t77vk5vzJVg0U9ZQmN7l UBpH08eNP+Y3d4TPYmmvGRGb2FEOGEGuIi4i8P1qawdVOhzZMG6cVVDAQnmkxoBV cuVVLam6tqMHFnxf2eLyaa+aQ0Ur/gHcZgN/chfa9wd9EzU9f0qLSRl2SrguJ9ui mMGRb2TruSFZfQvv7w3QeH4= Received: (qmail 43564 invoked by alias); 26 Jul 2016 15:23:49 -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 43535 invoked by uid 89); 26 Jul 2016 15:23:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.0 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 spammy=King, mandated, powerpc*-*-linux*, Join X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 26 Jul 2016 15:23:47 +0000 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u6QFJL1A102074 for ; Tue, 26 Jul 2016 11:23:44 -0400 Received: from e38.co.us.ibm.com (e38.co.us.ibm.com [32.97.110.159]) by mx0a-001b2d01.pphosted.com with ESMTP id 24dvp77g78-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 26 Jul 2016 11:23:44 -0400 Received: from localhost by e38.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 26 Jul 2016 09:23:43 -0600 Received: from d03dlp02.boulder.ibm.com (9.17.202.178) by e38.co.us.ibm.com (192.168.1.138) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 26 Jul 2016 09:23:41 -0600 X-IBM-Helo: d03dlp02.boulder.ibm.com X-IBM-MailFrom: meissner@ibm-tiger.the-meissners.org Received: from b01cxnp23034.gho.pok.ibm.com (b01cxnp23034.gho.pok.ibm.com [9.57.198.29]) by d03dlp02.boulder.ibm.com (Postfix) with ESMTP id 6119D3E4003E; Tue, 26 Jul 2016 09:23:40 -0600 (MDT) Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp23034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u6QFNbt011469306; Tue, 26 Jul 2016 15:23:43 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DD6B95E005; Tue, 26 Jul 2016 11:23:39 -0400 (EDT) Received: from ibm-tiger.the-meissners.org (unknown [9.32.77.111]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP id B7C8C11206F; Tue, 26 Jul 2016 11:23:39 -0400 (EDT) Received: by ibm-tiger.the-meissners.org (Postfix, from userid 500) id 20CF046CED; Tue, 26 Jul 2016 11:23:38 -0400 (EDT) Date: Tue, 26 Jul 2016 11:23:38 -0400 From: Michael Meissner To: gcc-patches@gcc.gnu.org, Segher Boessenkool , David Edelsohn , Bill Schmidt , Richard Biener , Jakub Jelinek Cc: murphyp@linux.vnet.ibm.com Subject: [PATCH], Fix PR 71869, Correctly implement isgreater, etc. on PowerPC __float128 Mail-Followup-To: Michael Meissner , gcc-patches@gcc.gnu.org, Segher Boessenkool , David Edelsohn , Bill Schmidt , Richard Biener , Jakub Jelinek , murphyp@linux.vnet.ibm.com MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16072615-0028-0000-0000-0000053EAFDF X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16072615-0029-0000-0000-00002DDC58ED Message-Id: <20160726152338.GA7191@ibm-tiger.the-meissners.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-07-26_10:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1607260166 X-IsSubscribed: yes When I originally developed the IEEE 128-bit floating point support, the emulation routines in libgcc did not raise errors on signalling NaNs. In the course of adding full support for IEEE 128-bit floating point, we now have added exception signaling support in the library. This means the C99/IEEE built-in functions isgreater, isgreaterequal, isless, islessequal, and islessgreater now will raise an error when you compare a signaling NaN. These functions are mandated not to raise an error. These patches add calls to __unordkf3 to validate that both arguments are ordered before calling the ge/le/eq comparison function. I have done bootstraps and make check on both little endian Power8 and big endian Power7 (both 32-bit and 64-bit tests done on the Power7 box) with no regressions. Are these patches ok for the trunk? In addition, since the glibc group needs this functionality to complete the __float128 library support, I would like to get it into GCC 6.2 if it is still possible. I know this is last minute, but this patch is important to the GLIBC group, and it was only noticed recently. I will be starting the bootstrap and regression test on the gcc6 branch shortly. If the patch works on gcc6, can I commit it to the gcc6 branch ASAP, or will it have to wait for GCC 6.3? [gcc] 2016-07-25 Michael Meissner PR target/71869 * config/rs6000/rs6000.c (rs6000_generate_compare): Rework __float128 support when we don't have hardware support, so that the IEEE built-in functions like isgreater, first call __unordkf3 to make sure neither operand is a NaN, and if both operands are ordered, do the normal comparison. [gcc/testsuite] 2016-07-25 Michael Meissner PR target/71869 * gcc.target/powerpc/float128-cmp.c: New test to make sure that IEEE built-in functions first check to see if the arguments are ordered. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 238730) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -21755,8 +21755,8 @@ rs6000_generate_compare (rtx cmp, machin else if (!TARGET_FLOAT128_HW && FLOAT128_VECTOR_P (mode)) { rtx libfunc = NULL_RTX; - bool uneq_or_ltgt = false; - rtx dest = gen_reg_rtx (SImode); + bool check_nan = false; + rtx dest; switch (code) { @@ -21783,21 +21783,23 @@ rs6000_generate_compare (rtx cmp, machin case UNGE: case UNGT: - libfunc = optab_libfunc (le_optab, mode); + check_nan = true; + libfunc = optab_libfunc (ge_optab, mode); code = (code == UNGE) ? GE : GT; break; case UNLE: case UNLT: - libfunc = optab_libfunc (ge_optab, mode); + check_nan = true; + libfunc = optab_libfunc (le_optab, mode); code = (code == UNLE) ? LE : LT; break; case UNEQ: case LTGT: - libfunc = optab_libfunc (le_optab, mode); - uneq_or_ltgt = true; - code = (code = UNEQ) ? NE : EQ; + check_nan = true; + libfunc = optab_libfunc (eq_optab, mode); + code = (code = UNEQ) ? EQ : NE; break; default: @@ -21805,21 +21807,56 @@ rs6000_generate_compare (rtx cmp, machin } gcc_assert (libfunc); - dest = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, - SImode, 2, op0, mode, op1, mode); - /* If this is UNEQ or LTGT, we call __lekf2, which returns -1 for less - than, 0 for equal, +1 for greater, and +2 for nan. We add 1, to give - a value of 0..3, and then do and AND immediate of 1 to isolate whether - it is 0/Nan (i.e. bottom bit is 0), or less than/greater than - (i.e. bottom bit is 1). */ - if (uneq_or_ltgt) - { - rtx add_result = gen_reg_rtx (SImode); - rtx and_result = gen_reg_rtx (SImode); - emit_insn (gen_addsi3 (add_result, dest, GEN_INT (1))); - emit_insn (gen_andsi3 (and_result, add_result, GEN_INT (1))); - dest = and_result; + if (!check_nan) + dest = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, + SImode, 2, op0, mode, op1, mode); + + /* The library signals an exception for signalling NaNs, so we need to + handle isgreater, etc. by first checking isordered. */ + else + { + rtx ne_rtx, normal_dest, unord_dest; + rtx unord_func = optab_libfunc (unord_optab, mode); + rtx join_label = gen_label_rtx (); + rtx join_ref = gen_rtx_LABEL_REF (VOIDmode, join_label); + rtx unord_cmp = gen_reg_rtx (comp_mode); + + + /* Test for either value being a NaN. */ + gcc_assert (unord_func); + unord_dest = emit_library_call_value (unord_func, NULL_RTX, LCT_CONST, + SImode, 2, op0, mode, op1, + mode); + + /* Set value (0) if either value is a NaN, and jump to the join + label. */ + dest = gen_reg_rtx (SImode); + emit_move_insn (dest, const1_rtx); + emit_insn (gen_rtx_SET (unord_cmp, + gen_rtx_COMPARE (comp_mode, unord_dest, + const0_rtx))); + + ne_rtx = gen_rtx_NE (comp_mode, unord_cmp, const0_rtx); + emit_jump_insn (gen_rtx_SET (pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, ne_rtx, + join_ref, + pc_rtx))); + + /* Do the normal comparison, knowing that the values are not + NaNs. */ + normal_dest = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, + SImode, 2, op0, mode, op1, + mode); + + emit_insn (gen_cstoresi4 (dest, + gen_rtx_fmt_ee (code, SImode, normal_dest, + const0_rtx), + normal_dest, const0_rtx)); + + /* Join NaN and non-Nan paths. Compare dest against 0. */ + emit_label (join_label); + code = NE; } emit_insn (gen_rtx_SET (compare_result, Index: gcc/testsuite/gcc.target/powerpc/float128-cmp.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-cmp.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-cmp.c (revision 0) @@ -0,0 +1,17 @@ +/* { dg-do compile { target { powerpc*-*-linux* } } } */ +/* { dg-require-effective-target powerpc_float128_sw_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ +/* { dg-options "-O2 -mcpu=power7 -mfloat128" } */ + +#ifndef __FLOAT128__ +#error "-mfloat128 is not supported." +#endif + +int +test_isgreater (__float128 a, __float128 b) +{ + return __builtin_isgreater (a, b); +} + +/* { dg-final { scan-assembler "bl __\[gl\]ekf2" } } */ +/* { dg-final { scan-assembler "bl __unordkf2" } } */