FreeBSD/ports c59e260 — comms/gnuradio Makefile pkg-plist

comms/gnuradio: Build QtGui

Set some paths and ENABLE_GR_QTGUI=ON to build QtGui

PR:             289371
Reported by:    Frans van der Veer
DeltaFile
+183-0comms/gnuradio/pkg-plist
+6-2comms/gnuradio/Makefile
+189-22 files

NetBSD/pkgsrc-wip 9f6a4b9 — . Makefile, geeqie-git distinfo DESCR

geeqie-git: add git package for geeqie
DeltaFile
+82-0geeqie-git/PLIST
+63-0geeqie-git/Makefile
+31-0geeqie-git/options.mk
+5-0geeqie-git/distinfo
+5-0geeqie-git/DESCR
+1-0Makefile
+187-06 files

LLVM/project 4428e95 — libc/src/__support/OSUtil/linux/syscall_wrappers fchownat.h, libc/src/unistd fchownat.h

[libc] Implement fchownat in unistd (#227974)

Implement the standard POSIX.1-2008 / POSIX.1-2024 function `fchownat`
in `<unistd.h>`, bringing the POSIX `*at` family of functions in
`<unistd.h>` to 100% completion.

Fixes #227848

Assisted by Antigravity and reviewed by Aman Maurya
DeltaFile
+119-0libc/test/src/unistd/fchownat_test.cpp
+37-0libc/src/__support/OSUtil/linux/syscall_wrappers/fchownat.h
+34-0libc/src/unistd/linux/fchownat.cpp
+28-0libc/src/unistd/fchownat.h
+22-0libc/test/src/unistd/CMakeLists.txt
+15-0libc/src/unistd/linux/CMakeLists.txt
+255-07 files not shown
+290-013 files

LLVM/project 0d151f3 — llvm/lib/Transforms/Vectorize VPlanConstruction.cpp, llvm/test/Transforms/LoopVectorize outer-loop-inner-latch-successors.ll

[VPlan] Canonicalize all inner loop headers and latches in plain CFG. (#228763)

The plain CFG mirrors the IR's predecessor and successor order.
Canonicalize all loops up front, to avoid verification issues when
vectorizing outer loops.

Fixes a crash with the newly added test.
DeltaFile
+88-1llvm/test/Transforms/LoopVectorize/outer-loop-inner-latch-successors.ll
+17-4llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
+105-52 files

NextBSD/src eef4669 — .github/workflows build.yml, tests loader.exp.inc qemu-arch.sh

T4: boot gates run on the shared nextbsd-ci harness @v0.2.1 (login-only)

img-boot-test.sh + iso-boot-test.sh become thin entry points onto the shared
harness (NB_LOGIN_ONLY; the live ISO adds NB_MEDIA=cd): they extract the
zipped artifact, check out nextbsd/nextbsd-ci at v0.2.1 (pinned tag = no drift),
and run harness/boot-test.sh. The loader un-mute dance, the arch-aware qemu
argv, login detection and teardown now come from the shared harness (one place,
every arch, kept green by its selftest) instead of the in-repo copies.

Delete the 1512-line tests/boot-test.sh monolith (nothing in CI invoked it) and
the in-repo tests/loader.exp.inc + tests/qemu-arch.sh (superseded by the
harness's contract.exp.inc + qemu-arch.sh). The jobs' serial-log dumps point at
the harness transcript. Both gates stay NON-GATING as before (not in release's
needs); the gate is the harness exit class.
DeltaFile
+0-1,512tests/boot-test.sh
+20-198tests/img-boot-test.sh
+18-188tests/iso-boot-test.sh
+0-119tests/qemu-arch.sh
+0-92tests/loader.exp.inc
+8-8.github/workflows/build.yml
+46-2,1171 files not shown
+47-2,1187 files

FreeBSD/ports 48ef898 — mail/fetchmail Makefile distinfo

mail/fetchmail: Update 6.6.8 => 6.6.9

Release Notes:
https://gitlab.com/fetchmail/fetchmail/-/blob/6.6.9/NEWS

PR:             299096
Sponsored by:   UNIS Labs (vvd, commit patch)
MFH:            2026Q4

(cherry picked from commit 14d62b999bd64260ee68f3c793eb41909572062e)
DeltaFile
+3-3mail/fetchmail/distinfo
+1-1mail/fetchmail/Makefile
+4-42 files

FreeBSD/ports 14d62b9 — mail/fetchmail Makefile distinfo

mail/fetchmail: Update 6.6.8 => 6.6.9

Release Notes:
https://gitlab.com/fetchmail/fetchmail/-/blob/6.6.9/NEWS

PR:             299096
Sponsored by:   UNIS Labs (vvd, commit patch)
MFH:            2026Q4
DeltaFile
+3-3mail/fetchmail/distinfo
+1-1mail/fetchmail/Makefile
+4-42 files

FreeBSD/ports 3efeda4 — www/deno Makefile, www/deno/files patch-ext_node_ops_process.rs patch-cargo-crates_v8-150.4.0_third__party_rust_temporal__capi_BUILD.gn

www/deno: enable Temporal, fix deno compile

- Re-enable Temporal support in V8.  Use the cargo-vendored
  temporal_capi crate instead of building it with GN, which would need
  the Chromium Rust toolchain; a static library built from it in
  pre-build is linked into mksnapshot.
- Fix executables produced by `deno compile`, which failed with
  "Exec format error": libsui relocated the program header table past
  the first page, which the FreeBSD kernel rejects.  For executables,
  store the payload in a non-allocated section and read it back from
  the file instead.
- Implement os.cpus() with sysctl(3) instead of returning dummy
  values, and process.title with setproctitle(3).
- Use system sqlite3, libffi, libdeflate and liblzma instead of
  bundled copies.
- Drop unused openssl crates from CARGO_CRATES; they were only needed
  by keyring's vendored feature, which is already disabled.
- Remove obsolete patches for the release channel and tsgo.
DeltaFile
+210-1www/deno/files/patch-cargo-crates_libsui-0.16.4_lib.rs
+78-44www/deno/files/patch-ext_node_ops_os_cpus.rs
+0-30www/deno/files/patch-cli_lib_version.rs
+25-4www/deno/Makefile
+26-0www/deno/files/patch-ext_node_ops_process.rs
+26-0www/deno/files/patch-cargo-crates_v8-150.4.0_third__party_rust_temporal__capi_BUILD.gn
+365-797 files not shown
+410-13013 files

FreeBSD/ports 86e0d73 — www/waterfox Makefile distinfo

www/waterfox: Update 6.7.4 => 6.7.5

Release Notes:
https://www.waterfox.com/releases/6.7.5/

PR:             299081
Sponsored by:   UNIS Labs (vvd, commit patch)
MFH:            2026Q4

(cherry picked from commit d05159827ae87c28c22192e96c289526cd87db6f)
DeltaFile
+5-5www/waterfox/distinfo
+2-2www/waterfox/Makefile
+7-72 files

FreeBSD/ports d051598 — www/waterfox Makefile distinfo

www/waterfox: Update 6.7.4 => 6.7.5

Release Notes:
https://www.waterfox.com/releases/6.7.5/

PR:             299081
Sponsored by:   UNIS Labs (vvd, commit patch)
MFH:            2026Q4
DeltaFile
+5-5www/waterfox/distinfo
+2-2www/waterfox/Makefile
+7-72 files

LLVM/project d9c433a — mlir/docs Canonicalization.md, mlir/docs/DefiningDialects _index.md

[mlir][tblgen] Warn about the deprecated multi-result fold form

The legacy form `LogicalResult fold(FoldAdaptor,
SmallVectorImpl<OpFoldResult> &)` will be removed. This patch makes
`mlir-tblgen -gen-op-decls` warn when a dialect keeps `useOpFoldResults`
at 0 and has an op with `hasFolder` that does not have exactly one fixed
result. The warning points at the dialect definition. A note names the
first op that uses the legacy form.

The warning comes once for each dialect in one `-gen-op-decls` run. A
dialect with ops in more than one `.td` file can warn once for each file
that contains such an op. `-gen-op-defs` does not warn.

No in-tree dialect warns, because each in-tree dialect with such an op
already sets the bit.

The diagnostic follows the `-on-deprecated` option: `none` silences it,
`warn` (the default) warns, and `error` reports an error and fails the
run. `MlirTblgenMain.h` exposes the option value through

    [3 lines not shown]
DeltaFile
+88-0mlir/test/mlir-tblgen/op-fold-results-deprecation.td
+45-3mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+6-3mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp
+6-0mlir/include/mlir/Tools/mlir-tblgen/MlirTblgenMain.h
+3-1mlir/docs/Canonicalization.md
+4-0mlir/docs/DefiningDialects/_index.md
+152-76 files

LLVM/project 272e3d7 — clang/lib/CIR/Dialect/IR CIRDialect.cpp, clang/test/CIR/Transforms canonicalize.cir

[mlir] Deprecate the legacy fold APIs with a results vector

The legacy `Operation::fold` overloads with a
`SmallVectorImpl<OpFoldResult> &` parameter drop partial folds. The
overloads that return `OpFoldResults` keep them.

This patch moves every in-tree caller of the legacy overloads to the
overloads that return `OpFoldResults`, except the unit tests of the
legacy APIs. `OpFoldResultsTest.cpp` suppresses the deprecation warnings
for these tests. Then the patch marks these APIs as deprecated: the two
legacy `Operation::fold` overloads, the legacy general `foldTrait` form,
the legacy fold hook overloads of `DynamicOpDefinition`, and the
`DynamicOpDefinition::LegacyFoldHookFn` alias. ODS cannot put an
attribute on an interface method, so only the documentation marks the
legacy `DialectFoldInterface::fold` method as deprecated.

The new code in `cir::CastOp::fold` also fixes two bugs. The fold
crashed when the source of an integral cast was a block argument, and it
read the fold result of result 0 when the source was a different result

    [17 lines not shown]
DeltaFile
+14-11mlir/lib/IR/ExtensibleDialect.cpp
+17-0clang/test/CIR/Transforms/canonicalize.cir
+11-4mlir/lib/IR/Operation.cpp
+6-8mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+11-2mlir/include/mlir/IR/ExtensibleDialect.h
+6-5clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+65-309 files not shown
+103-4715 files

LLVM/project 2bb3da7 — clang/include/clang/CIR/Dialect/IR CIRDialect.td, clang/lib/CIR/Dialect/IR CIRDialect.cpp

[mlir][CIR] Use OpFoldResults for the cir.scope fold

The CIR dialect now sets the `useOpFoldResults` bit. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each CIR op that does not have
exactly one fixed result. `cir.scope` is the only such op with a fold.
Its fold now returns the yielded value directly. The behavior does not
change. The existing test `clang/test/CIR/Transforms/canonicalize.cir`
covers this fold.

Signed-off-by: Víctor Pérez Carrasco <victor.pc.upm at gmail.com>
DeltaFile
+2-4clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+2-0clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+4-42 files

LLVM/project 9739980 — mlir/lib/Dialect/Math/IR MathOps.cpp, mlir/lib/Dialect/Shape/IR Shape.cpp

[mlir] Use OpFoldResults in more upstream dialects

The scf, shape, sparse_tensor, gpu, math, and builtin dialects now set
the `useOpFoldResults` bit. ODS then declares `OpFoldResults
fold(FoldAdaptor)` for each of their ops that does not have exactly one
fixed result. This patch moves the seven folds of such ops to the new
form: `scf.if`, `shape.split_at`, `sparse_tensor.crd_translate`,
`gpu.memcpy`, `gpu.memset`, `math.sincos`, and
`builtin.unrealized_conversion_cast`.

The behavior of the folds does not change, except in the graph-region
case below. Each fold builds the same normalized `OpFoldResults` object
that the legacy adapter built from the old return. The existing tests of
each dialect cover these folds.

In a graph region, an operand that `unrealized_conversion_cast` or
`sparse_tensor.crd_translate` forwards can be another result of the
same op that the same fold replaces. The new form drops such a fold.
For a forward chain, the legacy form gave a correct result by the order

    [22 lines not shown]
DeltaFile
+37-0mlir/test/Dialect/Builtin/canonicalize.mlir
+16-0mlir/test/Dialect/SparseTensor/fold.mlir
+6-9mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
+4-9mlir/lib/IR/BuiltinDialect.cpp
+3-7mlir/lib/Dialect/Math/IR/MathOps.cpp
+3-5mlir/lib/Dialect/Shape/IR/Shape.cpp
+69-308 files not shown
+79-3614 files

LLVM/project 70dae20 — mlir/include/mlir/Dialect/Linalg/IR LinalgBase.td, mlir/lib/Dialect/Linalg/IR LinalgOps.cpp

[mlir][linalg] Use OpFoldResults for linalg folds

The linalg dialect now sets the `useOpFoldResults` bit. ODS then
declares `OpFoldResults fold(FoldAdaptor)` for each linalg op that does
not have exactly one fixed result. This patch moves the eleven folds of
such ops in `LinalgOps.cpp` to the new form. It also changes the fold
template of `mlir-linalg-ods-yaml-gen`, so the generated named ops use
the new form too.

The behavior of the folds does not change. A fold that returned the
result of `memref::foldMemRefCast` now returns the same in-place state
through the `LogicalResult` constructor. The folds of `transpose`,
`pack`, and `unpack` return their replacement value directly.

The yaml-gen test now checks the generated fold definition.

A build directory that uses a native `mlir-linalg-ods-yaml-gen` does
not regenerate `LinalgNamedStructuredOps.yamlgen.cpp.inc` when the tool
changes. Delete that file before the build.

    [2 lines not shown]
DeltaFile
+19-36mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
+1-2mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-yaml-gen.cpp
+3-0mlir/test/mlir-linalg-ods-gen/test-linalg-ods-yaml-gen.yaml
+1-0mlir/include/mlir/Dialect/Linalg/IR/LinalgBase.td
+24-384 files

LLVM/project ffbad97 — mlir/include/mlir/Dialect/Vector/IR Vector.td, mlir/lib/Dialect/Vector/IR VectorOps.cpp

[mlir][vector] Use OpFoldResults for vector folds

The vector dialect now sets the `useOpFoldResults` bit. ODS then
declares `OpFoldResults fold(FoldAdaptor)` for each vector op that does
not have exactly one fixed result. This patch moves the five folds of
such ops to the new form: `to_elements`, `transfer_write`, `store`,
`masked_store`, and `mask`.

The behavior of the folds does not change, except in the graph-region
case below. A fold that returned success with an empty vector now
returns `success()`, which is an in-place change. A fold that filled the
vector now returns its values.

The all-true fold of `vector.mask` moves the masked op out of the
region, and the terminator then has null operands. So this fold must
replace every result, and the driver erases the op. A mask without
results has nothing to replace, so the fold reports the move as an
in-place change.


    [26 lines not shown]
DeltaFile
+65-0mlir/test/Dialect/Vector/canonicalize.mlir
+22-17mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+1-0mlir/include/mlir/Dialect/Vector/IR/Vector.td
+88-173 files

LLVM/project 351f9a6 — mlir/include/mlir/Dialect/MemRef/IR MemRefBase.td, mlir/lib/Dialect/MemRef/IR MemRefOps.cpp

[mlir][memref] Use OpFoldResults for memref folds

The memref dialect now sets `useOpFoldResults`. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each memref op that does not have
exactly one fixed result. This patch moves the seven folds of such ops
to the new form: `copy`, `dealloc`, `dma_start`, `dma_wait`,
`extract_strided_metadata`, `prefetch`, and `store`. The behavior of
these folds does not change, except for `extract_strided_metadata`.

The `memref.extract_strided_metadata` fold created `arith.constant` ops
with its own builder and replaced the uses of the constant results
itself. No driver saw these changes. The fold now returns a partial
fold: one replacement for each constant result, and an in-place mark
when it removes a `memref.cast` source. This patch removes the helper
`replaceConstantUsesOf`, which has no other user.

DialectConversion folds an op before it applies the patterns. So the
conversion did not see the new constants and left them unconverted.
With pattern rollback on, the conversion now does not apply the partial

    [27 lines not shown]
DeltaFile
+24-59mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
+25-0mlir/test/Conversion/MemRefToLLVM/memref-to-llvm.mlir
+1-0mlir/include/mlir/Dialect/MemRef/IR/MemRefBase.td
+50-593 files

LLVM/project 8054091 — mlir/include/mlir/Dialect/Affine/IR AffineOps.td, mlir/lib/Dialect/Affine/IR AffineOps.cpp

[mlir][affine] Use OpFoldResults for affine folds

The affine dialect now sets `useOpFoldResults`. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each affine op that does not have
exactly one fixed result. This patch moves the eight folds of such ops
to the new form: `dma_start`, `dma_wait`, `for`, `if`, `store`,
`prefetch`, `parallel`, and `delinearize_index`. The behavior of these
folds does not change, with two exceptions.

The `affine.delinearize_index` fold now replaces each result whose basis
element is 1 with the constant 0, and keeps the other results. In
`Tensor/bubble-up-extract-slice-op.mlir`, these results now fold to a
constant 0. The new test `Affine/fold-partial.mlir` runs
`-test-single-fold` and `-sccp`, because `-canonicalize` also runs
`DropUnitExtentBasis`, which hides a broken fold.

In a graph region, an init of a zero-trip `affine.for` can be another
result of the same loop. The fold also replaces that result, so the new
form drops the fold. For a forward chain such as

    [21 lines not shown]
DeltaFile
+43-41mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+74-0mlir/test/Dialect/Affine/fold-partial.mlir
+37-0mlir/test/Dialect/Affine/canonicalize.mlir
+6-4mlir/test/Dialect/Tensor/bubble-up-extract-slice-op.mlir
+1-0mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
+161-455 files

LLVM/project caf6afe — mlir/include/mlir/Dialect/Arith/IR ArithBase.td, mlir/lib/Dialect/Arith/IR ArithOps.cpp

[mlir][arith] Use OpFoldResults for arith folds

The arith dialect now sets `useOpFoldResults`. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each arith op that does not have
exactly one fixed result. This patch moves the four folds of such ops to
the new form: `addui_extended`, `subui_extended`, `mulsi_extended`, and
`mului_extended`. The behavior of these folds does not change, with two
exceptions.

The `arith.mulsi_extended` fold now replaces the low result of
`mulsi_extended(x, 1)` by `x`, and keeps the high result. This is also
correct for i1, where the constant `true` is -1. The i1 tests in
`Arith/canonicalize.mlir` change their expected output.

In a graph region, the identity fold of `addui_extended`,
`subui_extended`, or `mului_extended` can forward an operand that is the
other result of the same op. The fold also replaces that result, so the
new form drops the fold. The legacy form gave a correct result in this
case, because it first moved the uses to the forwarded result, and then

    [7 lines not shown]
DeltaFile
+22-52mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+73-0mlir/test/Dialect/Arith/fold-partial.mlir
+2-2mlir/test/Dialect/Arith/canonicalize.mlir
+1-0mlir/include/mlir/Dialect/Arith/IR/ArithBase.td
+98-544 files

LLVM/project ab63954 — mlir/lib/Analysis/DataFlow ConstantPropagationAnalysis.cpp, mlir/test/Transforms sccp.mlir

[mlir] Use the replaced results of a partial fold in SCCP

`SparseConstantPropagation` now uses the `OpFoldResults` form of
`Operation::fold`. It merges the value of each replaced result into the
lattice of that result, and it sets each kept result to the entry
state. A kept result must not join with its own lattice, because that
leaves the lattice uninitialized. Before this patch, SCCP saw a partial
fold as a failure and set every result to the entry state.

The new test in `sccp.mlir` checks that SCCP uses the replaced results
and that the kept result stays overdefined.

Signed-off-by: Víctor Pérez Carrasco <victor.pc.upm at gmail.com>
DeltaFile
+14-9mlir/lib/Analysis/DataFlow/ConstantPropagationAnalysis.cpp
+21-0mlir/test/Transforms/sccp.mlir
+35-92 files

LLVM/project a548a59 — mlir/lib/Transforms/Utils DialectConversion.cpp, mlir/test/Transforms test-legalizer-fold-dead-result.mlir test-legalizer-partial-fold.mlir

[mlir] Apply partial folds in DialectConversion

`OperationLegalizer::legalizeWithFold` now applies a partial fold when
pattern rollback is off. The legalizer cannot roll back the replacement
of some results of an op that stays. So with rollback on, the legalizer
applies a fold only if it replaces every result or changes the op in
place, as before. Without rollback, the legalizer uses the
`PartialLiveOnly` mode of `OpBuilder::tryFold`, replaces the uses of
each replaced result, and tries to legalize the op again.

In a graph region, the replacement skips the uses that come before the
replacement value. So the legalizer counts progress by the use counts
of the replaced results. A fold that replaces all results still erases
the op, also when all of its results have no uses. A fold that gives no
replacement and no in-place change fails.

The new tests `test-legalizer-partial-fold.mlir` and
`test-legalizer-fold-dead-result.mlir` run both modes.

Signed-off-by: Víctor Pérez Carrasco <victor.pc.upm at gmail.com>
DeltaFile
+118-0mlir/test/Transforms/test-legalizer-partial-fold.mlir
+65-10mlir/lib/Transforms/Utils/DialectConversion.cpp
+36-0mlir/test/Transforms/test-legalizer-fold-dead-result.mlir
+219-103 files

LLVM/project fc17b3e — mlir/docs Canonicalization.md, mlir/docs/DefiningDialects _index.md

[mlir] Apply partial folds in the greedy pattern rewrite driver

The greedy driver now applies the `OpFoldResults` of a fold:
- A fold that replaces every result erases the op. A result without
  uses gets no constant.
- A partial fold replaces the uses of each replaced result and keeps
  the op. The driver puts the op on the worklist again.
- The materialization of constants is all-or-nothing. When one
  constant fails, the driver erases only the constants of this call
  and applies no replacement. An in-place change still counts.
- A fold that keeps every result and has no in-place mark fails.

The driver uses `detail::materializeFoldResults` for the constants.

When `MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS` is on, the driver
compares the fingerprints of the op before and after the fold. A fold
that changes the op and returns failure is a fatal error. A fold that
changes an op that stays, without an in-place mark, is also a fatal
error.

    [8 lines not shown]
DeltaFile
+53-54mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
+98-0mlir/test/Transforms/test-canonicalize.mlir
+57-7mlir/docs/Canonicalization.md
+14-3mlir/docs/DefiningDialects/_index.md
+12-0mlir/test/Transforms/test-canonicalize-unmarked-in-place-fold.mlir
+7-2mlir/docs/Traits/_index.md
+241-661 files not shown
+245-677 files

LLVM/project cd6239e — mlir/include/mlir/Transforms FoldUtils.h, mlir/lib/Transforms/Utils FoldUtils.cpp

[mlir] Apply partial folds in OperationFolder

`OperationFolder::tryToFold` now applies the `OpFoldResults` of a fold.
A fold that replaces every result erases the op. A partial fold replaces
the uses of each replaced result, keeps the op, and sets
`inPlaceUpdate`. The folder materializes constants only for the replaced
results that have uses. If a constant fails to materialize, no result is
replaced, and an in-place change still counts. The private vector
overload of `tryToFold` has no callers after this change, so this patch
removes it.

This patch also fixes `OperationFolder::processFoldResults`. It moved a
reused constant to the front of the block as soon as it used the
constant for a result. If a later result then failed to materialize,
the cleanup erased all ops before the insertion point. These ops
included the moved constant, which still had uses. The folder now moves
the reused constants only after all results materialize.

The bug does not need partial folds. Without this patch, the new test

    [16 lines not shown]
DeltaFile
+98-0mlir/test/Transforms/constant-fold.mlir
+60-35mlir/lib/Transforms/Utils/FoldUtils.cpp
+9-13mlir/include/mlir/Transforms/FoldUtils.h
+167-483 files

LLVM/project 80e2f25 — mlir/include/mlir/IR Builders.h, mlir/lib/IR Builders.cpp

[mlir] Apply partial folds in OpBuilder::createOrFold

`OpBuilder::tryFold` gets a `FoldApplyMode` argument and an optional
in-place output. The default mode, `AllOrNothing`, keeps the old
contract: a fold that does not replace every result counts as an
in-place fold if it changed the op, and as a failure otherwise. The
`Partial` mode materializes each replaced result and puts the result of
the op in the entry of each kept result. The `PartialLiveOnly` mode
also skips the replaced results without uses. A later patch uses this
mode in DialectConversion.

The multi-result `createOrFold` uses the `Partial` mode. When the fold
keeps a result, the new op stays, and the results of `createOrFold` mix
the replacement values and the kept results of the op.

The new helper `detail::materializeFoldResults` materializes the
constants of a fold. It creates each constant unlinked and inserts the
constants only after all of them materialize. If one constant fails, it
erases the constants of this call and gives no replacement. `tryFold`

    [7 lines not shown]
DeltaFile
+90-41mlir/lib/IR/Builders.cpp
+60-6mlir/include/mlir/IR/Builders.h
+23-0mlir/test/Transforms/test-operation-folder.mlir
+18-1mlir/test/lib/Dialect/Test/TestPatterns.cpp
+7-0mlir/test/lib/Dialect/Test/TestOps.td
+198-485 files

LLVM/project 2bc630f — mlir/lib/Dialect/Shape/IR Shape.cpp

[mlir][shape] Report the in-place change of the assuming_all fold

The `shape.assuming_all` fold visits its inputs in reverse order. It
erases each constant input from the operands, and it returns null at
the first input that is not constant. If the fold already erased an
input at that point, it changed the op but reported a failure, so no
driver knew about the change. The fold now returns the result of the op
in this case, which is the in-place signal of the single-result fold
form.

No test fails on main. A later patch adds a fingerprint check of each
fold to the greedy driver, under
`MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS`. With that check and without
this fix, the existing test `Dialect/Shape/canonicalize.mlir` fails:

  $ mlir-opt -split-input-file -allow-unregistered-dialect \
      -canonicalize="test-convergence" \
      mlir/test/Dialect/Shape/canonicalize.mlir
  LLVM ERROR: fold returned failure but changed the operation

    [2 lines not shown]
DeltaFile
+9-4mlir/lib/Dialect/Shape/IR/Shape.cpp
+9-41 files

LLVM/project 4c6bfe7 — mlir/include/mlir/IR DialectBase.td, mlir/lib/TableGen Dialect.cpp

[mlir] Add the useOpFoldResults ODS dialect bit

The new `OpFoldResults fold(FoldAdaptor)` form needs a matching ODS
declaration. This patch adds the dialect bit `useOpFoldResults`. The bit
is off by default. When a dialect sets it, `genFolderDecls` declares
`OpFoldResults fold(FoldAdaptor adaptor)` for each op that does not have
exactly one fixed result. An op with one fixed result keeps the
`OpFoldResult` form. A dialect without the bit keeps the legacy
declaration.

The `test` dialect sets the bit. Its three folds of ops that do not have
exactly one fixed result now use the new form. The behavior of these
folds does not change, with one exception: the fold of
`TestOpWithVariadicResultsAndFolder` with no operands now fails. Before,
it reported an in-place change, but it changed nothing. The greedy
driver then put the op on the worklist again and folded it again, so
canonicalize did not stop. A new test in `test-canonicalize.mlir`
covers this case. Without this patch, canonicalize does not stop on the
test file, and `timeout` ends it:

    [16 lines not shown]
DeltaFile
+107-0mlir/test/mlir-tblgen/op-fold-results.td
+77-14mlir/test/lib/Dialect/Test/TestOpDefs.cpp
+60-2mlir/test/lib/Dialect/Test/TestOps.td
+9-0mlir/test/Transforms/test-canonicalize.mlir
+5-0mlir/include/mlir/IR/DialectBase.td
+4-0mlir/lib/TableGen/Dialect.cpp
+262-163 files not shown
+269-169 files

LLVM/project 85ecfc7 — mlir/include/mlir/IR OpDefinition.h, mlir/include/mlir/Interfaces FoldInterfaces.h DialectFoldInterface.td

[mlir] Add the OpFoldResults form to fold traits and DialectFoldInterface

The previous patch added `OpFoldResults fold(FoldAdaptor)` for ops. The
fold traits and `DialectFoldInterface` still use only the legacy vector
form, which cannot express a partial fold.

A trait can now define `static OpFoldResults foldTrait(Operation *,
ArrayRef<Attribute>)`. The trait fold dispatch detects this form by its
return type and calls it directly. This form has the same parameters as
the single-result trait form, so the single-result detector excludes it.
The legacy trait form still works through the strict adapter.
`IsCommutative` and `CastOpInterface` now use the new form.

`DialectFoldInterface` gets a new `fold` method that returns
`OpFoldResults`. Its default implementation calls the legacy `fold`
method through the strict adapter, so existing dialects keep their
behavior. `Operation::fold` now calls the new method.

The rule that a replacement does not name a result that the same fold

    [9 lines not shown]
DeltaFile
+281-3mlir/unittests/IR/OpFoldResultsTest.cpp
+28-10mlir/include/mlir/IR/OpDefinition.h
+12-6mlir/lib/IR/Operation.cpp
+17-0mlir/include/mlir/Interfaces/DialectFoldInterface.td
+11-1mlir/include/mlir/Interfaces/FoldInterfaces.h
+4-7mlir/lib/Interfaces/CastInterfaces.cpp
+353-272 files not shown
+358-338 files

LLVM/project a59bc0a — mlir/include/mlir/IR OperationSupport.h OpFoldResult.h, mlir/lib/IR OpFoldResult.cpp

[mlir] Add the OpFoldResults op fold form

An op can now define `OpFoldResults fold(FoldAdaptor)`. With this form,
a fold can replace some results of a multi-result op and keep the
others. The drivers still call the legacy `Operation::fold` overloads,
so they do not apply a partial fold yet. This form has the same
parameters as the single-result form, so the single-result detectors
also match it, and `getFoldHookFn` excludes it from the single-result
forms. `getFoldHookFn` selects the new form if the op defines it, else
the single-result form, else the legacy vector form. The new form then
folds the traits if its own fold replaces no result.

A replacement in a new-form result can be another result of the op
only if the fold keeps that result. The hook normalizes the result
first, so the op's own result in its own slot still means "keep". If a
replacement names a result that the same fold also replaces, the outcome
would depend on the order of the replacements, so the hook drops the
replacements. A forwarding fold can return such a result where an op can
use its own results: in a graph region or in an unreachable block.

    [16 lines not shown]
DeltaFile
+259-13mlir/unittests/IR/OpFoldResultsTest.cpp
+45-5mlir/include/mlir/IR/OpDefinition.h
+14-4mlir/include/mlir/IR/OpFoldResult.h
+14-0mlir/lib/IR/OpFoldResult.cpp
+2-1mlir/include/mlir/IR/OperationSupport.h
+334-235 files

LLVM/project 2ed8ec3 — mlir/include/mlir/IR ExtensibleDialect.h OperationSupport.h, mlir/lib/IR ExtensibleDialect.cpp Operation.cpp

[mlir] Return OpFoldResults from the type-erased fold hooks

The type-erased fold hooks return `LogicalResult` and fill a vector of
`OpFoldResult`. This form cannot express a fold that replaces only some
results of an op. This patch changes the hooks to return
`OpFoldResults`. The drivers do not use partial folds yet.

The single-result fold form, the legacy vector fold form, and the fold
traits go through adapters that return `OpFoldResults`. The legacy
vector form and the legacy trait form go through a strict adapter. Each
form then folds the traits if its own fold replaces no result. An op
without a fold method folds only the traits. The legacy hooks of
`DynamicOpDefinition` and `DialectFoldInterface` stay and go through
the same strict adapter.

The new `Operation::fold` overloads return a normalized
`OpFoldResults`. The legacy `Operation::fold` overloads return the full
vector only when the fold replaces all results. Otherwise they return
the in-place state and an empty vector. For folds and fold traits that

    [44 lines not shown]
DeltaFile
+330-0mlir/unittests/IR/OpFoldResultsTest.cpp
+80-66mlir/include/mlir/IR/OpDefinition.h
+33-43mlir/lib/IR/Operation.cpp
+30-23mlir/include/mlir/IR/OperationSupport.h
+39-2mlir/lib/IR/ExtensibleDialect.cpp
+20-3mlir/include/mlir/IR/ExtensibleDialect.h
+532-1373 files not shown
+568-1409 files

LLVM/project 4035e2e — mlir/include/mlir/IR OpFoldResult.h, mlir/lib/IR OpFoldResult.cpp

[mlir] Add OpFoldResults

A fold of a multi-result op can only replace all results or change the
op in place. It cannot replace some results and keep the others. For
example, a loop that yields one of its iteration arguments unchanged
could replace the matching result with the initial value and keep the
other results. This patch adds the class that holds such a partial
fold. Nothing uses the class yet.

The new class `OpFoldResults` in `mlir/IR/OpFoldResult.h` holds either
no replacement or one replacement per result, and an in-place bit. The
plural name says that the object holds one `OpFoldResult` per result of
the op. A null replacement keeps its result. `{}`, `nullptr`, and
`failure()` are failures, and `success()` is an in-place change.
`normalize` turns a replacement that is its own result into a null
replacement, and it clears the replacements if no result is replaced. In
assert builds, `normalize` also checks the type of each `Value`
replacement.


    [12 lines not shown]
DeltaFile
+452-0mlir/unittests/IR/OpFoldResultsTest.cpp
+125-0mlir/lib/IR/OpFoldResult.cpp
+104-1mlir/include/mlir/IR/OpFoldResult.h
+1-0mlir/unittests/IR/CMakeLists.txt
+682-14 files