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 ®ion : ::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 ®ion : ::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