Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp4412967rwb; Tue, 20 Sep 2022 13:36:10 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5o9ndKMwYk1N+Kg1IkyxRvlMnWS33v2nr7s1nqiftXryPQXWuoSg4rQQBGidWzLp34X3qn X-Received: by 2002:a05:6402:2692:b0:451:6515:1946 with SMTP id w18-20020a056402269200b0045165151946mr21534915edd.417.1663706170216; Tue, 20 Sep 2022 13:36:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663706170; cv=none; d=google.com; s=arc-20160816; b=saPKNd4lBcJ6m9z0lXKmLBpD8q8U+cCC27MuQzTK3Q5WFQiVCpF3p8S8VE0GSFGrkG OCtBVeWcRgY7W77J/hIeloJVKDmuuRYfuuXc3uhH0LaelPln8p41HvmIN59H+lkDHHHO a8eMSPgNeEBILWRyWfuhe7IRXWhjLBTKm0ePGiC0iFWH+r4y1SDwAl3qcBVn2JGuQo7+ O2hKHOkaQBHArbKf85gyW2Xjm6Alqh6xxTythH22LZ6Z3bELZwjGQ6VCu+lYZLKdtOZO QpsL586hPGwMo/19kqyClRsf6c/gLZfA6KnRZZYQCvIcj5FZJJbe0kCB7mFk8i+durYm nW9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=F6KfugY/ZF2k+N60z0DOxutQrzRQ1q7GMoUe0LhivhQ=; b=b+m5y2Ig/lTduBbftaaq8Xs3xNVxCUJ6D4b17hvbYP3lF3xrBQP5IZQsd8dEd0bG6S fhYH3NtdJBcn9UyLdMJnNm8IFrTuf6p8sdtM2annfjIveTY1imcocq4YT4PAPQBJnZUc z8+r7pPYjnqUcdNVTP5CjHKjIDKBr0+ioYv4B3mMcs0TRzIKxcx7Okg1AfWYhXDutgNl 7bOy/7bum9lA+12Si4+Vb33JyLS73HEqRyOJY63Bf5Egp/w9wzy4LGemTiIgUEiCA1kC MiPvtirxHCUN4GjzkH8OFuUPoUXsOj84EyHPwfW3xQLCU7zQdeuSHoi84T+hh62fnj+M k04w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=zELUirON; dkim=neutral (no key) header.i=@linutronix.de header.b=SSpRiuIf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ne33-20020a1709077ba100b0078185d33874si774150ejc.304.2022.09.20.13.35.43; Tue, 20 Sep 2022 13:36:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=zELUirON; dkim=neutral (no key) header.i=@linutronix.de header.b=SSpRiuIf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230216AbiITUA2 (ORCPT + 99 others); Tue, 20 Sep 2022 16:00:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229670AbiITUAZ (ORCPT ); Tue, 20 Sep 2022 16:00:25 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 25B163ED69; Tue, 20 Sep 2022 13:00:22 -0700 (PDT) Date: Tue, 20 Sep 2022 20:00:18 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1663704020; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F6KfugY/ZF2k+N60z0DOxutQrzRQ1q7GMoUe0LhivhQ=; b=zELUirONf6R7vie97BPX9AnZ2VjamZSksRRaV08+zTfKtYk2/Bg/N0zCYxoctMLaHRNwgR zqf2SV++qm5sffkAVZE+PcQuBHsONk0Rx7uGF9JOeSY5Ain9WLS9HV4IcdSVE59YGyJjb7 1GMTXDHBimKOhZKrrROP4DcVfBCDg1jVWabN5RxOT2Ktv+78jZw/suO90wyh2BA507sfhJ kpYemMp44QmYb+yb7LkRlRm83vK6q5w9hjHmPVlw83xoPNSk6dQe4mw9B0Rqm6vChvtvAV 1Eju7NA63+0CRnRlyC/6kgrSALfgi3getdc0k1hHEbf8rNtUGKQrDFxLnKSCYQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1663704020; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F6KfugY/ZF2k+N60z0DOxutQrzRQ1q7GMoUe0LhivhQ=; b=SSpRiuIfu6l4gPSIBu5IBl+nFPBNA80dxHSF/X64Ig5dnegfDauwjhqthaCZm29Jla2LcE HWi8q6N9JChTUcDA== From: "tip-bot2 for Vincent Mailhol" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/asm] x86/asm/bitops: Use __builtin_ctzl() to evaluate constant expressions Cc: Vincent Mailhol , Borislav Petkov , Nick Desaulniers , Yury Norov , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20220511160319.1045812-1-mailhol.vincent@wanadoo.fr> References: <20220511160319.1045812-1-mailhol.vincent@wanadoo.fr> MIME-Version: 1.0 Message-ID: <166370401862.401.15713055946708670653.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the x86/asm branch of tip: Commit-ID: fdb6649ab7c142e497539a471e573c2593b9c923 Gitweb: https://git.kernel.org/tip/fdb6649ab7c142e497539a471e573c2593b9c923 Author: Vincent Mailhol AuthorDate: Wed, 07 Sep 2022 18:09:35 +09:00 Committer: Borislav Petkov CommitterDate: Tue, 20 Sep 2022 15:35:37 +02:00 x86/asm/bitops: Use __builtin_ctzl() to evaluate constant expressions If x is not 0, __ffs(x) is equivalent to: (unsigned long)__builtin_ctzl(x) And if x is not ~0UL, ffz(x) is equivalent to: (unsigned long)__builtin_ctzl(~x) Because __builting_ctzl() returns an int, a cast to (unsigned long) is necessary to avoid potential warnings on implicit casts. Concerning the edge cases, __builtin_ctzl(0) is always undefined, whereas __ffs(0) and ffz(~0UL) may or may not be defined, depending on the processor. Regardless, for both functions, developers are asked to check against 0 or ~0UL so replacing __ffs() or ffz() by __builting_ctzl() is safe. For x86_64, the current __ffs() and ffz() implementations do not produce optimized code when called with a constant expression. On the contrary, the __builtin_ctzl() folds into a single instruction. However, for non constant expressions, the __ffs() and ffz() asm versions of the kernel remains slightly better than the code produced by GCC (it produces a useless instruction to clear eax). Use __builtin_constant_p() to select between the kernel's __ffs()/ffz() and the __builtin_ctzl() depending on whether the argument is constant or not. ** Statistics ** On a allyesconfig, before...: $ objdump -d vmlinux.o | grep tzcnt | wc -l 3607 ...and after: $ objdump -d vmlinux.o | grep tzcnt | wc -l 2600 So, roughly 27.9% of the calls to either __ffs() or ffz() were using constant expressions and could be optimized out. (tests done on linux v5.18-rc5 x86_64 using GCC 11.2.1) Note: on x86_64, the BSF instruction produces TZCNT when used with the REP prefix (which explain the use of `grep tzcnt' instead of `grep bsf' in above benchmark). c.f. [1] [1] e26a44a2d618 ("x86: Use REP BSF unconditionally") [ bp: Massage commit message. ] Signed-off-by: Vincent Mailhol Signed-off-by: Borislav Petkov Reviewed-by: Nick Desaulniers Reviewed-by: Yury Norov Link: https://lore.kernel.org/r/20220511160319.1045812-1-mailhol.vincent@wanadoo.fr --- arch/x86/include/asm/bitops.h | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 879238e..2edf684 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -247,17 +247,30 @@ arch_test_bit_acquire(unsigned long nr, const volatile unsigned long *addr) variable_test_bit(nr, addr); } +static __always_inline unsigned long variable__ffs(unsigned long word) +{ + asm("rep; bsf %1,%0" + : "=r" (word) + : "rm" (word)); + return word; +} + /** * __ffs - find first set bit in word * @word: The word to search * * Undefined if no bit exists, so code should check against 0 first. */ -static __always_inline unsigned long __ffs(unsigned long word) +#define __ffs(word) \ + (__builtin_constant_p(word) ? \ + (unsigned long)__builtin_ctzl(word) : \ + variable__ffs(word)) + +static __always_inline unsigned long variable_ffz(unsigned long word) { asm("rep; bsf %1,%0" : "=r" (word) - : "rm" (word)); + : "r" (~word)); return word; } @@ -267,13 +280,10 @@ static __always_inline unsigned long __ffs(unsigned long word) * * Undefined if no zero exists, so code should check against ~0UL first. */ -static __always_inline unsigned long ffz(unsigned long word) -{ - asm("rep; bsf %1,%0" - : "=r" (word) - : "r" (~word)); - return word; -} +#define ffz(word) \ + (__builtin_constant_p(word) ? \ + (unsigned long)__builtin_ctzl(~word) : \ + variable_ffz(word)) /* * __fls: find last set bit in word