From patchwork Sat Jul 4 06:34:26 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jeffrey Law X-Patchwork-Id: 138472 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 917E74BA79B5 for ; Sat, 4 Jul 2026 06:35:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 917E74BA79B5 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=ShNJ7CJ8; dkim=pass (2048-bit key, unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.a=rsa-sha256 header.s=google header.b=F0ZHlMcV X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by sourceware.org (Postfix) with ESMTPS id B82274BA2E37 for ; Sat, 4 Jul 2026 06:34:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B82274BA2E37 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=oss.qualcomm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oss.qualcomm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B82274BA2E37 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783146873; cv=none; b=YruV9I0SJvQZH8J2XMlSlLPNV+1vh+UEq2rksn9gcfHdZve5AlUnWuSIv2A/GLDvDjPTQzUmP6frqeNDwC7V0NhxEUVKhVnP071ycvnNrbwGqK0SBBJzvGogNJbR64llf+ctpp1gD88IuQNX+rb5TpU6dSBtfFqB7jkyuGgqHTM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783146873; c=relaxed/simple; bh=Mb/nBAClSND1QcvlbNS33wbj6GFlRYyeOaB+OMBoeQA=; h=DKIM-Signature:DKIM-Signature:Message-ID:Date:MIME-Version:From: Subject:To; b=rZEZSWNzVyhqiWQfWhAjKNGPh8JLGzs9JrbgMfhCumLYa5G2Dk+ItOujXalSwQDPyEnXZA1ngBn+0mLIPNMr5W52jMgPLgczh/wrS0Uid0sRLJspc5Rgt/1LJ5jLnLYG8BwIFghoa4yWbPmBVd913JOrR/HDdQdCasBwuuF2j+U= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=ShNJ7CJ8; dkim=pass (2048-bit key, unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.a=rsa-sha256 header.s=google header.b=F0ZHlMcV DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B82274BA2E37 Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66428jWE1744220 for ; Sat, 4 Jul 2026 06:34:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-type:date:from:message-id:mime-version:subject:to; s= qcppdkim1; bh=g1PUKbHZtioA/tvIhYQqiCebpgXKwgCB9duWTdHJwEU=; b=Sh NJ7CJ8yoWhTKaTXauhP+ezY/ANiZ/SU5lC2m1EltXfmioJJq52EJccOKLUAM41BG +zby3LYW2cWQFbcP0aYbvxzbGHareTu5SyHGEGINsJw9wSfRLy6XOoxQtFCl0OQx 1ZYEUiMvQ5fKLrje9b2oiSK/G3RYls16uIP19WqWRZOWHTYmRnkVrw+BHfWjl3zR oNuhy52BlHbwcXNShTGZjo4l2Wh7a6EfwEtU3MJUfg6AjG/gNu4UA5j/6qnUSaCb kT+rH1gkW2D8EeeG5K/VizvJ7yFeJm4ac/3731QWcbKDgGFOPXl+N5CFyYVmF6es bogrXwOoHhNSNfgilllg== Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4f6s4sre17-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Sat, 04 Jul 2026 06:34:30 +0000 (GMT) Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-c88aab7c1d4so1002906a12.3 for ; Fri, 03 Jul 2026 23:34:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783146869; x=1783751669; darn=sourceware.org; h=to:subject:from:content-language:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=g1PUKbHZtioA/tvIhYQqiCebpgXKwgCB9duWTdHJwEU=; b=F0ZHlMcVMd4CgJaJMAAOKVgPANOqd/CaU8Y2rucHPneiqTmtB1CMK99pCUzlWXFSqH mzMJrr+R8D2atL/XYFR8/JiB+VDwyGScDcU/CHa3RvK28mK7cQuHe2p5xwEIlrIvQOX5 xnrCgoTC2/nXLXkwYve0QlBAD+ShCX/kN07ETH1rk842FXCKw5DnhweJB/cRoUu9awm8 7Sc6GfrDilqZkT6l6nPiowLcGJI1/9m6VGlTTIcKbFI1MlwVexOGJus3QSLRO1y+H8rr SiFk5J7u8MteqRS2BMrZhrUeZvia9BDuLdcCw9J7Hs8w882a1/UkcFzz7zfPwvNQbbHz AHag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783146869; x=1783751669; h=to:subject:from:content-language:user-agent:mime-version:date :message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=g1PUKbHZtioA/tvIhYQqiCebpgXKwgCB9duWTdHJwEU=; b=aKZDghVGnP5kAY1eISeMh8YuyCifqywaDZMfPwjCooArm6s/i2FguGqf6FE4bJmMdF u0VrpBY4xZq4yr0if8whFBVX/VdrC0PcLSvLdwcBgGIDGU6N1gTK+FJV+/Wq7oJsoreP jaCBVYhY7rfNHjApbV0Jp4Sw2NO/5btnlJpYANEuSfyovmpwv/2D7TxzGAbSVJ8LDDQq JnPO4ZWzhqcgbIEgXMl3i7g5JGaoloJe/QRAWWt3q8bMI9LMIU8J9NRwnJX5a8JMNGZM +pJdzrgyW6Z1uh1XMpV1ufE7gYS5nMyH+Cecx4KlaPQarAcQuTvTVRTyGKeXdOyicuXU g/fg== X-Gm-Message-State: AOJu0YwDvJcDiVakuRxu+WWlySNOcO4fquP9u2rDEYp/TbdxCOIbjd/e lS4pJB8cMXzq6A+r0hJi57qkIic84fmdk3snuOz0rdmc2RdAMQSS2EqlHYvnWm9Gkvtr3jpnzNT N2RFg65RlhxMKv7X5qg02JMjt24HT5r2CF15TlXb+8gHhxOXBK1jKaEurNm3O9uBJCMB9ErA= X-Gm-Gg: AfdE7ckbWMx/rSIbgLwcEsL/E5AGyTi/cxp/vQocsZXKjoEy8iv38Xcre5PUHN0y7BI FIQHUpMKSBJnYmBs4aHazhugLXZ9OKBOqPdgkfVEjYG1Ov0hbBkHakrMpJTtHCx4zA1j3o/hC2C fWxXVHauCIIv0TMonZ4OTcgxaGh9TXZAwUAOqJ0RGIyEdNyR/NLwoOsN1DYmSB1U+BdYXLuCNxt 0hBI1IrtQTaW37e79a/Qk9LcQIPFs1J0YMpZOv72tDsSgs4YT7aOcdP85eou7gl7GfLpfcq2zXi ZX3lo+xr3NfamYQoga1ncdxSQHdy8plGLBePaqB1uHmLjR+0E7GLKdHw3GV2rh0PbRA06b1xjXX NlPoBbQfhRC6+DdyRPAwx3POFCBVDPg+y+LCRoFV0dE0= X-Received: by 2002:a05:6300:2287:b0:3bf:a941:8932 with SMTP id adf61e73a8af0-3c03e1f54bfmr2555936637.19.1783146869292; Fri, 03 Jul 2026 23:34:29 -0700 (PDT) X-Received: by 2002:a05:6300:2287:b0:3bf:a941:8932 with SMTP id adf61e73a8af0-3c03e1f54bfmr2555890637.19.1783146868568; Fri, 03 Jul 2026 23:34:28 -0700 (PDT) Received: from [192.168.1.109] ([129.222.131.109]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b3ececfe4sm31481042c88.8.2026.07.03.23.34.27 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 03 Jul 2026 23:34:27 -0700 (PDT) Message-ID: <201b88c9-cb09-4cd2-af3e-9d644f1c85b2@oss.qualcomm.com> Date: Sat, 4 Jul 2026 00:34:26 -0600 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US From: Jeffrey Law Subject: [V2] riscv: Implement Zbb based strlen and prefer it over the RVV based strlen implementation when Zbb is available To: "libc-alpha@sourceware.org" X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA0MDA2MSBTYWx0ZWRfX2h90+kK4BZau uD9bDEpf6DcbL2RIYkSzTMvNNi6HWTUNP0yRkKlCdkzyZhEkhBEVkrcgN1pSPzUVy58ljjChuY3 L9nMN3HxHA52ibawKlgJO49Jjtak8Co= X-Proofpoint-ORIG-GUID: SQhulGOg5MsoO2ZIY9mn7V8pnuqkwMGF X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA0MDA2MSBTYWx0ZWRfX/SkR6uLA8IaI hWr/Q6mY5/nasPhrXuShlfwW7OCKW7eKroO51k762yOD9ZByo51UhfadVd/PcoMoEsP2j9K4GLV bTXUfcX5ePmZZAMom6yL8+z0Y+XryGY8Gcgbw2ow2lxI0mJT6+3xX4c/DRCfToodbhvc5qbp2za UnS6Bx52srV1wpA3PiqfD+CUhxAl5Ne4gI1fNLDICxAkv3G+S9H9stn3MKD/VGCAR3hmcpKxIWY hqa4vGFO/VBKpPkXUKyGn6WzO0quY8QNC9FjZ9TM+Pvv3DjHCYbWr/JsVoeRfPz8CKrZWuY19Nh aQvngCi0lw8S/leUc7wBwgXKFsSyxrfIzKzIdaaPK/v3piIc/9MUAs6+DEpJ0qgPFCkQXMq3L4j dJ+jSNT0QjMgQqBQ4JIppdaqkdIfp/r6DHRzVMH2xn7gufzTqojBKk4gNnz8IQK6H4Cch32TnnC CKrfHIQ2q+P5G7EKqmg== X-Proofpoint-GUID: SQhulGOg5MsoO2ZIY9mn7V8pnuqkwMGF X-Authority-Analysis: v=2.4 cv=ZfQt8MVA c=1 sm=1 tr=0 ts=6a48a976 cx=c_pps a=Qgeoaf8Lrialg5Z894R3/Q==:117 a=lBvIj5/xOKdcLUUgmCwl7Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=r77TgQKjGQsHNAKrUKIA:9 a=5mLLFbtSKA03S62htvMA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=fBGkShfGU_G27EFFJ1AA:9 a=B2y7HmGcmWMA:10 a=x9snwWr2DeNwDh03kgHS:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-07-03_04,2026-07-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 adultscore=0 phishscore=0 priorityscore=1501 clxscore=1015 suspectscore=0 malwarescore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607040061 X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_PBL, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no 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 So this is the V2 patch of a Zbb strlen implementation.  As was previously noted, this is 2-4X faster than the current RVV implementation on the K3 and meaningfully faster on the K1 as well (I don't remember that data offhand other than Zbb was the best choice there too). The most important difference between this and the first patch is there's no longer a Zbb specific directory.  Per the discussion from last month there aren't any plans to make any Implies relationships and such. The ifunc resolver has been improved ever-so-slightly to avoid an extra round trip through the hwprobe interface.  We can get the state of Zbb and RVV with a single round trip.  A few comment typos spotted by an LLM  have been fixed as well. With dropping the Zbb subdirectory, the bits left in the multiarch directory have all the hidden symbol, alias and related stuff. I'm not at all familiar with what needs to be done in this case. So I'd appreciate a close look at that code. I've built and tested glibc on the K3 with this patch.  It shows no regressions relative to the baseline build.  I've also verified the performance data is not meaningfully changed. Obviously hoping we can get this included in the upcoming release... --- So we've had Zbb variants for strlen, strcmp and a few other routines sitting here in our local repositories for a long time. The original implementations were done by the VRULL team, then adjusted for minor bugs caught by the glibc testsuite and later wired into the hwprobe mechanism. Much like the RVV implementations that have been dropping into the tree, I want to focus on one routine at a time to make sure we're happy with the result, then move onto the next one.  In this particular patch I'm focused on strlen. The implementation is largely derived from the bitmanip examples, just cleaned up so that it ought to work for both rv32/rv64 and either big or little endian (little endian is untested, I believe VRULL tested rv32 at some point). Neither the Zbb nor the RVV implementation seems at all sensitive to data alignment concerns on the K3.  So we can safely ignore that input axis and focus on how many cycles it takes to handle a string of a particular length. I asked the LLM model to take the performance data, convert it to cycles per byte, then get the average cycles per byte over a range of lengths new buckets starting a power of 2 boundaries. Bucket        ZBB CPB        Vector CBP     Winner 1-1           4.227          17.312         ZBB is ~4.1x faster 2-3           1.714           7.232         ZBB is ~4.2x faster 4-7           0.870           3.287         ZBB is ~3.8x faster 8-15          0.563           1.950         ZBB is ~3.5x faster 16-31         0.446           0.954         ZBB is ~2.1x faster 32-63         0.299           0.477         ZBB is ~1.6x faster 64-127 0.190           0.414        ZBB is ~2.2x faster And so-on with the cycles-per-byte dropping for both, but ZBB consistently running ~2.1x faster than RVV up to a length of 8k. We can see the Zbb is just better all around.  There wasn't a single case where RVV won.  It's pretty obvious that the vector version has a higher fixed overhead, but I really expected vector to overcome that overhead as the strings got longer.  As it stands the data says quite clearly that we should be using Zbb on the K3 design and likely the K1 design (currently being tested). Given the K1/K3 designs are what folks can get their hands on, I'd recommend we make Zbb preferred over RVV.  We'll likely have to adjust that as newer designs come into the market, but the decision should be data driven.  I'm going to run this on our Veyron V2 design and Peter is going to run on the Ascalon design, but neither of those are generally available and probably shouldn't drive decisions, those are mostly for informational purposes and to give a sense of whether or not higher targeted designs are likely to benefit from the RVV variant when those higher performance designs hit the market. You could also legitimately ask what GCC should be doing here. Right now GCC will inline the strlen call, generating RVV code that is nearly identical to what's in glibc.  So it's probably not a win for GCC to inline an RVV strlen, though inlining does at least avoid the function call overhead and allow for secondary optimization affects since there's no call. This has been built and regression tested on the c920 and K3, the K1 is still running.  The c920 is interesting because it has neither RVV nor Zbb, so confirming I didn't do anything dumb in the resolver was useful. -- OK for the trunk? jeff From c26fdb04b7b64e36768686407fe110fe30ee49a3 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 9 Jun 2026 23:05:37 +0000 Subject: [PATCH] strlen zbb implementation --- sysdeps/riscv/multiarch/strlen-zbb.S | 126 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/Makefile | 1 + .../linux/riscv/multiarch/ifunc-impl-list.c | 6 + .../unix/sysv/linux/riscv/multiarch/strlen.c | 17 ++- 4 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 sysdeps/riscv/multiarch/strlen-zbb.S diff --git a/sysdeps/riscv/multiarch/strlen-zbb.S b/sysdeps/riscv/multiarch/strlen-zbb.S new file mode 100644 index 0000000000..f503acfda7 --- /dev/null +++ b/sysdeps/riscv/multiarch/strlen-zbb.S @@ -0,0 +1,126 @@ +/* Re-include the RISC-V Zbb based strlen implementation. + 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 + . */ + +#if IS_IN(libc) +# define STRLEN __strlen_zbb +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# undef weak_alias +# define weak_alias(name, alias) + +#include +#include + +/* Assumptions: rvi_zbb. */ +/* Implementation from the Bitmanip specification. */ + +#define src a0 +#define result a0 +#define addr a1 +#define data a2 +#define offset a3 +#define offset_bits a3 +#define valid_bytes a4 +#define m1 a4 + +#if __riscv_xlen == 64 +# define REG_L ld +# define SZREG 8 +# define PTRLOG 3 +#else +# define REG_L lw +# define SZREG 4 +# define PTRLOG 2 +#endif + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define CZ clz +# define SHIFT sll +#else +# define CZ ctz +# define SHIFT srl +#endif + +#ifndef STRLEN +# define STRLEN __strlen_zbb +#endif + +ENTRY (STRLEN) +.option push +.option arch,+zbb + + /* Number of irrelevant bytes in the first word. */ + andi offset, src, SZREG-1 + /* Align pointer. */ + andi addr, src, -SZREG + + li valid_bytes, SZREG + sub valid_bytes, valid_bytes, offset + slli offset_bits, offset, PTRLOG + + /* Get the first word. */ + REG_L data, 0(addr) + /* Shift away the partial data we loaded to remove the irrelevant bytes + * preceding the string with the effect of adding NUL bytes at the + * end of the string. */ + SHIFT data, data, offset_bits + /* Convert non-NUL into 0xff and NUL into 0x00. */ + orc.b data, data + /* Convert non-NUL into 0x00 and NUL into 0xff. */ + not data, data + /* Search for the first set bit (corresponding to a NUL byte in the + * original chunk). */ + CZ data, data + /* The first chunk is special: compare against the number + * of valid bytes in this chunk. */ + srli result, data, 3 + bgtu valid_bytes, result, L(done) + + /* Prepare for the word comparison loop. */ + addi offset, addr, SZREG + li m1, -1 + + /* Our critical loop is 4 instructions and processes data in + * 4 byte or 8 byte chunks. */ + .p2align 3 +L(loop): + REG_L data, SZREG(addr) + addi addr, addr, SZREG + orc.b data, data + beq data, m1, L(loop) + +L(epilogue): + not data, data + CZ data, data + /* Get number of processed words. */ + sub offset, addr, offset + /* Add number of characters in the first word. */ + add result, result, offset + srli data, data, 3 + /* Add number of characters in the last word. */ + add result, result, data +L(done): + ret + +.option pop + +END (STRLEN) +libc_hidden_builtin_def (STRLEN) +weak_alias (STRLEN, strlen) + +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile index 30d92c1ba9..0e42022fab 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile @@ -31,6 +31,7 @@ sysdep_routines += \ strlen \ strlen-generic \ strlen-vector \ + strlen-zbb \ strncmp \ strncmp-generic \ strncmp-vector \ diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c index 8027578529..4b0ac4ea51 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c @@ -27,6 +27,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t i = max; bool fast_unaligned = false; + bool zbb_enabled = false; bool rvv_enabled = false; struct riscv_hwprobe pairs[2] = { @@ -41,6 +42,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, if (pairs[1].value & RISCV_HWPROBE_IMA_V) rvv_enabled = true; + + if (pairs[1].value & RISCV_HWPROBE_EXT_ZBB) + zbb_enabled = true; } IFUNC_IMPL (i, name, memcpy, @@ -66,6 +70,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_generic)) IFUNC_IMPL (i, name, strlen, + IFUNC_IMPL_ADD (array, i, strlen, zbb_enabled, + __strlen_zbb) IFUNC_IMPL_ADD (array, i, strlen, rvv_enabled, __strlen_vector) IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_generic)) diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c index 9975286b85..c00f2787ff 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c @@ -32,14 +32,25 @@ extern __typeof (__redirect_strlen) __libc_strlen; extern __typeof (__redirect_strlen) __strlen_generic attribute_hidden; extern __typeof (__redirect_strlen) __strlen_vector attribute_hidden; +extern __typeof (__redirect_strlen) __strlen_zbb attribute_hidden; static inline __typeof (__redirect_strlen) * select_strlen_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { unsigned long long int v; - if (__riscv_hwprobe_one (hwprobe_func, RISCV_HWPROBE_KEY_IMA_EXT_0, &v) == 0 - && (v & RISCV_HWPROBE_IMA_V) == RISCV_HWPROBE_IMA_V) - return __strlen_vector; + + /* Testing has shown that on circa 2026 hardware a Zbb based strlen is + consistently faster than a V implementation. So we prefer Zbb for + now. As vector impementations mature this will likely need revisiting. */ + if (__riscv_hwprobe_one (hwprobe_func, RISCV_HWPROBE_KEY_IMA_EXT_0, &v) == 0) + { + if ((v & RISCV_HWPROBE_EXT_ZBB) == RISCV_HWPROBE_EXT_ZBB) + return __strlen_zbb; + + if ((v & RISCV_HWPROBE_IMA_V) == RISCV_HWPROBE_IMA_V) + return __strlen_vector; + } + return __strlen_generic; }