[Mlir-commits] [mlir] [mlir][LLVMIR] Fix loop follow-up metadata import and export (PR #223376)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Sep 14 04:42:20 PDT 2026
https://github.com/ardenyang0125 created https://github.com/llvm/llvm-project/pull/223376
## Problem
MLIR currently exports loop follow-up metadata by wrapping its properties in an additional self-referencing loop ID:
```llvm
!1 = !{!"llvm.loop.unroll.followup_unrolled", !2}
!2 = distinct !{!2, !3}
!3 = !{!"llvm.loop.mustprogress"}
```
LLVM expects the properties directly after the follow-up name:
```llvm
!1 = !{!"llvm.loop.unroll.followup_unrolled", !3}
!3 = !{!"llvm.loop.mustprogress"}
```
`makeFollowupLoopID` copies the follow-up operands without unwrapping a nested loop ID. Consequently, properties such as `llvm.loop.mustprogress` inside the extra wrapper are not recognized as properties of the resulting loop.
## Changes
- Export follow-up properties directly, excluding the temporary loop ID's self-reference.
- Update import to read direct property lists.
- Preserve explicitly empty follow-ups, multiple properties, nested follow-ups, and debug locations.
- Diagnose malformed follow-up metadata and detect cycles to prevent infinite recursion.
An explicitly empty follow-up is different from an absent follow-up: it specifies an empty configuration instead of leaving the transformation to use its default follow-up attributes. Import therefore preserves it as a non-null, empty `LoopAnnotationAttr`.
This patch corrects MLIR's representation of existing LLVM follow-up metadata. It does not change LLVM's transformation policies or introduce automatic attribute inheritance.
## Testing
Built `mlir-translate`, `FileCheck`, `count`, and `not` on Linux using a Release build with assertions enabled.
All three targeted regression tests passed:
- `mlir/test/Target/LLVMIR/loop-metadata.mlir`
- `mlir/test/Target/LLVMIR/Import/metadata-loop.ll`
- `mlir/test/Target/LLVMIR/Import/import-failure.ll`
`git diff --check` also passed. The full MLIR test suite was not run.
Assisted-by: OpenAI Codex
>From ac5d586080fd1d35984632b178fbf8f6489480f8 Mon Sep 17 00:00:00 2001
From: yangzihan <yangzihan at sunmmio.com>
Date: Mon, 14 Sep 2026 18:59:52 +0800
Subject: [PATCH] [mlir][LLVMIR] Fix loop follow-up metadata import and export
Emit follow-up properties directly instead of wrapping them in a loop ID. Update import to handle direct property lists, preserve empty and nested follow-ups, and detect cycles.
Assisted-by: OpenAI Codex
---
.../Target/LLVMIR/LoopAnnotationImporter.cpp | 79 +++++++++-------
.../LLVMIR/LoopAnnotationTranslation.cpp | 10 +-
.../Target/LLVMIR/Import/import-failure.ll | 38 +++++++-
.../Target/LLVMIR/Import/metadata-loop.ll | 92 +++++++++++++++++--
mlir/test/Target/LLVMIR/loop-metadata.mlir | 34 +++----
5 files changed, 187 insertions(+), 66 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp b/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
index 6658b4a920e373..672c8df1c9465f 100644
--- a/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "LoopAnnotationImporter.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
using namespace mlir;
@@ -16,10 +18,16 @@ using namespace mlir::LLVM::detail;
namespace {
/// Helper class that keeps the state of one metadata to attribute conversion.
struct LoopMetadataConversion {
- LoopMetadataConversion(const llvm::MDNode *node, Location loc,
- LoopAnnotationImporter &loopAnnotationImporter)
+ enum class InputKind { LoopID, Followup };
+
+ LoopMetadataConversion(
+ const llvm::MDNode *node, Location loc,
+ LoopAnnotationImporter &loopAnnotationImporter,
+ llvm::SmallPtrSetImpl<const llvm::MDNode *> &activeNodes,
+ InputKind inputKind = InputKind::LoopID)
: node(node), loc(loc), loopAnnotationImporter(loopAnnotationImporter),
- ctx(loc->getContext()){};
+ ctx(loc->getContext()), activeNodes(activeNodes), inputKind(inputKind) {
+ }
/// Converts this structs loop metadata node into a LoopAnnotationAttr.
LoopAnnotationAttr convert();
@@ -36,7 +44,6 @@ struct LoopMetadataConversion {
FailureOr<BoolAttr> lookupBoolNode(StringRef name, bool negated = false);
FailureOr<BoolAttr> lookupIntNodeAsBoolAttr(StringRef name);
FailureOr<IntegerAttr> lookupIntNode(StringRef name);
- FailureOr<llvm::MDNode *> lookupMDNode(StringRef name);
FailureOr<SmallVector<llvm::MDNode *>> lookupMDNodes(StringRef name);
FailureOr<LoopAnnotationAttr> lookupFollowupNode(StringRef name);
FailureOr<BoolAttr> lookupBooleanUnitNode(StringRef enableName,
@@ -63,14 +70,21 @@ struct LoopMetadataConversion {
Location loc;
LoopAnnotationImporter &loopAnnotationImporter;
MLIRContext *ctx;
+ llvm::SmallPtrSetImpl<const llvm::MDNode *> &activeNodes;
+ InputKind inputKind;
};
} // namespace
LogicalResult LoopMetadataConversion::initConversionState() {
- // Check if it's a valid node.
- if (node->getNumOperands() == 0 ||
- dyn_cast<llvm::MDNode>(node->getOperand(0)) != node)
- return emitWarning(loc) << "invalid loop node";
+ // LoopIDs begin with a self-reference; follow-ups begin with their name.
+ if (inputKind == InputKind::LoopID) {
+ if (node->getNumOperands() == 0 ||
+ dyn_cast<llvm::MDNode>(node->getOperand(0)) != node)
+ return emitWarning(loc) << "invalid loop node";
+ } else if (node->getNumOperands() == 0 ||
+ !isa<llvm::MDString>(node->getOperand(0))) {
+ return emitWarning(loc) << "invalid loop followup node";
+ }
for (const llvm::MDOperand &operand : llvm::drop_begin(node->operands())) {
if (auto *diLoc = dyn_cast<llvm::DILocation>(operand)) {
@@ -206,26 +220,6 @@ FailureOr<IntegerAttr> LoopMetadataConversion::lookupIntNode(StringRef name) {
val->getValue().getLimitedValue());
}
-FailureOr<llvm::MDNode *> LoopMetadataConversion::lookupMDNode(StringRef name) {
- const llvm::MDNode *property = lookupAndEraseProperty(name);
- if (!property)
- return nullptr;
-
- auto emitNodeWarning = [&]() {
- return emitWarning(loc)
- << "expected metadata node " << name << " to hold an MDNode";
- };
-
- if (property->getNumOperands() != 2)
- return emitNodeWarning();
-
- auto *node = dyn_cast<llvm::MDNode>(property->getOperand(1));
- if (!node)
- return emitNodeWarning();
-
- return node;
-}
-
FailureOr<SmallVector<llvm::MDNode *>>
LoopMetadataConversion::lookupMDNodes(StringRef name) {
const llvm::MDNode *property = lookupAndEraseProperty(name);
@@ -253,13 +247,17 @@ LoopMetadataConversion::lookupMDNodes(StringRef name) {
FailureOr<LoopAnnotationAttr>
LoopMetadataConversion::lookupFollowupNode(StringRef name) {
- auto node = lookupMDNode(name);
- if (failed(node))
- return failure();
- if (*node == nullptr)
+ const llvm::MDNode *followup = lookupAndEraseProperty(name);
+ if (!followup)
return LoopAnnotationAttr(nullptr);
- return loopAnnotationImporter.translateLoopAnnotation(*node, loc);
+ LoopAnnotationAttr attr =
+ LoopMetadataConversion(followup, loc, loopAnnotationImporter, activeNodes,
+ InputKind::Followup)
+ .convert();
+ if (!attr)
+ return failure();
+ return attr;
}
static bool isEmptyOrNull(const Attribute attr) { return !attr; }
@@ -432,9 +430,20 @@ FailureOr<FusedLoc> LoopMetadataConversion::convertEndLoc() {
}
LoopAnnotationAttr LoopMetadataConversion::convert() {
+ if (!activeNodes.insert(node).second) {
+ emitWarning(loc) << "cannot import cyclic loop annotation";
+ return {};
+ }
+ llvm::scope_exit guard([&] { activeNodes.erase(node); });
+
if (failed(initConversionState()))
return {};
+ // An explicit empty follow-up is different from an absent follow-up.
+ if (inputKind == InputKind::Followup && node->getNumOperands() == 1)
+ return LoopAnnotationAttr::get(ctx, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
+ {}, {}, {}, {}, {});
+
FailureOr<BoolAttr> disableNonForced =
lookupUnitNode("llvm.loop.disable_nonforced");
FailureOr<LoopVectorizeAttr> vecAttr = convertVectorizeAttr();
@@ -481,7 +490,9 @@ LoopAnnotationImporter::translateLoopAnnotation(const llvm::MDNode *node,
if (it != loopMetadataMapping.end())
return it->getSecond();
- LoopAnnotationAttr attr = LoopMetadataConversion(node, loc, *this).convert();
+ llvm::SmallPtrSet<const llvm::MDNode *, 4> activeNodes;
+ LoopAnnotationAttr attr =
+ LoopMetadataConversion(node, loc, *this, activeNodes).convert();
mapLoopMetadata(node, attr);
return attr;
diff --git a/mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp b/mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp
index 475799e7fdbfde..37866718de9e78 100644
--- a/mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp
@@ -110,11 +110,15 @@ void LoopAnnotationConversion::convertFollowupNode(StringRef name,
if (!attr)
return;
- llvm::MDNode *node =
+ llvm::MDNode *loopID =
loopAnnotationTranslation.translateLoopAnnotation(attr, op);
- metadataNodes.push_back(
- llvm::MDNode::get(ctx, {llvm::MDString::get(ctx, name), node}));
+ // Follow-ups contain properties directly, without the LoopID self-reference.
+ SmallVector<llvm::Metadata *, 4> operands;
+ operands.push_back(llvm::MDString::get(ctx, name));
+ for (const llvm::MDOperand &operand : llvm::drop_begin(loopID->operands()))
+ operands.push_back(operand.get());
+ metadataNodes.push_back(llvm::MDNode::get(ctx, operands));
}
void LoopAnnotationConversion::convertLoopOptions(LoopVectorizeAttr options) {
diff --git a/mlir/test/Target/LLVMIR/Import/import-failure.ll b/mlir/test/Target/LLVMIR/Import/import-failure.ll
index 9015eff87a8c76..552841ebda9eb6 100644
--- a/mlir/test/Target/LLVMIR/Import/import-failure.ll
+++ b/mlir/test/Target/LLVMIR/Import/import-failure.ll
@@ -175,7 +175,7 @@ end:
; // -----
; CHECK: <unknown>
-; CHECK-SAME: warning: expected metadata node llvm.loop.vectorize.followup_all to hold an MDNode
+; CHECK-SAME: warning: expected all loop properties to be either debug locations or metadata nodes
; CHECK: <unknown>
; CHECK-SAME: warning: unhandled metadata: ![[FOLLOWUP_LOOP:[0-9]+]] = distinct !{![[FOLLOWUP_LOOP]], ![[FOLLOWUP_PROP:[0-9]+]]}
define void @unsupported_loop_annotation(i64 %n, ptr %A) {
@@ -190,6 +190,42 @@ end:
; // -----
+; A whole LoopID is not a named property in a followup's direct attribute list.
+; CHECK: <unknown>
+; CHECK-SAME: warning: cannot import loop property without a name
+; CHECK: <unknown>
+; CHECK-SAME: warning: unhandled metadata: ![[WRAPPED_LOOP:[0-9]+]] = distinct !{![[WRAPPED_LOOP]], ![[WRAPPED_PROP:[0-9]+]]}
+define void @followup_with_loop_id() {
+entry:
+ br label %end, !llvm.loop !0
+end:
+ ret void
+}
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.unroll.followup_unrolled", !2}
+!2 = distinct !{!2, !3}
+!3 = !{!"llvm.loop.mustprogress"}
+
+; // -----
+
+; Reject recursive followup metadata instead of recursing indefinitely.
+; CHECK: <unknown>
+; CHECK-SAME: warning: cannot import cyclic loop annotation
+; CHECK: <unknown>
+; CHECK-SAME: warning: unhandled metadata: ![[CYCLIC_LOOP:[0-9]+]] = distinct !{![[CYCLIC_LOOP]], ![[CYCLIC_PROP:[0-9]+]]}
+define void @cyclic_followup() {
+entry:
+ br label %end, !llvm.loop !0
+end:
+ ret void
+}
+
+!0 = distinct !{!0, !1}
+!1 = distinct !{!"llvm.loop.unroll.followup_unrolled", !1}
+
+; // -----
+
; CHECK: <unknown>
; CHECK-SAME: warning: expected metadata node llvm.loop.parallel_accesses to hold one or multiple MDNodes
; CHECK: <unknown>
diff --git a/mlir/test/Target/LLVMIR/Import/metadata-loop.ll b/mlir/test/Target/LLVMIR/Import/metadata-loop.ll
index 89357186409e33..ba601fedecb291 100644
--- a/mlir/test/Target/LLVMIR/Import/metadata-loop.ll
+++ b/mlir/test/Target/LLVMIR/Import/metadata-loop.ll
@@ -1,4 +1,5 @@
; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s
+; RUN: mlir-translate -import-llvm -mlir-to-llvmir -split-input-file %s | FileCheck %s --check-prefix=ROUNDTRIP
; CHECK-DAG: #[[$GROUP0:.*]] = #llvm.access_group<id = {{.*}}>
; CHECK-DAG: #[[$GROUP1:.*]] = #llvm.access_group<id = {{.*}}>
@@ -94,8 +95,7 @@ end:
!7 = !{!"llvm.loop.vectorize.followup_epilogue", !9}
!8 = !{!"llvm.loop.vectorize.followup_all", !9}
-!9 = distinct !{!9, !10}
-!10 = !{!"llvm.loop.disable_nonforced"}
+!9 = !{!"llvm.loop.disable_nonforced"}
; // -----
@@ -138,8 +138,7 @@ end:
!7 = !{!"llvm.loop.unroll.followup_remainder", !9}
!8 = !{!"llvm.loop.unroll.followup_all", !9}
-!9 = distinct !{!9, !10}
-!10 = !{!"llvm.loop.disable_nonforced"}
+!9 = !{!"llvm.loop.disable_nonforced"}
; // -----
@@ -160,6 +159,69 @@ end:
; // -----
+; An explicitly empty followup must survive import and export, rather than
+; disappear or acquire a self-referential LoopID wrapper.
+; CHECK-DAG: #[[EMPTY:.*]] = #llvm.loop_annotation<>
+; CHECK-DAG: #[[UNROLL_ATTR:.*]] = #llvm.loop_unroll<count = 8 : i32, followupUnrolled = #[[EMPTY]]>
+; CHECK-DAG: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation<unroll = #[[UNROLL_ATTR]]>
+; CHECK-LABEL: @unroll_empty_followup
+; ROUNDTRIP-LABEL: @unroll_empty_followup(
+define void @unroll_empty_followup() {
+entry:
+; CHECK: llvm.br ^{{.*}} loop_annotation = #[[$ANNOT_ATTR]]
+; ROUNDTRIP: br label {{.*}}, !llvm.loop ![[EMPTY_LOOP:[0-9]+]]
+ br label %end, !llvm.loop !0
+end:
+ ret void
+}
+
+!0 = distinct !{!0, !1, !2}
+!1 = !{!"llvm.loop.unroll.count", i32 8}
+!2 = !{!"llvm.loop.unroll.followup_unrolled"}
+
+; ROUNDTRIP: ![[EMPTY_LOOP]] = distinct !{![[EMPTY_LOOP]], ![[COUNT:[0-9]+]], ![[EMPTY_FOLLOWUP:[0-9]+]]}
+; ROUNDTRIP-DAG: ![[COUNT]] = !{!"llvm.loop.unroll.count", i32 8}
+; ROUNDTRIP-DAG: ![[EMPTY_FOLLOWUP]] = !{!"llvm.loop.unroll.followup_unrolled"}
+
+; // -----
+
+; Keep multiple direct properties and a later followup as separate properties.
+; In particular, do not recursively flatten the nested empty followup.
+; CHECK-DAG: #[[EMPTY:.*]] = #llvm.loop_annotation<>
+; CHECK-DAG: #[[VECTORIZE_ATTR:.*]] = #llvm.loop_vectorize<disable = true>
+; CHECK-DAG: #[[INNER_UNROLL:.*]] = #llvm.loop_unroll<count = 2 : i32, followupUnrolled = #[[EMPTY]]>
+; CHECK-DAG: #[[FOLLOWUP:.*]] = #llvm.loop_annotation<vectorize = #[[VECTORIZE_ATTR]], unroll = #[[INNER_UNROLL]], mustProgress = true>
+; CHECK-DAG: #[[UNROLL_ATTR:.*]] = #llvm.loop_unroll<count = 8 : i32, followupUnrolled = #[[FOLLOWUP]]>
+; CHECK-DAG: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation<unroll = #[[UNROLL_ATTR]]>
+; CHECK-LABEL: @unroll_nested_followup
+; ROUNDTRIP-LABEL: @unroll_nested_followup(
+define void @unroll_nested_followup() {
+entry:
+; CHECK: llvm.br ^{{.*}} loop_annotation = #[[$ANNOT_ATTR]]
+; ROUNDTRIP: br label {{.*}}, !llvm.loop ![[NESTED_LOOP:[0-9]+]]
+ br label %end, !llvm.loop !0
+end:
+ ret void
+}
+
+!0 = distinct !{!0, !1, !2}
+!1 = !{!"llvm.loop.unroll.count", i32 8}
+!2 = !{!"llvm.loop.unroll.followup_unrolled", !3, !4, !5, !6}
+!3 = !{!"llvm.loop.mustprogress"}
+!4 = !{!"llvm.loop.vectorize.disable"}
+!5 = !{!"llvm.loop.unroll.count", i32 2}
+!6 = !{!"llvm.loop.unroll.followup_unrolled"}
+
+; ROUNDTRIP: ![[NESTED_LOOP]] = distinct !{![[NESTED_LOOP]], ![[COUNT:[0-9]+]], ![[FOLLOWUP:[0-9]+]]}
+; ROUNDTRIP: ![[COUNT]] = !{!"llvm.loop.unroll.count", i32 8}
+; ROUNDTRIP: ![[FOLLOWUP]] = !{!"llvm.loop.unroll.followup_unrolled", ![[PROGRESS:[0-9]+]], ![[VECTORIZE:[0-9]+]], ![[INNER_COUNT:[0-9]+]], ![[INNER_FOLLOWUP:[0-9]+]]}
+; ROUNDTRIP-DAG: ![[PROGRESS]] = !{!"llvm.loop.mustprogress"}
+; ROUNDTRIP-DAG: ![[VECTORIZE]] = !{!"llvm.loop.vectorize.disable"}
+; ROUNDTRIP-DAG: ![[INNER_COUNT]] = !{!"llvm.loop.unroll.count", i32 2}
+; ROUNDTRIP-DAG: ![[INNER_FOLLOWUP]] = !{!"llvm.loop.unroll.followup_unrolled"}
+
+; // -----
+
; CHECK-DAG: #[[FOLLOWUP:.*]] = #llvm.loop_annotation<disableNonforced = true>
; CHECK-DAG: #[[UNROLL_AND_JAM_ATTR:.*]] = #llvm.loop_unroll_and_jam<disable = false, count = 32 : i32, followupOuter = #[[FOLLOWUP]], followupInner = #[[FOLLOWUP]], followupRemainderOuter = #[[FOLLOWUP]], followupRemainderInner = #[[FOLLOWUP]], followupAll = #[[FOLLOWUP]]>
; CHECK-DAG: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation<unrollAndJam = #[[UNROLL_AND_JAM_ATTR]]>
@@ -182,8 +244,7 @@ end:
!7 = !{!"llvm.loop.unroll_and_jam.followup_remainder_inner", !9}
!8 = !{!"llvm.loop.unroll_and_jam.followup_all", !9}
-!9 = distinct !{!9, !10}
-!10 = !{!"llvm.loop.disable_nonforced"}
+!9 = !{!"llvm.loop.disable_nonforced"}
; // -----
@@ -225,8 +286,7 @@ end:
!5 = !{!"llvm.loop.distribute.followup_fallback", !9}
!6 = !{!"llvm.loop.distribute.followup_all", !9}
-!9 = distinct !{!9, !10}
-!10 = !{!"llvm.loop.disable_nonforced"}
+!9 = !{!"llvm.loop.disable_nonforced"}
; // -----
@@ -347,15 +407,20 @@ end:
; CHECK: #[[SUBPROGRAM:.*]] = #llvm.di_subprogram<
; CHECK: #[[start_loc_fused:.*]] = loc(fused<#[[SUBPROGRAM]]>[#[[start_loc]]])
; CHECK: #[[end_loc_fused:.*]] = loc(fused<#[[SUBPROGRAM]]>[#[[end_loc]]])
+; CHECK: #[[FOLLOWUP:.*]] = #llvm.loop_annotation<mustProgress = true, startLoc = #[[start_loc_fused]], endLoc = #[[end_loc_fused]]>
+; CHECK: #[[UNROLL_ATTR:.*]] = #llvm.loop_unroll<followupUnrolled = #[[FOLLOWUP]]>
; CHECK: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation<
+; CHECK-SAME: unroll = #[[UNROLL_ATTR]]
; CHECK-SAME: mustProgress = true
; CHECK-SAME: startLoc = #[[start_loc_fused]]
; CHECK-SAME: endLoc = #[[end_loc_fused]]
; CHECK-LABEL: @loop_locs
+; ROUNDTRIP-LABEL: @loop_locs(
define void @loop_locs(i64 %n, ptr %A) {
entry:
; CHECK: llvm.br ^{{.*}} loop_annotation = #[[$ANNOT_ATTR]]
+; ROUNDTRIP: br label {{.*}}, !llvm.loop ![[LOC_LOOP:[0-9]+]]
br label %end, !llvm.loop !6
end:
ret void
@@ -370,7 +435,16 @@ end:
!4 = !DILocation(line: 1, column: 2, scope: !3)
!5 = !DILocation(line: 2, column: 2, scope: !3)
-!6 = distinct !{!6, !4, !5, !7}
+!6 = distinct !{!6, !4, !5, !7, !8}
!7 = !{!"llvm.loop.mustprogress"}
+!8 = !{!"llvm.loop.unroll.followup_unrolled", !4, !5, !7}
!999 = !DISubroutineType(types: !1000)
!1000 = !{null}
+
+; Debug locations are direct followup operands too, not named properties to
+; filter out when removing a LoopID wrapper.
+; ROUNDTRIP: ![[LOC_LOOP]] = distinct !{![[LOC_LOOP]], ![[START:[0-9]+]], ![[END:[0-9]+]], ![[PROGRESS:[0-9]+]], ![[FOLLOWUP:[0-9]+]]}
+; ROUNDTRIP-DAG: ![[START]] = !DILocation(line: 1, column: 2, scope:
+; ROUNDTRIP-DAG: ![[END]] = !DILocation(line: 2, column: 2, scope:
+; ROUNDTRIP-DAG: ![[PROGRESS]] = !{!"llvm.loop.mustprogress"}
+; ROUNDTRIP-DAG: ![[FOLLOWUP]] = !{!"llvm.loop.unroll.followup_unrolled", ![[START]], ![[END]], ![[PROGRESS]]}
diff --git a/mlir/test/Target/LLVMIR/loop-metadata.mlir b/mlir/test/Target/LLVMIR/loop-metadata.mlir
index 12daaf6d5d2821..bb8a87ac330822 100644
--- a/mlir/test/Target/LLVMIR/loop-metadata.mlir
+++ b/mlir/test/Target/LLVMIR/loop-metadata.mlir
@@ -53,15 +53,14 @@ llvm.func @vectorizeOptions() {
}
// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
-// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.enable"}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.predicate.enable"}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.scalable.disable"}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.width", i32 16}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_vectorized", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_epilogue", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_all", ![[FOLLOWUP]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_vectorized", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_epilogue", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_all", ![[NON_FORCED]]}
// -----
@@ -92,14 +91,13 @@ llvm.func @unrollOptions() {
}
// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
-// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.disable"}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.count", i32 64}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.runtime.disable", i1 false}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_unrolled", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_remainder", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_all", ![[FOLLOWUP]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_unrolled", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_remainder", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_all", ![[NON_FORCED]]}
// -----
@@ -131,15 +129,14 @@ llvm.func @unrollAndJamOptions() {
}
// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
-// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.enable"}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.count", i32 8}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_inner", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_outer", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_inner", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_all", ![[FOLLOWUP]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_inner", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_outer", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_inner", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_all", ![[NON_FORCED]]}
// -----
@@ -183,13 +180,12 @@ llvm.func @distributeOptions() {
}
// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
-// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.disable"}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_coincident", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_sequential", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_fallback", ![[FOLLOWUP]]}
-// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_all", ![[FOLLOWUP]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_coincident", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_sequential", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_fallback", ![[NON_FORCED]]}
+// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_all", ![[NON_FORCED]]}
// -----
More information about the Mlir-commits
mailing list