From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sourceware.org (Postfix) with ESMTPS id 767B33846027 for ; Thu, 3 Jun 2021 10:22:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 767B33846027 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=inria.fr Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=inria.fr IronPort-HdrOrdr: =?us-ascii?q?A9a23=3Axf3Sra9sZSDgp+zvKoJuk+C7I+orL9Y04lQ7?= =?us-ascii?q?vn2ZhyY7TiX2rauTdZgguCMczQx+ZJhfo7q90cC7KBvhHNxOgbX5Vo3CYOCJgg?= =?us-ascii?q?eVEL0=3D?= X-IronPort-AV: E=Sophos;i="5.83,244,1616454000"; d="scan'208";a="383324997" Received: from tomate.loria.fr (HELO tomate) ([152.81.10.51]) by mail3-relais-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Jun 2021 12:21:47 +0200 Date: Thu, 03 Jun 2021 12:21:46 +0200 Message-Id: From: Paul Zimmermann To: Jeff Johnston Cc: joel@rtems.org, newlib@sourceware.org In-Reply-To: (message from Jeff Johnston on Wed, 2 Jun 2021 23:01:53 -0400) Subject: Re: incorrectly rounded square root References: <2f8796f4-f164-5734-16ca-9a392e788beb@gmail.com> X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: newlib@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Newlib mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Jun 2021 10:22:19 -0000 Hi Jeff, I've investigated and found (partially) the cause of the problem. When I compile my program, gcc uses the system fenv.h, which contains FE_TONEAREST=0, FE_DOWNWARD=0x400, FE_UPWARD=0x800, and FE_TOWARDZERO=0xc00 in /usr/include/bits/fenv.h. However, the values in x86_64/newlib/targ-include/sys/fenv.h are different: FE_TONEAREST=0, FE_DOWNWARD=1, FE_UPWARD=2, FE_TOWARDZERO=3. Thus the test at the beginning of fesetround in newlib/libm/machine/x86_64/fenv.c fails except for round=FE_TONEAREST: /* Will succeed for any valid value of the input parameter. */ if (round < FE_TONEAREST || round > FE_TOWARDZERO) return EINVAL; enter fesetround, round=0 use_sse=1 enter fesetround, round=3072 use_sse=1 enter fesetround, round=2048 use_sse=1 enter fesetround, round=1024 use_sse=1 This explains why the other modes are not set. A first question is why Newlib and the system libm (here glibc) use different constants for the rounding modes. Now if I compile with -I/tmp/x86_64/include (where the Newlib fenv.h is installed) I get: enter fesetround, round=0 use_sse=1 enter fesetround, round=3 use_sse=1 enter fesetround, round=2 use_sse=1 enter fesetround, round=1 use_sse=1 but I still do get the same results whatever the rounding mode! If I look at the cw and mxcsr registers like in Newlib fenv.c, I get with glibc (after the fesetround call): fegetround: 0 cw=895 mxcsr=8064 RNDN: 0x1.ff83fp+63 fegetround: 3072 cw=3967 mxcsr=32672 RNDZ: 0x1.ff83eep+63 fegetround: 2048 cw=2943 mxcsr=24480 RNDU: 0x1.ff83fp+63 fegetround: 1024 cw=1919 mxcsr=16288 RNDD: 0x1.ff83eep+63 and with Newlib: fegetround: 0 cw=895 mxcsr=8064 RNDN: 0x1.ff83fp+63 fegetround: 3 cw=3967 mxcsr=32640 RNDZ: 0x1.ff83fp+63 fegetround: 2 cw=2943 mxcsr=24448 RNDU: 0x1.ff83fp+63 fegetround: 1 cw=1919 mxcsr=16256 RNDD: 0x1.ff83fp+63 The cw values do match but not the mxcsr values. Best regards, Paul > Something weird is going on. I condensed the newlib code into the > following files and when I compile and run the test, > it works as expected: > > gcc -std=c99 -g3 -O0 test_sqrt.c fesetround.c ef_sqrt.c > [jjohnstn@localhost shared_x86]$ ./a.out > RNDN: 0x1.ff83fp+63 > RNDZ: 0x1.ff83eep+63 > RNDU: 0x1.ff83fp+63 > RNDD: 0x1.ff83eep+63 > > Can you verify that you are calling the fesetround in fenv.c and what > configuration call did you use for building newlib?