Skip to content

Fix ambiguous std::isnan call on xnn_float16 in vbinary tester - #11545

Merged
copybara-service[bot] merged 1 commit into
google:masterfrom
anagnorisis2peripeteia:fix-f16-isnan-overload-ambiguity
Oct 18, 2026
Merged

copybara-service[bot] merged 1 commit into
google:masterfrom
anagnorisis2peripeteia:fix-f16-isnan-overload-ambiguity

Conversation

@anagnorisis2peripeteia

Copy link
Copy Markdown
Contributor

Defect: the x86_64 test build does not compile

test/vbinary-microkernel-tester.cc:66 fails to build on x86_64:

test/vbinary-microkernel-tester.cc:66:11: error: call to 'isnan' is ambiguous
   66 |       if (std::isnan(y_ref[i])) {
/usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/cmath:1182:3: note: candidate function
 1182 |   isnan(float __x)
/usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/cmath:1190:3: note: candidate function
 1190 |   isnan(double __x)
/usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/cmath:1195:3: note: candidate function
 1195 |   isnan(long double __x)

Root cause

src/xnnpack/math.h:528-532 enables native _Float16 on x86 when F16C is present:

#if (defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__) && \
    defined(__FLT16_MAX__) && defined(__F16C__) &&                     \
    ((__clang_major__ >= 15 && !defined(_MSC_VER)) || (XNN_GNUC_ACTUAL >= 12))
#define XNN_HAVE_FLOAT16 1
#endif
...
#if XNN_HAVE_FLOAT16
typedef _Float16 xnn_float16;

std::isnan has no _Float16 overload, so the argument converts to float, double and long double by equally-ranked floating conversions. Overload resolution cannot pick one.

Minimal reproduction (libstdc++ 15):

_Float16 x = 1.0f; std::isnan(x);        // error: call to 'isnan' is ambiguous
_Float16 x = 1.0f; std::isnan(float(x)); // compiles

Impact

This is the only compile error across a 797-target x86_64 build, so it blocks every test binary that links vbinary-microkernel-tester. ninja -k 0 reports exactly one distinct error.

Fix

Cast to float — the same conversion the surrounding lines already use (static_cast<float>(y_ref[i]) appears three lines below). One line.

Why ARM64 never saw it

On ARM64, xnn_float16 is the struct form (math.h:552-566) with a single operator float(), which is unambiguous. Only the native-_Float16 path is affected.

Verification

  • Before: clang++ -std=gnu++17 -march=native -c test/vbinary-microkernel-tester.cc on x86_64 → error: call to 'isnan' is ambiguous
  • After: the same command compiles cleanly, no diagnostics.
  • ARM64 vbinary-microkernel-tester target still builds.

1 file, +5/-1. git diff --check clean; no line exceeds 120 columns.

Where the compiler and CPU support it, src/xnnpack/math.h defines
xnn_float16 as the native _Float16 type (XNN_HAVE_FLOAT16, e.g. x86_64
with F16C and clang >= 15 or GCC >= 12). std::isnan has no _Float16
overload, so the implicit conversions to float, double and long double
are all equally good candidates and overload resolution is ambiguous:

  test/vbinary-microkernel-tester.cc:66:11: error: call to 'isnan' is ambiguous
      if (std::isnan(y_ref[i])) {

Minimal reproduction under libstdc++ 15:
  _Float16 x = 1.0f; std::isnan(x);       // error: ambiguous
  _Float16 x = 1.0f; std::isnan(float(x)); // compiles

This is the only compile error in a 797-target x86_64 build, so it
blocked every test that links vbinary-microkernel-tester. Cast to
float, matching how the surrounding lines already use
static_cast<float>(y_ref[i]).

Does not affect ARM64, where xnn_float16 is a struct with a single
operator float(), making the conversion unambiguous.
@copybara-service
copybara-service Bot merged commit c7c8a48 into google:master Oct 18, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants