Enforce single-operand form for llvm.loop.vectorize.predicate metadata - #213902
Enforce single-operand form for llvm.loop.vectorize.predicate metadata#213902madhur13490 wants to merge 1 commit into
Conversation
|
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-clang-codegen Author: Madhur Amilkanthwar (madhur13490) ChangesReplace the two-operand boolean form !{!"llvm.loop.vectorize.predicate.enable"} The Verifier rejects the two-operand form, AutoUpgrade rewrites old bitcode, and the readers and producers in LLVM, Clang and MLIR are updated. Please refer to RFC: Patch is 35.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/213902.diff 40 Files Affected:
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp
index 499e2287ae84a..45ec2d36eb7a3 100644
--- a/clang/lib/CodeGen/CGLoopInfo.cpp
+++ b/clang/lib/CodeGen/CGLoopInfo.cpp
@@ -228,11 +228,11 @@ clang::CodeGen::LoopInfo::createLoopVectorizeMetadata(
IsVectorPredicateEnabled =
(Attrs.VectorizePredicateEnable == LoopAttributes::Enable);
- Metadata *Vals[] = {
- MDString::get(Ctx, "llvm.loop.vectorize.predicate.enable"),
- ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt1Ty(Ctx),
- IsVectorPredicateEnabled))};
- Args.push_back(MDNode::get(Ctx, Vals));
+ Args.push_back(MDNode::get(
+ Ctx,
+ {MDString::get(Ctx, IsVectorPredicateEnabled
+ ? "llvm.loop.vectorize.predicate.enable"
+ : "llvm.loop.vectorize.predicate.disable")}));
}
// Setting vectorize.width
diff --git a/clang/test/CodeGenCXX/pragma-loop-predicate.cpp b/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
index 8a25ed8de6239..b80c952fb122a 100644
--- a/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
@@ -106,10 +106,10 @@ void test9(int *List, int Length) {
// CHECK-NEXT: [[GEN3]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK-NEXT: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP]], [[GEN6:![0-9]+]], [[GEN3]]}
-// CHECK-NEXT: [[GEN6]] = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+// CHECK-NEXT: [[GEN6]] = !{!"llvm.loop.vectorize.predicate.enable"}
// CHECK-NEXT: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], [[GEN8:![0-9]+]], [[GEN3]]}
-// CHECK-NEXT: [[GEN8]] = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
+// CHECK-NEXT: [[GEN8]] = !{!"llvm.loop.vectorize.predicate.disable"}
// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], [[GEN6]], [[GEN3]]}
diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index 3735039b99977..58318e8a9888a 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -8073,14 +8073,11 @@ is a bit. If the bit operand value is 1 vectorization is enabled. A value of
This metadata selectively enables or disables creating predicated instructions
for the loop, which can enable folding of the scalar epilogue loop into the
-main loop. The first operand is the string
-`llvm.loop.vectorize.predicate.enable` and the second operand is a bit. If
-the bit operand value is 1 predication is enabled. A value of 0 disables
-predication:
+main loop. Each node has a single operand containing the name string:
```llvm
-!0 = !{!"llvm.loop.vectorize.predicate.enable", i1 0}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 1}
+!0 = !{!"llvm.loop.vectorize.predicate.enable"}
+!1 = !{!"llvm.loop.vectorize.predicate.disable"}
```
Additionally, enabling predication implicitly enables vectorization.
diff --git a/llvm/include/llvm/IR/AutoUpgrade.h b/llvm/include/llvm/IR/AutoUpgrade.h
index 423fea4205a80..ed8187ed1c512 100644
--- a/llvm/include/llvm/IR/AutoUpgrade.h
+++ b/llvm/include/llvm/IR/AutoUpgrade.h
@@ -112,12 +112,14 @@ namespace llvm {
/// Check whether a string looks like an old loop attachment tag.
inline bool mayBeOldLoopAttachmentTag(StringRef Name) {
- // "llvm.loop.distribute.enable" is intentionally included: the current
- // single-operand form shares the tag with the removed two-operand form
- // (!{!"llvm.loop.distribute.enable", i1 X}), so we can only decide by
- // inspecting the operands, which happens in upgradeLoopArgument().
+ // "llvm.loop.distribute.enable" and
+ // "llvm.loop.vectorize.predicate.enable" are intentionally included: the
+ // current single-operand form shares the tag with the removed two-operand
+ // form (!{!"...", i1 X}), so we can only decide by inspecting the
+ // operands, which happens in upgradeLoopArgument().
return Name.starts_with("llvm.vectorizer.") ||
- Name == "llvm.loop.distribute.enable";
+ Name == "llvm.loop.distribute.enable" ||
+ Name == "llvm.loop.vectorize.predicate.enable";
}
/// Upgrade the loop attachment metadata node.
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 4502759417c5a..1a3e538c3f8c6 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -7011,16 +7011,32 @@ void llvm::copyModuleAttrToFunctions(Module &M) {
}
}
-// Old two-operand form: !{!"llvm.loop.distribute.enable", i1 X}. The new
-// single-operand form uses "llvm.loop.distribute.enable" for X = true and
-// "llvm.loop.distribute.disable" for X = false.
-static bool isOldDistributeEnable(const MDTuple *T) {
- if (T->getNumOperands() != 2)
- return false;
+namespace {
+// Single-operand tags replacing a removed two-operand form
+// !{!"<Enable>", i1 X}: X = true selects Enable, X = false selects Disable.
+struct BooleanLoopTags {
+ StringLiteral Enable;
+ StringLiteral Disable;
+};
+} // namespace
+
+static constexpr BooleanLoopTags OldBooleanLoopTags[] = {
+ {"llvm.loop.distribute.enable", "llvm.loop.distribute.disable"},
+ {"llvm.loop.vectorize.predicate.enable",
+ "llvm.loop.vectorize.predicate.disable"}};
+
+// Return the replacement tags if \p T still uses a removed two-operand form.
+static const BooleanLoopTags *getOldBooleanLoopTags(const MDTuple *T) {
+ if (T->getNumOperands() != 2 || !mdconst::hasa<ConstantInt>(T->getOperand(1)))
+ return nullptr;
auto *Tag = dyn_cast_or_null<MDString>(T->getOperand(0));
- if (!Tag || Tag->getString() != "llvm.loop.distribute.enable")
- return false;
- return mdconst::hasa<ConstantInt>(T->getOperand(1));
+ if (!Tag)
+ return nullptr;
+ const auto *Tags =
+ find_if(OldBooleanLoopTags, [Tag](const BooleanLoopTags &Candidate) {
+ return Candidate.Enable == Tag->getString();
+ });
+ return Tags == std::end(OldBooleanLoopTags) ? nullptr : Tags;
}
static bool isOldLoopArgument(Metadata *MD) {
@@ -7034,7 +7050,7 @@ static bool isOldLoopArgument(Metadata *MD) {
return false;
if (S->getString().starts_with("llvm.vectorizer."))
return true;
- return isOldDistributeEnable(T);
+ return getOldBooleanLoopTags(T) != nullptr;
}
static MDString *upgradeLoopTag(LLVMContext &C, StringRef OldTag) {
@@ -7061,12 +7077,11 @@ static Metadata *upgradeLoopArgument(Metadata *MD) {
LLVMContext &C = T->getContext();
- // Rewrite the old two-operand distribute form to the single-operand pair.
- if (isOldDistributeEnable(T)) {
+ // Rewrite a removed two-operand boolean form to the single-operand pair.
+ if (const BooleanLoopTags *Tags = getOldBooleanLoopTags(T)) {
bool Enable = !mdconst::extract<ConstantInt>(T->getOperand(1))->isZero();
return MDTuple::get(
- C, {MDString::get(C, Enable ? "llvm.loop.distribute.enable"
- : "llvm.loop.distribute.disable")});
+ C, {MDString::get(C, Enable ? Tags->Enable : Tags->Disable)});
}
if (!OldTag->getString().starts_with("llvm.vectorizer."))
@@ -7090,14 +7105,14 @@ MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) {
if (none_of(T->operands(), isOldLoopArgument))
return &N;
- // Fix the old two-operand llvm.loop.distribute.enable nodes in place: the
- // Verifier rejects any MDNode carrying the distribute tag with more than one
- // operand, so a leftover reference (from the distinct loop-ID) would still
- // trigger a diagnostic. In-place mutation is safe on distinct MDNodes.
+ // Fix the removed two-operand boolean nodes in place: the Verifier rejects
+ // any MDNode carrying those tags with more than one operand, so a leftover
+ // reference (from the distinct loop-ID) would still trigger a diagnostic.
+ // In-place mutation is safe on distinct MDNodes.
if (T->isDistinct()) {
for (unsigned I = 0, E = T->getNumOperands(); I < E; ++I) {
auto *OpT = dyn_cast_or_null<MDTuple>(T->getOperand(I));
- if (OpT && isOldDistributeEnable(OpT))
+ if (OpT && getOldBooleanLoopTags(OpT))
T->replaceOperandWith(I, upgradeLoopArgument(OpT));
}
if (none_of(T->operands(), isOldLoopArgument))
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index c21b8c427ea46..2b72916ff40b2 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1017,6 +1017,15 @@ void Verifier::visitMDNode(const MDNode &BaseMD,
"Expected one operand for llvm.loop.distribute metadata",
CurrentMD);
+ // Enforce the single-operand form of the vectorize predication metadata.
+ if (CurrentMD->getNumOperands() > 0 &&
+ (CurrentMD->getOperand(0).equalsStr(
+ "llvm.loop.vectorize.predicate.enable") ||
+ CurrentMD->getOperand(0).equalsStr(
+ "llvm.loop.vectorize.predicate.disable")))
+ Check(CurrentMD->getNumOperands() == 1,
+ "Expecting only the metadata name", CurrentMD);
+
// Check these last, so we diagnose problems in operands first.
Check(!CurrentMD->isTemporary(), "Expected no forward declarations!",
CurrentMD);
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 8d875b2b6e492..e1afd87f15fc3 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -287,6 +287,14 @@ void LoopVectorizeHints::getHintsFromMetadata() {
// Check if the hint starts with the loop metadata prefix.
StringRef Name = S->getString();
+ // The single-operand enable/disable pair carries no argument.
+ if (Args.empty()) {
+ if (Name == "llvm.loop.vectorize.predicate.enable")
+ Predicate.Value = FK_Enabled;
+ else if (Name == "llvm.loop.vectorize.predicate.disable")
+ Predicate.Value = FK_Disabled;
+ continue;
+ }
if (Args.size() == 1)
setHint(Name, Args[0]);
}
diff --git a/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll
new file mode 100644
index 0000000000000..20e1f264e559c
--- /dev/null
+++ b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll
@@ -0,0 +1,37 @@
+; Test that older bitcode carrying the two-operand form of
+; "llvm.loop.vectorize.predicate.enable" is auto-upgraded to the
+; single-operand enable/disable pair on load.
+;
+; RUN: llvm-dis < %s.bc | FileCheck %s
+; RUN: verify-uselistorder < %s.bc
+
+define void @enable_true() {
+entry:
+ br label %body
+body:
+ br i1 0, label %body, label %exit, !llvm.loop !0
+exit:
+ ret void
+}
+
+define void @enable_false() {
+entry:
+ br label %body
+body:
+ br i1 0, label %body, label %exit, !llvm.loop !2
+exit:
+ ret void
+}
+
+; i1 true -> single-operand enable.
+; i1 false -> disable.
+; CHECK: !{!"llvm.loop.vectorize.predicate.enable"}
+; CHECK: !{!"llvm.loop.vectorize.predicate.disable"}
+; The old two-operand nodes must be gone from the module.
+; CHECK-NOT: llvm.loop.vectorize.predicate.enable", i1
+; CHECK-NOT: llvm.loop.vectorize.predicate.disable", i1
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!2 = distinct !{!2, !3}
+!3 = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
diff --git a/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll.bc b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll.bc
new file mode 100644
index 0000000000000..d8de6672e251b
Binary files /dev/null and b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll.bc differ
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll b/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll
index 1138b19bd3471..c68421ac4a2a4 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll
@@ -528,7 +528,7 @@ exit:
!0 = distinct !{!0, !1}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!1 = !{!"llvm.loop.vectorize.predicate.enable"}
!2 = !{!"branch_weights", i32 10, i32 30}
;.
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll
index 2f27092622192..80c5d3a89db8e 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll
@@ -447,7 +447,7 @@ exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll
index 0985d7f052a90..dbb541eb032a6 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll
@@ -393,7 +393,7 @@ for.exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
attributes #1 = { "target-features"="+neon" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll
index f0f9e8e74b3f5..6de37a2dc1dc4 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll
@@ -2394,5 +2394,5 @@ exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll
index 09e5959f7083c..0e09f6b5fd10c 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll
@@ -2691,7 +2691,7 @@ for.body:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
attributes #1 = { vscale_range(1,16) "target-features"="+neon,+dotprod,+sve" "target-cpu"="neoverse-v2" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll
index dd21d1994d95d..947c6625e9742 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll
@@ -523,7 +523,7 @@ for.exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll
index 03938490e465c..9aa27cee2ecb8 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll
@@ -1285,7 +1285,7 @@ exit:
!0 = distinct !{!0, !1}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!1 = !{!"llvm.loop.vectorize.predicate.enable"}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
attributes #1 = { vscale_range(1,16) "target-features"="+neon,+dotprod,+sve" "target-cpu"="neoverse-v2" }
attributes #2 = { "target-features"="+neon,+dotprod" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll b/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll
index 363223a66f398..72c225127fb9f 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll
@@ -370,7 +370,7 @@ attributes #1 = { "target-cpu"="neoverse-v2" }
!0 = distinct !{!0, !1, !2, !3}
!1 = !{!"llvm.loop.mustprogress"}
-!2 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!2 = !{!"llvm.loop.vectorize.predicate.enable"}
!3 = !{!"llvm.loop.vectorize.enable", i1 true}
; BFI computes if is taken 20 times, and loop 32 times. Make sure we round the
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll b/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll
index 4b2e5d051730b..8ce6605696529 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll
@@ -1417,5 +1417,5 @@ for.cond.cleanup:
!9 = !{!"llvm.loop.interleave.count", i32 1}
!10 = !{!"llvm.loop.interleave.count", i32 4}
!11 = !{!"llvm.loop.vectorize.enable", i1 true}
-!12 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!12 = !{!"llvm.loop.vectorize.predicate.enable"}
!13 = distinct !{!13, !6, !9, !11}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll b/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll
index 2ec48b25af5b5..b6bef8c3fe15c 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll
@@ -877,7 +877,7 @@ attributes #0 = { "target-features"="+sve2" vscale_range(1,16) }
!0 = distinct !{!0, !1}
!1 = !{!"llvm.loop.interleave.count", i32 2}
!2 = distinct !{!2, !3}
-!3 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!3 = !{!"llvm.loop.vectorize.predicate.enable"}
!4 = distinct !{!4, !5}
!5 = !{!"llvm.loop.interleave.count", i32 1}
!6 = !{!7}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll b/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll
index 0b783375a33e1..d323dce104e66 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll
@@ -150,7 +150,7 @@ while.end.loopexit:
}
!0 = distinct !{!0, !1, !2, !3, !4}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!1 = !{!"llvm.loop.vectorize.predicate.enable"}
!2 = !{!"llvm.loop.vectorize.scalable.enable", i1 true}
!3 = !{!"llvm.loop.interleave.count", i32 1}
!4 = !{!"llvm.loop.vectorize.width", i32 4}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll b/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll
index fbc313eddea8a..912b6a4215590 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll
@@ -55,7 +55,7 @@ attributes #0 = { "target-cpu"="neoverse-v2" }
!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.vectorize.enable", i1 true}
-!2 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!2 = !{!"llvm.loop.vectorize.predicate.enable"}
;.
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
diff --git a/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll b/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll
index 1b5db04061631..7e7b96d8a4113 100644
--- a/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll
+++ b/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll
@@ -425,7 +425,7 @@ attributes #0 = { nofree norecurse nounwind "target-features"="+armv8.1-m.main,+
!6 = !{!"llvm.loop.vectorize.enable", i1 true}
!7 = distinct !{!7, !8}
-!8 = !{!"llvm.loop.vectorize.predi...
[truncated]
|
|
@llvm/pr-subscribers-mlir-llvm Author: Madhur Amilkanthwar (madhur13490) ChangesReplace the two-operand boolean form !{!"llvm.loop.vectorize.predicate.enable"} The Verifier rejects the two-operand form, AutoUpgrade rewrites old bitcode, and the readers and producers in LLVM, Clang and MLIR are updated. Please refer to RFC: Patch is 35.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/213902.diff 40 Files Affected:
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp
index 499e2287ae84a..45ec2d36eb7a3 100644
--- a/clang/lib/CodeGen/CGLoopInfo.cpp
+++ b/clang/lib/CodeGen/CGLoopInfo.cpp
@@ -228,11 +228,11 @@ clang::CodeGen::LoopInfo::createLoopVectorizeMetadata(
IsVectorPredicateEnabled =
(Attrs.VectorizePredicateEnable == LoopAttributes::Enable);
- Metadata *Vals[] = {
- MDString::get(Ctx, "llvm.loop.vectorize.predicate.enable"),
- ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt1Ty(Ctx),
- IsVectorPredicateEnabled))};
- Args.push_back(MDNode::get(Ctx, Vals));
+ Args.push_back(MDNode::get(
+ Ctx,
+ {MDString::get(Ctx, IsVectorPredicateEnabled
+ ? "llvm.loop.vectorize.predicate.enable"
+ : "llvm.loop.vectorize.predicate.disable")}));
}
// Setting vectorize.width
diff --git a/clang/test/CodeGenCXX/pragma-loop-predicate.cpp b/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
index 8a25ed8de6239..b80c952fb122a 100644
--- a/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
@@ -106,10 +106,10 @@ void test9(int *List, int Length) {
// CHECK-NEXT: [[GEN3]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK-NEXT: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP]], [[GEN6:![0-9]+]], [[GEN3]]}
-// CHECK-NEXT: [[GEN6]] = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+// CHECK-NEXT: [[GEN6]] = !{!"llvm.loop.vectorize.predicate.enable"}
// CHECK-NEXT: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], [[GEN8:![0-9]+]], [[GEN3]]}
-// CHECK-NEXT: [[GEN8]] = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
+// CHECK-NEXT: [[GEN8]] = !{!"llvm.loop.vectorize.predicate.disable"}
// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], [[GEN6]], [[GEN3]]}
diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index 3735039b99977..58318e8a9888a 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -8073,14 +8073,11 @@ is a bit. If the bit operand value is 1 vectorization is enabled. A value of
This metadata selectively enables or disables creating predicated instructions
for the loop, which can enable folding of the scalar epilogue loop into the
-main loop. The first operand is the string
-`llvm.loop.vectorize.predicate.enable` and the second operand is a bit. If
-the bit operand value is 1 predication is enabled. A value of 0 disables
-predication:
+main loop. Each node has a single operand containing the name string:
```llvm
-!0 = !{!"llvm.loop.vectorize.predicate.enable", i1 0}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 1}
+!0 = !{!"llvm.loop.vectorize.predicate.enable"}
+!1 = !{!"llvm.loop.vectorize.predicate.disable"}
```
Additionally, enabling predication implicitly enables vectorization.
diff --git a/llvm/include/llvm/IR/AutoUpgrade.h b/llvm/include/llvm/IR/AutoUpgrade.h
index 423fea4205a80..ed8187ed1c512 100644
--- a/llvm/include/llvm/IR/AutoUpgrade.h
+++ b/llvm/include/llvm/IR/AutoUpgrade.h
@@ -112,12 +112,14 @@ namespace llvm {
/// Check whether a string looks like an old loop attachment tag.
inline bool mayBeOldLoopAttachmentTag(StringRef Name) {
- // "llvm.loop.distribute.enable" is intentionally included: the current
- // single-operand form shares the tag with the removed two-operand form
- // (!{!"llvm.loop.distribute.enable", i1 X}), so we can only decide by
- // inspecting the operands, which happens in upgradeLoopArgument().
+ // "llvm.loop.distribute.enable" and
+ // "llvm.loop.vectorize.predicate.enable" are intentionally included: the
+ // current single-operand form shares the tag with the removed two-operand
+ // form (!{!"...", i1 X}), so we can only decide by inspecting the
+ // operands, which happens in upgradeLoopArgument().
return Name.starts_with("llvm.vectorizer.") ||
- Name == "llvm.loop.distribute.enable";
+ Name == "llvm.loop.distribute.enable" ||
+ Name == "llvm.loop.vectorize.predicate.enable";
}
/// Upgrade the loop attachment metadata node.
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 4502759417c5a..1a3e538c3f8c6 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -7011,16 +7011,32 @@ void llvm::copyModuleAttrToFunctions(Module &M) {
}
}
-// Old two-operand form: !{!"llvm.loop.distribute.enable", i1 X}. The new
-// single-operand form uses "llvm.loop.distribute.enable" for X = true and
-// "llvm.loop.distribute.disable" for X = false.
-static bool isOldDistributeEnable(const MDTuple *T) {
- if (T->getNumOperands() != 2)
- return false;
+namespace {
+// Single-operand tags replacing a removed two-operand form
+// !{!"<Enable>", i1 X}: X = true selects Enable, X = false selects Disable.
+struct BooleanLoopTags {
+ StringLiteral Enable;
+ StringLiteral Disable;
+};
+} // namespace
+
+static constexpr BooleanLoopTags OldBooleanLoopTags[] = {
+ {"llvm.loop.distribute.enable", "llvm.loop.distribute.disable"},
+ {"llvm.loop.vectorize.predicate.enable",
+ "llvm.loop.vectorize.predicate.disable"}};
+
+// Return the replacement tags if \p T still uses a removed two-operand form.
+static const BooleanLoopTags *getOldBooleanLoopTags(const MDTuple *T) {
+ if (T->getNumOperands() != 2 || !mdconst::hasa<ConstantInt>(T->getOperand(1)))
+ return nullptr;
auto *Tag = dyn_cast_or_null<MDString>(T->getOperand(0));
- if (!Tag || Tag->getString() != "llvm.loop.distribute.enable")
- return false;
- return mdconst::hasa<ConstantInt>(T->getOperand(1));
+ if (!Tag)
+ return nullptr;
+ const auto *Tags =
+ find_if(OldBooleanLoopTags, [Tag](const BooleanLoopTags &Candidate) {
+ return Candidate.Enable == Tag->getString();
+ });
+ return Tags == std::end(OldBooleanLoopTags) ? nullptr : Tags;
}
static bool isOldLoopArgument(Metadata *MD) {
@@ -7034,7 +7050,7 @@ static bool isOldLoopArgument(Metadata *MD) {
return false;
if (S->getString().starts_with("llvm.vectorizer."))
return true;
- return isOldDistributeEnable(T);
+ return getOldBooleanLoopTags(T) != nullptr;
}
static MDString *upgradeLoopTag(LLVMContext &C, StringRef OldTag) {
@@ -7061,12 +7077,11 @@ static Metadata *upgradeLoopArgument(Metadata *MD) {
LLVMContext &C = T->getContext();
- // Rewrite the old two-operand distribute form to the single-operand pair.
- if (isOldDistributeEnable(T)) {
+ // Rewrite a removed two-operand boolean form to the single-operand pair.
+ if (const BooleanLoopTags *Tags = getOldBooleanLoopTags(T)) {
bool Enable = !mdconst::extract<ConstantInt>(T->getOperand(1))->isZero();
return MDTuple::get(
- C, {MDString::get(C, Enable ? "llvm.loop.distribute.enable"
- : "llvm.loop.distribute.disable")});
+ C, {MDString::get(C, Enable ? Tags->Enable : Tags->Disable)});
}
if (!OldTag->getString().starts_with("llvm.vectorizer."))
@@ -7090,14 +7105,14 @@ MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) {
if (none_of(T->operands(), isOldLoopArgument))
return &N;
- // Fix the old two-operand llvm.loop.distribute.enable nodes in place: the
- // Verifier rejects any MDNode carrying the distribute tag with more than one
- // operand, so a leftover reference (from the distinct loop-ID) would still
- // trigger a diagnostic. In-place mutation is safe on distinct MDNodes.
+ // Fix the removed two-operand boolean nodes in place: the Verifier rejects
+ // any MDNode carrying those tags with more than one operand, so a leftover
+ // reference (from the distinct loop-ID) would still trigger a diagnostic.
+ // In-place mutation is safe on distinct MDNodes.
if (T->isDistinct()) {
for (unsigned I = 0, E = T->getNumOperands(); I < E; ++I) {
auto *OpT = dyn_cast_or_null<MDTuple>(T->getOperand(I));
- if (OpT && isOldDistributeEnable(OpT))
+ if (OpT && getOldBooleanLoopTags(OpT))
T->replaceOperandWith(I, upgradeLoopArgument(OpT));
}
if (none_of(T->operands(), isOldLoopArgument))
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index c21b8c427ea46..2b72916ff40b2 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1017,6 +1017,15 @@ void Verifier::visitMDNode(const MDNode &BaseMD,
"Expected one operand for llvm.loop.distribute metadata",
CurrentMD);
+ // Enforce the single-operand form of the vectorize predication metadata.
+ if (CurrentMD->getNumOperands() > 0 &&
+ (CurrentMD->getOperand(0).equalsStr(
+ "llvm.loop.vectorize.predicate.enable") ||
+ CurrentMD->getOperand(0).equalsStr(
+ "llvm.loop.vectorize.predicate.disable")))
+ Check(CurrentMD->getNumOperands() == 1,
+ "Expecting only the metadata name", CurrentMD);
+
// Check these last, so we diagnose problems in operands first.
Check(!CurrentMD->isTemporary(), "Expected no forward declarations!",
CurrentMD);
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 8d875b2b6e492..e1afd87f15fc3 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -287,6 +287,14 @@ void LoopVectorizeHints::getHintsFromMetadata() {
// Check if the hint starts with the loop metadata prefix.
StringRef Name = S->getString();
+ // The single-operand enable/disable pair carries no argument.
+ if (Args.empty()) {
+ if (Name == "llvm.loop.vectorize.predicate.enable")
+ Predicate.Value = FK_Enabled;
+ else if (Name == "llvm.loop.vectorize.predicate.disable")
+ Predicate.Value = FK_Disabled;
+ continue;
+ }
if (Args.size() == 1)
setHint(Name, Args[0]);
}
diff --git a/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll
new file mode 100644
index 0000000000000..20e1f264e559c
--- /dev/null
+++ b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll
@@ -0,0 +1,37 @@
+; Test that older bitcode carrying the two-operand form of
+; "llvm.loop.vectorize.predicate.enable" is auto-upgraded to the
+; single-operand enable/disable pair on load.
+;
+; RUN: llvm-dis < %s.bc | FileCheck %s
+; RUN: verify-uselistorder < %s.bc
+
+define void @enable_true() {
+entry:
+ br label %body
+body:
+ br i1 0, label %body, label %exit, !llvm.loop !0
+exit:
+ ret void
+}
+
+define void @enable_false() {
+entry:
+ br label %body
+body:
+ br i1 0, label %body, label %exit, !llvm.loop !2
+exit:
+ ret void
+}
+
+; i1 true -> single-operand enable.
+; i1 false -> disable.
+; CHECK: !{!"llvm.loop.vectorize.predicate.enable"}
+; CHECK: !{!"llvm.loop.vectorize.predicate.disable"}
+; The old two-operand nodes must be gone from the module.
+; CHECK-NOT: llvm.loop.vectorize.predicate.enable", i1
+; CHECK-NOT: llvm.loop.vectorize.predicate.disable", i1
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!2 = distinct !{!2, !3}
+!3 = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
diff --git a/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll.bc b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll.bc
new file mode 100644
index 0000000000000..d8de6672e251b
Binary files /dev/null and b/llvm/test/Bitcode/upgrade-loop-vectorize-predicate-enable.ll.bc differ
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll b/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll
index 1138b19bd3471..c68421ac4a2a4 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/low_trip_count_predicates.ll
@@ -528,7 +528,7 @@ exit:
!0 = distinct !{!0, !1}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!1 = !{!"llvm.loop.vectorize.predicate.enable"}
!2 = !{!"branch_weights", i32 10, i32 30}
;.
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll
index 2f27092622192..80c5d3a89db8e 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-epilogue.ll
@@ -447,7 +447,7 @@ exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll
index 0985d7f052a90..dbb541eb032a6 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-mixed.ll
@@ -393,7 +393,7 @@ for.exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
attributes #1 = { "target-features"="+neon" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll
index f0f9e8e74b3f5..6de37a2dc1dc4 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product-neon.ll
@@ -2394,5 +2394,5 @@ exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll
index 09e5959f7083c..0e09f6b5fd10c 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-dot-product.ll
@@ -2691,7 +2691,7 @@ for.body:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
attributes #1 = { vscale_range(1,16) "target-features"="+neon,+dotprod,+sve" "target-cpu"="neoverse-v2" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll
index dd21d1994d95d..947c6625e9742 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub.ll
@@ -523,7 +523,7 @@ for.exit:
!7 = distinct !{!7, !8, !9, !10}
!8 = !{!"llvm.loop.mustprogress"}
-!9 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!9 = !{!"llvm.loop.vectorize.predicate.enable"}
!10 = !{!"llvm.loop.vectorize.enable", i1 true}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll
index 03938490e465c..9aa27cee2ecb8 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce.ll
@@ -1285,7 +1285,7 @@ exit:
!0 = distinct !{!0, !1}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!1 = !{!"llvm.loop.vectorize.predicate.enable"}
attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
attributes #1 = { vscale_range(1,16) "target-features"="+neon,+dotprod,+sve" "target-cpu"="neoverse-v2" }
attributes #2 = { "target-features"="+neon,+dotprod" }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll b/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll
index 363223a66f398..72c225127fb9f 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/predicated-costs.ll
@@ -370,7 +370,7 @@ attributes #1 = { "target-cpu"="neoverse-v2" }
!0 = distinct !{!0, !1, !2, !3}
!1 = !{!"llvm.loop.mustprogress"}
-!2 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!2 = !{!"llvm.loop.vectorize.predicate.enable"}
!3 = !{!"llvm.loop.vectorize.enable", i1 true}
; BFI computes if is taken 20 times, and loop 32 times. Make sure we round the
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll b/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll
index 4b2e5d051730b..8ce6605696529 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/strict-fadd.ll
@@ -1417,5 +1417,5 @@ for.cond.cleanup:
!9 = !{!"llvm.loop.interleave.count", i32 1}
!10 = !{!"llvm.loop.interleave.count", i32 4}
!11 = !{!"llvm.loop.vectorize.enable", i1 true}
-!12 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!12 = !{!"llvm.loop.vectorize.predicate.enable"}
!13 = distinct !{!13, !6, !9, !11}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll b/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll
index 2ec48b25af5b5..b6bef8c3fe15c 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/sve2-histcnt.ll
@@ -877,7 +877,7 @@ attributes #0 = { "target-features"="+sve2" vscale_range(1,16) }
!0 = distinct !{!0, !1}
!1 = !{!"llvm.loop.interleave.count", i32 2}
!2 = distinct !{!2, !3}
-!3 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!3 = !{!"llvm.loop.vectorize.predicate.enable"}
!4 = distinct !{!4, !5}
!5 = !{!"llvm.loop.interleave.count", i32 1}
!6 = !{!7}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll b/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll
index 0b783375a33e1..d323dce104e66 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/tail-folding-styles.ll
@@ -150,7 +150,7 @@ while.end.loopexit:
}
!0 = distinct !{!0, !1, !2, !3, !4}
-!1 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!1 = !{!"llvm.loop.vectorize.predicate.enable"}
!2 = !{!"llvm.loop.vectorize.scalable.enable", i1 true}
!3 = !{!"llvm.loop.interleave.count", i32 1}
!4 = !{!"llvm.loop.vectorize.width", i32 4}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll b/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll
index fbc313eddea8a..912b6a4215590 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll
@@ -55,7 +55,7 @@ attributes #0 = { "target-cpu"="neoverse-v2" }
!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.vectorize.enable", i1 true}
-!2 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+!2 = !{!"llvm.loop.vectorize.predicate.enable"}
;.
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
diff --git a/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll b/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll
index 1b5db04061631..7e7b96d8a4113 100644
--- a/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll
+++ b/llvm/test/Transforms/LoopVectorize/ARM/prefer-tail-loop-folding.ll
@@ -425,7 +425,7 @@ attributes #0 = { nofree norecurse nounwind "target-features"="+armv8.1-m.main,+
!6 = !{!"llvm.loop.vectorize.enable", i1 true}
!7 = distinct !{!7, !8}
-!8 = !{!"llvm.loop.vectorize.predi...
[truncated]
|
Replace the two-operand boolean form
!{!"llvm.loop.vectorize.predicate.enable", i1 0/1} with a single-operand
enable/disable pair:
!{!"llvm.loop.vectorize.predicate.enable"}
!{!"llvm.loop.vectorize.predicate.disable"}
The Verifier rejects the two-operand form, AutoUpgrade rewrites old
bitcode, and the readers and producers in LLVM, Clang and MLIR are
updated.
Please refer to RFC:
https://discourse.llvm.org/t/rfc-enforce-single-operand-format-for-all-enable-metadata-nodes/90571/
19ad2d7 to
31cd99c
Compare
| static bool isOldVectorizeEnable(const MDTuple *T) { | ||
| if (T->getNumOperands() != 2) | ||
| return false; | ||
| // Return the replacement tags if \p T still uses a removed two-operand form. |
There was a problem hiding this comment.
| // Return the replacement tags if \p T still uses a removed two-operand form. | |
| /// Return the replacement tags if \p T still uses a removed two-operand form. |
[nit]
| {"llvm.loop.vectorize.predicate.enable", | ||
| "llvm.loop.vectorize.predicate.disable"}}; | ||
|
|
||
| // Return the replacement tags for the enable tag \p Name, or nullptr. |
There was a problem hiding this comment.
| // Return the replacement tags for the enable tag \p Name, or nullptr. | |
| /// Return the replacement tags for the enable tag \p Name, or nullptr. |
[nit]
| // enable/disable pair. | ||
| if (isOldVectorizeEnable(T)) | ||
| return makeVectorizeEnableNode(C, T->getOperand(1)); | ||
| // Rewrite a removed two-operand boolean form to the single-operand pair. |
There was a problem hiding this comment.
| // Rewrite a removed two-operand boolean form to the single-operand pair. | |
| /// Rewrite a removed two-operand boolean form to the single-operand pair. |
[nit]
| /// Emits the single-operand node of an enable/disable pair. As in | ||
| /// convertBoolNode, \p negated ^ the attribute value is the enable bit. |
There was a problem hiding this comment.
Add explantion that its ternary logic: If BoolAttr is unset, don't add any node.
| // Enforce the single-operand form of the vectorize predication metadata. | ||
| if (CurrentMD->getNumOperands() > 0 && | ||
| (CurrentMD->getOperand(0).equalsStr( | ||
| "llvm.loop.vectorize.predicate.enable") || | ||
| CurrentMD->getOperand(0).equalsStr( | ||
| "llvm.loop.vectorize.predicate.disable"))) | ||
| Check(CurrentMD->getNumOperands() == 1, | ||
| "Expecting only the metadata name", CurrentMD); | ||
|
|
There was a problem hiding this comment.
Could this be generalized with the code above?
| return Name.starts_with("llvm.vectorizer.") || | ||
| Name == "llvm.loop.distribute.enable" || | ||
| Name == "llvm.loop.vectorize.enable"; | ||
| Name == "llvm.loop.vectorize.enable" || | ||
| Name == "llvm.loop.vectorize.predicate.enable"; |
There was a problem hiding this comment.
Use the OldBooleanLoopTags list here?
| Hint *Hints[] = {&Width, &Interleave, &Force, | ||
| &IsVectorized, &Predicate, &Scalable}; |
There was a problem hiding this comment.
Are these stil needed? Predicate.Name is us used only be the old mechanism
| !1 = !{!"llvm.loop.vectorize.disable"} | ||
| ``` | ||
|
|
||
| #### '`llvm.loop.vectorize.predicate.enable`' Metadata |
There was a problem hiding this comment.
| #### '`llvm.loop.vectorize.predicate.enable`' and '`llvm.loop.vectorize.predicate.disable`' Metadata |
Replace the two-operand boolean form
!{!"llvm.loop.vectorize.predicate.enable", i1 0/1} with a single-operand enable/disable pair:
!{!"llvm.loop.vectorize.predicate.enable"}
!{!"llvm.loop.vectorize.predicate.disable"}
The Verifier rejects the two-operand form, AutoUpgrade rewrites old bitcode, and the readers and producers in LLVM, Clang and MLIR are updated.
Please refer to RFC:
https://discourse.llvm.org/t/rfc-enforce-single-operand-format-for-all-enable-metadata-nodes/90571/
Assisted by AI