[llvm] [UTC][LV] Allow running multiple UTC scripts on a single file (PR #212374)
Andrei Elovikov via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 17 15:49:12 PDT 2026
https://github.com/eas updated https://github.com/llvm/llvm-project/pull/212374
>From 6b8bad25faa6a96d81b96fbe2f60a3137e1235df Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 14:32:20 -0700
Subject: [PATCH 01/21] First step - support option in analyze_test_checks
---
.../Inputs/run-lines.ll | 17 +++++
.../Inputs/run-lines.ll.expected1 | 67 +++++++++++++++++++
.../update_analyze_test_checks/run-lines.test | 8 +++
llvm/utils/update_analyze_test_checks.py | 54 ++++++++++++++-
4 files changed, 145 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected1
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll
new file mode 100644
index 0000000000000..eed034f87df67
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll
@@ -0,0 +1,17 @@
+; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+
+define void @simple(ptr %p, i64 %n) {
+entry:
+ br label %loop
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep = getelementptr i32, ptr %p, i64 %iv
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp ult i64 %iv.next, %n
+ br i1 %cmp, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected1 b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected1
new file mode 100644
index 0000000000000..9a519c4469b7a
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected1
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
+; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+
+define void @simple(ptr %p, i64 %n) {
+; CHECK-LABEL: VPlan for loop in 'simple'
+; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<entry>:
+; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
+; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: Successor(s): vector loop
+; CHECK-EMPTY:
+; CHECK-NEXT: <x1> vector loop: {
+; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.body:
+; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
+; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer ir<%gep>, ir<1>
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
+; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
+; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+; CHECK-NEXT: Successor(s): middle.block
+; CHECK-EMPTY:
+; CHECK-NEXT: middle.block:
+; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<exit>:
+; CHECK-NEXT: No successors
+; CHECK-EMPTY:
+; CHECK-NEXT: scalar.ph:
+; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK-NEXT: Successor(s): ir-bb<loop>
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<loop>:
+; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
+; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
+; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
+; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+;
+entry:
+ br label %loop
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep = getelementptr i32, ptr %p, i64 %iv
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp ult i64 %iv.next, %n
+ br i1 %cmp, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
new file mode 100644
index 0000000000000..d8fbb97b7e2ed
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
@@ -0,0 +1,8 @@
+# REQUIRES: asserts
+
+## Basic test checking that update_analyze_test_checks.py works correctly for Run-Lines output
+# RUN: cp -f %S/Inputs/run-lines.ll %t.ll && %update_analyze_test_checks --run-lines=1 %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected1
+## Check that running the script again does not change the result:
+# RUN: %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected1
diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py
index 5329851e465e3..145ae49fd6107 100755
--- a/llvm/utils/update_analyze_test_checks.py
+++ b/llvm/utils/update_analyze_test_checks.py
@@ -41,6 +41,52 @@
from UpdateTestChecks import common
+def _parse_run_lines(run_lines_filter: str, num_run_lines: int):
+ selected = set()
+ for item in run_lines_filter.split(","):
+ item = item.strip()
+ if not item:
+ raise ValueError("empty item in --run-lines filter")
+
+ if "-" in item:
+ bounds = item.split("-", 1)
+ if len(bounds) != 2 or not bounds[0] or not bounds[1]:
+ raise ValueError(
+ "invalid --run-lines range '{}'; expected N or N-M".format(item)
+ )
+ start = int(bounds[0])
+ end = int(bounds[1])
+ else:
+ start = end = int(item)
+
+ if start <= 0 or end <= 0:
+ raise ValueError("--run-lines entries must be positive: '{}'".format(item))
+ if start > end:
+ raise ValueError(
+ "invalid --run-lines range '{}'; start must not exceed end".format(
+ item
+ )
+ )
+ if end > num_run_lines:
+ raise ValueError(
+ "--run-lines selects RUN line {} but only {} RUN lines exist".format(
+ end, num_run_lines
+ )
+ )
+
+ selected.update(range(start, end + 1))
+
+ return selected
+
+
+def _filter_run_lines(run_lines, run_lines_filter: str):
+ if run_lines_filter is None:
+ return run_lines
+
+ selected = _parse_run_lines(run_lines_filter, len(run_lines))
+ return [line for (index, line) in enumerate(run_lines, start=1) if index in selected]
+
+
def update_test(opt_basename: str, ti: common.TestInfo):
triple_in_ir = None
for l in ti.input_lines:
@@ -49,8 +95,10 @@ def update_test(opt_basename: str, ti: common.TestInfo):
triple_in_ir = m.groups()[0]
break
+ run_lines = _filter_run_lines(ti.run_lines, ti.args.run_lines)
+
prefix_list = []
- for l in ti.run_lines:
+ for l in run_lines:
if "|" not in l:
common.warn("Skipping unparsable RUN line: " + l)
continue
@@ -210,6 +258,10 @@ def main():
help="The opt binary used to generate the test case",
)
parser.add_argument("--function", help="The function in the test file to update")
+ parser.add_argument(
+ "--run-lines",
+ help="Comma-separated list of 1-based RUN line numbers or ranges to use",
+ )
parser.add_argument("tests", nargs="+")
initial_args = common.parse_commandline_args(parser)
>From 6b09d0836ea5ae29a487169176f8d4accf255551 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 14:37:55 -0700
Subject: [PATCH 02/21] Move support to common.py, extend test to verify the
same for update_test_checks.py
---
.../Inputs/run-lines.ll.expected2 | 50 +++++++++++++++++
.../update_analyze_test_checks/run-lines.test | 9 +++-
llvm/utils/UpdateTestChecks/common.py | 54 ++++++++++++++++++-
llvm/utils/update_analyze_test_checks.py | 54 +------------------
llvm/utils/update_mca_test_checks.py | 4 +-
llvm/utils/update_mir_test_checks.py | 4 +-
6 files changed, 118 insertions(+), 57 deletions(-)
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected2
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected2 b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected2
new file mode 100644
index 0000000000000..a13338fda1203
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected2
@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
+; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+
+define void @simple(ptr %p, i64 %n) {
+; LLVM-LABEL: @simple(
+; LLVM-NEXT: entry:
+; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; LLVM: vector.ph:
+; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
+; LLVM: vector.body:
+; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; LLVM: middle.block:
+; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; LLVM: scalar.ph:
+; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; LLVM-NEXT: br label [[LOOP:%.*]]
+; LLVM: loop:
+; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
+; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; LLVM: exit:
+; LLVM-NEXT: ret void
+;
+entry:
+ br label %loop
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep = getelementptr i32, ptr %p, i64 %iv
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp ult i64 %iv.next, %n
+ br i1 %cmp, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
index d8fbb97b7e2ed..95b653f6d50c5 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
@@ -1,8 +1,15 @@
# REQUIRES: asserts
-## Basic test checking that update_analyze_test_checks.py works correctly for Run-Lines output
+## Basic test checking that update_analyze_test_checks.py works correctly for Run-Lines output.
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll && %update_analyze_test_checks --run-lines=1 %t.ll
# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected1
## Check that running the script again does not change the result:
# RUN: %update_analyze_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected1
+
+## Check that update_test_checks.py can process the same input using the second RUN line.
+# RUN: cp -f %S/Inputs/run-lines.ll %t.ll && %update_test_checks --run-lines=2 %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected2
+## Check that running the script again does not change the result:
+# RUN: %update_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected2
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 8eb3249c3f6c2..4f44941ca9819 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -227,6 +227,10 @@ def __call__(self, parser, namespace, values, option_string=None):
default=[],
help="List of regular expressions such that, for matching global value declarations, literal integer values should be encoded in hex in the associated FileCheck directives",
)
+ parser.add_argument(
+ "--run-lines",
+ help="Comma-separated list of 1-based RUN line numbers or ranges to use",
+ )
# FIXME: in 3.9, we can use argparse.BooleanOptionalAction. At that point,
# we need to rename the flag to just -generate-body-for-unused-prefixes.
parser.add_argument(
@@ -293,7 +297,9 @@ def __init__(
_prefix_filecheck_ir_name = args.prefix_filecheck_ir_name
self.argv = argv
self.input_lines = input_lines
- self.run_lines = find_run_lines(test, self.input_lines)
+ self.run_lines = filter_run_lines(
+ find_run_lines(test, self.input_lines), args.run_lines
+ )
self.comment_prefix = comment_prefix
if self.comment_prefix is None:
if self.path.endswith(".mir") or self.path.endswith(".txt"):
@@ -670,6 +676,52 @@ def find_run_lines(test, lines):
return run_lines
+def parse_run_lines(run_lines_filter, num_run_lines):
+ selected = set()
+ for item in run_lines_filter.split(","):
+ item = item.strip()
+ if not item:
+ raise ValueError("empty item in --run-lines filter")
+
+ if "-" in item:
+ bounds = item.split("-", 1)
+ if len(bounds) != 2 or not bounds[0] or not bounds[1]:
+ raise ValueError(
+ "invalid --run-lines range '{}'; expected N or N-M".format(item)
+ )
+ start = int(bounds[0])
+ end = int(bounds[1])
+ else:
+ start = end = int(item)
+
+ if start <= 0 or end <= 0:
+ raise ValueError("--run-lines entries must be positive: '{}'".format(item))
+ if start > end:
+ raise ValueError(
+ "invalid --run-lines range '{}'; start must not exceed end".format(
+ item
+ )
+ )
+ if end > num_run_lines:
+ raise ValueError(
+ "--run-lines selects RUN line {} but only {} RUN lines exist".format(
+ end, num_run_lines
+ )
+ )
+
+ selected.update(range(start, end + 1))
+
+ return selected
+
+
+def filter_run_lines(run_lines, run_lines_filter):
+ if run_lines_filter is None:
+ return run_lines
+
+ selected = parse_run_lines(run_lines_filter, len(run_lines))
+ return [line for (index, line) in enumerate(run_lines, start=1) if index in selected]
+
+
def get_triple_from_march(march):
triples = {
"amdgcn": "amdgcn",
diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py
index 145ae49fd6107..5329851e465e3 100755
--- a/llvm/utils/update_analyze_test_checks.py
+++ b/llvm/utils/update_analyze_test_checks.py
@@ -41,52 +41,6 @@
from UpdateTestChecks import common
-def _parse_run_lines(run_lines_filter: str, num_run_lines: int):
- selected = set()
- for item in run_lines_filter.split(","):
- item = item.strip()
- if not item:
- raise ValueError("empty item in --run-lines filter")
-
- if "-" in item:
- bounds = item.split("-", 1)
- if len(bounds) != 2 or not bounds[0] or not bounds[1]:
- raise ValueError(
- "invalid --run-lines range '{}'; expected N or N-M".format(item)
- )
- start = int(bounds[0])
- end = int(bounds[1])
- else:
- start = end = int(item)
-
- if start <= 0 or end <= 0:
- raise ValueError("--run-lines entries must be positive: '{}'".format(item))
- if start > end:
- raise ValueError(
- "invalid --run-lines range '{}'; start must not exceed end".format(
- item
- )
- )
- if end > num_run_lines:
- raise ValueError(
- "--run-lines selects RUN line {} but only {} RUN lines exist".format(
- end, num_run_lines
- )
- )
-
- selected.update(range(start, end + 1))
-
- return selected
-
-
-def _filter_run_lines(run_lines, run_lines_filter: str):
- if run_lines_filter is None:
- return run_lines
-
- selected = _parse_run_lines(run_lines_filter, len(run_lines))
- return [line for (index, line) in enumerate(run_lines, start=1) if index in selected]
-
-
def update_test(opt_basename: str, ti: common.TestInfo):
triple_in_ir = None
for l in ti.input_lines:
@@ -95,10 +49,8 @@ def update_test(opt_basename: str, ti: common.TestInfo):
triple_in_ir = m.groups()[0]
break
- run_lines = _filter_run_lines(ti.run_lines, ti.args.run_lines)
-
prefix_list = []
- for l in run_lines:
+ for l in ti.run_lines:
if "|" not in l:
common.warn("Skipping unparsable RUN line: " + l)
continue
@@ -258,10 +210,6 @@ def main():
help="The opt binary used to generate the test case",
)
parser.add_argument("--function", help="The function in the test file to update")
- parser.add_argument(
- "--run-lines",
- help="Comma-separated list of 1-based RUN line numbers or ranges to use",
- )
parser.add_argument("tests", nargs="+")
initial_args = common.parse_commandline_args(parser)
diff --git a/llvm/utils/update_mca_test_checks.py b/llvm/utils/update_mca_test_checks.py
index 87f795c8075e7..ab483458dfcfe 100755
--- a/llvm/utils/update_mca_test_checks.py
+++ b/llvm/utils/update_mca_test_checks.py
@@ -548,7 +548,9 @@ def update_test_file(args, test_path, autogenerated_note):
with open(test_path) as f:
input_lines = [l.rstrip() for l in f]
- run_lines = common.find_run_lines(test_path, input_lines)
+ run_lines = common.filter_run_lines(
+ common.find_run_lines(test_path, input_lines), args.run_lines
+ )
run_infos = _get_run_infos(run_lines, args)
common_prefix, prefix_pad = _get_useful_prefix_info(run_infos)
block_infos = _get_block_infos(run_infos, test_path, args, common_prefix)
diff --git a/llvm/utils/update_mir_test_checks.py b/llvm/utils/update_mir_test_checks.py
index 0870b66f4139b..86bd3b156d2ea 100755
--- a/llvm/utils/update_mir_test_checks.py
+++ b/llvm/utils/update_mir_test_checks.py
@@ -116,7 +116,9 @@ def update_test_file(args, test, autogenerated_note):
input_lines = [l.rstrip() for l in fd]
triple_in_ir = find_triple_in_ir(input_lines, args.verbose)
- run_lines = common.find_run_lines(test, input_lines)
+ run_lines = common.filter_run_lines(
+ common.find_run_lines(test, input_lines), args.run_lines
+ )
run_list = build_run_list(test, run_lines, args.verbose)
func_dict = {}
>From fe26371588fbadd7e7e7033ccc46b7d8462d953f Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 14:40:55 -0700
Subject: [PATCH 03/21] Move run lines filter into existing find_run_lines
---
llvm/utils/UpdateTestChecks/common.py | 19 +++++++------------
llvm/utils/update_mca_test_checks.py | 4 +---
llvm/utils/update_mir_test_checks.py | 4 +---
3 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 4f44941ca9819..26727803c6b52 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -297,9 +297,7 @@ def __init__(
_prefix_filecheck_ir_name = args.prefix_filecheck_ir_name
self.argv = argv
self.input_lines = input_lines
- self.run_lines = filter_run_lines(
- find_run_lines(test, self.input_lines), args.run_lines
- )
+ self.run_lines = find_run_lines(test, self.input_lines, args.run_lines)
self.comment_prefix = comment_prefix
if self.comment_prefix is None:
if self.path.endswith(".mir") or self.path.endswith(".txt"):
@@ -661,7 +659,7 @@ def debug(*args, **kwargs):
print(*args, **kwargs)
-def find_run_lines(test, lines):
+def find_run_lines(test, lines, run_lines_filter=None):
debug("Scanning for RUN lines in test file:", test)
raw_lines = [m.group(1) for m in [RUN_LINE_RE.match(l) for l in lines] if m]
run_lines = [raw_lines[0]] if len(raw_lines) > 0 else []
@@ -670,6 +668,11 @@ def find_run_lines(test, lines):
run_lines[-1] = run_lines[-1].rstrip("\\") + " " + l
else:
run_lines.append(l)
+ if run_lines_filter is not None:
+ selected = parse_run_lines(run_lines_filter, len(run_lines))
+ run_lines = [
+ line for (index, line) in enumerate(run_lines, start=1) if index in selected
+ ]
debug("Found {} RUN lines in {}:".format(len(run_lines), test))
for l in run_lines:
debug(" RUN: {}".format(l))
@@ -714,14 +717,6 @@ def parse_run_lines(run_lines_filter, num_run_lines):
return selected
-def filter_run_lines(run_lines, run_lines_filter):
- if run_lines_filter is None:
- return run_lines
-
- selected = parse_run_lines(run_lines_filter, len(run_lines))
- return [line for (index, line) in enumerate(run_lines, start=1) if index in selected]
-
-
def get_triple_from_march(march):
triples = {
"amdgcn": "amdgcn",
diff --git a/llvm/utils/update_mca_test_checks.py b/llvm/utils/update_mca_test_checks.py
index ab483458dfcfe..579229d8f92dd 100755
--- a/llvm/utils/update_mca_test_checks.py
+++ b/llvm/utils/update_mca_test_checks.py
@@ -548,9 +548,7 @@ def update_test_file(args, test_path, autogenerated_note):
with open(test_path) as f:
input_lines = [l.rstrip() for l in f]
- run_lines = common.filter_run_lines(
- common.find_run_lines(test_path, input_lines), args.run_lines
- )
+ run_lines = common.find_run_lines(test_path, input_lines, args.run_lines)
run_infos = _get_run_infos(run_lines, args)
common_prefix, prefix_pad = _get_useful_prefix_info(run_infos)
block_infos = _get_block_infos(run_infos, test_path, args, common_prefix)
diff --git a/llvm/utils/update_mir_test_checks.py b/llvm/utils/update_mir_test_checks.py
index 86bd3b156d2ea..c2c4b26e839f3 100755
--- a/llvm/utils/update_mir_test_checks.py
+++ b/llvm/utils/update_mir_test_checks.py
@@ -116,9 +116,7 @@ def update_test_file(args, test, autogenerated_note):
input_lines = [l.rstrip() for l in fd]
triple_in_ir = find_triple_in_ir(input_lines, args.verbose)
- run_lines = common.filter_run_lines(
- common.find_run_lines(test, input_lines), args.run_lines
- )
+ run_lines = common.find_run_lines(test, input_lines, args.run_lines)
run_list = build_run_list(test, run_lines, args.verbose)
func_dict = {}
>From ee96c7280dd34ee63a7925e8f5ccfc043ddd413c Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 14:49:20 -0700
Subject: [PATCH 04/21] Extend to allow generating using multiple scripts
---
...l.expected1 => run-lines.analyze.expected} | 0
.../run-lines.analyze.then.llvm.expected | 100 ++++++++++++++++++
...s.ll.expected2 => run-lines.llvm.expected} | 0
.../run-lines.llvm.then.analyze.expected | 100 ++++++++++++++++++
.../update_analyze_test_checks/run-lines.test | 36 +++++--
llvm/utils/UpdateTestChecks/common.py | 42 +++++---
6 files changed, 254 insertions(+), 24 deletions(-)
rename llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/{run-lines.ll.expected1 => run-lines.analyze.expected} (100%)
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected
rename llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/{run-lines.ll.expected2 => run-lines.llvm.expected} (100%)
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected1 b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected1
rename to llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected
new file mode 100644
index 0000000000000..212d57177c8cd
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected
@@ -0,0 +1,100 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
+; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+
+define void @simple(ptr %p, i64 %n) {
+; CHECK-LABEL: VPlan for loop in 'simple'
+; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<entry>:
+; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
+; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: Successor(s): vector loop
+; CHECK-EMPTY:
+; CHECK-NEXT: <x1> vector loop: {
+; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.body:
+; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
+; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer ir<%gep>, ir<1>
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
+; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
+; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+; CHECK-NEXT: Successor(s): middle.block
+; CHECK-EMPTY:
+; CHECK-NEXT: middle.block:
+; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<exit>:
+; CHECK-NEXT: No successors
+; CHECK-EMPTY:
+; CHECK-NEXT: scalar.ph:
+; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK-NEXT: Successor(s): ir-bb<loop>
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<loop>:
+; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
+; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
+; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
+; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+;
+; LLVM-LABEL: @simple(
+; LLVM-NEXT: entry:
+; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; LLVM: vector.ph:
+; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
+; LLVM: vector.body:
+; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; LLVM: middle.block:
+; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; LLVM: scalar.ph:
+; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; LLVM-NEXT: br label [[LOOP:%.*]]
+; LLVM: loop:
+; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
+; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; LLVM: exit:
+; LLVM-NEXT: ret void
+;
+entry:
+ br label %loop
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep = getelementptr i32, ptr %p, i64 %iv
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp ult i64 %iv.next, %n
+ br i1 %cmp, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected2 b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll.expected2
rename to llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
new file mode 100644
index 0000000000000..62bbadf295f91
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
@@ -0,0 +1,100 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
+; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+
+define void @simple(ptr %p, i64 %n) {
+; LLVM-LABEL: @simple(
+; LLVM-NEXT: entry:
+; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; LLVM: vector.ph:
+; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
+; LLVM: vector.body:
+; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; LLVM: middle.block:
+; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; LLVM: scalar.ph:
+; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; LLVM-NEXT: br label [[LOOP:%.*]]
+; LLVM: loop:
+; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
+; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; LLVM: exit:
+; LLVM-NEXT: ret void
+;
+; CHECK-LABEL: VPlan for loop in 'simple'
+; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<entry>:
+; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
+; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: Successor(s): vector loop
+; CHECK-EMPTY:
+; CHECK-NEXT: <x1> vector loop: {
+; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.body:
+; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
+; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer ir<%gep>, ir<1>
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
+; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
+; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+; CHECK-NEXT: Successor(s): middle.block
+; CHECK-EMPTY:
+; CHECK-NEXT: middle.block:
+; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<exit>:
+; CHECK-NEXT: No successors
+; CHECK-EMPTY:
+; CHECK-NEXT: scalar.ph:
+; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK-NEXT: Successor(s): ir-bb<loop>
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<loop>:
+; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
+; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
+; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
+; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+;
+entry:
+ br label %loop
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep = getelementptr i32, ptr %p, i64 %iv
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp ult i64 %iv.next, %n
+ br i1 %cmp, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
index 95b653f6d50c5..be2d9d5fbb452 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
@@ -1,15 +1,35 @@
# REQUIRES: asserts
-## Basic test checking that update_analyze_test_checks.py works correctly for Run-Lines output.
+## Analyze-only update using the first RUN line.
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll && %update_analyze_test_checks --run-lines=1 %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected1
-## Check that running the script again does not change the result:
+# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.expected
+## Check that running the same script again does not change the result:
# RUN: %update_analyze_test_checks %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected1
+# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.expected
-## Check that update_test_checks.py can process the same input using the second RUN line.
+## LLVM-IR-only update using the second RUN line.
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll && %update_test_checks --run-lines=2 %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected2
-## Check that running the script again does not change the result:
+# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.expected
+## Check that running the same script again does not change the result:
# RUN: %update_test_checks %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.ll.expected2
+# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.expected
+
+## Update analyze checks first, then LLVM IR checks.
+# RUN: cp -f %S/Inputs/run-lines.ll %t.ll
+# RUN: %update_analyze_test_checks --run-lines=1 %t.ll
+# RUN: %update_test_checks --run-lines=2 %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.then.llvm.expected
+## Check that re-running both scripts does not change the result:
+# RUN: %update_analyze_test_checks %t.ll
+# RUN: %update_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.then.llvm.expected
+
+## Update LLVM IR checks first, then analyze checks.
+# RUN: cp -f %S/Inputs/run-lines.ll %t.ll
+# RUN: %update_test_checks --run-lines=2 %t.ll
+# RUN: %update_analyze_test_checks --run-lines=1 %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.then.analyze.expected
+## Check that re-running both scripts does not change the result:
+# RUN: %update_test_checks %t.ll
+# RUN: %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.then.analyze.expected
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 26727803c6b52..854d0a0c8885b 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -307,25 +307,29 @@ def __init__(
else:
self.comment_prefix = ";"
self.autogenerated_note_prefix = self.comment_prefix + " " + UTC_ADVERT
- self.test_autogenerated_note = self.autogenerated_note_prefix + script_name
+ self.script_autogenerated_note_prefix = self.autogenerated_note_prefix + script_name
+ self.test_autogenerated_note = self.script_autogenerated_note_prefix
self.test_autogenerated_note += get_autogennote_suffix(parser, self.args)
self.test_unused_note = (
self.comment_prefix + self.comment_prefix + " " + UNUSED_NOTE
)
def ro_iterlines(self):
+ args = self.args
+ argv = self.argv
for line_num, input_line in enumerate(self.input_lines):
- args, argv = check_for_command(
- input_line, self.parser, self.args, self.argv, self.argparse_callback
- )
+ if not input_line.startswith(self.autogenerated_note_prefix):
+ args, argv = check_for_command(
+ input_line, self.parser, args, argv, self.argparse_callback
+ )
yield InputLineInfo(input_line, line_num, args, argv)
def iterlines(self, output_lines):
output_lines.append(self.test_autogenerated_note)
for line_info in self.ro_iterlines():
input_line = line_info.line
- # Discard any previous script advertising.
- if input_line.startswith(self.autogenerated_note_prefix):
+ # Discard any previous advertising for this script only.
+ if input_line.startswith(self.script_autogenerated_note_prefix):
continue
self.args = line_info.args
self.argv = line_info.argv
@@ -373,7 +377,17 @@ def itertests(
if UTC_AVOID in first_line:
warn("Skipping test that must not be autogenerated: " + test)
continue
- is_regenerate = UTC_ADVERT in first_line
+
+ autogenerated_lines = []
+ for line in input_lines:
+ if UTC_ADVERT not in line:
+ break
+ autogenerated_lines.append(line)
+
+ regenerate_line = next(
+ (line for line in autogenerated_lines if script_name in line), None
+ )
+ is_regenerate = regenerate_line is not None
# If we're generating a new test, set the default version to the latest.
argv = sys.argv[:]
@@ -384,18 +398,14 @@ def itertests(
if argparse_callback is not None:
argparse_callback(args)
if is_regenerate:
- if script_name not in first_line and not args.force_update:
- warn(
- "Skipping test which wasn't autogenerated by " + script_name,
- test,
- )
- continue
args, argv = check_for_command(
- first_line, parser, args, argv, argparse_callback
+ regenerate_line, parser, args, argv, argparse_callback
)
elif args.update_only:
- assert UTC_ADVERT not in first_line
- warn("Skipping test which isn't autogenerated: " + test)
+ warn(
+ "Skipping test which isn't autogenerated by " + script_name,
+ test,
+ )
continue
final_input_lines = []
for l in input_lines:
>From 6810441391110ea8e91027b42e041914d3dc10da Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 15:00:19 -0700
Subject: [PATCH 05/21] Totally vibe-coded order fix
---
.../run-lines.analyze.then.llvm.expected | 2 +-
.../run-lines.llvm.then.analyze.expected | 64 +++----
llvm/utils/UpdateTestChecks/common.py | 160 +++++++++++++++++-
llvm/utils/update_analyze_test_checks.py | 3 +
llvm/utils/update_test_checks.py | 3 +
5 files changed, 195 insertions(+), 37 deletions(-)
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected
index 212d57177c8cd..539baec1a3c47 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected
@@ -1,5 +1,5 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
index 62bbadf295f91..539baec1a3c47 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
@@ -5,38 +5,6 @@
; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
define void @simple(ptr %p, i64 %n) {
-; LLVM-LABEL: @simple(
-; LLVM-NEXT: entry:
-; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
-; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
-; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
-; LLVM: vector.ph:
-; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
-; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
-; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
-; LLVM: vector.body:
-; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
-; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
-; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
-; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
-; LLVM: middle.block:
-; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
-; LLVM: scalar.ph:
-; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
-; LLVM-NEXT: br label [[LOOP:%.*]]
-; LLVM: loop:
-; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
-; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
-; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
-; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
-; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
-; LLVM: exit:
-; LLVM-NEXT: ret void
-;
; CHECK-LABEL: VPlan for loop in 'simple'
; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
@@ -86,6 +54,38 @@ define void @simple(ptr %p, i64 %n) {
; CHECK-NEXT: No successors
; CHECK-NEXT: }
;
+; LLVM-LABEL: @simple(
+; LLVM-NEXT: entry:
+; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; LLVM: vector.ph:
+; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
+; LLVM: vector.body:
+; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; LLVM: middle.block:
+; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; LLVM: scalar.ph:
+; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; LLVM-NEXT: br label [[LOOP:%.*]]
+; LLVM: loop:
+; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
+; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; LLVM: exit:
+; LLVM-NEXT: ret void
+;
entry:
br label %loop
loop:
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 854d0a0c8885b..18dfecda38ed4 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -297,7 +297,9 @@ def __init__(
_prefix_filecheck_ir_name = args.prefix_filecheck_ir_name
self.argv = argv
self.input_lines = input_lines
+ self.all_run_lines = find_run_lines(test, self.input_lines)
self.run_lines = find_run_lines(test, self.input_lines, args.run_lines)
+ self.run_line_prefix_order = get_run_line_check_prefix_order(self.all_run_lines)
self.comment_prefix = comment_prefix
if self.comment_prefix is None:
if self.path.endswith(".mir") or self.path.endswith(".txt"):
@@ -307,13 +309,51 @@ def __init__(
else:
self.comment_prefix = ";"
self.autogenerated_note_prefix = self.comment_prefix + " " + UTC_ADVERT
- self.script_autogenerated_note_prefix = self.autogenerated_note_prefix + script_name
+ self.current_script_name = script_name
+ self.script_autogenerated_note_prefix = (
+ self.autogenerated_note_prefix + self.current_script_name
+ )
self.test_autogenerated_note = self.script_autogenerated_note_prefix
self.test_autogenerated_note += get_autogennote_suffix(parser, self.args)
+ self.autogenerated_note_lines = []
+ for input_line in self.input_lines:
+ if not input_line.startswith(self.autogenerated_note_prefix):
+ break
+ self.autogenerated_note_lines.append(input_line)
self.test_unused_note = (
self.comment_prefix + self.comment_prefix + " " + UNUSED_NOTE
)
+ def _parse_autogenerated_note(self, line):
+ if not line.startswith(self.autogenerated_note_prefix):
+ return (None, "")
+ suffix = line[len(self.autogenerated_note_prefix) :]
+ script_name, _, args_suffix = suffix.partition(" " + UTC_ARGS_KEY)
+ args_suffix = args_suffix.strip()
+ return (script_name, args_suffix)
+
+ def _get_run_lines_filter_from_note_args(self, args_suffix):
+ argv = shlex.split(args_suffix)
+ for index, option in enumerate(argv):
+ if option == "--run-lines" and index + 1 < len(argv):
+ return argv[index + 1]
+ if option.startswith("--run-lines="):
+ return option.split("=", 1)[1]
+ return None
+
+ def _note_run_line_sort_key(self, line):
+ script_name, args_suffix = self._parse_autogenerated_note(line)
+ min_run_line = len(self.all_run_lines) + 1
+ run_lines_filter = self._get_run_lines_filter_from_note_args(args_suffix)
+ if run_lines_filter is not None:
+ try:
+ min_run_line = min(
+ parse_run_lines(run_lines_filter, len(self.all_run_lines))
+ )
+ except ValueError:
+ pass
+ return (min_run_line, script_name or "", line)
+
def ro_iterlines(self):
args = self.args
argv = self.argv
@@ -325,11 +365,21 @@ def ro_iterlines(self):
yield InputLineInfo(input_line, line_num, args, argv)
def iterlines(self, output_lines):
- output_lines.append(self.test_autogenerated_note)
+ note_lines = []
+ saw_current_script = False
+ for input_line in self.autogenerated_note_lines:
+ script_name, _ = self._parse_autogenerated_note(input_line)
+ if script_name == self.current_script_name:
+ note_lines.append(self.test_autogenerated_note)
+ saw_current_script = True
+ else:
+ note_lines.append(input_line)
+ if not saw_current_script:
+ note_lines.append(self.test_autogenerated_note)
+ output_lines.extend(sorted(note_lines, key=self._note_run_line_sort_key))
for line_info in self.ro_iterlines():
input_line = line_info.line
- # Discard any previous advertising for this script only.
- if input_line.startswith(self.script_autogenerated_note_prefix):
+ if input_line.startswith(self.autogenerated_note_prefix):
continue
self.args = line_info.args
self.argv = line_info.argv
@@ -2759,6 +2809,23 @@ def get_check_prefixes(filecheck_cmd):
return check_prefixes
+def get_run_line_check_prefix_order(run_lines):
+ prefix_order = []
+ seen = set()
+ for run_line in run_lines:
+ if "|" not in run_line:
+ continue
+ filecheck_cmd = run_line.rsplit("|", 1)[1].strip()
+ if not filecheck_cmd.startswith("FileCheck "):
+ continue
+ for prefix in get_check_prefixes(filecheck_cmd):
+ if prefix in seen:
+ continue
+ seen.add(prefix)
+ prefix_order.append(prefix)
+ return prefix_order
+
+
def verify_filecheck_prefixes(fc_cmd):
fc_cmd_parts = fc_cmd.split()
for part in fc_cmd_parts:
@@ -2903,6 +2970,91 @@ def dump_input_lines(output_lines, test_info, prefix_set, comment_string):
output_lines.append(line.rstrip("\n"))
+def reorder_function_start_check_blocks(lines, prefix_order, comment_string):
+ if not prefix_order:
+ return lines
+
+ ordered_prefixes = {prefix: index for index, prefix in enumerate(prefix_order)}
+ result = []
+ index = 0
+ while index < len(lines):
+ line = lines[index]
+ result.append(line)
+ index += 1
+ if not IR_FUNCTION_RE.match(line):
+ continue
+
+ prologue = []
+ while index < len(lines):
+ next_line = lines[index]
+ if next_line == "" or next_line.lstrip().startswith(comment_string):
+ prologue.append(next_line)
+ index += 1
+ continue
+ break
+
+ blocks = []
+ other_lines = []
+ current_prefix = None
+ current_block = []
+ saw_check_block = False
+
+ def flush_current_block():
+ nonlocal current_prefix, current_block
+ if current_prefix is not None:
+ while current_block and current_block[-1].strip() in (
+ "",
+ comment_string,
+ comment_string + SEPARATOR,
+ ):
+ current_block.pop()
+ if current_block:
+ blocks.append((current_prefix, current_block))
+ current_prefix = None
+ current_block = []
+
+ for prologue_line in prologue:
+ match = CHECK_RE.match(prologue_line)
+ if match:
+ prefix = match.group(1)
+ if current_prefix != prefix:
+ flush_current_block()
+ current_prefix = prefix
+ saw_check_block = True
+ current_block.append(prologue_line)
+ continue
+
+ if current_prefix is not None and prologue_line.strip() in (
+ "",
+ comment_string,
+ comment_string + SEPARATOR,
+ ):
+ current_block.append(prologue_line)
+ continue
+
+ flush_current_block()
+ other_lines.append(prologue_line)
+
+ flush_current_block()
+
+ if not saw_check_block:
+ result.extend(prologue)
+ continue
+
+ result.extend(other_lines)
+ blocks.sort(
+ key=lambda block: (
+ ordered_prefixes.get(block[0], len(ordered_prefixes)),
+ block[0],
+ )
+ )
+ for _, block_lines in blocks:
+ result.extend(block_lines)
+ result.append(comment_string)
+
+ return result
+
+
def add_checks_at_end(
output_lines, prefix_list, func_order, comment_string, check_generator
):
diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py
index 5329851e465e3..c6bf52e50a273 100755
--- a/llvm/utils/update_analyze_test_checks.py
+++ b/llvm/utils/update_analyze_test_checks.py
@@ -187,6 +187,9 @@ def update_test(opt_basename: str, ti: common.TestInfo):
continue
is_in_function = is_in_function_start = True
+ output_lines = common.reorder_function_start_check_blocks(
+ output_lines, ti.run_line_prefix_order, ";"
+ )
if ti.args.gen_unused_prefix_body:
output_lines.extend(
ti.get_checks_for_unused_prefixes(prefix_list, generated_prefixes)
diff --git a/llvm/utils/update_test_checks.py b/llvm/utils/update_test_checks.py
index 74e87787fd5b8..b2e1ab96d508c 100755
--- a/llvm/utils/update_test_checks.py
+++ b/llvm/utils/update_test_checks.py
@@ -311,6 +311,9 @@ def update_test(ti: common.TestInfo):
args.check_globals,
)
)
+ output_lines = common.reorder_function_start_check_blocks(
+ output_lines, ti.run_line_prefix_order, ";"
+ )
if ti.args.gen_unused_prefix_body:
output_lines.extend(
ti.get_checks_for_unused_prefixes(prefix_list, generated_prefixes)
>From 722697f4304f4b4c62abd85f60919059a9a0961a Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 15:05:59 -0700
Subject: [PATCH 06/21] Test cleanup
---
...pected => run-lines.analyze-only.expected} | 0
....llvm.expected => run-lines.both.expected} | 0
....expected => run-lines.llvm-only.expected} | 0
.../run-lines.llvm.then.analyze.expected | 100 ------------------
.../update_analyze_test_checks/run-lines.test | 21 ++--
5 files changed, 11 insertions(+), 110 deletions(-)
rename llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/{run-lines.analyze.expected => run-lines.analyze-only.expected} (100%)
rename llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/{run-lines.analyze.then.llvm.expected => run-lines.both.expected} (100%)
rename llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/{run-lines.llvm.expected => run-lines.llvm-only.expected} (100%)
delete mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze-only.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.expected
rename to llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze-only.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.both.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze.then.llvm.expected
rename to llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.both.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm-only.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.expected
rename to llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm-only.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
deleted file mode 100644
index 539baec1a3c47..0000000000000
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm.then.analyze.expected
+++ /dev/null
@@ -1,100 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
-; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
-; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
-; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
-
-define void @simple(ptr %p, i64 %n) {
-; CHECK-LABEL: VPlan for loop in 'simple'
-; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
-; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
-; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
-; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
-; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<entry>:
-; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
-; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.ph:
-; CHECK-NEXT: Successor(s): vector loop
-; CHECK-EMPTY:
-; CHECK-NEXT: <x1> vector loop: {
-; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.body:
-; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
-; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
-; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer ir<%gep>, ir<1>
-; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
-; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
-; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
-; CHECK-NEXT: Successor(s): middle.block
-; CHECK-EMPTY:
-; CHECK-NEXT: middle.block:
-; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
-; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
-; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<exit>:
-; CHECK-NEXT: No successors
-; CHECK-EMPTY:
-; CHECK-NEXT: scalar.ph:
-; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK-NEXT: Successor(s): ir-bb<loop>
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<loop>:
-; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
-; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
-; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
-; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
-; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
-;
-; LLVM-LABEL: @simple(
-; LLVM-NEXT: entry:
-; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
-; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
-; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
-; LLVM: vector.ph:
-; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
-; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
-; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
-; LLVM: vector.body:
-; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
-; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
-; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
-; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
-; LLVM: middle.block:
-; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
-; LLVM: scalar.ph:
-; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
-; LLVM-NEXT: br label [[LOOP:%.*]]
-; LLVM: loop:
-; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
-; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
-; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
-; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
-; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
-; LLVM: exit:
-; LLVM-NEXT: ret void
-;
-entry:
- br label %loop
-loop:
- %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
- %gep = getelementptr i32, ptr %p, i64 %iv
- store i32 0, ptr %gep
- %iv.next = add i64 %iv, 1
- %cmp = icmp ult i64 %iv.next, %n
- br i1 %cmp, label %loop, label %exit
-exit:
- ret void
-}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
index be2d9d5fbb452..398c89f4f6e73 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
@@ -2,34 +2,35 @@
## Analyze-only update using the first RUN line.
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll && %update_analyze_test_checks --run-lines=1 %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.expected
+# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze-only.expected
## Check that running the same script again does not change the result:
# RUN: %update_analyze_test_checks %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.expected
+# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze-only.expected
## LLVM-IR-only update using the second RUN line.
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll && %update_test_checks --run-lines=2 %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.expected
+# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm-only.expected
## Check that running the same script again does not change the result:
# RUN: %update_test_checks %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.expected
+# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm-only.expected
## Update analyze checks first, then LLVM IR checks.
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll
# RUN: %update_analyze_test_checks --run-lines=1 %t.ll
# RUN: %update_test_checks --run-lines=2 %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.then.llvm.expected
-## Check that re-running both scripts does not change the result:
+# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
+## Check that re-running both scripts is stable:
# RUN: %update_analyze_test_checks %t.ll
# RUN: %update_test_checks %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.analyze.then.llvm.expected
+# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
## Update LLVM IR checks first, then analyze checks.
+## The final output should converge to the same result as above.
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll
# RUN: %update_test_checks --run-lines=2 %t.ll
# RUN: %update_analyze_test_checks --run-lines=1 %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.then.analyze.expected
-## Check that re-running both scripts does not change the result:
+# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
+## Check that re-running both scripts is stable:
# RUN: %update_test_checks %t.ll
# RUN: %update_analyze_test_checks %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.llvm.then.analyze.expected
+# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
>From 356c3004bbf893fbd0740bcdb6152081a32ecc9a Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 15:15:19 -0700
Subject: [PATCH 07/21] Implement update_any_test_checks support + move to a
dedicated directory
---
.../test/tools/UpdateTestChecks/lit.local.cfg | 8 ++
.../Inputs/run-lines.analyze-only.expected | 0
.../Inputs/run-lines.both.expected | 0
.../Inputs/run-lines.ll | 0
.../Inputs/run-lines.llvm-only.expected | 0
.../Inputs/run-lines.with-both-notes.ll | 19 +++
.../multiple_utc/lit.local.cfg | 3 +
.../run-lines.test | 5 +
llvm/utils/update_any_test_checks.py | 125 +++++++++++-------
9 files changed, 112 insertions(+), 48 deletions(-)
rename llvm/test/tools/UpdateTestChecks/{update_analyze_test_checks => multiple_utc}/Inputs/run-lines.analyze-only.expected (100%)
rename llvm/test/tools/UpdateTestChecks/{update_analyze_test_checks => multiple_utc}/Inputs/run-lines.both.expected (100%)
rename llvm/test/tools/UpdateTestChecks/{update_analyze_test_checks => multiple_utc}/Inputs/run-lines.ll (100%)
rename llvm/test/tools/UpdateTestChecks/{update_analyze_test_checks => multiple_utc}/Inputs/run-lines.llvm-only.expected (100%)
create mode 100644 llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
create mode 100644 llvm/test/tools/UpdateTestChecks/multiple_utc/lit.local.cfg
rename llvm/test/tools/UpdateTestChecks/{update_analyze_test_checks => multiple_utc}/run-lines.test (86%)
diff --git a/llvm/test/tools/UpdateTestChecks/lit.local.cfg b/llvm/test/tools/UpdateTestChecks/lit.local.cfg
index 1445d186b93ed..6c297ab12d721 100644
--- a/llvm/test/tools/UpdateTestChecks/lit.local.cfg
+++ b/llvm/test/tools/UpdateTestChecks/lit.local.cfg
@@ -54,6 +54,14 @@ split_file_path = os.path.join(config.llvm_tools_dir, "split-file")
if os.path.isfile(split_file_path):
add_update_script_substitution("%update_test_body")
+update_any_test_checks_path = os.path.join(
+ config.llvm_src_root, "utils", "update_any_test_checks.py"
+)
+assert os.path.isfile(update_any_test_checks_path)
+config.substitutions.append(
+ ("%update_any_test_checks", "'%s' %s" % (config.python_executable, update_any_test_checks_path))
+)
+
llvm_mc_path = os.path.join(config.llvm_tools_dir, "llvm-mc")
if os.path.isfile(llvm_mc_path):
llvm_mc_arg = "--llvm-mc-binary " + shell_quote(llvm_mc_path)
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze-only.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.analyze-only.expected
rename to llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.both.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.both.expected
rename to llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.ll
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.ll
rename to llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.ll
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm-only.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.llvm-only.expected
similarity index 100%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/run-lines.llvm-only.expected
rename to llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.llvm-only.expected
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
new file mode 100644
index 0000000000000..370a1ae3b7bd1
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
+; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+
+define void @simple(ptr %p, i64 %n) {
+entry:
+ br label %loop
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep = getelementptr i32, ptr %p, i64 %iv
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp ult i64 %iv.next, %n
+ br i1 %cmp, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/lit.local.cfg b/llvm/test/tools/UpdateTestChecks/multiple_utc/lit.local.cfg
new file mode 100644
index 0000000000000..13223e9b4f75e
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/lit.local.cfg
@@ -0,0 +1,3 @@
+# These tests require opt.
+if "opt-binary" not in config.available_features:
+ config.unsupported = True
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
similarity index 86%
rename from llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
rename to llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
index 398c89f4f6e73..7a6121acd25d5 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/run-lines.test
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
@@ -34,3 +34,8 @@
# RUN: %update_test_checks %t.ll
# RUN: %update_analyze_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
+
+## update_any_test_checks.py should dispatch to both scripts from the NOTE block.
+# RUN: cp -f %S/Inputs/run-lines.with-both-notes.ll %t.ll
+# RUN: %update_any_test_checks --path %llvm_tools_dir %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
diff --git a/llvm/utils/update_any_test_checks.py b/llvm/utils/update_any_test_checks.py
index ec277f140a34f..1a663ad62630d 100755
--- a/llvm/utils/update_any_test_checks.py
+++ b/llvm/utils/update_any_test_checks.py
@@ -22,6 +22,18 @@
)
+def get_autogenerated_utc_names(lines):
+ utc_names = []
+ for line in lines:
+ m = RE_ASSERTIONS.search(line.strip())
+ if m is None:
+ break
+ utc_name = m.group(1)
+ if utc_name not in utc_names:
+ utc_names.append(utc_name)
+ return utc_names
+
+
def find_utc_tool(search_path, utc_name):
"""
Return the path to the given UTC tool in the search path, or None if not
@@ -44,6 +56,16 @@ def run_utc_tool(utc_name, utc_tool, testname, environment):
return (result.returncode, result.stdout, result.stderr)
+def update_test_file(utc_names, utc_tools, testname, environment):
+ outputs = []
+ for utc_name in utc_names:
+ return_code, stdout, stderr = run_utc_tool(
+ utc_name, utc_tools[utc_name], testname, environment
+ )
+ outputs.append((utc_name, return_code, stdout, stderr))
+ return outputs
+
+
def read_arguments_from_file(filename):
try:
with open(filename, "r") as file:
@@ -72,30 +94,33 @@ def utc_lit_plugin(result, test, commands):
utc_search_path = os.path.join(os.path.dirname(script_name), os.path.pardir)
with open(testname, "r") as f:
- header = f.readline().strip()
+ utc_names = get_autogenerated_utc_names(f)
- m = RE_ASSERTIONS.search(header)
- if m is None:
+ if not utc_names:
return None
- utc_name = m.group(1)
- utc_tool = find_utc_tool([utc_search_path], utc_name)
- if not utc_tool:
- return f"update-utc-tests: {utc_name} not found"
-
- return_code, stdout, stderr = run_utc_tool(
- utc_name, utc_tool, testname, test.config.environment
- )
+ utc_tools = {}
+ for utc_name in utc_names:
+ utc_tool = find_utc_tool([utc_search_path], utc_name)
+ if not utc_tool:
+ return f"update-utc-tests: {utc_name} not found"
+ utc_tools[utc_name] = utc_tool
+
+ outputs = update_test_file(utc_names, utc_tools, testname, test.config.environment)
+ messages = []
+ for utc_name, return_code, stdout, stderr in outputs:
+ stderr = stderr.decode(errors="replace")
+ if return_code != 0:
+ if stderr:
+ return f"update-utc-tests: {utc_name} exited with return code {return_code}\n{stderr.rstrip()}"
+ return f"update-utc-tests: {utc_name} exited with return code {return_code}"
- stderr = stderr.decode(errors="replace")
- if return_code != 0:
- if stderr:
- return f"update-utc-tests: {utc_name} exited with return code {return_code}\n{stderr.rstrip()}"
- return f"update-utc-tests: {utc_name} exited with return code {return_code}"
+ stdout = stdout.decode(errors="replace")
+ if stdout:
+ messages.append(stdout.rstrip())
- stdout = stdout.decode(errors="replace")
- if stdout:
- return f"update-utc-tests: updated {testname}\n{stdout.rstrip()}"
+ if messages:
+ return f"update-utc-tests: updated {testname}\n" + "\n".join(messages)
return f"update-utc-tests: updated {testname}"
@@ -147,46 +172,50 @@ def main():
for testname in tests:
with open(testname, "r") as f:
- header = f.readline().strip()
- m = RE_ASSERTIONS.search(header)
- if m is None:
+ utc_names = get_autogenerated_utc_names(f)
+ if not utc_names:
not_autogenerated.append(testname)
continue
- utc_name = m.group(1)
- if utc_name not in utc_tools:
- utc_tools[utc_name] = find_utc_tool(utc_search_path, utc_name)
- if not utc_tools[utc_name]:
- print(
- f"{utc_name}: not found (used in {testname})",
- file=sys.stderr,
- )
- have_error = True
- continue
+ missing_tool = False
+ for utc_name in utc_names:
+ if utc_name not in utc_tools:
+ utc_tools[utc_name] = find_utc_tool(utc_search_path, utc_name)
+ if not utc_tools[utc_name]:
+ print(
+ f"{utc_name}: not found (used in {testname})",
+ file=sys.stderr,
+ )
+ have_error = True
+ missing_tool = True
+ break
+ if missing_tool:
+ continue
future = executor.submit(
- run_utc_tool, utc_name, utc_tools[utc_name], testname, local_env
+ update_test_file, utc_names, utc_tools, testname, local_env
)
jobs.append((testname, future))
for testname, future in jobs:
- return_code, stdout, stderr = future.result()
+ outputs = future.result()
print(f"Update {testname}")
- stdout = stdout.decode(errors="replace")
- if stdout:
- print(stdout, end="")
- if not stdout.endswith("\n"):
- print()
-
- stderr = stderr.decode(errors="replace")
- if stderr:
- print(stderr, end="")
- if not stderr.endswith("\n"):
- print()
- if return_code != 0:
- print(f"Return code: {return_code}")
- have_error = True
+ for utc_name, return_code, stdout, stderr in outputs:
+ stdout = stdout.decode(errors="replace")
+ if stdout:
+ print(stdout, end="")
+ if not stdout.endswith("\n"):
+ print()
+
+ stderr = stderr.decode(errors="replace")
+ if stderr:
+ print(stderr, end="")
+ if not stderr.endswith("\n"):
+ print()
+ if return_code != 0:
+ print(f"Return code: {return_code}")
+ have_error = True
if have_error:
sys.exit(1)
>From a36c45c1f783f06e817456a1d8693374005cffad Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 15:51:34 -0700
Subject: [PATCH 08/21] Update a few tests
---
.../AArch64/aarch64-predication.ll | 4 +-
.../LoopVectorize/AArch64/intrinsiccost.ll | 211 ++++++++-------
.../AArch64/maximize-bandwidth-invalidate.ll | 18 +-
.../AArch64/multiple-result-intrinsics.ll | 245 ++++++++++--------
.../AArch64/struct-return-cost.ll | 132 +++++-----
.../AArch64/type-shrinkage-zext-costs.ll | 105 ++++----
6 files changed, 361 insertions(+), 354 deletions(-)
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/aarch64-predication.ll b/llvm/test/Transforms/LoopVectorize/AArch64/aarch64-predication.ll
index d5b96fbd4ce4c..cfb531cad7347 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/aarch64-predication.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/aarch64-predication.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --run-lines 2 --version 6
; REQUIRES: asserts
; RUN: opt < %s -passes=loop-vectorize -force-vector-interleave=1 -disable-output -debug-only=loop-vectorize 2>&1 | FileCheck %s --check-prefix=COST
; RUN: opt < %s -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -S | FileCheck %s
@@ -85,5 +85,3 @@ for.end:
%var7 = phi i64 [ %var6, %for.inc ]
ret i64 %var7
}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; COST: {{.*}}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/intrinsiccost.ll b/llvm/test/Transforms/LoopVectorize/AArch64/intrinsiccost.ll
index c8555a8629ec5..53149e537da05 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/intrinsiccost.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/intrinsiccost.ll
@@ -1,18 +1,19 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes=loop-vectorize -S %s | FileCheck %s --check-prefix=CHECK
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost of.*WIDEN-INTRINSIC" --run-lines 1
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
+
; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize -disable-output %s 2>&1 | FileCheck %s --check-prefix=CHECK-COST
+; RUN: opt -passes=loop-vectorize -S %s | FileCheck %s --check-prefix=CHECK
; REQUIRES: asserts
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-gnu"
-; CHECK-COST-LABEL: sadd
-; CHECK-COST: Found an estimated cost of 6 for VF 1 For instruction: %1 = tail call i16 @llvm.sadd.sat.i16(i16 %0, i16 %offset)
-; CHECK-COST: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
-; CHECK-COST: Cost of 1 for VF 4: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
-; CHECK-COST: Cost of 1 for VF 8: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
-
define void @saddsat(ptr nocapture readonly %pSrc, i16 signext %offset, ptr nocapture noalias %pDst, i32 %blockSize) #0 {
+; CHECK-COST-LABEL: 'saddsat'
+; CHECK-COST: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
+; CHECK-COST: Cost of 1 for VF 4: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
+; CHECK-COST: Cost of 1 for VF 8: WIDEN-INTRINSIC ir<%1> = call llvm.sadd.sat(ir<%0>, ir<%offset>)
+;
; CHECK-LABEL: @saddsat(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_NOT6:%.*]] = icmp eq i32 [[BLOCKSIZE:%.*]], 0
@@ -27,30 +28,30 @@ define void @saddsat(ptr nocapture readonly %pSrc, i16 signext %offset, ptr noca
; CHECK: vector.ph:
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 16
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
-; CHECK-NEXT: [[DOTCAST1:%.*]] = trunc i64 [[N_VEC]] to i32
-; CHECK-NEXT: [[IND_END8:%.*]] = sub i32 [[BLOCKSIZE]], [[DOTCAST1]]
-; CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[N_VEC]], 1
-; CHECK-NEXT: [[IND_END10:%.*]] = getelementptr i8, ptr [[PSRC:%.*]], i64 [[TMP6]]
-; CHECK-NEXT: [[IND_END13:%.*]] = getelementptr i8, ptr [[PDST:%.*]], i64 [[TMP6]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[N_VEC]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[BLOCKSIZE]], [[TMP1]]
+; CHECK-NEXT: [[TMP3:%.*]] = shl i64 [[N_VEC]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[PSRC:%.*]], i64 [[TMP3]]
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[PDST:%.*]], i64 [[TMP3]]
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i16> poison, i16 [[OFFSET:%.*]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i16> [[BROADCAST_SPLATINSERT]], <8 x i16> poison, <8 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; CHECK-NEXT: [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 1
-; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[OFFSET_IDX]]
-; CHECK-NEXT: [[NEXT_GEP3:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[OFFSET_IDX]]
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i16, ptr [[NEXT_GEP]], i64 8
+; CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[INDEX]], 1
+; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[TMP6]]
+; CHECK-NEXT: [[NEXT_GEP2:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[TMP6]]
+; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i16, ptr [[NEXT_GEP]], i64 8
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i16>, ptr [[NEXT_GEP]], align 2
-; CHECK-NEXT: [[WIDE_LOAD4:%.*]] = load <8 x i16>, ptr [[TMP1]], align 2
-; CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> [[WIDE_LOAD]], <8 x i16> [[BROADCAST_SPLAT]])
-; CHECK-NEXT: [[TMP3:%.*]] = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> [[WIDE_LOAD4]], <8 x i16> [[BROADCAST_SPLAT]])
-; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i16, ptr [[NEXT_GEP3]], i64 8
-; CHECK-NEXT: store <8 x i16> [[TMP2]], ptr [[NEXT_GEP3]], align 2
-; CHECK-NEXT: store <8 x i16> [[TMP3]], ptr [[TMP4]], align 2
+; CHECK-NEXT: [[WIDE_LOAD3:%.*]] = load <8 x i16>, ptr [[TMP7]], align 2
+; CHECK-NEXT: [[TMP8:%.*]] = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> [[WIDE_LOAD]], <8 x i16> [[BROADCAST_SPLAT]])
+; CHECK-NEXT: [[TMP9:%.*]] = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> [[WIDE_LOAD3]], <8 x i16> [[BROADCAST_SPLAT]])
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr i16, ptr [[NEXT_GEP2]], i64 8
+; CHECK-NEXT: store <8 x i16> [[TMP8]], ptr [[NEXT_GEP2]], align 2
+; CHECK-NEXT: store <8 x i16> [[TMP9]], ptr [[TMP10]], align 2
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16
-; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
; CHECK-NEXT: br i1 [[CMP_N]], label [[WHILE_END_LOOPEXIT:%.*]], label [[VEC_EPILOG_ITER_CHECK:%.*]]
@@ -59,44 +60,44 @@ define void @saddsat(ptr nocapture readonly %pSrc, i16 signext %offset, ptr noca
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]], !prof [[PROF3:![0-9]+]]
; CHECK: vec.epilog.ph:
; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
-; CHECK-NEXT: [[N_MOD_VF4:%.*]] = urem i64 [[TMP0]], 4
-; CHECK-NEXT: [[N_VEC6:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF4]]
-; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i64 [[N_VEC6]] to i32
-; CHECK-NEXT: [[IND_END:%.*]] = sub i32 [[BLOCKSIZE]], [[DOTCAST]]
-; CHECK-NEXT: [[TMP8:%.*]] = shl i64 [[N_VEC6]], 1
-; CHECK-NEXT: [[IND_END9:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[TMP8]]
-; CHECK-NEXT: [[IND_END12:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[TMP8]]
-; CHECK-NEXT: [[BROADCAST_SPLATINSERT21:%.*]] = insertelement <4 x i16> poison, i16 [[OFFSET]], i64 0
-; CHECK-NEXT: [[BROADCAST_SPLAT22:%.*]] = shufflevector <4 x i16> [[BROADCAST_SPLATINSERT21]], <4 x i16> poison, <4 x i32> zeroinitializer
+; CHECK-NEXT: [[N_MOD_VF6:%.*]] = urem i64 [[TMP0]], 4
+; CHECK-NEXT: [[N_VEC7:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF6]]
+; CHECK-NEXT: [[TMP12:%.*]] = trunc i64 [[N_VEC7]] to i32
+; CHECK-NEXT: [[TMP13:%.*]] = sub i32 [[BLOCKSIZE]], [[TMP12]]
+; CHECK-NEXT: [[TMP14:%.*]] = shl i64 [[N_VEC7]], 1
+; CHECK-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[TMP14]]
+; CHECK-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[TMP14]]
+; CHECK-NEXT: [[BROADCAST_SPLATINSERT8:%.*]] = insertelement <4 x i16> poison, i16 [[OFFSET]], i64 0
+; CHECK-NEXT: [[BROADCAST_SPLAT9:%.*]] = shufflevector <4 x i16> [[BROADCAST_SPLATINSERT8]], <4 x i16> poison, <4 x i32> zeroinitializer
; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]]
; CHECK: vec.epilog.vector.body:
-; CHECK-NEXT: [[INDEX15:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT23:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
-; CHECK-NEXT: [[OFFSET_IDX16:%.*]] = shl i64 [[INDEX15]], 1
-; CHECK-NEXT: [[NEXT_GEP17:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[OFFSET_IDX16]]
-; CHECK-NEXT: [[NEXT_GEP19:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[OFFSET_IDX16]]
-; CHECK-NEXT: [[WIDE_LOAD20:%.*]] = load <4 x i16>, ptr [[NEXT_GEP17]], align 2
-; CHECK-NEXT: [[TMP10:%.*]] = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> [[WIDE_LOAD20]], <4 x i16> [[BROADCAST_SPLAT22]])
-; CHECK-NEXT: store <4 x i16> [[TMP10]], ptr [[NEXT_GEP19]], align 2
-; CHECK-NEXT: [[INDEX_NEXT23]] = add nuw i64 [[INDEX15]], 4
-; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT23]], [[N_VEC6]]
-; CHECK-NEXT: br i1 [[TMP11]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
+; CHECK-NEXT: [[INDEX10:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT14:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
+; CHECK-NEXT: [[TMP17:%.*]] = shl i64 [[INDEX10]], 1
+; CHECK-NEXT: [[NEXT_GEP11:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[TMP17]]
+; CHECK-NEXT: [[NEXT_GEP12:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[TMP17]]
+; CHECK-NEXT: [[WIDE_LOAD13:%.*]] = load <4 x i16>, ptr [[NEXT_GEP11]], align 2
+; CHECK-NEXT: [[TMP18:%.*]] = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> [[WIDE_LOAD13]], <4 x i16> [[BROADCAST_SPLAT9]])
+; CHECK-NEXT: store <4 x i16> [[TMP18]], ptr [[NEXT_GEP12]], align 2
+; CHECK-NEXT: [[INDEX_NEXT14]] = add nuw i64 [[INDEX10]], 4
+; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i64 [[INDEX_NEXT14]], [[N_VEC7]]
+; CHECK-NEXT: br i1 [[TMP19]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
; CHECK: vec.epilog.middle.block:
-; CHECK-NEXT: [[CMP_N14:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC6]]
-; CHECK-NEXT: br i1 [[CMP_N14]], label [[WHILE_END_LOOPEXIT]], label [[VEC_EPILOG_SCALAR_PH]]
+; CHECK-NEXT: [[CMP_N15:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC7]]
+; CHECK-NEXT: br i1 [[CMP_N15]], label [[WHILE_END_LOOPEXIT]], label [[VEC_EPILOG_SCALAR_PH]]
; CHECK: vec.epilog.scalar.ph:
-; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ [[IND_END]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END8]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[BLOCKSIZE]], [[ITER_CHECK]] ]
-; CHECK-NEXT: [[BC_RESUME_VAL11:%.*]] = phi ptr [ [[IND_END9]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END10]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PSRC]], [[ITER_CHECK]] ]
-; CHECK-NEXT: [[BC_RESUME_VAL14:%.*]] = phi ptr [ [[IND_END12]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END13]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PDST]], [[ITER_CHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL16:%.*]] = phi i32 [ [[TMP13]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[TMP2]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[BLOCKSIZE]], [[ITER_CHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL17:%.*]] = phi ptr [ [[TMP15]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[TMP4]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PSRC]], [[ITER_CHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL18:%.*]] = phi ptr [ [[TMP16]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[TMP5]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PDST]], [[ITER_CHECK]] ]
; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
; CHECK: while.body:
-; CHECK-NEXT: [[BLKCNT_09:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL]], [[VEC_EPILOG_SCALAR_PH]] ]
-; CHECK-NEXT: [[PSRC_ADDR_08:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL11]], [[VEC_EPILOG_SCALAR_PH]] ]
-; CHECK-NEXT: [[PDST_ADDR_07:%.*]] = phi ptr [ [[INCDEC_PTR3:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL14]], [[VEC_EPILOG_SCALAR_PH]] ]
+; CHECK-NEXT: [[BLKCNT_09:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL16]], [[VEC_EPILOG_SCALAR_PH]] ]
+; CHECK-NEXT: [[PSRC_ADDR_08:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL17]], [[VEC_EPILOG_SCALAR_PH]] ]
+; CHECK-NEXT: [[PDST_ADDR_07:%.*]] = phi ptr [ [[INCDEC_PTR3:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL18]], [[VEC_EPILOG_SCALAR_PH]] ]
; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i16, ptr [[PSRC_ADDR_08]], i32 1
-; CHECK-NEXT: [[TMP12:%.*]] = load i16, ptr [[PSRC_ADDR_08]], align 2
-; CHECK-NEXT: [[TMP13:%.*]] = tail call i16 @llvm.sadd.sat.i16(i16 [[TMP12]], i16 [[OFFSET]])
+; CHECK-NEXT: [[TMP20:%.*]] = load i16, ptr [[PSRC_ADDR_08]], align 2
+; CHECK-NEXT: [[TMP21:%.*]] = tail call i16 @llvm.sadd.sat.i16(i16 [[TMP20]], i16 [[OFFSET]])
; CHECK-NEXT: [[INCDEC_PTR3]] = getelementptr inbounds i16, ptr [[PDST_ADDR_07]], i32 1
-; CHECK-NEXT: store i16 [[TMP13]], ptr [[PDST_ADDR_07]], align 2
+; CHECK-NEXT: store i16 [[TMP21]], ptr [[PDST_ADDR_07]], align 2
; CHECK-NEXT: [[DEC]] = add i32 [[BLKCNT_09]], -1
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[DEC]], 0
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[WHILE_END_LOOPEXIT]], label [[WHILE_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
@@ -126,15 +127,13 @@ while.end:
ret void
}
-; CHECK-COST-LABEL: umin
-; CHECK-COST: Found an estimated cost of 2 for VF 1 For instruction: %1 = tail call i8 @llvm.umin.i8(i8 %0, i8 %offset)
-; CHECK-COST: Cost of 1 for VF 2: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
-; CHECK-COST: Cost of 1 for VF 4: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
-; CHECK-COST: Cost of 1 for VF 8: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
-; CHECK-COST: Cost of 1 for VF 16: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
-
-
define void @umin(ptr nocapture readonly %pSrc, i8 signext %offset, ptr nocapture noalias %pDst, i32 %blockSize) #0 {
+; CHECK-COST-LABEL: 'umin'
+; CHECK-COST: Cost of 1 for VF 2: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
+; CHECK-COST: Cost of 1 for VF 4: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
+; CHECK-COST: Cost of 1 for VF 8: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
+; CHECK-COST: Cost of 1 for VF 16: WIDEN-INTRINSIC ir<%1> = call llvm.umin(ir<%0>, ir<%offset>)
+;
; CHECK-LABEL: @umin(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_NOT6:%.*]] = icmp eq i32 [[BLOCKSIZE:%.*]], 0
@@ -149,10 +148,10 @@ define void @umin(ptr nocapture readonly %pSrc, i8 signext %offset, ptr nocaptur
; CHECK: vector.ph:
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 32
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
-; CHECK-NEXT: [[DOTCAST6:%.*]] = trunc i64 [[N_VEC]] to i32
-; CHECK-NEXT: [[IND_END7:%.*]] = sub i32 [[BLOCKSIZE]], [[DOTCAST6]]
-; CHECK-NEXT: [[IND_END9:%.*]] = getelementptr i8, ptr [[PSRC:%.*]], i64 [[N_VEC]]
-; CHECK-NEXT: [[IND_END12:%.*]] = getelementptr i8, ptr [[PDST:%.*]], i64 [[N_VEC]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[N_VEC]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[BLOCKSIZE]], [[TMP1]]
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[PSRC:%.*]], i64 [[N_VEC]]
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[PDST:%.*]], i64 [[N_VEC]]
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <16 x i8> poison, i8 [[OFFSET:%.*]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <16 x i8> [[BROADCAST_SPLATINSERT]], <16 x i8> poison, <16 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -160,17 +159,17 @@ define void @umin(ptr nocapture readonly %pSrc, i8 signext %offset, ptr nocaptur
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[INDEX]]
; CHECK-NEXT: [[NEXT_GEP2:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[INDEX]]
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[NEXT_GEP]], i64 16
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[NEXT_GEP]], i64 16
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <16 x i8>, ptr [[NEXT_GEP]], align 2
-; CHECK-NEXT: [[WIDE_LOAD3:%.*]] = load <16 x i8>, ptr [[TMP1]], align 2
-; CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.umin.v16i8(<16 x i8> [[WIDE_LOAD]], <16 x i8> [[BROADCAST_SPLAT]])
-; CHECK-NEXT: [[TMP3:%.*]] = call <16 x i8> @llvm.umin.v16i8(<16 x i8> [[WIDE_LOAD3]], <16 x i8> [[BROADCAST_SPLAT]])
-; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[NEXT_GEP2]], i64 16
-; CHECK-NEXT: store <16 x i8> [[TMP2]], ptr [[NEXT_GEP2]], align 2
-; CHECK-NEXT: store <16 x i8> [[TMP3]], ptr [[TMP4]], align 2
+; CHECK-NEXT: [[WIDE_LOAD3:%.*]] = load <16 x i8>, ptr [[TMP5]], align 2
+; CHECK-NEXT: [[TMP6:%.*]] = call <16 x i8> @llvm.umin.v16i8(<16 x i8> [[WIDE_LOAD]], <16 x i8> [[BROADCAST_SPLAT]])
+; CHECK-NEXT: [[TMP7:%.*]] = call <16 x i8> @llvm.umin.v16i8(<16 x i8> [[WIDE_LOAD3]], <16 x i8> [[BROADCAST_SPLAT]])
+; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[NEXT_GEP2]], i64 16
+; CHECK-NEXT: store <16 x i8> [[TMP6]], ptr [[NEXT_GEP2]], align 2
+; CHECK-NEXT: store <16 x i8> [[TMP7]], ptr [[TMP8]], align 2
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32
-; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
; CHECK-NEXT: br i1 [[CMP_N]], label [[WHILE_END_LOOPEXIT:%.*]], label [[VEC_EPILOG_ITER_CHECK:%.*]]
@@ -179,42 +178,42 @@ define void @umin(ptr nocapture readonly %pSrc, i8 signext %offset, ptr nocaptur
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]], !prof [[PROF7:![0-9]+]]
; CHECK: vec.epilog.ph:
; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
-; CHECK-NEXT: [[N_MOD_VF4:%.*]] = urem i64 [[TMP0]], 8
-; CHECK-NEXT: [[N_VEC5:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF4]]
-; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i64 [[N_VEC5]] to i32
-; CHECK-NEXT: [[IND_END:%.*]] = sub i32 [[BLOCKSIZE]], [[DOTCAST]]
-; CHECK-NEXT: [[IND_END8:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[N_VEC5]]
-; CHECK-NEXT: [[IND_END11:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[N_VEC5]]
-; CHECK-NEXT: [[BROADCAST_SPLATINSERT18:%.*]] = insertelement <8 x i8> poison, i8 [[OFFSET]], i64 0
-; CHECK-NEXT: [[BROADCAST_SPLAT19:%.*]] = shufflevector <8 x i8> [[BROADCAST_SPLATINSERT18]], <8 x i8> poison, <8 x i32> zeroinitializer
+; CHECK-NEXT: [[N_MOD_VF6:%.*]] = urem i64 [[TMP0]], 8
+; CHECK-NEXT: [[N_VEC7:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF6]]
+; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[N_VEC7]] to i32
+; CHECK-NEXT: [[TMP11:%.*]] = sub i32 [[BLOCKSIZE]], [[TMP10]]
+; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[N_VEC7]]
+; CHECK-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[N_VEC7]]
+; CHECK-NEXT: [[BROADCAST_SPLATINSERT8:%.*]] = insertelement <8 x i8> poison, i8 [[OFFSET]], i64 0
+; CHECK-NEXT: [[BROADCAST_SPLAT9:%.*]] = shufflevector <8 x i8> [[BROADCAST_SPLATINSERT8]], <8 x i8> poison, <8 x i32> zeroinitializer
; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]]
; CHECK: vec.epilog.vector.body:
-; CHECK-NEXT: [[INDEX14:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT20:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
-; CHECK-NEXT: [[NEXT_GEP15:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[INDEX14]]
-; CHECK-NEXT: [[NEXT_GEP16:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[INDEX14]]
-; CHECK-NEXT: [[WIDE_LOAD17:%.*]] = load <8 x i8>, ptr [[NEXT_GEP15]], align 2
-; CHECK-NEXT: [[TMP6:%.*]] = call <8 x i8> @llvm.umin.v8i8(<8 x i8> [[WIDE_LOAD17]], <8 x i8> [[BROADCAST_SPLAT19]])
-; CHECK-NEXT: store <8 x i8> [[TMP6]], ptr [[NEXT_GEP16]], align 2
-; CHECK-NEXT: [[INDEX_NEXT20]] = add nuw i64 [[INDEX14]], 8
-; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT20]], [[N_VEC5]]
-; CHECK-NEXT: br i1 [[TMP7]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
+; CHECK-NEXT: [[INDEX10:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT14:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
+; CHECK-NEXT: [[NEXT_GEP11:%.*]] = getelementptr i8, ptr [[PSRC]], i64 [[INDEX10]]
+; CHECK-NEXT: [[NEXT_GEP12:%.*]] = getelementptr i8, ptr [[PDST]], i64 [[INDEX10]]
+; CHECK-NEXT: [[WIDE_LOAD13:%.*]] = load <8 x i8>, ptr [[NEXT_GEP11]], align 2
+; CHECK-NEXT: [[TMP14:%.*]] = call <8 x i8> @llvm.umin.v8i8(<8 x i8> [[WIDE_LOAD13]], <8 x i8> [[BROADCAST_SPLAT9]])
+; CHECK-NEXT: store <8 x i8> [[TMP14]], ptr [[NEXT_GEP12]], align 2
+; CHECK-NEXT: [[INDEX_NEXT14]] = add nuw i64 [[INDEX10]], 8
+; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT14]], [[N_VEC7]]
+; CHECK-NEXT: br i1 [[TMP15]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
; CHECK: vec.epilog.middle.block:
-; CHECK-NEXT: [[CMP_N13:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC5]]
-; CHECK-NEXT: br i1 [[CMP_N13]], label [[WHILE_END_LOOPEXIT]], label [[VEC_EPILOG_SCALAR_PH]]
+; CHECK-NEXT: [[CMP_N15:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC7]]
+; CHECK-NEXT: br i1 [[CMP_N15]], label [[WHILE_END_LOOPEXIT]], label [[VEC_EPILOG_SCALAR_PH]]
; CHECK: vec.epilog.scalar.ph:
-; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ [[IND_END]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END7]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[BLOCKSIZE]], [[ITER_CHECK]] ]
-; CHECK-NEXT: [[BC_RESUME_VAL10:%.*]] = phi ptr [ [[IND_END8]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END9]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PSRC]], [[ITER_CHECK]] ]
-; CHECK-NEXT: [[BC_RESUME_VAL13:%.*]] = phi ptr [ [[IND_END11]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[IND_END12]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PDST]], [[ITER_CHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL16:%.*]] = phi i32 [ [[TMP11]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[TMP2]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[BLOCKSIZE]], [[ITER_CHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL17:%.*]] = phi ptr [ [[TMP12]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[TMP3]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PSRC]], [[ITER_CHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL18:%.*]] = phi ptr [ [[TMP13]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[TMP4]], [[VEC_EPILOG_ITER_CHECK]] ], [ [[PDST]], [[ITER_CHECK]] ]
; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
; CHECK: while.body:
-; CHECK-NEXT: [[BLKCNT_09:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL]], [[VEC_EPILOG_SCALAR_PH]] ]
-; CHECK-NEXT: [[PSRC_ADDR_08:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL10]], [[VEC_EPILOG_SCALAR_PH]] ]
-; CHECK-NEXT: [[PDST_ADDR_07:%.*]] = phi ptr [ [[INCDEC_PTR3:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL13]], [[VEC_EPILOG_SCALAR_PH]] ]
+; CHECK-NEXT: [[BLKCNT_09:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL16]], [[VEC_EPILOG_SCALAR_PH]] ]
+; CHECK-NEXT: [[PSRC_ADDR_08:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL17]], [[VEC_EPILOG_SCALAR_PH]] ]
+; CHECK-NEXT: [[PDST_ADDR_07:%.*]] = phi ptr [ [[INCDEC_PTR3:%.*]], [[WHILE_BODY]] ], [ [[BC_RESUME_VAL18]], [[VEC_EPILOG_SCALAR_PH]] ]
; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, ptr [[PSRC_ADDR_08]], i32 1
-; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[PSRC_ADDR_08]], align 2
-; CHECK-NEXT: [[TMP9:%.*]] = tail call i8 @llvm.umin.i8(i8 [[TMP8]], i8 [[OFFSET]])
+; CHECK-NEXT: [[TMP16:%.*]] = load i8, ptr [[PSRC_ADDR_08]], align 2
+; CHECK-NEXT: [[TMP17:%.*]] = tail call i8 @llvm.umin.i8(i8 [[TMP16]], i8 [[OFFSET]])
; CHECK-NEXT: [[INCDEC_PTR3]] = getelementptr inbounds i8, ptr [[PDST_ADDR_07]], i32 1
-; CHECK-NEXT: store i8 [[TMP9]], ptr [[PDST_ADDR_07]], align 2
+; CHECK-NEXT: store i8 [[TMP17]], ptr [[PDST_ADDR_07]], align 2
; CHECK-NEXT: [[DEC]] = add i32 [[BLKCNT_09]], -1
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[DEC]], 0
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[WHILE_END_LOOPEXIT]], label [[WHILE_BODY]], !llvm.loop [[LOOP9:![0-9]+]]
@@ -243,7 +242,3 @@ while.body:
while.end:
ret void
}
-
-
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-COST: {{.*}}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/maximize-bandwidth-invalidate.ll b/llvm/test/Transforms/LoopVectorize/AArch64/maximize-bandwidth-invalidate.ll
index e5d13bea64fba..0073661d686ac 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/maximize-bandwidth-invalidate.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/maximize-bandwidth-invalidate.ll
@@ -1,7 +1,8 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost of .*REPLICATE ir<%0> = load" --filter "LV: Selecting VF:" --run-lines 1 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-vectorize -vectorizer-maximize-bandwidth -S 2>&1 | FileCheck %s
; RUN: opt < %s -passes=loop-vectorize -vectorizer-maximize-bandwidth -S -debug-only=loop-vectorize 2>&1 -disable-output | FileCheck %s --check-prefix=COST
+; RUN: opt < %s -passes=loop-vectorize -vectorizer-maximize-bandwidth -S 2>&1 | FileCheck %s
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64"
@@ -10,13 +11,14 @@ target triple = "aarch64"
; due to invalid cost decisions. The loop below has a low maximum trip count,
; so will be masked.
-; COST: Cost of 3000000 for VF 2: REPLICATE ir<%0> = load
-; COST: Cost of 3000000 for VF 4: REPLICATE ir<%0> = load
-; COST: Cost of 3000000 for VF 8: REPLICATE ir<%0> = load
-; COST: Cost of 3000000 for VF 16: REPLICATE ir<%0> = load
-; COST: LV: Selecting VF: 1.
-
define i32 @test(ptr nocapture noundef readonly %pInVec, ptr nocapture noundef readonly %pInA1, ptr nocapture noundef readonly %pInA2, ptr nocapture noundef readonly %pInA3, ptr nocapture noundef readonly %pInA4, i32 noundef %numCols) {
+; COST-LABEL: 'test'
+; COST: Cost of 3000000 for VF 2: REPLICATE ir<%0> = load vp<%next.gep> (S->V)
+; COST: Cost of 3000000 for VF 4: REPLICATE ir<%0> = load vp<%next.gep> (S->V)
+; COST: Cost of 3000000 for VF 8: REPLICATE ir<%0> = load vp<%next.gep> (S->V)
+; COST: Cost of 3000000 for VF 16: REPLICATE ir<%0> = load vp<%next.gep> (S->V)
+; COST: LV: Selecting VF: 1.
+;
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[AND:%.*]] = and i32 [[NUMCOLS:%.*]], 3
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll b/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll
index 55994ad9a98f8..109cec3e9d323 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll
@@ -1,27 +1,30 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|sincos|modf|extractvalue|store|with\.overflow)" --version 5
-; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve < %s -S -o - -debug-only=loop-vectorize 2>%t.1 | FileCheck %s --check-prefix=CHECK
-; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve -vector-library=ArmPL < %s -S -o - -debug-only=loop-vectorize 2>%t.2 | FileCheck %s --check-prefix=CHECK-ARMPL
-; RUN: FileCheck --input-file=%t.1 --check-prefix=CHECK-COST %s
-; RUN: FileCheck --input-file=%t.2 --check-prefix=CHECK-COST-ARMPL %s
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Found an estimated cost of .*@llvm\." --filter "Cost of .*: (WIDEN-INTRINSIC|REPLICATE)" --run-lines 1,2 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|sincos|modf|extractvalue|store|with\.overflow)" --run-lines 3,4 --version 5
+; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve < %s -disable-output -debug-only=loop-vectorize 2>&1 | FileCheck %s --check-prefix=CHECK-COST
+; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve -vector-library=ArmPL < %s -disable-output -debug-only=loop-vectorize 2>&1 | FileCheck %s --check-prefix=CHECK-COST-ARMPL
+; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve < %s -S -o - | FileCheck %s --check-prefix=CHECK
+; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve -vector-library=ArmPL < %s -S -o - | FileCheck %s --check-prefix=CHECK-ARMPL
; REQUIRES: asserts
-; CHECK-COST-LABEL: sincos_f32
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
-; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-
-; CHECK-COST-ARMPL-LABEL: sincos_f32
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
-; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 12 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+
define void @sincos_f32(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'sincos_f32'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
+; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+;
+; CHECK-COST-ARMPL-LABEL: 'sincos_f32'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
+; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 12 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+;
; CHECK-LABEL: define void @sincos_f32(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK: [[ENTRY:.*:]]
@@ -82,19 +85,21 @@ exit:
ret void
}
-; CHECK-COST-LABEL: sincos_f64
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincos.f64(double %in_val)
-; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f64(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f64(ir<%in_val>)
-; CHECK-COST-ARMPL-LABEL: sincos_f64
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincos.f64(double %in_val)
-; CHECK-COST-ARMPL: Cost of 12 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f64(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
define void @sincos_f64(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'sincos_f64'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincos.f64(double %in_val)
+; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f64(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f64(ir<%in_val>)
+;
+; CHECK-COST-ARMPL-LABEL: 'sincos_f64'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincos.f64(double %in_val)
+; CHECK-COST-ARMPL: Cost of 12 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f64(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+;
; CHECK-LABEL: define void @sincos_f64(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0]] {
; CHECK: [[ENTRY:.*:]]
@@ -155,23 +160,25 @@ exit:
ret void
}
-; CHECK-COST-LABEL: predicated_sincos
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
-; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-
-; CHECK-COST-ARMPL-LABEL: predicated_sincos
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
-; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 12 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+
define void @predicated_sincos(float %x, ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'predicated_sincos'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
+; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+;
+; CHECK-COST-ARMPL-LABEL: 'predicated_sincos'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincos.f32(float %in_val)
+; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 12 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincos.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincos(ir<%in_val>)
+;
; CHECK-LABEL: define void @predicated_sincos(
; CHECK-SAME: float [[X:%.*]], ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0]] {
; CHECK: [[ENTRY:.*:]]
@@ -227,23 +234,25 @@ for.end:
ret void
}
-; CHECK-COST-LABEL: modf_f32
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.modf.f32(float %in_val)
-; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
-; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
-
-; CHECK-COST-ARMPL-LABEL: modf_f32
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.modf.f32(float %in_val)
-; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 11 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 12 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+
define void @modf_f32(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'modf_f32'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.modf.f32(float %in_val)
+; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
+;
+; CHECK-COST-ARMPL-LABEL: 'modf_f32'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.modf.f32(float %in_val)
+; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 11 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.modf.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 12 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+;
; CHECK-LABEL: define void @modf_f32(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0]] {
; CHECK: [[ENTRY:.*:]]
@@ -304,19 +313,21 @@ exit:
ret void
}
-; CHECK-COST-LABEL: modf_f64
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.modf.f64(double %in_val)
-; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f64(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.modf.f64(ir<%in_val>)
-; CHECK-COST-ARMPL-LABEL: modf_f64
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.modf.f64(double %in_val)
-; CHECK-COST-ARMPL: Cost of 11 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f64(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 12 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
define void @modf_f64(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'modf_f64'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.modf.f64(double %in_val)
+; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f64(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.modf.f64(ir<%in_val>)
+;
+; CHECK-COST-ARMPL-LABEL: 'modf_f64'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.modf.f64(double %in_val)
+; CHECK-COST-ARMPL: Cost of 11 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.modf.f64(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 12 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.modf(ir<%in_val>)
+;
; CHECK-LABEL: define void @modf_f64(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0]] {
; CHECK: [[ENTRY:.*:]]
@@ -377,23 +388,25 @@ exit:
ret void
}
-; CHECK-COST-LABEL: sincospi_f32
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincospi.f32(float %in_val)
-; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
-; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
-
-; CHECK-COST-ARMPL-LABEL: sincospi_f32
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincospi.f32(float %in_val)
-; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 12 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+
define void @sincospi_f32(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'sincospi_f32'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincospi.f32(float %in_val)
+; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+; CHECK-COST: Cost of 58 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
+;
+; CHECK-COST-ARMPL-LABEL: 'sincospi_f32'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { float, float } @llvm.sincospi.f32(float %in_val)
+; CHECK-COST-ARMPL: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 12 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincospi.f32(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+;
; CHECK-LABEL: define void @sincospi_f32(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0]] {
; CHECK: [[ENTRY:.*:]]
@@ -454,19 +467,21 @@ exit:
ret void
}
-; CHECK-COST-LABEL: sincospi_f64
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincospi.f64(double %in_val)
-; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f64(ir<%in_val>)
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincospi.f64(ir<%in_val>)
-; CHECK-COST-ARMPL-LABEL: sincospi_f64
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincospi.f64(double %in_val)
-; CHECK-COST-ARMPL: Cost of 12 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f64(ir<%in_val>)
-; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
define void @sincospi_f64(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'sincospi_f64'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincospi.f64(double %in_val)
+; CHECK-COST: Cost of 26 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f64(ir<%in_val>)
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @llvm.sincospi.f64(ir<%in_val>)
+;
+; CHECK-COST-ARMPL-LABEL: 'sincospi_f64'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { double, double } @llvm.sincospi.f64(double %in_val)
+; CHECK-COST-ARMPL: Cost of 12 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sincospi.f64(ir<%in_val>)
+; CHECK-COST-ARMPL: Cost of 13 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sincospi(ir<%in_val>)
+;
; CHECK-LABEL: define void @sincospi_f64(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0]] {
; CHECK: [[ENTRY:.*:]]
@@ -527,27 +542,29 @@ exit:
ret void
}
-; CHECK-COST-LABEL: sadd_with_overflow_i32
-; CHECK-COST: LV: Found an estimated cost of 1 for VF 1 For instruction: %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
-; CHECK-COST: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 4 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 7 for VF 8: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 13 for VF 16: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sadd.with.overflow.i32(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 4 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 4 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-
-; CHECK-COST-ARMPL-LABEL: sadd_with_overflow_i32
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 1 for VF 1 For instruction: %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
-; CHECK-COST-ARMPL: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 4 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 7 for VF 8: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 13 for VF 16: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sadd.with.overflow.i32(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 4 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 4 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+
define void @sadd_with_overflow_i32(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
+; CHECK-COST-LABEL: 'sadd_with_overflow_i32'
+; CHECK-COST: LV: Found an estimated cost of 1 for VF 1 For instruction: %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
+; CHECK-COST: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST: Cost of 4 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST: Cost of 7 for VF 8: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST: Cost of 13 for VF 16: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sadd.with.overflow.i32(ir<%val_a>, ir<%val_b>)
+; CHECK-COST: Cost of 4 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST: Cost of 4 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+;
+; CHECK-COST-ARMPL-LABEL: 'sadd_with_overflow_i32'
+; CHECK-COST-ARMPL: LV: Found an estimated cost of 1 for VF 1 For instruction: %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
+; CHECK-COST-ARMPL: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST-ARMPL: Cost of 4 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST-ARMPL: Cost of 7 for VF 8: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST-ARMPL: Cost of 13 for VF 16: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sadd.with.overflow.i32(ir<%val_a>, ir<%val_b>)
+; CHECK-COST-ARMPL: Cost of 4 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+; CHECK-COST-ARMPL: Cost of 4 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
+;
; CHECK-LABEL: define void @sadd_with_overflow_i32(
; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) #[[ATTR0]] {
; CHECK: [[ENTRY:.*:]]
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/struct-return-cost.ll b/llvm/test/Transforms/LoopVectorize/AArch64/struct-return-cost.ll
index e2e69eb4ca147..c73ec63a1697d 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/struct-return-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/struct-return-cost.ll
@@ -1,29 +1,27 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|@)" --version 5
-; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize < %s -S -o - 2>%t | FileCheck %s
-; RUN: cat %t | FileCheck %s --check-prefix=CHECK-COST
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Found an estimated cost of .*%call = tail call \{ half, half \} @foo" --filter "Found an estimated cost of .*%extract_(a|b) = extractvalue \{ half, half \} %call, [01]" --filter "Cost of .*: WIDEN-CALL ir<%call> = call @foo" --filter "Cost of .*: REPLICATE ir<%call> = call @foo" --filter "Cost of .*: WIDEN ir<%extract_(a|b)> = extractvalue ir<%call>, ir<[01]>" --run-lines 1 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|@)" --run-lines 2 --version 5
+; RUN: opt -passes=loop-vectorize < %s -disable-output -debug-only=loop-vectorize 2>&1 | FileCheck %s --check-prefix=CHECK-COST
+; RUN: opt -passes=loop-vectorize < %s -S -o - | FileCheck %s --check-prefix=CHECK
; REQUIRES: asserts
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-gnu"
-; CHECK-COST-LABEL: struct_return_widen
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { half, half } @foo(half %in_val)
-; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_a = extractvalue { half, half } %call, 0
-; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_b = extractvalue { half, half } %call, 1
-;
-; CHECK-COST: Cost of 10 for VF 2: WIDEN-CALL ir<%call> = call @foo(ir<%in_val>) (using library function: fixed_vec_foo)
-; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of 58 for VF 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of 122 for VF 8: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-
define void @struct_return_widen(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'struct_return_widen'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { half, half } @foo(half %in_val) #1
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_a = extractvalue { half, half } %call, 0
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_b = extractvalue { half, half } %call, 1
+; CHECK-COST: Cost of 10 for VF 2: WIDEN-CALL ir<%call> = call @foo(ir<%in_val>) (using library function: fixed_vec_foo)
+; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of 58 for VF 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of 122 for VF 8: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+;
; CHECK-LABEL: define void @struct_return_widen(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) {
; CHECK: [[ENTRY:.*:]]
@@ -56,31 +54,28 @@ exit:
ret void
}
-; CHECK-COST-LABEL: struct_return_replicate
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { half, half } @foo(half %in_val)
-; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_a = extractvalue { half, half } %call, 0
-; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_b = extractvalue { half, half } %call, 1
-;
-; CHECK-COST: Cost of 26 for VF 2: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of 58 for VF 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of 122 for VF 8: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-
define void @struct_return_replicate(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
+; CHECK-COST-LABEL: 'struct_return_replicate'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { half, half } @foo(half %in_val) #1
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_a = extractvalue { half, half } %call, 0
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_b = extractvalue { half, half } %call, 1
+; CHECK-COST: Cost of 26 for VF 2: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of 58 for VF 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of 122 for VF 8: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+;
; CHECK-LABEL: define void @struct_return_replicate(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) {
; CHECK: [[ENTRY:.*:]]
; CHECK: [[VECTOR_PH:.*:]]
; CHECK: [[VECTOR_BODY:.*:]]
-; CHECK: [[TMP3:%.*]] = tail call { half, half } @foo(half [[TMP1:%.*]]) #[[ATTR2:[0-9]+]]
-; CHECK: [[TMP4:%.*]] = tail call { half, half } @foo(half [[TMP2:%.*]]) #[[ATTR2]]
+; CHECK: [[TMP2:%.*]] = tail call { half, half } @foo(half [[TMP1:%.*]]) #[[ATTR2:[0-9]+]]
+; CHECK: [[TMP4:%.*]] = tail call { half, half } @foo(half [[TMP3:%.*]]) #[[ATTR2]]
; CHECK: [[MIDDLE_BLOCK:.*:]]
; CHECK: [[EXIT:.*:]]
;
@@ -107,40 +102,33 @@ exit:
ret void
}
-; CHECK-COST-LABEL: struct_return_scalable
-; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { half, half } @foo(half %in_val)
-; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_a = extractvalue { half, half } %call, 0
-; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_b = extractvalue { half, half } %call, 1
-;
-; CHECK-COST: Cost of 26 for VF 2: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of 58 for VF 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of 122 for VF 8: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF vscale x 1: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF vscale x 1: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF vscale x 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF vscale x 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
-; CHECK-COST: Cost of 0 for VF vscale x 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF vscale x 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-;
-; CHECK-COST: Cost of 10 for VF vscale x 8: WIDEN-CALL ir<%call> = call @foo(ir<%in_val>, ir<true>) (using library function: scalable_vec_masked_foo)
-; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
-; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
-
define void @struct_return_scalable(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) #2 {
+; CHECK-COST-LABEL: 'struct_return_scalable'
+; CHECK-COST: LV: Found an estimated cost of 10 for VF 1 For instruction: %call = tail call { half, half } @foo(half %in_val) #1
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_a = extractvalue { half, half } %call, 0
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %extract_b = extractvalue { half, half } %call, 1
+; CHECK-COST: Cost of 26 for VF 2: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of 58 for VF 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of 122 for VF 8: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF vscale x 1: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF vscale x 1: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of Invalid for VF vscale x 2: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF vscale x 2: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF vscale x 2: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of Invalid for VF vscale x 4: REPLICATE ir<%call> = call @foo(ir<%in_val>)
+; CHECK-COST: Cost of 0 for VF vscale x 4: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF vscale x 4: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+; CHECK-COST: Cost of 10 for VF vscale x 8: WIDEN-CALL ir<%call> = call @foo(ir<%in_val>, ir<true>) (using library function: scalable_vec_masked_foo)
+; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN ir<%extract_a> = extractvalue ir<%call>, ir<0>
+; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN ir<%extract_b> = extractvalue ir<%call>, ir<1>
+;
; CHECK-LABEL: define void @struct_return_scalable(
; CHECK-SAME: ptr noalias [[IN:%.*]], ptr noalias writeonly [[OUT_A:%.*]], ptr noalias writeonly [[OUT_B:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK: [[VECTOR_PH1:.*:]]
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/type-shrinkage-zext-costs.ll b/llvm/test/Transforms/LoopVectorize/AArch64/type-shrinkage-zext-costs.ll
index b5c8c922a24d3..631e4672b225f 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/type-shrinkage-zext-costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/type-shrinkage-zext-costs.ll
@@ -1,22 +1,26 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "LV: Found an estimated cost of .* For instruction:\s+%conv = (z|s)ext i8 %0 to i32" --filter "Cost of .*: WIDEN-CAST ir<%conv> = (z|s)ext ir<%0> to i16" --run-lines 1 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2 --version 2
; REQUIRES: asserts
-; RUN: opt -S -passes=loop-vectorize -force-vector-interleave=1 \
-; RUN: -enable-epilogue-vectorization=false -debug-only=loop-vectorize 2>%t < %s | FileCheck %s
-; RUN: cat %t | FileCheck %s --check-prefix=CHECK-COST
+; RUN: opt < %s -passes=loop-vectorize -force-vector-interleave=1 \
+; RUN: -enable-epilogue-vectorization=false -disable-output -debug-only=loop-vectorize 2>&1 | FileCheck %s --check-prefix=CHECK-COST
+; RUN: opt < %s -S -passes=loop-vectorize -force-vector-interleave=1 \
+; RUN: -enable-epilogue-vectorization=false | FileCheck %s
target triple = "aarch64-unknown-linux-gnu"
define void @zext_i8_i16(ptr noalias nocapture readonly %p, ptr noalias nocapture %q, i32 %len) #0 {
-; CHECK-COST-LABEL: LV: Checking a loop in 'zext_i8_i16'
-; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %conv = zext i8 %0 to i32
-; CHECK-COST: Cost of 1 for VF 2: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF 4: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF 8: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
-; CHECK-COST: Cost of 2 for VF 16: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF vscale x 1: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF vscale x 2: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF vscale x 4: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
-; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST-LABEL: 'zext_i8_i16'
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %conv = zext i8 %0 to i32
+; CHECK-COST: Cost of 1 for VF 2: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF 4: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF 8: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 2 for VF 16: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF vscale x 1: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF vscale x 2: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF vscale x 4: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+; CHECK-COST: Cost of 2 for VF vscale x 16: WIDEN-CAST ir<%conv> = zext ir<%0> to i16
+;
; CHECK-LABEL: define void @zext_i8_i16
; CHECK-SAME: (ptr noalias readonly captures(none) [[P:%.*]], ptr noalias captures(none) [[Q:%.*]], i32 [[LEN:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -28,21 +32,21 @@ define void @zext_i8_i16(ptr noalias nocapture readonly %p, ptr noalias nocaptur
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], [[TMP4]]
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
-; CHECK-NEXT: [[TMP6:%.*]] = shl nuw i64 [[TMP3]], 4
-; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP5:%.*]] = shl nuw i64 [[TMP3]], 4
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], [[TMP5]]
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[INDEX]]
-; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[TMP7]], align 1
-; CHECK-NEXT: [[TMP8:%.*]] = zext <vscale x 16 x i8> [[WIDE_LOAD]] to <vscale x 16 x i16>
-; CHECK-NEXT: [[TMP9:%.*]] = add <vscale x 16 x i16> [[TMP8]], splat (i16 2)
-; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i16, ptr [[Q]], i64 [[INDEX]]
-; CHECK-NEXT: store <vscale x 16 x i16> [[TMP9]], ptr [[TMP10]], align 2
-; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP6]]
-; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[INDEX]]
+; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[TMP6]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = zext <vscale x 16 x i8> [[WIDE_LOAD]] to <vscale x 16 x i16>
+; CHECK-NEXT: [[TMP8:%.*]] = add <vscale x 16 x i16> [[TMP7]], splat (i16 2)
+; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i16, ptr [[Q]], i64 [[INDEX]]
+; CHECK-NEXT: store <vscale x 16 x i16> [[TMP8]], ptr [[TMP9]], align 2
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
+; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
@@ -52,8 +56,8 @@ define void @zext_i8_i16(ptr noalias nocapture readonly %p, ptr noalias nocaptur
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[INDVARS_IV]]
-; CHECK-NEXT: [[TMP12:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP12]] to i32
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP11]] to i32
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[CONV]], 2
; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[ADD]] to i16
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i16, ptr [[Q]], i64 [[INDVARS_IV]]
@@ -87,15 +91,18 @@ exit:
}
define void @sext_i8_i16(ptr noalias nocapture readonly %p, ptr noalias nocapture %q, i32 %len) #0 {
-; CHECK-COST-LABEL: LV: Checking a loop in 'sext_i8_i16'
-; CHECK-COST: Cost of 1 for VF 2: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF 4: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF 8: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
-; CHECK-COST: Cost of 2 for VF 16: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF vscale x 1: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF vscale x 2: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
-; CHECK-COST: Cost of 1 for VF vscale x 4: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
-; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST-LABEL: 'sext_i8_i16'
+; CHECK-COST: LV: Found an estimated cost of 0 for VF 1 For instruction: %conv = sext i8 %0 to i32
+; CHECK-COST: Cost of 1 for VF 2: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF 4: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF 8: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 2 for VF 16: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF vscale x 1: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF vscale x 2: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 1 for VF vscale x 4: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 0 for VF vscale x 8: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+; CHECK-COST: Cost of 2 for VF vscale x 16: WIDEN-CAST ir<%conv> = sext ir<%0> to i16
+;
; CHECK-LABEL: define void @sext_i8_i16
; CHECK-SAME: (ptr noalias readonly captures(none) [[P:%.*]], ptr noalias captures(none) [[Q:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
@@ -107,21 +114,21 @@ define void @sext_i8_i16(ptr noalias nocapture readonly %p, ptr noalias nocaptur
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], [[TMP4]]
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
-; CHECK-NEXT: [[TMP6:%.*]] = shl nuw i64 [[TMP3]], 4
-; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP5:%.*]] = shl nuw i64 [[TMP3]], 4
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], [[TMP5]]
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[INDEX]]
-; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[TMP7]], align 1
-; CHECK-NEXT: [[TMP8:%.*]] = sext <vscale x 16 x i8> [[WIDE_LOAD]] to <vscale x 16 x i16>
-; CHECK-NEXT: [[TMP9:%.*]] = add <vscale x 16 x i16> [[TMP8]], splat (i16 2)
-; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i16, ptr [[Q]], i64 [[INDEX]]
-; CHECK-NEXT: store <vscale x 16 x i16> [[TMP9]], ptr [[TMP10]], align 2
-; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP6]]
-; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[INDEX]]
+; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[TMP6]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = sext <vscale x 16 x i8> [[WIDE_LOAD]] to <vscale x 16 x i16>
+; CHECK-NEXT: [[TMP8:%.*]] = add <vscale x 16 x i16> [[TMP7]], splat (i16 2)
+; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i16, ptr [[Q]], i64 [[INDEX]]
+; CHECK-NEXT: store <vscale x 16 x i16> [[TMP8]], ptr [[TMP9]], align 2
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
+; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
@@ -131,8 +138,8 @@ define void @sext_i8_i16(ptr noalias nocapture readonly %p, ptr noalias nocaptur
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[INDVARS_IV]]
-; CHECK-NEXT: [[TMP12:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
-; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP12]] to i32
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP11]] to i32
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[CONV]], 2
; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[ADD]] to i16
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i16, ptr [[Q]], i64 [[INDVARS_IV]]
>From 6f6b962575f2f19c855d1b3e66fd15a333595a01 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 27 Jul 2026 17:56:00 -0700
Subject: [PATCH 09/21] More updates
---
.../AMDGPU/amdgpu-codegenprepare-idiv.ll | 315 +++++++++---------
.../LoopVectorize/ARM/mve-selectandorcost.ll | 16 +-
.../LoopVectorize/RISCV/stepvector-cost.ll | 16 +-
.../VPlan/AArch64/sve-tail-folding-forced.ll | 61 ++--
4 files changed, 208 insertions(+), 200 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll
index 70835df894d0e..99b16d43199a8 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll
@@ -1,4 +1,5 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 1 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --run-lines 2-3 --version 6
; RUN: opt -S -mtriple=amdgpu6.00-- -amdgpu-codegenprepare -amdgpu-bypass-slow-div=0 %s | FileCheck %s
; RUN: llc -mtriple=amdgpu6.00-- -amdgpu-bypass-slow-div=0 < %s | FileCheck -check-prefix=GFX6 %s
; RUN: llc -mtriple=amdgpu9.00-- -amdgpu-bypass-slow-div=0 < %s | FileCheck -check-prefix=GFX9 %s
@@ -9286,6 +9287,13 @@ define <2 x i64> @v_udiv_i64_exact(<2 x i64> %num) {
}
define i64 @udiv_i64_gt_smax(i8 %size) {
+; CHECK-LABEL: define i64 @udiv_i64_gt_smax(
+; CHECK-SAME: i8 [[SIZE:%.*]]) {
+; CHECK-NEXT: [[ESIZE:%.*]] = sext i8 [[SIZE]] to i64
+; CHECK-NEXT: [[MINUS:%.*]] = sub nuw nsw i64 -1, [[ESIZE]]
+; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[MINUS]], 10
+; CHECK-NEXT: ret i64 [[DIV]]
+;
; GFX6-LABEL: udiv_i64_gt_smax:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -9334,12 +9342,6 @@ define i64 @udiv_i64_gt_smax(i8 %size) {
; GFX9-NEXT: v_alignbit_b32 v0, v1, v0, 3
; GFX9-NEXT: v_lshrrev_b32_e32 v1, 3, v1
; GFX9-NEXT: s_setpc_b64 s[30:31]
-; CHECK-LABEL: define i64 @udiv_i64_gt_smax(
-; CHECK-SAME: i8 [[SIZE:%.*]]) {
-; CHECK-NEXT: [[ESIZE:%.*]] = sext i8 [[SIZE]] to i64
-; CHECK-NEXT: [[MINUS:%.*]] = sub nuw nsw i64 -1, [[ESIZE]]
-; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[MINUS]], 10
-; CHECK-NEXT: ret i64 [[DIV]]
%esize = sext i8 %size to i64
%minus = sub nuw nsw i64 -1, %esize
%div = udiv i64 %minus, 10
@@ -9347,6 +9349,24 @@ define i64 @udiv_i64_gt_smax(i8 %size) {
}
define i64 @udiv_i64_9divbits(i8 %size) {
+; CHECK-LABEL: define i64 @udiv_i64_9divbits(
+; CHECK-SAME: i8 [[SIZE:%.*]]) {
+; CHECK-NEXT: [[ZEXTEND:%.*]] = zext i8 [[SIZE]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[ZEXTEND]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = add i32 1, [[TMP1]]
+; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
+; CHECK-NEXT: [[TMP5:%.*]] = uitofp i32 [[TMP4]] to float
+; CHECK-NEXT: [[TMP6:%.*]] = call float @llvm.amdgcn.rcp.f32(float 1.000000e+01)
+; CHECK-NEXT: [[TMP10:%.*]] = bitcast float [[TMP5]] to i32
+; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP10]], 1
+; CHECK-NEXT: [[TMP9:%.*]] = bitcast i32 [[TMP12]] to float
+; CHECK-NEXT: [[TMP7:%.*]] = fmul float [[TMP9]], [[TMP6]]
+; CHECK-NEXT: [[TMP8:%.*]] = call float @llvm.trunc.f32(float [[TMP7]])
+; CHECK-NEXT: [[TMP11:%.*]] = fptoui float [[TMP8]] to i32
+; CHECK-NEXT: [[TMP17:%.*]] = zext i32 [[TMP11]] to i64
+; CHECK-NEXT: ret i64 [[TMP17]]
+;
; GFX6-LABEL: udiv_i64_9divbits:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -9374,23 +9394,6 @@ define i64 @udiv_i64_9divbits(i8 %size) {
; GFX9-NEXT: v_cvt_u32_f32_e32 v0, v0
; GFX9-NEXT: v_mov_b32_e32 v1, 0
; GFX9-NEXT: s_setpc_b64 s[30:31]
-; CHECK-LABEL: define i64 @udiv_i64_9divbits(
-; CHECK-SAME: i8 [[SIZE:%.*]]) {
-; CHECK-NEXT: [[ZEXTEND:%.*]] = zext i8 [[SIZE]] to i64
-; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[ZEXTEND]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = add i32 1, [[TMP1]]
-; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
-; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
-; CHECK-NEXT: [[TMP5:%.*]] = uitofp i32 [[TMP4]] to float
-; CHECK-NEXT: [[TMP6:%.*]] = call float @llvm.amdgcn.rcp.f32(float 1.000000e+01)
-; CHECK-NEXT: [[TMP10:%.*]] = bitcast float [[TMP5]] to i32
-; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP10]], 1
-; CHECK-NEXT: [[TMP9:%.*]] = bitcast i32 [[TMP12]] to float
-; CHECK-NEXT: [[TMP7:%.*]] = fmul float [[TMP9]], [[TMP6]]
-; CHECK-NEXT: [[TMP8:%.*]] = call float @llvm.trunc.f32(float [[TMP7]])
-; CHECK-NEXT: [[TMP11:%.*]] = fptoui float [[TMP8]] to i32
-; CHECK-NEXT: [[TMP17:%.*]] = zext i32 [[TMP11]] to i64
-; CHECK-NEXT: ret i64 [[TMP17]]
%zextend = zext i8 %size to i64
%num = add nuw nsw i64 1, %zextend
%div = udiv i64 %num, 10
@@ -9398,6 +9401,10 @@ define i64 @udiv_i64_9divbits(i8 %size) {
}
define <2 x i64> @srem_zero_zero() {
+; CHECK-LABEL: define <2 x i64> @srem_zero_zero() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: ret <2 x i64> poison
+;
; GFX6-LABEL: srem_zero_zero:
; GFX6: ; %bb.0: ; %entry
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -9407,9 +9414,6 @@ define <2 x i64> @srem_zero_zero() {
; GFX9: ; %bb.0: ; %entry
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: s_setpc_b64 s[30:31]
-; CHECK-LABEL: define <2 x i64> @srem_zero_zero() {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: ret <2 x i64> poison
entry:
%B = srem <2 x i64> zeroinitializer, zeroinitializer
ret <2 x i64> %B
@@ -9417,6 +9421,23 @@ entry:
; 23-bit sdiv, can use expandDivRemToFloatImpl
define amdgpu_kernel void @sdiv23(ptr addrspace(1) %out, i23 %x, i23 %y) {
+; CHECK-LABEL: define amdgpu_kernel void @sdiv23(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i23 [[X:%.*]], i23 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = sext i23 [[X]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = sext i23 [[Y]] to i32
+; CHECK-NEXT: [[TMP6:%.*]] = sitofp fast i32 [[TMP1]] to float
+; CHECK-NEXT: [[TMP7:%.*]] = sitofp fast i32 [[TMP2]] to float
+; CHECK-NEXT: [[TMP8:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP7]])
+; CHECK-NEXT: [[TMP11:%.*]] = bitcast float [[TMP6]] to i32
+; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP11]], 1
+; CHECK-NEXT: [[TMP14:%.*]] = bitcast i32 [[TMP12]] to float
+; CHECK-NEXT: [[TMP9:%.*]] = fmul fast float [[TMP14]], [[TMP8]]
+; CHECK-NEXT: [[TMP10:%.*]] = call fast float @llvm.trunc.f32(float [[TMP9]])
+; CHECK-NEXT: [[TMP13:%.*]] = fptosi float [[TMP10]] to i32
+; CHECK-NEXT: [[TMP19:%.*]] = trunc i32 [[TMP13]] to i23
+; CHECK-NEXT: store i23 [[TMP19]], ptr addrspace(1) [[OUT]], align 4
+; CHECK-NEXT: ret void
+;
; GFX6-LABEL: sdiv23:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9
@@ -9456,22 +9477,6 @@ define amdgpu_kernel void @sdiv23(ptr addrspace(1) %out, i23 %x, i23 %y) {
; GFX9-NEXT: v_and_b32_e32 v0, 0x7fffff, v0
; GFX9-NEXT: global_store_byte_d16_hi v1, v0, s[0:1] offset:2
; GFX9-NEXT: s_endpgm
-; CHECK-LABEL: define amdgpu_kernel void @sdiv23(
-; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i23 [[X:%.*]], i23 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = sext i23 [[X]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = sext i23 [[Y]] to i32
-; CHECK-NEXT: [[TMP6:%.*]] = sitofp fast i32 [[TMP1]] to float
-; CHECK-NEXT: [[TMP7:%.*]] = sitofp fast i32 [[TMP2]] to float
-; CHECK-NEXT: [[TMP8:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP7]])
-; CHECK-NEXT: [[TMP11:%.*]] = bitcast float [[TMP6]] to i32
-; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP11]], 1
-; CHECK-NEXT: [[TMP14:%.*]] = bitcast i32 [[TMP12]] to float
-; CHECK-NEXT: [[TMP9:%.*]] = fmul fast float [[TMP14]], [[TMP8]]
-; CHECK-NEXT: [[TMP10:%.*]] = call fast float @llvm.trunc.f32(float [[TMP9]])
-; CHECK-NEXT: [[TMP13:%.*]] = fptosi float [[TMP10]] to i32
-; CHECK-NEXT: [[TMP19:%.*]] = trunc i32 [[TMP13]] to i23
-; CHECK-NEXT: store i23 [[TMP19]], ptr addrspace(1) [[OUT]], align 4
-; CHECK-NEXT: ret void
%r = sdiv i23 %x, %y
store i23 %r, ptr addrspace(1) %out
ret void
@@ -9479,6 +9484,52 @@ define amdgpu_kernel void @sdiv23(ptr addrspace(1) %out, i23 %x, i23 %y) {
; 24-bit sdiv, cannot use expandDivRemToFloatImpl
define amdgpu_kernel void @sdiv24(ptr addrspace(1) %out, i24 %x, i24 %y) {
+; CHECK-LABEL: define amdgpu_kernel void @sdiv24(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i24 [[X:%.*]], i24 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = sext i24 [[X]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = sext i24 [[Y]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = ashr i32 [[TMP1]], 31
+; CHECK-NEXT: [[TMP4:%.*]] = ashr i32 [[TMP2]], 31
+; CHECK-NEXT: [[TMP5:%.*]] = xor i32 [[TMP3]], [[TMP4]]
+; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP2]], [[TMP4]]
+; CHECK-NEXT: [[TMP8:%.*]] = xor i32 [[TMP6]], [[TMP3]]
+; CHECK-NEXT: [[TMP9:%.*]] = xor i32 [[TMP7]], [[TMP4]]
+; CHECK-NEXT: [[TMP10:%.*]] = uitofp fast i32 [[TMP9]] to float
+; CHECK-NEXT: [[TMP11:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP10]])
+; CHECK-NEXT: [[TMP12:%.*]] = fmul fast float [[TMP11]], f0x4F7FFFFE
+; CHECK-NEXT: [[TMP13:%.*]] = fptoui float [[TMP12]] to i32
+; CHECK-NEXT: [[TMP14:%.*]] = sub i32 0, [[TMP9]]
+; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[TMP14]], [[TMP13]]
+; CHECK-NEXT: [[TMP16:%.*]] = zext i32 [[TMP13]] to i64
+; CHECK-NEXT: [[TMP17:%.*]] = zext i32 [[TMP15]] to i64
+; CHECK-NEXT: [[TMP18:%.*]] = mul i64 [[TMP16]], [[TMP17]]
+; CHECK-NEXT: [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
+; CHECK-NEXT: [[TMP20:%.*]] = lshr i64 [[TMP18]], 32
+; CHECK-NEXT: [[TMP21:%.*]] = trunc i64 [[TMP20]] to i32
+; CHECK-NEXT: [[TMP22:%.*]] = add i32 [[TMP13]], [[TMP21]]
+; CHECK-NEXT: [[TMP23:%.*]] = zext i32 [[TMP8]] to i64
+; CHECK-NEXT: [[TMP24:%.*]] = zext i32 [[TMP22]] to i64
+; CHECK-NEXT: [[TMP25:%.*]] = mul i64 [[TMP23]], [[TMP24]]
+; CHECK-NEXT: [[TMP26:%.*]] = trunc i64 [[TMP25]] to i32
+; CHECK-NEXT: [[TMP27:%.*]] = lshr i64 [[TMP25]], 32
+; CHECK-NEXT: [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
+; CHECK-NEXT: [[TMP29:%.*]] = mul i32 [[TMP28]], [[TMP9]]
+; CHECK-NEXT: [[TMP30:%.*]] = sub i32 [[TMP8]], [[TMP29]]
+; CHECK-NEXT: [[TMP31:%.*]] = icmp uge i32 [[TMP30]], [[TMP9]]
+; CHECK-NEXT: [[TMP32:%.*]] = add i32 [[TMP28]], 1
+; CHECK-NEXT: [[TMP33:%.*]] = select i1 [[TMP31]], i32 [[TMP32]], i32 [[TMP28]]
+; CHECK-NEXT: [[TMP34:%.*]] = sub i32 [[TMP30]], [[TMP9]]
+; CHECK-NEXT: [[TMP35:%.*]] = select i1 [[TMP31]], i32 [[TMP34]], i32 [[TMP30]]
+; CHECK-NEXT: [[TMP36:%.*]] = icmp uge i32 [[TMP35]], [[TMP9]]
+; CHECK-NEXT: [[TMP37:%.*]] = add i32 [[TMP33]], 1
+; CHECK-NEXT: [[TMP38:%.*]] = select i1 [[TMP36]], i32 [[TMP37]], i32 [[TMP33]]
+; CHECK-NEXT: [[TMP39:%.*]] = xor i32 [[TMP38]], [[TMP5]]
+; CHECK-NEXT: [[TMP40:%.*]] = sub i32 [[TMP39]], [[TMP5]]
+; CHECK-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP40]] to i24
+; CHECK-NEXT: store i24 [[TMP41]], ptr addrspace(1) [[OUT]], align 4
+; CHECK-NEXT: ret void
+;
; GFX6-LABEL: sdiv24:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9
@@ -9558,51 +9609,6 @@ define amdgpu_kernel void @sdiv24(ptr addrspace(1) %out, i24 %x, i24 %y) {
; GFX9-NEXT: global_store_byte_d16_hi v1, v0, s[0:1] offset:2
; GFX9-NEXT: global_store_short v1, v0, s[0:1]
; GFX9-NEXT: s_endpgm
-; CHECK-LABEL: define amdgpu_kernel void @sdiv24(
-; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i24 [[X:%.*]], i24 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = sext i24 [[X]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = sext i24 [[Y]] to i32
-; CHECK-NEXT: [[TMP3:%.*]] = ashr i32 [[TMP1]], 31
-; CHECK-NEXT: [[TMP4:%.*]] = ashr i32 [[TMP2]], 31
-; CHECK-NEXT: [[TMP5:%.*]] = xor i32 [[TMP3]], [[TMP4]]
-; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP1]], [[TMP3]]
-; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP2]], [[TMP4]]
-; CHECK-NEXT: [[TMP8:%.*]] = xor i32 [[TMP6]], [[TMP3]]
-; CHECK-NEXT: [[TMP9:%.*]] = xor i32 [[TMP7]], [[TMP4]]
-; CHECK-NEXT: [[TMP10:%.*]] = uitofp fast i32 [[TMP9]] to float
-; CHECK-NEXT: [[TMP11:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP10]])
-; CHECK-NEXT: [[TMP12:%.*]] = fmul fast float [[TMP11]], f0x4F7FFFFE
-; CHECK-NEXT: [[TMP13:%.*]] = fptoui float [[TMP12]] to i32
-; CHECK-NEXT: [[TMP14:%.*]] = sub i32 0, [[TMP9]]
-; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[TMP14]], [[TMP13]]
-; CHECK-NEXT: [[TMP16:%.*]] = zext i32 [[TMP13]] to i64
-; CHECK-NEXT: [[TMP17:%.*]] = zext i32 [[TMP15]] to i64
-; CHECK-NEXT: [[TMP18:%.*]] = mul i64 [[TMP16]], [[TMP17]]
-; CHECK-NEXT: [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
-; CHECK-NEXT: [[TMP20:%.*]] = lshr i64 [[TMP18]], 32
-; CHECK-NEXT: [[TMP21:%.*]] = trunc i64 [[TMP20]] to i32
-; CHECK-NEXT: [[TMP22:%.*]] = add i32 [[TMP13]], [[TMP21]]
-; CHECK-NEXT: [[TMP23:%.*]] = zext i32 [[TMP8]] to i64
-; CHECK-NEXT: [[TMP24:%.*]] = zext i32 [[TMP22]] to i64
-; CHECK-NEXT: [[TMP25:%.*]] = mul i64 [[TMP23]], [[TMP24]]
-; CHECK-NEXT: [[TMP26:%.*]] = trunc i64 [[TMP25]] to i32
-; CHECK-NEXT: [[TMP27:%.*]] = lshr i64 [[TMP25]], 32
-; CHECK-NEXT: [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
-; CHECK-NEXT: [[TMP29:%.*]] = mul i32 [[TMP28]], [[TMP9]]
-; CHECK-NEXT: [[TMP30:%.*]] = sub i32 [[TMP8]], [[TMP29]]
-; CHECK-NEXT: [[TMP31:%.*]] = icmp uge i32 [[TMP30]], [[TMP9]]
-; CHECK-NEXT: [[TMP32:%.*]] = add i32 [[TMP28]], 1
-; CHECK-NEXT: [[TMP33:%.*]] = select i1 [[TMP31]], i32 [[TMP32]], i32 [[TMP28]]
-; CHECK-NEXT: [[TMP34:%.*]] = sub i32 [[TMP30]], [[TMP9]]
-; CHECK-NEXT: [[TMP35:%.*]] = select i1 [[TMP31]], i32 [[TMP34]], i32 [[TMP30]]
-; CHECK-NEXT: [[TMP36:%.*]] = icmp uge i32 [[TMP35]], [[TMP9]]
-; CHECK-NEXT: [[TMP37:%.*]] = add i32 [[TMP33]], 1
-; CHECK-NEXT: [[TMP38:%.*]] = select i1 [[TMP36]], i32 [[TMP37]], i32 [[TMP33]]
-; CHECK-NEXT: [[TMP39:%.*]] = xor i32 [[TMP38]], [[TMP5]]
-; CHECK-NEXT: [[TMP40:%.*]] = sub i32 [[TMP39]], [[TMP5]]
-; CHECK-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP40]] to i24
-; CHECK-NEXT: store i24 [[TMP41]], ptr addrspace(1) [[OUT]], align 4
-; CHECK-NEXT: ret void
%r = sdiv i24 %x, %y
store i24 %r, ptr addrspace(1) %out
ret void
@@ -9610,6 +9616,23 @@ define amdgpu_kernel void @sdiv24(ptr addrspace(1) %out, i24 %x, i24 %y) {
; 22-bit udiv, can use expandDivRemToFloatImpl
define amdgpu_kernel void @udiv22(ptr addrspace(1) %out, i22 %x, i22 %y) {
+; CHECK-LABEL: define amdgpu_kernel void @udiv22(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i22 [[X:%.*]], i22 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = zext i22 [[X]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = zext i22 [[Y]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = uitofp fast i32 [[TMP1]] to float
+; CHECK-NEXT: [[TMP4:%.*]] = uitofp fast i32 [[TMP2]] to float
+; CHECK-NEXT: [[TMP5:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP4]])
+; CHECK-NEXT: [[TMP9:%.*]] = bitcast float [[TMP3]] to i32
+; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP9]], 1
+; CHECK-NEXT: [[TMP8:%.*]] = bitcast i32 [[TMP11]] to float
+; CHECK-NEXT: [[TMP6:%.*]] = fmul fast float [[TMP8]], [[TMP5]]
+; CHECK-NEXT: [[TMP7:%.*]] = call fast float @llvm.trunc.f32(float [[TMP6]])
+; CHECK-NEXT: [[TMP10:%.*]] = fptoui float [[TMP7]] to i32
+; CHECK-NEXT: [[TMP16:%.*]] = trunc i32 [[TMP10]] to i22
+; CHECK-NEXT: store i22 [[TMP16]], ptr addrspace(1) [[OUT]], align 4
+; CHECK-NEXT: ret void
+;
; GFX6-LABEL: udiv22:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9
@@ -9649,22 +9672,6 @@ define amdgpu_kernel void @udiv22(ptr addrspace(1) %out, i22 %x, i22 %y) {
; GFX9-NEXT: v_and_b32_e32 v0, 0x3fffff, v0
; GFX9-NEXT: global_store_byte_d16_hi v1, v0, s[0:1] offset:2
; GFX9-NEXT: s_endpgm
-; CHECK-LABEL: define amdgpu_kernel void @udiv22(
-; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i22 [[X:%.*]], i22 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = zext i22 [[X]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = zext i22 [[Y]] to i32
-; CHECK-NEXT: [[TMP3:%.*]] = uitofp fast i32 [[TMP1]] to float
-; CHECK-NEXT: [[TMP4:%.*]] = uitofp fast i32 [[TMP2]] to float
-; CHECK-NEXT: [[TMP5:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP4]])
-; CHECK-NEXT: [[TMP9:%.*]] = bitcast float [[TMP3]] to i32
-; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP9]], 1
-; CHECK-NEXT: [[TMP8:%.*]] = bitcast i32 [[TMP11]] to float
-; CHECK-NEXT: [[TMP6:%.*]] = fmul fast float [[TMP8]], [[TMP5]]
-; CHECK-NEXT: [[TMP7:%.*]] = call fast float @llvm.trunc.f32(float [[TMP6]])
-; CHECK-NEXT: [[TMP10:%.*]] = fptoui float [[TMP7]] to i32
-; CHECK-NEXT: [[TMP16:%.*]] = trunc i32 [[TMP10]] to i22
-; CHECK-NEXT: store i22 [[TMP16]], ptr addrspace(1) [[OUT]], align 4
-; CHECK-NEXT: ret void
%r = udiv i22 %x, %y
store i22 %r, ptr addrspace(1) %out
ret void
@@ -9672,6 +9679,43 @@ define amdgpu_kernel void @udiv22(ptr addrspace(1) %out, i22 %x, i22 %y) {
; 23-bit udiv, cannot use expandDivRemToFloatImpl
define amdgpu_kernel void @udiv23(ptr addrspace(1) %out, i23 %x, i23 %y) {
+; CHECK-LABEL: define amdgpu_kernel void @udiv23(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i23 [[X:%.*]], i23 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = zext i23 [[X]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = zext i23 [[Y]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = uitofp fast i32 [[TMP2]] to float
+; CHECK-NEXT: [[TMP4:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP3]])
+; CHECK-NEXT: [[TMP5:%.*]] = fmul fast float [[TMP4]], f0x4F7FFFFE
+; CHECK-NEXT: [[TMP6:%.*]] = fptoui float [[TMP5]] to i32
+; CHECK-NEXT: [[TMP7:%.*]] = sub i32 0, [[TMP2]]
+; CHECK-NEXT: [[TMP8:%.*]] = mul i32 [[TMP7]], [[TMP6]]
+; CHECK-NEXT: [[TMP9:%.*]] = zext i32 [[TMP6]] to i64
+; CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[TMP8]] to i64
+; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]
+; CHECK-NEXT: [[TMP12:%.*]] = trunc i64 [[TMP11]] to i32
+; CHECK-NEXT: [[TMP13:%.*]] = lshr i64 [[TMP11]], 32
+; CHECK-NEXT: [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32
+; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[TMP6]], [[TMP14]]
+; CHECK-NEXT: [[TMP16:%.*]] = zext i32 [[TMP1]] to i64
+; CHECK-NEXT: [[TMP17:%.*]] = zext i32 [[TMP15]] to i64
+; CHECK-NEXT: [[TMP18:%.*]] = mul i64 [[TMP16]], [[TMP17]]
+; CHECK-NEXT: [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
+; CHECK-NEXT: [[TMP20:%.*]] = lshr i64 [[TMP18]], 32
+; CHECK-NEXT: [[TMP21:%.*]] = trunc i64 [[TMP20]] to i32
+; CHECK-NEXT: [[TMP22:%.*]] = mul i32 [[TMP21]], [[TMP2]]
+; CHECK-NEXT: [[TMP23:%.*]] = sub i32 [[TMP1]], [[TMP22]]
+; CHECK-NEXT: [[TMP24:%.*]] = icmp uge i32 [[TMP23]], [[TMP2]]
+; CHECK-NEXT: [[TMP25:%.*]] = add i32 [[TMP21]], 1
+; CHECK-NEXT: [[TMP26:%.*]] = select i1 [[TMP24]], i32 [[TMP25]], i32 [[TMP21]]
+; CHECK-NEXT: [[TMP27:%.*]] = sub i32 [[TMP23]], [[TMP2]]
+; CHECK-NEXT: [[TMP28:%.*]] = select i1 [[TMP24]], i32 [[TMP27]], i32 [[TMP23]]
+; CHECK-NEXT: [[TMP29:%.*]] = icmp uge i32 [[TMP28]], [[TMP2]]
+; CHECK-NEXT: [[TMP30:%.*]] = add i32 [[TMP26]], 1
+; CHECK-NEXT: [[TMP31:%.*]] = select i1 [[TMP29]], i32 [[TMP30]], i32 [[TMP26]]
+; CHECK-NEXT: [[TMP32:%.*]] = trunc i32 [[TMP31]] to i23
+; CHECK-NEXT: store i23 [[TMP32]], ptr addrspace(1) [[OUT]], align 4
+; CHECK-NEXT: ret void
+;
; GFX6-LABEL: udiv23:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9
@@ -9741,10 +9785,17 @@ define amdgpu_kernel void @udiv23(ptr addrspace(1) %out, i23 %x, i23 %y) {
; GFX9-NEXT: v_mov_b32_e32 v0, s2
; GFX9-NEXT: global_store_byte_d16_hi v1, v0, s[0:1] offset:2
; GFX9-NEXT: s_endpgm
-; CHECK-LABEL: define amdgpu_kernel void @udiv23(
-; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i23 [[X:%.*]], i23 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = zext i23 [[X]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = zext i23 [[Y]] to i32
+ %r = udiv i23 %x, %y
+ store i23 %r, ptr addrspace(1) %out
+ ret void
+}
+
+; 24-bit udiv, cannot use expandDivRemToFloatImpl
+define amdgpu_kernel void @udiv24(ptr addrspace(1) %out, i24 %x, i24 %y) {
+; CHECK-LABEL: define amdgpu_kernel void @udiv24(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i24 [[X:%.*]], i24 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = zext i24 [[X]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = zext i24 [[Y]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = uitofp fast i32 [[TMP2]] to float
; CHECK-NEXT: [[TMP4:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP3]])
; CHECK-NEXT: [[TMP5:%.*]] = fmul fast float [[TMP4]], f0x4F7FFFFE
@@ -9774,16 +9825,10 @@ define amdgpu_kernel void @udiv23(ptr addrspace(1) %out, i23 %x, i23 %y) {
; CHECK-NEXT: [[TMP29:%.*]] = icmp uge i32 [[TMP28]], [[TMP2]]
; CHECK-NEXT: [[TMP30:%.*]] = add i32 [[TMP26]], 1
; CHECK-NEXT: [[TMP31:%.*]] = select i1 [[TMP29]], i32 [[TMP30]], i32 [[TMP26]]
-; CHECK-NEXT: [[TMP32:%.*]] = trunc i32 [[TMP31]] to i23
-; CHECK-NEXT: store i23 [[TMP32]], ptr addrspace(1) [[OUT]], align 4
+; CHECK-NEXT: [[TMP32:%.*]] = trunc i32 [[TMP31]] to i24
+; CHECK-NEXT: store i24 [[TMP32]], ptr addrspace(1) [[OUT]], align 4
; CHECK-NEXT: ret void
- %r = udiv i23 %x, %y
- store i23 %r, ptr addrspace(1) %out
- ret void
-}
-
-; 24-bit udiv, cannot use expandDivRemToFloatImpl
-define amdgpu_kernel void @udiv24(ptr addrspace(1) %out, i24 %x, i24 %y) {
+;
; GFX6-LABEL: udiv24:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9
@@ -9851,42 +9896,6 @@ define amdgpu_kernel void @udiv24(ptr addrspace(1) %out, i24 %x, i24 %y) {
; GFX9-NEXT: global_store_byte_d16_hi v1, v0, s[0:1] offset:2
; GFX9-NEXT: global_store_short v1, v0, s[0:1]
; GFX9-NEXT: s_endpgm
-; CHECK-LABEL: define amdgpu_kernel void @udiv24(
-; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i24 [[X:%.*]], i24 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = zext i24 [[X]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = zext i24 [[Y]] to i32
-; CHECK-NEXT: [[TMP3:%.*]] = uitofp fast i32 [[TMP2]] to float
-; CHECK-NEXT: [[TMP4:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP3]])
-; CHECK-NEXT: [[TMP5:%.*]] = fmul fast float [[TMP4]], f0x4F7FFFFE
-; CHECK-NEXT: [[TMP6:%.*]] = fptoui float [[TMP5]] to i32
-; CHECK-NEXT: [[TMP7:%.*]] = sub i32 0, [[TMP2]]
-; CHECK-NEXT: [[TMP8:%.*]] = mul i32 [[TMP7]], [[TMP6]]
-; CHECK-NEXT: [[TMP9:%.*]] = zext i32 [[TMP6]] to i64
-; CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[TMP8]] to i64
-; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]
-; CHECK-NEXT: [[TMP12:%.*]] = trunc i64 [[TMP11]] to i32
-; CHECK-NEXT: [[TMP13:%.*]] = lshr i64 [[TMP11]], 32
-; CHECK-NEXT: [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32
-; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[TMP6]], [[TMP14]]
-; CHECK-NEXT: [[TMP16:%.*]] = zext i32 [[TMP1]] to i64
-; CHECK-NEXT: [[TMP17:%.*]] = zext i32 [[TMP15]] to i64
-; CHECK-NEXT: [[TMP18:%.*]] = mul i64 [[TMP16]], [[TMP17]]
-; CHECK-NEXT: [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
-; CHECK-NEXT: [[TMP20:%.*]] = lshr i64 [[TMP18]], 32
-; CHECK-NEXT: [[TMP21:%.*]] = trunc i64 [[TMP20]] to i32
-; CHECK-NEXT: [[TMP22:%.*]] = mul i32 [[TMP21]], [[TMP2]]
-; CHECK-NEXT: [[TMP23:%.*]] = sub i32 [[TMP1]], [[TMP22]]
-; CHECK-NEXT: [[TMP24:%.*]] = icmp uge i32 [[TMP23]], [[TMP2]]
-; CHECK-NEXT: [[TMP25:%.*]] = add i32 [[TMP21]], 1
-; CHECK-NEXT: [[TMP26:%.*]] = select i1 [[TMP24]], i32 [[TMP25]], i32 [[TMP21]]
-; CHECK-NEXT: [[TMP27:%.*]] = sub i32 [[TMP23]], [[TMP2]]
-; CHECK-NEXT: [[TMP28:%.*]] = select i1 [[TMP24]], i32 [[TMP27]], i32 [[TMP23]]
-; CHECK-NEXT: [[TMP29:%.*]] = icmp uge i32 [[TMP28]], [[TMP2]]
-; CHECK-NEXT: [[TMP30:%.*]] = add i32 [[TMP26]], 1
-; CHECK-NEXT: [[TMP31:%.*]] = select i1 [[TMP29]], i32 [[TMP30]], i32 [[TMP26]]
-; CHECK-NEXT: [[TMP32:%.*]] = trunc i32 [[TMP31]] to i24
-; CHECK-NEXT: store i24 [[TMP32]], ptr addrspace(1) [[OUT]], align 4
-; CHECK-NEXT: ret void
%r = udiv i24 %x, %y
store i24 %r, ptr addrspace(1) %out
ret void
diff --git a/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll b/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll
index 81df356c607df..2bc78a909d931 100644
--- a/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll
+++ b/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll
@@ -1,17 +1,19 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
-; RUN: opt -passes=loop-vectorize < %s -S -o - | FileCheck %s --check-prefix=CHECK
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "LV: Found an estimated cost of .* For instruction:\s+%or\.cond = select i1 %cmp2, i1 true, i1 %cmp3" --filter "Cost of .*: WIDEN ir<%or\.cond> = select ir<%cmp2>, ir<true>, ir<%cmp3>" --run-lines 1 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --run-lines 2 --version 6
; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize -disable-output < %s 2>&1 | FileCheck %s --check-prefix=CHECK-COST
+; RUN: opt -passes=loop-vectorize < %s -S -o - | FileCheck %s --check-prefix=CHECK
; REQUIRES: asserts
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv8.1m.main-arm-none-eabi"
-; CHECK-COST-LABEL: test
-; CHECK-COST: LV: Found an estimated cost of 1 for VF 1 For instruction: %or.cond = select i1 %cmp2, i1 true, i1 %cmp3
-; CHECK-COST: Cost of 26 for VF 2: WIDEN ir<%or.cond> = select ir<%cmp2>, ir<true>, ir<%cmp3>
-; CHECK-COST: Cost of 2 for VF 4: WIDEN ir<%or.cond> = select ir<%cmp2>, ir<true>, ir<%cmp3>
define float @test(ptr nocapture readonly %pA, ptr nocapture readonly %pB, i32 %blockSize) #0 {
+; CHECK-COST-LABEL: 'test'
+; CHECK-COST: LV: Found an estimated cost of 1 for VF 1 For instruction: %or.cond = select i1 %cmp2, i1 true, i1 %cmp3
+; CHECK-COST: Cost of 26 for VF 2: WIDEN ir<%or.cond> = select ir<%cmp2>, ir<true>, ir<%cmp3>
+; CHECK-COST: Cost of 2 for VF 4: WIDEN ir<%or.cond> = select ir<%cmp2>, ir<true>, ir<%cmp3>
+;
; CHECK-LABEL: define float @test(
; CHECK-SAME: ptr readonly captures(none) [[PA:%.*]], ptr readonly captures(none) [[PB:%.*]], i32 [[BLOCKSIZE:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
@@ -135,5 +137,3 @@ while.end:
attributes #0 = { "target-features"="+mve.fp" }
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-COST: {{.*}}
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/stepvector-cost.ll b/llvm/test/Transforms/LoopVectorize/RISCV/stepvector-cost.ll
index 1c6b88d549159..a437f19b2d1d9 100644
--- a/llvm/test/Transforms/LoopVectorize/RISCV/stepvector-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/stepvector-cost.ll
@@ -1,16 +1,18 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "LV: Checking a loop in 'pointer_induction_stepvector_cost'" --filter "Cost of .*: EMIT vp<.*> = step-vector i32" --run-lines 1 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2 --version 6
; REQUIRES: asserts
-; RUN: opt -mtriple riscv64 -mattr=+v -p loop-vectorize -debug-only=loop-vectorize -S < %s 2>%t | FileCheck %s
-; RUN: cat %t | FileCheck %s --check-prefix=COST
+; RUN: opt -mtriple riscv64 -mattr=+v -passes=loop-vectorize -debug-only=loop-vectorize -disable-output < %s 2>&1 | FileCheck %s --check-prefix=COST
+; RUN: opt -mtriple riscv64 -mattr=+v -passes=loop-vectorize -S < %s | FileCheck %s
-; COST: LV: Checking a loop in 'pointer_induction_stepvector_cost'
-; COST: Cost of 0 for VF vscale x 1: EMIT vp<%6> = step-vector i32
-; COST: Cost of 0 for VF vscale x 2: EMIT vp<%6> = step-vector i32
-; COST: Cost of 0 for VF vscale x 4: EMIT vp<%6> = step-vector i32
; NOTE: All costs are invalid despite each individual operation having a valid cost.
; TODO: VPlan shows the step-vector instruction is not hoisted out of the loop.
define void @pointer_induction_stepvector_cost(ptr %src.start, ptr %dst.start, ptr %src.end) {
+; COST-LABEL: 'pointer_induction_stepvector_cost'
+; COST: Cost of 0 for VF vscale x 1: EMIT vp<[[VP6:%[0-9]+]]> = step-vector i32
+; COST: Cost of 0 for VF vscale x 2: EMIT vp<[[VP6]]> = step-vector i32
+; COST: Cost of 0 for VF vscale x 4: EMIT vp<[[VP6]]> = step-vector i32
+;
; CHECK-LABEL: define void @pointer_induction_stepvector_cost(
; CHECK-SAME: ptr [[SRC_START:%.*]], ptr [[DST_START:%.*]], ptr [[SRC_END:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/sve-tail-folding-forced.ll b/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/sve-tail-folding-forced.ll
index c01da392c49ee..e17bba9d6574d 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/sve-tail-folding-forced.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/sve-tail-folding-forced.ll
@@ -1,45 +1,42 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter-out-after "^scalar.ph:"
-; RUN: opt -S -passes=loop-vectorize -debug-only=loop-vectorize < %s 2>%t | FileCheck %s
-; RUN: cat %t | FileCheck %s --check-prefix=VPLANS
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "middle.block:" --run-lines 1 --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter-out-after "^scalar.ph:" --run-lines 2
+; RUN: opt -passes=loop-vectorize -disable-output -vplan-print-after="printFinalVPlan$" < %s 2>&1 | FileCheck %s --check-prefix=VPLANS
+; RUN: opt -S -passes=loop-vectorize < %s | FileCheck %s
; These tests ensure that tail-folding is enabled when the predicate.enable
; loop attribute is set to true.
target triple = "aarch64-unknown-linux-gnu"
-; VPLANS-LABEL: Checking a loop in 'simple_memset'
-; VPLANS: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF>=1' {
-; VPLANS-NEXT: Live-in vp<[[VF:%.+]]> = VF
-; VPLANS-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
-; VPLANS: vp<[[TC:%[0-9]+]]> = original trip-count
+
+define void @simple_memset(i32 %val, ptr %ptr, i64 %n) #0 {
+; VPLANS-LABEL: VPlan for loop in 'simple_memset'
+; VPLANS: VPlan 'Final VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF={1}' {
; VPLANS-EMPTY:
-; VPLANS-NEXT: ir-bb<entry>:
-; VPLANS-NEXT: EMIT vp<[[TC]]> = EXPAND SCEV (1 umax %n)
-; VPLANS-NEXT: Successor(s): scalar.ph, vector.ph
+; VPLANS-NEXT: ir-bb<entry>:
+; VPLANS-NEXT: EMIT-SCALAR vp<[[VP2:%[0-9]+]]> = call i64 @llvm.umax(ir<%n>, ir<1>)
+; VPLANS-NEXT: Successor(s): vector.ph
; VPLANS-EMPTY:
-; VPLANS-NEXT: vector.ph:
-; VPLANS-NEXT: EMIT vp<[[VF_PER_PART:%.+]]> = VF * Part + ir<0>
-; VPLANS-NEXT: EMIT vp<[[LANEMASK_ENTRY:%.+]]> = active lane mask vp<[[VF_PER_PART]]>, vp<[[TC]]>
-; VPLANS-NEXT: Successor(s): vector loop
+; VPLANS-NEXT: vector.ph:
+; VPLANS-NEXT: EMIT-SCALAR vp<[[VP3:%[0-9]+]]> = call i64 @llvm.vscale()
+; VPLANS-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = shl nuw vp<[[VP3]]>, ir<2>
+; VPLANS-NEXT: EMIT vp<%active.lane.mask.entry> = active lane mask ir<0>, vp<[[VP2]]>, ir<1>
+; VPLANS-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = broadcast ir<%val>
+; VPLANS-NEXT: Successor(s): vector.body
; VPLANS-EMPTY:
-; VPLANS-NEXT: <x1> vector loop: {
-; VPLANS-NEXT: vp<[[INDV:%[0-9]+]]> = CANONICAL-IV
+; VPLANS-NEXT: vector.body:
+; VPLANS-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ]
+; VPLANS-NEXT: ACTIVE-LANE-MASK-PHI vp<[[VP6:%[0-9]+]]> = phi vp<%active.lane.mask.entry>, vp<%active.lane.mask.next>
+; VPLANS-NEXT: CLONE ir<%gep> = getelementptr ir<%ptr>, vp<%index>
+; VPLANS-NEXT: WIDEN store ir<%gep>, vp<[[VP5]]>, vp<[[VP6]]>
+; VPLANS-NEXT: EMIT vp<%index.next> = add vp<%index>, vp<[[VP4]]>
+; VPLANS-NEXT: EMIT vp<%active.lane.mask.next> = active lane mask vp<%index.next>, vp<[[VP2]]>, ir<1>
+; VPLANS-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = not vp<%active.lane.mask.next>
+; VPLANS-NEXT: EMIT branch-on-cond vp<[[VP7]]>
+; VPLANS-NEXT: Successor(s): middle.block, vector.body
; VPLANS-EMPTY:
-; VPLANS-NEXT: vector.body:
-; VPLANS-NEXT: ACTIVE-LANE-MASK-PHI vp<[[LANEMASK_PHI:%[0-9]+]]> = phi vp<[[LANEMASK_ENTRY]]>, vp<[[LANEMASK_LOOP:%.+]]>
-; VPLANS-NEXT: vp<[[STEP:%[0-9]+]]> = SCALAR-STEPS vp<[[INDV]]>, ir<1>, vp<[[VF]]>
-; VPLANS-NEXT: CLONE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEP]]>
-; VPLANS-NEXT: vp<[[VEC_PTR:%[0-9]+]]> = vector-pointer ir<%gep>
-; VPLANS-NEXT: WIDEN store vp<[[VEC_PTR]]>, ir<%val>, vp<[[LANEMASK_PHI]]>
-; VPLANS-NEXT: EMIT vp<[[INDV_UPDATE:%.+]]> = add vp<[[INDV]]>, vp<[[VFxUF]]>
-; VPLANS-NEXT: EMIT vp<[[INC:%[0-9]+]]> = VF * Part + vp<[[INDV_UPDATE]]>, vp<[[VF]]>
-; VPLANS-NEXT: EMIT vp<[[LANEMASK_LOOP]]> = active lane mask vp<[[INC]]>, vp<[[TC]]>
-; VPLANS-NEXT: EMIT vp<[[NOT:%[0-9]+]]> = not vp<[[LANEMASK_LOOP]]>
-; VPLANS-NEXT: EMIT branch-on-cond vp<[[NOT]]>
-; VPLANS-NEXT: No successors
-; VPLANS-NEXT: }
-
-define void @simple_memset(i32 %val, ptr %ptr, i64 %n) #0 {
+; VPLANS-NEXT: middle.block:
+;
; CHECK-LABEL: @simple_memset(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
>From 14999542891c8826dc47ff4297e126c0f162cd7b Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Wed, 29 Jul 2026 10:59:32 -0700
Subject: [PATCH 10/21] Cleanup vibe-coded patch
---
llvm/utils/UpdateTestChecks/common.py | 195 +++++++++++++----------
llvm/utils/update_analyze_test_checks.py | 4 +-
llvm/utils/update_any_test_checks.py | 10 +-
llvm/utils/update_test_checks.py | 4 +-
4 files changed, 115 insertions(+), 98 deletions(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 18dfecda38ed4..049191e138297 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -3,6 +3,7 @@
import collections
import copy
import glob
+import itertools
import os
import re
import subprocess
@@ -297,9 +298,11 @@ def __init__(
_prefix_filecheck_ir_name = args.prefix_filecheck_ir_name
self.argv = argv
self.input_lines = input_lines
+ # We need all RUN lines in the test, unfiltered by `--run-lines` to:
+ # - parse that option and ensure its arguments are in the range
+ # - sort CHECK blocks when updating the test
self.all_run_lines = find_run_lines(test, self.input_lines)
self.run_lines = find_run_lines(test, self.input_lines, args.run_lines)
- self.run_line_prefix_order = get_run_line_check_prefix_order(self.all_run_lines)
self.comment_prefix = comment_prefix
if self.comment_prefix is None:
if self.path.endswith(".mir") or self.path.endswith(".txt"):
@@ -308,77 +311,61 @@ def __init__(
self.comment_prefix = "//"
else:
self.comment_prefix = ";"
+ # This UTC invocation:
self.autogenerated_note_prefix = self.comment_prefix + " " + UTC_ADVERT
+ self.test_autogenerated_note = self.autogenerated_note_prefix + script_name
+ self.test_autogenerated_note += get_autogennote_suffix(parser, self.args)
self.current_script_name = script_name
- self.script_autogenerated_note_prefix = (
- self.autogenerated_note_prefix + self.current_script_name
+
+ # All autogenerated UTC lines for the test:
+ self.autogenerated_utc_header = list(
+ itertools.takewhile(lambda line: UTC_ADVERT in line, input_lines)
)
- self.test_autogenerated_note = self.script_autogenerated_note_prefix
- self.test_autogenerated_note += get_autogennote_suffix(parser, self.args)
- self.autogenerated_note_lines = []
- for input_line in self.input_lines:
- if not input_line.startswith(self.autogenerated_note_prefix):
- break
- self.autogenerated_note_lines.append(input_line)
+
self.test_unused_note = (
self.comment_prefix + self.comment_prefix + " " + UNUSED_NOTE
)
- def _parse_autogenerated_note(self, line):
- if not line.startswith(self.autogenerated_note_prefix):
- return (None, "")
- suffix = line[len(self.autogenerated_note_prefix) :]
- script_name, _, args_suffix = suffix.partition(" " + UTC_ARGS_KEY)
- args_suffix = args_suffix.strip()
- return (script_name, args_suffix)
-
- def _get_run_lines_filter_from_note_args(self, args_suffix):
- argv = shlex.split(args_suffix)
- for index, option in enumerate(argv):
- if option == "--run-lines" and index + 1 < len(argv):
- return argv[index + 1]
- if option.startswith("--run-lines="):
- return option.split("=", 1)[1]
- return None
-
- def _note_run_line_sort_key(self, line):
- script_name, args_suffix = self._parse_autogenerated_note(line)
- min_run_line = len(self.all_run_lines) + 1
- run_lines_filter = self._get_run_lines_filter_from_note_args(args_suffix)
- if run_lines_filter is not None:
- try:
- min_run_line = min(
- parse_run_lines(run_lines_filter, len(self.all_run_lines))
- )
- except ValueError:
- pass
- return (min_run_line, script_name or "", line)
-
def ro_iterlines(self):
- args = self.args
- argv = self.argv
for line_num, input_line in enumerate(self.input_lines):
- if not input_line.startswith(self.autogenerated_note_prefix):
- args, argv = check_for_command(
- input_line, self.parser, args, argv, self.argparse_callback
- )
+ args, argv = check_for_command(
+ input_line, self.parser, self.args, self.argv, self.argparse_callback
+ )
yield InputLineInfo(input_line, line_num, args, argv)
def iterlines(self, output_lines):
- note_lines = []
- saw_current_script = False
- for input_line in self.autogenerated_note_lines:
- script_name, _ = self._parse_autogenerated_note(input_line)
- if script_name == self.current_script_name:
- note_lines.append(self.test_autogenerated_note)
- saw_current_script = True
- else:
- note_lines.append(input_line)
- if not saw_current_script:
- note_lines.append(self.test_autogenerated_note)
- output_lines.extend(sorted(note_lines, key=self._note_run_line_sort_key))
+ run_lines_parser = argparse.ArgumentParser(add_help=False)
+ run_lines_parser.add_argument("--run-lines")
+
+ def utc_header_sorter(line):
+ """Sort UTC header lines based on the order of check-prefixes they update."""
+ suffix = line[len(self.autogenerated_note_prefix) :]
+ script_name, _, args_suffix = suffix.partition(" " + UTC_ARGS_KEY)
+ args_suffix = args_suffix.strip()
+ min_run_line = len(self.all_run_lines) + 1
+ run_lines_filter = run_lines_parser.parse_known_args(
+ shlex.split(args_suffix)
+ )[0].run_lines
+ if run_lines_filter is not None:
+ min_run_line = min(
+ parse_run_lines_argument(
+ run_lines_filter, len(self.all_run_lines)
+ )
+ )
+ return (min_run_line, script_name or "", line)
+
+ new_utc_header = [
+ line
+ for line in self.autogenerated_utc_header
+ if self.current_script_name not in line
+ ]
+ new_utc_header.append(self.test_autogenerated_note)
+ new_utc_header.sort(key=utc_header_sorter)
+ output_lines.extend(new_utc_header)
+
for line_info in self.ro_iterlines():
input_line = line_info.line
+ # Discard previous autogenerated UTC header.
if input_line.startswith(self.autogenerated_note_prefix):
continue
self.args = line_info.args
@@ -428,16 +415,15 @@ def itertests(
warn("Skipping test that must not be autogenerated: " + test)
continue
- autogenerated_lines = []
- for line in input_lines:
- if UTC_ADVERT not in line:
- break
- autogenerated_lines.append(line)
+ autogenerated_utc_header = list(
+ itertools.takewhile(lambda line: UTC_ADVERT in line, input_lines)
+ )
- regenerate_line = next(
- (line for line in autogenerated_lines if script_name in line), None
+ # Check if the header contains an entry for this `script_name`.
+ autogenerated_note = next(
+ (line for line in autogenerated_utc_header if script_name in line), None
)
- is_regenerate = regenerate_line is not None
+ is_regenerate = autogenerated_note is not None
# If we're generating a new test, set the default version to the latest.
argv = sys.argv[:]
@@ -449,7 +435,7 @@ def itertests(
argparse_callback(args)
if is_regenerate:
args, argv = check_for_command(
- regenerate_line, parser, args, argv, argparse_callback
+ autogenerated_note, parser, args, argv, argparse_callback
)
elif args.update_only:
warn(
@@ -729,7 +715,7 @@ def find_run_lines(test, lines, run_lines_filter=None):
else:
run_lines.append(l)
if run_lines_filter is not None:
- selected = parse_run_lines(run_lines_filter, len(run_lines))
+ selected = parse_run_lines_argument(run_lines_filter, len(run_lines))
run_lines = [
line for (index, line) in enumerate(run_lines, start=1) if index in selected
]
@@ -739,7 +725,26 @@ def find_run_lines(test, lines, run_lines_filter=None):
return run_lines
-def parse_run_lines(run_lines_filter, num_run_lines):
+def parse_run_lines_argument(run_lines_filter, num_run_lines):
+ """Parse a --run-lines filter into a set of selected 1-based RUN indices.
+
+ The filter is a comma-separated list of items, where each item is either a
+ single positive line number ``N`` or an inclusive range ``N-M``. All
+ selected indices must refer to existing RUN lines in the current test file,
+ so values are validated against ``num_run_lines``.
+
+ Args:
+ run_lines_filter: The raw ``--run-lines`` option value.
+ num_run_lines: Total number of RUN lines available in the test.
+
+ Returns:
+ A set of 1-based RUN line indices selected by the filter.
+
+ Raises:
+ ValueError: If the filter contains an empty item, an invalid range,
+ non-positive indices, a descending range, or an index past the end
+ of the available RUN lines.
+ """
selected = set()
for item in run_lines_filter.split(","):
item = item.strip()
@@ -2809,23 +2814,6 @@ def get_check_prefixes(filecheck_cmd):
return check_prefixes
-def get_run_line_check_prefix_order(run_lines):
- prefix_order = []
- seen = set()
- for run_line in run_lines:
- if "|" not in run_line:
- continue
- filecheck_cmd = run_line.rsplit("|", 1)[1].strip()
- if not filecheck_cmd.startswith("FileCheck "):
- continue
- for prefix in get_check_prefixes(filecheck_cmd):
- if prefix in seen:
- continue
- seen.add(prefix)
- prefix_order.append(prefix)
- return prefix_order
-
-
def verify_filecheck_prefixes(fc_cmd):
fc_cmd_parts = fc_cmd.split()
for part in fc_cmd_parts:
@@ -2970,7 +2958,33 @@ def dump_input_lines(output_lines, test_info, prefix_set, comment_string):
output_lines.append(line.rstrip("\n"))
-def reorder_function_start_check_blocks(lines, prefix_order, comment_string):
+def sort_check_blocks(lines, all_run_lines, comment_string):
+ """Reorder per-prefix check blocks at function starts to match RUN-line order.
+
+ For each IR function definition in ``lines``, inspect the immediately
+ following prologue of blank lines and comment lines. If that prologue
+ contains FileCheck directives, group those directives into per-prefix
+ blocks and reorder the blocks so their prefixes appear in the same
+ first-seen order as the ``FileCheck`` prefixes from ``all_run_lines``.
+ Non-check prologue lines are preserved, and functions without such check
+ blocks are left unchanged.
+ """
+ # Preserve the first-seen FileCheck prefix order implied by the full set of
+ # RUN lines, not just any selected subset being regenerated.
+ prefix_order = []
+ seen = set()
+ for run_line in all_run_lines:
+ if "|" not in run_line:
+ continue
+ filecheck_cmd = run_line.rsplit("|", 1)[1].strip()
+ if not filecheck_cmd.startswith("FileCheck "):
+ continue
+ for prefix in get_check_prefixes(filecheck_cmd):
+ if prefix in seen:
+ continue
+ seen.add(prefix)
+ prefix_order.append(prefix)
+
if not prefix_order:
return lines
@@ -2984,6 +2998,8 @@ def reorder_function_start_check_blocks(lines, prefix_order, comment_string):
if not IR_FUNCTION_RE.match(line):
continue
+ # Collect the contiguous function-start prologue made up of blank lines
+ # and comments, because this is where generated check blocks live.
prologue = []
while index < len(lines):
next_line = lines[index]
@@ -3002,6 +3018,9 @@ def reorder_function_start_check_blocks(lines, prefix_order, comment_string):
def flush_current_block():
nonlocal current_prefix, current_block
if current_prefix is not None:
+ # Keep internal spacing within a check block, but drop trailing
+ # separators so they can be reintroduced consistently after
+ # reordering.
while current_block and current_block[-1].strip() in (
"",
comment_string,
@@ -3013,6 +3032,8 @@ def flush_current_block():
current_prefix = None
current_block = []
+ # Split the prologue into reorderable per-prefix check blocks and all
+ # other lines, which keep their relative order.
for prologue_line in prologue:
match = CHECK_RE.match(prologue_line)
if match:
diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py
index c6bf52e50a273..94152d51163a9 100755
--- a/llvm/utils/update_analyze_test_checks.py
+++ b/llvm/utils/update_analyze_test_checks.py
@@ -187,9 +187,7 @@ def update_test(opt_basename: str, ti: common.TestInfo):
continue
is_in_function = is_in_function_start = True
- output_lines = common.reorder_function_start_check_blocks(
- output_lines, ti.run_line_prefix_order, ";"
- )
+ output_lines = common.sort_check_blocks(output_lines, ti.all_run_lines, ";")
if ti.args.gen_unused_prefix_body:
output_lines.extend(
ti.get_checks_for_unused_prefixes(prefix_list, generated_prefixes)
diff --git a/llvm/utils/update_any_test_checks.py b/llvm/utils/update_any_test_checks.py
index 1a663ad62630d..95c65776f5a1d 100755
--- a/llvm/utils/update_any_test_checks.py
+++ b/llvm/utils/update_any_test_checks.py
@@ -11,6 +11,7 @@
from __future__ import print_function
import argparse
+import itertools
import os
import re
import subprocess
@@ -24,11 +25,10 @@
def get_autogenerated_utc_names(lines):
utc_names = []
- for line in lines:
- m = RE_ASSERTIONS.search(line.strip())
- if m is None:
- break
- utc_name = m.group(1)
+ for line in itertools.takewhile(
+ lambda line: RE_ASSERTIONS.search(line.strip()) is not None, lines
+ ):
+ utc_name = RE_ASSERTIONS.search(line.strip()).group(1)
if utc_name not in utc_names:
utc_names.append(utc_name)
return utc_names
diff --git a/llvm/utils/update_test_checks.py b/llvm/utils/update_test_checks.py
index b2e1ab96d508c..c601f6ea669c1 100755
--- a/llvm/utils/update_test_checks.py
+++ b/llvm/utils/update_test_checks.py
@@ -311,9 +311,7 @@ def update_test(ti: common.TestInfo):
args.check_globals,
)
)
- output_lines = common.reorder_function_start_check_blocks(
- output_lines, ti.run_line_prefix_order, ";"
- )
+ output_lines = common.sort_check_blocks(output_lines, ti.all_run_lines, ";")
if ti.args.gen_unused_prefix_body:
output_lines.extend(
ti.get_checks_for_unused_prefixes(prefix_list, generated_prefixes)
>From a4ad0a7096025d9f31e200fc4cfef16212940ce7 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Wed, 29 Jul 2026 11:34:20 -0700
Subject: [PATCH 11/21] Fix formatting
---
llvm/utils/UpdateTestChecks/common.py | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 049191e138297..3b3fe3e20fa53 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -348,9 +348,7 @@ def utc_header_sorter(line):
)[0].run_lines
if run_lines_filter is not None:
min_run_line = min(
- parse_run_lines_argument(
- run_lines_filter, len(self.all_run_lines)
- )
+ parse_run_lines_argument(run_lines_filter, len(self.all_run_lines))
)
return (min_run_line, script_name or "", line)
@@ -766,9 +764,7 @@ def parse_run_lines_argument(run_lines_filter, num_run_lines):
raise ValueError("--run-lines entries must be positive: '{}'".format(item))
if start > end:
raise ValueError(
- "invalid --run-lines range '{}'; start must not exceed end".format(
- item
- )
+ "invalid --run-lines range '{}'; start must not exceed end".format(item)
)
if end > num_run_lines:
raise ValueError(
>From 9ef0b22b11dd5dbbcb5165c02438a65f41f44d9d Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Wed, 29 Jul 2026 14:36:37 -0700
Subject: [PATCH 12/21] Fix test after merge
---
.../multiple_utc/Inputs/run-lines.analyze-only.expected | 2 +-
.../multiple_utc/Inputs/run-lines.both.expected | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
index 9a519c4469b7a..ad6acb9a9c73d 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
@@ -24,7 +24,7 @@ define void @simple(ptr %p, i64 %n) {
; CHECK-NEXT: vector.body:
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
-; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer ir<%gep>, ir<1>
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
index 539baec1a3c47..b6c5ac59d8f4b 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
@@ -25,7 +25,7 @@ define void @simple(ptr %p, i64 %n) {
; CHECK-NEXT: vector.body:
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
-; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer ir<%gep>, ir<1>
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
>From 74d7ca163d983193607497654a6746b049c7eb2e Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 09:20:10 -0700
Subject: [PATCH 13/21] More cleanup, keeping blocks sorting as post-processing
---
.../Inputs/run-lines.with-both-notes.expected | 104 ++++++++++++++++++
.../Inputs/run-lines.with-both-notes.ll | 8 ++
.../multiple_utc/run-lines.test | 6 +-
llvm/utils/UpdateTestChecks/common.py | 17 ++-
4 files changed, 124 insertions(+), 11 deletions(-)
create mode 100644 llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected
new file mode 100644
index 0000000000000..d05b5fb51e365
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected
@@ -0,0 +1,104 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
+; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+
+define void @simple(ptr %p, i64 %n) {
+; Some comment
+; NOTE: This is not a check directive.
+; Another comment
+; And another non-CHECK: comment
+; CHECK-LABEL: VPlan for loop in 'simple'
+; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<entry>:
+; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
+; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: Successor(s): vector loop
+; CHECK-EMPTY:
+; CHECK-NEXT: <x1> vector loop: {
+; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.body:
+; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
+; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
+; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
+; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+; CHECK-NEXT: Successor(s): middle.block
+; CHECK-EMPTY:
+; CHECK-NEXT: middle.block:
+; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<exit>:
+; CHECK-NEXT: No successors
+; CHECK-EMPTY:
+; CHECK-NEXT: scalar.ph:
+; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK-NEXT: Successor(s): ir-bb<loop>
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<loop>:
+; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
+; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
+; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
+; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+;
+; LLVM-LABEL: @simple(
+; LLVM-NEXT: entry:
+; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; LLVM: vector.ph:
+; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
+; LLVM: vector.body:
+; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; LLVM: middle.block:
+; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; LLVM: scalar.ph:
+; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; LLVM-NEXT: br label [[LOOP:%.*]]
+; LLVM: loop:
+; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
+; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; LLVM: exit:
+; LLVM-NEXT: ret void
+;
+entry:
+ br label %loop
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep = getelementptr i32, ptr %p, i64 %iv
+ store i32 0, ptr %gep
+ %iv.next = add i64 %iv, 1
+ %cmp = icmp ult i64 %iv.next, %n
+ br i1 %cmp, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
index 370a1ae3b7bd1..1083dc813d3f7 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
@@ -5,6 +5,14 @@
; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
define void @simple(ptr %p, i64 %n) {
+; Some comment
+; CHECK-LABEL: @simple
+; CHECK-NEXT: something stale
+; NOTE: This is not a check directive.
+; Another comment
+; LLVM-LABEL: @simple
+; LLVM-NEXT: another stale
+; And another non-CHECK: comment
entry:
br label %loop
loop:
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
index 7a6121acd25d5..edfa435b8fb17 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
@@ -35,7 +35,9 @@
# RUN: %update_analyze_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
-## update_any_test_checks.py should dispatch to both scripts from the NOTE block.
+## update_any_test_checks.py dispatches to both scripts from the NOTE block.
# RUN: cp -f %S/Inputs/run-lines.with-both-notes.ll %t.ll
# RUN: %update_any_test_checks --path %llvm_tools_dir %t.ll
-# RUN: diff -u %t.ll %S/Inputs/run-lines.both.expected
+# RUN: diff -u %t.ll %S/Inputs/run-lines.with-both-notes.expected
+# RUN: %update_any_test_checks --path %llvm_tools_dir %t.ll
+# RUN: diff -u %t.ll %S/Inputs/run-lines.with-both-notes.expected
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 3b3fe3e20fa53..c3e6c2593502c 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -338,7 +338,7 @@ def iterlines(self, output_lines):
run_lines_parser.add_argument("--run-lines")
def utc_header_sorter(line):
- """Sort UTC header lines based on the order of check-prefixes they update."""
+ """Sort UTC header lines by RUN lines they handle."""
suffix = line[len(self.autogenerated_note_prefix) :]
script_name, _, args_suffix = suffix.partition(" " + UTC_ARGS_KEY)
args_suffix = args_suffix.strip()
@@ -355,6 +355,8 @@ def utc_header_sorter(line):
new_utc_header = [
line
for line in self.autogenerated_utc_header
+ # We might be updating UTC_ARGS, so ignore existing entry
+ # corresponding to the current invocation:
if self.current_script_name not in line
]
new_utc_header.append(self.test_autogenerated_note)
@@ -2962,20 +2964,17 @@ def sort_check_blocks(lines, all_run_lines, comment_string):
contains FileCheck directives, group those directives into per-prefix
blocks and reorder the blocks so their prefixes appear in the same
first-seen order as the ``FileCheck`` prefixes from ``all_run_lines``.
- Non-check prologue lines are preserved, and functions without such check
- blocks are left unchanged.
+ Non-check prologue lines are retained before the reordered check blocks,
+ and functions without such check blocks are left unchanged.
"""
# Preserve the first-seen FileCheck prefix order implied by the full set of
# RUN lines, not just any selected subset being regenerated.
prefix_order = []
seen = set()
for run_line in all_run_lines:
- if "|" not in run_line:
+ if "FileCheck" not in run_line:
continue
- filecheck_cmd = run_line.rsplit("|", 1)[1].strip()
- if not filecheck_cmd.startswith("FileCheck "):
- continue
- for prefix in get_check_prefixes(filecheck_cmd):
+ for prefix in get_check_prefixes(run_line):
if prefix in seen:
continue
seen.add(prefix)
@@ -3032,7 +3031,7 @@ def flush_current_block():
# other lines, which keep their relative order.
for prologue_line in prologue:
match = CHECK_RE.match(prologue_line)
- if match:
+ if match and match.group(1) in ordered_prefixes:
prefix = match.group(1)
if current_prefix != prefix:
flush_current_block()
>From c2a19dd60d5d0bbc42fe946239d25ce05d95394a Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 09:33:11 -0700
Subject: [PATCH 14/21] Swap/rename prefixes: CHECK/LLVM->VPLAN/CHECK, order of
RUN lines is unchanged
---
.../Inputs/run-lines.analyze-only.expected | 100 +++++------
.../Inputs/run-lines.both.expected | 162 +++++++++---------
.../multiple_utc/Inputs/run-lines.ll | 4 +-
.../Inputs/run-lines.llvm-only.expected | 66 +++----
.../Inputs/run-lines.with-both-notes.expected | 162 +++++++++---------
.../Inputs/run-lines.with-both-notes.ll | 12 +-
6 files changed, 253 insertions(+), 253 deletions(-)
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
index ad6acb9a9c73d..c1d7fdda6b32d 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.analyze-only.expected
@@ -1,57 +1,57 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
-; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
-; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s --check-prefix VPLAN
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
define void @simple(ptr %p, i64 %n) {
-; CHECK-LABEL: VPlan for loop in 'simple'
-; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
-; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
-; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
-; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
-; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<entry>:
-; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
-; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.ph:
-; CHECK-NEXT: Successor(s): vector loop
-; CHECK-EMPTY:
-; CHECK-NEXT: <x1> vector loop: {
-; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.body:
-; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
-; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
-; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
-; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
-; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
-; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
-; CHECK-NEXT: Successor(s): middle.block
-; CHECK-EMPTY:
-; CHECK-NEXT: middle.block:
-; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
-; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
-; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<exit>:
-; CHECK-NEXT: No successors
-; CHECK-EMPTY:
-; CHECK-NEXT: scalar.ph:
-; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK-NEXT: Successor(s): ir-bb<loop>
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<loop>:
-; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
-; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
-; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
-; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
-; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
+; VPLAN-LABEL: VPlan for loop in 'simple'
+; VPLAN: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; VPLAN-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; VPLAN-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; VPLAN-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; VPLAN-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<entry>:
+; VPLAN-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
+; VPLAN-NEXT: Successor(s): scalar.ph, vector.ph
+; VPLAN-EMPTY:
+; VPLAN-NEXT: vector.ph:
+; VPLAN-NEXT: Successor(s): vector loop
+; VPLAN-EMPTY:
+; VPLAN-NEXT: <x1> vector loop: {
+; VPLAN-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
+; VPLAN-EMPTY:
+; VPLAN-NEXT: vector.body:
+; VPLAN-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
+; VPLAN-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
+; VPLAN-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
+; VPLAN-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
+; VPLAN-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
+; VPLAN-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; VPLAN-NEXT: No successors
+; VPLAN-NEXT: }
+; VPLAN-NEXT: Successor(s): middle.block
+; VPLAN-EMPTY:
+; VPLAN-NEXT: middle.block:
+; VPLAN-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; VPLAN-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; VPLAN-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<exit>:
+; VPLAN-NEXT: No successors
+; VPLAN-EMPTY:
+; VPLAN-NEXT: scalar.ph:
+; VPLAN-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; VPLAN-NEXT: Successor(s): ir-bb<loop>
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<loop>:
+; VPLAN-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; VPLAN-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
+; VPLAN-NEXT: IR store i32 0, ptr %gep, align 4
+; VPLAN-NEXT: IR %iv.next = add i64 %iv, 1
+; VPLAN-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
+; VPLAN-NEXT: No successors
+; VPLAN-NEXT: }
;
entry:
br label %loop
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
index b6c5ac59d8f4b..e0d510917f0c3 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.both.expected
@@ -1,90 +1,90 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
-; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
-; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s --check-prefix VPLAN
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
define void @simple(ptr %p, i64 %n) {
-; CHECK-LABEL: VPlan for loop in 'simple'
-; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
-; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
-; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
-; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
-; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<entry>:
-; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
-; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.ph:
-; CHECK-NEXT: Successor(s): vector loop
-; CHECK-EMPTY:
-; CHECK-NEXT: <x1> vector loop: {
-; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.body:
-; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
-; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
-; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
-; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
-; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
-; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
-; CHECK-NEXT: Successor(s): middle.block
-; CHECK-EMPTY:
-; CHECK-NEXT: middle.block:
-; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
-; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
-; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<exit>:
-; CHECK-NEXT: No successors
-; CHECK-EMPTY:
-; CHECK-NEXT: scalar.ph:
-; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK-NEXT: Successor(s): ir-bb<loop>
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<loop>:
-; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
-; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
-; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
-; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
-; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
+; VPLAN-LABEL: VPlan for loop in 'simple'
+; VPLAN: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; VPLAN-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; VPLAN-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; VPLAN-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; VPLAN-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<entry>:
+; VPLAN-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
+; VPLAN-NEXT: Successor(s): scalar.ph, vector.ph
+; VPLAN-EMPTY:
+; VPLAN-NEXT: vector.ph:
+; VPLAN-NEXT: Successor(s): vector loop
+; VPLAN-EMPTY:
+; VPLAN-NEXT: <x1> vector loop: {
+; VPLAN-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
+; VPLAN-EMPTY:
+; VPLAN-NEXT: vector.body:
+; VPLAN-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
+; VPLAN-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
+; VPLAN-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
+; VPLAN-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
+; VPLAN-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
+; VPLAN-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; VPLAN-NEXT: No successors
+; VPLAN-NEXT: }
+; VPLAN-NEXT: Successor(s): middle.block
+; VPLAN-EMPTY:
+; VPLAN-NEXT: middle.block:
+; VPLAN-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; VPLAN-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; VPLAN-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<exit>:
+; VPLAN-NEXT: No successors
+; VPLAN-EMPTY:
+; VPLAN-NEXT: scalar.ph:
+; VPLAN-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; VPLAN-NEXT: Successor(s): ir-bb<loop>
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<loop>:
+; VPLAN-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; VPLAN-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
+; VPLAN-NEXT: IR store i32 0, ptr %gep, align 4
+; VPLAN-NEXT: IR %iv.next = add i64 %iv, 1
+; VPLAN-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
+; VPLAN-NEXT: No successors
+; VPLAN-NEXT: }
;
-; LLVM-LABEL: @simple(
-; LLVM-NEXT: entry:
-; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
-; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
-; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
-; LLVM: vector.ph:
-; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
-; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
-; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
-; LLVM: vector.body:
-; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
-; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
-; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
-; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
-; LLVM: middle.block:
-; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
-; LLVM: scalar.ph:
-; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
-; LLVM-NEXT: br label [[LOOP:%.*]]
-; LLVM: loop:
-; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
-; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
-; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
-; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
-; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
-; LLVM: exit:
-; LLVM-NEXT: ret void
+; CHECK-LABEL: @simple(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; CHECK: vector.ph:
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
+; CHECK: vector.body:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK: middle.block:
+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; CHECK: scalar.ph:
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4
+; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
;
entry:
br label %loop
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.ll b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.ll
index eed034f87df67..6921e914d8039 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.ll
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.ll
@@ -1,6 +1,6 @@
; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
-; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
-; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s --check-prefix VPLAN
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
define void @simple(ptr %p, i64 %n) {
entry:
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.llvm-only.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.llvm-only.expected
index a13338fda1203..af08675fbd22c 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.llvm-only.expected
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.llvm-only.expected
@@ -1,40 +1,40 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
-; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
-; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s --check-prefix VPLAN
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
define void @simple(ptr %p, i64 %n) {
-; LLVM-LABEL: @simple(
-; LLVM-NEXT: entry:
-; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
-; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
-; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
-; LLVM: vector.ph:
-; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
-; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
-; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
-; LLVM: vector.body:
-; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
-; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
-; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
-; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
-; LLVM: middle.block:
-; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
-; LLVM: scalar.ph:
-; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
-; LLVM-NEXT: br label [[LOOP:%.*]]
-; LLVM: loop:
-; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
-; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
-; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
-; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
-; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
-; LLVM: exit:
-; LLVM-NEXT: ret void
+; CHECK-LABEL: @simple(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; CHECK: vector.ph:
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
+; CHECK: vector.body:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK: middle.block:
+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; CHECK: scalar.ph:
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4
+; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
;
entry:
br label %loop
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected
index d05b5fb51e365..6ba4d4cd586f7 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.expected
@@ -1,94 +1,94 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
-; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
-; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s --check-prefix VPLAN
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
define void @simple(ptr %p, i64 %n) {
; Some comment
; NOTE: This is not a check directive.
; Another comment
; And another non-CHECK: comment
-; CHECK-LABEL: VPlan for loop in 'simple'
-; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
-; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
-; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
-; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
-; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<entry>:
-; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
-; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.ph:
-; CHECK-NEXT: Successor(s): vector loop
-; CHECK-EMPTY:
-; CHECK-NEXT: <x1> vector loop: {
-; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
-; CHECK-EMPTY:
-; CHECK-NEXT: vector.body:
-; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
-; CHECK-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
-; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
-; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
-; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
-; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
-; CHECK-NEXT: Successor(s): middle.block
-; CHECK-EMPTY:
-; CHECK-NEXT: middle.block:
-; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
-; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
-; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<exit>:
-; CHECK-NEXT: No successors
-; CHECK-EMPTY:
-; CHECK-NEXT: scalar.ph:
-; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK-NEXT: Successor(s): ir-bb<loop>
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<loop>:
-; CHECK-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
-; CHECK-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
-; CHECK-NEXT: IR store i32 0, ptr %gep, align 4
-; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
-; CHECK-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
+; VPLAN-LABEL: VPlan for loop in 'simple'
+; VPLAN: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; VPLAN-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; VPLAN-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; VPLAN-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; VPLAN-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<entry>:
+; VPLAN-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV (1 umax %n)
+; VPLAN-NEXT: Successor(s): scalar.ph, vector.ph
+; VPLAN-EMPTY:
+; VPLAN-NEXT: vector.ph:
+; VPLAN-NEXT: Successor(s): vector loop
+; VPLAN-EMPTY:
+; VPLAN-NEXT: <x1> vector loop: {
+; VPLAN-NEXT: vp<[[VP4:%[0-9]+]]> = CANONICAL-IV
+; VPLAN-EMPTY:
+; VPLAN-NEXT: vector.body:
+; VPLAN-NEXT: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4]]>, ir<1>, vp<[[VP0]]>
+; VPLAN-NEXT: CLONE ir<%gep> = getelementptr ir<%p>, vp<[[VP5]]>
+; VPLAN-NEXT: vp<[[VP6:%[0-9]+]]> = vector-pointer i32, ir<%gep>, ir<1>
+; VPLAN-NEXT: WIDEN store vp<[[VP6]]>, ir<0>
+; VPLAN-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP4]]>, vp<[[VP1]]>
+; VPLAN-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; VPLAN-NEXT: No successors
+; VPLAN-NEXT: }
+; VPLAN-NEXT: Successor(s): middle.block
+; VPLAN-EMPTY:
+; VPLAN-NEXT: middle.block:
+; VPLAN-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; VPLAN-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; VPLAN-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<exit>:
+; VPLAN-NEXT: No successors
+; VPLAN-EMPTY:
+; VPLAN-NEXT: scalar.ph:
+; VPLAN-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; VPLAN-NEXT: Successor(s): ir-bb<loop>
+; VPLAN-EMPTY:
+; VPLAN-NEXT: ir-bb<loop>:
+; VPLAN-NEXT: IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; VPLAN-NEXT: IR %gep = getelementptr i32, ptr %p, i64 %iv
+; VPLAN-NEXT: IR store i32 0, ptr %gep, align 4
+; VPLAN-NEXT: IR %iv.next = add i64 %iv, 1
+; VPLAN-NEXT: IR %cmp = icmp ult i64 %iv.next, %n
+; VPLAN-NEXT: No successors
+; VPLAN-NEXT: }
;
-; LLVM-LABEL: @simple(
-; LLVM-NEXT: entry:
-; LLVM-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
-; LLVM-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
-; LLVM-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
-; LLVM: vector.ph:
-; LLVM-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
-; LLVM-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
-; LLVM-NEXT: br label [[VECTOR_BODY:%.*]]
-; LLVM: vector.body:
-; LLVM-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; LLVM-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
-; LLVM-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
-; LLVM-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
-; LLVM-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
-; LLVM: middle.block:
-; LLVM-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
-; LLVM-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
-; LLVM: scalar.ph:
-; LLVM-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
-; LLVM-NEXT: br label [[LOOP:%.*]]
-; LLVM: loop:
-; LLVM-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; LLVM-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
-; LLVM-NEXT: store i32 0, ptr [[GEP]], align 4
-; LLVM-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
-; LLVM-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
-; LLVM-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
-; LLVM: exit:
-; LLVM-NEXT: ret void
+; CHECK-LABEL: @simple(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.umax.i64(i64 [[N:%.*]], i64 1)
+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; CHECK: vector.ph:
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
+; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
+; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
+; CHECK: vector.body:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
+; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[TMP1]], align 4
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK: middle.block:
+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
+; CHECK: scalar.ph:
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV]]
+; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4
+; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], [[N]]
+; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
;
entry:
br label %loop
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
index 1083dc813d3f7..2f8cead9b01b0 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/Inputs/run-lines.with-both-notes.ll
@@ -1,17 +1,17 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --run-lines 1
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --run-lines 2
; RUN: opt -passes=loop-vectorize -vplan-print-after="optimize$" \
-; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s
-; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s --check-prefix LLVM
+; RUN: -force-vector-width=4 -disable-output %s 2>&1 | FileCheck %s --check-prefix VPLAN
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
define void @simple(ptr %p, i64 %n) {
; Some comment
-; CHECK-LABEL: @simple
-; CHECK-NEXT: something stale
+; VPLAN-LABEL: @simple
+; VPLAN-NEXT: something stale
; NOTE: This is not a check directive.
; Another comment
-; LLVM-LABEL: @simple
-; LLVM-NEXT: another stale
+; CHECK-LABEL: @simple
+; CHECK-NEXT: another stale
; And another non-CHECK: comment
entry:
br label %loop
>From 78e2433c7678cbf681f2016128690dbd5edc8382 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 09:38:54 -0700
Subject: [PATCH 15/21] More cleanup
---
llvm/utils/UpdateTestChecks/common.py | 154 +++++++++++---------------
1 file changed, 67 insertions(+), 87 deletions(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index c3e6c2593502c..eb0b2eaab8a60 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -2956,19 +2956,8 @@ def dump_input_lines(output_lines, test_info, prefix_set, comment_string):
output_lines.append(line.rstrip("\n"))
-def sort_check_blocks(lines, all_run_lines, comment_string):
- """Reorder per-prefix check blocks at function starts to match RUN-line order.
-
- For each IR function definition in ``lines``, inspect the immediately
- following prologue of blank lines and comment lines. If that prologue
- contains FileCheck directives, group those directives into per-prefix
- blocks and reorder the blocks so their prefixes appear in the same
- first-seen order as the ``FileCheck`` prefixes from ``all_run_lines``.
- Non-check prologue lines are retained before the reordered check blocks,
- and functions without such check blocks are left unchanged.
- """
- # Preserve the first-seen FileCheck prefix order implied by the full set of
- # RUN lines, not just any selected subset being regenerated.
+def get_check_prefix_order(all_run_lines):
+ """Return FileCheck prefixes in first-seen RUN-line order."""
prefix_order = []
seen = set()
for run_line in all_run_lines:
@@ -2979,94 +2968,85 @@ def sort_check_blocks(lines, all_run_lines, comment_string):
continue
seen.add(prefix)
prefix_order.append(prefix)
+ return prefix_order
+
+def sort_check_blocks(lines, all_run_lines, comment_string):
+ """Reorder per-prefix check blocks at function starts to match RUN-line order."""
+ # Preserve the first-seen FileCheck prefix order implied by the full set of
+ # RUN lines, not just any selected subset being regenerated.
+ prefix_order = get_check_prefix_order(all_run_lines)
if not prefix_order:
return lines
-
ordered_prefixes = {prefix: index for index, prefix in enumerate(prefix_order)}
- result = []
- index = 0
- while index < len(lines):
- line = lines[index]
- result.append(line)
- index += 1
- if not IR_FUNCTION_RE.match(line):
- continue
- # Collect the contiguous function-start prologue made up of blank lines
- # and comments, because this is where generated check blocks live.
- prologue = []
- while index < len(lines):
- next_line = lines[index]
- if next_line == "" or next_line.lstrip().startswith(comment_string):
- prologue.append(next_line)
- index += 1
- continue
- break
-
- blocks = []
- other_lines = []
- current_prefix = None
- current_block = []
- saw_check_block = False
-
- def flush_current_block():
- nonlocal current_prefix, current_block
- if current_prefix is not None:
- # Keep internal spacing within a check block, but drop trailing
- # separators so they can be reintroduced consistently after
- # reordering.
- while current_block and current_block[-1].strip() in (
+ FUNCTION_START = object()
+ PROLOGUE_NON_CHECK = object()
+ REST = object()
+ previous_line_group = REST
+
+ def get_line_group(line):
+ nonlocal previous_line_group
+ if IR_FUNCTION_RE.match(line):
+ group = FUNCTION_START
+ elif previous_line_group is REST:
+ group = REST
+ else:
+ match = CHECK_RE.match(line)
+ if match and match.group(1) in ordered_prefixes:
+ group = match.group(1)
+ elif line == "" or line.lstrip().startswith(comment_string):
+ if previous_line_group in ordered_prefixes and line.strip() in (
"",
comment_string,
comment_string + SEPARATOR,
):
- current_block.pop()
- if current_block:
- blocks.append((current_prefix, current_block))
- current_prefix = None
- current_block = []
-
- # Split the prologue into reorderable per-prefix check blocks and all
- # other lines, which keep their relative order.
- for prologue_line in prologue:
- match = CHECK_RE.match(prologue_line)
- if match and match.group(1) in ordered_prefixes:
- prefix = match.group(1)
- if current_prefix != prefix:
- flush_current_block()
- current_prefix = prefix
- saw_check_block = True
- current_block.append(prologue_line)
- continue
-
- if current_prefix is not None and prologue_line.strip() in (
- "",
- comment_string,
- comment_string + SEPARATOR,
- ):
- current_block.append(prologue_line)
- continue
+ group = previous_line_group
+ else:
+ group = PROLOGUE_NON_CHECK
+ else:
+ group = REST
+ previous_line_group = group
+ return group
- flush_current_block()
- other_lines.append(prologue_line)
+ result = []
+ blocks = []
+ other_lines = []
- flush_current_block()
+ for group, group_lines in itertools.chain(
+ itertools.groupby(lines, key=get_line_group),
+ # Fake entry to ensure last real one gets written.
+ ((REST, ()),),
+ ):
+ if group in (FUNCTION_START, REST):
+ if blocks:
+ blocks.sort(key=lambda block: ordered_prefixes[block[0]])
+ result.extend(other_lines)
+ for _, block_lines in blocks:
+ result.extend(block_lines)
+ result.append(comment_string)
+ else:
+ result.extend(other_lines)
+ blocks = []
+ other_lines = []
+ result.extend(group_lines)
+ continue
- if not saw_check_block:
- result.extend(prologue)
+ block_lines = list(group_lines)
+ if group is PROLOGUE_NON_CHECK:
+ other_lines.extend(block_lines)
continue
- result.extend(other_lines)
- blocks.sort(
- key=lambda block: (
- ordered_prefixes.get(block[0], len(ordered_prefixes)),
- block[0],
- )
- )
- for _, block_lines in blocks:
- result.extend(block_lines)
- result.append(comment_string)
+ # Keep internal spacing within a check block, but drop trailing
+ # separators so they can be reintroduced consistently after reordering.
+ while block_lines and block_lines[-1].strip() in (
+ "",
+ comment_string,
+ comment_string + SEPARATOR,
+ ):
+ block_lines.pop()
+ if block_lines:
+ blocks.append((group, block_lines))
return result
>From 0ca4578613bafd372937befe054c2428fa8eb06b Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 11:02:23 -0700
Subject: [PATCH 16/21] Cleanup vibe-coded parts of update_any_test_checks.py
---
llvm/utils/update_any_test_checks.py | 77 +++++++++++++++-------------
1 file changed, 40 insertions(+), 37 deletions(-)
diff --git a/llvm/utils/update_any_test_checks.py b/llvm/utils/update_any_test_checks.py
index 95c65776f5a1d..f8994c434676d 100755
--- a/llvm/utils/update_any_test_checks.py
+++ b/llvm/utils/update_any_test_checks.py
@@ -29,8 +29,11 @@ def get_autogenerated_utc_names(lines):
lambda line: RE_ASSERTIONS.search(line.strip()) is not None, lines
):
utc_name = RE_ASSERTIONS.search(line.strip()).group(1)
- if utc_name not in utc_names:
- utc_names.append(utc_name)
+ assert (
+ utc_name not in utc_names,
+ "Multiple entries for the same script aren't supported",
+ )
+ utc_names.append(utc_name)
return utc_names
@@ -57,13 +60,17 @@ def run_utc_tool(utc_name, utc_tool, testname, environment):
def update_test_file(utc_names, utc_tools, testname, environment):
- outputs = []
+ stdout = []
+ stderr = []
for utc_name in utc_names:
- return_code, stdout, stderr = run_utc_tool(
+ return_code, tool_stdout, tool_stderr = run_utc_tool(
utc_name, utc_tools[utc_name], testname, environment
)
- outputs.append((utc_name, return_code, stdout, stderr))
- return outputs
+ stdout.append(tool_stdout)
+ stderr.append(tool_stderr)
+ if return_code != 0:
+ return utc_name, return_code, b"".join(stdout), b"".join(stderr)
+ return utc_name, 0, b"".join(stdout), b"".join(stderr)
def read_arguments_from_file(filename):
@@ -106,21 +113,18 @@ def utc_lit_plugin(result, test, commands):
return f"update-utc-tests: {utc_name} not found"
utc_tools[utc_name] = utc_tool
- outputs = update_test_file(utc_names, utc_tools, testname, test.config.environment)
- messages = []
- for utc_name, return_code, stdout, stderr in outputs:
- stderr = stderr.decode(errors="replace")
- if return_code != 0:
- if stderr:
- return f"update-utc-tests: {utc_name} exited with return code {return_code}\n{stderr.rstrip()}"
- return f"update-utc-tests: {utc_name} exited with return code {return_code}"
-
- stdout = stdout.decode(errors="replace")
- if stdout:
- messages.append(stdout.rstrip())
-
- if messages:
- return f"update-utc-tests: updated {testname}\n" + "\n".join(messages)
+ utc_name, return_code, stdout, stderr = update_test_file(
+ utc_names, utc_tools, testname, test.config.environment
+ )
+ stderr = stderr.decode(errors="replace")
+ if return_code != 0:
+ if stderr:
+ return f"update-utc-tests: {utc_name} exited with return code {return_code}\n{stderr.rstrip()}"
+ return f"update-utc-tests: {utc_name} exited with return code {return_code}"
+
+ stdout = stdout.decode(errors="replace")
+ if stdout:
+ return f"update-utc-tests: updated {testname}\n{stdout.rstrip()}"
return f"update-utc-tests: updated {testname}"
@@ -198,24 +202,23 @@ def main():
jobs.append((testname, future))
for testname, future in jobs:
- outputs = future.result()
+ _, return_code, stdout, stderr = future.result()
print(f"Update {testname}")
- for utc_name, return_code, stdout, stderr in outputs:
- stdout = stdout.decode(errors="replace")
- if stdout:
- print(stdout, end="")
- if not stdout.endswith("\n"):
- print()
-
- stderr = stderr.decode(errors="replace")
- if stderr:
- print(stderr, end="")
- if not stderr.endswith("\n"):
- print()
- if return_code != 0:
- print(f"Return code: {return_code}")
- have_error = True
+ stdout = stdout.decode(errors="replace")
+ if stdout:
+ print(stdout, end="")
+ if not stdout.endswith("\n"):
+ print()
+
+ stderr = stderr.decode(errors="replace")
+ if stderr:
+ print(stderr, end="")
+ if not stderr.endswith("\n"):
+ print()
+ if return_code != 0:
+ print(f"Return code: {return_code}")
+ have_error = True
if have_error:
sys.exit(1)
>From 07bdb9f66cc45632f74853fcfec29283aface44a Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 11:20:18 -0700
Subject: [PATCH 17/21] Only perform blocks sorting if necessary
---
llvm/utils/update_analyze_test_checks.py | 3 ++-
llvm/utils/update_test_checks.py | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py
index 94152d51163a9..bb214e546e79a 100755
--- a/llvm/utils/update_analyze_test_checks.py
+++ b/llvm/utils/update_analyze_test_checks.py
@@ -187,7 +187,8 @@ def update_test(opt_basename: str, ti: common.TestInfo):
continue
is_in_function = is_in_function_start = True
- output_lines = common.sort_check_blocks(output_lines, ti.all_run_lines, ";")
+ if ti.args.run_lines:
+ output_lines = common.sort_check_blocks(output_lines, ti.all_run_lines, ";")
if ti.args.gen_unused_prefix_body:
output_lines.extend(
ti.get_checks_for_unused_prefixes(prefix_list, generated_prefixes)
diff --git a/llvm/utils/update_test_checks.py b/llvm/utils/update_test_checks.py
index c601f6ea669c1..b1b2c5309b117 100755
--- a/llvm/utils/update_test_checks.py
+++ b/llvm/utils/update_test_checks.py
@@ -311,7 +311,8 @@ def update_test(ti: common.TestInfo):
args.check_globals,
)
)
- output_lines = common.sort_check_blocks(output_lines, ti.all_run_lines, ";")
+ if ti.args.run_lines:
+ output_lines = common.sort_check_blocks(output_lines, ti.all_run_lines, ";")
if ti.args.gen_unused_prefix_body:
output_lines.extend(
ti.get_checks_for_unused_prefixes(prefix_list, generated_prefixes)
>From 20c508f43b844c8fba5e38372bd983b67a4c53ea Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 13:41:01 -0700
Subject: [PATCH 18/21] Simplify parse_run_lines_argument + test for error
reporting
---
.../multiple_utc/run-lines.test | 15 ++++++++
llvm/utils/UpdateTestChecks/common.py | 36 +++++++++----------
2 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
index edfa435b8fb17..c86812c5138c2 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
@@ -41,3 +41,18 @@
# RUN: diff -u %t.ll %S/Inputs/run-lines.with-both-notes.expected
# RUN: %update_any_test_checks --path %llvm_tools_dir %t.ll
# RUN: diff -u %t.ll %S/Inputs/run-lines.with-both-notes.expected
+
+# RUN: cp -f %S/Inputs/run-lines.ll %t.ll
+# RUN: %update_test_checks --run-lines=1,2-2 %t.ll
+
+## Invalid --run-lines:
+# RUN: not %update_test_checks --run-lines= %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=
+# RUN: not %update_test_checks --run-lines=1- %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=1-
+# RUN: not %update_test_checks --run-lines=0 %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=0
+# RUN: not %update_test_checks --run-lines=2-1 %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=2-1
+# RUN: not %update_test_checks --run-lines=1-2- %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=1-2-
+# RUN: not %update_test_checks --run-lines=3 %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=3
+# RUN: not %update_test_checks --run-lines=one %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=one
+# RUN: not %update_test_checks --run-lines=one-two %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=one-two
+
+# INVALID: ValueError: invalid --run-lines entry '[[ENTRY]]'; expected N or N-M, 0 < N <= M <= 2
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index eb0b2eaab8a60..e2d07e4ec120e 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -748,32 +748,28 @@ def parse_run_lines_argument(run_lines_filter, num_run_lines):
selected = set()
for item in run_lines_filter.split(","):
item = item.strip()
+ error_str = "invalid --run-lines entry '{}'; expected N or N-M, 0 < N <= M <= {}".format(
+ item, num_run_lines
+ )
if not item:
- raise ValueError("empty item in --run-lines filter")
+ raise ValueError(error_str)
if "-" in item:
bounds = item.split("-", 1)
if len(bounds) != 2 or not bounds[0] or not bounds[1]:
- raise ValueError(
- "invalid --run-lines range '{}'; expected N or N-M".format(item)
- )
- start = int(bounds[0])
- end = int(bounds[1])
- else:
- start = end = int(item)
+ raise ValueError(error_str)
- if start <= 0 or end <= 0:
- raise ValueError("--run-lines entries must be positive: '{}'".format(item))
- if start > end:
- raise ValueError(
- "invalid --run-lines range '{}'; start must not exceed end".format(item)
- )
- if end > num_run_lines:
- raise ValueError(
- "--run-lines selects RUN line {} but only {} RUN lines exist".format(
- end, num_run_lines
- )
- )
+ try:
+ if "-" in item:
+ start = int(bounds[0])
+ end = int(bounds[1])
+ else:
+ start = end = int(item)
+ except ValueError:
+ raise ValueError(error_str) from None
+
+ if start <= 0 or end <= 0 or start > end or end > num_run_lines:
+ raise ValueError(error_str)
selected.update(range(start, end + 1))
>From 18e6adf1adfabe7a50e103c6dc340bfaab3ccccb Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 15:05:21 -0700
Subject: [PATCH 19/21] Move list->dict conversion into
`get_check_prefix_order` helper
---
llvm/utils/UpdateTestChecks/common.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index e2d07e4ec120e..95fd444433144 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -2964,17 +2964,18 @@ def get_check_prefix_order(all_run_lines):
continue
seen.add(prefix)
prefix_order.append(prefix)
- return prefix_order
+ if not prefix_order:
+ return None
+ return {prefix: index for index, prefix in enumerate(prefix_order)}
def sort_check_blocks(lines, all_run_lines, comment_string):
"""Reorder per-prefix check blocks at function starts to match RUN-line order."""
# Preserve the first-seen FileCheck prefix order implied by the full set of
# RUN lines, not just any selected subset being regenerated.
- prefix_order = get_check_prefix_order(all_run_lines)
- if not prefix_order:
+ ordered_prefixes = get_check_prefix_order(all_run_lines)
+ if not ordered_prefixes:
return lines
- ordered_prefixes = {prefix: index for index, prefix in enumerate(prefix_order)}
FUNCTION_START = object()
PROLOGUE_NON_CHECK = object()
>From 38f35a2579efb1c76c6ee1b41f2b4cbd8fec39a6 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 15:42:30 -0700
Subject: [PATCH 20/21] Fix assert to use proper syntax
---
llvm/utils/update_any_test_checks.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/utils/update_any_test_checks.py b/llvm/utils/update_any_test_checks.py
index f8994c434676d..7ca1b60da8420 100755
--- a/llvm/utils/update_any_test_checks.py
+++ b/llvm/utils/update_any_test_checks.py
@@ -30,9 +30,9 @@ def get_autogenerated_utc_names(lines):
):
utc_name = RE_ASSERTIONS.search(line.strip()).group(1)
assert (
- utc_name not in utc_names,
- "Multiple entries for the same script aren't supported",
- )
+ utc_name not in utc_names
+ ), "Multiple entries for the same script aren't supported"
+
utc_names.append(utc_name)
return utc_names
>From 96dab660b766da71a5f67f2f9c9d722320f69026 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Fri, 31 Jul 2026 15:42:57 -0700
Subject: [PATCH 21/21] Update `parse_run_lines_argument`, prohibit
--run-lines=N-N
---
.../multiple_utc/run-lines.test | 5 +--
llvm/utils/UpdateTestChecks/common.py | 33 ++++++++++++-------
2 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
index c86812c5138c2..4c5da4e6b1e6e 100644
--- a/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
+++ b/llvm/test/tools/UpdateTestChecks/multiple_utc/run-lines.test
@@ -43,11 +43,12 @@
# RUN: diff -u %t.ll %S/Inputs/run-lines.with-both-notes.expected
# RUN: cp -f %S/Inputs/run-lines.ll %t.ll
-# RUN: %update_test_checks --run-lines=1,2-2 %t.ll
+# RUN: %update_test_checks --run-lines=1-2 %t.ll
## Invalid --run-lines:
# RUN: not %update_test_checks --run-lines= %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=
# RUN: not %update_test_checks --run-lines=1- %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=1-
+# RUN: not %update_test_checks --run-lines=1-1 %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=1-1
# RUN: not %update_test_checks --run-lines=0 %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=0
# RUN: not %update_test_checks --run-lines=2-1 %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=2-1
# RUN: not %update_test_checks --run-lines=1-2- %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=1-2-
@@ -55,4 +56,4 @@
# RUN: not %update_test_checks --run-lines=one %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=one
# RUN: not %update_test_checks --run-lines=one-two %S/Inputs/run-lines.ll 2>&1 | FileCheck %s --check-prefix=INVALID -DENTRY=one-two
-# INVALID: ValueError: invalid --run-lines entry '[[ENTRY]]'; expected N or N-M, 0 < N <= M <= 2
+# INVALID: ValueError: invalid --run-lines entry '[[ENTRY]]'; expected N or N-M, 0 < N < M <= 2
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 95fd444433144..eb8660e93aae7 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -748,30 +748,41 @@ def parse_run_lines_argument(run_lines_filter, num_run_lines):
selected = set()
for item in run_lines_filter.split(","):
item = item.strip()
- error_str = "invalid --run-lines entry '{}'; expected N or N-M, 0 < N <= M <= {}".format(
- item, num_run_lines
+ error_str = (
+ "invalid --run-lines entry '{}'; expected N or N-M, 0 < N < M <= {}".format(
+ item, num_run_lines
+ )
)
if not item:
raise ValueError(error_str)
- if "-" in item:
- bounds = item.split("-", 1)
- if len(bounds) != 2 or not bounds[0] or not bounds[1]:
+ if not "-" in item:
+ try:
+ idx = int(item)
+ except ValueError:
+ raise ValueError(error_str) from None
+
+ if not (0 < idx <= num_run_lines):
raise ValueError(error_str)
+ selected.add(idx)
+ continue
+
+ bounds = item.split("-", 1)
+ if len(bounds) != 2 or not bounds[0] or not bounds[1]:
+ raise ValueError(error_str)
+
try:
- if "-" in item:
- start = int(bounds[0])
- end = int(bounds[1])
- else:
- start = end = int(item)
+ start = int(bounds[0])
+ end = int(bounds[1])
except ValueError:
raise ValueError(error_str) from None
- if start <= 0 or end <= 0 or start > end or end > num_run_lines:
+ if not (0 < start < end <= num_run_lines):
raise ValueError(error_str)
selected.update(range(start, end + 1))
+ continue
return selected
More information about the llvm-commits
mailing list