Re: [PATCH 3/4] selftests/nolibc: add abs() range test

Ammar Faizi <[email protected]> Mon, 27 Jul 2026 08:32:58 +0700
Newsgroups dev.linux.lists.llvm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest
Message-ID <[email protected]>
On 7/27/26 3:00 AM, Thomas Weißschuh wrote:
>> +/* abs(), labs() and llabs() over the whole range of their argument type */
>> +int test_abs_range(void)
>> +{
>> +	int i, ri;
>> +	long l, rl;
>> +	long long ll, rll;
> 
> Reverse xmas?

Fixed for the next revision.

>> +
>> +	/*
>> +	 * Both the inputs and the results have to stay opaque: the compiler
>> +	 * knows abs() and friends never return a negative value and would
>> +	 * otherwise fold the comparisons below at build time, which would also
>> +	 * hide the undefined behavior that is being tested for.
>> +	 */
>> +	i = INT_MIN; l = LONG_MIN; ll = LLONG_MIN;
>> +	__asm__ ("" : "+r" (i), "+r" (l), "+r" (ll));
> 
> We have _NOLIBC_OPTIMIZER_HIDE_VAR() for this.

Oh, I missed it.

> Maybe it can be made variadic.
Sounds good to me.

Does the following patch look good?

From: Ammar Faizi <[email protected]>
Date: Sun, 26 Jul 2026 13:17:14 -0700
Subject: [PATCH] tools/nolibc: make _NOLIBC_OPTIMIZER_HIDE_VAR() variadic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The macro only takes a single variable, so code that needs to hide
several at once has to either repeat it or open-code an asm statement
with a list of operands. Accept up to four variables and build the
operand list from them.

Existing single-argument users are unaffected; the code generated for
the callers in stdio.h is unchanged on i386 and x86-64.

Suggested-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
  tools/include/nolibc/compiler.h | 15 +++++++++++++--
  1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h
index f2d7a81d0d7c..ed69f6d26f56 100644
--- a/tools/include/nolibc/compiler.h
+++ b/tools/include/nolibc/compiler.h
@@ -77,8 +77,19 @@
  #  define __nolibc_static_assert(_t)
  #endif
  
-/* Make the optimizer believe the variable can be manipulated arbitrarily. */
-#define _NOLIBC_OPTIMIZER_HIDE_VAR(var)	__asm__ ("" : "+r" (var))
+#define __nolibc_hide1(_1)		"+r" (_1)
+#define __nolibc_hide2(_1, ...)		"+r" (_1), __nolibc_hide1(__VA_ARGS__)
+#define __nolibc_hide3(_1, ...)		"+r" (_1), __nolibc_hide2(__VA_ARGS__)
+#define __nolibc_hide4(_1, ...)		"+r" (_1), __nolibc_hide3(__VA_ARGS__)
+#define ___nolibc_hide_narg(_1, _2, _3, _4, N, ...) N
+#define __nolibc_hide_narg(...)		___nolibc_hide_narg(__VA_ARGS__, 4, 3, 2, 1)
+#define __nolibc_hide(N, ...)		__nolibc_hide##N(__VA_ARGS__)
+#define __nolibc_hide_n(N, ...)		__nolibc_hide(N, __VA_ARGS__)
+
+/* Make the optimizer believe the variables can be manipulated arbitrarily. */
+#define _NOLIBC_OPTIMIZER_HIDE_VAR(...)					\
+	__asm__ ("" : __nolibc_hide_n(__nolibc_hide_narg(__VA_ARGS__),	\
+				      __VA_ARGS__))
  
  #if __nolibc_has_feature(undefined_behavior_sanitizer)
  #  if defined(__clang__)

-- 
Ammar Faizi