Reland [MC] Fuse relaxation and layout into a single forward pass (#190318)

This relands debb2514ea7f, which was reverted by #189548 due to ARM
spurious `cbz` out of range error (Chromium, Android).

---

Replace the two-pass inner loop in relaxOnce (relaxFragment +
layoutSection) with a single forward pass that sets each fragment's
offset before processing it.

- Extract relaxAlign from layoutSection's FT_Align handling and call
  it from relaxFragment. FT_Align padding is computed inline with the
  tracked Offset, so alignment fragments always see fresh upstream
  offsets. This structurally eliminates the O(N) convergence pitfall
  where stale offsets caused each iteration to fix only one more
  alignment fragment.

- The new MCAssembler::Stretch field tracks the cumulative upstream size
  delta. In evaluateFixup, for PCRel fixups during relaxation, Stretch
  is added to forward-reference target values (LayoutOrder comparison).
  This makes displacement = target_old - source_old, identical to the
  old two-pass approach, preventing premature relaxation for
  span-dependent instructions.

- FT_Fill/FT_Org removed from relaxFragment; `if (F.Offset != Offset) in
  the fused loop detects their size changes.

- layoutSection is retained for initial layout and post-finishLayout.

This fixes the FT_BoundaryAlign linear time convergence issue reported
by #176535. In addition, backward branches near the short/near boundary
may benefit from tighter encoding when a .p2align between the target and
the branch absorbs upstream growth (see relax-branch-align.s).

Key commits that updated relaxFragment/layoutSection:
- 742ecfc13e8a [MC] Relax MCFillFragment and compute fragment offsets
eagerly
- 9f66ebe42715 MC: Eliminate redundant fragment relaxation
- df71243fa885 MC: Evaluate .org during fragment relaxation
- b1d58f025e83 MCAssembler: Simplify fragment relaxation
- 58d16db8b5d2 MCAssembler: Simplify relaxation of FT_Fill and FT_Org

---

Fix for the ARM regression (see thumb-ldr-stretch.s):

ARM `evaluateFixup` pre-seeds Value with
`(F.Offset + fixup_offset) % 4` for Thumb's AlignDown(PC, 4) semantics.
The full displacement formulas:

```
Old two-pass:
  (source_old % 4) + target_old - source_old
  = target_old - alignDown(source_old, 4)

Reverted buggy fused:
  (source_new % 4) + target_old - source_new + Stretch
  = target_old + Stretch - alignDown(source_new, 4)

Fixed fused:
  ((source_new - Stretch) % 4) + target_old - source_new + Stretch
  = (source_old % 4) + target_old - source_old
  = target_old - alignDown(source_old, 4)
```

With the fused pass, F.Offset is already updated by Stretch, so the
pre-seed used the new offset while the generic Stretch compensation
assumed the old offset, producing a misaligned displacement. This caused
spurious tLDRpci -> t2LDRpci relaxation (+2 bytes each), which cascaded
to push the initial CBZ target out of range.

The fix uses pre-Stretch source offsets for the AlignDown(PC, 4)
pre-seed in evaluateFixup, leading to the same displacement
as the old two-pass algorithm.
8 files changed
tree: f38adfae2acf052fd33ee3f1914986e1abf5ad4d
  1. .ci/
  2. .github/
  3. bolt/
  4. clang/
  5. clang-tools-extra/
  6. cmake/
  7. compiler-rt/
  8. cross-project-tests/
  9. flang/
  10. flang-rt/
  11. libc/
  12. libclc/
  13. libcxx/
  14. libcxxabi/
  15. libsycl/
  16. libunwind/
  17. lld/
  18. lldb/
  19. llvm/
  20. llvm-libgcc/
  21. mlir/
  22. offload/
  23. openmp/
  24. orc-rt/
  25. polly/
  26. runtimes/
  27. third-party/
  28. utils/
  29. .clang-format
  30. .clang-format-ignore
  31. .clang-tidy
  32. .git-blame-ignore-revs
  33. .gitattributes
  34. .gitignore
  35. .mailmap
  36. CODE_OF_CONDUCT.md
  37. CONTRIBUTING.md
  38. LICENSE.TXT
  39. pyproject.toml
  40. README.md
  41. SECURITY.md
README.md

The LLVM Compiler Infrastructure

OpenSSF Scorecard OpenSSF Best Practices libc++

Welcome to the LLVM project!

This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.

The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.

C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.

Other components include: the libc++ C++ standard library, the LLD linker, and more.

Getting the Source Code and Building LLVM

Consult the Getting Started with LLVM page for information on building and running LLVM.

For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.

Getting in touch

Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.

The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.