Skip to content

m68k-amigaos-gcc -O2 miscompile: UWORD struct field reaching sprintf's %u varargs gets garbage upper bits #23

Description

@sidick

Found while adding Kickstart/Workbench version telemetry to mqttstats (PR #22): reading a UWORD struct field (SysBase->LibNode.lib_Version, workbench.library's lib_Version/lib_Revision) and passing it through sprintf(buf, "%u.%u", ...) produces garbage in the upper 16 bits of the promoted value only at -O2 - confirmed via an isolated on-target repro under Copperline. -O0 is correct.

Two "obvious" fixes did not work:

  • & 0xFFFF masking at the call site: optimized away as "provably redundant" by GCC's own (here, wrong) UWORD range analysis - confirmed by a byte-identical rebuild of the binary with and without the mask.
  • Routing the value through a volatile local: fixed an isolated single-function repro, but did not fix the real call site inside mqttstats_main.c - something about the surrounding code (register pressure? inlining decisions?) reintroduces it.

What actually worked, shipped in mqttstats_main.c's format_bcd_version(): a volatile local at the call site feeding a dedicated __attribute__((noinline)) manual digit-formatter, entirely avoiding sprintf's %u varargs path. See that function's own comment for the full story.

Why this matters beyond mqttstats: since M68K_CFLAGS builds everything at -O2 by default, this could silently affect any other code passing a 16-bit (UWORD) value through a variadic call (sprintf/RawDoFmt/etc.) - worth a dedicated investigation to find the toolchain version, minimal repro, and whether it's a known upstream m68k-amigaos-gcc bug, rather than working around it ad hoc every time it's hit. Not urgent (the workaround above is shipped and correct) but worth tracking so it doesn't get rediscovered from scratch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions