571 Commits

Author SHA1 Message Date
Alessandro Di Federico 7d03759672 Drop test_pointer_array_emission 2026-06-15 17:28:22 +02:00
Ivan Krysak 57bbb7b962 Do not propagate model unnecessarily 2026-06-15 17:28:22 +02:00
Alessandro Di Federico 6a594a9133 MFP: rename namespace MFP into mfp 2026-06-11 17:39:53 +02:00
Alessandro Di Federico 4f52d444c6 tests/unit: add MFP tests 2026-06-11 17:39:53 +02:00
Alessandro Di Federico d03e62c250 MFP: add ExtraState, MFPConfiguration, variant
Three closely-coupled changes that have to land together to keep
every caller compiling:

- Introduce a per-instance ExtraState recording surface (with a
  NoExtraState default) and thread it through applyTransferFunction.
- Replace getMaximalFixedPoint's positional arg list with a single
  MFPConfiguration struct, so callers spell out only the fields they
  need.
- Replace the EntryLabels pointer with an Entry/All/vector* variant
  so callers can ask for the graph entry, every node, or a custom
  list without juggling extra arguments.

Update every existing caller for the new signatures and switch
Liveness::GraphType to a plain Function* (with the inverse
GraphTraits selected at call sites).
2026-06-11 17:39:53 +02:00
Alessandro Di Federico 5fa47e8d37 Reorganize lit tests under tests/filecheck 2026-06-03 13:59:53 +02:00
Andrea Gussoni 9c8808fd9e InlineHelpers: Use revng.inline.policy metadata
Use the helper's `!revng.inline.policy` and inline at each call site
only when every critical argument is constant.
2026-05-29 17:12:35 +02:00
Andrea Gussoni 8443f06170 DetectUninlinableHelpers: introduce pass
Introduce a pass which statically demotes some helpers from candidates
for inlining:
1) Helpers which are part of SCC on the callgraph.
2) Helpers which contains an `insertvalue`.
3) Helpers which _fail_ the `CriticalArguments` criterion.

A critical argument is defined starting from the critical operand
definition.
A critical operand is either the condition of a `switch` instruction or
the indices of a `getelementptr` instruction.
If the dataflow computing the the operand trace back to a formal
parameter of the function, that parameter will be considered critical
when attempting the inlining of the helper.

In case each condition is satisfied, the `revng.inline.policy` metadata
is attached to the function, so that it can be used at _inline_ time to
take the decision based on the critical arguments constantness.

The metadata is encoded as an `iN` integer with N = `arg_size() + 1`:
the extra most-significant bit is always zero so LLVM's signed-decimal
`iN` printer renders the value positively (avoiding e.g. `!{i2 -2}`).

The (de)serialisation primitives live in `revng/Support/IRHelpers.h`
as `serializeInliningPolicy` / `deserializeInliningPolicy` so the
runtime `revngFunctionIsolation` doesn't need to link the build-time
`revngHelperInliningAnalyses` to read the metadata back.
2026-05-29 17:12:35 +02:00
Andrea Gussoni 8103e2046c MarkInlineHelpersUpTo: introduce pass
Introduce a build-time pass that tags every QEMU helper transitively
reaching a function defined under one of the configured runtime-library
directories (currently `fpu/` only) as `revng_inline`. The intent is to
make the lift pipeline surface "leaf-level" runtime-library calls (e.g.
softfloat ops) directly in the lifted IR by inlining away every wrapper
helper that sits between QEMU's `helper_*` boundary and the leaf.

We also gate the tagging by a per-function body-size budget.

The pass is run in the pipeline building the `libtcg-helpers-full-*.bc`
artifacts.
2026-05-29 17:12:35 +02:00
Lauri Vasama b078f2c809 Fix C label output around hidden statements 2026-05-25 09:00:41 +02:00
Lauri Vasama 5c9a7b4207 Fix C output around hidden casts
```
// before
(var_0.x)[1];

// after
var_0.x[1];
```
2026-05-25 09:00:41 +02:00
Lauri Vasama 039f533a9f Add ternary inversion rewrite pattern
```
// before
!x ? y ? z

// after
x ? z ? y
```
2026-05-25 09:00:41 +02:00
Lauri Vasama e30a09644e Introduce hoist-variable-initializers pass 2026-05-25 09:00:41 +02:00
Lauri Vasama afaff540ed Implement Clift local variable self-assignment
Local variable initializer regions can now have a block argument
representing the local variable being initialized.
2026-05-25 09:00:41 +02:00
Roberto Bertolini 5dcd6334b3 Add Clift local variable scope tightening 2026-05-13 15:32:34 +02:00
Pietro Fezzardi 986ec7a3b8 STS: add unit tests with the store before the call
Add three more unit tests that mirror the previous "with_alloca"
variants but where the store of the extra argument %val into the
pre-existing alloca happens BEFORE the call instead of after it. The
expected number of NEW allocas after the pass is the same as in the
corresponding store-after-call variant: the position of the store
relative to the call does not change the picker's decision.
2026-05-08 17:16:57 +02:00
Pietro Fezzardi 325af4f696 STS: add unit tests with a pre-existing alloca
Add three more unit tests, one for each of the three call patterns
introduced in the previous commit. Each test takes an extra i64
argument %val, has an alloca pre-existing in the entry block, stores
%val into the alloca right after the call, and at least one branch
returns by loading from the alloca.

