Skip to content

clang+LTO makes USB Serial unacceptably slow #2464

Open
@Ivan-Voronyuk

Description

@Ivan-Voronyuk

TL;DR

Enabling -flto (or CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) causes USB Serial to output only one "block" per second in Release mode. The issue disappears in Debug builds.


Detailed Description

Minimal Repro Code

#include <pico/stdio.h>
int main() {
  stdio_init_all();
  uint32_t cnt = 0;
  while (1) stdio_printf("!!! %d\n", cnt++);
}
  • Behavior with LTO:

    • Outputs exactly one line per second (vs. ~1.8k lines/s without LTO).
    • Replacing stdio_printf with printf doesn't make a difference
    • std::cout << "!!! " << cnt++ << std::endl; emits exactly one symbol per second.

    Issue only occurs with CMAKE_BUILD_TYPE=Release. Debug builds work normally.


How to Reproduce

  1. Code: Use the main.cpp above.
  2. CMakeLists.txt:
cmake_minimum_required(VERSION 3.13...3.27)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)  # <-- Triggers the bug
set(PICO_SDK_PATH "<your_sdk_path>")
set(PICO_TOOLCHAIN_PATH "<llvm_toolchain_path>")  # Tested with clang-18, LLVM-ET-Arm-18.1.3-Linux-x86_64 toolchain
set(PICO_COMPILER pico_arm_cortex_m0plus_clang)
include(.../pico_sdk_import.cmake)

project(SLOW)
pico_sdk_init()

# Configure stdio
set(PICO_STDIO_UART OFF)
set(PICO_STDIO_USB ON)

add_executable(main main.cpp)
target_link_libraries(main PRIVATE pico_stdlib)
pico_enable_stdio_usb(main 1)
pico_enable_stdio_uart(main 0)
pico_set_float_implementation(main pico)
pico_add_extra_outputs(main)

This issue on tinyusb repo: hathach/tinyusb#3120

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions