xref: /llvm-project/mlir/test/mlir-tblgen/constraint-unique.td (revision db791b278a414fb6df1acc1799adcf11d8fb9169)
1// RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s
2
3include "mlir/IR/OpBase.td"
4
5def Test_Dialect : Dialect {
6  let name = "test";
7  let usePropertiesForAttributes = 0;
8}
9
10class NS_Op<string mnemonic, list<Trait> traits = []> :
11    Op<Test_Dialect, mnemonic, traits>;
12
13/// Test unique'ing of type, attribute, successor, and region constraints.
14
15def ATypePred : CPred<"typePred($_self, $_op)">;
16def AType : Type<ATypePred, "a type">;
17def OtherType : Type<ATypePred, "another type">;
18
19def AnAttrPred : CPred<"attrPred($_self, $_op)">;
20def AnAttr : Attr<AnAttrPred, "an attribute">;
21def OtherAttr : Attr<AnAttrPred, "another attribute">;
22
23def ASuccessorPred : CPred<"successorPred($_self, $_op)">;
24def ASuccessor : Successor<ASuccessorPred, "a successor">;
25def OtherSuccessor : Successor<ASuccessorPred, "another successor">;
26
27def ARegionPred : CPred<"regionPred($_self, $_op)">;
28def ARegion : Region<ARegionPred, "a region">;
29def OtherRegion : Region<ARegionPred, "another region">;
30
31// OpA and OpB have the same type, attribute, successor, and region constraints.
32
33def OpA : NS_Op<"op_a"> {
34  let arguments = (ins AType:$a, AnAttr:$b);
35  let results = (outs AType:$ret);
36  let successors = (successor ASuccessor:$c);
37  let regions = (region ARegion:$d);
38}
39
40def OpB : NS_Op<"op_b"> {
41  let arguments = (ins AType:$a, AnAttr:$b);
42  let successors = (successor ASuccessor:$c);
43  let regions = (region ARegion:$d);
44}
45
46// OpC has the same type, attribute, successor, and region predicates but has
47// difference descriptions for them.
48
49def OpC : NS_Op<"op_c"> {
50  let arguments = (ins OtherType:$a, OtherAttr:$b);
51  let results = (outs OtherType:$ret);
52  let successors = (successor OtherSuccessor:$c);
53  let regions = (region OtherRegion:$d);
54}
55
56/// Test that a type contraint was generated.
57// CHECK:    static ::llvm::LogicalResult [[$A_TYPE_CONSTRAINT:__mlir_ods_local_type_constraint.*]](
58// CHECK:      if (!((typePred(type, *op)))) {
59// CHECK-NEXT:   return op->emitOpError(valueKind) << " #" << valueIndex
60// CHECK-NEXT:       << " must be a type, but got " << type;
61
62/// Test that duplicate type constraint was not generated.
63// CHECK-NOT:        << " must be a type, but got " << type;
64
65/// Test that a type constraint with a different description was generated.
66// CHECK:    static ::llvm::LogicalResult [[$O_TYPE_CONSTRAINT:__mlir_ods_local_type_constraint.*]](
67// CHECK:      if (!((typePred(type, *op)))) {
68// CHECK-NEXT:   return op->emitOpError(valueKind) << " #" << valueIndex
69// CHECK-NEXT:       << " must be another type, but got " << type;
70
71/// Test that an attribute contraint was generated.
72// CHECK:    static ::llvm::LogicalResult [[$A_ATTR_CONSTRAINT:__mlir_ods_local_attr_constraint.*]](
73// CHECK:      if (attr && !((attrPred(attr, *op))))
74// CHECK-NEXT:   return emitError() << "attribute '" << attrName
75// CHECK-NEXT:       << "' failed to satisfy constraint: an attribute";
76
77/// Test that duplicate attribute constraint was not generated.
78// CHECK-NOT:        << "' failed to satisfy constraint: an attribute";
79
80/// Test that a attribute constraint with a different description was generated.
81// CHECK:    static ::llvm::LogicalResult [[$O_ATTR_CONSTRAINT:__mlir_ods_local_attr_constraint.*]](
82// CHECK:    static ::llvm::LogicalResult [[$O_ATTR_CONSTRAINT:__mlir_ods_local_attr_constraint.*]](
83// CHECK:      if (attr && !((attrPred(attr, *op))))
84// CHECK-NEXT:   return emitError() << "attribute '" << attrName
85// CHECK-NEXT:       << "' failed to satisfy constraint: another attribute";
86
87/// Test that a successor contraint was generated.
88// CHECK:    static ::llvm::LogicalResult [[$A_SUCCESSOR_CONSTRAINT:__mlir_ods_local_successor_constraint.*]](
89// CHECK:      if (!((successorPred(successor, *op)))) {
90// CHECK-NEXT:   return op->emitOpError("successor #") << successorIndex << " ('"
91// CHECK-NEXT:       << successorName << ")' failed to verify constraint: a successor";
92
93/// Test that duplicate successor constraint was not generated.
94// CHECK-NOT:        << successorName << ")' failed to verify constraint: a successor";
95
96/// Test that a successor constraint with a different description was generated.
97// CHECK:    static ::llvm::LogicalResult [[$O_SUCCESSOR_CONSTRAINT:__mlir_ods_local_successor_constraint.*]](
98// CHECK:      if (!((successorPred(successor, *op)))) {
99// CHECK-NEXT:   return op->emitOpError("successor #") << successorIndex << " ('"
100// CHECK-NEXT:       << successorName << ")' failed to verify constraint: another successor";
101
102/// Test that a region contraint was generated.
103// CHECK:    static ::llvm::LogicalResult [[$A_REGION_CONSTRAINT:__mlir_ods_local_region_constraint.*]](
104// CHECK:      if (!((regionPred(region, *op)))) {
105// CHECK-NEXT:   return op->emitOpError("region #") << regionIndex
106// CHECK-NEXT:       << (regionName.empty() ? " " : " ('" + regionName + "') ")
107// CHECK-NEXT:       << "failed to verify constraint: a region";
108
109/// Test that duplicate region constraint was not generated.
110// CHECK-NOT:        << "failed to verify constraint: a region";
111
112/// Test that a region constraint with a different description was generated.
113// CHECK:    static ::llvm::LogicalResult [[$O_REGION_CONSTRAINT:__mlir_ods_local_region_constraint.*]](
114// CHECK:      if (!((regionPred(region, *op)))) {
115// CHECK-NEXT:   return op->emitOpError("region #") << regionIndex
116// CHECK-NEXT:       << (regionName.empty() ? " " : " ('" + regionName + "') ")
117// CHECK-NEXT:       << "failed to verify constraint: another region";
118
119/// Test that the uniqued constraints are being used.
120// CHECK-LABEL: OpA::verify
121// CHECK:         ::mlir::Attribute [[$B_ATTR:.*b]];
122// CHECK:         if (::mlir::failed([[$A_ATTR_CONSTRAINT]](*this, [[$B_ATTR]], "b")))
123// CHECK-NEXT:      return ::mlir::failure();
124// CHECK:         auto [[$A_VALUE_GROUP:.*]] = getODSOperands(0);
125// CHECK:         for (auto [[$A_VALUE:.*]] : [[$A_VALUE_GROUP]])
126// CHECK-NEXT:      if (::mlir::failed([[$A_TYPE_CONSTRAINT]](*this, [[$A_VALUE]].getType(), "operand", index++)))
127// CHECK-NEXT:        return ::mlir::failure();
128// CHECK:         auto [[$RET_VALUE_GROUP:.*]] = getODSResults(0);
129// CHECK:         for (auto [[$RET_VALUE:.*]] : [[$RET_VALUE_GROUP]])
130// CHECK-NEXT:      if (::mlir::failed([[$A_TYPE_CONSTRAINT]](*this, [[$RET_VALUE]].getType(), "result", index++)))
131// CHECK-NEXT:        return ::mlir::failure();
132// CHECK:         for (auto &region : ::llvm::MutableArrayRef((*this)->getRegion(0)))
133// CHECK-NEXT:      if (::mlir::failed([[$A_REGION_CONSTRAINT]](*this, region, "d", index++)))
134// CHECK-NEXT:        return ::mlir::failure();
135// CHECK:         for (auto *successor : ::llvm::MutableArrayRef(c()))
136// CHECK-NEXT:      if (::mlir::failed([[$A_SUCCESSOR_CONSTRAINT]](*this, successor, "c", index++)))
137// CHECK-NEXT:        return ::mlir::failure();
138
139/// Test that the op with the same predicates but different with descriptions
140/// uses the different constraints.
141// CHECK-LABEL: OpC::verify
142// CHECK:         ::mlir::Attribute [[$B_ATTR:.*b]];
143// CHECK:         if (::mlir::failed([[$O_ATTR_CONSTRAINT]](*this, [[$B_ATTR]], "b")))
144// CHECK-NEXT:      return ::mlir::failure();
145// CHECK:         auto [[$A_VALUE_GROUP:.*]] = getODSOperands(0);
146// CHECK:         for (auto [[$A_VALUE:.*]] : [[$A_VALUE_GROUP]])
147// CHECK-NEXT:      if (::mlir::failed([[$O_TYPE_CONSTRAINT]](*this, [[$A_VALUE]].getType(), "operand", index++)))
148// CHECK-NEXT:        return ::mlir::failure();
149// CHECK:         auto [[$RET_VALUE_GROUP:.*]] = getODSResults(0);
150// CHECK:         for (auto [[$RET_VALUE:.*]] : [[$RET_VALUE_GROUP]])
151// CHECK-NEXT:      if (::mlir::failed([[$O_TYPE_CONSTRAINT]](*this, [[$RET_VALUE]].getType(), "result", index++)))
152// CHECK-NEXT:        return ::mlir::failure();
153// CHECK:         for (auto &region : ::llvm::MutableArrayRef((*this)->getRegion(0)))
154// CHECK-NEXT:      if (::mlir::failed([[$O_REGION_CONSTRAINT]](*this, region, "d", index++)))
155// CHECK-NEXT:        return ::mlir::failure();
156// CHECK:         for (auto *successor : ::llvm::MutableArrayRef(c()))
157// CHECK-NEXT:      if (::mlir::failed([[$O_SUCCESSOR_CONSTRAINT]](*this, successor, "c", index++)))
158// CHECK-NEXT:        return ::mlir::failure();
159