The pre-existing alloca/store/load pattern does not write to memory
the call could read (the alloca is local and the call's pointer
argument is unrelated) and the call cannot write to the alloca, so
the picker should reach the same conclusion as in the simpler
counterpart tests: the variant of @call_rw_one_use generates no new
alloca, @call_rw_two_uses generates one new alloca alongside the
pre-existing one, and @call_ro_two_uses generates none.
2026-05-08 17:14:10 +02:00
Pietro Fezzardi 133b29a474 STS: add unit tests for calls and serialization
Cover three representative cases for how the picker should treat
function calls in non-legacy mode:

- A call to a read+write function with a single use (an icmp that
  feeds a conditional branch). The call has only one use, so the
  picker does not pick it and no new alloca is created.
- The same shape, but with two uses of the call (the icmp and a
  return). Because the function may read+write memory and the call
  has more than one use, the picker picks the call: a new alloca is
  created at the top of entry, the result of the call is stored into
  it, and every user of the call uses a load from the alloca.
- The same shape as the second case but with a function that only
  reads memory (and is also nounwind willreturn so that
  Instruction::mayHaveSideEffects returns false). The picker does
  not pick the call and no new alloca is created.
2026-05-08 17:11:00 +02:00
Pietro Fezzardi e41e243d68 ArithmeticToGEP: see through Add subtrees
Make cannotBePointer recurse through an Add when both of its
operands cannot be pointers. This lets canDisambiguatePointerOperand
identify the only viable base pointer of an outer Add even when the
offset side is itself an Add (or a deeper tree of Adds) whose leaves
are all clearly-non-pointer values, e.g.

    %offset = add i64 (%a*%b), (%c*%d)
    %result = add i64 %arg, %offset

Two unit tests cover the simple two-mul case and a deeper
four-mul binary-tree variant.
2026-05-08 11:37:11 +02:00
Pietro Fezzardi 9dd0770290 ArithmeticToGEP: add deep ambiguous-add tests
Cover several scenarios where a single base pointer is reachable
only after the discovery walk in ArithmeticToGEPPass propagates
through many layers of Add instructions, each of which has
ambiguous pointer operands and must be disambiguated separately:

- A chain of 8 chained adds with a varied set of clearly-non-pointer
  offset opcodes (mul, ashr, shl, and, or, xor, sdiv, srem), with
  discovery seeded from the !revng.pointers metadata on the return.
- A chain seeded from a pointer argument (forward propagation).
- A chain feeding the integer argument of a call whose argument is
  a pointer (backwards discovery from the call site).
- A chain where the pointer side alternates between operand 0 and
  operand 1 of each add.
- A chain whose offset side is hidden behind freeze instructions,
  so the cannotBePointer recursion through transparent casts is
  exercised.
- A chain where every add reuses the same multiplication as offset,
  exercising independent disambiguation per-add over a shared
  sub-expression.
- A chain interrupted by ptrtoint/inttoptr round-trips between adds.
2026-05-08 11:37:11 +02:00
Pietro Fezzardi a28e6b8b87 CliftTransforms: add BitCastOfBitCastPattern
Add a Clift expression-rewrite pattern that collapses
`(T2)(T1)x` into `(T2)x` when both casts are BitCastOps. A
matching mlir-lit test is added.
2026-05-08 11:37:10 +02:00
Pietro Fezzardi cb5702dc04 Add ArithmeticToGEP pass
Introduce the ArithmeticToGEP canonicalisation pass. It detects
pointers (LLVM-typed pointer values, model pointers flagged by the
"revng.pointers" metadata, and pointer-tagged extract values) and
rewrites integer arithmetic computed on top of them as i8 GEPs,
followed by a ptrtoint when the original use needs an integer.

For each obvious pointer the pass also walks backwards through Add
chains and disambiguates the pointer operand of each Add when the
other operand cannot be a pointer, so the rewrite extends to integer
arithmetic that only later flows into a pointer use.
2026-05-08 11:37:10 +02:00
Pietro Fezzardi 9111f127dd STS: add unit tests
Add an llvm-lit test suite for the new-PassManager
SwitchToStatements pass, exercised via
`revng opt -passes=switch-to-statements-test` (registered by the
pass's registerCallbacks hook). The tests cover load/store
serialisation, side-effecting calls and a few representative
patterns where an instruction must be picked for serialisation
because its memory read is no longer available at one of its uses.
2026-05-08 11:37:10 +02:00
Lauri Vasama c7e3a12657 Add implicit cast elision pass 2026-05-04 10:49:07 +03:00
Lauri Vasama 04fe27b8e9 Migrate Clift users to CDataModel 2026-05-04 10:49:03 +03:00
Lauri Vasama f6d2eaea4b Add Clift DataModelAttr 2026-05-04 10:48:03 +03:00
Lauri Vasama 0ab9f769dd Add CDataModel in ABI definition 2026-05-02 17:21:47 +03:00
Lauri Vasama 5a538c0f84 Add (*x).m -> x->m expression rewrite 2026-04-30 15:09:16 +03:00
Lauri Vasama 90e5dfd4c9 Pass MLIRContext by address
Passing by address is more conventional. This is what MLIR does most of
the time, and it avoids dereferences and addressofs everywhere.
2026-04-30 15:09:16 +03:00
Lauri Vasama 31c80b0625 Fix (&x)->m -> x.m expression rewrite 2026-04-30 15:09:16 +03:00
Lauri Vasama 3f89cdcbd8 Disable MLIR output in Clift backend tests 2026-04-27 12:48:24 +03:00
Lauri Vasama a338194eb7 Move namespace mlir::clift out of namespace mlir 2026-04-27 12:48:24 +03:00
Ivan Krysak 490504604c mlir-lit-tests: test forbidden attributes 2026-04-22 08:19:35 +00:00
Ivan Krysak f83465eadb mlir-lit-tests: test unknown attributes 2026-04-22 08:19:34 +00:00
Ivan Krysak e1c4ad760f mlir-lit-tests: test function type attributes 2026-04-22 08:19:34 +00:00
Ivan Krysak 41c4dcd6ee mlir-lit-tests: add missing _ABI attributes 2026-04-22 08:19:33 +00:00
Ivan Krysak 935208dc43 mlir-lit-tests: test struct attributes 2026-04-22 08:19:33 +00:00
Ivan Krysak 61c8a44870 mlir-lit-tests: test function attributes 2026-04-22 08:19:32 +00:00
Ivan Krysak 1b6c4c8f45 mlir-lit-tests: test raw function attributes 2026-04-22 08:19:32 +00:00
Ivan Krysak 0a23d51da8 model-verify tests: separate a handles subset 2026-04-22 08:19:31 +00:00
Ivan Krysak 6f1c8edd16 Avoid relative paths in LLVM lit tests 2026-04-22 08:19:31 +00:00
Lauri Vasama cd45c8a831 Avoid relative paths in MLIR lit tests 2026-04-22 08:19:31 +00:00
Ivan Krysak e693cdbd53 model-verify-clift -> verify-against-model 2026-04-22 08:19:30 +00:00
Ivan Krysak ce7e5a3917 CliftModelVerify: improve error message wording 2026-04-22 08:19:30 +00:00
Ivan Krysak 5cc5bf77ed mlir_lit_tests: add header-level comment tests 2026-04-22 08:19:29 +00:00
Ivan Krysak 141bddb241 CDoxygenEmitter: pull factories in as methods 2026-04-22 06:33:56 +00:00
Ivan Krysak 2f8557a418 Doxygen unit test: improve the error message 2026-04-22 06:33:56 +00:00
Andrea Gussoni 4e3af009fe Expressions: fold x[0] into *x
Implement a DDR rewriting for folding the `x[0]` into `*x`, in order
to avoid a useless verbose syntax. Due to concatenation of rewrites, we
will get `&(x[0])` transformed into `x`, which is the rewriting we are
aiming to.
2026-04-14 09:52:07 +02:00
Andrea Gussoni 8359b4da26 EmitFieldAccesses: indirection propagation test 2026-04-14 09:50:48 +02:00
Andrea Gussoni f6b1772bbd EmitFieldAccesses: add const-qualified test 2026-04-14 09:50:48 +02:00