[llvm] [AMDGPU] Generalize generic-target numeric property validation (PR #223177)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 03:27:08 PDT 2026


================
@@ -476,60 +478,183 @@ collectVisibleFeatures(const Record *GPU,
   return Visible;
 }
 
+namespace {
+enum class GenericNumericComparison { AtLeast, AtMost, Equal };
+
+struct NumericProperty {
+  int64_t DefaultValue;
+  GenericNumericComparison Comparison;
+};
+
+using NumericPropertyMap = MapVector<StringRef, NumericProperty>;
+} // namespace
+
+// The value of the features setting FieldName in GPU's closure. Preserve the
+// check that such features agree: some backend consumers inspect individual
+// feature bits instead of using SubtargetFeature's maximum-value rule.
+// If no feature sets the field, use its property default, or
+// UnregisteredDefault for fields without metadata.
+static int64_t getFeatureValue(const Record *GPU,
+                               ArrayRef<const Record *> Closure,
+                               StringRef FieldName,
+                               const NumericPropertyMap &Properties,
+                               int64_t UnregisteredDefault = 0) {
+  auto It = Properties.find(FieldName);
+  int64_t Value =
+      It == Properties.end() ? UnregisteredDefault : It->second.DefaultValue;
+
+  const Record *Found = nullptr;
+  for (const Record *F : Closure) {
+    if (F->getValueAsString("FieldName") != FieldName)
+      continue;
+
+    int64_t V;
+    if (!to_integer(F->getValueAsString("Value"), V)) {
+      PrintFatalError(F->getLoc(), "feature '" + F->getValueAsString("Name") +
+                                       "' must have an integer value");
+    }
+    if (Found && V != Value) {
+      PrintFatalError(GPU->getLoc(),
+                      "GPU '" + GPU->getValueAsString("Name") +
+                          "' gets conflicting '" + FieldName +
+                          "' values from '" + Found->getValueAsString("Name") +
+                          "' and '" + F->getValueAsString("Name") + "'");
+    }
+    Found = F;
+    Value = V;
+  }
+  return Value;
+}
+
+static NumericPropertyMap collectNumericProperties(const RecordKeeper &RK) {
+  NumericPropertyMap Properties;
+  for (const Record *R :
+       RK.getAllDerivedDefinitionsIfDefined("AMDGPUGenericNumericProperty")) {
+    StringRef FieldName = R->getValueAsString("FieldName");
+    if (FieldName.empty())
+      PrintFatalError(R->getLoc(), "numeric property must have a field name");
+
+    StringRef ComparisonName = R->getValueAsDef("GenericComparison")->getName();
+    GenericNumericComparison Comparison;
+    if (ComparisonName == "AMDGPUGenericAtLeast")
+      Comparison = GenericNumericComparison::AtLeast;
+    else if (ComparisonName == "AMDGPUGenericAtMost")
+      Comparison = GenericNumericComparison::AtMost;
+    else if (ComparisonName == "AMDGPUGenericEqual")
----------------
arsenm wrote:

What case is this useful for? I would expect we have cases for merge min and merge max 

https://github.com/llvm/llvm-project/pull/223177


More information about the llvm-commits mailing list