From patchwork Fri Mar 20 09:12:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 132009 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id C0DE84B1A29C for ; Fri, 20 Mar 2026 09:15:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C0DE84B1A29C Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=xry111.site header.i=@xry111.site header.a=rsa-sha256 header.s=default header.b=F6bk/cOt X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 110034B1A2F9 for ; Fri, 20 Mar 2026 09:14:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 110034B1A2F9 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 110034B1A2F9 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773998095; cv=none; b=bhrfmXCa4Us0Dm1sXBm1ge00RutE9fdUsOXatIr0XHkCweHk+1bg/x+7zgk3uPOvOdZ3o6cZKkj2HoiXlM5VK55Vb8H/Kq2p3AwlWKjt/9s+cgElpxIE4t7zf7dsUdH2FNDkdO/JcJ9BPC8rL/CR7zzeSn1NM1+UkBqo3enr13M= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773998095; c=relaxed/simple; bh=oLTHaKWqn+dKu1YUt5BQRJ6UFxmO24nn3SJ9yq7JdR0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=QO1m7U05tEsveMmkABCxn4YsUUM+npg/NG59+q6VnOv14nYMh8CKb6J9EVZggSrNT+O6sgmAezwrVvTKXyebaUdMxIsa6YTD47zp+YbQfZtzwkM79dKFV24Qq5Lq8QZk66DMRAmK9g7nFqoS6gGNNELpscZ27/o8a4Vfu/PZ2yQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 110034B1A2F9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=xry111.site; s=default; t=1773998059; bh=08lgZOBIpcmGJTWWoVSuMBNbhgZaz6CgrBi6G8PHb5U=; h=From:To:Cc:Subject:Date:From; b=F6bk/cOtT5Sv3rekQ69Q7qPLDlql11LtkpQAgrMXXIL8WBgCaPxWS1luxF6W+TYFA 55Lzfsr3/3Spiwz9cZ9egYFwZGC2Hfc71BcJ0Cyb3bXabYOM2t0LMj5oCFHoPGepTn EnLhSoEm7e676biRFn6iXUj6EvdkvhnMLvWXn2Ek= Received: from stargazer (unknown [IPv6:2409:8a4c:e11:4510:818c:b334:624:49f8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 0AE671A41EE; Fri, 20 Mar 2026 05:14:16 -0400 (EDT) From: Xi Ruoyao To: libc-alpha@sourceware.org Cc: caiyinyu , WANG Rui , Joseph Myers , Mingcong Bai , WANG Xuerui , Zixing Liu , Xi Ruoyao Subject: [PATCH v2] LoongArch: fix missing trap for enabled exceptions on narrowing operation Date: Fri, 20 Mar 2026 17:12:34 +0800 Message-ID: <20260320091233.1813940-2-xry111@xry111.site> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 X-Spam-Status: No, score=-8.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, LIKELY_SPAM_FROM, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_PASS, TXREP, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The libc_feupdateenv_test macro is supposed to trap when the trap for a previously held exception is enabled. But libc_feupdateenv_test_loongarch wasn't doing it properly: the comment claims "setting of the cause bits" would cause "the hardware to generate the exception" but that's simply not true for the LoongArch movgr2fcsr instruction. To fix the issue, we need to call __feraiseexcept in case a held exception is enabled to trap. Signed-off-by: Xi Ruoyao --- Change from v1: - Fix a leftover from earlier debugging in the test case, which caused test failures on 32-bit LoongArch and ARM. - Simplify the test using glibc test framework. math/Makefile | 3 ++ math/test-narrowing-trap.c | 60 ++++++++++++++++++++++++++++++++ sysdeps/loongarch/fenv_private.h | 22 ++++++------ sysdeps/loongarch/fpu_control.h | 3 ++ 4 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 math/test-narrowing-trap.c diff --git a/math/Makefile b/math/Makefile index 2eb0085de9..7a9352c2cd 100644 --- a/math/Makefile +++ b/math/Makefile @@ -563,6 +563,7 @@ tests = \ test-nan-overflow \ test-nan-payload \ test-narrow-macros \ + test-narrowing-trap \ test-nearbyint-except \ test-nearbyint-except-2 \ test-powl \ @@ -1172,6 +1173,8 @@ CFLAGS-test-ceil-except-2.c += -fno-builtin CFLAGS-test-floor-except-2.c += -fno-builtin CFLAGS-test-trunc-except-2.c += -fno-builtin +CFLAGS-test-narrowing-trap.c += -fno-builtin + include ../Rules gen-all-calls = $(gen-libm-calls) $(gen-calls) diff --git a/math/test-narrowing-trap.c b/math/test-narrowing-trap.c new file mode 100644 index 0000000000..27c31245c1 --- /dev/null +++ b/math/test-narrowing-trap.c @@ -0,0 +1,60 @@ +/* Copyright (C) 2026 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + pid_t pid; + + if (!EXCEPTION_ENABLE_SUPPORTED (FE_INVALID)) + FAIL_UNSUPPORTED ("feenableexcept (FE_INVALID) not supported"); + + pid = xfork (); + if (pid == 0) + { + int r = feenableexcept (FE_INVALID); + if (r == -1) + exit (2); + + fdiv (0.0, 0.0); + exit (0); + } + else + { + int status; + xwaitpid (pid, &status, 0); + + TEST_VERIFY (WIFSIGNALED (status)); + TEST_COMPARE (WTERMSIG (status), SIGFPE); + } + + return 0; +} + +#include diff --git a/sysdeps/loongarch/fenv_private.h b/sysdeps/loongarch/fenv_private.h index 7b49d82527..f782447fa2 100644 --- a/sysdeps/loongarch/fenv_private.h +++ b/sysdeps/loongarch/fenv_private.h @@ -115,20 +115,20 @@ static __always_inline int libc_feupdateenv_test_loongarch (fenv_t *envp, int excepts) { /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */ - int cw, temp; + int held_ex, cw = envp->__fp_control_register; - /* Get current control word. */ - _FPU_GETCW (cw); + /* Get the current flag, i.e. all exceptions raised since we started + to hold the exceptions. We don't care CAUSE. */ + _FPU_GET_FLAGS_CAUSE (held_ex); - /* Set flag bits (which are accumulative), and *also* set the - cause bits. The setting of the cause bits is what actually causes - the hardware to generate the exception, if the corresponding enable - bit is set as well. */ - temp = cw & FE_ALL_EXCEPT; - temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT); + /* Set flag bits (which are accumulative). */ + cw |= held_ex; + _FPU_SETCW (cw); - /* Set new state. */ - _FPU_SETCW (temp); + /* Raise SIGFPE for any new exceptions since the hold, in case any is + enabled. */ + if (__glibc_unlikely (((cw & ENABLE_MASK) << ENABLE_SHIFT) & held_ex)) + __feraiseexcept (held_ex); return cw & excepts & FE_ALL_EXCEPT; } diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h index 95976fa192..4d9dd52fca 100644 --- a/sysdeps/loongarch/fpu_control.h +++ b/sysdeps/loongarch/fpu_control.h @@ -97,6 +97,9 @@ extern void __loongarch_fpu_setcw (fpu_control_t) __THROW; #define _FPU_GET_ENABLES(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr1" : "=r"(cw)) #define _FPU_SET_ENABLES(cw) __asm__ volatile ("movgr2fcsr $fcsr1,%0" : : "r"(cw)) +#define _FPU_GET_FLAGS_CAUSE(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr2" : "=r"(cw)) +#define _FPU_SET_FLAGS_CAUSE(cw) __asm__ volatile ("movgr2fcsr $fcsr2,%0" : : "r"(cw)) + #define _FPU_GET_RM(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr3" : "=r"(cw)) #define _FPU_SET_RM(cw) __asm__ volatile ("movgr2fcsr $fcsr3,%0" : : "r"(cw))