# LLVM 15 Release Notes

# Introduction

This document contains the release notes for the LLVM Compiler Infrastructure, release 15. Here we describe the status of LLVM, including major improvements from the previous release, improvements in various subprojects of LLVM, and some of the current users of the code. All LLVM releases may be downloaded from the LLVM releases web site.

For more information about LLVM, including information about the latest release, please check out the main LLVM web site. If you have questions or comments, the Discourse forums is a good place to ask them.

Note that if you are reading this file from a Git checkout or the main LLVM web page, this document applies to the next release, not the current one. To see the release notes for a specific release, please see the releases page.

# Non-comprehensive list of changes in this release

- …

## Changes to the LLVM IR

- The `ptrtoaddr` instruction was introduced. This instruction returns the address component of a pointer type variable but unlike `ptrtoint` does not capture provenance (#139357).

- The alignment argument of the `@llvm.masked.load`, `@llvm.masked.store`, `@llvm.masked.gather` and `@llvm.masked.scatter` intrinsics has been removed. Instead, the `align` attribute should be placed on the pointer (or vector of pointers) argument.

- A `load atomic` may now be used with vector types on x86.

- Added `@llvm.reloc.none` intrinsic to emit null relocations to symbols. This emits an undefined symbol reference without adding any dedicated code or data to to bear the relocation.

- Added `modular-format` attribute to dynamically pull in aspects of libc format string function implementations from statically-linked libc’s based on the requirements of each call. Currently only `float` is supported; this can keep floating point support out of printf if it can be proven unused.

- Case values are no longer operands of `SwitchInst`.

- Allow metadata to be attached to IFuncs.

## Changes to LLVM infrastructure

- On AIX, fixed the OS version in target triples on PASE.

- On AIX, automatically raise soft memory limits to hard limits on tool startup (#167928).

## Changes to building LLVM

- On AIX, remove default flag `-fno-semantic-interposition`.

- On AIX, LLVM shared libraries are now built as shared library archives by default (#155686).

- On AIX, enable building with CMake 4.0 and above (#154537).

- On AIX, enable building with the AIX form of the lto cache dir option (#168868).

## Changes to TableGen

- The `!getop` and `!setop` bang operators have been removed in favor of `!getdagop` and `!setdagop`.

## Changes to Interprocedural Optimizations

- Added `-enable-machine-outliner={optimistic-pgo,conservative-pgo}` to read profile data to guide the machine outliner (#154437).

- Fixed static resolution of indirect calls to versioned functions on AArch64, by separating unrelated caller versions which were previously mixed together. Also improved the accuracy of the algorithm for low version counts.

## Changes to Vectorizers

- Added initial support for copyable elements in SLP, which models copyable elements as add <element>, 0, i.e. uses identity constants for missing lanes.

- SLP vectorizer supports initial recognition of FMA/FMAD pattern

## Changes to the AArch64 Backend

- Assembler/disassembler support has been added for Armv9.7-A (2025) architecture extensions.

- Assembler/disassembler support has been added for ‘Virtual Tagging Extension (vMTE)’ and ‘Permission Overlay Extension version 2 (POE2)’ Future Architecture Technologies extensions.

- `FEAT_TME` support has been removed, as it has been withdrawn from all future versions of the A-profile architecture.

- Added support for C1-Nano, C1-Pro, C1-Premium, and C1-Ultra CPUs.

- Added support for Ampere1C cores.

## Changes to the AMDGPU Backend

- Removed `llvm.amdgcn.atomic.cond.sub.u32` and `llvm.amdgcn.atomic.csub.u32` intrinsics. Users should use the `atomicrmw` instruction with `usub_cond` and `usub_sat` instead.

## Changes to the ARM Backend

## Changes to the AVR Backend

## Changes to the DirectX Backend

## Changes to the Hexagon Backend

## Changes to the LoongArch Backend

- RuntimeDyld now supports the `Large` code model for LoongArch64.

- The `PreserveMost` calling convention is now supported.

- An option named `loongarch-enable-merge-offset` is added to allow disabling the `MergeBaseOffset` pass.

- A macro instruction named `ud` is added.

- `la.abs` now generates `R_LARCH_MARK_LA` relocation.

- LASX and LSX conversion intrinsics are added.

- Tail calls for `sret` and `byval` functions are now supported.

- Always emit symbol-based relocations regardless of relaxation.

- DWARF fission is now compatible with linker relaxations, allowing `-gsplit-dwarf` and `-mrelax` to be used together when building for the LoongArch platform.

- Improved LoongArch32 support by adding LA32R/LA32S relocations, PC-relative address materialization, and `call`/`tail` macro instructions.

- Assorted codegen improvements.

## Changes to the MIPS Backend

## Changes to the PowerPC Backend

- `half` now uses a soft float ABI, which works correctly in more cases.

- Add `mtpidr` alias introduced in ISA3.0.

- Update `tlbie` instruction implementation for ISA3.0+.

- Update `strlen`, `strcpy` and `memcmp` to use milicode calls instead of library calls.

- Prototyped intrinsic for xvrlw and load/store with right length left-justified.

- Prototyped Elliptic Curve Cryptography (ECC) Instructions.

- Prototyped VSX Vector Integer Arithmetic Instructions.

- Prototyped AES Acceleration Instructions.

- Prototyped vector uncompress instructions.

- Prototyped vector unpack instructions.

- Prototyped 32-byte indexed paired load and store instructions.

- Prototyped Context Switch instruction `mtlpl`.

- Prototyped VSX rotate left word instruction.

- Prototyped paddis.

- Prototyped eTCE instructions.

- Prototyped Dense Math Facility and DMR COPY support.

- Implement the trampoline intrinsics and nest parameter for AIX.

- Introduced a minimum threshold for the largest number of comparisons needed to trigger bit test generation during switch lowering.

- Relax strictfp to constrain only `libm` libcalls, permitting non-FP optimizations.

- Use `bne-` for atomic operations after store conditional.

- Consolidated predicate definitions into `PPC.td`.

- Cleanup asm parser code to use template functions for the various versions of `getImm*Encoding()` and `is*Imm()` used in `PPCRegisterInfo.td`.

## Changes to the RISC-V Backend

- The loop vectorizer now performs tail folding by default on RISC-V, which removes the need for a scalar epilogue loop. To restore the previous behaviour use `-prefer-predicate-over-epilogue=scalar-epilogue`.

- `llvm-objdump` now has basic support for switching between disassembling code and data using mapping symbols such as `$x` and `$d`. Switching architectures using `$x` with an architecture string suffix is not yet supported.

- Ssctr and Smctr extensions are no longer experimental.

- Add support for Zvfbfa (Additional BF16 vector compute support)

- Adds experimental support for the ‘Zibi` (Branch with Immediate) extension.

- Add support for Zvfofp8min (OFP8 conversion extension)

- Adds assembler support for the Andes `XAndesvsinth` (Andes Vector Small Int Handling Extension).

- DWARF fission is now compatible with linker relaxations, allowing `-gsplit-dwarf` and `-mrelax` to be used together when building for the RISC-V platform.

- The Xqci Qualcomm uC Vendor Extension is no longer marked as experimental.

- The Xqccmp Qualcomm Vendor Extension is no longer marked as experimental.

## Changes to the WebAssembly Backend

- `half` now uses a soft float lowering, which resolves various precision and bitcast issues.

- The `wasm32-wasi` target has been renamed to `wasm32-wasip1`. The old option is still recognized, though by default will emit a deprecation warning.

## Changes to the Windows Target

- `-fpseudo-probe-for-profiling` is now supported for COFF.

## Changes to the X86 Backend

- `-mcpu=wildcatlake` is now supported.

- `-mcpu=novalake` is now supported.

## Changes to the OCaml bindings

- The IR reader bindings renamed `parse_ir` to `parse_ir_bitcode_or_assembly` to clarify that the parser accepts both textual IR and bitcode. This rename is intentional to force existing code to update because the ownership semantics changed: the function no longer takes ownership of the input memory buffer.

## Changes to the Python bindings

## Changes to the C API

- Add `LLVMGetOrInsertFunction` to get or insert a function, replacing the combination of `LLVMGetNamedFunction` and `LLVMAddFunction`.

- Allow `LLVMGetVolatile` to work with any kind of Instruction.

- Add `LLVMConstFPFromBits` to get a constant floating-point value from an array of 64 bit values.

- Add `LLVMParseIRInContext2`, which is equivalent to `LLVMParseIRInContext` but does not take ownership of the input `LLVMMemoryBufferRef`. This matches the underlying C++ API and avoids ownership surprises in language bindings and examples.

- Functions working on the global context have been deprecated. Use the functions that work on a specific context instead.

  - `LLVMGetGlobalContext` -> use `LLVMContextCreate` context instead

  - `LLVMInt1Type` -> `LLVMInt1TypeInContext`

  - `LLVMInt8Type` -> `LLVMInt8TypeInContext`

  - `LLVMInt16Type` -> `LLVMInt16TypeInContext`

  - `LLVMInt32Type` -> `LLVMInt32TypeInContext`

  - `LLVMInt64Type` -> `LLVMInt64TypeInContext`

  - `LLVMInt128Type` -> `LLVMInt128TypeInContext`

  - `LLVMIntType` -> `LLVMIntTypeInContext`

  - `LLVMHalfType` -> `LLVMHalfTypeInContext`

  - `LLVMBFloatType` -> `LLVMBFloatTypeInContext`

  - `LLVMFloatType` -> `LLVMFloatTypeInContext`

  - `LLVMDoubleType` -> `LLVMDoubleTypeInContext`

  - `LLVMX86FP80Type` -> `LLVMX86FP80TypeInContext`

  - `LLVMFP128Type` -> `LLVMFP128TypeInContext`

  - `LLVMPPCFP128Type` -> `LLVMPPCFP128TypeInContext`

  - `LLVMStructType` -> `LLVMStructTypeInContext`

  - `LLVMVoidType` -> `LLVMVoidTypeInContext`

  - `LLVMLabelType` -> `LLVMLabelTypeInContext`

  - `LLVMX86AMXType` -> `LLVMX86AMXTypeInContext`

  - `LLVMConstString` -> `LLVMConstStringInContext2`

  - `LLVMConstStruct` -> `LLVMConstStructInContext`

  - `LLVMMDString` -> `LLVMMDStringInContext2`

  - `LLVMMDNode` -> `LLVMMDNodeInContext2`

  - `LLVMAppendBasicBlock` -> `LLVMAppendBasicBlockInContext`

  - `LLVMInsertBasicBlock` -> `LLVMInsertBasicBlockInContext`

  - `LLVMCreateBuilder` -> `LLVMCreateBuilderInContext`

  - `LLVMIntPtrType` -> `LLVMIntPtrTypeInContext`

  - `LLVMIntPtrTypeForAS` -> `LLVMIntPtrTypeForASInContext`

  - `LLVMParseBitcode` -> `LLVMParseBitcodeInContext2`

  - `LLVMParseBitcode2` -> `LLVMParseBitcodeInContext2`

  - `LLVMGetBitcodeModule` -> `LLVMGetBitcodeModuleInContext2`

  - `LLVMGetBitcodeModule2` -> `LLVMGetBitcodeModuleInContext2`

- Add `LLVMGetSwitchCaseValue` and `LLVMSetSwitchCaseValue` to get and set switch case values; switch case values are no longer operands of the instruction.

## Changes to the CodeGen infrastructure

## Changes to the Metadata Info

## Changes to the Debug Info

## Changes to the LLVM tools

- `llvm-profgen` now supports decoding pseudo probe for COFF binaries.

- `llvm-readelf` now dumps all hex format values in lower-case mode.

- Some code paths for supporting Python 2.7 in `llvm-lit` have been removed.

- Support for `%T` in lit has been removed.

- Add `--save-stats` option to `llc` to save LLVM statistics to a file. Compatible with the Clang option.

- Add `--save-stats` option to `opt` to save LLVM statistics to a file. Compatible with the Clang option.

- `llvm-config` gained a new flag `--quote-paths` which quotes and escapes paths emitted on stdout, to account for spaces or other special characters in path. (`#97305 <https://github.com/llvm/llvm-project/pull/97305>`_).

- `llvm-objdump` now supports using `--mcpu=help` and `--mattr=help` with the `--triple` option without requiring an input file or the `-d` (disassemble) flag.

## Changes to LLDB

- LLDB can now set breakpoints, show backtraces, and display variables when debugging Wasm with supported runtimes (WAMR and V8).

- LLDB now has a Wasm platform, which can be configured to run WebAssembly binaries directly under a Wasm runtime. Configurable through the platform.plugin.wasm settings.

- LLDB no longer stops processes by default when receiving SIGWINCH signals (window resize events) on Linux. This is the default on other Unix platforms. You can re-enable it using `process handle --notify=true --stop=true SIGWINCH`.

- The `show-progress` setting, which became a NOOP with the introduction of the statusline, now defaults to off and controls using OSC escape codes to show a native progress bar in supporting terminals like Ghostty and ConEmu.

- The default PDB reader on Windows was changed from DIA to native, which uses LLVM’s PDB and CodeView support. You can switch back to the DIA reader with `settings set plugin.symbol-file.pdb.reader dia`. Note that support for the DIA reader will be removed in a future version of LLDB.

- A `--verbose` option was added to the `version` command. When `--verbose` is used, LLDB’s build configuration is included in the command’s output. This includes all the supported targets, along with the presence of (or lack of) optional features like XML parsing.

- LLDB now includes formatters for many types from the MSVC STL.

- DIL (the new `frame variable` implementation) now uses ‘:’ as a bitfield extraction range character. ‘-’ is deprecated and will output an error when used.

- LLDB 22 is the last release supporting FreeBSD 13 and below. As a result, LLDB 23 will remove support for FreeBSD on MIPS64 and assume that FreeBSD targets have watchpoint support.

## Changes to BOLT

- Added support for lite mode on AArch64. It can be enabled with -lite=1. When used, BOLT avoids duplicating cold code by reusing the original code, which reduces output binary size.

## Changes to Sanitizers

- Support running TypeSanitizer with UndefinedBehaviourSanitizer.

- TypeSanitizer no longer inlines all instrumentation by default. Added the `-f[no-]sanitize-type-outline-instrumentation` flags to give users control over this behaviour.

## Other Changes

- Introduces the `AllocToken` pass, an instrumentation pass providing tokens to memory allocators enabling various heap organization strategies, such as heap partitioning.

- Integrated Distributed ThinLTO (DTLTO) aims to support distribution of ThinLTO backend compilations for any in-process ThinLTO invocation. To enable this, support for the ThinLTO cache (for incremental builds) has been added in this release, and support for additional input file types has been implemented.

  Bitcode objects contained in static libraries and archives (e.g. libc.a) are now handled transparently by temporarily extracting referenced objects for distribution. When thin archives are used (supported since LLVM 21), no extraction is required.

  DTLTO creates a number of temporary files during operation, which are now cleaned up correctly when the process exits abnormally, for example due to Ctrl+C or similar termination events.

  A new DTLTO linker option, –thinlto-remote-compiler-prepend-arg, has been added to support multi-call LLVM drivers. This option allows specifying an additional argument to select the desired subcommand, for example `llvm clang ....`

  Note that ELF and COFF remain the only supported platforms.

# External Open Source Projects Using LLVM 15

- A project…

# Additional Information

A wide variety of additional information is available on the LLVM web page, in particular in the documentation section. The web page also contains versions of the API documentation which is up-to-date with the Git version of the source code. You can access versions of these documents specific to this release by going into the `llvm/docs/` directory in the LLVM tree.

If you have any questions or comments about LLVM, please feel free to contact us via the Discourse forums.