Skip to content

teensylc: -flto=auto overflows Thumb-1 PC-relative offset limit on Cortex-M0+ #301

Description

@zackees

Symptom

Every FastLED teensyLC release build on master fails:

.lto-tmp/ccWj7t00.s:193: Error: invalid offset, value too big (0x000004CC)
.lto-tmp/ccWj7t00.s:206: Error: invalid offset, value too big (0x00000498)
lto-wrapper: fatal error: make returned 2 exit status
ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status

Root cause

Teensy LC = MKL26Z64 = Cortex-M0+ = Thumb-1 only. Thumb-1 PC-relative loads (ldr Rd, [PC, #imm]) have an immediate-offset limit of about 1 KB (10-bit immediate, word-aligned → max 0x3FC).

crates/fbuild-build/src/teensy/configs/teensylc.json declares:

"profiles": {
  "release": {
    "compile_flags": ["-Os", "-flto=auto", "-fno-fat-lto-objects"],
    "link_flags":    ["-Os", "-flto=auto", "-fuse-linker-plugin"]
  },
  ...
}

LTO rearranges literal pools across translation units, and on Thumb-1 the rearranged offsets routinely exceed 0x400. Modern GCC's assembler catches this at the .lto-tmp/*.s step rather than producing wrong code.

This is Thumb-1-specific: every other Teensy MCU (3.0/3.1/3.2 = MK20DX, 3.5 = MK64FX, 3.6 = MK66FX, 4.x = IMXRT1062) is Cortex-M3 or later — all Thumb-2 — and Thumb-2's wider 12-bit PC-relative offsets don't hit this wall. So the fix is targeted to teensylc only.

Fix (this PR)

crates/fbuild-build/src/teensy/configs/teensylc.json: drop -flto=auto and -fno-fat-lto-objects / -fuse-linker-plugin from the release profile. Keep -Os for size. Reference config (configs/reference/teensylc.json) doesn't list -flto either, so test_linker_flags_match_platformio_reference continues to pass.

All 38 cargo test -p fbuild-build --lib teensy:: tests pass after the change.

Affected workflows

  • FastLED teensyLC — every example.

Why not "fix LTO instead"

Thumb-1's offset limit is hardware. The only way to keep LTO on M0+ would be to bound the size of literal pools per TU — GCC doesn't expose a knob for that, and even if it did, the spec window where it works would be narrow and fragile. Industry norm for Cortex-M0/M0+ embedded toolchains is "no LTO" — Teensyduino itself doesn't enable it on LC.


Filed during a coordinated CI-green sweep; fix PR landing immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions