This change enables update_llc_test_checks.py to automatically generate
MIR checks for RUN lines that use `-stop-before` or `-stop-after` flags
allowing tests to verify intermediate compilation stages (e.g., after
instruction selection but before peephole optimizations) alongside the
final assembly output. If `-debug-only` flag is present in the run line it's
considered as the main point of interest for testing and stop flags above
are ignored (that is no MIR checks are generated).
This resulted from the scenario, when I needed to test two instruction
matching patterns where the later pattern in the peepholer reverts the
earlier pattern in the instruction selector and distinguish it from the
case when the earlier pattern didn't worked at all.
Initially created by Claude Sonnet 4.5 it was improved later to handle
conflicts in MIR <-> ASM prefixes and formatting.
This change enables update_llc_test_checks.py to automatically generate
MIR checks for RUN lines that use `-stop-before` or `-stop-after` flags
allowing tests to verify intermediate compilation stages (e.g., after
instruction selection but before peephole optimizations) alongside the
final assembly output. If `-debug-only` flag is present in the run line it's
considered as the main point of interest for testing and stop flags above
are ignored (that is no MIR checks are generated).
This resulted from the scenario, when I needed to test two instruction
matching patterns where the later pattern in the peepholer reverts the
earlier pattern in the instruction selector and distinguish it from the
case when the earlier pattern didn't worked at all.
Initially created by Claude Sonnet 4.5 it was improved later to handle
conflicts in MIR <-> ASM prefixes and formatting.
Since #163011 changed AMDGPU to use ELF mangling, the regexp failed to
match private functions because of the inconsistent presence/absence of
the .L prefix on the first line of the function e.g.:
```
.Lfoo: ; @foo
```
Previously, any blank lines in IR were ignored by UTC, leading to more
fragile `CHECK`s being generated.
This change lets UTC, 1) emit `CHECK-EMPTY` to check blank lines, and 2)
generate more `CHECK-NEXT`s, landing the discussion
https://github.com/llvm/llvm-project/pull/165419#issuecomment-3457572422.
Moreover, this change also aligns the behavior of IR check-gen to ASM
check-gen, which has been emitting `CHECK-EMPTY` since
a8a89c77ea.
Some analysis/transformation, e.g., predicate info/ mem ssa, insert
instruction annotations as comments, referring to
https://github.com/llvm/llvm-project/pull/165249#discussion_r2466200672.
This PR makes UTC support checking these instruction annotations with an
extra UTC option `-check-inst-comments`.
E.g.,
Before:
```LLVM
; CHECK: [[Z_0:%.*]] = bitcast i1 [[Z]] to i1
```
After:
```LLVM
; CHECK-NEXT: ; branch predicate info { TrueEdge: 0 Comparison: [[Z]] = and i1 [[XZ]], [[YZ]] Edge: [label [[TMP0:%.*]],label %nope], RenamedOp: [[Z]] }
; CHECK-NEXT: [[Z_0:%.*]] = bitcast i1 [[Z]] to i1
```
This PR also regenerates all UTC-generated tests for PredicateInfo; No
MemSSA test is updated, as there are no UTC-generated tests designated
for `print<memoryssa>`.
This commit extracts some MIR-related code from `common.py` and
`update_mir_test_checks.py` into a dedicated `mir.py` module to improve
code organization. This is a preparation step for
https://github.com/llvm/llvm-project/pull/164965 and also moves some
pieces already moved by https://github.com/llvm/llvm-project/pull/140296
All code intentionally moved verbatim with minimal necessary
adaptations:
* `log()` calls converted to `print(..., file=sys.stderr)` at `mir.py`
lines 62, 64 due to a `log` locality.
LLVM prints switch cases indented by 2 additional spaces, as follows:
```LLVM
switch i32 %x, label %default [
i32 0, label %phi
i32 1, label %phi
]
```
Since this only changes the output IR of update_test_checks.py and does
not change the logic of the File Check Pattern, there seems to be no
need to update the existing test cases.
Adds `arm64-apple-darwin` support to `asm.py` matching and removes now
invalidated `target-triple-mismatch` test (I dont have another triple
supported by llc but not the autogenerator that make this test useful).
There is a warning that triggers if you (for instance) run
`update_llc_test_checks.py` on an input where _all_ functions have
conflicting check lines and so no checks are generated. However, there
are no warnings emitted at all for the case where some functions have
non-conflicting check lines but others don't. This is a source of
frustration because running update_llc_test_checks can result in all
check lines being removed for certain functions when such a conflict
exists with no warning, meaning we have to be extra vigilant inspecting
the diff. I've also personally wasted time tracking down the source of
the dropped lines assuming that update_test_checks would emit a warning
in such cases.
This change adds logic to emit warnings on a function-by-function basis
for any RUN that has conflicting prefixes meaning no output is
generated. This subsumes the previous warning for when _all_ functions
conflict.
UpdateTestChecks have been updated to take into account TBAA
semantics as well, when emitting checks. This is achieved by
parsing TBAA metadata for each tool invocation – whose tool
is identified by their prefixes –, and maintaining a global
dict of prefixes, TBAA nodes.
PR #148287 removed the "\s*" before ".Lfunc_end" for AArch64, which
broke `update_llc_test_checks.py` for a number of tests including:
- `llvm/test/CodeGen/AArch64/sme-za-exceptions.ll`
- `llvm/test/CodeGen/AArch64/win-sve.ll`
This patch adds the "\s*" back.
This patch introduces `SCEVDivisionPrinterPass` and registers it under
the name `print<scev-division>`, primarily for testing purposes. This
pass invokes `SCEVDivision::divide` upon encountering `sdiv`, and prints
the numerator, denominator, quotient, and remainder. It also adds
several test cases, some of which are currently incorrect and require
fixing.
Along with that, this patch added some comments to clarify the behavior
of `SCEVDivision::divide`, as follows:
- This function does NOT actually perform the division
- Given the `Numerator` and `Denominator`, find a pair
`(Quotient, Remainder)` s.t.
`Numerator = Quotient * Denominator + Remainder`
- The common condition `Remainder < Denominator` is NOT necessarily
required
- There may be multiple solutions for `(Quotient, Remainder)`, and this
function finds one of them
- Especially, there is always a trivial solution `(0, Numerator)`
- The following computations may wrap
- The multiplication of `Quotient` and `Denominator`
- The addition of `Quotient * Denominator` and `Remainder`
Related discussion: #154745
In this patch:
1. Adapt the output of printDelinearization() to match what the script
expects to see, "Printing analysis 'Delinearization' for function".
2. Register the "Delinearization" pass in the update script.
3. Automatically remove the existing CHECK statements.
4. Update the tests with a run of:
```
$ ~/llvm-project/llvm/utils/update_analyze_test_checks.py
--opt=~/llvm-project/build/bin/opt
~/llvm-project/llvm/test/Analysis/Delinearization/*.ll
```
5. Drop llvm/test/Analysis/Delinearization/undef.ll because the test
does not pass the github-actions "undef deprecator."
6. Only run delinearization pretty-print pass on the most internal loop.
7. Only run delinearization pretty-print pass on load and store
instructions.
Fixes#147485.
I changed the regexp for the ARM targets making the part `@+[\t]*@"?(?P=func)"?` optional since when the -asm-verbose=false is passed it is not generated and this led to the issue.
Aims to improve error reporting by printing a warning if the target
function regex that has been selected finds no matches. For example, a
`-mtriple=arm64-apple-darwin` runline, would map to the `arm64` prefix
by `update_llc_test_checks.py` and wouldn't match Apple's function
layout, generating some not understandable garbage checks.
The implementation changes `common.process_run_line` to return an
abstract indicator of number of functions processed, without breaking
the drivers. Then `update_llc_test_checks.py` prints a driver specific
error message.
As with the other update scripts this takes the output of
-passes=print<gisel-value-tracking> and inserts the results into an
existing mir file. This means that the input is a lot like
update_analysis_test_checks.py, and the output needs to insert into a
mir file similarly to update_mir_test_checks.py. The code used to do the
inserting has been moved to common, to allow it to be reused. Otherwise
it tries to reuse the existing infrastructure, and
update_givaluetracking_test_checks is kept relatively short.
UpdateTestChecks has a make_analyzer_generalizer to replace pointer
addressess from the debug output of LAA with a pattern, which is an
acceptable solution when there is one RUN line. However, when there are
multiple RUN lines with a common pattern, UTC fails to recognize common
output due to mismatched pointer addresses. Instead of hacking UTC scrub
the output before comparing the outputs from the different RUN lines,
fix the issue once and for all by making LAA not output unstable pointer
addresses in the first place.
The removal of the now-dead make_analyzer_generalizer is left as a
non-trivial exercise for a follow-up.
The .syntax unified directive and .codeX/.code X directives are, other
than some simple common printing code, exclusively implemented in the
targets themselves. Thus, remove the corresponding MCAF_* flags and
reimplement the directives solely within the targets. This avoids
exposing all targets to all other targets' flags.
Since MCAF_SubsectionsViaSymbols is all that remains, convert it to its
own function like other directives, simplifying its implementation.
Note that, on X86, we now always need a target streamer when parsing
assembly, as it's now used for directives that aren't COFF-specific. It
still does not however need to do anything when producing a non-COFF
object file, so this commit does not introduce any new target streamers.
There is some churn in test output, and corresponding UTC regex changes,
due to comments no longer being flushed by these various directives (and
EmitEOL is not exposed outside MCAsmStreamer.cpp so we couldn't do so
even if we wanted to), but that was a bit odd to be doing anyway.
This is motivated by Morello LLVM, which adds yet another assembler flag
to distinguish A64 and C64 instruction sets, but did not update every
switch and so emits warnings during the build. Rather than fix those
warnings it seems better to instead make the problem not exist in the
first place via this change.
Avoid baking in absolute paths in check lines generated for DIFile
metadata. Generated test checks cannot be sensitive to absolute paths
anyway, as those vary with the environment, but there could be
situations where some sensitivity to partial paths is required for
certain tests. This implementation just assumes such tests aren't worth
the effort to support, but it could be supported in the future.
This is most useful for update_cc_test_checks with debug info enabled,
where the test writer cannot manipulate the paths within the generated
IR directly.
Whilst trying to clean up some loop vectoriser IR tests (see
test/Transforms/LoopVectorize/AArch64/partial-reduce-chained.ll
for example) a reviewer on PR #129047 suggested it would be
nice to have an option to stop generating CHECK lines after a
certain point. Typically when performing a transformation with
the loop vectoriser we don't usually care about any CHECK lines
generated for the scalar tail of the loop, since the scalar
loop is kept intact. Previously if you wanted to eliminate such
unwanted CHECK lines you had to run the update script, then
manually delete all the lines corresponding to the scalar loop.
This can be very time consuming if the tests ever need changing.
What I've tried to do here is add a new --filter-out-after
option alongside the existing --filter* options that provides
support for stopping the generation of any CHECK lines beyond
the line that matches the filter. With the existing filter
options we never generate CHECK-NEXT lines, but we still care
about ordering with --filter-out-after so I've amended the
code to ensure we treat this filter differently.
When --check-globals none, we skipped all the globals in check lines.
However, we are still checking the meta info in function defintion.
The generated checks are still sensitive to metadata changes.
This is to scrub the meta info and match them with {{.*}} instead.
Modify the DA pretty printer to match the output of other analysis
passes. This enables update_analyze_test_checks.py to also work on DA
tests. Auto generate all the Dependence Analysis tests.
For some ABIs `update_cc_test_checks.py` is unable to generate tests
because of the mismatch between the mangled function names reported by
clang's `-asd-dump` and the function names in LLVM IR.
This patch fixes it by striping the leading underscore from the mangled
name for global functions if the data layout string says they have one.
update_mc_test_check script handle the "error case testline" wrong in
three cases:
1. when user select "--llvm-mc-binary" with a path, the script does not
add "not" on top of the "--llvm-mc-binary" and thus getting non-zero
exit code and failed.
2. When "not" is presented in runline while not all testlines are
expected to fail, the script need to check if the "not" is needed when
it execute llvm-mc line by line. Otherwise the script will fail on
testline which is passing.
3. When there are multiple runlines, the error checkline need to use
correct line offset for "[[LINE-X]]"
This patch solve these three issues
add a unique and a sort option to the update_mc_test_check script.
These mc asm/dasm files are usually large in number of lines, and these
lines are mostly similar to each other. These options can be useful when
maintainer is merging or resolving conflicts by making the file
identifical
Also fixed a small issue in asm/dasm such that the auto generated header
line is
1. asm using ";" instead of "//" as comment marker
2. dasm using ";" instead of "#" as comment marker
Old versions of UTC produced function labels like:
; CHECK-LABEL: @func(
Fix the regular expression used when scanning for old check lines to
recognize this form of label.
This allows meta variable stability to apply when running UTC on tests
using this form of label.
Reported-by: Nikita Popov <npopov@redhat.com>
By default, UTC attempts to keep the produced diff small by keeping IR
value name variables stable. The old algorithm was roughly:
1. Compute a diff between the old and new check lines, where
"uncommitted" variable names are replaced by a wildcard.
This leads to a set of non-crossing "candidate" pairs of
(old line, new line) that we can try to make equal.
2. Greedily walk this list of candidates, committing to variable names
that make candidate lines equal if possible.
The greedy approach in the second step has the downside that committing
to a variable name greedily can sometimes prevent many subsequent
candidates from getting the variable name assignment that would make
them equal.
We keep the first step as-is, but replace the second one by an algorithm
that finds a large independent set of candidates, i.e. candidate pairs
of (old line, new line) which are non-conflicting in the sense that
their desired variable name mappings are not in conflict.
We find the large independent set by greedily assigning a coloring to
the conflict graph and taking the largest color class. We then commit to
all the variable name mappings which are desired by candidates in this
largest color class.
As before, we then recurse into regions between matching lines. This is
required in large cases. For example, running this algorithm at the
top-level of the new test case (stable_ir_values5.ll) matches up most of
the instructions, but not the names of the result values of all the
`load`s. This is because (unlike e.g. the getelementptrs) the load
instructions are all equal except for variable names, and so step 1 (the
diff algorithm) doesn't consider them as candidates. However, they are
trivially matched by recursion.
This also happens to fix a bug in tracking line indices that went
unnoticed previously...
As is usually the case with these changes, the quality improvement is
hard to see from the diff of this patch. However, it becomes obvious
when
comparing the diff of stable_ir_values5.ll against
stable_ir_value5.ll.expected
before and after this change.
Added a script to update the test file generated by llvm-mc binary. The
script accepts .s and .txt for asm and dasm.
For mc test I am targetting there is no function name which can be used
as a key, thus no clear mapping between input and output. The script
assumes the test are always line-by-line and it update the output marker
for each test line-by-line.
---------
Co-authored-by: Alexander Richardson <mail@alexrichardson.me>
There is no need to support Python 2.7 anymore, Python 3.3+ has
`subprocess.DEVNULL`. This is good practice and also prevents file
handles from
staying open unnecessarily.
Also remove a couple unused or unneeded `__future__` imports.
Updating `llvm/test/CodeGen/AMDGPU/GlobalISel/extractelement.ll` with
`update_llc_test_checks.py` ended with several kernels with no checks.
Llc's output contained the line ".amdgpu_hsa_kernel <funcname>" after
the ".type <funcname>,@function" entry which was not considered by the
regexp.
Tweak the LoopDistribute debug output to be prefixed with "LDist: ", get
it to be stable, and extend update_analyze_test_checks.py trivially to
support this output.
Having the version in `get_run_handlers` meant that a RUN line without the
version in it would not match, and therefore UTC would generate a useless
catch-all check of the form:
```
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CHECK: {{.*}}
```
This patch also adds `arm64_32` as a base-level run handler, and assumes it
will always apply to a darwin target (which is currently the case for all
arm64_32-* triples I see in tree currently).
A full downstream fork can already hack up update_llc_test_checks.py to
support custom tools that output assembly.
An out-of-tree frontend which is meant to build against upstream
llvm-project cannot do this, and so providing additional arguments to
support a non-standard tool is useful.
This also makes a minor adjustment to the regular expression for
matching AMDGPU functions when fewer comments are enabled, which happens
to be the case for our out-of-tree shader compiler (which motivated this
change).
Labels are matched using a regexp of the form '^(pattern):', which
requires the addition of a "suffix" concept to NamelessValue.
Aside from that, the key challenge is that block labels are values, and
we typically capture values including the prefix '%'. However, when
labels appear at the start of a basic block, the prefix '%' is not
included, so we must capture block label values *without* the prefix
'%'.
We don't know ahead of time whether an IR value is a label or not. In
most cases, they are prefixed by the word "label" (their type), but this
isn't the case in phi nodes. We solve this issue by leveraging the
two-phase nature of variable generalization: the first pass finds all
occurences of a variable and determines whether the '%' prefix can be
included or not. The second pass does the actual substitution.
This change also unifies the generalization path for assembly with that
for IR and analysis, in the hope that any future changes avoid diverging
those cases future.
I also considered the alternative of trying to detect the phi node case
using more regular expression special cases but ultimately decided
against that because it seemed more fragile, and perhaps the approach of
keeping a tentative prefix that may later be discarded could also be
eventually applied to some metadata and attribute cases.
Note that an early version of this change was reviewed as
https://reviews.llvm.org/D142452, before version numbers were
introduced. This is a substantially updated version of that change.
As we've added new IR elements for the RemoveDIs project,
we need the update_test_checks script to understand them. For the
records themselves this is already done automatically, but their
metadata arguments are not recognized as such due to lacking the
`metadata` prefix, which means they won't be checked by the script. This
patch fixes this by adding a check for all `![0-9]+` patterns as long as
they are not at the start of a line (which avoids matching global
values).
Collect the original check lines in a manner that is independent of
where the check lines appear in the file. This is so that we keep
FileCheck variable names stable even when --include-generated-funcs is
used.
Reported-by: Ruiling Song <ruiling.song@amd.com>